home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
unix
/
volume22
/
elm2.3
/
part24
< prev
next >
Wrap
Text File
|
1990-06-07
|
50KB
|
1,884 lines
Subject: v22i082: ELM mail syste, release 2.3, Part24/26
Newsgroups: comp.sources.unix
Approved: rsalz@uunet.UU.NET
X-Checksum-Snefru: 4eb49da1 1fd21ca1 8aa2115d 95ac623e
Submitted-by: Syd Weinstein <syd@dsinc.dsi.com>
Posting-number: Volume 22, Issue 82
Archive-name: elm2.3/part24
---- Cut Here and unpack ----
#!/bin/sh
# this is part 24 of a multipart archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file utils/answer.c continued
#
CurArch=24
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/answer.c"
sed 's/^X//' << 'SHAR_EOF' >> utils/answer.c
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 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 depth = 0, buffer_index = 0;
X
X for (; *string; string++) {
X if (*string == '(')
X depth++;
X else if (*string == ')')
X depth--;
X else if (depth == 0)
X buffer[buffer_index++] = *string;
X }
X
X buffer[buffer_index] = '\0';
X
X return( (char *) buffer);
X}
SHAR_EOF
echo "File utils/answer.c is complete"
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 4.1 90/04/28 22:44:33 syd Exp $";
X
X/*******************************************************************************
X * The Elm Mail System - $Revision: 4.1 $ $State: Exp $
X *
X * Copyright (c) 1986, 1987 Dave Taylor
X * Copyright (c) 1988, 1989, 1990 USENET Community Trust
X *******************************************************************************
X * Bug reports, patches, comments, suggestions should be sent to:
X *
X * Syd Weinstein, Elm Coordinator
X * elm@DSI.COM dsinc!elm
X *
X *******************************************************************************
X * $Log: arepdaem.c,v $
X * Revision 4.1 90/04/28 22:44:33 syd
X * checkin of Elm 2.3 as of Release PL0
X *
X *
X ******************************************************************************/
X
X/** Keep track of mail as it arrives, and respond by sending a 'recording'
X file to the sender as new mail is received.
X
X Note: the user program that interacts with this program is the
X 'autoreply' program and that should be consulted for further
X usage information.
X
X This program is part of the 'autoreply' system, and is designed
X to run every hour and check all mailboxes listed in the file
X "/etc/autoreply.data", where the data is in the form:
X
X username replyfile current-mailfile-size
X
X To avoid a flood of autoreplies, this program will NOT reply to mail
X that contains header "X-Mailer: fastmail". Further, each time the
X program responds to mail, the 'mailfile size' entry is updated in
X the file /etc/autoreply.data to allow the system to be brought
X down and rebooted without any loss of data or duplicate messages.
X
X This daemon also uses a lock semaphore file, /usr/spool/uucp/LCK..arep,
X to ensure that more than one copy of itself is never running. For this
X reason, it is recommended that this daemon be started up each morning
X from cron, since it will either start since it's needed or simply see
X that the file is there and disappear.
X
X Since this particular program is the main daemon answering any
X number of different users, it must be run with uid root.
X**/
X
X#include <stdio.h>
X#include "defs.h"
X
X#ifdef BSD
X# include <sys/time.h>
X#else
X# include <time.h>
X#endif
X
X#include <sys/types.h>
X#include <sys/stat.h>
X#include <signal.h>
X#include <fcntl.h>
X#include <errno.h>
X
Xstatic char ident[] = { WHAT_STRING };
X
X#define arep_lock_file "LCK..arep"
X
X#define autoreply_file "/etc/autoreply.data"
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
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
X#ifdef VOIDSIG
Xvoid term_signal();
X#else
Xint term_signal();
X#endif
X
Xmain()
X{
X long size;
X int person, data_changed;
X
X if (fork()) exit(0);
X
X if (! lock())
X exit(0); /* already running! */
X
X signal(SIGTERM, term_signal); /* Terminate signal */
X
X/*
X * note the usage of the BSD style setpgrp wont hurt
X * system V as its calling sequence is no arguments.
X * The idea is to disassociate from the terminal to
X * prevent signals.
X */
X person = getpid();
X setpgrp(person, person);
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/*
X * clear old entries prior to reread
X */
X for (person = 0; person < active; person++)
X reply_table[person].in_list = 0;
X
X if ((file = fopen(autoreply_file,"r")) == NULL) {
X log("No-one is using autoreply...");
X } else {
X while (fscanf(file, "%s %s %dl", username, replyfile, &size) != EOF) {
X /* check to see if this person is already in the list */
X if ((person = in_list(username)) != -1) {
X reply_table[person].in_list = 1;
X reply_table[person].mailsize = size; /* sync */
X }
X else { /* if not, add them */
X if (active == MAX_PEOPLE) {
X unlock();
X exit(log("Couldn't add %s - already at max people!",
X username));
X }
X log("adding %s to the active list", username);
X strcpy(reply_table[active].username, username);
X sprintf(reply_table[active].mailfile, "%s%s", mailhome, username);
X strcpy(reply_table[active].replyfile, replyfile);
X reply_table[active].mailsize = size;
X reply_table[active].in_list = 1; /* obviously! */
X active++;
X }
X }
X fclose(file);
X }
X
X /** now check to see if anyone has been removed... **/
X
X for (person = 0; person < active; person++)
X if (reply_table[person].in_list == 0) {
X log("removing %s from the active list",
X reply_table[person].username);
X strcpy(reply_table[person].username,
X reply_table[active-1].username);
X strcpy(reply_table[person].mailfile,
X reply_table[active-1].mailfile);
X strcpy(reply_table[person].replyfile,
X reply_table[active-1].replyfile);
X reply_table[person].mailsize = reply_table[active-1].mailsize;
X active--;
X }
X}
X
Xupdate_autoreply_file()
X{
X /** update the entries in the autoreply file... **/
X
X FILE *file;
X register int person;
X
X if ((file = fopen(autoreply_file,"w")) == NULL) {
X log("Couldn't update autoreply file!");
X return;
X }
X
X for (person = 0; person < active; person++)
X fprintf(file, "%s %s %ld\n",
X reply_table[person].username,
X reply_table[person].replyfile,
X reply_table[person].mailsize);
X
X fclose(file);
X
X/* printf("updated autoreply file\n"); */
X autoreply_size = bytes(autoreply_file);
X}
X
Xint
Xin_list(name)
Xchar *name;
X{
X /** search the current active reply list for the specified username.
X return the index if found, or '-1' if not. **/
X
X register int iindex;
X
X for (iindex = 0; iindex < active; iindex++)
X if (strcmp(name, reply_table[iindex].username) == 0)
X return(iindex);
X
X return(-1);
X}
X
Xread_newmail(person)
Xint person;
X{
X /** Read the new mail for the specified person. **/
X
X
X FILE *mailfile;
X char from_whom[SLEN], subject[SLEN];
X int sendit;
X
X log("New mail for %s", reply_table[person].username);
X
X if ((mailfile = fopen(reply_table[person].mailfile,"r")) == NULL)
X return(log("can't open mailfile for user %s",
X reply_table[person].username));
X
X if (fseek(mailfile, reply_table[person].mailsize, BEGINNING) == -1)
X return(log("couldn't seek to %ld in mail file!",
X reply_table[person].mailsize));
X
X while (get_return(mailfile, person, from_whom, subject, &sendit) != -1)
X if (sendit)
X reply_to_mail(person, from_whom, subject);
X
X return;
X}
X
Xint
Xget_return(file, person, from, subject, sendit)
XFILE *file;
Xint person, *sendit;
Xchar *from, *subject;
X{
X /** Reads the new message and return the from and subject lines.
X sendit is set to true iff it isn't a machine generated msg
X **/
X
X char name1[SLEN], name2[SLEN], lastname[SLEN];
X char buffer[SLEN], hold_return[NLEN];
X int done = 0, in_header = 0;
X
X from[0] = '\0';
X name1[0] = '\0';
X name2[0] = '\0';
X lastname[0] = '\0';
X *sendit = 1;
X
X while (! done) {
X
X if (fgets(buffer, SLEN, file) == NULL)
X return(-1);
X
X if (first_word(buffer, "From ")) {
X in_header++;
X sscanf(buffer, "%*s %s", hold_return);
X }
X else if (in_header) {
X if (first_word(buffer, ">From")) {
X sscanf(buffer,"%*s %s %*s %*s %*s %*s %*s %*s %*s %s", name1, name2);
X add_site(from, name2, lastname);
X }
X else if (first_word(buffer,"Subject:")) {
X remove_return(buffer);
X strcpy(subject, (char *) (buffer + 8));
X }
X else if (first_word(buffer,"X-Mailer: fastmail"))
X *sendit = 0;
X else if (strlen(buffer) == 1)
X done = 1;
X }
X }
X
X if (from[0] == '\0')
X strcpy(from, hold_return); /* default address! */
X else
X add_site(from, name1, lastname); /* get the user name too! */
X
X return(0);
X}
X
Xadd_site(buffer, site, lastsite)
Xchar *buffer, *site, *lastsite;
X{
X /** add site to buffer, unless site is 'uucp', or the same as
X lastsite. If not, set lastsite to site.
X **/
X
X char local_buffer[SLEN], *strip_parens();
X
X if (strcmp(site, "uucp") != 0)
X if (strcmp(site, lastsite) != 0) {
X if (buffer[0] == '\0')
X strcpy(buffer, strip_parens(site)); /* first in list! */
X else {
X sprintf(local_buffer,"%s!%s", buffer, strip_parens(site));
X strcpy(buffer, local_buffer);
X }
X strcpy(lastsite, strip_parens(site)); /* don't want THIS twice! */
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/fastmail -f '%s [autoreply]' -s '%s' %s %s",
X BIN, 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 *thetime;
X long clock;
X#ifndef _POSIX_SOURCE
X struct tm *localtime();
X long time();
X#endif
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")) == NULL)
X if ((fd = fopen(logfile2, "a")) == NULL) {
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[SLEN];
X register int depth = 0, buffer_index = 0;
X
X for (; *string; string++) {
X if (*string == '(')
X depth++;
X else if (*string == ')')
X depth--;
X else if (depth == 0)
X buffer[buffer_index++] = *string;
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 char lock_name[SLEN]; /* name of lock file */
X char pid_buffer[SHORT];
X int pid, create_fd;
X extern int errno; /* system error number! */
X
X sprintf(lock_name, "%s/%s", LOCK_DIR, arep_lock_file);
X#ifdef PIDCHECK
X /** first, try to read the lock file, and if possible, check the pid.
X If we can validate that the pid is no longer active, then remove
X the lock file.
X **/
X if((create_fd=open(lock_name,O_RDONLY)) != -1) {
X if (read(create_fd, pid_buffer, SHORT) > 0) {
X pid = atoi(pid_buffer);
X if (pid) {
X if (kill(pid, 0)) {
X close(create_fd);
X if (unlink(lock_name) != 0) {
X printf("Error %s (%s)\n\ttrying to unlink file %s (%s)\n",
X error_name(errno), error_description(errno), lock_name, "lock");
X return(0);
X }
X } else /* kill pid check succeeded */
X return(0);
X } else /* pid was zero */
X return(0);
X } else /* read failed */
X return(0);
X }
X /* ok, either the open failed or we unlinked it, now recreate it. */
X#else
X if (access(lock_name, EXISTS) == 0)
X return(0); /* file already exists */
X#endif
X
X if (create_fd=creat(lock_name, O_RDONLY) == -1)
X return(0); /* can't create file!! */
X
X sprintf(pid_buffer,"%d\n", getpid() ); /* write the current pid to the file */
X write(create_fd, pid_buffer, strlen(pid_buffer));
X close(create_fd); /* no need to keep it open */
X
X return(1);
X
X}
X
Xunlock()
X{
X /** remove lock file if it's there! **/
X
X (void) unlink(arep_lock_file);
X}
X
X#ifdef VOIDSIG
Xvoid term_signal()
X#else
Xint term_signal()
X#endif
X{
X unlock();
X exit(1); /* give up! */
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 4.1 90/04/28 22:44:35 syd Exp $";
X
X/*******************************************************************************
X * The Elm Mail System - $Revision: 4.1 $ $State: Exp $
X *
X * Copyright (c) 1986, 1987 Dave Taylor
X * Copyright (c) 1988, 1989, 1990 USENET Community Trust
X *******************************************************************************
X * Bug reports, patches, comments, suggestions should be sent to:
X *
X * Syd Weinstein, Elm Coordinator
X * elm@DSI.COM dsinc!elm
X *
X *******************************************************************************
X * $Log: autoreply.c,v $
X * Revision 4.1 90/04/28 22:44:35 syd
X * checkin of Elm 2.3 as of Release PL0
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#ifdef PWDINSYS
X# include <sys/pwd.h>
X#else
X# include <pwd.h>
X#endif
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 int userid;
X struct passwd *pass;
X#ifndef _POSIX_SOURCE
X struct passwd *getpwuid();
X#endif
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 userid = getuid();
X
X /*
X * Get username (logname) field from the password entry for this user id.
X */
X
X if((pass = getpwuid(userid)) == NULL) {
X printf("You have no password entry!");
X exit(1);
X }
X strcpy(username, pass->pw_name);
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/checkalias (Text)"
sed 's/^X//' << 'SHAR_EOF' > utils/checkalias &&
X: Use /bin/sh
X# checkalias: part of the Elm mail system
X# @(#)$Id: checkalias,v 4.1 90/04/28 22:44:36 syd Exp $
X
Xif [ "$*" = "" ]; then
X echo Usage: checkalias alias \[alias ...\] 1>&2
X exit 1
Xfi
X
Xexec elm -c $*
SHAR_EOF
chmod 0444 utils/checkalias || echo "restore of utils/checkalias fails"
echo "x - extracting utils/expand.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > utils/expand.c &&
X
Xstatic char rcsid[] = "@(#)$Id: expand.c,v 4.1 90/04/28 22:44:37 syd Exp $";
X
X/*******************************************************************************
X * The Elm Mail System - $Revision: 4.1 $ $State: Exp $
X *
X * Copyright (c) 1986, 1987 Dave Taylor
X * Copyright (c) 1988, 1989, 1990 USENET Community Trust
X *******************************************************************************
X * Bug reports, patches, comments, suggestions should be sent to:
X *
X * Syd Weinstein, Elm Coordinator
X * elm@DSI.COM dsinc!elm
X *
X *******************************************************************************
X * $Log: expand.c,v $
X * Revision 4.1 90/04/28 22:44:37 syd
X * checkin of Elm 2.3 as of Release PL0
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 return(NO);
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 return(NO);
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 return(NO);
X }
X
X /** Home now points to the string containing your maildir, with
X no leading or trailing white space...
X **/
X
X if ((expanded_dir = expand_define(home)) == NULL)
X return(NO);
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 return(YES);
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 return(NULL);
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 4.1 90/04/28 22:44:39 syd Exp $";
X
X/*******************************************************************************
X * The Elm Mail System - $Revision: 4.1 $ $State: Exp $
X *
X * Copyright (c) 1986, 1987 Dave Taylor
X * Copyright (c) 1988, 1989, 1990 USENET Community Trust
X *******************************************************************************
X * Bug reports, patches, comments, suggestions should be sent to:
X *
X * Syd Weinstein, Elm Coordinator
X * elm@DSI.COM dsinc!elm
X *
X *******************************************************************************
X * $Log: fastmail.c,v $
X * Revision 4.1 90/04/28 22:44:39 syd
X * checkin of Elm 2.3 as of Release PL0
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#include "defs.h"
X#include "patchlevel.h"
X
X#ifdef I_TIME
X# include <time.h>
X#endif
X#ifdef I_SYSTIME
X# include <sys/time.h>
X#endif
X#ifdef BSD
X# include <sys/types.h>
X# include <sys/timeb.h>
X#endif
X
Xstatic char ident[] = { WHAT_STRING };
X
X#define binrmail "/bin/rmail"
X#define temphome "/tmp/fastmail."
X
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#if defined(BSD) && !defined(_POSIX_SOURCE)
X char *timezone();
X#else
X extern char *tzname[];
X#endif
X
Xmain(argc, argv)
Xint argc;
Xchar *argv[];
X{
X
X extern char *optarg;
X extern int optind;
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 from_string[0] = '\0';
X subject[0] = '\0';
X replyto[0] = '\0';
X cc_list[0] = '\0';
X bcc_list[0] = '\0';
X to_list[0] = '\0';
X from_addr[0] = '\0';
X
X while ((c = getopt(argc, argv, "b:c:df:F:r:s:")) != EOF) {
X switch (c) {
X case 'b' : strcpy(bcc_list, optarg); break;
X case 'c' : strcpy(cc_list, optarg); break;
X case 'd' : debug++; break;
X case 'f' : strcpy(from_string, optarg); break;
X case 'F' : strcpy(from_addr, optarg); break;
X case 'r' : strcpy(replyto, optarg); break;
X case 's' : strcpy(subject, optarg); break;
X case '?' :
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");
X fprintf(stderr,"\t-f from-name\n\t-F from-addr\n");
X fprintf(stderr, "\t-r reply-to\n\t-s subject\n\n");
X exit(1);
X }
X }
X
X if (optind > 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[optind++]);
X
X if (optind > 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#ifdef HOSTCOMPILED
X strncpy(hostname, HOSTNAME, sizeof(hostname));
X#else
X gethostname(hostname, sizeof(hostname));
X#endif
X
X strcpy(username, getlogin());
X
X if (strlen(username) == 0)
X cuserid(username);
X
X if (access(filename, READ_ACCESS) == -1) {
X fprintf(stderr, "Error: can't find file %s!\n", filename);
X exit(1);
X }
X
X sprintf(tempfilename, "%s%d", temphome, getpid());
X
X if ((tempfile = fopen(tempfilename, "w")) == NULL) {
X fprintf(stderr, "Couldn't open temp file %s\n", tempfilename);
X exit(1);
X }
X
X /** Subject must appear even if "null" and must be first
X at top of headers for mail because the
X pure System V.3 mailer, in its infinite wisdom, now
X assumes that anything the user sends is part of the
X message body unless either:
X 1. the "-s" flag is used (although it doesn't seem
X to be supported on all implementations??)
X 2. the first line is "Subject:". If so, then it'll
X read until a blank line and assume all are meant
X to be headers.
X So the gory solution here is to move the Subject: line
X up to the top. I assume it won't break anyone elses program
X or anything anyway (besides, RFC-822 specifies that the *order*
X of headers is irrelevant). Gahhhhh....
X **/
X fprintf(tempfile, "Subject: %s\n", subject);
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(replyto) > 0)
X fprintf(tempfile, "Reply-To: %s\n", replyto);
X
X while (optind < argc)
X sprintf(to_list, "%s%s%s", to_list, (strlen(to_list) > 0? " ":""),
X argv[optind++]);
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 fprintf(tempfile, "X-Mailer: fastmail [version %s PL%d]\n",
X VERSION, PATCHLEVEL);
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 if (debug)
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 c = system(command_buffer);
X
X unlink(tempfilename);
X
X exit(c != 0);
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 long junk; /* time in seconds.... */
X#ifndef _POSIX_SOURCE
X struct tm *localtime();
X#endif
X#ifdef BSD
X# ifndef TZ_MINUTESWEST
X struct timeb loc_time; /* of course this is different! */
X# ifndef _POSIX_SOURCE
X long time();
X# endif
X# else
X struct timeval time_val;
X struct timezone time_zone;
X# endif
X#else
X long time();
X#endif
X
X#ifdef BSD
X# ifndef TZ_MINUTESWEST
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#if defined(BSD) && !defined(_POSIX_SOURCE)
X# ifndef TZ_MINUTESWEST
X timezone(loc_time.time_zone, the_time->tz_isdst));
X# else
X# ifdef GOULD_NP1
X the_time->tm_zone);
X# else
X timezone(time_zone.tz_minuteswest, time_zone.tz_dsttime));
X# endif
X# endif
X#else
X tzname[the_time->tm_isdst]);
X#endif
X
X return( (char *) buffer);
X}
SHAR_EOF
chmod 0444 utils/fastmail.c || echo "restore of utils/fastmail.c fails"
echo "x - extracting utils/from.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > utils/from.c &&
X
Xstatic char rcsid[] = "@(#)$Id: from.c,v 4.1 90/04/28 22:44:41 syd Exp $";
X
X/*******************************************************************************
X * The Elm Mail System - $Revision: 4.1 $ $State: Exp $
X *
X * Copyright (c) 1986, 1987 Dave Taylor
X * Copyright (c) 1988, 1989, 1990 USENET Community Trust
X *******************************************************************************
X * Bug reports, patches, comments, suggestions should be sent to:
X *
X * Syd Weinstein, Elm Coordinator
X * elm@DSI.COM dsinc!elm
X *
X *******************************************************************************
X * $Log: from.c,v $
X * Revision 4.1 90/04/28 22:44:41 syd
X * checkin of Elm 2.3 as of Release PL0
X *
X *
X ******************************************************************************/
X
X/** print out whom each message is from in the pending folder or specified
X one, including a subject line if available..
X
X**/
X
X#include <stdio.h>
X#include <pwd.h>
X#include "defs.h"
X
Xstatic char ident[] = { WHAT_STRING };
X
X#ifdef MMDF
Xchar username[SLEN] = {0};
X#endif /* MMDF */
X
X#define LINEFEED (char) 10
X
X#define metachar(c) (c == '=' || c == '+' || c == '%')
X
XFILE *mailfile;
X
Xint number = 0, /* should we number the messages?? */
X verbose = 0; /* and should we prepend a header? */
X
Xmain(argc, argv)
Xint argc;
Xchar *argv[];
X{
X char infile[SLEN], *cp ;
X int multiple_files = 0, output_files = 0, c;
X struct passwd *pass;
X#ifndef _POSIX_SOURCE
X struct passwd *getpwuid();
X#endif
X extern int optind;
X
X while ((c = getopt(argc, argv, "nv")) != EOF)
X switch (c) {
X case (int)'n': number++; break;
X case (int)'v': verbose++; break;
X case (int)'?': printf("Usage: %s [-n] [-v] {filename | username}\n",
X argv[0]);
X exit(1);
X }
X
X infile[0] = '\0';
X if (optind == argc) {
X /*
X * determine mail file from environment variable if found,
X * else use password entry
X */
X if ((cp = getenv("MAIL")) == NULL) {
X if((pass = getpwuid(getuid())) == NULL) {
X printf("You have no password entry!");
X exit(1);
X }
X sprintf(infile,"%s%s",mailhome, pass->pw_name);
X }
X else
X strcpy(infile, cp);
X optind -= 1; /* ensure one pass through loop */
X }
X
X#ifdef MMDF
X if((pass = getpwuid(getuid())) == NULL) {
X printf("You have no password entry!");
X exit(1);
X }
X strcpy(username,pass->pw_name);
X#endif /* MMDF */
X
X multiple_files = (argc - optind > 1);
X
X while (optind < argc) {
X
X if (multiple_files) {
X strcpy(infile, argv[optind]);
X printf("%s%s: \n", output_files++ > 0 ? "\n":"", infile);
X }
X else if (infile[0] == '\0')
X strcpy(infile, argv[optind]);
X
X if (metachar(infile[0])) {
X if (expand(infile) == 0) {
X fprintf(stderr, "%s: couldn't expand filename %s!\n",
X argv[0], infile);
X exit(1);
X }
X }
X
X if ((mailfile = fopen(infile,"r")) == NULL) {
X if (optind+1 == argc)
X printf("No mail.\n");
X else {
X if (infile[0] == '/')
X printf("Couldn't open folder \"%s\".\n", infile);
X else {
X sprintf(infile,"%s%s", mailhome, argv[optind]);
X if ((mailfile = fopen(infile,"r")) == NULL)
X printf("Couldn't open folders \"%s\" or \"%s\".\n",
X argv[optind], infile);
X else {
X if (read_headers()==0)
X printf("No messages in that folder!\n");
X fclose(mailfile);
X }
X }
X }
X } else {
X if (read_headers(optind+1 == argc)==0)
X if (optind+1 == argc)
X printf("No mail\n");
X else
X printf("No messages in that folder!\n");
X fclose(mailfile);
X }
X
X optind++;
X }
X exit(0);
X}
X
Xint
Xread_headers(user_mailbox)
Xint user_mailbox;
X{
X /** Read the headers, output as found. User-Mailbox is to guarantee
X that we get a reasonably sensible message from the '-v' option
X **/
X
X char buffer[SLEN], from_whom[SLEN], subject[SLEN];
X register int in_header = 0, count = 0;
X#ifdef MMDF
X int newheader = 0;
X#endif /* MMDF */
X
X while (fgets(buffer, SLEN, mailfile) != NULL) {
X if (index(buffer, '\n') == NULL && !feof(mailfile)) {
X int c;
X while ((c = getc(mailfile)) != EOF && c != '\n')
X ; /* keep reading */
X }
X
X#ifdef MMDF
X if (strcmp(buffer, MSG_SEPERATOR) == 0) {
X newheader = !newheader;
X if (newheader) {
X subject[0] = '\0';
X in_header = 1;
X }
X }
X#else
X if (first_word(buffer,"From ")
X && real_from(buffer, from_whom)) {
X subject[0] = '\0';
X in_header = 1;
X }
X#endif /* MMDF */
X else if (in_header) {
X#ifdef MMDF
X if (first_word(buffer,"From "))
X real_from(buffer, from_whom);
X#endif /* MMDF */
X if (first_word(buffer,">From "))
X forwarded(buffer, from_whom); /* return address */
X else if (first_word(buffer,"Subject:") ||
X first_word(buffer,"Re:")) {
X if (subject[0] == '\0') {
X remove_first_word(buffer);
X strcpy(subject, buffer);
X }
X }
X else if (first_word(buffer,"From:") ||
X first_word(buffer, ">From:"))
X parse_arpa_from(buffer, from_whom);
X else if (buffer[0] == LINEFEED) {
X if (verbose && count == 0)
X printf("%s contains the following messages:\n\n",
X user_mailbox?"Your mailbox" : "Folder");
X#ifdef MMDF
X if (*from_whom == '\0')
X strcpy(from_whom,username);
X#endif /* MMDF */
X ++count;
X show_header(count, from_whom, subject);
X in_header = 0;
X }
X }
X }
X return(count);
X}
X
Xint
Xreal_from(buffer, who)
Xchar *buffer, *who;
X{
X /***** returns true iff 's' has the seven 'from' fields,
X initializing the who to the sender *****/
X
X char junk[SLEN];
X
X junk[0] = '\0';
X sscanf(buffer, "%*s %s %*s %*s %*s %*s %s",
X who, junk);
X return(junk[0] != '\0');
X}
X
Xforwarded(buffer, who)
Xchar *buffer, *who;
X{
X /** change 'from' and date fields to reflect the ORIGINATOR of
X the message by iteratively parsing the >From fields... **/
X
X char machine[SLEN], buff[SLEN], holding_from[SLEN];
X
X machine[0] = '\0';
X holding_from[0] = '\0';
X sscanf(buffer, "%*s %s %*s %*s %*s %*s %*s %*s %*s %*s %s",
X holding_from, machine);
X
X if(machine[0] == '\0') /* try for address with timezone in date */
X sscanf(buffer, "%*s %s %*s %*s %*s %*s %*s %*s %*s %s",
X holding_from, machine);
X
X if (machine[0] == '\0') /* try for srm address */
X sscanf(buffer, "%*s %s %*s %*s %*s %*s %*s %*s %s",
X holding_from, machine);
X
X if (machine[0] == '\0')
X sprintf(buff, holding_from[0] ? holding_from : "anonymous");
X else
X sprintf(buff,"%s!%s", machine, holding_from);
X
X strncpy(who, buff, SLEN);
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
Xshow_header(count, from, subject)
Xint count;
Xchar *from, *subject;
X{
X /** output header in clean format, including abbreviation
X of return address if more than one machine name is
X contained within it! **/
X
X char buffer[SLEN];
X int loc, i=0, exc=0, len;
X
X#ifndef INTERNET
X char *p;
X
X if (chloc(from,'!') != -1 && chloc(from,'@') > 0) {
X for (p=from;*p != '@'; p++) ;
X *p = '\0';
X }
X#endif
X
X loc = strlen(from);
X
X while (exc < 2 && loc > 0)
X if (from[--loc] == '!')
X exc++;
X
X if (exc == 2) { /* lots of machine names! Get last one */
X loc++;
X len = strlen(from);
X while (loc < len && loc < SLEN)
X buffer[i++] = from[loc++];
X buffer[i] = '\0';
X if (number)
X printf("%3d: %-20s %s\n", count, buffer, subject);
X else
X printf("%-20s %s\n", buffer, subject);
X }
X else
X if (number)
X printf("%3d: %-20s %s\n", count, from, subject);
X else
X printf("%-20s %s\n", from, subject);
X}
X
Xparse_arpa_from(buffer, newfrom)
Xchar *buffer, *newfrom;
X{
X /** try to parse the 'From:' line given... It can be in one of
X two formats:
X From: Dave Taylor <hpcnou!dat>
X or From: hpcnou!dat (Dave Taylor)
X Change 'newfrom' ONLY if sucessfully parsed this entry and
X the resulting name is non-null!
X **/
X
X char temp_buffer[SLEN], *temp;
X register int i, j = 0, in_parens;
X
X temp = (char *) temp_buffer;
X temp[0] = '\0';
X
X no_ret(buffer); /* blow away '\n' char! */
X
X if (lastch(buffer) == '>') {
X for (i=strlen("From: "); buffer[i] != '\0' && buffer[i] != '<' &&
X buffer[i] != '('; i++)
X temp[j++] = buffer[i];
X temp[j] = '\0';
X }
X else if (lastch(buffer) == ')') {
X in_parens = 1;
X for (i=strlen(buffer)-2; buffer[i] != '\0' && buffer[i] != '<'; i--) {
X switch(buffer[i]) {
X case ')': in_parens++;
X break;
X case '(': in_parens--;
X break;
X }
X if(!in_parens) break;
X temp[j++] = buffer[i];
X }
X temp[j] = '\0';
X reverse(temp);
X }
X
X/* this stuff copied from src/addr_util.c */
X#ifdef USE_EMBEDDED_ADDRESSES
X
X /** if we have a null string at this point, we must just have a
X From: line that contains an address only. At this point we
X can have one of a few possibilities...
X
X From: address
X From: <address>
X From: address ()
X **/
X
X if (strlen(temp) == 0) {
X if (lastch(buffer) != '>') {
X for (i=strlen("From:");buffer[i] != '\0' && buffer[i] != '('; i++)
X temp[j++] = buffer[i];
X temp[j] = '\0';
X }
X else { /* get outta '<>' pair, please! */
X for (i=strlen(buffer)-2;buffer[i] != '<' && buffer[i] != ':';i--)
X temp[j++] = buffer[i];
X temp[j] = '\0';
X reverse(temp);
X }
X }
X#endif
X
X if (strlen(temp) > 0) { /* mess with buffer... */
X
X /* remove leading spaces... */
X
X while (whitespace(temp[0]))
X temp = (char *) (temp + 1); /* increment address! */
X
X /* remove trailing spaces... */
X
X i = strlen(temp) - 1;
X
X while (whitespace(temp[i]))
X temp[i--] = '\0';
X
X /* remove surrounding paired quotation marks */
X if((temp[i] == '"') & (*temp == '"')) {
SHAR_EOF
echo "End of part 24"
echo "File utils/from.c is continued in part 25"
echo "25" > s2_seq_.tmp
exit 0
"File utils/answer.c is continued in part 24"
echo "24" > s2_seq_.tmp
exit 0
exit 0 # Just in case...