home *** CD-ROM | disk | FTP | other *** search
- /*++
- /* NAME
- /* rmail
- /* SUMMARY
- /* extract originator from new mail received by cico
- /* PROJECT
- /* pc-mail
- /* PACKAGE
- /* rmail
- /* SYNOPSIS
- /* rmail
- /* DESCRIPTION
- /* rmail searches for new mail files received by cico and extracts
- /* the originator's name, for later use by the mail visual shell.
- /*
- /* Return address formats we understand (in order of preference):
- /* .nf
- /*
- /* From: address (full_name) (accept the full_name)
- /* From: address (accept the address)
- /* >From address (take address and keep scanning)
- /* From address (take address and keep scanning)
- /*
- /* .fi
- /* To avoid tampering, new files will have read-only permission.
- /*
- /* In order to avoid corruption, control-c interrupts are disabled.
- /* FILES
- /* In the spool directory:
- /* n<seqno> received mail message
- /* h<seqno> extracted originator address
- /* SEE ALSO
- /* path(5) spool directory, file names
- /* cico(1) network process
- /* mailsh(1) visual mail shell
- /* DIAGNOSTICS
- /* Exit status zero when no errors were detected, nonzero in case of file
- /* access errors. See status(5) for error codes.
- /* BUGS
- /* Note that the format "From: full_name <address>" is not
- /* recognized. The program will just pick up the first word from
- /* full_name.
- /*
- /* Does not really do a good job when parsing the mail headers.
- /* At least, not good enough to extract a return path.
- /* AUTHOR(S)
- /* W.Z. Venema
- /* Eindhoven University of Technology
- /* Department of Mathematics and Computer Science
- /* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
- /* CREATION DATE
- /* Tue Mar 31 20:14:11 GMT+1:00 1987
- /* LAST MODIFICATION
- /* Wed Apr 6 00:21:54 MET 1988
- /* VERSION/RELEASE
- /* 1.4
- /*--*/
-
- #include <setjmp.h>
- #include <signal.h>
- #include <time.h>
- #include <ctype.h>
- #include "defs.h"
- #include "dir.h"
- #include "path.h"
- #include "status.h"
-
- extern struct tm *localtime(); /* system functions */
-
- hidden void parse_args(); /* forward declarations */
- hidden void newmail();
- hidden void extract();
- hidden void usage();
-
- #define HLEN 20 /* nbr of header lines scanned */
-
- hidden int dflag = 0; /* debugging option */
-
- #define debug if (dflag) printf
-
- main(argc,argv)
- int argc;
- char **argv;
- {
- signal(SIGINT,SIG_IGN); /* disable ctrl-c */
- parse_args(argc,argv); /* parse command args */
- pathinit(); /* get path info */
- umask(0222); /* make files read-only */
- newmail(); /* get headers from new mail */
- exit(0);
- /* NOTREACHED */
- }
-
- /* parse_args - process command-line arguments */
-
- hidden void parse_args(argc,argv)
- int argc;
- char **argv;
- {
- while (--argc && *++argv && **argv == '-') { /* process options */
- switch (*++*argv) {
- case 'd': /* turn debugging on */
- if (--argc == 0)
- usage("missing debugging level argument");
- sscanf(*++argv,"%d",&dflag);
- if (dflag < 0 || dflag > 9)
- dflag = 0;
- break;
- default: /* unknown option */
- usage(strcons("invalid option: -%c",**argv));
- break;
- }
- }
-
- /* check for extraneous arguments */
-
- if (argc > 0)
- usage(strcons("unexpected argument: %s",*argv));
- }
-
- /* scan for new mail that hasn't gotten yet a metafile */
-
- hidden void newmail()
- {
- register int dd;
- int pfxlen = sizeof(NEWPFX)-1;
- char *f;
-
- debug("directory: \"%s\"\n",maildir); /* verify */
-
- /*
- * Scan the spool directory for newly-arrived mail.
- *
- * Incoming mail message files have a name of "n<seqno>".
- * The originator name is normally present in files with names
- * "h<seqno>" or "o<seqno>".
- * The presence of an "o" file implies that the file "n<seqno>"
- * has been read by the user. An "h" file means that the user
- * has not yet read the message file.
- *
- * If a message file has no corresponding "h" or "o" file we
- * assume it is a new mail message and create an "h" file with
- * the name of the originator.
- */
-
- for (dd = opendir(maildir); f = readdir(dd); /* void */) {
- int seqno;
- debug("rmail: file \"%s\"\n",f);
- if (strncmp(f,NEWPFX,pfxlen) == 0 && sscanf(f+pfxlen,"%d",&seqno)) {
- if (access(in_meta(seqno),4) == 0) { /* message already */
- /* void */ ; /* marked as read */
- } else if (access(new_meta(seqno),4) == 0) {/* message already */
- /* void */ ; /* marked as unread */
- } else { /* create meta file */
- extract(new_mesg(seqno),new_meta(seqno));
- }
- }
- }
- closedir(dd);
- }
-
- /* extract - extract originator info from mail file to meta file */
-
- hidden void extract(mail,meta)
- char *mail;
- char *meta;
- {
- FILE *mesgfp,*metafp;
- char line[BUFSIZ];
- char from[BUFSIZ];
- int n;
-
- debug("-- \"%s\" -> \"%s\"\n",mail,meta);
-
- if ((mesgfp = fopen(mail,"r")) == NULL) /* cannot open existing file */
- exit(E_SYSFAIL);
-
- strcpy(from,"Somewhere"); /* default originator */
-
- /*
- * Some mailers generate real headers, separated from the message
- * body by an empty line. So we stop when we find an empty line.
- * Other mailers have no headers, so we stop after HLEN lines.
- * The following algorithm tries to extract the real user name
- * if possible, otherwise it takes whatever it can get.
- */
-
- for (n = 0; n < HLEN && fgets(line,BUFSIZ,mesgfp) && *line != '\n'; n++) {
- if (sscanf(line,"From: %*s ( %[^)] )",from) == 1)
- break;
- if (sscanf(line,"From: %s",from) == 1)
- break;
- sscanf(line,"%*[>] From %s",from) || sscanf(line,"From %s",from);
- }
-
- /* carefully check all went well */
-
- if (ferror(mesgfp)) /* sorry, read problem */
- exit(E_READERR);
- if ((metafp = fopen(meta,"w")) == NULL) /* cannot create metafile */
- exit(E_WRITERR);
- fprintf(metafp,"%s\n",from); /* write originator */
- if (ferror(metafp)) {
- fclose(metafp); /* ms-dog needs this! */
- chmod(meta,0666); /* sorry, write problem */
- unlink(meta); /* delete metafile */
- exit(E_WRITERR);
- }
- fclose(mesgfp);
- fclose(metafp);
- }
-
- /* usage - explain what is wrong */
-
- hidden void usage(str)
- char *str;
- {
- fprintf(stderr,"%s\nusage: rmail [-d debugging_level]\n",str);
- exit(2);
- }
-