syd@dsinc.UUCP (Syd Weinstein) (12/14/88)
---- Cut Here and unpack ---- #!/bin/sh # this is part 20 of a multipart archive # do not concatenate these parts, unpack them in order with /bin/sh # file utils/Makefile.mt continued # CurArch=20 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 utils/Makefile.mt" sed 's/^X//' << 'SHAR_EOF' >> utils/Makefile.mt X -o ../bin/fastmail X X../bin/readmsg: readmsg.c ../src/getopt.o ../src/opt_utils.o ../src/string2.o X ${CC} ${CFLAGS} ${DEFINE} readmsg.c ../src/getopt.o ../src/string2.o \ X ../src/opt_utils.o -o ../bin/readmsg X X../bin/arepdaemon: arepdaem.c X ${CC} ${CFLAGS} ${DEFINE} arepdaem.c -o ../bin/arepdaemon X X../bin/autoreply: autoreply.c ../src/opt_utils.o X ${CC} ${CFLAGS} ${DEFINE} autoreply.c ../src/opt_utils.o \ X -o ../bin/autoreply X X../bin/printmail: Makefile X @echo ': Use /bin/sh' > ../bin/printmail X @echo '# printmail: part of the Elm mail system' >> ../bin/printmail X @echo ' ' >> ../bin/printmail X @echo 'if [ "$$1" = "-p" ]; then' >> ../bin/printmail X @echo ' flags="-p";shift' >> ../bin/printmail X @echo 'fi' >> ../bin/printmail X @echo ' ' >> ../bin/printmail X @echo 'if [ "$$1" != "" ]; then' >> ../bin/printmail X @echo ' if [ ! -r $$1 ]; then' >> ../bin/printmail X @echo ' echo printmail: cannot open folder $$1' >> ../bin/printmail X @echo ' exit 1' >> ../bin/printmail X @echo ' else' >> ../bin/printmail X @echo ' flags="$$flags -f $$1"'>> ../bin/printmail X @echo ' fi' >> ../bin/printmail X @echo 'fi' >> ../bin/printmail X @echo ' ' >> ../bin/printmail X @echo '# and now invoke readmsg' >> ../bin/printmail X @echo 'exec readmsg $$flags \\*' >> ../bin/printmail X @chmod +x ../bin/printmail X X../bin/checkalias: Makefile X @echo ': Use /bin/sh' > ../bin/checkalias X @echo '# checkalias: part of the Elm mail system' >> ../bin/checkalias X @echo ' ' >> ../bin/checkalias X @echo 'if [ "$$*" = "" ]; then' >> ../bin/checkalias X @echo ' echo Usage: checkalias alias \[alias ...\]' >> \ X ../bin/checkalias X @echo ' exit 1' >> ../bin/checkalias X @echo 'fi' >> ../bin/checkalias X @echo ' ' >> ../bin/checkalias X @echo 'exec elm -c $$*' >> ../bin/checkalias X @chmod +x ../bin/checkalias X X../bin/messages: Makefile X @echo ': Use /bin/sh' > ../bin/messages X @echo '# messages: part of the Elm mail system' >> ../bin/messages X @echo ' ' >> ../bin/messages X @echo 'if [ "$$2" != "" ]; then' >> ../bin/messages X @echo ' echo Usage: messages \{folder-name\}' >> ../bin/messages X @echo ' exit 1' >> ../bin/messages X @echo 'fi' >> ../bin/messages X @echo ' ' >> ../bin/messages X @echo 'if [ "$$1" = "" ]; then' >> ../bin/messages X @echo ' fname=$$MAIL' >> ../bin/messages X @echo ' optional="in your mailbox"' >> ../bin/messages X @echo 'else' >> ../bin/messages X @echo ' fname=$$1' >> ../bin/messages X @echo ' optional="in folder $$1"' >> ../bin/messages X @echo 'fi' >> ../bin/messages X @echo ' ' >> ../bin/messages X @echo 'if [ -f $$fname ]; then' >> ../bin/messages X @echo ' mcount=`egrep "^From " $$fname | wc -l`' >> ../bin/messages X @echo 'else' >> ../bin/messages X @echo ' exit 0' >> ../bin/messages X @echo 'fi' >> ../bin/messages X @echo ' ' >> ../bin/messages X @echo 'if [ $$mcount = 1 ];then' >> ../bin/messages X @echo ' echo There is $$mcount message $$optional' >> ../bin/messages X @echo 'else' >> ../bin/messages X @echo ' echo There are $$mcount messages $$optional' >> ../bin/messages X @echo 'fi' >> ../bin/messages X @echo ' ' >> ../bin/messages X @echo 'exit $$mcount' >> ../bin/messages X @chmod +x ../bin/messages X X../src/validname.o: ../src/validname.c ../hdrs/defs.h X @(cd ../src; ${CC} -c ${CFLAGS} ${DEFINE} validname.c; cd ../utils) X X../src/opt_utils.o: ../src/opt_utils.c ../hdrs/defs.h X @(cd ../src; ${CC} -c ${CFLAGS} ${DEFINE} opt_utils.c; cd ../utils) X X../src/getopt.o: ../src/getopt.c ../hdrs/defs.h X @(cd ../src; ${CC} -c ${CFLAGS} ${DEFINE} getopt.c; cd ../utils) X X../src/string2.o: ../src/string2.c ../hdrs/defs.h X @(cd ../src; ${CC} -c ${CFLAGS} ${DEFINE} string2.c; cd ../utils) X Xexpand.o: expand.c ../hdrs/defs.h X ${CC} -c ${CFLAGS} ${DEFINE} expand.c X Xclean: X ${RM} *.o ${OBJS} ../bin/utils X Xlint: X lint -p -I../hdrs *.c > LINT.OUT SHAR_EOF echo "File utils/Makefile.mt is complete" chmod 0444 utils/Makefile.mt || echo "restore of utils/Makefile.mt 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.1 88/09/15 21:07:24 syd Exp $"; X X/******************************************************************************* X * The Elm Mail System - $Revision: 2.1 $ $State: Exp $ X * X * Copyright (c) 1986 Dave Taylor X ******************************************************************************* X * Bug reports, patches, comments, suggetions should be sent to: X * X * Eric D. Christensen - edc@altnet.ALTOS.COM X * uunet!altnet!edc X * X ******************************************************************************* X * $Log: answer.c,v $ X * Revision 2.1 88/09/15 21:07:24 syd X * checked in with -k by syd at 88.09.15.21.07.24. X * X * 88/08/27 David Klann <gatech!uwvax.cs.wisc.edu!m5r3!davek> X * fix path name to current path X * X * Revision 2.1 88/07/21 10:00:54 edc X * Final hacks and cleanup to the 2.1 alpha test release X * X * Revision 2.0 88/06/27 16:53:43 edc X * The original 2.0 gamma sources as leaked from HP X * 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]; 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 (gets(user_name) == NULL || user_name[0] == '\0') X goto prompt; 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 = (gets(buffer, SLEN) == NULL))) X fprintf(fd, "%s\n", buffer); X } while (! eof && strlen(buffer) > 0); 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, 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.1 88/09/15 21:07:25 syd Exp $"; X X/******************************************************************************* X * The Elm Mail System - $Revision: 2.1 $ $State: Exp $ X * X * Copyright (c) 1986 Dave Taylor X ******************************************************************************* X * Bug reports, patches, comments, suggetions should be sent to: X * X * Eric D. Christensen - edc@altnet.ALTOS.COM X * uunet!altnet!edc X * X ******************************************************************************* X * $Log: arepdaem.c,v $ X * Revision 2.1 88/09/15 21:07:25 syd X * checked in with -k by syd at 88.09.15.21.07.25. X * X * Revision 2.1 88/07/21 10:01:21 edc X * Final hacks and cleanup to the 2.1 alpha test release X * X * Revision 2.0 88/06/27 16:54:02 edc X * The original 2.0 gamma sources as leaked from HP X * 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 (C) 1985, Dave Taylor, HP Colorado Networks Operation X**/ X X#include <stdio.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 X#include "defs.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, "/usr/mail/%s", 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 index; X X for (index = 0; index < active; index++) X if (strcmp(name, reply_table[index].username) == 0) X return(index); 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[LONG_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[LONG_SLEN], hold_return[NLEN]; X int done = 0, in_header = 0; X X from[0] = '\0'; X *sendit = 1; X X while (! done) { X X if (fgets(buffer, LONG_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[LONG_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! */ X } X} X Xremove_first_word(string) Xchar *string; X{ /** removes first word of string, ie up to first non-white space X following a white space! **/ X X register int loc; X X for (loc = 0; string[loc] != ' ' && string[loc] != '\0'; loc++) X ; X X while (string[loc] == ' ' || string[loc] == '\t') X loc++; X X move_left(string, loc); X} X Xmove_left(string, chars) Xchar string[]; Xint chars; X{ X /** moves string chars characters to the left DESTRUCTIVELY **/ X X register int i; X X chars--; /* index starting at zero! */ X X for (i=chars; string[i] != '\0' && string[i] != '\n'; i++) X string[i-chars] = string[i]; X X string[i-chars] = '\0'; X} X Xreply_to_mail(person, from, subject) Xint person; Xchar *from, *subject; X{ X /** Respond to the message from the specified person with the X specified subject... **/ X X char buffer[SLEN]; X X if (strlen(subject) == 0) X strcpy(subject, "Auto-reply Mail"); X else if (! first_word(subject,"Auto-reply")) { X sprintf(buffer, "Auto-reply to:%s", subject); X strcpy(subject, buffer); X } X X log("auto-replying to '%s'", from); X X mail(from, subject, reply_table[person].replyfile, person); X} X Xreverse(string) Xchar *string; X{ X /** reverse string... pretty trivial routine, actually! **/ X X char buffer[SLEN]; X register int i, j = 0; X X for (i = strlen(string)-1; i >= 0; i--) X buffer[j++] = string[i]; X X buffer[j] = '\0'; X X strcpy(string, buffer); X} X Xlong Xbytes(name) Xchar *name; X{ X /** return the number of bytes in the specified file. This X is to check to see if new mail has arrived.... **/ X X int ok = 1; X extern int errno; /* system error number! */ X struct stat buffer; X X if (stat(name, &buffer) != 0) X if (errno != 2) { X unlock(); X exit(fprintf(stderr,"Error %d attempting fstat on %s", errno, name)); X } X else X ok = 0; X X return(ok ? buffer.st_size : 0); X} X Xmail(to, subject, filename, person) Xchar *to, *subject, *filename; Xint person; X{ X /** Mail 'file' to the user from person... **/ X X char buffer[VERY_LONG_STRING]; X X sprintf(buffer, "%s -f '%s [autoreply]' -s '%s' %s %s", X fastmail, reply_table[person].username, X subject, filename, to); X X system(buffer); X} X Xlog(message, arg) Xchar *message; Xchar *arg; X{ X /** Put log entry into log file. Use the format: X date-time: <message> X **/ X X struct tm *localtime(), *thetime; X long time(), clock; X char buffer[SLEN]; X X /** first off, get the time and date **/ X X clock = time((long *) 0); /* seconds since ??? */ X thetime = localtime(&clock); /* and NOW the time... */ X X /** then put the message out! **/ X X sprintf(buffer, message, arg); X X fprintf(logfd,"%d/%d-%d:%02d: %s\n", X thetime->tm_mon+1, thetime->tm_mday, X thetime->tm_hour, thetime->tm_min, X buffer); X} X XFILE *open_logfile() X{ X /** open the logfile. returns a valid file descriptor **/ X X FILE *fd; X X if ((fd = fopen(logfile, "a")) == 0) X if ((fd = fopen(logfile2, "a")) == 0) { X unlock(); X exit(1); /* give up! */ X } X X return( (FILE *) fd); X} X Xclose_logfile() X{ X /** Close the logfile until needed again. **/ X X fclose(logfd); 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_SLEN]; 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} X X/*** LOCK and UNLOCK - ensure only one copy of this daemon running at any X given time by using a file existance semaphore (wonderful stuff!) ***/ X Xlock() X{ X /** Try to create the lock file. If it's there, or we can't X create it for some stupid reason, return zero, otherwise, X a non-zero return code indicates success in locking this X process in. **/ X X if (access(arep_lock_file, EXISTS) == 0) X return(0); /* file already exists!! */ X X if (creat(arep_lock_file, MODE) == -1) X return(0); /* can't create file!! */ X X return(1); X} X Xunlock() X{ X /** remove lock file if it's there! **/ X X (void) unlink(arep_lock_file); X} SHAR_EOF chmod 0444 utils/arepdaem.c || echo "restore of utils/arepdaem.c fails" echo "x - extracting utils/autoreply.c (Text)" sed 's/^X//' << 'SHAR_EOF' > utils/autoreply.c && X Xstatic char rcsid[] = "@(#)$Id: autoreply.c,v 2.1 88/09/15 21:07:27 syd Exp $"; X X/******************************************************************************* X * The Elm Mail System - $Revision: 2.1 $ $State: Exp $ X * X * Copyright (c) 1986 Dave Taylor X ******************************************************************************* X * Bug reports, patches, comments, suggetions should be sent to: X * X * Eric D. Christensen - edc@altnet.ALTOS.COM X * uunet!altnet!edc X * X ******************************************************************************* X * $Log: autoreply.c,v $ X * Revision 2.1 88/09/15 21:07:27 syd X * checked in with -k by syd at 88.09.15.21.07.27. X * X * Revision 2.1 88/07/21 10:01:25 edc X * Final hacks and cleanup to the 2.1 alpha test release X * X * Revision 2.0 88/06/27 16:54:05 edc X * The original 2.0 gamma sources as leaked from HP X * X * X * X ******************************************************************************/ X X/** This is the front-end for the autoreply system, and performs two X functions: it either adds the user to the list of people using the X autoreply function (starting the daemon if no-one else) or removes X a user from the list of people. X X Usage: autoreply filename X autoreply "off" X or autoreply [to find current status] X X**/ X X#include <stdio.h> X#include <errno.h> X#include <sys/types.h> X#include <sys/stat.h> X X#include "defs.h" X Xstatic char ident[] = { WHAT_STRING }; X X#define tempdir "/tmp/arep" /* file prefix */ X#define autoreply_file "/etc/autoreply.data" /* autoreply data file */ X Xextern int errno; /* system error code */ Xchar username[NLEN]; /* login name of user */ X Xmain(argc, argv) Xint argc; Xchar *argv[]; X{ X char filename[SLEN]; X X if (argc > 2) { X printf("Usage: %s <filename>\tto start autoreply,\n", argv[0]); X printf(" %s off\t\tto turn off autoreply\n", argv[0]); X printf(" or %s \t\tto check current status\n", argv[0]); X exit(1); X } X X (void) cuserid(username); X X if (argc == 1 || strcmp(argv[1], "off") == 0) X remove_user((argc == 1)); X else { X strcpy(filename, argv[1]); X if (access(filename,READ_ACCESS) != 0) { X printf("Error: Can't read file '%s'\n", filename); X exit(1); X } X X if (filename[0] != '/') /* prefix home directory */ X sprintf(filename,"%s/%s", getenv("HOME"), argv[1]); X X add_user(filename); X } X X exit(0); X} X Xremove_user(stat_only) Xint stat_only; X{ X /** Remove the user from the list of currently active autoreply X people. If 'stat_only' is set, then just list the name of X the file being used to autoreply with, if any. **/ X X FILE *temp, *repfile; X char tempfile[SLEN], user[SLEN], filename[SLEN]; X int c, copied = 0, found = 0; X long filesize, bytes(); X X if (! stat_only) { X sprintf(tempfile, "%s.%06d", tempdir, getpid()); X X if ((temp = fopen(tempfile, "w")) == NULL) { X printf("Error: couldn't open tempfile '%s'. Not removed\n", X tempfile); X exit(1); X } X } X X if ((repfile = fopen(autoreply_file, "r")) == NULL) { X if (stat_only) { X printf("You're not currently autoreplying to mail.\n"); X exit(0); X } X printf("No-one is autoreplying to their mail!\n"); X exit(0); X } X X /** copy out of real replyfile... **/ X X while (fscanf(repfile, "%s %s %ld", user, filename, &filesize) != EOF) X X if (strcmp(user, username) != 0) { X if (! stat_only) { X copied++; X fprintf(temp, "%s %s %ld\n", user, filename, filesize); X } X } X else { X if (stat_only) { X printf("You're currently autoreplying to mail with the file %s\n", filename); X exit(0); X } X found++; X } X X fclose(temp); X fclose(repfile); X X if (! found) { X printf("You're not currently autoreplying to mail%s\n", X stat_only? "." : "!"); X if (! stat_only) X unlink(tempfile); X exit(! stat_only); X } X X /** now copy tempfile back into replyfile **/ X X if (copied == 0) { /* removed the only person! */ X unlink(autoreply_file); X } X else { /* save everyone else */ X X if ((temp = fopen(tempfile,"r")) == NULL) { X printf("Error: couldn't reopen tempfile '%s'. Not removed.\n", X tempfile); X unlink(tempfile); X exit(1); X } X X if ((repfile = fopen(autoreply_file, "w")) == NULL) { X printf( X "Error: couldn't reopen autoreply file for writing! Not removed.\n"); X unlink(tempfile); X exit(1); X } X X while ((c = getc(temp)) != EOF) X putc(c, repfile); X X fclose(temp); X fclose(repfile); X X } X unlink(tempfile); X X if (found > 1) X printf("Warning: your username appeared %d times!! Removed all\n", X found); X else X printf("You've been removed from the autoreply table.\n"); X} X Xadd_user(filename) Xchar *filename; X{ X /** add the user to the autoreply file... **/ X X FILE *repfile; X char mailfile[SLEN]; X long bytes(); X X if ((repfile = fopen(autoreply_file, "a")) == NULL) { X printf("Error: couldn't open the autoreply file! Not added\n"); X exit(1); X } X X sprintf(mailfile,"%s/%s", mailhome, username); X X fprintf(repfile,"%s %s %ld\n", username, filename, bytes(mailfile)); X X fclose(repfile); X X printf("You've been added to the autoreply system.\n"); X} X X Xlong Xbytes(name) Xchar *name; X{ X /** return the number of bytes in the specified file. This X is to check to see if new mail has arrived.... **/ X X int ok = 1; X extern int errno; /* system error number! */ X struct stat buffer; X X if (stat(name, &buffer) != 0) X if (errno != 2) X exit(fprintf(stderr,"Error %d attempting fstat on %s", errno, name)); X else X ok = 0; X X return(ok ? buffer.st_size : 0L); X} SHAR_EOF chmod 0444 utils/autoreply.c || echo "restore of utils/autoreply.c fails" echo "x - extracting utils/expand.c (Text)" sed 's/^X//' << 'SHAR_EOF' > utils/expand.c && X Xstatic char rcsid[] = "@(#)$Id: expand.c,v 2.1 88/09/15 21:07:28 syd Exp $"; X X/******************************************************************************* X * The Elm Mail System - $Revision: 2.1 $ $State: Exp $ X * X * Copyright (c) 1986, 1987 Dave Taylor X ******************************************************************************* X * Bug reports, patches, comments, suggetions should be sent to: X * X * Eric D. Christensen - edc@altnet.ALTOS.COM X * uunet!altnet!edc X * X ******************************************************************************* X * $Log: expand.c,v $ X * Revision 2.1 88/09/15 21:07:28 syd X * checked in with -k by syd at 88.09.15.21.07.28. X * X * Revision 2.1 88/07/21 10:01:27 edc X * Final hacks and cleanup to the 2.1 alpha test release X * X * Revision 2.0 88/06/27 16:54:06 edc X * The original 2.0 gamma sources as leaked from HP X * X * X * X ******************************************************************************/ X X/** This is a library routine for the various utilities that allows X users to have the standard 'Elm' folder directory nomenclature X for all filenames (e.g. '+', '=' or '%'). It should be compiled X and then linked in as needed. X X**/ X X#include <stdio.h> X#include "defs.h" X Xchar *expand_define(); X Xint Xexpand(filename) Xchar *filename; X{ X /** Expand the filename since the first character is a meta- X character that should expand to the "maildir" variable X in the users ".elmrc" file... X X Note: this is a brute force way of getting the entry out X of the .elmrc file, and isn't recommended for the faint X of heart! X **/ X X FILE *rcfile; X char buffer[SLEN], *expanded_dir, *home, *getenv(), *bufptr; X int foundit = 0; X X bufptr = (char *) buffer; /* same address */ X X if ((home = getenv("HOME")) == NULL) { X printf( X "Can't expand environment variable $HOME to find .elmrc file!\n"); X exit(1); X } X X sprintf(buffer, "%s/%s", home, elmrcfile); X X if ((rcfile = fopen(buffer, "r")) == NULL) { X printf("Can't open your \".elmrc\" file (%s) for reading!\n", X buffer); X exit(1); X } X X while (fgets(buffer, SLEN, rcfile) != NULL && ! foundit) { X if (strncmp(buffer, "maildir", 7) == 0 || X strncmp(buffer, "folders", 7) == 0) { X while (*bufptr != '=' && *bufptr) X bufptr++; X bufptr++; /* skip the equals sign */ X while (whitespace(*bufptr) && *bufptr) X bufptr++; X home = bufptr; /* remember this address */ X X while (! whitespace(*bufptr) && *bufptr != '\n') X bufptr++; X X *bufptr = '\0'; /* remove trailing space */ X foundit++; X } X } X X fclose(rcfile); /* be nice... */ X X if (! foundit) { X printf("Couldn't find \"maildir\" in your .elmrc file!\n"); X exit(1); X } X X /** Home now points to the string containing your maildir, with X no leading or trailing white space... X **/ X X expanded_dir = expand_define(home); X X sprintf(buffer, "%s%s%s", expanded_dir, X (expanded_dir[strlen(expanded_dir)-1] == '/' || X filename[0] == '/') ? "" : "/", (char *) filename+1); X X strcpy(filename, buffer); X} X Xchar *expand_define(maildir) Xchar *maildir; X{ X /** This routine expands any occurances of "~" or "$var" in X the users definition of their maildir directory out of X their .elmrc file. X X Again, another routine not for the weak of heart or staunch X of will! X **/ X X static char buffer[SLEN]; /* static buffer AIEE!! */ X char name[SLEN], /* dynamic buffer!! (?) */ X *nameptr, /* pointer to name?? */ X *value; /* char pointer for munging */ X X if (*maildir == '~') X sprintf(buffer, "%s%s", getenv("HOME"), ++maildir); X else if (*maildir == '$') { /* shell variable */ X X /** break it into a single word - the variable name **/ X X strcpy(name, (char *) maildir + 1); /* hurl the '$' */ X nameptr = (char *) name; X while (*nameptr != '/' && *nameptr) nameptr++; X *nameptr = '\0'; /* null terminate */ X X /** got word "name" for expansion **/ X X if ((value = getenv(name)) == NULL) { X printf("Couldn't expand shell variable $%s in .elmrc!\n", name); X exit(1); X } X sprintf(buffer, "%s%s", value, maildir + strlen(name) + 1); X } X else strcpy(buffer, maildir); X X return( ( char *) buffer); X} SHAR_EOF chmod 0444 utils/expand.c || echo "restore of utils/expand.c fails" echo "x - extracting utils/fastmail.c (Text)" sed 's/^X//' << 'SHAR_EOF' > utils/fastmail.c && X Xstatic char rcsid[] = "@(#)$Id: fastmail.c,v 2.1 88/09/15 21:07:29 syd Exp $"; X X/******************************************************************************* X * The Elm Mail System - $Revision: 2.1 $ $State: Exp $ X * X * Copyright (c) 1986 Dave Taylor X ******************************************************************************* X * Bug reports, patches, comments, suggetions should be sent to: X * X * Eric D. Christensen - edc@altnet.ALTOS.COM X * uunet!altnet!edc X * X ******************************************************************************* X * $Log: fastmail.c,v $ X * Revision 2.1 88/09/15 21:07:29 syd X * checked in with -k by syd at 88.09.15.21.07.29. X * X * 88/09/08 Rob Bernardo <rob@pbhyf.PacBell.COM> X * Remove comma seperation from list of addresses X * Remove single quotes from command. X * X * Revision 2.1 88/07/21 10:01:29 edc X * Final hacks and cleanup to the 2.1 alpha test release X * X * Revision 2.0 88/06/27 16:54:06 edc X * The original 2.0 gamma sources as leaked from HP X * X * X * X ******************************************************************************/ X X/** This program is specifically written for group mailing lists and X such batch type mail processing. It does NOT use aliases at all, X it does NOT read the /etc/password file to find the From: name X of the user and does NOT expand any addresses. It is meant X purely as a front-end for either /bin/mail or /usr/lib/sendmail X (according to what is available on the current system). X X **** This program should be used with CAUTION ***** X X**/ X X/** The calling sequence for this program is: X X fastmail {args} filename full-email-address X X where args could be any (or all) of; X X -b bcc-list (Blind carbon copies to) X -c cc-list (carbon copies to) X -d (debug on) X -f from (from name) X -F from-addr (the actual address to be put in the From: line) X -r reply-to-address (Reply-To:) X -s subject (subject of message) X**/ X X#include <stdio.h> X X#ifdef BSD X# ifdef BSD4.1 X# include <time.h> X# include <sys/types.h> X# include <sys/timeb.h> X# else X# include <sys/time.h> X# endif X#else X# include <time.h> X#endif X X#include "defs.h" X Xstatic char ident[] = { WHAT_STRING }; X X#define binrmail "/bin/rmail" X#define temphome "/tmp/fastmail." X X#define DONE 0 X#define ERROR -1 X Xchar *optional_arg; /* optional argument as we go */ Xint opt_index; /* argnum + 1 when we leave */ X Xchar *arpa_dayname[] = { "Sun", "Mon", "Tue", "Wed", "Thu", X "Fri", "Sat", "" }; X Xchar *arpa_monname[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", X "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", ""}; X Xchar *get_arpa_date(); X X#ifdef BSD X char *timezone(); X#else X extern char *tzname[]; X#endif X Xmain(argc, argv) Xint argc; Xchar *argv[]; X{ X X FILE *tempfile; X char hostname[NLEN], username[NLEN], from_string[SLEN], subject[SLEN]; X char filename[SLEN], tempfilename[SLEN], command_buffer[256]; X char replyto[SLEN], cc_list[SLEN], bcc_list[SLEN], to_list[SLEN]; X char from_addr[SLEN]; X int c, sendmail_available, debug = 0; X X replyto[0] = '\0'; X cc_list[0] = '\0'; X bcc_list[0] = '\0'; X from_addr[0] = '\0'; X X while ((c = get_options(argc, argv, "b:c:df:F:r:s:")) > 0) { X switch (c) { X case 'b' : strcpy(bcc_list, optional_arg); break; X case 'c' : strcpy(cc_list, optional_arg); break; X case 'd' : debug++; break; X case 'f' : strcpy(from_string, optional_arg); break; X case 'F' : strcpy(from_addr, optional_arg); break; X case 'r' : strcpy(replyto, optional_arg); break; X case 's' : strcpy(subject, optional_arg); break; X } X } X X if (c == ERROR) { X fprintf(stderr,"Usage: fastmail {args} filename address(es)\n"); X fprintf(stderr, " where {args} can be;\n"); X fprintf(stderr,"\t-b bcc-list\n\t-c cc-list\n\t-d\n\t-f from-name\n"); X fprintf(stderr,"\t-F from-addr\n"); X fprintf(stderr, "\t-r reply-to\n\t-s subject\n\n"); X exit(1); X } X X if (opt_index > argc) { X fprintf(stderr,"Usage: fastmail {args} filename address(es)\n"); X fprintf(stderr, " where {args} can be;\n"); X fprintf(stderr,"\t-b bcc-list\n\t-c cc-list\n\t-d\n\t-f from-name\n"); X fprintf(stderr,"\t-F from-addr\n"); X fprintf(stderr, "\t-r reply-to\n\t-s subject\n\n"); X exit(1); X } X X strcpy(filename, argv[opt_index++]); X X if (opt_index > argc) { X fprintf(stderr,"Usage: fastmail {args} filename address(es)\n"); X fprintf(stderr, " where {args} can be;\n"); X fprintf(stderr,"\t-b bcc-list\n\t-c cc-list\n\t-d\n\t-f from-name\n"); X fprintf(stderr,"\t-F from-addr\n"); X fprintf(stderr,"\t-r reply-to\n\t-s subject\n\n"); X exit(1); X } X X gethostname(hostname, sizeof(hostname)); X X strcpy(username, getlogin()); X X if (strlen(username) == 0) X cuserid(username); X X if (access(filename, READ_ACCESS) == -1) X exit(fprintf(stderr, "Error: can't find file %s!\n", filename)); X X sprintf(tempfilename, "%s%d", temphome, getpid()); X X if ((tempfile = fopen(tempfilename, "w")) == NULL) X exit(fprintf(stderr, "Couldn't open temp file %s\n", tempfilename)); X X if (strlen(from_string) > 0) X if (strlen(from_addr) > 0) X fprintf(tempfile, "From: %s (%s)\n", from_addr, from_string); X else X fprintf(tempfile, "From: %s!%s (%s)\n", hostname, username, X from_string); X else X if (strlen(from_addr) > 0) X fprintf(tempfile, "From: %s\n", from_addr); X else X fprintf(tempfile, "From: %s!%s\n", hostname, username); X X fprintf(tempfile, "Date: %s\n", get_arpa_date()); X X if (strlen(subject) > 0) X fprintf(tempfile, "Subject: %s\n", subject); X X if (strlen(replyto) > 0) X fprintf(tempfile, "Reply-To: %s\n", replyto); X X while (opt_index < argc) X sprintf(to_list, "%s%s%s", to_list, (strlen(to_list) > 0? " ":""), X argv[opt_index++]); X X fprintf(tempfile, "To: %s\n", to_list); X X if (strlen(cc_list) > 0) X fprintf(tempfile, "Cc: %s\n", cc_list); X X if (strlen(bcc_list) > 0) X fprintf(tempfile, "Bcc: %s\n", bcc_list); /* trust xport */ X X fprintf(tempfile, "X-Mailer: fastmail [version %s]\n", VERSION); X fprintf(tempfile, "\n"); X X fclose(tempfile); X X /** now we'll cat both files to /bin/rmail or sendmail... **/ X X sendmail_available = (access(sendmail, EXECUTE_ACCESS) != -1); X X printf("Mailing to %s%s%s%s%s [via %s]\n", to_list, X (strlen(cc_list) > 0 ? " ":""), cc_list, X (strlen(bcc_list) > 0 ? " ":""), bcc_list, X sendmail_available? "sendmail" : "rmail"); X X sprintf(command_buffer, "cat %s %s | %s %s %s %s", X tempfilename, filename, X sendmail_available? sendmail : mailer, X to_list, cc_list, bcc_list); X X if (debug) X printf("%s\n", command_buffer); X X system(command_buffer); X X unlink(tempfilename); X} X X Xchar *get_arpa_date() X{ X /** returns an ARPA standard date. The format for the date X according to DARPA document RFC-822 is exemplified by; X X Mon, 12 Aug 85 6:29:08 MST X X **/ X X static char buffer[SLEN]; /* static character buffer */ X struct tm *the_time, /* Time structure, see CTIME(3C) */ X *localtime(); X long junk; /* time in seconds.... */ X#ifdef BSD X# ifdef BSD4.1 X struct timeb loc_time; /* of course this is different! */ X# else X struct timeval time_val; X struct timezone time_zone; X# endif X#endif X X#ifdef BSD X# ifdef BSD4.1 X junk = (long) time((long *) 0); X ftime(&loc_time); X# else X gettimeofday(&time_val, &time_zone); X junk = time_val.tv_sec; X# endif X#else X junk = time(0); /* this must be here for it to work! */ X#endif X the_time = localtime(&junk); X X sprintf(buffer, "%s, %d %s %d %d:%02d:%02d %s", X arpa_dayname[the_time->tm_wday], X the_time->tm_mday % 32, X arpa_monname[the_time->tm_mon], X the_time->tm_year % 100, X the_time->tm_hour % 24, X the_time->tm_min % 61, X the_time->tm_sec % 61, X#ifdef BSD X# ifdef BSD4.1 X timezone(loc_time.time_zone, the_time->tz_isdst)); X# else X timezone(time_zone.tz_minuteswest, time_zone.tz_dsttime)); X# endif X#else X tzname[the_time->tm_isdst]); X#endif X X return( (char *) buffer); X} X X/** Starting argument parsing routine. X X Called as "get_options(argc, argv, options)" where options is a string X of the form "abc:d" indicating that 'a' 'b' and 'd' are flags and X 'c' is a flag with a trailing argument. Optional arguments are X returned in the external char * variable "optional_arg", and the X external int "opt_index" is set to the first entry in the argv list X that wasn't processed (ie after the flags). X X For example, the C compiler would have something of the form X getopt(argc, argv, "Oo:l:") to allow "cc -O -o output -l lib file.c" X X (C) Copyright 1986, Dave Taylor X**/ X Xint _indx = 1, _argnum = 1; X Xint Xget_options(argc, argv, options) SHAR_EOF echo "End of part 20" echo "File utils/fastmail.c is continued in part 21" echo "21" > s2_seq_.tmp exit 0 -- ===================================================================== Sydney S. Weinstein, CDP, CCP Elm Coordinator Datacomp Systems, Inc. Voice: (215) 947-9900 {allegra,bellcore,bpa,vu-vlsi}!dsinc!syd FAX: (215) 938-0235