v18i101: Elm mail system, release 2.2, Part22/24
Rich Salz
rsalz at uunet.uu.net
Fri Apr 14 07:19:40 AEST 1989
Submitted-by: dsinc!syd at uunet.UU.NET (Syd Weinstein)
Posting-number: Volume 18, Issue 101
Archive-name: elm2.2/part22
#!/bin/sh
# this is part 22 of a multipart archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file src/utils.c continued
#
CurArch=22
if test ! -r s2_seq_.tmp
then echo "Please unpack part 1 first!"
exit 1; fi
( read Scheck
if test "$Scheck" != $CurArch
then echo "Please unpack part $Scheck next!"
exit 1;
else exit 0; fi
) < s2_seq_.tmp || exit 1
echo "x - Continuing file src/utils.c"
sed 's/^X//' << 'SHAR_EOF' >> src/utils.c
X dprint(1, (debugfile, "\nDump of stats for mailfile %s;\n",
X (folder_type == NON_SPOOL ? cur_folder : cur_tempfolder)));
X
X dprint(1, (debugfile, "\tinode: %d, mode: %o, uid: %d, ",
X buffer.st_ino, buffer.st_mode, buffer.st_uid));
X
X dprint(1, (debugfile,
X "gid: %d, size: %d\n\n", buffer.st_gid, buffer.st_size));
X
X dprint(1, (debugfile, "\toffset into file = %l\n", ftell(mailfile)));
X }
X else
X dprint(1, (debugfile,
X "\nfstat on mailfile '%s' failed with error %s!!\n\n",
X (folder_type == NON_SPOOL ? cur_folder : cur_tempfolder),
X error_name(errno)));
X}
X
Xemergency_exit()
X{
X /** used in dramatic cases when we must leave without altering
X ANYTHING about the system... **/
X char buffer[SLEN];
X char *mk_lockname();
X
X dprint(1, (debugfile,
X "\nERROR: Something dreadful is happening! Taking emergency exit!!\n\n"));
X dprint(1, (debugfile,
X " possibly leaving behind the following files;\n"));
X dprint(1, (debugfile,
X " The mailbox tempfile : %s\n", cur_tempfolder));
X if(folder_type == SPOOL) dprint(1, (debugfile,
X " The mailbox lock file: %s\n", mk_lockname(cur_folder)));
X dprint(1, (debugfile,
X " The composition file : %s%d\n", temp_file, getpid()));
X dprint(1, (debugfile,
X " The readmsg data file: %s/%s\n", home, readmsg_file));
X
X Raw(OFF);
X if (cursor_control) transmit_functions(OFF);
X if (hp_terminal) softkeys_off();
X
X if (cursor_control)
X MoveCursor(LINES, 0);
X
X PutLine0(LINES,0,
X "\nEmergency exit taken! All temp files intact!\n\n");
X
X exit(1);
X}
X
X/*ARGSUSED*/
X/*VARARGS0*/
X
Xleave(val)
Xint val; /* not used, placeholder for signal catching! */
X{
X char buffer[SLEN];
X
X dprint(2, (debugfile, "\nLeaving mailer normally (leave)\n"));
X
X Raw(OFF);
X if (cursor_control) transmit_functions(OFF);
X if (hp_terminal) softkeys_off();
X
X sprintf(buffer,"%s%d",temp_file, getpid()); /* editor buffer */
X (void) unlink(buffer);
X
X if (folder_type == SPOOL) {
X (void) unlink(cur_tempfolder);
X }
X
X sprintf(buffer,"%s/%s", home, readmsg_file); /* readmsg temp */
X (void) unlink(buffer);
X
X unlock(); /* remove lock file if any */
X
X if(!batch_only) {
X MoveCursor(LINES,0);
X NewLine();
X }
X
X exit(0);
X}
X
Xsilently_exit()
X{
X /** This is the same as 'leave', but it doesn't remove any non-pid
X files. It's used when we notice that we're trying to create a
X temp mail file and one already exists!!
X **/
X char buffer[SLEN];
X
X dprint(2, (debugfile, "\nLeaving mailer quietly (silently_exit)\n"));
X
X Raw(OFF);
X if (cursor_control) transmit_functions(OFF);
X if (hp_terminal) softkeys_off();
X
X sprintf(buffer,"%s%d",temp_file, getpid()); /* editor buffer */
X (void) unlink(buffer);
X
X MoveCursor(LINES,0);
X NewLine();
X
X exit(0);
X}
X
X/*ARGSUSED0*/
X
Xleave_locked(val)
Xint val; /* not used, placeholder for signal catching! */
X{
X /** same as leave routine, but don't disturb lock file **/
X
X char buffer[SLEN];
X
X dprint(3, (debugfile,
X "\nLeaving mailer due to presence of lock file (leave_locked)\n"));
X
X Raw(OFF);
X if (cursor_control) transmit_functions(OFF);
X if (hp_terminal) softkeys_off();
X
X sprintf(buffer,"%s%d",temp_file, getpid()); /* editor buffer */
X (void) unlink(buffer);
X
X (void) unlink(cur_tempfolder); /* temp mailbox */
X
X MoveCursor(LINES,0);
X NewLine();
X exit(0);
X}
X
Xint
Xget_page(msg_pointer)
Xint msg_pointer;
X{
X /** Ensure that 'current' is on the displayed page,
X returning non-zero iff the page changed! **/
X
X register int first_on_page, last_on_page;
X
X first_on_page = (header_page * headers_per_page) + 1;
X
X last_on_page = first_on_page + headers_per_page - 1;
X
X if (selected) /* but what is it on the SCREEN??? */
X msg_pointer = compute_visible(msg_pointer);
X
X if (selected && msg_pointer > selected)
X return(FALSE); /* too far - page can't change! */
X
X if (msg_pointer > last_on_page) {
X header_page = (int) (msg_pointer-1)/ headers_per_page;
X return(1);
X }
X else if (msg_pointer < first_on_page) {
X header_page = (int) (msg_pointer-1) / headers_per_page;
X return(1);
X }
X else
X return(0);
X}
X
Xchar *nameof(filename)
Xchar *filename;
X{
X /** checks to see if 'filename' has any common prefixes, if
X so it returns a string that is the same filename, but
X with '=' as the folder directory, or '~' as the home
X directory..
X **/
X
X static char buffer[STRING];
X register int i = 0, iindex = 0;
X
X if (strncmp(filename, folders, strlen(folders)) == 0) {
X if (strlen(folders) > 0) {
X buffer[i++] = '=';
X iindex = strlen(folders);
X if(filename[iindex] == '/')
X iindex++;
X }
X }
X else if (strncmp(filename, home, strlen(home)) == 0) {
X if (strlen(home) > 0) {
X buffer[i++] = '~';
X iindex = strlen(home);
X }
X }
X else iindex = 0;
X
X while (filename[iindex] != '\0')
X buffer[i++] = filename[iindex++];
X buffer[i] = '\0';
X
X return( (char *) buffer);
X}
SHAR_EOF
echo "File src/utils.c is complete"
chmod 0444 src/utils.c || echo "restore of src/utils.c fails"
echo "x - extracting src/validname.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > src/validname.c &&
X
Xstatic char rcsid[] = "@(#)$Id: validname.c,v 2.8 89/03/25 21:47:34 syd Exp $";
X
X/*******************************************************************************
X * The Elm Mail System - $Revision: 2.8 $ $State: Exp $
X *
X * Copyright (c) 1986, 1987 Dave Taylor
X * Copyright (c) 1988, 1989 USENET Community Trust
X *******************************************************************************
X * Bug reports, patches, comments, suggestions should be sent to:
X *
X * Syd Weinstein, Elm Coordinator
X * elm at dsinc.UUCP dsinc!elm
X *
X *******************************************************************************
X * $Log: validname.c,v $
X * Revision 2.8 89/03/25 21:47:34 syd
X * Initial 2.2 Release checkin
X *
X *
X ******************************************************************************/
X
X#include "defs.h"
X
X#include <stdio.h>
X
X#ifdef PWDINSYS
X# include <sys/pwd.h>
X#else
X# include <pwd.h>
X#endif
X
Xint
Xvalid_name(name)
Xchar *name;
X{
X /** Determine whether "name" is a valid logname on this system.
X It is valid if there is a password entry, or if there is
X a mail file in the mail spool directory for "name".
X **/
X
X#ifdef NOCHECK_VALIDNAME /* Force a return of valid */
X
X return(TRUE);
X
X#else
X
X char filebuf[SLEN];
X struct passwd *getpwnam();
X
X if(getpwnam(name) != NULL)
X return(TRUE);
X
X sprintf(filebuf,"%s/%s", mailhome, name);
X if (access(filebuf, ACCESS_EXISTS) == 0)
X return(TRUE);
X
X return(FALSE);
X
X#endif
X}
SHAR_EOF
chmod 0444 src/validname.c || echo "restore of src/validname.c fails"
echo "x - extracting test/test.empty (Text)"
sed 's/^X//' << 'SHAR_EOF' > test/test.empty &&
SHAR_EOF
chmod 0644 test/test.empty || echo "restore of test/test.empty fails"
echo "x - extracting test/test.mail (Text)"
sed 's/^X//' << 'SHAR_EOF' > test/test.mail &&
XFrom root Wed Oct 30 14:03:36 1985
X>From srmmail Wed Oct 30 14:10:08 1985 remote from veeger
X>From hplabs Wed Oct 30 14:00:16 1985 remote from hpcnof
X>From hpl-opus!poulton Wed Oct 30 02:06:16 1985 remote from hplabs
XDate: Wed, 30 Oct 85 01:55:05 pst
XFrom: <hplabs!hpl-opus!poulton>
XReceived: by HP-VENUS id AA26352; Wed, 30 Oct 85 01:55:05 pst
XMessage-Id: <8510300955.AA26352 at HP-VENUS>
XTo: hplabs!hpldat!taylor
XSubject: Re: announce(1)
X
XThe announce I got was shar'd July 8. NLEN was not defined in that
Xsource, just used. LONG_SLEN is not defined in the newmail(1)
Xthat you sent me. What system are you running on?
XMy s500 doesn't have these def's.
X
X -> Monday, January 3rd: Call your mother
X
XAs to announce --> newmail: why the switch?
XSeems like both are useful, in different situations.
X
XKen Poulton
XHPL
X
X
X
X
XFrom root Wed Oct 30 14:03:39 1985
X>From srmmail Wed Oct 30 14:10:12 1985 remote from veeger
X>From hplabs Wed Oct 30 13:59:53 1985 remote from hpcnof
X>From fowler Wed Oct 30 12:57:11 1985 remote from hplabs
XDate: Wed, 30 Oct 85 12:57:11 pst
XFrom: Greg Fowler <hplabs!fowler>
XReceived: by HP-VENUS id AA12562; Wed, 30 Oct 85 12:57:11 pst
XMessage-Id: <8510302057.AA12562 at HP-VENUS>
XTo: mail-men at rochester
XSubject: Re: Summary of Network Mail Headers
XReferences: <36700044 at hpcnof.UUCP>
XPriority: Most Urgent
X
XI believe your introduction referred to the uucp network. usenet is the network news
Xsoftware mechanism and isn't a "network".
X
X - > February 19, 1986
X -
X - A longer test of the system
X -
X
X Greg
X
X
X
XFrom root Wed Oct 30 14:13:23 1985
X>From srmmail Wed Oct 30 14:20:08 1985 remote from veeger
X>From root Wed Oct 30 14:01:57 1985 remote from hpcnof
XTo: DCC at hplabs
XSubject: Log of backup tape #1
X
X
XFull Backup starting at Wed Oct 30 12:45:14 MST 1985
X
X
X
Xbacking up directories:
X ./users/fh ./users/rmd ./users/vince ./users/roberts ./users/row ./users/dt ./lost+found ./users/lost+found ./users/scb ./users/kevin ./users/du
X
X
X
X
X
XFrom root Wed Oct 30 15:33:24 1985
X>From srmmail Wed Oct 30 15:40:26 1985 remote from veeger
X>From root Wed Oct 30 15:37:17 1985 remote from hpcnof
XTo: root, uucp, taylor at hplabs.ARPA
XSubject: Log of backup tape #2
X
Xbacking up directories:
X ./users/fh ./users/rmd ./users/vince ./users/roberts ./users/row ./users/dt ./lost+found ./users/lost+found ./users/scb ./users/kevin ./users/du
X
X
X
X
Xbacking up directories:
X ./users/sbh ./users/ges ./users/cpb ./users/amy ./net ./users/root ./users/balza ./dev ./users/remple ./users/jr ./users/mwr ./users/larryf
X
X
X
X
X
XFrom root Sun Dec 8 22:50:18 1985
X>From srmmail Mon Dec 9 00:50:05 1985 remote from veeger
X>From root Mon Dec 9 00:41:15 1985 remote from hpcnof
X>From JLarson.pa at Xerox.ARPA Sun Dec 8 20:45:55 1985 remote from hplabs
XDate: 8 Dec 85 20:36:36 PST (Sunday)
XFrom: hplabs!JLarson.pa at Xerox.ARPA
XSubject: How's it going, anyway?
XTo: hpcnou!dat at HPLABS.ARPA (Dave Taylor)
XCc: JLarson.pa at Xerox.ARPA
X
XHow are things with you? Could you send me that paper we were talking
Xabout?
X
X Thanks
X
XJohn Larson
XXerox Palo Alto Research Center
X3333 Coyote Hill Road
XPalo Alto, Ca 94304
X
X
X
X
XFrom To:host!root at hplabs.HP.COM Wed Aug 7 19:58:30 1985
X#From uucp Wed Aug 7 19:55:12 1985 remote from veeger
X#From hplabs Wed Aug 7 19:48:10 1985 remote from hpcnof
X#From RICHER at SUMEX-AIM Wed Aug 7 09:23:12 1985 remote from hplabs
XReceived: by HP-VENUS id AA18269; Wed, 7 Aug 85 09:11:48 pdt
XDate: Tue 6 Aug 85 09:12:37-PDT
X#From: Mark Richer <hplabs!RICHER at SUMEX-AIM>
XReceived: by HP-VENUS via CSNET; 7 Aug 1985 09:11:37-PDT (Wed)
XReceived: from sumex-aim.arpa by csnet-relay.arpa id a015812; 6 Aug 85 12:14 EDT
XTo: hpcnof!veeger!hpcnou!dat%hplabs.csnet at CSNET-RELAY
XVia: CSNet; 7 Aug 85 9:11-PDT
XSubject: Re: AI in Education mailing list...
XCc: RICHER at SUMEX-AIM
XIn-Reply-To: <8508030243.AA27641 at HP-VENUS>
XMessage-Id: <12132987812.61.RICHER at SUMEX-AIM.ARPA>
X
XI added you to aied. This message may be of interest to you:
X
XArtificial Intelligence in Education Meeting at IJCAI 85
X---------- ------------ -- --------- ------- -- ----- --
X
XPlace: Math Sciences Auditorium (a.k.a. Math 4000A), UCLA campus
XTime: 6:30 pm, Tuesday, Aug. 20, 1985 (length: 1 - 1 1/4 hr)
X
XAgenda:
X I have two speakers scheduled to make presentations that
Xshould stimulate questions and discussions:
X
X (1) Short Announcements
X
X (2) Jeff Bonar, Research Scientist, Learning Research and
X Development Center (LRDC), University of Pittsburgh
X
X --- on-going ICAI research projects at LRDC
X --- dissemination of ICAI technology in the form of software
X tools, workshops, written materials, and video tapes.
X
X (3) Gary Fine, Product Engineering Manager, INTELLICORP,
X formerly with a company producing CAI products, also graduate
X work in ICAI
X
X --- bridging the gap between current ICAI technology and the
X real world
X
X[IJCAI-85, the 9th International Joint Conference on Artificial
XIntelligence is being held at UCLA Campus, August 18-23, 1985. This
Xconference is co-sponsered by the American Association for Artificial
XIntelligence (AAAI) this year, and I have been told by their office
Xthat only walk-in registration is available at this time. For more
Xinformation, contact AAAI: AAAI-OFFICE at SUMEX-AIM.ARPA
X AAAI, 445 Burgess Drive, Menlo Park, CA 94025
X or call (415) 328-3123]
X
XDirect questions on the AI in ED meeting (only) to Mark Richer,
XRICHER at SUMEX-AIM.ARPA
X-------
X
X
X
X
XFrom root Tue Sep 24 09:53:24 1985
X>From HPMAIL-gateway Tue Sep 24 9:46:47 1985 remote from veeger
X>From Simon_CINTZ_/_HPD600/TR Tue Sep 24 9:46:47 1985 remote from hpmail
XDate: Tue, 24 Sep 85 9:14:00 MDT
XFrom: Simon_CINTZ_/_HPD600/TR (Simon Cintz)
XSubject: ITF
XFrom: Simon_CINTZ_/_HPD600/TR (Simon Cintz)
XTo: Dave_TAYLOR_/_HPF100/00
X
XDave -
X
XJust as one programming language doesn't suit the needs of
Xall programmers, one authoring facility will probably not
Xsuit the needs of all HP entities that require CBT -- at least
Xnot in the near future. Of course, this is my personal opinion
Xand if I'm wrong, it won't be the first time.
X
XGood luck.
X
X
X - Simon
X
XFrom root Mon Oct 21 10:43:37 1985
X>From srmmail Mon Oct 21 10:30:16 1985 remote from veeger
X>From root Mon Oct 21 10:28:58 1985 remote from hpcnof
X>From DLS.MDC%office-X.arpa at CSNET-RELAY Mon Oct 21 01:57:05 1985 remote from hplabs
XReceived: by HP-VENUS id AA17376; Mon, 21 Oct 85 01:57:05 pdt
XDate: 21 Oct 85 01:02 EDT
XFrom: Duane Stone / McDonnell Douglas / CSC-ASD <hplabs!DLS.MDC%office-1.arpa at CSNET-RELAY>
XReceived: by HP-VENUS via CSNET; 21 Oct 1985 01:57:01-PDT (Mon)
XReceived: from office-1.arpa by CSNET-RELAY.ARPA id a019220; 21 Oct 85 1:18 EDT
XTo: Dave Taylor <hpcnou!dat%hplabs.csnet at CSNET-RELAY>
XVia: CSNet; 21 Oct 85 1:56-PDT
XSubject: Re: More Mail Headers...
XMessage-Id: <MDC-DLS-7W9CS at OFFICE-1>
XComment: Dave -- this is the body of the message I previously 'sent' to you via
X
Xa Journal.
X
XI might suggest re-wording the para on Author -- my associates might object to
X'strange' -- something like:
X
X This is used to credit the original author, or to give credit on article
X excerpts (from Newspapers, magazines, books, etc).
X
XOne field which I forgot is:
X
X Length: This is computed when the message is sent and gives the recipients
X an estimate of the number of pages in the document.
X
X Example:
X
X Length: 6 pages [estimate]
X
XAccess:
X
X Used to declare whether a Journal item should be Public or Private (to those
X that are on the distribution list or Extended Access list)
X
X Example:
X
X Access: Unrestricted
X
XAcknowledge-Delivery:
X
X Used to request the system mailer send back a message when it has
X successfully delivered the item.
X
X Example:
X
X Acknowledge-Delivery: Requested
X
XAcknowledge-Receipt:
X
X Used to to ask the recipient to acknowledge receipt of the message.
X
X Example:
X
X Acknowledge-Receipt: Requested
X
XAddendum-To:
X
X A pointer to a previously submitted Journal item.
X
X Example:
X
X Addendum-To: <ASD,1234,>
X
XDelivery-Timing:
X
X Used by the sender to indicate when the message should be submitted to the
X mailer.
X
X Examples:
X
X Rush: - immediate
X
X Soon: - as soon as possible
X
X Defer: - overnight
X
X Start-Delivery: DATE TIME
X
X Stop-Delivery: DATE TIME (if not yet delivered)
X
XDisposition-Code:
X
X Used by the system to group Journal items into one of several classes for
X eventual archive to tape and as an indicator of how long the archive tapes
X should be retained.
X
X Example:
X
X Disposition-Code: Temporary (2 years)
X
XExtended-access:
X
X Used with private Journal items to allow access by other than those on the
X distribution list.
X
X Example:
X
X Extended-access: ASD.MDC
X
XLocation:
X
X Used to submit the message to the Journal. The adressees receive a short
X citation with other header fields and a "Location:" field pointing to a file
X in an electronic library.
X
X Example:
X
X Location: <MDC,1234,>
X
XPart-Of:
X
X A pointer to a previously submitted Journal item.
X
X Example:
X
X Part-Of: <MDC,1234,>
X
XRoute-To:
X
X Used to send a message "in-turn" to addressees in the "To:" field -- as
X opposed to the broadcast method of delivery where everyone gets the message
X "simultaneously". Any addresses in the "Cc:" field receive a copy of the
X message each time it is passed from one adressee to the next in the "To:"
X field.
X
X Example:
X
X Routed-to: {addresses in To field}
X
XSigned:
X
X Created when the user employs the Sign command; used to electronically sign
X a message. It affixes a signature-block to a message. A "Verify Signature"
X command is available to recipients that lets them find out if anyone has
X changed the body of the message since the message was signed.
X
X Example:
X
X SIGNED
X
X Duane L. Stone
X App. Dev. Mgr.
X
XSupersedes:
X
X A pointer to a previously submitted Journal item.
X
X Example:
X
X Supersedes: <MDC,1234,>
X
X
X--- last line of the file --
SHAR_EOF
chmod 0644 test/test.mail || echo "restore of test/test.mail fails"
echo "x - extracting utils/Makefile.SH (Text)"
sed 's/^X//' << 'SHAR_EOF' > utils/Makefile.SH &&
Xcase $CONFIG in
X'')
X if test ! -f config.sh; then
X ln ../config.sh . || \
X ln ../../config.sh . || \
X ln ../../../config.sh . || \
X (echo "Can't find config.sh."; exit 1)
X fi
X . ./config.sh
X ;;
Xesac
Xcase "$0" in
X*/*) cd `expr X$0 : 'X\(.*\)/'` ;;
Xesac
X
Xecho "Extracting utils/Makefile (with variable substitutions)"
Xcat >Makefile <<!GROK!THIS!
X
X# @(#)$Id: Makefile.SH,v 2.17 89/03/25 21:47:36 syd Exp $
X#
X# Makefile for the Elm system utilities
X#
X# Copyright (c) 1986, 1987 Dave Taylor
X# Copyright (c) 1988, 1989 USENET Community Trust
X#
X# Bug reports, patches, comments, suggestions should be sent to:
X#
X# Syd Weinstein - elm at dsinc.UUCP
X# dsinc!elm
X#
X# $Log: Makefile.SH,v $
X# Revision 2.17 89/03/25 21:47:36 syd
X# Initial 2.2 Release checkin
X#
X#
X# Variables
X# Variables established by Configure
XCC = $cc
XCCFLAGS = $ccflags $xencf
XCHMOD = $chmod
XCP = $cp
XDEST = $bin
XECHO = $echo
XLFLAGS = $ldflags $xenlf
XLIB = $lib
XLIB2 = $libs
XLIBS = $termlib $dbm
XLINT = $lint
XLN = $ln
XMAKE = $make
XMV = $mv
XOPTIMIZE = $optimize
XRM = $rm -f
XTOUCH = $touch
X!GROK!THIS!
X
Xcat >>Makefile <<'!NO!SUBS!'
X# Variables you may want to manually edit
X# If you want debug logging then you'll
X# want to uncomment the following.
X#DEBUG = -DDEBUG
X
X# Other general variables
XBIN = ../bin
XCFLAGS = $(CCFLAGS) $(OPTIMIZE) -I$(INCLDIR) $(DEBUG) $(DACSNET)
XINCLDIR = ../hdrs
XLINTFLAGS = -I$(INCLDIR)
XSHELL = /bin/sh
X
X# Lists
X# List of installed programs - excludes wnewmail, which is
X# handled separately
XINSTALL_LIST = $(DEST)/answer \
X $(DEST)/arepdaemon \
X $(DEST)/autoreply \
X $(DEST)/checkalias \
X $(DEST)/fastmail \
X $(DEST)/frm \
X $(DEST)/listalias \
X $(DEST)/messages \
X $(DEST)/newalias \
X $(DEST)/newmail \
X $(DEST)/printmail \
X $(DEST)/readmsg
X
X# List of remotely install programs
XREMOTE_LIST = $(REMOTE)$(DEST)/answer \
X $(REMOTE)$(DEST)/arepdaemon \
X $(REMOTE)$(DEST)/autoreply \
X $(REMOTE)$(DEST)/checkalias \
X $(REMOTE)$(DEST)/fastmail \
X $(REMOTE)$(DEST)/frm \
X $(REMOVE)$(DEST)/listalias \
X $(REMOVE)$(DEST)/messages \
X $(REMOVE)$(DEST)/newalias \
X $(REMOVE)$(DEST)/newmail \
X $(REMOVE)$(DEST)/printmail \
X $(REMOVE)$(DEST)/readmsg
X
X# List of programs in bin directory
XBINARY_LIST = $(BIN)/answer \
X $(BIN)/arepdaemon \
X $(BIN)/autoreply \
X $(BIN)/checkalias \
X $(BIN)/fastmail \
X $(BIN)/frm \
X $(BIN)/listalias \
X $(BIN)/messages \
X $(BIN)/newalias \
X $(BIN)/newmail \
X $(BIN)/printmail \
X $(BIN)/readmsg
X
X# List of programs to $(LINT) - only C programs
XLINT_LIST = answer_lint \
X arepdaemon_lint \
X autoreply_lint \
X fastmail_lint \
X frm_lint \
X listalias_lint \
X newalias_lint \
X newmail_lint \
X readmsg_lint
X
X# List of all object files in all util programs (used in parallel makes)
XUTIL_OBJ = answer.o \
X arepdaem.o \
X autoreply.o \
X expand.o \
X fastmail.o \
X from.o \
X listalias.o \
X newalias.o \
X newmail.o \
X readmsg.o \
X ../src/opt_utils.o \
X ../src/string2.o \
X ../src/validname.o
X
X# Lists of source and object files for each C program
XANSWER_SRC = answer.c ../src/opt_utils.c
XANSWER_OBJ = answer.o ../src/opt_utils.o
XAREPDAEMON_SRC = arepdaem.c ../src/opt_utils.c
XAREPDAEMON_OBJ = arepdaem.o ../src/opt_utils.o
XAUTOREPLY_SRC = autoreply.c ../src/opt_utils.c
XAUTOREPLY_OBJ = autoreply.o ../src/opt_utils.o
XFASTMAIL_SRC = fastmail.c ../src/opt_utils.c
XFASTMAIL_OBJ = fastmail.o ../src/opt_utils.o
XFRM_SRC = from.c expand.c ../src/opt_utils.c ../src/string2.c
XFRM_OBJ = from.o expand.o ../src/opt_utils.o ../src/string2.o
XLISTALIAS_SRC = listalias.c
XLISTALIAS_OBJ = listalias.o
XNEWALIAS_SRC = newalias.c ../src/validname.c ../src/opt_utils.c
XNEWALIAS_OBJ = newalias.o ../src/validname.o ../src/opt_utils.o
XNEWMAIL_SRC = newmail.c expand.c ../src/opt_utils.c ../src/string2.c
XNEWMAIL_OBJ = newmail.o expand.o ../src/opt_utils.o ../src/string2.o
XREADMSG_SRC = readmsg.c ../src/opt_utils.c ../src/string2.c
XREADMSG_OBJ = readmsg.o ../src/opt_utils.o ../src/string2.o
X
X# Standard targets
Xall: objects $(BINARY_LIST)
X
X# This unusual target enables highly efficial compilation of object files
X# on systems that have the parallel make feature.
Xobjects: $& $(UTIL_OBJ)
X
Xinstall: $(INSTALL_LIST) $(DEST)/wnewmail
X
Xuninstall:
X $(RM) $(INSTALL_LIST) $(DEST)/wnewmail
X
X# This is the only target that gets installed even if not out-of-date
X# with respect the files from which it is installed.
Xrmt-install: rmt-defined
X -$(MV) $(DEST)/answer $(DEST)/answer.old
X -$(MV) $(DEST)/arepdaemon $(DEST)/arepdaemon.old
X -$(MV) $(DEST)/autoreply $(DEST)/autoreply.old
X -$(MV) $(DEST)/checkalias $(DEST)/checkalias.old
X -$(MV) $(DEST)/fastmail $(DEST)/fastmail.old
X -$(MV) $(DEST)/frm $(DEST)/frm.old
X -$(MV) $(DEST)/listalias $(DEST)/listalias.old
X -$(MV) $(DEST)/messages $(DEST)/messages.old
X -$(MV) $(DEST)/newalias $(DEST)/newalias.old
X -$(MV) $(DEST)/newmail $(DEST)/newmail.old
X -$(MV) $(DEST)/printmail $(DEST)/printmail.old
X -$(MV) $(DEST)/readmsg $(DEST)/readmsg.old
X -$(MV) $(DEST)/wnewmail $(DEST)/wnewmail.old
X -$(RM) $(DEST)/answer.old
X -$(RM) $(DEST)/arepdaemon.old
X -$(RM) $(DEST)/autoreply.old
X -$(RM) $(DEST)/checkalias.old
X -$(RM) $(DEST)/fastmail.old
X -$(RM) $(DEST)/frm.old
X -$(RM) $(DEST)/listalias.old
X -$(RM) $(DEST)/messages.old
X -$(RM) $(DEST)/newalias.old
X -$(RM) $(DEST)/newmail.old
X -$(RM) $(DEST)/printmail.old
X -$(RM) $(DEST)/readmsg.old
X -$(RM) $(DEST)/wnewmail.old
X $(CP) $(REMOTE_LIST) $(DEST)
X $(LN) $(REMOTE)$(DEST)/wnewmail $(DEST)
X $(CHMOD) a+rx $(INSTALL_LIST)
X
Xrmt-defined:
X @(if [ "$(REMOTE)" = "" ];\
X then\
X $(ECHO) "You need to define 'REMOTE' as the remote file system";\
X $(ECHO) "for this particular command. The easiest way to do this";\
X $(ECHO) "to type:";\
X $(ECHO) " make REMOTE=<remote file system> rmt-install";\
X exit 1;\
X fi);
X
X# This rule allows us to put lint output for each program on the
X# same file, but make sure we start off fresh each time.
Xlint:
X $(RM) LINT.OUT; $(MAKE) -$(MAKEFLAGS) $(LINT_LIST)
X
Xclean:
X $(RM) $(UTIL_OBJ) $(BINARY_LIST)
X
X# Dependencies and rules
X# Dependencies and rules for compiling and linting C programs
X$(BIN)/answer: $(ANSWER_OBJ)
X $(CC) $(LFLAGS) -o $@ $(ANSWER_OBJ) $(LIB2)
X
Xanswer_lint: $(ANSWER_SRC)
X $(LINT) $(LINTFLAGS) $(ANSWER_SRC) >> LINT.OUT
X
X$(BIN)/arepdaemon: $(AREPDAEMON_OBJ)
X $(CC) $(LFLAGS) -o $@ $(AREPDAEMON_OBJ) $(LIB2)
X
Xarepdaemon_lint: $(AREPDAEMON_SRC)
X $(LINT) $(LINTFLAGS) $(AREPDAEMON_SRC) >> LINT.OUT
X
X$(BIN)/autoreply: $(AUTOREPLY_OBJ)
X $(CC) $(LFLAGS) -o $@ $(AUTOREPLY_OBJ) $(LIB2)
X
Xautoreply_lint: $(AUTOREPLY_SRC)
X $(LINT) $(LINTFLAGS) $(AUTOREPLY_SRC) >> LINT.OUT
X
X$(BIN)/fastmail: $(FASTMAIL_OBJ)
X $(CC) $(LFLAGS) -o $@ $(FASTMAIL_OBJ) $(LIB2)
X
Xfastmail_lint: $(FASTMAIL_SRC)
X $(LINT) $(LINTFLAGS) $(FASTMAIL_SRC) >> LINT.OUT
X
X$(BIN)/frm: $(FRM_OBJ)
X $(CC) $(LFLAGS) -o $@ $(FRM_OBJ) $(LIB2)
X
Xfrm_lint: $(FRM_SRC)
X $(LINT) $(LINTFLAGS) $(FRM_SRC) >> LINT.OUT
X
X$(BIN)/listalias: $(LISTALIAS_OBJ)
X $(CC) $(LFLAGS) -o $@ $(LISTALIAS_OBJ) $(LIB2)
X
Xlistalias_lint: $(LISTALIAS_SRC)
X $(LINT) $(LINTFLAGS) $(LISTALIAS_SRC) >> LINT.OUT
X
X$(BIN)/newalias: $(NEWALIAS_OBJ)
X $(CC) $(LFLAGS) -o $@ $(NEWALIAS_OBJ) $(LIB2)
X
Xnewalias_lint: $(NEWALIAS_SRC)
X $(LINT) $(LINTFLAGS) $(NEWALIAS_SRC) >> LINT.OUT
X
X$(BIN)/newmail: $(NEWMAIL_OBJ)
X $(CC) $(LFLAGS) -o $@ $(NEWMAIL_OBJ) $(LIB2)
X
Xnewmail_lint: $(NEWMAIL_SRC)
X $(LINT) $(LINTFLAGS) $(NEWMAIL_SRC) >> LINT.OUT
X
X$(BIN)/readmsg: $(READMSG_OBJ)
X $(CC) $(LFLAGS) -o $@ $(READMSG_OBJ) $(LIB2)
X
Xreadmsg_lint: $(READMSG_SRC)
X $(LINT) $(LINTFLAGS) $(READMSG_SRC) >> LINT.OUT
X
X
X# Rules to make shell scripts in bin directory
X$(BIN)/checkalias: checkalias
X $(CP) $? $@
X $(CHMOD) u+w,a+rx $@
X
X$(BIN)/messages: messages
X $(CP) $? $@
X $(CHMOD) u+w,a+rx $@
X
X$(BIN)/printmail: printmail
X $(CP) $? $@
X $(CHMOD) u+w,a+rx $@
X
X# Dependencies of header files upon other header files they include
X$(INCLDIR)/defs.h: $(INCLDIR)/../config.h $(INCLDIR)/sysdefs.h
X $(CHMOD) u+w $@
X $(TOUCH) $@
X
X$(INCLDIR)/elm.h: $(INCLDIR)/curses.h $(INCLDIR)/defs.h
X $(CHMOD) u+w $@
X $(TOUCH) $@
X
X$(INCLDIR)/headers.h: $(INCLDIR)/curses.h $(INCLDIR)/defs.h
X $(CHMOD) u+w $@
X $(TOUCH) $@
X
X# Rules to make objects from src directory
X../src/opt_utils.o:
X cd ../src; $(MAKE) -$(MAKEFLAGS) opt_utils.o
X
X../src/string2.o:
X cd ../src; $(MAKE) -$(MAKEFLAGS) string2.o
X
X../src/validname.o:
X cd ../src; $(MAKE) -$(MAKEFLAGS) validname.o
X
X# Dependencies of C object files
Xanswer.o: $(INCLDIR)/defs.h
Xarepdaem.o: $(INCLDIR)/defs.h
Xautoreply.o: $(INCLDIR)/defs.h
Xexpand.o: $(INCLDIR)/defs.h
Xfastmail.o: $(INCLDIR)/defs.h $(INCLDIR)/patchlevel.h
Xfrom.o: $(INCLDIR)/defs.h
Xlistalias.o: $(INCLDIR)/defs.h $(INCLDIR)/sysdefs.h
Xnewalias.o: $(INCLDIR)/defs.h $(INCLDIR)/sysdefs.h
Xnewmail.o: $(INCLDIR)/defs.h
Xreadmsg.o: $(INCLDIR)/defs.h
X
X# Dependencies and rules for installing programs from bin directory
X$(DEST)/answer: $(BIN)/answer
X -$(MV) $@ $@.old
X -$(RM) $@.old
X $(CP) $? $@
X $(CHMOD) a+x $@
X
X$(DEST)/arepdaemon: $(BIN)/arepdaemon
X -$(MV) $@ $@.old
X -$(RM) $@.old
X $(CP) $? $@
X $(CHMOD) a+x $@
X
X$(DEST)/autoreply: $(BIN)/autoreply
X -$(MV) $@ $@.old
X -$(RM) $@.old
X $(CP) $? $@
X $(CHMOD) a+x $@
X $(CHMOD) u+s $@
X
X$(DEST)/checkalias: $(BIN)/checkalias
X -$(MV) $@ $@.old
X -$(RM) $@.old
X $(CP) $? $@
X $(CHMOD) a+rx $@
X
X$(DEST)/fastmail: $(BIN)/fastmail
X -$(MV) $@ $@.old
X -$(RM) $@.old
X $(CP) $? $@
X $(CHMOD) a+x $@
X
X$(DEST)/frm: $(BIN)/frm
X -$(MV) $@ $@.old
X -$(RM) $@.old
X $(CP) $? $@
X $(CHMOD) a+x $@
X
X$(DEST)/listalias: $(BIN)/listalias
X -$(MV) $@ $@.old
X -$(RM) $@.old
X $(CP) $? $@
X $(CHMOD) a+x $@
X
X$(DEST)/messages: $(BIN)/messages
X -$(MV) $@ $@.old
X -$(RM) $@.old
X $(CP) $? $@
X $(CHMOD) a+rx $@
X
X$(DEST)/newalias: $(BIN)/newalias
X -$(MV) $@ $@.old
X -$(RM) $@.old
X $(CP) $? $@
X $(CHMOD) a+x $@
X
X$(DEST)/newmail: $(BIN)/newmail
X -$(MV) $@ $@.old
X -$(RM) $@.old
X $(RM) $@
X $(CP) $? $@
X $(CHMOD) a+x $@
X
X$(DEST)/printmail: $(BIN)/printmail
X -$(MV) $@ $@.old
X -$(RM) $@.old
X $(CP) $? $@
X $(CHMOD) a+rx $@
X
X$(DEST)/readmsg: $(BIN)/readmsg
X -$(MV) $@ $@.old
X -$(RM) $@.old
X $(CP) $? $@
X $(CHMOD) a+x $@
X
X$(DEST)/wnewmail: $(DEST)/newmail
X -$(MV) $@ $@.old
X -$(RM) $@.old
X $(RM) $@
X $(LN) $? $@
X
X!NO!SUBS!
SHAR_EOF
chmod 0444 utils/Makefile.SH || echo "restore of utils/Makefile.SH fails"
echo "x - extracting utils/answer.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > utils/answer.c &&
X
Xstatic char rcsid[] = "@(#)$Id: answer.c,v 2.5 89/03/25 21:47:38 syd Exp $";
X
X/*******************************************************************************
X * The Elm Mail System - $Revision: 2.5 $ $State: Exp $
X *
X * Copyright (c) 1986, 1987 Dave Taylor
X * Copyright (c) 1988, 1989 USENET Community Trust
X *******************************************************************************
X * Bug reports, patches, comments, suggestions should be sent to:
X *
X * Syd Weinstein, Elm Coordinator
X * elm at dsinc.UUCP dsinc!elm
X *
X *******************************************************************************
X * $Log: answer.c,v $
X * Revision 2.5 89/03/25 21:47:38 syd
X * Initial 2.2 Release checkin
X *
X *
X ******************************************************************************/
X
X/** This program is a phone message transcription system, and
X is designed for secretaries and the like, to allow them to
X painlessly generate electronic mail instead of paper forms.
X
X Note: this program ONLY uses the local alias file, and does not
X even read in the system alias file at all.
X
X**/
X
X#include <stdio.h>
X#include <fcntl.h>
X#include <ctype.h>
X
X#include "defs.h" /* ELM system definitions */
X
X#define ELM "elm" /* where the elm program lives */
X
X#define answer_temp_file "/tmp/answer."
X
Xstatic char ident[] = { WHAT_STRING };
X
Xstruct alias_rec user_hash_table [MAX_UALIASES];
X
Xint user_data; /* fileno of user data file */
X
Xchar *expand_group(), *get_alias_address(), *get_token(), *strip_parens();
X
Xmain()
X{
X FILE *fd;
X char *address, buffer[LONG_STRING], tempfile[SLEN], *cp;
X char name[SLEN], user_name[SLEN];
X int msgnum = 0, eof;
X
X read_alias_files();
X
X while (1) {
X if (msgnum > 9999) msgnum = 0;
X
X printf("\n-------------------------------------------------------------------------------\n");
X
Xprompt: printf("\nMessage to: ");
X if (fgets(user_name, SLEN, stdin) == NULL || user_name[0] == '\0')
X goto prompt;
X
X cp = &user_name[strlen(user_name)-1];
X if(*cp == '\n') *cp = '\0';
X
X if ((strcmp(user_name,"quit") == 0) ||
X (strcmp(user_name,"exit") == 0) ||
X (strcmp(user_name,"done") == 0) ||
X (strcmp(user_name,"bye") == 0))
X exit(0);
X
X if (translate(user_name, name) == 0)
X goto prompt;
X
X address = get_alias_address(name, 1, 0);
X
X printf("address '%s'\n", address);
X
X if (address == NULL || strlen(address) == 0) {
X printf("Sorry, could not find '%s' [%s] in list!\n", user_name,
X name);
X goto prompt;
X }
X
X sprintf(tempfile, "%s%d", answer_temp_file, msgnum++);
X
X if ((fd = fopen(tempfile,"w")) == NULL)
X exit(printf("** Fatal Error: could not open %s to write\n",
X tempfile));
X
X
X printf("\nEnter message for %s ending with a blank line.\n\n",
X user_name);
X
X fprintf(fd,"\n\n");
X
X do {
X printf("> ");
X if (! (eof = (fgets(buffer, SLEN, stdin) == NULL)))
X fprintf(fd, "%s", buffer);
X } while (! eof && strlen(buffer) > 1);
X
X fclose(fd);
X
X sprintf(buffer,
X "((%s -s \"While You Were Out\" %s ; %s %s) & ) < %s > /dev/null",
X ELM, strip_parens(address), remove_cmd, tempfile, tempfile);
X
X system(buffer);
X }
X}
X
Xint
Xtranslate(fullname, name)
Xchar *fullname, *name;
X{
X /** translate fullname into name..
X 'first last' translated to first_initial - underline - last
X 'initial last' translated to initial - underline - last
X Return 0 if error.
X **/
X register int i, lastname = 0;
X
X for (i=0; i < strlen(fullname); i++) {
X
X if (isupper(fullname[i]))
X fullname[i] = tolower(fullname[i]);
X
X if (fullname[i] == ' ')
X if (lastname) {
X printf(
X "** Can't have more than 'FirstName LastName' as address!\n");
X return(0);
X }
X else
X lastname = i+1;
X
X }
X
X if (lastname)
X sprintf(name, "%c_%s", fullname[0], (char *) fullname + lastname);
X else
X strcpy(name, fullname);
X
X return(1);
X}
X
X
Xread_alias_files()
X{
X /** read the user alias file **/
X
X char fname[SLEN];
X int hash;
X
X sprintf(fname, "%s/.elm/aliases.hash", getenv("HOME"));
X
X if ((hash = open(fname, O_RDONLY)) == -1)
X exit(printf("** Fatal Error: Could not open %s!\n", fname));
X
X read(hash, user_hash_table, sizeof user_hash_table);
X close(hash);
X
X sprintf(fname, "%s/.elm/aliases.data", getenv("HOME"));
X
X if ((user_data = open(fname, O_RDONLY)) == -1)
X return;
X}
X
Xchar *get_alias_address(name, mailing, depth)
Xchar *name;
Xint mailing, depth;
X{
X /** return the line from either datafile that corresponds
X to the specified name. If 'mailing' specified, then
X fully expand group names. Returns NULL if not found.
X Depth is the nesting depth, and varies according to the
X nesting level of the routine. **/
X
X static char buffer[VERY_LONG_STRING];
X int loc;
X
X if ((loc = find(name, user_hash_table, MAX_UALIASES)) >= 0) {
X lseek(user_data, user_hash_table[loc].byte, 0L);
X get_line(user_data, buffer);
X if (buffer[0] == '!' && mailing)
X return( (char *) expand_group(buffer, depth));
X else
X return( (char *) buffer);
X }
X
X return( (char *) NULL);
X}
X
Xchar *expand_group(members, depth)
Xchar *members;
Xint depth;
X{
X /** given a group of names separated by commas, this routine
X will return a string that is the full addresses of each
X member separated by spaces. Depth is the current recursion
X depth of the expansion (for the 'get_token' routine) **/
X
X char buffer[VERY_LONG_STRING];
X char buf[LONG_STRING], *word, *address, *bufptr;
X
X strcpy(buf, members); /* parameter safety! */
X buffer[0] = '\0'; /* nothing in yet! */
X bufptr = (char *) buf; /* grab the address */
X depth++; /* one more deeply into stack */
X
X while ((word = (char *) get_token(bufptr, "!, ", depth)) != NULL) {
X if ((address = (char *) get_alias_address(word, 1, depth)) == NULL) {
X fprintf(stderr, "Alias %s not found for group expansion!", word);
X return( (char *) NULL);
X }
X else if (strcmp(buffer,address) != 0) {
X sprintf(buffer,"%s %s", buffer, address);
X }
X
X bufptr = NULL;
X }
X
X return( (char *) buffer);
X}
X
Xint
Xfind(word, table, size)
Xchar *word;
Xstruct alias_rec table[];
Xint size;
X{
X /** find word and return loc, or -1 **/
X register int loc;
X
X if (strlen(word) > 20)
X exit(printf("Bad alias name: %s. Too long.\n", word));
X
X loc = hash_it(word, size);
X
X while (strcmp(word, table[loc].name) != 0) {
X if (table[loc].name[0] == '\0')
X return(-1);
X loc = (loc + 1) % size;
X }
X
X return(loc);
X}
X
Xint
Xhash_it(string, table_size)
Xchar *string;
Xint table_size;
X{
X /** compute the hash function of the string, returning
X it (mod table_size) **/
X
X register int i, sum = 0;
X
X for (i=0; string[i] != '\0'; i++)
X sum += (int) string[i];
X
X return(sum % table_size);
X}
X
Xget_line(fd, buffer)
Xint fd;
Xchar *buffer;
X{
X /* read from file fd. End read upon reading either
X EOF or '\n' character (this is where it differs
X from a straight 'read' command!) */
X
X register int i= 0;
X char ch;
X
X while (read(fd, &ch, 1) > 0)
X if (ch == '\n' || ch == '\r') {
X buffer[i] = 0;
X return;
X }
X else
X buffer[i++] = ch;
X}
X
Xprint_long(buffer, init_len)
Xchar *buffer;
Xint init_len;
X{
X /** print buffer out, 80 characters (or less) per line, for
X as many lines as needed. If 'init_len' is specified,
X it is the length that the first line can be.
X **/
X
X register int i, loc=0, space, length;
X
X /* In general, go to 80 characters beyond current character
X being processed, and then work backwards until space found! */
X
X length = init_len;
X
X do {
X if (strlen(buffer) > loc + length) {
X space = loc + length;
X while (buffer[space] != ' ' && space > loc + 50) space--;
X for (i=loc;i <= space;i++)
X putchar(buffer[i]);
X putchar('\n');
X loc = space;
X }
X else {
X for (i=loc;i < strlen(buffer);i++)
X putchar(buffer[i]);
X putchar('\n');
X loc = strlen(buffer);
X }
X length = 80;
X } while (loc < strlen(buffer));
X}
X
X/****
X The following is a newly chopped version of the 'strtok' routine
X that can work in a recursive way (up to 20 levels of recursion) by
X changing the character buffer to an array of character buffers....
X****/
X
X#define MAX_RECURSION 20 /* up to 20 deep recursion */
X
X#undef NULL
X#define NULL (char *) 0 /* for this routine only */
X
Xextern int strspn();
Xextern char *strpbrk();
X
Xchar *get_token(string, sepset, depth)
Xchar *string, *sepset;
Xint depth;
X{
X
X /** string is the string pointer to break up, sepstr are the
X list of characters that can break the line up and depth
X is the current nesting/recursion depth of the call **/
X
X register char *p, *q, *r;
X static char *savept[MAX_RECURSION];
X
X /** is there space on the recursion stack? **/
X
X if (depth >= MAX_RECURSION) {
X fprintf(stderr,"Error: Get_token calls nested greated than %d deep!\n",
X MAX_RECURSION);
X exit(1);
X }
X
X /* set up the pointer for the first or subsequent call */
X p = (string == NULL)? savept[depth]: string;
X
X if(p == 0) /* return if no tokens remaining */
X return(NULL);
X
X q = p + strspn(p, sepset); /* skip leading separators */
X
X if (*q == '\0') /* return if no tokens remaining */
X return(NULL);
X
X if ((r = strpbrk(q, sepset)) == NULL) /* move past token */
X savept[depth] = 0; /* indicate this is last token */
X else {
X *r = '\0';
X savept[depth] = ++r;
X }
X return(q);
X}
X
Xchar *strip_parens(string)
Xchar *string;
X{
X /** Return string with all parenthesized information removed.
X This is a non-destructive algorithm... **/
X
X static char buffer[LONG_STRING];
X register int i, depth = 0, buffer_index = 0;
X
X for (i=0; i < strlen(string); i++) {
X if (string[i] == '(')
X depth++;
X else if (string[i] == ')')
X depth--;
X else if (depth == 0)
X buffer[buffer_index++] = string[i];
X }
X
X buffer[buffer_index] = '\0';
X
X return( (char *) buffer);
X}
SHAR_EOF
chmod 0444 utils/answer.c || echo "restore of utils/answer.c fails"
echo "x - extracting utils/arepdaem.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > utils/arepdaem.c &&
X
Xstatic char rcsid[] = "@(#)$Id: arepdaem.c,v 2.6 89/03/25 21:47:39 syd Exp $";
X
X/*******************************************************************************
X * The Elm Mail System - $Revision: 2.6 $ $State: Exp $
X *
X * Copyright (c) 1986, 1987 Dave Taylor
X * Copyright (c) 1988, 1989 USENET Community Trust
X *******************************************************************************
X * Bug reports, patches, comments, suggestions should be sent to:
X *
X * Syd Weinstein, Elm Coordinator
X * elm at dsinc.UUCP dsinc!elm
X *
X *******************************************************************************
X * $Log: arepdaem.c,v $
X * Revision 2.6 89/03/25 21:47:39 syd
X * Initial 2.2 Release checkin
X *
X *
X ******************************************************************************/
X
X/** Keep track of mail as it arrives, and respond by sending a 'recording'
X file to the sender as new mail is received.
X
X Note: the user program that interacts with this program is the
X 'autoreply' program and that should be consulted for further
X usage information.
X
X This program is part of the 'autoreply' system, and is designed
X to run every hour and check all mailboxes listed in the file
X "/etc/autoreply.data", where the data is in the form:
X
X username replyfile current-mailfile-size
X
X To avoid a flood of autoreplies, this program will NOT reply to mail
X that contains header "X-Mailer: fastmail". Further, each time the
X program responds to mail, the 'mailfile size' entry is updated in
X the file /etc/autoreply.data to allow the system to be brought
X down and rebooted without any loss of data or duplicate messages.
X
X This daemon also uses a lock semaphore file, /usr/spool/uucp/LCK..arep,
X to ensure that more than one copy of itself is never running. For this
X reason, it is recommended that this daemon be started up each morning
X from cron, since it will either start since it's needed or simply see
X that the file is there and disappear.
X
X Since this particular program is the main daemon answering any
X number of different users, it must be run with uid root.
X**/
X
X#include <stdio.h>
X#include "defs.h"
X
X#ifdef BSD
X# include <sys/time.h>
X#else
X# include <time.h>
X#endif
X
X#include <sys/types.h>
X#include <sys/stat.h>
X
Xstatic char ident[] = { WHAT_STRING };
X
X#define arep_lock_file "/usr/spool/uucp/LCK..arep"
X
X#define autoreply_file "/etc/autoreply.data"
X#define fastmail "/usr/local/bin/fastmail"
X
X#define logfile "/etc/autoreply.log" /* first choice */
X#define logfile2 "/tmp/autoreply.log" /* second choice */
X
X#define BEGINNING 0 /* see fseek(3S) for info */
X#define SLEEP_TIME 3600 /* run once an hour */
X#define MAX_PEOPLE 20 /* max number in program */
X
X#define EXISTS 00 /* lock file exists?? */
X#define MODE 0777 /* lockfile creation mode */
X
X#define remove_return(s) if (strlen(s) > 0) { \
X if (s[strlen(s)-1] == '\n') \
X s[strlen(s)-1] = '\0'; \
X }
X
Xstruct replyrec {
X char username[NLEN]; /* login name of user */
X char mailfile[SLEN]; /* name of mail file */
X char replyfile[SLEN]; /* name of reply file */
X long mailsize; /* mail file size */
X int in_list; /* for new replies */
X } reply_table[MAX_PEOPLE];
X
XFILE *logfd; /* logfile (log action) */
Xlong autoreply_size = 0L; /* size of autoreply file */
Xint active = 0; /* # of people 'enrolled' */
X
XFILE *open_logfile(); /* forward declaration */
X
Xlong bytes(); /* ditto */
X
Xmain()
X{
X long size;
X int person, data_changed;
X
X if (! lock())
X exit(0); /* already running! */
X
X if (fork()) exit(0);
X
X while (1) {
X
X logfd = open_logfile(); /* open the log */
X
X /* 1. check to see if autoreply table has changed.. */
X
X if ((size = bytes(autoreply_file)) != autoreply_size) {
X read_autoreply_file();
X autoreply_size = size;
X }
X
X /* 2. now for each active person... */
X
X data_changed = 0;
X
X for (person = 0; person < active; person++) {
X if ((size = bytes(reply_table[person].mailfile)) !=
X reply_table[person].mailsize) {
X if (size > reply_table[person].mailsize)
X read_newmail(person);
X /* else mail removed - resync */
X reply_table[person].mailsize = size;
X data_changed++;
X }
X }
X
X /* 3. if data changed, update autoreply file */
X
X if (data_changed)
X update_autoreply_file();
X
X close_logfile(); /* close the logfile again */
X
X /* 4. Go to sleep... */
X
X sleep(SLEEP_TIME);
X }
X}
X
Xint
Xread_autoreply_file()
X{
X /** We're here because the autoreply file has changed size!! It
X could either be because someone has been added or because
X someone has been removed...since the list will always be in
X order (nice, eh?) we should have a pretty easy time of it...
X **/
X
X FILE *file;
X char username[SLEN], replyfile[SLEN];
X int person;
X long size;
X
X log("Autoreply data file has changed! Reading...");
X
X if ((file = fopen(autoreply_file,"r")) == NULL) {
X log("No-one is using autoreply...");
X return(0);
X }
X
X for (person = 0; person < active; person++)
X reply_table[person].in_list = 0;
X
X while (fscanf(file, "%s %s %dl", username, replyfile, &size) != EOF) {
X /* check to see if this person is already in the list */
X if ((person = in_list(username)) != -1) {
X reply_table[person].in_list = 1;
X reply_table[person].mailsize = size; /* sync */
X }
X else { /* if not, add them */
X if (active == MAX_PEOPLE) {
X unlock();
X exit(log("Couldn't add %s - already at max people!",
X username));
X }
X log("adding %s to the active list", username);
X strcpy(reply_table[active].username, username);
X sprintf(reply_table[active].mailfile, "%s%s", mailhome, username);
X strcpy(reply_table[active].replyfile, replyfile);
X reply_table[active].mailsize = size;
X reply_table[active].in_list = 1; /* obviously! */
X active++;
X }
X }
X
X /** now check to see if anyone has been removed... **/
X
X for (person = 0; person < active; person++)
X if (reply_table[person].in_list == 0) {
X log("removing %s from the active list",
X reply_table[person].username);
X strcpy(reply_table[person].username,
X reply_table[active-1].username);
X strcpy(reply_table[person].mailfile,
X reply_table[active-1].mailfile);
X strcpy(reply_table[person].replyfile,
X reply_table[active-1].replyfile);
X reply_table[person].mailsize = reply_table[active-1].mailsize;
X active--;
X }
X}
X
Xupdate_autoreply_file()
X{
X /** update the entries in the autoreply file... **/
X
X FILE *file;
X register int person;
X
X if ((file = fopen(autoreply_file,"w")) == NULL) {
X log("Couldn't update autoreply file!");
X return;
X }
X
X for (person = 0; person < active; person++)
X fprintf(file, "%s %s %ld\n",
X reply_table[person].username,
X reply_table[person].replyfile,
X reply_table[person].mailsize);
X
X fclose(file);
X
X/* printf("updated autoreply file\n"); */
X autoreply_size = bytes(autoreply_file);
X}
X
Xint
Xin_list(name)
Xchar *name;
X{
X /** search the current active reply list for the specified username.
X return the index if found, or '-1' if not. **/
X
X register int iindex;
X
X for (iindex = 0; iindex < active; iindex++)
X if (strcmp(name, reply_table[iindex].username) == 0)
X return(iindex);
X
X return(-1);
X}
X
Xread_newmail(person)
Xint person;
X{
X /** Read the new mail for the specified person. **/
X
X
X FILE *mailfile;
X char from_whom[SLEN], subject[SLEN];
X int sendit;
X
X log("New mail for %s", reply_table[person].username);
X
X if ((mailfile = fopen(reply_table[person].mailfile,"r")) == NULL)
X return(log("can't open mailfile for user %s",
X reply_table[person].username));
X
X if (fseek(mailfile, reply_table[person].mailsize, BEGINNING) == -1)
X return(log("couldn't seek to %ld in mail file!",
X reply_table[person].mailsize));
X
X while (get_return(mailfile, person, from_whom, subject, &sendit) != -1)
X if (sendit)
X reply_to_mail(person, from_whom, subject);
X
X return;
X}
X
Xint
Xget_return(file, person, from, subject, sendit)
XFILE *file;
Xint person, *sendit;
Xchar *from, *subject;
X{
X /** Reads the new message and return the from and subject lines.
X sendit is set to true iff it isn't a machine generated msg
X **/
X
X char name1[SLEN], name2[SLEN], lastname[SLEN];
X char buffer[SLEN], hold_return[NLEN];
X int done = 0, in_header = 0;
X
X from[0] = '\0';
X name1[0] = '\0';
X name2[0] = '\0';
X lastname[0] = '\0';
X *sendit = 1;
X
X while (! done) {
X
X if (fgets(buffer, SLEN, file) == NULL)
X return(-1);
X
X if (first_word(buffer, "From ")) {
X in_header++;
X sscanf(buffer, "%*s %s", hold_return);
X }
X else if (in_header) {
X if (first_word(buffer, ">From")) {
X sscanf(buffer,"%*s %s %*s %*s %*s %*s %*s %*s %*s %s", name1, name2);
X add_site(from, name2, lastname);
X }
X else if (first_word(buffer,"Subject:")) {
X remove_return(buffer);
X strcpy(subject, (char *) (buffer + 8));
X }
X else if (first_word(buffer,"X-Mailer: fastmail"))
X *sendit = 0;
X else if (strlen(buffer) == 1)
X done = 1;
X }
X }
X
X if (from[0] == '\0')
X strcpy(from, hold_return); /* default address! */
X else
X add_site(from, name1, lastname); /* get the user name too! */
X
X return(0);
X}
X
Xadd_site(buffer, site, lastsite)
Xchar *buffer, *site, *lastsite;
X{
X /** add site to buffer, unless site is 'uucp', or the same as
X lastsite. If not, set lastsite to site.
X **/
X
X char local_buffer[SLEN], *strip_parens();
X
X if (strcmp(site, "uucp") != 0)
X if (strcmp(site, lastsite) != 0) {
X if (buffer[0] == '\0')
X strcpy(buffer, strip_parens(site)); /* first in list! */
X else {
X sprintf(local_buffer,"%s!%s", buffer, strip_parens(site));
X strcpy(buffer, local_buffer);
X }
X strcpy(lastsite, strip_parens(site)); /* don't want THIS twice! */
SHAR_EOF
echo "End of part 22"
echo "File utils/arepdaem.c is continued in part 23"
echo "23" > s2_seq_.tmp
exit 0
--
Please send comp.sources.unix-related mail to rsalz at uunet.uu.net.
More information about the Comp.sources.unix
mailing list