[net.sources] mailway for 4bsd systems

arnold@ucsfcgl.UUCP (Ken Arnold%CGL) (05/09/86)

#! /bin/sh
#
# The mailway program recently posted failed to work on my system,
# mostly because the system V and bsd mail programs are quite
# different.  It also could not handle general mail addresses, such as
# "a@b", "a%b", and "@a:b", so it has been fixed to handle these (other
# types may pop up, and will also be handle as I can manage.  Also,
# there was a '=' instead of '==' bug.  Here is a copy of the source
# and manual page, as a shar file.  To compile for System V systems,
# compile with -DSYSV.  Otherwise it will compile for Berkeley.  The
# changes are
#
#	(a)	Work with Berkeley Mail program
#	(b)	Run under non-sysV systems (only tested on 4.3bsd)
#	(c)	Add a -m flag to specifiy an alternate mail file
#	(d)	Handle general net addressing (at least normal ones)
#	(e) 	Fix a bug
#	(f)	Optimize a couple of things
#
# While I was at it, I also redid mailaway.1 to fit the standard manual
# style, since I had to update the page to include the new option.
#
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create:
#	mailaway.1
#	mailaway.c
# This archive created: Thu May  8 15:31:29 1986
export PATH; PATH=/bin:/usr/bin:$PATH
if test -f 'mailaway.1'
then
	echo shar: "will not over-write existing file 'mailaway.1'"
else
cat << \SHAR_EOF > 'mailaway.1'
.TH MAILAWAY 1 "HFVR"
.SH NAME
.\" name \- one-line description for in permuted index
mailaway \- Unix mail answering service
.SH SYNOPSIS
.\" bnf on command syntax
.B mailaway
[
.B \-dVH
] [
.B \-f
.I file
] [
.B \-m
.I mailfile
] [
.B \-o
.I options
] [
.B \-x
.I pgrm
]
.SH DESCRIPTION
.\" semantics
Mailaway will determine for each electronic message waiting for
you, the following facts:
.IP SUBJECT \w'NROFLINES\ \ 'u
The subject of this message (if any) (leading spaces stripped)
.IP SENDER
The login name of the sender
.IP NROFLINES
The length of the message in lines
.IP SIZE
The size of the message in characters
.IP VIA
The full path (including
.BR SENDER )
used to send this message
.IP MESSAGE
The name of the file containing a copy of the message
.IP DEMON
Either
.SM
.B TRUE
or
.SM
.B FALSE
if sender is a known demon
.IP LAST
Either
.SM
.B TRUE
or
.SM
.B FALSE
if this was last message or not
.PP
These facts are stored into shell variables of the same name. After
doing so this information is passed on to the executor (default:
.BR /bin/sh )
for execution. After the executor stops the message is deleted.
.SH OPTIONS
.IP \-f 5n
Takes as argument the name of a file which will also be passed
to the executor (default is
.IR $HOME/.mailawayrc ).
.IP \-m
Takes as argument the name of the file which contains the mail to be processed
instead of the system mailbox file.
.IP \-x
Takes as argument the name of an alternative for the executor.
(default is
.BR /bin/sh ).
.IP \-o
Takes one argument which will be passed to the executor as
command line option. Default is empty.
.SH EXAMPLES
To append all your messages to a file
.I $HOME/x
you can use:
.PP
.RS
mailaway \-f append
.RE
.PP
Where
.I append
is a shell script containing the line:
.PP
.RS
cat $MESSAGE >> $HOME/x
.RE
.PP
To append messages to files depending on the sender of the message
use:
.PP
.RS
mailaway \-f append2
.RE
.PP
Where
.I append2
is a shell script containing the line:
.PP
.RS
cat $MESSAGE >> $HOME/mail/$SENDER
.RE
.PP
To automatically answer your mail while away:
.PP
.RS
mailaway \-f answerit
.RE
.PP
Where
.I answerit
could contains the lines:
.PP
.RS
.ta
.ta 4n +4n +4n +4n +4n +4n +4n +4n +4n +4n +4n +4n +4n +4n +4n +4n +4n
.nf
if test "$DEMON" = "TRUE"
then
	exit	# ignore them
fi

# reply to sender

/bin/mail $VIA <<!!
Subject: Auto answering service
Dear $SENDER,
I am away right now but received your message at `date`
I will answer it as soon as a return on 1 April.
!!

cat $MESSAGE >> $HOME/mail/.stack_of_mail	# save it
if test "$SENDER" = "myboss"	# see if needs forwarding
then
	TMP=/usr/tmp/$$
	cat > $TMP <<!!
Dear representative,
Could you treat the following message?

bvd, $LOGIN

!!
	cat $MESSAGE >> $TMP
	/bin/mail friend < $TMP
	rm \-f $TMP
fi
.fi
.RE
.PP
The following script can be used for those logins that are yours to
maintain but usually you do not login there. However you do want
mail forwarded to you that looks like it is personal.
.PP
.RS
mailaway \-f getpersonal
.RE
.PP
Where
.I getpersonal
contains:
.PP
.RS
.nf
if test "$DEMON" = "TRUE"
then
	exit # just ignore these
fi

# save all mail that are used as updates (have 'update' in
# subject)

echo $SUBJECT | grep \-i 'update' >/dev/null 2>&1
if test "$?" = "0"
then
	cat $MESSAGE >> $HOME/todo/updates
fi

# forward all other stuff
/bin/mail yourlogin < $MESSAGE
.RE
.fi
.SH FILES
.RI /usr/spool/mail/ login-name
.I or
$MAIL
.br
$HOME/.mailawayrc
.SH "BE AWARE"
Be aware that if you use
.IR cron (8)
to execute
.BR mailaway ,
the output is
sent as mail, it is therefore best to redirect
.I stdout
and
.I stderr
to some log file as follows:
.PP
.RS
mailaway ..... >$HOME/log 2>&1
.RE
.PP
.SH SEE ALSO
mail(1), answer(1), crontab(1)
SHAR_EOF
fi
if test -f 'mailaway.c'
then
	echo shar: "will not over-write existing file 'mailaway.c'"
else
cat << \SHAR_EOF > 'mailaway.c'
/* mailaway.c -*-update-version-*-
** program to auto execute some shell script for each mail message waiting
** HFVR VERSION=Wed Mar 19 08:12:25 1986
**
** Modified by Ken Arnold, 8 April 1986 to:
**	(a)	Work with Berkeley Mail program
**	(b)	Run under non-sysV systems (only tested on 4.3bsd)
**	(c)	Add a -m flag to specifiy an alternate mail file
**	(d)	Handle general net addressing (at least normal ones)
**	(e) 	Fix a bug
**	(f)	Optimize a couple of things
** Called version 0.9.1
*/

#include 	<stdio.h>
#include	<ctype.h>
#include	<pwd.h>

#define equal		!strcmp
#define equaln		!strncmp
#define	TRUE	1
#define	FALSE	0
#define	TOSIZE		512		/* size of buffer to hold dests */
#define MAXLINES	50		/* max nr of from lines */
#define LINELENGTH	256		/* max length from line */

#ifndef SYSV
#define	MAILPROG	"/usr/ucb/mail"	/* where Berkeley mail program lives */
#define	strchr		index
#define	strrchr		rindex
#endif

char	fflag[LINELENGTH];	/* file to include */
char	xflag[LINELENGTH];	/* program to execute file (executor)*/
char	oflag[LINELENGTH];	/* options to program */
char	mflag[LINELENGTH];	/* alternate mail file to use */
int	dflag = FALSE;		/* to debug */

char 	TEMPA[]		= "/usr/tmp/AXXXXXX";	/* message file */
char	TEMPM[]		= "/usr/tmp/MXXXXXX";	/* copy of whole $MAIL */
char	TEMPS[]		= "/usr/tmp/SXXXXXX";	/* file to execute */
char	NAME[]		= "mailaway";		/* program name */
char 	subject[]	= "Subject:";		/* start of subject line */
char	rmtfrom[]	= " remote from ";
char	fwrdmsg[]	= " forwarded by ";
char	from[] 		= "From ";

FILE *f1;				/* input file */
char *lp;				/* pointer for reading file */
char	line[LINELENGTH];		/* line last read from f1 */
int frcnt;				/* nr of from lines in message */
char	frlist[MAXLINES][LINELENGTH];	/* from lines in message */

/* variables to determine from message */
char	SUBJECT[LINELENGTH];	/* whats behind Subject: */
char	SENDER[LINELENGTH];	/* login name of sender */
int	NROFLINES;		/* length of message */
int	SIZE;			/* size in chars. of message */
char	VIA[TOSIZE];		/* full return mail address */
char	MESSAGE[LINELENGTH];	/* filename where message is saved */
char	DEMON[6];		/* TRUE or FALSE */
char	LAST[6];		/* TRUE or FALSE */

/* EXTERNAL ROUTINES FROM OUR LIBRARIES */
extern	char	*strchr(/* s , c */);
/*	char	*s;
**	int	c;
**
** Returns a pointer to the first occurence of character s in string s,
** or a NULL pointer if c does not occur in the string s. 
** The null character terminating the string is considered part of the string.
*/

extern	char	*strrchr(/* s , c */);
/*	char	*s;
**	int	c;
**
** Returns a pointer to the last occurence of character s in string s,
** or a NULL pointer if c does not occur in the string s. 
** The null character terminating the string is considered part of the string.
*/

extern char	*getenv(/* sp */);
/*	char	*sp;
**
** Returns a pointer to the value of the environment variable named by
** "sp".  If no such variable is named, it can return either NULL or
** "", depending on the system.
*/

/* END OF EXTERNAL ROUTINES */

void	finit();

char	*one_in();

/* sindex looks for an occurance  of the string s2 in the string
** s1. If s2 does not ocurr, sindex returns -1. Otherwise, sindex
** returns the integer offset from s1 where s2 ocurrs.
*/
int sindex(s1,s2)
register char *s1;
register char *s2;
{	
	register char *p1;
	register char *p2;
	register int flag;
	register int ii;

	p1 = &s1[0];
	p2 = &s2[0];
	flag = -1;
	for(ii = 0; ; ii++) {
		while(*p1 == *p2) {
			if(flag < 0) flag = ii;
			if(*p1++ == 0) return(flag);
			p2++;
		}
		if(*p2 == 0) return(flag);
		if(flag >= 0) {
			flag = -1;
			p2 = &s2[0];
		}
		if(*s1++ == 0) return(flag);
		p1 = s1;
	}
}/*sindex*/

/* returns pointer to string with sender address in it
** input is frlist[] with lines like:
**
** [>]From USER DATE 				or
** [>]From USER DATE forwarded by WHOCARES	or
** [>]From USER DATE remote from MACHINE
**
** some lines might be duplicated
** we save only the last USER and string together all MACHINEs
** except if the previous machine equals the current one
** forwarded by lines are simply ignored
** address format is mach!mach!....!user or user
** if flg TRUE then it is also printed to stdout
*/
char *frflsh(flg)
{	
	static char address[TOSIZE] ;
	char user[80];
	char mach1[80]  ;	/* previous machine name */
	char mach2[80]  ; 	/* current machine name */
	register int i;
	register int j;
	register char *p;
	register char *q;

	strcpy(address,"");
	strcpy(mach1,"");

	for (i = 0 ; i < frcnt ; i++) { /* examine every From line */
		p = frlist[i] ;
		if ( *p == '>' ) p++;	/* skip leading > */
		if ( equaln(p, from , 5 ) ) {
			p += 5;			/* skip FromSP */
		} else {
			continue; /* does not match FromSP , try next line */
		}

		/* get user from line and skip past it */
		/* but first skip past spaces and tabs */
		while ( isspace(*p) )
			p++;
		q = user;
		while ( *p != '\0' && !isspace(*p))
			*q++ = *p++;
		*q = '\0';

		/* get machine name */
		strcpy(mach1,mach2);	/* save previous name */

		/* see if 'remote from' in line */
		j = sindex(frlist[i], rmtfrom) ;
		if ( j == -1 ) continue ; /* no so try next line */

		p = &frlist[i][j+sizeof(rmtfrom) -1];	/* skip past remote from */
		while ( *p != '\0' && isspace(*p))	/* skip spaces */
		q = mach2;
		while ( *p != '\0' && !isspace(*p))
			*q++ = *p++;
		*q = '\0';

		/* append to address if different from previous machine mach1 */
		if ( equal(mach1,mach2) ) {
			continue;	/* equal so skip it */
		} else {
			strcat(address,mach2);
			strcat(address,"!");
		}
	}/* for */

	strcat(address,user);
	if (flg) printf("Sender=%s\n",address);
	return(address);
}/*frflsh*/

/* Determine if line is genuine article.
** Should be of 2 forms:
** From.*[0-9][0-9]:[0-9][0-9].*
** 	or
** >From.*[0-9][0-9]:[0-9][0-9].*
**
** The [0-9] stuff is the date representation by ctime.
** Some systems use only the 09:43 part of the time (i.e.
** no seconds representation).
*/
Isfrom(line)
register char *line;	/* line to parse */
{	
	register char *p;

	if(equaln(line, from, 5))
	{
		if((p=strchr(line, ':')) != NULL)
		{
colontest:
			if(	isdigit(p[-2]) &&
			    isdigit(p[-1]) &&
			    isdigit(p[1]) &&
			    isdigit(p[2]))      return(1);
		}
		/*
		 *	If more colons, try again.
		 */
		if(p=strchr(++p, ':'))
			goto colontest;
	}
	return(0);
}/*Isfrom*/

/* fillfrom: fills frlist[] with FROM lines and sets frcnt to nr of lines 
** also set all mail variables
*/
int fillfrom()
{ 	
	char *ptr;
	register char	*sp;
	auto char	tmp[sizeof VIA];

	frcnt = 0;
	/* set all message variables to defaults */
	strcpy(SUBJECT,"");
	strcpy(SENDER,"");
	NROFLINES = 0;
	SIZE = 0;
	strcpy(VIA,"");
	strcpy(MESSAGE,"");
	strcpy(DEMON,"FALSE");
	strcpy(LAST,"FALSE");

	/* skip until From is found */
	while ( lp != NULL && !Isfrom(line)) {
		lp = fgets(line, LINELENGTH, f1);
	}
	if ( NULL == lp ) return(FALSE);	/* EOF */

	/* copy in first From line */
	strcpy(frlist[frcnt] , line);
	NROFLINES++;
	SIZE = SIZE + strlen(line);
	frcnt++;

	/* copy in >From lines */
	lp = fgets(line, LINELENGTH, f1);
	while ( lp != NULL && Isfrom(line+1)) {
		strcpy(frlist[frcnt] , line);
		NROFLINES++;
		SIZE = SIZE + strlen(line);
		frcnt++;
		lp = fgets(line, LINELENGTH, f1);
	}
	if  ( NULL == lp ) return(FALSE);	/* EOF */
	strcpy(VIA, frflsh(0));	/* get VIA */

	/* get SENDER */
	strcpy(tmp, VIA);
	ptr = tmp;
	if (one_in(tmp, "!%@") != NULL)
		while (two_in(ptr, "!%@")) {
			if (*ptr == '@') {	/* @mach:<rest of route> */
				ptr++;
				while (*ptr != ':' && *ptr != '@')
					ptr++;
				if (*ptr == '@') /* handle @mach1@mach2 */
					ptr--;
				else
					ptr++;	/* skip over ':' */
			}
			else if ((sp = strrchr(ptr, '@')) != NULL)
				*sp = '\0';	/* strip off trailing name */
			else if ((sp = strrchr(ptr, '%')) != NULL)
				*sp = '\0';	/* strip off trailing name */
			else {
				while (*ptr != '!')
					ptr++;
				ptr++;		/* skip over the ! or % */
			}
		}
	strcpy(SENDER, ptr);

	/* determine if demon, default = FALSE */
	if ( (equal (ptr , "**NSC**" ))  ||
	    (equaln(ptr , "NUSEND",6))  ||
	    (equal (ptr , "uucp"    ))  ||
	    (equal (ptr , "**RJE**" ))  ||
	    (equal (ptr , "root"    ))  ||
	    (equal (ptr , "nhcms"   ))  ||
	    (equal (ptr , "demon"   ))  ||
	    (equal (ptr , "deamon"  ))  ||
	    (equal (ptr , "daemon"  ))
	    ) {
		strcpy(DEMON,"TRUE");
	}/*fi*/

	/* now look through text until subject or start next message */
	while ( lp != NULL && !Isfrom(line)) {
		if (equaln(line,subject,strlen(subject))) {
			/* skip past spaces */
			ptr = &line[strlen(subject)];
			while (*ptr == ' ') {
				ptr++;
			}
			strcpy(SUBJECT,ptr);
			SUBJECT[strlen(SUBJECT)-1] = '\0'; /* take of CR */
			break;
		}/*fi*/
		NROFLINES++;
		SIZE = SIZE + strlen(line);
		lp = fgets(line, LINELENGTH, f1);
	}

	/* now just look through text until start of next message or EOF */
	while ( lp != NULL && !Isfrom(line)) {
		NROFLINES++;
		SIZE = SIZE + strlen(line);
		lp = fgets(line, LINELENGTH, f1);
	}

	if  ( NULL == lp ) strcpy(LAST,"TRUE");	/* EOF means last message */
	return(TRUE);
}/*fillfrom*/

/* copy mail file to TEMPM so we can process it */
void readmail()
{
	char cmd[LINELENGTH];

	mktemp(TEMPM);
	unlink(TEMPM);
#ifdef SYSV
	sprintf(cmd, "/bin/mail -p -r -f %s > %s", mflag, TEMPM);
#else
	sprintf(cmd, "cp %s %s", mflag, TEMPM);
#endif
	if (dflag) printf("cmd=%s\n",cmd);
	system(cmd);
}/*readmail*/

/* check to see if message was saved okay */
chkmsg()
{
	FILE *f2;

	f2 = fopen(MESSAGE,"r");
	if (f2 == NULL) {
		fprintf(stderr,"%s: ERROR cannot open message file %s\n",NAME,
			MESSAGE);
		exit(1);
	}
	fclose(f2);
}/*chkmsg*/

/* save message into temp file after deleting previous version */
#ifndef SYSV
/*
 * We don't use sockets here so that it will work on any UNIX system
 * which has Berkeley Mail.  Portability is more important than the
 * efficieny and elegance of sockets.
 */
#endif
savemsg()
{
	char cmd[LINELENGTH];
#ifndef SYSV
	register char	c;
	auto int	i;
	static int	message_no = 1;
	static int	pto[2] = { -1, -1 };	/* pipe to mail program */
	static int	pfrom[2] = { -1, -1 };	/* pipe to mail program */
	static FILE	*pmail[2] = { NULL, NULL };
#endif

	unlink(MESSAGE);	/* previous message*/
	strcpy(MESSAGE,TEMPA);
	mktemp(MESSAGE);
	unlink(MESSAGE);
#ifdef SYSV
	sprintf(cmd,"echo 's %s' | /bin/mail -r >/dev/null",MESSAGE);
#else
	/*
	 * If we haven't yet set the mail program running, do so, and
	 * set up the pipes in both directions.
	 *	pmail[0]:	input to the Mail program
	 *	pmail[1]:	output from the Mail program
	 */

	if (pmail[0] == NULL) {
		if (pipe(pto) < 0 || pipe(pfrom) < 0)
			error("cannot set up pipe");
		if ((i = fork()) < 0)
			error("cannot fork mail program");
		if (i == 0) {		/* child process */
			(void) close(fileno(stdin));
			(void) dup(pto[0]);
			(void) close(fileno(stdout));
			(void) dup(pfrom[1]);
			(void) close(pto[0]);
			(void) close(pto[1]);
			(void) close(pfrom[0]);
			(void) close(pfrom[1]);
			(void) execl(MAILPROG, "Mail", "-f", TEMPM, NULL);
			perror(MAILPROG);
			exit(-1);
		}
		/* parent process */
		pmail[0] = fdopen(pfrom[0], "r");
		pmail[1] = fdopen(pto[1], "w");
		(void) close(pfrom[1]);
		(void) close(pto[0]);

		/*
		 * wait until it's ready for commands
		 */

		/* "Mail verssion ..." */
		if (fgets(cmd, sizeof cmd, pmail[0]) == NULL)
			error("premature EOF from mail file");
		/* "<file name> <num> messages ... " */
		if (fgets(cmd, sizeof cmd, pmail[0]) == NULL)
			error("premature EOF from mail file");
		/* pick the number out of the line */
		if (sscanf(cmd, "\"%*[^\"]\": %d", &i) != 1)
			error("badly formed message count line");
		/* toss away one line per message */
		while (i--)
			if (fgets(cmd, sizeof cmd, pmail[0]) == NULL)
				error("premature EOF from mail file");
	}

	sprintf(cmd, "s %d %s\n", message_no++, MESSAGE);
#endif
	if (dflag) {
		printf("UNEXECUTED cmd=%s\n",cmd);
	} else {
#ifdef SYSV
		system(cmd);
#else
		/*
		 * Put the command down the pipe, and then wait for the
		 * response.  Mail will only generate one-line responses
		 * to the commands we give it.
		 */
		(void) fputs(cmd, pmail[1]);
		(void) fflush(pmail[1]);
		fgets(cmd, sizeof cmd, pmail[0]);
#endif
		chkmsg();
	}/*fi*/
}/*savemsg*/

void init()
{
	readmail();
	/* open mail and read first line */
	f1 = fopen(TEMPM,"r");
	if ( NULL == f1 ) {
		fprintf(stderr,"%s: ERROR cannot open copy of mail file\n",NAME);
		exit(1);
	}
	lp = fgets(line, LINELENGTH, f1);
}

void finit()
{
	unlink(MESSAGE);
	unlink(TEMPM);
}/*finit*/

void usage()
{
	printf("Usage: %s [-d] [-V] [-H] [-f input] [-x prgm] [-o options]\n",NAME);
}/*usage*/

/* parse options */
void options(argc,argv)
int	argc;
char	*argv[];
{
	int	ch;
	extern char *optarg;

	while ((ch=getopt(argc,argv,"vVhHdf:x:o:m:")) != EOF) {
		switch (ch) {
		case 'V' :
		case 'v' :
			printf("%s: version 0.9.1\n",NAME);
			exit(0);
			break;
		case 'h' :
		case 'H' :
			usage();
			exit(0);
			break;
		case 'd' :
			dflag = TRUE;
			break;
		case 'f' :
			sscanf(optarg,"%s",fflag);
			break;
		case 'x' :
			sscanf(optarg,"%s",xflag);
			break;
		case 'o' :
			strcpy(oflag,optarg);
			break;
		case 'm' :
			strcpy(mflag,optarg);
			break;
		case '?' :
		default :
			usage();
			exit(1);
			break;
		}/*switch*/
	}/*while*/
}/*options*/

/* return pointer to copy of input but with special characters backslashed */
char *unquote(input)
register char input[];
{
	register int i;
	register int j;
	static char output[TOSIZE];

	i = 0;
	j = 0;
	while (input[i] != '\0') {
		if ( (input[i] == '\"') || 
		    (input[i] == '\\') ||
		    (input[i] == '\$') ||
		    (input[i] == '\`') ) {
			output[j] = '\\';
			j++;
		}
		output[j] = input[i];
		j++;
		i++;
	}/*while*/
	output[j] = '\0';
	return(output);
}/*unquote*/

/* put all variables into file */
void printit(file)
char file[];
{
	FILE *f2;

	f2 = fopen(file,"w");
	if (f2 == NULL) {
		fprintf(stderr,"%s: ERROR cannot create work file",NAME);
		exit(1);
	}
	fprintf(f2,"SUBJECT=\"%s\" ; export SUBJECT\n",unquote(SUBJECT));
	fprintf(f2,"SENDER='%s' ; export SENDER\n",SENDER);
	fprintf(f2,"NROFLINES='%d' ; export NROFLINES\n",NROFLINES);
	fprintf(f2,"SIZE='%d' ; export SIZE\n",SIZE);
	fprintf(f2,"VIA='%s' ; export VIA\n",VIA);
	fprintf(f2,"MESSAGE='%s' ; export MESSAGE\n",MESSAGE);
	fprintf(f2,"DEMON='%s' ; export DEMON\n",DEMON);
	fprintf(f2,"LAST='%s' ; export LAST\n",LAST);
	fprintf(f2,". %s\n",fflag);
	fflush(f2);
	fclose(f2);
}/*printit*/

/* make work file and execute it */
execmsg()
{
	char cmd[LINELENGTH];
	char file[40];

	unlink(file);	/* remove previous version*/
	strcpy(file,TEMPS);
	mktemp(file);
	unlink(file);
	printit(file);
	sprintf(cmd,"%s %s < %s",xflag,oflag,file);
	if (dflag) {
		printf("UNEXECUTED cmd=%s\n",cmd);
		printf("CONTENTS of %s:\n#=======\n",file);
		sprintf(cmd,"/bin/cat %s",file);
		system(cmd);
		printf("#=======\n");
	} else {
		system(cmd);
	}/*fi*/
	unlink(file);
}/*execmsg*/

int main(argc,argv)
int	argc;
char	*argv[];
{
	register char		*sp;
	register struct passwd	*pp;

	strcpy(fflag,"$HOME/.mailawayrc");
	strcpy(xflag,"/bin/sh");
	strcpy(oflag,"");
	if ((sp = getenv("MAIL")) == NULL)
		sp = "";
	strcpy(mflag, sp);
	options(argc,argv);
	if (mflag[0] == '\0') {
		if ((sp = getenv("USER")) == NULL) {
			if ((pp = getpwuid(getuid())) == NULL) {
				fprintf(stderr, "cannot find mail file name\n");
				finit();
				exit(1);
			}
			sp = pp->pw_name;
		}
		sprintf(mflag, "/usr/spool/mail/%s", sp);
	}
	init();

	/* now for each message */
	while (fillfrom()) {
		savemsg();
		execmsg();
	}/*while*/

	finit();
	return(0);
}/*main*/

/*
 * error:
 *	Print out an error message and then exit.
 */
error(str)
char	*str;
{
	fprintf(stderr, "mailway:%s\n", str);
	finit();
	exit(-1);
}

/*
 * one_in:
 *	If "str" contains at least one instance any char in the string
 *	"list" return a pointer to the first instance in "str",
 *	otherwise return NULL.
 */
char *
one_in(str, list)
register char	*str, *list;
{
	register char	*sp;

	for (; *list; list++)
		for (sp = str; *sp; sp++)
			if (*sp == *list)
				return sp;
	return NULL;
}

/*
 * two_in:
 *	Return TRUE if "str" contains at least two instances any char in
 *	the string "list".
 */
two_in(str, list)
char	*str, *list;
{
	char	*sp;

	if ((sp = one_in(str, list)) == NULL)
		return FALSE;
	if (one_in(++sp, list) == NULL)
		return FALSE;
	return TRUE;
}
SHAR_EOF
fi
exit 0
#	End of shell archive