home *** CD-ROM | disk | FTP | other *** search
- Subject: v06i038: Elm mail system (elm), Part13/14
- Newsgroups: mod.sources
- Approved: rs@mirror.UUCP
-
- Submitted by: Dave Taylor <pyramid!hplabs!hpldat!taylor>
- Mod.sources: Volume 6, Issue 38
- Archive-name: elm/Part13
-
- # Continuation of Shell Archive, created by hpldat!taylor
-
- # This is part 13
-
- # To unpack the enclosed files, please use this file as input to the
- # Bourne (sh) shell. This can be most easily done by the command;
- # sh < thisfilename
-
-
- if [ ! -d utils ]
- then
- echo creating directory utils
- mkdir utils
- fi
-
- # ---------- file utils/arepdaemon.c ----------
-
- filename="utils/arepdaemon.c"
-
- if [ -f $filename ]
- then
- echo File \"$filename\" already exists\! Skipping...
- filename=/dev/null # throw it away
- else
- echo extracting file utils/arepdaemon.c...
- fi
-
- cat << 'END-OF-FILE' > $filename
- /** arepdaemon.c **/
-
- /** (C) Copyright 1986 Dave Taylor **/
-
- /** Keep track of mail as it arrives, and respond by sending a 'recording'
- file to the sender as new mail is received.
-
- Note: the user program that interacts with this program is the
- 'autoreply' program and that should be consulted for further
- usage information.
-
- This program is part of the 'autoreply' system, and is designed
- to run every hour and check all mailboxes listed in the file
- "/etc/autoreply.data", where the data is in the form:
-
- username replyfile current-mailfile-size
-
- To avoid a flood of autoreplies, this program will NOT reply to mail
- that contains header "X-Mailer: fastmail". Further, each time the
- program responds to mail, the 'mailfile size' entry is updated in
- the file /etc/autoreply.data to allow the system to be brought
- down and rebooted without any loss of data or duplicate messages.
-
- This daemon also uses a lock semaphore file, /usr/spool/uucp/LCK..arep,
- to ensure that more than one copy of itself is never running. For this
- reason, it is recommended that this daemon be started up each morning
- from cron, since it will either start since it's needed or simply see
- that the file is there and disappear.
-
- Since this particular program is the main daemon answering any
- number of different users, it must be run with uid root.
-
- (C) 1985, Dave Taylor, HP Colorado Networks Operation
- **/
-
- #include <stdio.h>
- #include <time.h>
- #include <sys/types.h>
- #include <sys/stat.h>
-
- #include "defs.h"
-
- static char ident[] = { WHAT_STRING };
-
- #define arep_lock_file "/usr/spool/uucp/LCK..arep"
-
- #define autoreply_file "/etc/autoreply.data"
- #define fastmail "/usr/local/bin/fastmail"
-
- #define logfile "/etc/autoreply.log" /* first choice */
- #define logfile2 "/tmp/autoreply.log" /* second choice */
-
- #define BEGINNING 0 /* see fseek(3S) for info */
- #define SLEEP_TIME 3600 /* run once an hour */
- #define MAX_PEOPLE 20 /* max number in program */
-
- #define EXISTS 00 /* lock file exists?? */
- #define MODE 0777 /* lockfile creation mode */
-
- #define NLEN 20
-
- #define remove_return(s) if (strlen(s) > 0) { \
- if (s[strlen(s)-1] == '\n') \
- s[strlen(s)-1] = '\0'; \
- }
-
- struct replyrec {
- char username[NLEN]; /* login name of user */
- char mailfile[SLEN]; /* name of mail file */
- char replyfile[SLEN]; /* name of reply file */
- long mailsize; /* mail file size */
- int in_list; /* for new replies */
- } reply_table[MAX_PEOPLE];
-
- FILE *logfd; /* logfile (log action) */
- long autoreply_size = 0L; /* size of autoreply file */
- int active = 0; /* # of people 'enrolled' */
-
- FILE *open_logfile(); /* forward declaration */
-
- long bytes(); /* ditto */
-
- main()
- {
- long size;
- int person, data_changed;
-
- if (! lock())
- exit(0); /* already running! */
-
- while (1) {
-
- logfd = open_logfile(); /* open the log */
-
- /* 1. check to see if autoreply table has changed.. */
-
- if ((size = bytes(autoreply_file)) != autoreply_size) {
- read_autoreply_file();
- autoreply_size = size;
- }
-
- /* 2. now for each active person... */
-
- data_changed = 0;
-
- for (person = 0; person < active; person++) {
- if ((size = bytes(reply_table[person].mailfile)) !=
- reply_table[person].mailsize) {
- if (size > reply_table[person].mailsize)
- read_newmail(person);
- /* else mail removed - resync */
- reply_table[person].mailsize = size;
- data_changed++;
- }
- }
-
- /* 3. if data changed, update autoreply file */
-
- if (data_changed)
- update_autoreply_file();
-
- close_logfile(); /* close the logfile again */
-
- /* 4. Go to sleep... */
-
- sleep(SLEEP_TIME);
- }
- }
-
- int
- read_autoreply_file()
- {
- /** We're here because the autoreply file has changed size!! It
- could either be because someone has been added or because
- someone has been removed...since the list will always be in
- order (nice, eh?) we should have a pretty easy time of it...
- **/
-
- FILE *file;
- char username[SLEN], replyfile[SLEN];
- int person;
- long size;
-
- log("Autoreply data file has changed! Reading...");
-
- if ((file = fopen(autoreply_file,"r")) == NULL) {
- log("No-one is using autoreply...");
- return(0);
- }
-
- for (person = 0; person < active; person++)
- reply_table[person].in_list = 0;
-
- while (fscanf(file, "%s %s %dl", username, replyfile, &size) != EOF) {
- /* check to see if this person is already in the list */
- if ((person = in_list(username)) != -1) {
- reply_table[person].in_list = 1;
- reply_table[person].mailsize = size; /* sync */
- }
- else { /* if not, add them */
- if (active == MAX_PEOPLE) {
- unlock();
- exit(log("Couldn't add %s - already at max people!",
- username));
- }
- log("adding %s to the active list", username);
- strcpy(reply_table[active].username, username);
- sprintf(reply_table[active].mailfile, "/usr/mail/%s", username);
- strcpy(reply_table[active].replyfile, replyfile);
- reply_table[active].mailsize = size;
- reply_table[active].in_list = 1; /* obviously! */
- active++;
- }
- }
-
- /** now check to see if anyone has been removed... **/
-
- for (person = 0; person < active; person++)
- if (reply_table[person].in_list == 0) {
- log("removing %s from the active list",
- reply_table[person].username);
- strcpy(reply_table[person].username,
- reply_table[active-1].username);
- strcpy(reply_table[person].mailfile,
- reply_table[active-1].mailfile);
- strcpy(reply_table[person].replyfile,
- reply_table[active-1].replyfile);
- reply_table[person].mailsize = reply_table[active-1].mailsize;
- active--;
- }
- }
-
- update_autoreply_file()
- {
- /** update the entries in the autoreply file... **/
-
- FILE *file;
- register int person;
-
- if ((file = fopen(autoreply_file,"w")) == NULL) {
- log("Couldn't update autoreply file!");
- return;
- }
-
- for (person = 0; person < active; person++)
- fprintf(file, "%s %s %ld\n",
- reply_table[person].username,
- reply_table[person].replyfile,
- reply_table[person].mailsize);
-
- fclose(file);
-
- printf("updated autoreply file\n");
- autoreply_size = bytes(autoreply_file);
- }
-
- int
- in_list(name)
- char *name;
- {
- /** search the current active reply list for the specified username.
- return the index if found, or '-1' if not. **/
-
- register int index;
-
- for (index = 0; index < active; index++)
- if (strcmp(name, reply_table[index].username) == 0)
- return(index);
-
- return(-1);
- }
-
- read_newmail(person)
- int person;
- {
- /** Read the new mail for the specified person. **/
-
-
- FILE *mailfile;
- char from_whom[LONG_SLEN], subject[SLEN];
- int sendit;
-
- log("New mail for %s", reply_table[person].username);
-
- if ((mailfile = fopen(reply_table[person].mailfile,"r")) == NULL)
- return(log("can't open mailfile for user %s",
- reply_table[person].username));
-
- if (fseek(mailfile, reply_table[person].mailsize, BEGINNING) == -1)
- return(log("couldn't seek to %ld in mail file!",
- reply_table[person].mailsize));
-
- while (get_return(mailfile, person, from_whom, subject, &sendit) != -1)
- if (sendit)
- reply_to_mail(person, from_whom, subject);
-
- return;
- }
-
- int
- get_return(file, person, from, subject, sendit)
- FILE *file;
- int person, *sendit;
- char *from, *subject;
- {
- /** Reads the new message and return the from and subject lines.
- sendit is set to true iff it isn't a machine generated msg
- **/
-
- char name1[SLEN], name2[SLEN], lastname[SLEN];
- char buffer[LONG_SLEN], hold_return[NLEN];
- int done = 0, in_header = 0;
-
- from[0] = '\0';
- *sendit = 1;
-
- while (! done) {
-
- if (fgets(buffer, LONG_SLEN, file) == NULL)
- return(-1);
-
- if (first_word(buffer, "From ")) {
- in_header++;
- sscanf(buffer, "%*s %s", hold_return);
- }
- else if (in_header) {
- if (first_word(buffer, ">From")) {
- sscanf(buffer,"%*s %s %*s %*s %*s %*s %*s %*s %*s %s", name1, name2);
- add_site(from, name2, lastname);
- }
- else if (first_word(buffer,"Subject:")) {
- remove_return(buffer);
- strcpy(subject, (char *) (buffer + 8));
- }
- else if (first_word(buffer,"X-Mailer: fastmail"))
- *sendit = 0;
- else if (strlen(buffer) == 1)
- done = 1;
- }
- }
-
- if (from[0] == '\0')
- strcpy(from, hold_return); /* default address! */
- else
- add_site(from, name1, lastname); /* get the user name too! */
-
- return(0);
- }
-
- add_site(buffer, site, lastsite)
- char *buffer, *site, *lastsite;
- {
- /** add site to buffer, unless site is 'uucp', or the same as
- lastsite. If not, set lastsite to site.
- **/
-
- char local_buffer[LONG_SLEN], *strip_parens();
-
- if (strcmp(site, "uucp") != 0)
- if (strcmp(site, lastsite) != 0) {
- if (buffer[0] == '\0')
- strcpy(buffer, strip_parens(site)); /* first in list! */
- else {
- sprintf(local_buffer,"%s!%s", buffer, strip_parens(site));
- strcpy(buffer, local_buffer);
- }
- strcpy(lastsite, strip_parens(site)); /* don't want THIS twice! */
- }
- }
-
- remove_first_word(string)
- char *string;
- { /** removes first word of string, ie up to first non-white space
- following a white space! **/
-
- register int loc;
-
- for (loc = 0; string[loc] != ' ' && string[loc] != '\0'; loc++)
- ;
-
- while (string[loc] == ' ' || string[loc] == '\t')
- loc++;
-
- move_left(string, loc);
- }
-
- move_left(string, chars)
- char string[];
- int chars;
- {
- /** moves string chars characters to the left DESTRUCTIVELY **/
-
- register int i;
-
- chars--; /* index starting at zero! */
-
- for (i=chars; string[i] != '\0' && string[i] != '\n'; i++)
- string[i-chars] = string[i];
-
- string[i-chars] = '\0';
- }
-
- reply_to_mail(person, from, subject)
- int person;
- char *from, *subject;
- {
- /** Respond to the message from the specified person with the
- specified subject... **/
-
- char buffer[SLEN];
-
- if (strlen(subject) == 0)
- strcpy(subject, "Auto-reply Mail");
- else if (! first_word(subject,"Auto-reply")) {
- sprintf(buffer, "Auto-reply to:%s", subject);
- strcpy(subject, buffer);
- }
-
- log("auto-replying to '%s'", from);
-
- mail(from, subject, reply_table[person].replyfile, person);
- }
-
- reverse(string)
- char *string;
- {
- /** reverse string... pretty trivial routine, actually! **/
-
- char buffer[SLEN];
- register int i, j = 0;
-
- for (i = strlen(string)-1; i >= 0; i--)
- buffer[j++] = string[i];
-
- buffer[j] = '\0';
-
- strcpy(string, buffer);
- }
-
- long
- bytes(name)
- char *name;
- {
- /** return the number of bytes in the specified file. This
- is to check to see if new mail has arrived.... **/
-
- int ok = 1;
- extern int errno; /* system error number! */
- struct stat buffer;
-
- if (stat(name, &buffer) != 0)
- if (errno != 2) {
- unlock();
- exit(fprintf(stderr,"Error %d attempting fstat on %s", errno, name));
- }
- else
- ok = 0;
-
- return(ok ? buffer.st_size : 0);
- }
-
- mail(to, subject, filename, person)
- char *to, *subject, *filename;
- int person;
- {
- /** Mail 'file' to the user from person... **/
-
- char buffer[VERY_LONG_STRING];
-
- sprintf(buffer, "%s -f '%s [autoreply]' -s '%s' %s %s",
- fastmail, reply_table[person].username,
- subject, filename, to);
-
- system(buffer);
- }
-
- log(message, arg)
- char *message;
- char *arg;
- {
- /** Put log entry into log file. Use the format:
- date-time: <message>
- **/
-
- struct tm *localtime(), *thetime;
- long time(), clock;
- char buffer[SLEN];
-
- /** first off, get the time and date **/
-
- clock = time((long *) 0); /* seconds since ??? */
- thetime = localtime(&clock); /* and NOW the time... */
-
- /** then put the message out! **/
-
- sprintf(buffer, message, arg);
-
- fprintf(logfd,"%d/%d-%d:%02d: %s\n",
- thetime->tm_mon+1, thetime->tm_mday,
- thetime->tm_hour, thetime->tm_min,
- buffer);
- }
-
- FILE *open_logfile()
- {
- /** open the logfile. returns a valid file descriptor **/
-
- FILE *fd;
-
- if ((fd = fopen(logfile, "a")) == 0)
- if ((fd = fopen(logfile2, "a")) == 0) {
- unlock();
- exit(1); /* give up! */
- }
-
- return( (FILE *) fd);
- }
-
- close_logfile()
- {
- /** Close the logfile until needed again. **/
-
- fclose(logfd);
- }
-
- char *strip_parens(string)
- char *string;
- {
- /** Return string with all parenthesized information removed.
- This is a non-destructive algorithm... **/
-
- static char buffer[LONG_SLEN];
- register int i, depth = 0, buffer_index = 0;
-
- for (i=0; i < strlen(string); i++) {
- if (string[i] == '(')
- depth++;
- else if (string[i] == ')')
- depth--;
- else if (depth == 0)
- buffer[buffer_index++] = string[i];
- }
-
- buffer[buffer_index] = '\0';
-
- return( (char *) buffer);
- }
-
- /*** LOCK and UNLOCK - ensure only one copy of this daemon running at any
- given time by using a file existance semaphore (wonderful stuff!) ***/
-
- lock()
- {
- /** Try to create the lock file. If it's there, or we can't
- create it for some stupid reason, return zero, otherwise,
- a non-zero return code indicates success in locking this
- process in. **/
-
- if (access(arep_lock_file, EXISTS) == 0)
- return(0); /* file already exists!! */
-
- if (creat(arep_lock_file, MODE) == -1)
- return(0); /* can't create file!! */
-
- return(1);
- }
-
- unlock()
- {
- /** remove lock file if it's there! **/
-
- (void) unlink(arep_lock_file);
- }
- END-OF-FILE
-
- if [ "$filename" != "/dev/null" ]
- then
- size=`wc -c < $filename`
-
- if [ $size != 13380 ]
- then
- echo $filename changed - should be 13380 bytes, not $size bytes
- fi
-
- chmod 666 $filename
- fi
-
- # ---------- file utils/autoreply.c ----------
-
- filename="utils/autoreply.c"
-
- if [ -f $filename ]
- then
- echo File \"$filename\" already exists\! Skipping...
- filename=/dev/null # throw it away
- else
- echo extracting file utils/autoreply.c...
- fi
-
- cat << 'END-OF-FILE' > $filename
- /** autoreply.c **/
-
- /** This is the front-end for the autoreply system, and performs two
- functions: it either adds the user to the list of people using the
- autoreply function (starting the daemon if no-one else) or removes
- a user from the list of people.
-
- Usage: autoreply filename
- autoreply "off"
- or autoreply [to find current status]
-
- (C) 1986, Dave Taylor
- **/
-
- #include <stdio.h>
- #include <errno.h>
- #include <sys/types.h>
- #include <sys/stat.h>
-
- #include "defs.h"
-
- static char ident[] = { WHAT_STRING };
-
- #define READ_ACCESS 04 /* is file readable? */
-
- #define tempdir "/tmp/arep" /* file prefix */
- #define autoreply_file "/etc/autoreply.data" /* autoreply data file */
-
- extern int errno; /* system error code */
- char username[NLEN]; /* login name of user */
-
- main(argc, argv)
- int argc;
- char *argv[];
- {
- char filename[SLEN];
-
- if (argc > 2) {
- printf("Usage: %s <filename>\tto start autoreply,\n", argv[0]);
- printf(" %s off\t\tto turn off autoreply\n", argv[0]);
- printf(" or %s \t\tto check current status\n", argv[0]);
- exit(1);
- }
-
- (void) cuserid(username);
-
- if (argc == 1 || strcmp(argv[1], "off") == 0)
- remove_user((argc == 1));
- else {
- strcpy(filename, argv[1]);
- if (access(filename,READ_ACCESS) != 0) {
- printf("Error: Can't read file '%s'\n", filename);
- exit(1);
- }
-
- if (filename[0] != '/') /* prefix home directory */
- sprintf(filename,"%s/%s", getenv("HOME"), argv[1]);
-
- add_user(filename);
- }
-
- exit(0);
- }
-
- remove_user(stat_only)
- int stat_only;
- {
- /** Remove the user from the list of currently active autoreply
- people. If 'stat_only' is set, then just list the name of
- the file being used to autoreply with, if any. **/
-
- FILE *temp, *repfile;
- char tempfile[SLEN], user[SLEN], filename[SLEN];
- int c, copied = 0, found = 0;
- long filesize, bytes();
-
- if (! stat_only) {
- sprintf(tempfile, "%s.%06d", tempdir, getpid());
-
- if ((temp = fopen(tempfile, "w")) == NULL) {
- printf("Error: couldn't open tempfile '%s'. Not removed\n",
- tempfile);
- exit(1);
- }
- }
-
- if ((repfile = fopen(autoreply_file, "r")) == NULL) {
- if (stat_only) {
- printf("You're not currently autoreplying to mail.\n");
- exit(0);
- }
- printf("No-one is autoreplying to their mail!\n");
- exit(0);
- }
-
- /** copy out of real replyfile... **/
-
- while (fscanf(repfile, "%s %s %ld", user, filename, &filesize) != EOF)
-
- if (strcmp(user, username) != 0) {
- if (! stat_only) {
- copied++;
- fprintf(tempfile, "%s %s %ld\n", user, filename, filesize);
- }
- }
- else {
- if (stat_only) {
- printf("You're currently autoreplying to mail with the file %s\n", filename);
- exit(0);
- }
- found++;
- }
-
- fclose(temp);
- fclose(repfile);
-
- if (! found) {
- printf("You're not currently autoreplying to mail%s\n",
- stat_only? "." : "!");
- if (! stat_only)
- unlink(tempfile);
- exit(! stat_only);
- }
-
- /** now copy tempfile back into replyfile **/
-
- if (copied == 0) { /* removed the only person! */
- unlink(autoreply_file);
- }
- else { /* save everyone else */
-
- if ((temp = fopen(tempfile,"r")) == NULL) {
- printf("Error: couldn't reopen tempfile '%s'. Not removed.\n",
- tempfile);
- unlink(tempfile);
- exit(1);
- }
-
- if ((repfile = fopen(autoreply_file, "w")) == NULL) {
- printf(
- "Error: couldn't reopen autoreply file for writing! Not removed.\n");
- unlink(tempfile);
- exit(1);
- }
-
- while ((c = getc(temp)) != EOF)
- putc(c, repfile);
-
- fclose(temp);
- fclose(repfile);
-
- }
- unlink(tempfile);
-
- if (found > 1)
- printf("Warning: your username appeared %d times!! Removed all\n",
- found);
- else
- printf("You've been removed from the autoreply table.\n");
- }
-
- add_user(filename)
- char *filename;
- {
- /** add the user to the autoreply file... **/
-
- FILE *repfile;
- char mailfile[SLEN];
- long bytes();
-
- if ((repfile = fopen(autoreply_file, "a")) == NULL) {
- printf("Error: couldn't open the autoreply file! Not added\n");
- exit(1);
- }
-
- sprintf(mailfile,"%s/%s", mailhome, username);
-
- fprintf(repfile,"%s %s %ld\n", username, filename, bytes(mailfile));
-
- fclose(repfile);
-
- printf("You've been added to the autoreply system.\n");
- }
-
-
- long
- bytes(name)
- char *name;
- {
- /** return the number of bytes in the specified file. This
- is to check to see if new mail has arrived.... **/
-
- int ok = 1;
- extern int errno; /* system error number! */
- struct stat buffer;
-
- if (stat(name, &buffer) != 0)
- if (errno != 2)
- exit(fprintf(stderr,"Error %d attempting fstat on %s", errno, name));
- else
- ok = 0;
-
- return(ok ? buffer.st_size : 0L);
- }
- END-OF-FILE
-
- if [ "$filename" != "/dev/null" ]
- then
- size=`wc -c < $filename`
-
- if [ $size != 4746 ]
- then
- echo $filename changed - should be 4746 bytes, not $size bytes
- fi
-
- chmod 666 $filename
- fi
-
- # ---------- file utils/fastmail.c ----------
-
- filename="utils/fastmail.c"
-
- if [ -f $filename ]
- then
- echo File \"$filename\" already exists\! Skipping...
- filename=/dev/null # throw it away
- else
- echo extracting file utils/fastmail.c...
- fi
-
- cat << 'END-OF-FILE' > $filename
- /** fastmail.c **/
-
- /** This program is specifically written for group mailing lists and
- such batch type mail processing. It does NOT use aliases at all,
- it does NOT read the /etc/password file to find the From: name
- of the user and does NOT expand any addresses. It is meant
- purely as a front-end for either /bin/mail or /usr/lib/sendmail
- (according to what is available on the current system).
-
- **** This program should be used with CAUTION *****
-
- (C) Copyright 1985 Dave Taylor
- **/
-
- /** The calling sequence for this program is:
-
- fastmail {args} filename full-email-address
-
- where args could be any (or all) of;
-
- -b bcc-list (Blind carbon copies to)
- -c cc-list (carbon copies to)
- -d (debug on)
- -f from (from name)
- -r reply-to-address (Reply-To:)
- -s subject (subject of message)
- **/
-
- #include <stdio.h>
-
- #ifdef BSD
- # include <sys/time.h>
- #else
- # include <time.h>
- #endif
-
- #include "defs.h"
-
- static char ident[] = { WHAT_STRING };
-
- #define binrmail "/bin/rmail"
- #define temphome "/tmp/fastmail."
-
- #define DONE 0
- #define ERROR -1
-
- char *optional_arg; /* optional argument as we go */
- int opt_index; /* argnum + 1 when we leave */
-
- char *arpa_dayname[] = { "Sun", "Mon", "Tue", "Wed", "Thu",
- "Fri", "Sat", "" };
-
- char *arpa_monname[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
- "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", ""};
-
- char *get_arpa_date();
-
- #ifdef BSD
- char *timezone();
- #else
- extern char *tzname[];
- #endif
-
- main(argc, argv)
- int argc;
- char *argv[];
- {
-
- FILE *tempfile;
- char hostname[NLEN], username[NLEN], from_string[SLEN], subject[SLEN];
- char filename[SLEN], tempfilename[SLEN], command_buffer[256];
- char replyto[SLEN], cc_list[SLEN], bcc_list[SLEN], to_list[SLEN];
- int c, sendmail_available, debug = 0;
-
- replyto[0] = '\0';
- cc_list[0] = '\0';
- bcc_list[0] = '\0';
-
- while ((c = get_options(argc, argv, "b:c:df:r:s:")) > 0) {
- switch (c) {
- case 'b' : strcpy(bcc_list, optional_arg); break;
- case 'c' : strcpy(cc_list, optional_arg); break;
- case 'd' : debug++; break;
- case 'f' : strcpy(from_string, optional_arg); break;
- case 'r' : strcpy(replyto, optional_arg); break;
- case 's' : strcpy(subject, optional_arg); break;
- }
- }
-
- if (c == ERROR) {
- fprintf(stderr,"Usage: fastmail {args} filename address(es)\n");
- fprintf(stderr, " where {args} can be;\n");
- fprintf(stderr,"\t-b bcc-list\n\t-c cc-list\n\t-d\n\t-f from-name\n");
- fprintf(stderr, "\t-r reply-to\n\t-s subject\n\n");
- exit(1);
- }
-
- if (opt_index > argc) {
- fprintf(stderr,"Usage: fastmail {args} filename address(es)\n");
- fprintf(stderr, " where {args} can be;\n");
- fprintf(stderr,"\t-b bcc-list\n\t-c cc-list\n\t-d\n\t-f from-name\n");
- fprintf(stderr, "\t-r reply-to\n\t-s subject\n\n");
- exit(1);
- }
-
- strcpy(filename, argv[opt_index++]);
-
- if (opt_index > argc) {
- fprintf(stderr,"Usage: fastmail {args} filename address(es)\n");
- fprintf(stderr, " where {args} can be;\n");
- fprintf(stderr,"\t-b bcc-list\n\t-c cc-list\n\t-d\n\t-f from-name\n");
- fprintf(stderr, "\t-r reply-to\n\t-s subject\n\n");
- exit(1);
- }
-
- gethostname(hostname, sizeof(hostname));
- strcpy(username, getlogin());
- if (strlen(username) == 0)
- cuserid(username);
-
- if (access(filename, READ_ACCESS) == -1)
- exit(fprintf(stderr, "Error: can't find file %s!\n", filename));
-
- sprintf(tempfilename, "%s%d", temphome, getpid());
-
- if ((tempfile = fopen(tempfilename, "w")) == NULL)
- exit(fprintf(stderr, "Couldn't open temp file %s\n", tempfilename));
-
- if (strlen(from_string) > 0)
- fprintf(tempfile, "From: %s!%s (%s)\n",
- hostname, username, from_string);
- else
- fprintf(tempfile, "From: %s!%s\n", hostname, username);
-
- fprintf(tempfile, "Date: %s\n", get_arpa_date());
-
- if (strlen(subject) > 0)
- fprintf(tempfile, "Subject: %s\n", subject);
-
- if (strlen(replyto) > 0)
- fprintf(tempfile, "Reply-To: %s\n", replyto);
-
- while (opt_index < argc)
- sprintf(to_list, "%s%s%s", to_list, (strlen(to_list) > 0? ", ":""),
- argv[opt_index++]);
-
- fprintf(tempfile, "To: %s\n", to_list);
-
- if (strlen(cc_list) > 0)
- fprintf(tempfile, "Cc: %s\n", cc_list);
-
- if (strlen(bcc_list) > 0)
- fprintf(tempfile, "Bcc: %s\n", bcc_list); /* trust xport */
-
- fprintf(tempfile, "X-Mailer: fastmail [version %s]\n", VERSION);
- fprintf(tempfile, "\n");
-
- fclose(tempfile);
-
- /** now we'll cat both files to /bin/rmail or sendmail... **/
-
- sendmail_available = (access(sendmail, EXECUTE_ACCESS) != -1);
-
- printf("Mailing to %s%s%s%s%s [via %s]\n", to_list,
- (strlen(cc_list) > 0 ? " ":""), cc_list,
- (strlen(bcc_list) > 0 ? " ":""), bcc_list,
- sendmail_available? "sendmail" : "rmail");
-
- sprintf(command_buffer, "cat %s %s | %s '%s %s %s'",
- tempfilename, filename,
- sendmail_available? sendmail : mailer,
- to_list, cc_list, bcc_list);
-
- if (debug)
- printf("%s\n", command_buffer);
-
- system(command_buffer);
-
- unlink(tempfilename);
- }
-
-
- char *get_arpa_date()
- {
- /** returns an ARPA standard date. The format for the date
- according to DARPA document RFC-822 is exemplified by;
-
- Mon, 12 Aug 85 6:29:08 MST
-
- **/
-
- static char buffer[SLEN]; /* static character buffer */
- struct tm *the_time, /* Time structure, see CTIME(3C) */
- *localtime();
- long junk; /* time in seconds.... */
- #ifdef BSD
- struct timeval time_val;
- struct timezone time_zone;
- #endif
-
- #ifdef BSD
- gettimeofday(&time_val, &time_zone);
- junk = time_val.tv_sec;
- #else
- junk = time(0); /* this must be here for it to work! */
- #endif
- the_time = localtime(&junk);
-
- sprintf(buffer, "%s, %d %s %d %d:%02d:%02d %s",
- arpa_dayname[the_time->tm_wday],
- the_time->tm_mday % 32,
- arpa_monname[the_time->tm_mon],
- the_time->tm_year % 100,
- the_time->tm_hour % 24,
- the_time->tm_min % 61,
- the_time->tm_sec % 61,
- #ifdef BSD
- timezone(time_zone.tz_minuteswest, time_zone.tz_dsttime));
- #else
- tzname[the_time->tm_isdst]);
- #endif
-
- return( (char *) buffer);
- }
-
- /** Starting argument parsing routine.
-
- Called as "get_options(argc, argv, options)" where options is a string
- of the form "abc:d" indicating that 'a' 'b' and 'd' are flags and
- 'c' is a flag with a trailing argument. Optional arguments are
- returned in the external char * variable "optional_arg", and the
- external int "opt_index" is set to the first entry in the argv list
- that wasn't processed (ie after the flags).
-
- For example, the C compiler would have something of the form
- getopt(argc, argv, "Oo:l:") to allow "cc -O -o output -l lib file.c"
-
- (C) Copyright 1986, Dave Taylor
- **/
-
- int _indx = 1, _argnum = 1;
-
- int
- get_options(argc, argv, options)
- int argc;
- char *argv[], *options;
- {
- /** Returns the character argument next, and optionally instantiates
- "argument" to the argument associated with the particular option
- **/
-
- char *word, *strchr();
-
- if (_indx >= strlen(argv[_argnum])) {
- _argnum++;
- _indx = 1; /* zeroeth char is '-' */
- }
-
- if (_argnum >= argc) {
- opt_index = argc;
- return(DONE);
- }
-
- if (argv[_argnum][0] != '-') {
- opt_index = _argnum;
- return(DONE);
- }
-
- word = strchr(options, argv[_argnum][_indx++]);
-
- if (strlen(word) == 0)
- return(ERROR);
-
- if (word[1] == ':') {
-
- /** Two possibilities - either tailing end of this argument or the
- next argument in the list **/
-
- if (_indx < strlen(argv[_argnum])) { /* first possibility */
- optional_arg = (char *) (argv[_argnum] + _indx);
- _argnum++;
- _indx = 1;
- }
- else { /* second choice */
- if (++_argnum >= argc)
- return(ERROR); /* no argument!! */
-
- optional_arg = (char *) argv[_argnum++];
- _indx = 1;
- }
- }
-
- return((int) word[0]);
- }
- END-OF-FILE
-
- if [ "$filename" != "/dev/null" ]
- then
- size=`wc -c < $filename`
-
- if [ $size != 7799 ]
- then
- echo $filename changed - should be 7799 bytes, not $size bytes
- fi
-
- chmod 666 $filename
- fi
-
- # ---------- file utils/from.c ----------
-
- filename="utils/from.c"
-
- if [ -f $filename ]
- then
- echo File \"$filename\" already exists\! Skipping...
- filename=/dev/null # throw it away
- else
- echo extracting file utils/from.c...
- fi
-
- cat << 'END-OF-FILE' > $filename
- /** from.c **/
-
- /** print out whom each message is from in the pending mailbox
- or specified one, including a subject line if available..
-
- Added PREFER_UUCP knowledge 6/86
-
- (C) Copyright 1986 Dave Taylor **/
-
- #include <stdio.h>
- #include "defs.h"
-
- static char ident[] = { WHAT_STRING };
-
- #define LINEFEED (char) 10
-
- #define metachar(c) (c == '=' || c == '+' || c == '%')
-
- FILE *mailfile;
-
- char *expand_define();
-
- main(argc, argv)
- int argc;
- char *argv[];
- {
- char infile[LONG_SLEN], username[SLEN];
-
- if (argc > 2)
- exit(printf("Usage: %s {filename}\n", argv[0]));
-
- if (argc == 2)
- strcpy(infile, argv[1]);
- else {
- strcpy(username, getlogin());
- if (strlen(username) == 0)
- cuserid(username);
- sprintf(infile,"%s/%s",mailhome, username);
- }
-
- if (metachar(infile[0]))
- if (expand(infile) == 0)
- printf("%s: couldn't expand filename %s!\n", argv[0], infile);
-
- if ((mailfile = fopen(infile,"r")) == NULL) {
- if (argc == 1)
- printf("No mail!\n");
- else
- printf("%s: Couldn't open file %s\n", argv[0], infile);
- }
- else
- if (read_headers()==0)
- printf("No messages in mailbox!\n");
- }
-
- int
- read_headers()
- {
- /** read the headers, output as found **/
-
- char buffer[LONG_SLEN], from_whom[SLEN], subject[SLEN];
- register int subj = 0, in_header = 1, count = 0;
-
- while (fgets(buffer, LONG_SLEN, mailfile) != NULL) {
- if (first_word(buffer,"From ")) {
- if (real_from(buffer, from_whom)) {
- subj = 0;
- in_header = 1;
- }
- }
- else if (in_header) {
- if (first_word(buffer,">From"))
- forwarded(buffer, from_whom); /* return address */
- else if (first_word(buffer,"Subject:") ||
- first_word(buffer,"Re:")) {
- if (! subj++) {
- remove_first_word(buffer);
- strcpy(subject, buffer);
- }
- }
- else if (first_word(buffer,"From:"))
- parse_arpa_from(buffer, from_whom);
- else if (buffer[0] == LINEFEED) {
- in_header = 0; /* in body of message! */
- show_header(from_whom, subject);
- from_whom[0] = 0;
- subject[0] = 0;
- count++;
- }
- }
- }
- return(count);
- }
-
- int
- real_from(buffer, who)
- char *buffer, *who;
- {
- /***** returns true iff 's' has the seven 'from' fields,
- initializing the who to the sender *****/
-
- char junk[80];
-
- junk[0] = '\0';
- sscanf(buffer, "%*s %s %*s %*s %*s %*s %s",
- who, junk);
- return(junk[0] != '\0');
- }
-
- forwarded(buffer, who)
- char *buffer, *who;
- {
- /** change 'from' and date fields to reflect the ORIGINATOR of
- the message by iteratively parsing the >From fields... **/
-
- char machine[80], buff[80];
-
- machine[0] = '\0';
- sscanf(buffer, "%*s %s %*s %*s %*s %*s %*s %*s %*s %s",
- who, machine);
-
- if (machine[0] == '\0') /* try for srm address */
- sscanf(buffer, "%*s %s %*s %*s %*s %*s %*s %*s %s",
- who, machine);
-
- if (machine[0] == '\0')
- sprintf(buff,"anonymous");
- else
- sprintf(buff,"%s!%s", machine, who);
-
- strncpy(who, buff, 80);
- }
-
-
- remove_first_word(string)
- char *string;
- { /** removes first word of string, ie up to first non-white space
- following a white space! **/
-
- register int loc;
-
- for (loc = 0; string[loc] != ' ' && string[loc] != '\0'; loc++)
- ;
-
- while (string[loc] == ' ' || string[loc] == '\t')
- loc++;
-
- move_left(string, loc);
- }
-
- move_left(string, chars)
- char string[];
- int chars;
- {
- /** moves string chars characters to the left DESTRUCTIVELY **/
-
- register int i;
-
- chars--; /* index starting at zero! */
-
- for (i=chars; string[i] != '\0' && string[i] != '\n'; i++)
- string[i-chars] = string[i];
-
- string[i-chars] = '\0';
- }
-
- show_header(from, subject)
- char *from, *subject;
- {
- /** output header in clean format, including abbreviation
- of return address if more than one machine name is
- contained within it! **/
-
- char buffer[SLEN];
- int loc, i=0, exc=0;
-
- #ifdef PREFER_UUCP
-
- if (chloc(from,'!') != -1 && in_string(from, BOGUS_INTERNET))
- from[strlen(from) - strlen(BOGUS_INTERNET)] = '\0';
-
- #endif
-
- loc = strlen(from);
-
- while (exc < 2 && loc > 0)
- if (from[--loc] == '!')
- exc++;
-
- if (exc == 2) { /* lots of machine names! Get last one */
- loc++;
- while (loc < strlen(from) && loc < SLEN)
- buffer[i++] = from[loc++];
- buffer[i] = '\0';
- printf("%-20s %s\n", buffer, subject);
- }
- else
- printf("%-20s %s\n", from, subject);
- }
-
- parse_arpa_from(buffer, newfrom)
- char *buffer, *newfrom;
- {
- /** try to parse the 'From:' line given... It can be in one of
- two formats:
- From: Dave Taylor <hpcnou!dat>
- or From: hpcnou!dat (Dave Taylor)
- Change 'newfrom' ONLY if sucessfully parsed this entry and
- the resulting name is non-null!
- **/
-
- char temp_buffer[SLEN], *temp;
- register int i, j = 0;
-
- temp = (char *) temp_buffer;
- temp[0] = '\0';
-
- no_ret(buffer); /* blow away '\n' char! */
-
- if (lastch(buffer) == '>') {
- for (i=strlen("From: "); buffer[i] != '\0' && buffer[i] != '<' &&
- buffer[i] != '('; i++)
- temp[j++] = buffer[i];
- temp[j] = '\0';
- }
- else if (lastch(buffer) == ')') {
- for (i=strlen(buffer)-2; buffer[i] != '\0' && buffer[i] != '(' &&
- buffer[i] != '<'; i--)
- temp[j++] = buffer[i];
- temp[j] = '\0';
- reverse(temp);
- }
-
- if (strlen(temp) > 0) { /* mess with buffer... */
-
- /* remove leading spaces... */
-
- while (whitespace(temp[0]))
- temp = (char *) (temp + 1); /* increment address! */
-
- /* remove trailing spaces... */
-
- i = strlen(temp) - 1;
-
- while (whitespace(temp[i]))
- temp[i--] = '\0';
-
- /* if anything is left, let's change 'from' value! */
-
- if (strlen(temp) > 0)
- strcpy(newfrom, temp);
- }
- }
-
- reverse(string)
- char *string;
- {
- /** reverse string... pretty trivial routine, actually! **/
-
- char buffer[SLEN];
- register int i, j = 0;
-
- for (i = strlen(string)-1; i >= 0; i--)
- buffer[j++] = string[i];
-
- buffer[j] = '\0';
-
- strcpy(string, buffer);
- }
-
- int
- expand(infile)
- char *infile;
- {
- /** Expand the filename since the first character is a meta-
- character that should expand to the "maildir" variable
- in the users ".elmrc" file...
-
- Note: this is a brute force way of getting the entry out
- of the .elmrc file, and isn't recommended for the faint
- of heart!
- **/
-
- FILE *rcfile;
- char buffer[SLEN], *expanded_dir, *home, *getenv(), *bufptr;
- int foundit = 0;
-
- bufptr = (char *) buffer; /* same address */
-
- if ((home = getenv("HOME")) == NULL) {
- printf(
- "Can't expand environment variable $HOME to find .elmrc file!\n");
- exit(1);
- }
-
- sprintf(buffer, "%s/%s", home, elmrcfile);
-
- if ((rcfile = fopen(buffer, "r")) == NULL) {
- printf("Can't open your \".elmrc\" file (%s) for reading!\n",
- buffer);
- exit(1);
- }
-
- while (fgets(buffer, SLEN, rcfile) != NULL && ! foundit) {
- if (strncmp(buffer, "maildir", 7) == 0 ||
- strncmp(buffer, "folders", 7) == 0) {
- while (*bufptr != '=' && *bufptr)
- bufptr++;
- bufptr++; /* skip the equals sign */
- while (whitespace(*bufptr) && *bufptr)
- bufptr++;
- home = bufptr; /* remember this address */
-
- while (! whitespace(*bufptr) && *bufptr != '\n')
- bufptr++;
-
- *bufptr = '\0'; /* remove trailing space */
- foundit++;
- }
- }
-
- fclose(rcfile); /* be nice... */
-
- if (! foundit) {
- printf("Couldn't find \"maildir\" in your .elmrc file!\n");
- exit(1);
- }
-
- /** Home now points to the string containing your maildir, with
- no leading or trailing white space...
- **/
-
- expanded_dir = expand_define(home);
-
- sprintf(buffer, "%s%s%s", expanded_dir,
- (expanded_dir[strlen(expanded_dir)-1] == '/' ||
- infile[0] == '/') ? "" : "/", (char *) infile+1);
-
- strcpy(infile, buffer);
- }
-
- char *expand_define(maildir)
- char *maildir;
- {
- /** This routine expands any occurances of "~" or "$var" in
- the users definition of their maildir directory out of
- their .elmrc file.
-
- Again, another routine not for the weak of heart or staunch
- of will!
- **/
-
- static char buffer[SLEN]; /* static buffer AIEE!! */
- char name[SLEN], /* dynamic buffer!! (?) */
- *nameptr, /* pointer to name?? */
- *value; /* char pointer for munging */
-
- if (*maildir == '~')
- sprintf(buffer, "%s%s", getenv("HOME"), ++maildir);
- else if (*maildir == '$') { /* shell variable */
-
- /** break it into a single word - the variable name **/
-
- strcpy(name, (char *) maildir + 1); /* hurl the '$' */
- nameptr = (char *) name;
- while (*nameptr != '/' && *nameptr) nameptr++;
- *nameptr = '\0'; /* null terminate */
-
- /** got word "name" for expansion **/
-
- if ((value = getenv(name)) == NULL) {
- printf("Couldn't expand shell variable $%s in .elmrc!\n", name);
- exit(1);
- }
- sprintf(buffer, "%s%s", value, maildir + strlen(name) + 1);
- }
-
- return( ( char *) buffer);
- }
- END-OF-FILE
-
- if [ "$filename" != "/dev/null" ]
- then
- size=`wc -c < $filename`
-
- if [ $size != 8783 ]
- then
- echo $filename changed - should be 8783 bytes, not $size bytes
- fi
-
- chmod 666 $filename
- fi
-
- # ---------- file utils/newmail.c ----------
-
- filename="utils/newmail.c"
-
- if [ -f $filename ]
- then
- echo File \"$filename\" already exists\! Skipping...
- filename=/dev/null # throw it away
- else
- echo extracting file utils/newmail.c...
- fi
-
- cat << 'END-OF-FILE' > $filename
- /** newmail.c **/
-
- /** Keep track of the mail for the current user...if new mail
- arrives, output a line of the form;
-
- Mail has arrived from <name> - <subject>
-
- where <name> is either the persons full name, or machine!login.
- If there is no subject, it will say.
-
- Added: you can specify a file other than the mailbox to keep
- track of - if an argument is given, the program will try
- to use it as a filename...
-
- Also, the program will quit when you log off of the machine.
-
- (C) 1986, Dave Taylor
- **/
-
- #ifdef AUTO_BACKGROUND
- #include <signal.h> /* background jobs ignore some signals... */
- #endif
-
- #include <stdio.h>
- #include <sys/types.h>
- #include <sys/stat.h>
-
- #include "defs.h"
-
- static char ident[] = { WHAT_STRING };
-
- #define LINEFEED (char) 10
- #define BEGINNING 0 /* seek fseek(3S) */
- #define SLEEP_TIME 60
-
- #define NO_SUBJECT "(No Subject Specified)"
-
- FILE *mailfile;
-
- long bytes();
-
- main(argc, argv)
- int argc;
- char *argv[];
- {
- char filename[LONG_SLEN];
- long size, newsize;
-
- if (argc > 2)
- fprintf(stderr, "Usage: %s [filename] &\n", argv[0]);
- else if (argc == 2) {
- strcpy(filename, argv[1]);
- if (access(filename, ACCESS_EXISTS) == -1) {
- fprintf(stderr,"%s: Can't open file %s to keep track of!\n",
- argv[0], filename);
- exit(1);
- }
- }
- else
- sprintf(filename,"%s/%s",mailhome, getlogin());
-
- #ifdef AUTO_BACKGROUND
- if (fork()) /* automatically puts this task in background! */
- exit(0);
-
- signal(SIGINT, SIG_IGN);
- signal(SIGQUIT, SIG_IGN);
- signal(SIGHUP, SIG_DFL); /* so we exit when logged out */
- #endif
-
- size = bytes(filename);
-
- mailfile = (FILE *) NULL;
-
- while (1) {
-
- #ifndef AUTO_BACKGROUND /* won't work if we're nested this deep! */
- if (getppid() == 1) /* we've lost our shell! */
- exit();
- #endif
-
- /** Note the lack of error checking on the fopen() (Philip Peake
- did!) - this is okay since if it fails we don't have any
- mail and we can sleep(60) and try again later...
- **/
-
- if (mailfile == (FILE *) NULL)
- mailfile = fopen(filename,"r");
-
- if ((newsize = bytes(filename)) > size) { /* new mail */
- fseek(mailfile, size, BEGINNING); /* skip all current mail */
- size = newsize;
- printf("\n\r"); /* blank lines surrounding message */
- read_headers();
- printf("\n\r");
- }
- else if (newsize != size) {
- size = newsize; /* mail's been removed... */
- (void) fclose(mailfile); /* close it and ... */
- mailfile = (FILE *) NULL; /* let's reopen the file */
- }
-
- sleep(SLEEP_TIME);
- }
- }
-
- int
- read_headers()
- {
- /** read the headers, output as found **/
-
- char buffer[LONG_SLEN], from_whom[SLEN], subject[SLEN];
- register int subj = 0, in_header = 1, count = 0;
-
- while (fgets(buffer, LONG_SLEN, mailfile) != NULL) {
- if (first_word(buffer,"From ")) {
- if (real_from(buffer, from_whom)) {
- subj = 0;
- in_header = 1;
- }
- }
- else if (in_header) {
- if (first_word(buffer,">From"))
- forwarded(buffer, from_whom); /* return address */
- else if (first_word(buffer,"Subject:") ||
- first_word(buffer,"Re:")) {
- if (! subj++) {
- remove_first_word(buffer);
- strcpy(subject, buffer);
- }
- }
- else if (first_word(buffer,"From:"))
- parse_arpa_from(buffer, from_whom);
- else if (buffer[0] == LINEFEED) {
- in_header = 0; /* in body of message! */
- show_header(from_whom, subject);
- from_whom[0] = 0;
- subject[0] = 0;
- count++;
- }
- }
- }
- return(count);
- }
-
- int
- real_from(buffer, who)
- char *buffer, *who;
- {
- /***** returns true iff 's' has the seven 'from' fields,
- initializing the who to the sender *****/
-
- char junk[80];
-
- junk[0] = '\0';
- sscanf(buffer, "%*s %s %*s %*s %*s %*s %s",
- who, junk);
- return(junk[0] != '\0');
- }
-
- forwarded(buffer, who)
- char *buffer, *who;
- {
- /** change 'from' and date fields to reflect the ORIGINATOR of
- the message by iteratively parsing the >From fields... **/
-
- char machine[80], buff[80];
-
- machine[0] = '\0';
- sscanf(buffer, "%*s %s %*s %*s %*s %*s %*s %*s %*s %s",
- who, machine);
-
- if (machine[0] == '\0') /* try for srm address */
- sscanf(buffer, "%*s %s %*s %*s %*s %*s %*s %*s %s",
- who, machine);
-
- if (machine[0] == '\0')
- sprintf(buff,"anonymous");
- else
- sprintf(buff,"%s!%s", machine, who);
-
- strncpy(who, buff, 80);
- }
-
-
- remove_first_word(string)
- char *string;
- { /** removes first word of string, ie up to first non-white space
- following a white space! **/
-
- register int loc;
-
- for (loc = 0; string[loc] != ' ' && string[loc] != '\0'; loc++)
- ;
-
- while (string[loc] == ' ' || string[loc] == '\t')
- loc++;
-
- move_left(string, loc);
- }
-
- move_left(string, chars)
- char string[];
- int chars;
- {
- /** moves string chars characters to the left DESTRUCTIVELY **/
-
- register int i;
-
- chars--; /* index starting at zero! */
-
- for (i=chars; string[i] != '\0' && string[i] != '\n'; i++)
- string[i-chars] = string[i];
-
- string[i-chars] = '\0';
- }
-
- show_header(from, subject)
- char *from, *subject;
- {
- /** output header in clean format, including abbreviation
- of return address if more than one machine name is
- contained within it! **/
- char buffer[SLEN];
- int loc, i=0, exc=0;
-
- #ifdef PREFER_UUCP
-
- if (chloc(from, '!') != -1 && in_string(from, BOGUS_INTERNET))
- from[strlen(from) - strlen(BOGUS_INTERNET)] = '\0';
-
- #endif
-
- loc = strlen(from);
-
- while (exc < 2 && loc > 0)
- if (from[--loc] == '!')
- exc++;
-
- if (exc == 2) { /* lots of machine names! Get last one */
- loc++;
- while (loc < strlen(from) && loc < SLEN)
- buffer[i++] = from[loc++];
- buffer[i] = '\0';
- strcpy(from, buffer);
- }
-
- if (strlen(subject) < 2)
- strcpy(subject, NO_SUBJECT);
-
- printf(">> New mail from %s - %s\n\r", from, subject);
- }
-
- parse_arpa_from(buffer, newfrom)
- char *buffer, *newfrom;
- {
- /** try to parse the 'From:' line given... It can be in one of
- two formats:
- From: Dave Taylor <hpcnou!dat>
- or From: hpcnou!dat (Dave Taylor)
- Change 'newfrom' ONLY if sucessfully parsed this entry and
- the resulting name is non-null!
- **/
-
- char temp_buffer[SLEN], *temp;
- register int i, j = 0;
-
- temp = (char *) temp_buffer;
- temp[0] = '\0';
-
- no_ret(buffer); /* blow away '\n' char! */
-
- if (lastch(buffer) == '>') {
- for (i=strlen("From: "); buffer[i] != '\0' && buffer[i] != '<' &&
- buffer[i] != '('; i++)
- temp[j++] = buffer[i];
- temp[j] = '\0';
- }
- else if (lastch(buffer) == ')') {
- for (i=strlen(buffer)-2; buffer[i] != '\0' && buffer[i] != '(' &&
- buffer[i] != '<'; i--)
- temp[j++] = buffer[i];
- temp[j] = '\0';
- reverse(temp);
- }
-
- if (strlen(temp) > 0) { /* mess with buffer... */
-
- /* remove leading spaces... */
-
- while (whitespace(temp[0]))
- temp = (char *) (temp + 1); /* increment address! */
-
- /* remove trailing spaces... */
-
- i = strlen(temp) - 1;
-
- while (whitespace(temp[i]))
- temp[i--] = '\0';
-
- /* if anything is left, let's change 'from' value! */
-
- if (strlen(temp) > 0)
- strcpy(newfrom, temp);
- }
- }
-
- reverse(string)
- char *string;
- {
- /** reverse string... pretty trivial routine, actually! **/
-
- char buffer[SLEN];
- register int i, j = 0;
-
- for (i = strlen(string)-1; i >= 0; i--)
- buffer[j++] = string[i];
-
- buffer[j] = '\0';
-
- strcpy(string, buffer);
- }
-
- long
- bytes(name)
- char *name;
- {
- /** return the number of bytes in the specified file. This
- is to check to see if new mail has arrived.... **/
-
- int ok = 1;
- extern int errno; /* system error number! */
- struct stat buffer;
-
- if (stat(name, &buffer) != 0)
- if (errno != 2)
- exit(fprintf(stderr,"Error %d attempting fstat on %s", errno, name));
- else
- ok = 0;
-
- return(ok ? buffer.st_size : 0);
- }
- END-OF-FILE
-
- if [ "$filename" != "/dev/null" ]
- then
- size=`wc -c < $filename`
-
- if [ $size != 7761 ]
- then
- echo $filename changed - should be 7761 bytes, not $size bytes
- fi
-
- chmod 666 $filename
- fi
-
- # ---------- file utils/newalias.c ----------
-
- filename="utils/newalias.c"
-
- if [ -f $filename ]
- then
- echo File \"$filename\" already exists\! Skipping...
- filename=/dev/null # throw it away
- else
- echo extracting file utils/newalias.c...
- fi
-
- cat << 'END-OF-FILE' > $filename
- /** newalias.c **/
-
- /** (C) Copyright 1986 Dave Taylor **/
-
- /** Install a new set of aliases for the 'Elm' mailer.
-
- If invoked with a specific filename, it assumes that
- it is working with an individual users alias tables, and
- generates the .alias.hash and .alias.data files in their
- home directory.
- If, however, it is invoked with no arguments, then
- it assumes that the user is updating the system alias
- file and uses the defaults for everything.
-
- The format for the input file is;
- alias1, alias2, ... : username : address
- or alias1, alias2, ... : groupname: member, member, member, ...
- member, member, member, ...
-
- "-q" flag added: 6/17/86
- **/
-
- #ifdef BSD
- # include <sys/file.h>
- #else
- # include <fcntl.h>
- #endif
-
- #include <stdio.h>
- #include "defs.h" /* ELM system definitions */
-
- static char ident[] = { WHAT_STRING };
-
- #ifndef TAB
- # define TAB '\t' /* TAB character! */
- #endif
-
- #define alias_hash ".alias_hash"
- #define alias_data ".alias_data"
- #define alias_text ".alias_text"
-
- #define group(string) (strpbrk(string,", ") != NULL)
-
- struct alias_rec
- shash_table[MAX_SALIASES]; /* the actual hash table */
-
- struct alias_rec
- uhash_table[MAX_UALIASES]; /* the actual hash table */
-
- int hash_table_loaded=0; /* is system table actually loaded? */
-
- int buff_loaded; /* for file input overlap... */
- int error= 0; /* if errors, don't save! */
- int system=0; /* system file updating? */
- int count=0; /* how many aliases so far? */
- long offset = 0L; /* data file line offset! */
-
- main(argc, argv)
- int argc;
- char *argv[];
- {
- FILE *in, *data;
- char inputname[SLEN], hashname[SLEN], dataname[SLEN];
- char home[SLEN], buffer[LONG_STRING];
- int hash, count = 0, owner, quiet = 0;
-
- if (argc != 1)
- if (strcmp(argv[1], "-q") == 0)
- quiet++;
- else
- exit(printf("Usage: %s\n", argv[0]));
-
- owner = getuid();
-
- if (owner == 0 && ! quiet) { /* being run by root! */
- printf("Would you like to update the system aliases? (y/n)");
- gets(buffer, 2);
- if (buffer[0] == 'y' || buffer[0] == 'Y') {
- printf("Updating the system alias file...\n");
-
- sprintf(inputname, "%s/%s", mailhome, alias_text);
- sprintf(hashname, "%s/%s", mailhome, alias_hash);
- sprintf(dataname, "%s/%s", mailhome, alias_data);
- system++;
- init_table(shash_table, MAX_SALIASES);
- }
- else
- printf("Updating your personal alias file...\n");
- }
-
- if (! system) {
- if (strcpy(home, getenv("HOME")) == NULL)
- exit(printf("Confused: No HOME variable in environment!\n"));
-
- sprintf(inputname, "%s/%s", home, alias_text);
- sprintf(hashname, "%s/%s", home, alias_hash);
- sprintf(dataname, "%s/%s", home, alias_data);
-
- init_table(uhash_table, MAX_UALIASES);
-
- read_in_system(shash_table, sizeof shash_table);
- }
-
- if ((in = fopen(inputname,"r")) == NULL)
- exit(printf("Couldn't open %s for input!\n", inputname));
-
- if ((hash = open(hashname, O_WRONLY | O_CREAT, 0644)) == -1)
- exit(printf("Couldn't open %s for output!\n", hashname));
-
- if ((data = fopen(dataname,"w")) == NULL)
- exit(printf("Couldn't open %s for output!\n", dataname));
-
- buff_loaded = 0; /* file buffer empty right now! */
-
- while (get_alias(in, buffer) != -1) {
- if (system)
- put_alias(data, buffer, shash_table, MAX_SALIASES);
- else
- put_alias(data, buffer, uhash_table, MAX_UALIASES);
- count++;
- }
-
- if (error) {
- printf("\n** Not saving tables! Please fix and re-run %s!\n",
- argv[0]);
- exit(1);
- }
- else {
- if (system)
- write(hash, shash_table, sizeof shash_table);
- else
- write(hash, uhash_table, sizeof uhash_table);
-
- close(hash);
- fclose(data);
- close(in);
-
- printf("Processed %d aliases\n", count);
- exit(0);
- }
- }
-
- int
- get_alias(file, buffer)
- FILE *file;
- char *buffer;
- {
- /* load buffer with the next complete alias from the file.
- (this can include reading in multiple lines and appending
- them all together!) Returns EOF after last entry in file.
-
- Lines that start with '#' are assumed to be comments and are
- ignored. White space as the first field of a line is taken
- to indicate that this line is a continuation of the previous. */
-
- static char mybuffer[SLEN];
- int done = 0, first_read = 1;
-
- /** get the first line of the entry... **/
-
- buffer[0] = '\0'; /* zero out line */
-
- do {
- if (get_line(file, mybuffer, first_read) == -1)
- return(-1);
- first_read = 0;
- if (mybuffer[0] != '#')
- strcpy(buffer, mybuffer);
- } while (strlen(buffer) == 0);
-
- /** now read in the rest (if there is any!) **/
-
- do {
- if (get_line(file, mybuffer, first_read) == -1) {
- buff_loaded = 0; /* force a read next pass! */
- return(0); /* okay. let's just hand 'buffer' back! */
- }
- done = (mybuffer[0] != ' ' && mybuffer[0] != TAB);
- if (mybuffer[0] != '#' && ! done)
- strcat(buffer, mybuffer);
- done = (done && mybuffer[0] != '#');
- } while (! done);
-
- return(0); /* no sweat! */
- }
-
- put_alias(data, buffer, table, size)
- FILE *data;
- char *buffer;
- struct alias_rec table[];
- int size;
- {
- /** break buffer down into two pieces: aliases, and address,
- throwing away the username (comment) field.
- Make the appropriate entries in the table (size) **/
-
- char aliases[LONG_STRING], address[LONG_STRING];
- int i = 0, j = 0;
-
- remove_all(' ', TAB, buffer);
-
- for (i=0; buffer[i] != ':' && i < LONG_STRING; i++)
- aliases[i] = buffer[i];
- aliases[i] = '\0';
-
- for (i=strlen(buffer)-1; buffer[i] != ':' && i > 0; i--)
- address[j++] = buffer[i];
- address[j] = '\0';
-
- reverse(address);
-
- add_to_table(data, aliases, address, table, size);
- }
-
- int
- get_line(file, buffer, first_line)
- FILE *file;
- char *buffer;
- int first_line;
- {
- /** read line from file. If first_line and buff_loaded,
- then just return! **/
- int stat;
-
- if (first_line && buff_loaded) {
- buff_loaded = 1;
- return;
- }
-
- buff_loaded = 1; /* we're going to get SOMETHING in the buffer */
-
- stat = fgets(buffer, SLEN, file) == NULL ? -1 : 0;
-
- if (stat != -1)
- no_ret(buffer);
-
- return(stat);
- }
-
- reverse(string)
- char *string;
- {
- /** reverse the order of the characters in string...
- uses a bubble-sort type of algorithm! **/
-
- register int f, l;
- char c;
-
- f = 0;
- l = strlen(string) - 1;
-
- while (f < l) {
- c = string[f];
- string[f] = string[l];
- string[l] = c;
- f++;
- l--;
- }
- }
-
- add_to_table(data, aliases, address, table, size)
- FILE *data;
- char *aliases, *address;
- struct alias_rec table[];
- int size;
- {
- /** add address to datafile, incrementing offset count (bytes),
- then for each alias in the aliases string, add to the
- hash table, with the associated pointer value! **/
-
- static char buf[SLEN], *word;
- long additive = 1L;
-
- word = buf; /* use the allocated space! */
-
- if (group(address)) {
- check_group(address, aliases);
- if (error) return; /* don't do work if we aren't to save it! */
- fprintf(data, "!%s\n", address);
- additive = 2L;
- }
- else {
- if (error) return; /* don't do work if we aren't to save it! */
- fprintf(data, "%s\n", address);
- }
-
- while ((word = (char *) strtok(aliases,", ")) != NULL) {
- add_to_hash_table(word, offset, table, size);
- aliases = NULL; /* let's get ALL entries via 'strtok' */
- count++;
- }
-
- if ( system ? count > MAX_SALIASES-35 : count > MAX_UALIASES-21) {
- printf("** Too many aliases in file! **\n");
- error++;
- }
-
- offset = (offset + (long) strlen(address) + additive);
- }
-
- remove_all(c1, c2, string)
- char c1, c2, *string;
- {
- /* remove all occurances of character 'c' from string. */
- char buffer[LONG_STRING];
- register int i = 0, j = 0;
-
- for (i = 0; string[i] != '\0' && i < LONG_STRING; i++)
- if (string[i] != c1 && string[i] != c2)
- buffer[j++] = string[i];
-
- buffer[j] = '\0';
- strcpy(string, buffer);
- }
-
- add_to_hash_table(word, offset, table, size)
- char *word;
- long offset;
- struct alias_rec table[];
- int size;
- {
- /** add word and offset to current hash table. **/
- register int loc;
-
- if (strlen(word) > 20)
- exit(printf("Bad alias name: %s. Too long.\n", word));
-
- loc = hash_it(word, size);
-
- while (table[loc].name[0] != '\0' && strcmp(table[loc].name, word) != 0)
- loc = loc + 1 % size;
-
- if (table[loc].name[0] == '\0') {
- strcpy(table[loc].name, word);
- table[loc].byte = offset;
- }
- else
- printf("** Duplicate alias '%s' in file. Multiples ignored.\n",
- word);
- }
-
- int
- hash_it(string, table_size)
- char *string;
- {
- /** compute the hash function of the string, returning
- it (mod table_size) **/
-
- register int i, sum = 0;
-
- for (i=0; string[i] != '\0'; i++)
- sum += (int) string[i];
-
- return(sum % table_size);
- }
-
- init_table(table, size)
- struct alias_rec table[];
- int size;
- {
- /** initialize hash table! **/
-
- register int i;
-
- for (i=0; i < size; i++)
- table[i].name[0] = '\0';
- }
-
- read_in_system(table, size)
- struct alias_rec table[];
- int size;
- {
- /** read in the system hash table...to check for group aliases
- from the user alias file (to ensure that there are no names
- in the user group files that are not purely contained within
- either alias table) **/
-
- int fd;
- char fname[SLEN];
-
- sprintf(fname, "%s/%s", mailhome, alias_hash);
-
- if ((fd = open(fname, O_RDONLY)) == -1)
- return; /* no sweat: flag 'hash_table_loaded' not set! */
-
- (void) read(fd, table, size);
- close(fd);
- hash_table_loaded++;
- }
-
- check_group(names, groupname)
- char *names, *groupname;
- {
- /** one by one make sure each name in the group is defined
- in either the system alias file or the user alias file.
- This search is linearly dependent, so all group aliases
- in the source file should appear LAST, after all the user
- aliases! **/
-
- char *word, *bufptr, buffer[LONG_STRING];
-
- strcpy(buffer, names);
- bufptr = (char *) buffer;
-
- while ((word = (char *) strtok(bufptr,", ")) != NULL) {
- if (! can_find(word))
- if (! valid_name(word)) {
- error++;
- printf("** Alias %s in group %s is bad!\n", word, groupname);
- }
- bufptr = NULL;
- }
- }
-
- int
- can_find(name)
- char *name;
- {
- /** find name in either hash table...use 'system' variable to
- determine if we should look in both or just system.... **/
-
- register int loc;
-
- if (strlen(name) > 20) {
- error++;
- printf("** Bad alias name: %s. Too long.\n", name);
- return(1); /* fake out: don't want 2 error messages! */
- }
-
- /** system alias table... **/
- if (hash_table_loaded || system) {
- loc = hash_it(name, MAX_SALIASES);
-
- while (strcmp(name, shash_table[loc].name) != 0 &&
- shash_table[loc].name[0] != '\0')
- loc = (loc + 1) % MAX_SALIASES;
-
- if (strcmp(name, shash_table[loc].name) == 0)
- return(1); /* found it! */
- }
-
- if (! system) { /* okay! Let's check the user alias file! */
- loc = hash_it(name, MAX_UALIASES);
-
- while (strcmp(name, uhash_table[loc].name) != 0 &&
- uhash_table[loc].name[0] != '\0')
- loc = (loc + 1) % MAX_UALIASES;
-
- if (strcmp(name, uhash_table[loc].name) == 0)
- return(1); /* found it! */
- }
-
- return(0);
- }
- END-OF-FILE
-
- if [ "$filename" != "/dev/null" ]
- then
- size=`wc -c < $filename`
-
- if [ $size != 11051 ]
- then
- echo $filename changed - should be 11051 bytes, not $size bytes
- fi
-
- chmod 666 $filename
- fi
-
- # ---------- file utils/printmail.c ----------
-
- filename="utils/printmail.c"
-
- if [ -f $filename ]
- then
- echo File \"$filename\" already exists\! Skipping...
- filename=/dev/null # throw it away
- else
- echo extracting file utils/printmail.c...
- fi
-
- cat << 'END-OF-FILE' > $filename
- /** printmail.c **/
-
- /** print mail, adding a formfeed between each message **/
- /** Modified to use stdin if being fed from a pipe. **/
-
- /** (C) Copyright 1985, Dave Taylor **/
-
- #include <stdio.h>
- #include "defs.h"
-
- static char ident[] = { WHAT_STRING };
-
- #define dashes \
- "\n\n------------------------------------------------------------------------------\n\n"
- #define FF "\014" /* form feed! */
-
- FILE *mailfile;
- char separator[80];
-
- main(argc, argv)
- int argc;
- char *argv[];
- {
- char infile[80], username[40], c;
-
- strcpy(separator, FF);
-
- *argv++; /* get past argv[0] */
-
- if (argc > 1)
- if (strcmp(*argv, "-d") == 0) {
- strcpy(separator, dashes);
- --argc;
- *argv++;
- }
-
- if (argc > 1 && *argv[0] == '-')
- exit(fprintf(stderr, "Usage: printmail {-d} {filename (s)}\n"));
-
- if (argc == 1) {
- strcpy(username, getlogin());
- if (strlen(username) == 0)
- cuserid(username);
- if (isatty(fileno(stdin))) { /* normal invokation... */
- sprintf(infile,"%s/%s",mailhome, username);
- if ((mailfile = fopen(infile,"r")) == NULL) {
- fprintf(stderr, "No mail!\n");
- exit(0);
- }
- }
- else
- mailfile = stdin; /* read from stdin! */
-
- if (read_headers() == 0)
- fprintf(stderr, "No messages in mailbox!\n");
- }
-
- if (argc > 1) /* more than one file - delimit each */
- if (strcmp(separator, FF) != 0)
- printf("\t\t\t%s\n%s", *argv, separator);
- else
- printf("\t\t\t%s\n\n", *argv); /* Don't put a formfeed! */
-
- while (--argc) {
- if ((mailfile = fopen(*argv,"r")) == NULL) {
- fprintf(stderr, "Could not open file '%s'!", *argv);
- break;
- }
- else
- if (read_headers() == 0)
- fprintf(stderr, "No messages in mailbox '%s'!\n", *argv);
- *argv++;
- if (argc) {
- if (strcmp(separator, FF) != 0)
- printf("%s\t\t\t%s%s", separator, *argv, separator);
- else
- printf("%s\t\t\t%s\n\n", separator, *argv);
- }
- }
- }
-
- int
- read_headers()
- {
- char buffer[100];
- register int count = 0;
-
- while (fgets(buffer, 100, mailfile) != NULL)
- if (first_word(buffer,"From ")) {
- if (real_from(buffer)) {
- printf("%s%s", count ? separator : "", buffer);
- count++;
- }
- }
- else
- printf("%s", buffer);
-
- return(count);
- }
-
- int
- real_from(buffer)
- char *buffer;
- {
- /***** returns true iff 's' has the seven 'from' fields *****/
-
- char junk[80];
-
- junk[0] = '\0';
- sscanf(buffer, "%*s %*s %*s %*s %*s %*s %s", junk);
- return(junk[0] != '\0');
- }
- END-OF-FILE
-
- if [ "$filename" != "/dev/null" ]
- then
- size=`wc -c < $filename`
-
- if [ $size != 2472 ]
- then
- echo $filename changed - should be 2472 bytes, not $size bytes
- fi
-
- chmod 666 $filename
- fi
-
- echo end of this archive file....
- exit 0
-
-