MAILAWAY to hanlde your Unix mail while away
VanRietschote
jchvr at ihlpg.UUCP
Tue Apr 29 23:58:37 AEST 1986
--
A while back I posted a program to handle unix mail while you
were away for a while. Although it did some smart stuff (according to
me the author), some people wanted things just a little different. So
now there is for those mailaway.C which for each message waiting to
be read, determines things like the author, the size the subject
etc. and then lets you execute a shell routine which can work on
the mail message. (For more details see manual page in next
posting).
Feel free to use or misuse this program.
#------ cut here
/* 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
*/
#include <stdio.h>
#include <ctype.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 */
char fflag[LINELENGTH]; /* file to include */
char xflag[LINELENGTH]; /* program to execute file (executor)*/
char oflag[LINELENGTH]; /* options to program */
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.
*/
/* END OF EXTERNAL ROUTINES */
/* 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 ( *p == ' ' || *p == '\t' ) p++;
q = user;
while ( *p != 10 && *p != '\0' && *p != ' ' && *p != '\t' ) {
*q = *p;
p++;
q++;
}
*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 == ' ' || *p == '\t' ) p++; /* skip spaces */
q = mach2;
while ( *p != 10 && *p != '\0' && *p != ' ' && *p != '\t' ) {
*q = *p;
p++;
q++;
}
*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;
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 */
ptr = strrchr(VIA,'!');
if (NULL == ptr) {
ptr = VIA;
} else {
ptr++;
}/*fi*/
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[80];
mktemp(TEMPM);
unlink(TEMPM);
sprintf(cmd,"/bin/mail -p -r >%s",TEMPM);
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",NAME);
exit(1);
}
fclose(f2);
}/*chkmsg*/
/* save message into temp file after deleting previous version */
savemsg()
{
char cmd[80];
unlink(MESSAGE); /* previous message*/
strcpy(MESSAGE,TEMPA);
mktemp(MESSAGE);
unlink(MESSAGE);
sprintf(cmd,"echo 's %s' | /bin/mail -r >/dev/null",MESSAGE);
if (dflag) {
printf("UNEXECUTED cmd=%s\n",cmd);
} else {
system(cmd);
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:")) != EOF) {
switch (ch) {
case 'V' :
case 'v' :
printf("%s: version 0.9\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 '?' :
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[80];
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[];
{
strcpy(fflag,"$HOME/.mailawayrc");
strcpy(xflag,"/bin/sh");
strcpy(oflag,"");
options(argc,argv);
init();
/* now for each message */
while (fillfrom()) {
savemsg();
execmsg();
}/*while*/
finit();
return(0);
}/*main*/
More information about the Comp.sources.unix
mailing list