add free_field as standard for struct field
[mmh] / uip / slocal.c
index ac9225b..3b5007d 100644 (file)
@@ -9,29 +9,26 @@
 /*
 **  Under sendmail, users should add the line
 **
-**      "| /usr/local/nmh/lib/slocal"
+**      "| /usr/local/mmh/bin/slocal"
 **
 **  to their $HOME/.forward file.
 **
 */
 
-/* Changed to use getutent() and friends.  Assumes that when getutent() exists,
-** a number of other things also exist.  Please check.
-** Ruud de Rooij <ruud@ruud.org>  Sun, 28 May 2000 17:28:55 +0200
-*/
-
 #include <h/mh.h>
-#include <h/dropsbr.h>
 #include <h/rcvmail.h>
 #include <h/signals.h>
 #include <h/tws.h>
-#include <h/mts.h>
 #include <h/utils.h>
-
 #include <pwd.h>
 #include <signal.h>
 #include <sys/ioctl.h>
 #include <fcntl.h>
+#include <unistd.h>
+#include <stdarg.h>
+#include <sys/stat.h>
+#include <locale.h>
+#include <sysexits.h>
 
 #ifdef INITGROUPS_HEADER
 #include INITGROUPS_HEADER
 extern int  initgroups(char*, int);
 #endif
 
-/*
-** This define is needed for Berkeley db v2 and above to
-** make the header file expose the 'historical' ndbm APIs.
-** We define it unconditionally because this is simple and
-** harmless.
-*/
-#define DB_DBM_HSEARCH 1
-#ifdef NDBM_HEADER
-#include NDBM_HEADER
-#endif
-
-#include <utmp.h>
-
-#ifndef HAVE_GETUTENT
-# ifndef UTMP_FILE
-#  ifdef _PATH_UTMP
-#   define UTMP_FILE _PATH_UTMP
-#  else
-#   define UTMP_FILE "/etc/utmp"
-#  endif
-# endif
-#endif
-
 static struct swit switches[] = {
 #define ADDRSW  0
        { "addr address", 0 },
@@ -88,24 +62,19 @@ static struct swit switches[] = {
 #define VERBSW  8
        { "verbose", 0 },
 #define NVERBSW  9
-       { "noverbose", 0 },
-#define SUPPRESSDUP   10
-       { "suppressdup", 0 },
-#define NSUPPRESSDUP 11
-       { "nosuppressdup", 0 },
-#define DEBUGSW  12
+       { "noverbose", 2 },
+#define DEBUGSW  10
        { "debug", 0 },
-#define VERSIONSW  13
-       { "version", 0 },
-#define HELPSW  14
+#define VERSIONSW  11
+       { "Version", 0 },
+#define HELPSW  12
        { "help", 0 },
        { NULL, 0 }
 };
 
+
 static int globbed = 0;  /* have we built "vars" table yet? */
-static int parsed = 0;  /* have we built header field table yet   */
-static int utmped = 0;  /* have we scanned umtp(x) file yet */
-static int suppressdup = 0;  /* are we suppressing duplicate messages? */
+static int parsed = 0;  /* have we built header field table yet */
 
 static int verbose = 0;
 static int debug = 0;
@@ -124,7 +93,8 @@ static struct passwd *pw;  /* passwd file entry */
 static char ddate[BUFSIZ];  /* record the delivery date */
 struct tws *now;
 
-static jmp_buf myctx;
+volatile sig_atomic_t eflag = 0; /* flag to indecate interrupt */
+static volatile pid_t child_id;
 
 /* flags for pair->p_flags */
 #define P_NIL  0x00
@@ -187,19 +157,16 @@ static int parse(int);
 static void expand(char *, char *, int);
 static void glob(int);
 static struct pair *lookup(struct pair *, char *);
-static int logged_in(void);
-static int timely(char *, char *);
-static int usr_file(int, char *, int);
+static int usr_file(int, char *);
 static int usr_pipe(int, char *, char *, char **, int);
 static int usr_folder(int, char *);
-static RETSIGTYPE alrmser(int);
+static void alrmser(int);
 static void get_sender(char *, char **);
 static int copy_message(int, char *, int);
 static void verbose_printf(char *fmt, ...);
 static void adorn(char *, char *, ...);
 static void debug_printf(char *fmt, ...);
-static int suppress_duplicates(int, char *);
-static char *trim(char *);
+static char *trimstr(char *);
 
 
 int
@@ -211,16 +178,9 @@ main(int argc, char **argv)
        char mailbox[BUFSIZ], tmpfil[BUFSIZ];
        char **argp, **arguments;
 
-#ifdef LOCALE
        setlocale(LC_ALL, "");
-#endif
        invo_name = mhbasename(*argv);
 
-       /* foil search of user profile/context */
-       if (context_foil(NULL) == -1)
-               done(1);
-
-       mts_init(invo_name);
        arguments = getarguments(invo_name, argc, argv, 0);
        argp = arguments;
 
@@ -228,104 +188,117 @@ main(int argc, char **argv)
        while ((cp = *argp++)) {
                if (*cp == '-') {
                        switch (smatch(++cp, switches)) {
-                               case AMBIGSW:
-                                       ambigsw(cp, switches);
-                                       done(1);
-                               case UNKWNSW:
-                                       adios(NULL, "-%s unknown", cp);
-
-                               case HELPSW:
-                                       snprintf(buf, sizeof(buf), "%s [switches] [address info sender]", invo_name);
-                                       print_help(buf, switches, 0);
-                                       done(1);
-                               case VERSIONSW:
-                                       print_version(invo_name);
-                                       done(1);
-
-                               case ADDRSW:
-                                       if (!(addr = *argp++))
-                                               /* allow -xyz arguments */
-                                               adios(NULL, "missing argument to %s", argp[-2]);
-                                       continue;
-                               case INFOSW:
-                                       if (!(info = *argp++))
-                                               /* allow -xyz arguments */
-                                               adios(NULL, "missing argument to %s", argp[-2]);
-                                       continue;
-                               case USERSW:
-                                       if (!(user = *argp++))
-                                               /* allow -xyz arguments */
-                                               adios(NULL, "missing argument to %s", argp[-2]);
-                                       continue;
-                               case FILESW:
-                                       if (!(file = *argp++) || *file == '-')
-                                               adios(NULL, "missing argument to %s", argp[-2]);
-                                       continue;
-                               case SENDERSW:
-                                       if (!(sender = *argp++))
-                                               /* allow -xyz arguments */
-                                               adios(NULL, "missing argument to %s", argp[-2]);
-                                       continue;
-                               case MAILBOXSW:
-                                       if (!(mbox = *argp++) || *mbox == '-')
-                                               adios(NULL, "missing argument to %s", argp[-2]);
-                                       continue;
-                               case HOMESW:
-                                       if (!(home = *argp++) || *home == '-')
-                                               adios(NULL, "missing argument to %s", argp[-2]);
-                                       continue;
+                       case AMBIGSW:
+                               ambigsw(cp, switches);
+                               exit(EX_USAGE);
+                       case UNKWNSW:
+                               adios(EX_USAGE, NULL, "-%s unknown", cp);
+
+                       case HELPSW:
+                               snprintf(buf, sizeof(buf), "%s [switches] [address info sender]", invo_name);
+                               print_help(buf, switches, 0);
+                               exit(argc == 2 ? EX_OK : EX_USAGE);
+                       case VERSIONSW:
+                               print_version(invo_name);
+                               exit(argc == 2 ? EX_OK : EX_USAGE);
+
+                       case ADDRSW:
+                               if (!(addr = *argp++)) {
+                                       /* allow -xyz arguments */
+                                       adios(EX_USAGE, NULL, "missing argument to %s",
+                                                       argp[-2]);
+                               }
+                               continue;
+                       case INFOSW:
+                               if (!(info = *argp++)) {
+                                       /* allow -xyz arguments */
+                                       adios(EX_USAGE, NULL, "missing argument to %s",
+                                                       argp[-2]);
+                               }
+                               continue;
+                       case USERSW:
+                               if (!(user = *argp++)) {
+                                       /* allow -xyz arguments */
+                                       adios(EX_USAGE, NULL, "missing argument to %s",
+                                                       argp[-2]);
+                               }
+                               continue;
+                       case FILESW:
+                               if (!(file = *argp++) || *file == '-') {
+                                       adios(EX_USAGE, NULL, "missing argument to %s",
+                                                       argp[-2]);
+                               }
+                               continue;
+                       case SENDERSW:
+                               if (!(sender = *argp++)) {
+                                       /* allow -xyz arguments */
+                                       adios(EX_USAGE, NULL, "missing argument to %s",
+                                                       argp[-2]);
+                               }
+                               continue;
+                       case MAILBOXSW:
+                               if (!(mbox = *argp++) || *mbox == '-') {
+                                       adios(EX_USAGE, NULL, "missing argument to %s",
+                                                       argp[-2]);
+                               }
+                               continue;
+                       case HOMESW:
+                               if (!(home = *argp++) || *home == '-') {
+                                       adios(EX_USAGE, NULL, "missing argument to %s",
+                                                       argp[-2]);
+                               }
+                               continue;
 
-                               case MAILSW:
-                                       if (!(cp = *argp++) || *cp == '-')
-                                               adios(NULL, "missing argument to %s", argp[-2]);
-                                       if (mdlvr)
-                                               adios(NULL, "only one maildelivery file at a time!");
-                                       mdlvr = cp;
-                                       continue;
+                       case MAILSW:
+                               if (!(cp = *argp++) || *cp == '-') {
+                                       adios(EX_USAGE, NULL, "missing argument to %s",
+                                                       argp[-2]);
+                               }
+                               if (mdlvr) {
+                                       adios(EX_USAGE, NULL, "only one maildelivery file at a time!");
+                               }
+                               mdlvr = cp;
+                               continue;
 
-                               case VERBSW:
-                                       verbose++;
-                                       continue;
-                               case NVERBSW:
-                                       verbose = 0;
-                                       continue;
+                       case VERBSW:
+                               verbose++;
+                               continue;
+                       case NVERBSW:
+                               verbose = 0;
+                               continue;
 
-                               case SUPPRESSDUP:
-                                       suppressdup++;
-                                       continue;
-                               case NSUPPRESSDUP:
-                                       suppressdup = 0;
-                                       continue;
-                               case DEBUGSW:
-                                       debug++;
-                                       continue;
+                       case DEBUGSW:
+                               debug++;
+                               continue;
                        }
                }
 
                switch (argp - (argv + 1)) {
-                       case 1:
-                               addr = cp;
-                               break;
-
-                       case 2:
-                               info = cp;
-                               break;
-
-                       case 3:
-                               sender = cp;
-                               break;
+               case 1:
+                       addr = cp;
+                       break;
+               case 2:
+                       info = cp;
+                       break;
+               case 3:
+                       sender = cp;
+                       break;
                }
        }
 
-       if (addr == NULL)
+       if (!addr) {
                addr = getusername();
-       if (user == NULL)
+       }
+       if (!user) {
                user = (cp = strchr(addr, '.')) ? ++cp : addr;
-       if ((pw = getpwnam(user)) == NULL)
-               adios(NULL, "no such local user as %s", user);
+       }
+       if (!(pw = getpwnam(user))) {
+               adios(EX_NOUSER, NULL, "no such local user as %s", user);
+       }
 
-       if (chdir(pw->pw_dir) == -1)
+       if (chdir(pw->pw_dir) == -1) {
                chdir("/");
+       }
        umask(0077);
 
        if (geteuid() == 0) {
@@ -334,15 +307,17 @@ main(int argc, char **argv)
                setuid(pw->pw_uid);
        }
 
-       if (info == NULL)
+       if (!info) {
                info = "";
+       }
 
        setbuf(stdin, NULL);
 
        /* Record the delivery time */
-       if ((now = dlocaltimenow()) == NULL)
-               adios(NULL, "unable to ascertain local time");
-       snprintf(ddate, sizeof(ddate), "Delivery-Date: %s\n", dtimenow(0));
+       if (!(now = dlocaltimenow())) {
+               adios(EX_OSERR, NULL, "unable to ascertain local time");
+       }
+       snprintf(ddate, sizeof(ddate), "Delivery-Date: %s\n", dtimenow());
 
        /*
        ** Copy the message to a temporary file
@@ -351,24 +326,30 @@ main(int argc, char **argv)
                int tempfd;
 
                /* getting message from file */
-               if ((tempfd = open(file, O_RDONLY)) == -1)
-                       adios(file, "unable to open");
-               if (debug)
+               if ((tempfd = open(file, O_RDONLY)) == -1) {
+                       adios(EX_IOERR, file, "unable to open");
+               }
+               if (debug) {
                        debug_printf("retrieving message from file \"%s\"\n",
                                        file);
-               if ((fd = copy_message(tempfd, tmpfil, 1)) == -1)
-                       adios(NULL, "unable to create temporary file");
+               }
+               if ((fd = copy_message(tempfd, tmpfil, 1)) == -1) {
+                       adios(EX_CANTCREAT, NULL, "unable to create temporary file");
+               }
                close(tempfd);
        } else {
                /* getting message from stdin */
-               if (debug)
+               if (debug) {
                        debug_printf("retrieving message from stdin\n");
-               if ((fd = copy_message(fileno(stdin), tmpfil, 1)) == -1)
-                       adios(NULL, "unable to create temporary file");
+               }
+               if ((fd = copy_message(fileno(stdin), tmpfil, 1)) == -1) {
+                       adios(EX_CANTCREAT, NULL, "unable to create temporary file");
+               }
        }
 
-       if (debug)
+       if (debug) {
                debug_printf("temporary file=\"%s\"\n", tmpfil);
+       }
 
        /*
        ** Delete the temp file now or a copy of every single message
@@ -387,75 +368,65 @@ main(int argc, char **argv)
        */
        unlink(tmpfil);
 
-       if (!(fp = fdopen(fd, "r+")))
-               adios(NULL, "unable to access temporary file");
+       if (!(fp = fdopen(fd, "r+"))) {
+               adios(EX_IOERR, NULL, "unable to access temporary file");
+       }
 
-       /*
-       ** If no sender given, extract it
-       ** from envelope information.
-       */
-       if (sender == NULL)
+       /* If no sender given, extract it from envelope information. */
+       if (!sender) {
                get_sender(envelope, &sender);
-
-       if (mbox == NULL) {
+       }
+       if (!mbox) {
                snprintf(mailbox, sizeof(mailbox), "%s/%s",
-                               mmdfldir[0] ? mmdfldir : pw->pw_dir,
-                               mmdflfil[0] ? mmdflfil : pw->pw_name);
+                               mailspool, pw->pw_name);
                mbox = mailbox;
        }
-       if (home == NULL)
+       if (!home) {
                home = pw->pw_dir;
+       }
 
        if (debug) {
-               debug_printf("addr=\"%s\"\n", trim(addr));
-               debug_printf("user=\"%s\"\n", trim(user));
-               debug_printf("info=\"%s\"\n", trim(info));
-               debug_printf("sender=\"%s\"\n", trim(sender));
+               debug_printf("addr=\"%s\"\n", trimstr(addr));
+               debug_printf("user=\"%s\"\n", trimstr(user));
+               debug_printf("info=\"%s\"\n", trimstr(info));
+               debug_printf("sender=\"%s\"\n", trimstr(sender));
                debug_printf("envelope=\"%s\"\n",
-                               envelope ? trim(envelope) : "");
-               debug_printf("mbox=\"%s\"\n", trim(mbox));
-               debug_printf("home=\"%s\"\n", trim(home));
-               debug_printf("ddate=\"%s\"\n", trim(ddate));
+                               envelope ? trimstr(envelope) : "");
+               debug_printf("mbox=\"%s\"\n", trimstr(mbox));
+               debug_printf("home=\"%s\"\n", trimstr(home));
+               debug_printf("ddate=\"%s\"\n", trimstr(ddate));
                debug_printf("now=%02d:%02d\n\n", now->tw_hour, now->tw_min);
        }
 
        /* deliver the message */
        status = localmail(fd, mdlvr);
 
-       done(status != -1 ? RCV_MOK : RCV_MBX);
-       return 1;
+       return (status != -1 ? RCV_MOK : RCV_MBX);
 }
 
 
 /*
 ** Main routine for delivering message.
 */
-
 static int
 localmail(int fd, char *mdlvr)
 {
-       /* check if this message is a duplicate */
-       if (suppressdup && suppress_duplicates(fd, mdlvr ?
-                       mdlvr : ".maildelivery") == DONE)
-               return 0;
+       char buf[BUFSIZ];
 
        /* delivery according to personal Maildelivery file */
-       if (usr_delivery(fd, mdlvr ? mdlvr : ".maildelivery", 0) != -1)
+       if (usr_delivery(fd, mdlvr ? mdlvr : ".maildelivery", 0) != -1) {
                return 0;
-
+       }
        /* delivery according to global Maildelivery file */
-       if (usr_delivery(fd, maildelivery, 1) != -1)
+       snprintf(buf, sizeof buf, "%s/%s", mhetcdir, "maildelivery");
+       if (usr_delivery(fd, buf, 1) != -1) {
                return 0;
-
-       if (verbose)
+       }
+       if (verbose) {
                verbose_printf("(delivering to standard mail spool)\n");
-
+       }
        /* last resort - deliver to standard mail spool */
-#ifdef SLOCAL_MBOX
-       return usr_file(fd, mbox, MBOX_FORMAT);
-#else
-       return usr_file(fd, mbox, MMDF_FORMAT);
-#endif
+       return usr_file(fd, mbox);
 }
 
 
@@ -464,7 +435,6 @@ localmail(int fd, char *mdlvr)
 /*
 ** Parse the delivery file, and process incoming message.
 */
-
 static int
 usr_delivery(int fd, char *delivery, int su)
 {
@@ -477,9 +447,9 @@ usr_delivery(int fd, char *delivery, int su)
        FILE *fp;
 
        /* open the delivery file */
-       if ((fp = fopen(delivery, "r")) == NULL)
+       if (!(fp = fopen(delivery, "r"))) {
                return -1;
-
+       }
        /* check if delivery file has bad ownership or permissions */
        if (fstat(fileno(fp), &st) == -1 ||
                        (st.st_uid != 0 && (su || st.st_uid != pw->pw_uid)) ||
@@ -496,13 +466,13 @@ usr_delivery(int fd, char *delivery, int su)
        /* read and process delivery file */
        while (fgets(buffer, sizeof(buffer), fp)) {
                /* skip comments and empty lines */
-               if (*buffer == '#' || *buffer == '\n')
+               if (*buffer == '#' || *buffer == '\n') {
                        continue;
-
+               }
                /* zap trailing newline */
-               if ((cp = strchr(buffer, '\n')))
-                       *cp = 0;
-
+               if ((cp = strchr(buffer, '\n'))) {
+                       *cp = '\0';
+               }
                /* split buffer into fields */
                vecp = split(buffer, vec);
 
@@ -514,9 +484,10 @@ usr_delivery(int fd, char *delivery, int su)
                }
 
                if (debug) {
-                       for (i = 0; vec[i]; i++)
+                       for (i = 0; vec[i]; i++) {
                                debug_printf("vec[%d]: \"%s\"\n",
-                                               i, trim(vec[i]));
+                                               i, trimstr(vec[i]));
+                       }
                }
 
                field   = vec[0];
@@ -527,162 +498,157 @@ usr_delivery(int fd, char *delivery, int su)
 
                /* find out how to perform the action */
                switch (result[0]) {
-                       case 'N':
-                       case 'n':
-                               /*
-                               ** If previous condition failed, don't
-                               ** do this - else fall through
-                               */
-                                if (!next)
-                                       continue;  /* else fall */
-
-                       case '?':
-                               /*
-                               ** If already delivered, skip this action.
-                               ** Else consider delivered if action is
-                               ** successful.
-                               */
-                               if (won)
-                                       continue;  /* else fall */
+               case 'N':
+               case 'n':
+                       /*
+                       ** If previous condition failed, don't
+                       ** do this - else fall through
+                       */
+                       if (!next) {
+                               continue;
+                       }
+                       /* fall */
 
-                       case 'A':
-                       case 'a':
-                               /*
-                               ** Take action, and consider delivered if
-                               ** action is successful.
-                               */
-                               accept = 1;
-                               break;
+               case '?':
+                       /*
+                       ** If already delivered, skip this action.
+                       ** Else consider delivered if action is
+                       ** successful.
+                       */
+                       if (won) {
+                               continue;
+                       }
+                       /* fall */
 
-                       case 'R':
-                       case 'r':
-                       default:
-                               /*
-                               ** Take action, but don't consider delivered,
-                               ** even if action is successful
-                               */
-                               accept = 0;
-                               break;
-               }
+               case 'A':
+               case 'a':
+                       /*
+                       ** Take action, and consider delivered if
+                       ** action is successful.
+                       */
+                       accept = 1;
+                       break;
 
-               if (vecp > 5) {
-                       if (!mh_strcasecmp(vec[5], "select")) {
-                               if (logged_in() != -1)
-                                       continue;
-                               if (vecp > 7 && timely(vec[6], vec[7]) == -1)
-                                       continue;
-                       }
+               case 'R':
+               case 'r':
+               default:
+                       /*
+                       ** Take action, but don't consider delivered,
+                       ** even if action is successful
+                       */
+                       accept = 0;
+                       break;
                }
 
                /* check if the field matches */
                switch (*field) {
-                       case '*':
+               case '*':
                        /* always matches */
-                               break;
+                       break;
 
-                       case 'd':
+               case 'd':
                        /*
                        ** "default" matches only if the message hasn't
                        ** been delivered yet.
                        */
-                               if (!mh_strcasecmp(field, "default")) {
-                                       if (won)
-                                               continue;
-                                       break;
-                               }  /* else fall */
-
-                       default:
-                               /* parse message and build lookup table */
-                               if (!parsed && parse(fd) == -1) {
-                                       fclose(fp);
-                                       return -1;
-                               }
-                               /*
-                               ** find header field in lookup table, and
-                               ** see if the pattern matches.
-                               */
-                               if ((p = lookup(hdrs, field)) &&
-                                               (p->p_value != NULL) &&
-                                               matches(p->p_value, pattern)
-                                               ) {
-                                       next = 1;
-                               } else {
-                                       next = 0;
+                       if (mh_strcasecmp(field, "default")==0) {
+                               if (won) {
                                        continue;
                                }
                                break;
+                       }
+                       /* fall */
+               default:
+                       /* parse message and build lookup table */
+                       if (!parsed && parse(fd) == -1) {
+                               fclose(fp);
+                               return -1;
+                       }
+                       /*
+                       ** find header field in lookup table, and
+                       ** see if the pattern matches.
+                       */
+                       if ((p = lookup(hdrs, field)) && p->p_value &&
+                                       matches(p->p_value, pattern)) {
+                               next = 1;
+                       } else {
+                               next = 0;
+                               continue;
+                       }
+                       break;
                }
 
                /* find out the action to perform */
                switch (*action) {
-                       case 'q':
-                               /* deliver to quoted pipe */
-                               if (mh_strcasecmp(action, "qpipe"))
-                                       continue;  /* else fall */
-                       case '^':
-                               expand(tmpbuf, string, fd);
-                               if (split(tmpbuf, vec) < 1)
-                                       continue;
-                               status = usr_pipe(fd, tmpbuf, vec[0], vec, 0);
-                               break;
+               case 'q':
+                       /* deliver to quoted pipe */
+                       if (mh_strcasecmp(action, "qpipe")) {
+                               continue;
+                       }
+                       /* fall */
+               case '^':
+                       expand(tmpbuf, string, fd);
+                       if (split(tmpbuf, vec) < 1) {
+                               continue;
+                       }
+                       status = usr_pipe(fd, tmpbuf, vec[0], vec, 0);
+                       break;
 
-                       case 'p':
-                               /* deliver to pipe */
-                               if (mh_strcasecmp(action, "pipe"))
-                                       continue;  /* else fall */
-                       case '|':
-                               vec[2] = "sh";
-                               vec[3] = "-c";
-                               expand(tmpbuf, string, fd);
-                               vec[4] = tmpbuf;
-                               vec[5] = NULL;
-                               status = usr_pipe(fd, tmpbuf, "/bin/sh",
-                                               vec + 2, 0);
-                               break;
+               case 'p':
+                       /* deliver to pipe */
+                       if (mh_strcasecmp(action, "pipe")) {
+                               continue;
+                       }
+                       /* fall */
+               case '|':
+                       vec[2] = "sh";
+                       vec[3] = "-c";
+                       expand(tmpbuf, string, fd);
+                       vec[4] = tmpbuf;
+                       vec[5] = NULL;
+                       status = usr_pipe(fd, tmpbuf, "/bin/sh", vec+2, 0);
+                       break;
 
-                       case 'f':
+               case 'f':
+                       if (mh_strcasecmp(action, "file")==0) {
                                /* mbox format */
-                               if (!mh_strcasecmp(action, "file")) {
-                                       status = usr_file(fd, string,
-                                                       MBOX_FORMAT);
-                                       break;
-                               }
-                               /* deliver to nmh folder */
-                               else if (mh_strcasecmp(action, "folder"))
-                                       continue;  /* else fall */
-                       case '+':
-                               status = usr_folder(fd, string);
+                               status = usr_file(fd, string);
                                break;
+                       }
+                       if (mh_strcasecmp(action, "folder")!=0) {
+                               continue;
+                       }
+                       /* fall */
+               case '+':
+                       /* deliver to nmh folder */
+                       status = usr_folder(fd, string);
+                       break;
 
-                       case 'm':
-                               /* mmdf format */
-                               if (!mh_strcasecmp(action, "mmdf")) {
-                                       status = usr_file(fd, string,
-                                                       MMDF_FORMAT);
-                                       break;
-                               }
-                               /* mbox format */
-                               else if (mh_strcasecmp(action, "mbox"))
-                                       continue;  /* else fall */
-
-                       case '>':
-                               /* mbox format */
-                               status = usr_file(fd, string, MBOX_FORMAT);
-                               break;
+               case 'm':
+                       /* mbox format */
+                       if (mh_strcasecmp(action, "mbox")!=0) {
+                               continue;
+                       }
+                       /* fall */
+               case '>':
+                       /* mbox format */
+                       status = usr_file(fd, string);
+                       break;
 
-                       case 'd':
-                               /* ignore message */
-                               if (mh_strcasecmp(action, "destroy"))
-                                       continue;
-                               status = 0;
-                               break;
+               case 'd':
+                       /* ignore message */
+                       if (mh_strcasecmp(action, "destroy")!=0) {
+                               continue;
+                       }
+                       status = 0;
+                       break;
                }
 
-               if (status)
+               if (status) {
                        next = 0;  /* action failed, mark for 'N' result */
-
-               if (accept && status == 0)
+               } else if (accept) {
                        won++;
+               }
        }
 
        fclose(fp);
@@ -690,13 +656,10 @@ usr_delivery(int fd, char *delivery, int su)
 }
 
 
-#define QUOTE  '\\'
-
 /*
 ** Split buffer into fields (delimited by whitespace or
 ** comma's).  Return the number of fields found.
 */
-
 static int
 split(char *cp, char **vec)
 {
@@ -710,13 +673,13 @@ split(char *cp, char **vec)
                vec[i] = NULL;
 
                /* zap any whitespace and comma's */
-               while (isspace(*s) || *s == ',')
-                       *s++ = 0;
-
+               while (isspace(*s) || *s == ',') {
+                       *s++ = '\0';
+               }
                /* end of buffer, time to leave */
-               if (*s == 0)
+               if (!*s) {
                        break;
-
+               }
                /* get double quote text as a single field */
                if (*s == '"') {
                        for (vec[i++] = ++s; *s && *s != '"'; s++) {
@@ -724,24 +687,29 @@ split(char *cp, char **vec)
                                ** Check for escaped double quote.  We need
                                ** to shift the string to remove slash.
                                */
-                               if (*s == QUOTE) {
-                                       if (*++s == '"')
+                               if (*s == '\\') {
+                                       if (*++s == '"') {
                                                strcpy(s - 1, s);
+                                       }
                                        s--;
                                }
                        }
-                       if (*s == '"')  /* zap trailing double quote */
-                               *s++ = 0;
+                       if (*s == '"') {
+                               /* zap trailing double quote */
+                               *s++ = '\0';
+                       }
                        continue;
                }
 
-               if (*s == QUOTE && *++s != '"')
+               if (*s == '\\' && *++s != '"') {
                        s--;
+               }
                vec[i++] = s++;
 
                /* move forward to next field delimiter */
-               while (*s && !isspace(*s) && *s != ',')
+               while (*s && !isspace(*s) && *s != ',') {
                        s++;
+               }
        }
        vec[i] = NULL;
 
@@ -753,158 +721,150 @@ split(char *cp, char **vec)
 ** Parse the headers of a message, and build the
 ** lookup table for matching fields and patterns.
 */
-
 static int
 parse(int fd)
 {
-       int i, state;
-       int fd1;
+       enum state state;
+       struct field f = free_field;
+       int i, fd1;
        char *cp, *dp, *lp;
-       char name[NAMESZ], field[BUFSIZ];
        struct pair *p, *q;
        FILE  *in;
 
-       if (parsed++)
+       if (parsed++) {
                return 0;
+       }
 
        /* get a new FILE pointer to message */
-       if ((fd1 = dup(fd)) == -1)
+       if ((fd1 = dup(fd)) == -1) {
                return -1;
-       if ((in = fdopen(fd1, "r")) == NULL) {
+       }
+       if (!(in = fdopen(fd1, "r"))) {
                close(fd1);
                return -1;
        }
        rewind(in);
 
        /* add special entries to lookup table */
-       if ((p = lookup(hdrs, "source")))
+       if ((p = lookup(hdrs, "source"))) {
                p->p_value = getcpy(sender);
-       if ((p = lookup(hdrs, "addr")))
+       }
+       if ((p = lookup(hdrs, "addr"))) {
                p->p_value = getcpy(addr);
+       }
 
        /*
-        * Scan the headers of the message and build
-        * a lookup table.
-        */
-       for (i = 0, state = FLD;;) {
-               switch (state = m_getfld(state, name, field, sizeof(field),
-                               in)) {
-                       case FLD:
-                       case FLDEOF:
-                       case FLDPLUS:
-                               lp = getcpy(field);
-                               while (state == FLDPLUS) {
-                                       state = m_getfld(state, name, field,
-                                                       sizeof(field), in);
-                                       lp = add(field, lp);
-                               }
-                               for (p = hdrs; p->p_name; p++) {
-                                       if (!mh_strcasecmp(p->p_name, name)) {
-                                               if (!(p->p_flags & P_HID)) {
-                                                       if ((cp = p->p_value)) {
-                                                               if (p->p_flags & P_ADR) {
-                                                                       dp = cp + strlen(cp) - 1;
-                                                                       if (*dp == '\n')
-                                                                               *dp = 0;
-                                                                       cp = add(",\n\t", cp);
-                                                               } else {
-                                                                       cp = add("\t", cp);
+       ** Scan the headers of the message and build a lookup table.
+       */
+       for (i = 0, state = FLD2;;) {
+               switch (state = m_getfld2(state, &f, in)) {
+               case FLD2:
+                       lp = getcpy(f.value);
+                       for (p = hdrs; p->p_name; p++) {
+                               if (mh_strcasecmp(p->p_name, f.name)!=0) {
+                                       if (!(p->p_flags & P_HID)) {
+                                               if ((cp = p->p_value)) {
+                                                       if (p->p_flags & P_ADR) {
+                                                               dp = cp + strlen(cp) - 1;
+                                                               if (*dp == '\n') {
+                                                                       *dp = '\0';
                                                                }
+                                                               cp = add(",\n\t", cp);
+                                                       } else {
+                                                               cp = add("\t", cp);
                                                        }
-                                                       p->p_value = add(lp, cp);
                                                }
-                                               free(lp);
-                                               break;
+                                               p->p_value = add(lp, cp);
                                        }
+                                       free(lp);
+                                       break;
                                }
-                               if (p->p_name == NULL && i < NVEC) {
-                                       p->p_name = getcpy(name);
-                                       p->p_value = lp;
-                                       p->p_flags = P_NIL;
-                                       p++, i++;
-                                       p->p_name = NULL;
-                               }
-                               if (state != FLDEOF)
-                                       continue;
-                               break;
+                       }
+                       if (!p->p_name && i < NVEC) {
+                               p->p_name = getcpy(f.name);
+                               p->p_value = lp;
+                               p->p_flags = P_NIL;
+                               p++, i++;
+                               p->p_name = NULL;
+                       }
+                       continue;
 
-                       case BODY:
-                       case BODYEOF:
-                       case FILEEOF:
-                               break;
+               case BODY2:
+               case FILEEOF2:
+                       break;
 
-                       case LENERR:
-                       case FMTERR:
-                               advise(NULL, "format error in message");
-                               break;
+               case LENERR2:
+               case FMTERR2:
+               case IOERR2:
+                       advise(NULL, "format error in message");
+                       break;
 
-                       default:
-                               advise(NULL, "internal error in m_getfld");
-                               fclose(in);
-                               return -1;
+               default:
+                       advise(NULL, "internal error in m_getfld");
+                       fclose(in);
+                       return -1;
                }
                break;
        }
        fclose(in);
 
        if ((p = lookup(vars, "reply-to"))) {
-               if ((q = lookup(hdrs, "reply-to")) == NULL ||
-                               q->p_value == NULL)
+               if (!(q = lookup(hdrs, "reply-to")) || !q->p_value) {
                        q = lookup(hdrs, "from");
+               }
                p->p_value = getcpy(q ? q->p_value : "");
                p->p_flags &= ~P_CHK;
-               if (debug)
+               if (debug) {
                        debug_printf("vars[%d]: name=\"%s\" value=\"%s\"\n",
-                                       p - vars, p->p_name, trim(p->p_value));
+                                       p - vars, p->p_name, trimstr(p->p_value));
+               }
        }
        if (debug) {
-               for (p = hdrs; p->p_name; p++)
+               for (p = hdrs; p->p_name; p++) {
                        debug_printf("hdrs[%d]: name=\"%s\" value=\"%s\"\n",
-                               p - hdrs, p->p_name, p->p_value ? trim(p->p_value) : "");
+                                       p - hdrs, p->p_name,
+                                       p->p_value ? trimstr(p->p_value) : "");
+               }
        }
-
        return 0;
 }
 
 
-#define LPAREN '('
-#define RPAREN ')'
-
 /*
 ** Expand any builtin variables such as $(sender),
 ** $(address), etc., in a string.
 */
-
 static void
 expand(char *s1, char *s2, int fd)
 {
        char c, *cp;
        struct pair *p;
 
-       if (!globbed)
+       if (!globbed) {
                glob(fd);
-
+       }
        while ((c = *s2++)) {
-               if (c != '$' || *s2 != LPAREN) {
+               if (c != '$' || *s2 != '(') {
                        *s1++ = c;
                } else {
-                       for (cp = ++s2; *s2 && *s2 != RPAREN; s2++)
+                       for (cp = ++s2; *s2 && *s2 != ')'; s2++) {
                                continue;
-                       if (*s2 != RPAREN) {
+                       }
+                       if (*s2 != ')') {
                                s2 = --cp;
                                continue;
                        }
-                       *s2++ = 0;
+                       *s2++ = '\0';
                        if ((p = lookup(vars, cp))) {
-                               if (!parsed && (p->p_flags & P_CHK))
+                               if (!parsed && (p->p_flags & P_CHK)) {
                                        parse(fd);
-
+                               }
                                strcpy(s1, p->p_value);
                                s1 += strlen(s1);
                        }
                }
        }
-       *s1 = 0;
+       *s1 = '\0';
 }
 
 
@@ -914,7 +874,6 @@ expand(char *s1, char *s2, int fd)
 ** variables in the string for a "pipe" or "qpipe"
 ** action.
 */
-
 static void
 glob(int fd)
 {
@@ -922,25 +881,28 @@ glob(int fd)
        struct stat st;
        struct pair *p;
 
-       if (globbed++)
+       if (globbed++) {
                return;
-
-       if ((p = lookup(vars, "sender")))
+       }
+       if ((p = lookup(vars, "sender"))) {
                p->p_value = getcpy(sender);
-       if ((p = lookup(vars, "address")))
+       }
+       if ((p = lookup(vars, "address"))) {
                p->p_value = getcpy(addr);
+       }
        if ((p = lookup(vars, "size"))) {
                snprintf(buffer, sizeof(buffer), "%d",
                                fstat(fd, &st) != -1 ? (int) st.st_size : 0);
                p->p_value = getcpy(buffer);
        }
-       if ((p = lookup(vars, "info")))
+       if ((p = lookup(vars, "info"))) {
                p->p_value = getcpy(info);
-
+       }
        if (debug) {
-               for (p = vars; p->p_name; p++)
+               for (p = vars; p->p_name; p++) {
                        debug_printf("vars[%d]: name=\"%s\" value=\"%s\"\n",
-                                       p - vars, p->p_name, trim(p->p_value));
+                                       p - vars, p->p_name, trimstr(p->p_value));
+               }
        }
 }
 
@@ -949,310 +911,164 @@ glob(int fd)
 ** Find a matching name in a lookup table.  If found,
 ** return the "pairs" entry, else return NULL.
 */
-
 static struct pair *
 lookup(struct pair *pairs, char *key)
 {
-       for (; pairs->p_name; pairs++)
-               if (!mh_strcasecmp(pairs->p_name, key))
+       for (; pairs->p_name; pairs++) {
+               if (!mh_strcasecmp(pairs->p_name, key)) {
                        return pairs;
-
-       return NULL;
-}
-
-
-/*
-** Check utmp(x) file to see if user is currently
-** logged in.
-*/
-
-#ifdef HAVE_GETUTENT
-static int
-logged_in(void)
-{
-       struct utmp * utp;
-
-       if (utmped)
-               return utmped;
-
-       setutent();
-
-       while ((utp = getutent()) != NULL) {
-               if (
-#ifdef HAVE_STRUCT_UTMP_UT_TYPE
-                               utp->ut_type == USER_PROCESS &&
-#endif
-                               utp->ut_name[0] != 0 &&
-                               strncmp(user, utp->ut_name,
-                               sizeof(utp->ut_name)) == 0) {
-                       if (debug)
-                               continue;
-                       endutent();
-                       return (utmped = DONE);
-               }
-       }
-
-       endutent();
-       return (utmped = NOTOK);
-}
-#else
-static int
-logged_in(void)
-{
-       struct utmp ut;
-       FILE *uf;
-
-       if (utmped)
-               return utmped;
-
-       if ((uf = fopen(UTMP_FILE, "r")) == NULL)
-               return NOTOK;
-
-       while (fread((char *) &ut, sizeof(ut), 1, uf) == 1) {
-               if (ut.ut_name[0] != 0 &&
-                               strncmp(user, ut.ut_name, sizeof(ut.ut_name))
-                               == 0) {
-                       if (debug)
-                               continue;
-                       fclose(uf);
-                       return (utmped = DONE);
                }
        }
-
-       fclose(uf);
-       return (utmped = NOTOK);
-}
-#endif
-
-#define check(t,a,b)  if (t < a || t > b) return -1
-#define cmpar(h1,m1,h2,m2)  if (h1 < h2 || (h1 == h2 && m1 < m2)) return 0
-
-static int
-timely(char *t1, char *t2)
-{
-       int t1hours, t1mins, t2hours, t2mins;
-
-       if (sscanf(t1, "%d:%d", &t1hours, &t1mins) != 2)
-               return -1;
-       check(t1hours, 0, 23);
-       check(t1mins, 0, 59);
-
-       if (sscanf(t2, "%d:%d", &t2hours, &t2mins) != 2)
-               return -1;
-       check(t2hours, 0, 23);
-       check(t2mins, 0, 59);
-
-       cmpar(now->tw_hour, now->tw_min, t1hours, t1mins);
-       cmpar(t2hours, t2mins, now->tw_hour, now->tw_min);
-
-       return -1;
+       return NULL;
 }
 
 
 /*
-** Deliver message by appending to a file.
+** Deliver message by appending to a file, using rcvpack(1).
 */
-
 static int
-usr_file(int fd, char *mailbox, int mbx_style)
+usr_file(int fd, char *mailbox)
 {
-       int md, mapping;
+       char *vec[3];
 
-       if (verbose)
-               verbose_printf("delivering to file \"%s\"", mailbox);
-
-       if (mbx_style == MBOX_FORMAT) {
-               if (verbose)
-                       verbose_printf(" (mbox style)");
-               mapping = 0;
-       } else {
-               if (verbose)
-                       verbose_printf(" (mmdf style)");
-               mapping = 1;
-       }
-
-       /* open and lock the file */
-       if ((md = mbx_open(mailbox, mbx_style, pw->pw_uid, pw->pw_gid,
-                       m_gmprot())) == -1) {
-               if (verbose)
-                       adorn("", "unable to open:");
-               return -1;
-       }
-
-       lseek(fd, (off_t) 0, SEEK_SET);
-
-       /* append message to file */
-       if (mbx_copy(mailbox, mbx_style, md, fd, mapping, NULL, verbose)
-                       == -1) {
-               if (verbose)
-                       adorn("", "error writing to:");
-               return -1;
-       }
-
-       /* close and unlock file */
-       if (mbx_close(mailbox, md) == NOTOK) {
-               if (verbose)
-                       adorn("", "error closing:");
-               return -1;
+       if (verbose) {
+               verbose_printf("delivering to file \"%s\" (mbox style)",
+                               mailbox);
        }
+       vec[0] = "rcvpack";
+       vec[1] = mailbox;
+       vec[2] = NULL;
 
-       if (verbose)
-               verbose_printf(", success.\n");
-       return 0;
+       return usr_pipe(fd, "rcvpack", "rcvpack", vec, 1);
 }
 
 
 /*
-** Deliver message to a nmh folder.
+** Deliver message to a nmh folder, using rcvstore(1).
 */
-
 static int
 usr_folder(int fd, char *string)
 {
-       int status;
        char folder[BUFSIZ], *vec[3];
 
        /* get folder name ready */
-       if (*string == '+')
+       if (*string == '+') {
                strncpy(folder, string, sizeof(folder));
-       else
+       }else {
                snprintf(folder, sizeof(folder), "+%s", string);
-
-       if (verbose)
+       }
+       if (verbose) {
                verbose_printf("delivering to folder \"%s\"", folder + 1);
-
+       }
        vec[0] = "rcvstore";
        vec[1] = folder;
        vec[2] = NULL;
 
-       /* use rcvstore to put message in folder */
-       status = usr_pipe(fd, "rcvstore", rcvstoreproc, vec, 1);
-
-#if 0
-       /*
-       ** Currently, verbose status messages are handled by usr_pipe().
-       */
-       if (verbose) {
-               if (status == 0)
-                       verbose_printf(", success.\n");
-               else
-                       verbose_printf(", failed.\n");
-       }
-#endif
-
-       return status;
+       return usr_pipe(fd, "rcvstore", "rcvstore", vec, 1);
 }
 
 /*
 ** Deliver message to a process.
 */
-
 static int
 usr_pipe(int fd, char *cmd, char *pgm, char **vec, int suppress)
 {
-       pid_t child_id;
-       int i, bytes, seconds, status;
+       int bytes, seconds, status, n;
        struct stat st;
+       char *path;
 
-       if (verbose && !suppress)
+       if (verbose && !suppress) {
                verbose_printf("delivering to pipe \"%s\"", cmd);
-
+       }
        lseek(fd, (off_t) 0, SEEK_SET);
 
-       for (i = 0; (child_id = fork()) == -1 && i < 5; i++)
-               sleep(5);
-
-       switch (child_id) {
-               case -1:
-                       /* fork error */
-                       if (verbose)
-                               adorn("fork", "unable to");
-                       return -1;
+       switch ((child_id = fork())) {
+       case -1:
+               /* fork error */
+               if (verbose) {
+                       adorn("fork", "unable to");
+               }
+               return -1;
 
-               case 0:
-                       /* child process */
-                       if (fd != 0)
-                               dup2(fd, 0);
-                       freopen("/dev/null", "w", stdout);
-                       freopen("/dev/null", "w", stderr);
-                       if (fd != 3)
-                               dup2(fd, 3);
-                       closefds(4);
+       case 0:
+               /* child process */
+               if (fd != 0) {
+                       dup2(fd, 0);
+               }
+               freopen("/dev/null", "w", stdout);
+               freopen("/dev/null", "w", stderr);
+               if (fd != 3) {
+                       dup2(fd, 3);
+               }
+               for (n=4; n<OPEN_MAX; n++) {
+                       close(n);
+               }
 
 #ifdef TIOCNOTTY
-                       if ((fd = open("/dev/tty", O_RDWR)) != -1) {
-                               ioctl(fd, TIOCNOTTY, NULL);
-                               close(fd);
-                       }
+               if ((fd = open("/dev/tty", O_RDWR)) != -1) {
+                       ioctl(fd, TIOCNOTTY, NULL);
+                       close(fd);
+               }
 #endif /* TIOCNOTTY */
 
-                       /* put in own process group */
-                       setpgid((pid_t) 0, getpid());
-
-                       *environ = NULL;
-                       m_putenv("USER", pw->pw_name);
-                       m_putenv("HOME", pw->pw_dir);
-                       m_putenv("SHELL", pw->pw_shell);
-
-                       execvp(pgm, vec);
-                       _exit(-1);
+               /* put in own process group */
+               setpgid((pid_t) 0, getpid());
+
+               path = getenv("PATH");
+               *environ = NULL;
+               m_putenv("USER", pw->pw_name);
+               m_putenv("HOME", pw->pw_dir);
+               m_putenv("SHELL", pw->pw_shell);
+               m_putenv("PATH", path);
+
+               execvp(pgm, vec);
+               _exit(EX_OSERR);
+
+       default:
+               /* parent process */
+               SIGNAL(SIGALRM, alrmser);
+               bytes = fstat(fd, &st) != -1 ? (int) st.st_size : 100;
+
+               /* amount of time to wait depends on message size */
+               if (bytes <= 100) {
+                       /* give at least 5 minutes */
+                       seconds = 300;
+               } else if (bytes >= 90000) {
+                       /* a half hour is long enough */
+                       seconds = 1800;
+               } else {
+                       seconds = (bytes / 60) + 300;
+               }
+               alarm((unsigned int) seconds);
+               status = pidwait(child_id, 0);
+               alarm(0);
 
-               default:
-                       /* parent process */
-                       if (!setjmp(myctx)) {
-                               SIGNAL(SIGALRM, alrmser);
-                               bytes = fstat(fd, &st) != -1 ?
-                                               (int) st.st_size : 100;
+               if (eflag) {
+                       if (verbose) {
+                               verbose_printf(", timed-out; terminated\n");
+                       }
+                       return -1;
+               }
 
-                               /*
-                               ** amount of time to wait depends on
-                               ** message size
-                               */
-                               if (bytes <= 100) {
-                                       /* give at least 5 minutes */
-                                       seconds = 300;
-                               } else if (bytes >= 90000) {
-                                       /* a half hour is long enough */
-                                       seconds = 1800;
-                               } else {
-                                       seconds = (bytes / 60) + 300;
-                               }
-                               alarm((unsigned int) seconds);
-                               status = pidwait(child_id, 0);
-                               alarm(0);
-
-                               if (verbose) {
-                                       if (status == 0)
-                                               verbose_printf(", success.\n");
-                                       else
-                                               if ((status & 0xff00) == 0xff00)
-                                                       verbose_printf(", system error\n");
-                                               else
-                                                       pidstatus(status, stdout, ", failed");
-                               }
-                               return (status == 0 ? 0 : -1);
+               if (verbose) {
+                       if (!status) {
+                               verbose_printf(", success.\n");
+                       } else if ((status & 0xff00) == 0xff00) {
+                               verbose_printf(", system error\n");
                        } else {
-                               /*
-                               ** Ruthlessly kill the child and anything
-                               ** else in its process group.
-                               */
-                               KILLPG(child_id, SIGKILL);
-                               if (verbose)
-                                       verbose_printf(", timed-out; terminated\n");
-                               return -1;
+                               pidstatus(status, stdout, ", failed");
                        }
+               }
+               return (status == 0 ? 0 : -1);
        }
 }
 
 
-static RETSIGTYPE
+static void
 alrmser(int i)
 {
-#ifndef RELIABLE_SIGNALS
-       SIGNAL(SIGALRM, alrmser);
-#endif
-
-       longjmp(myctx, DONE);
+       eflag = 1;
+       kill(-child_id, SIGKILL);
 }
 
 
@@ -1260,7 +1076,6 @@ alrmser(int i)
 ** Get the `sender' from the envelope
 ** information ("From " line).
 */
-
 static void
 get_sender(char *envelope, char **sender)
 {
@@ -1268,28 +1083,31 @@ get_sender(char *envelope, char **sender)
        unsigned char *cp;
        unsigned char buffer[BUFSIZ];
 
-       if (envelope == NULL) {
+       if (!envelope) {
                *sender = getcpy("");
                return;
        }
 
        i = strlen("From ");
        strncpy(buffer, envelope + i, sizeof(buffer));
+       buffer[sizeof buffer -1] = '\0';  /* ensure termination */
        if ((cp = strchr(buffer, '\n'))) {
-               *cp = 0;
+               *cp = '\0';
                cp -= 24;
-               if (cp < buffer)
+               if (cp < buffer) {
                        cp = buffer;
+               }
        } else {
                cp = buffer;
        }
-       *cp = 0;
+       *cp = '\0';
 
        for (cp = buffer + strlen(buffer) - 1; cp >= buffer; cp--)
-               if (isspace(*cp))
-                       *cp = 0;
-               else
+               if (isspace(*cp)) {
+                       *cp = '\0';
+               } else {
                        break;
+               }
        *sender = getcpy(buffer);
 }
 
@@ -1299,7 +1117,6 @@ get_sender(char *envelope, char **sender)
 ** While copying, it will do some header processing
 ** including the extraction of the envelope information.
 */
-
 static int
 copy_message(int qd, char *tmpfil, int fold)
 {
@@ -1308,21 +1125,23 @@ copy_message(int qd, char *tmpfil, int fold)
        FILE *qfp, *ffp;
        char *tfile = NULL;
 
-       tfile = m_mktemp2(NULL, invo_name, &fd1, NULL);
+       tfile = m_mktemp2("/tmp/", invo_name, &fd1, NULL);
        if (tfile == NULL) return -1;
        fchmod(fd1, 0600);
        strncpy(tmpfil, tfile, BUFSIZ);
 
        if (!fold) {
-               while ((i = read(qd, buffer, sizeof(buffer))) > 0)
+               while ((i = read(qd, buffer, sizeof(buffer))) > 0) {
                        if (write(fd1, buffer, i) != i) {
 you_lose:
                                close(fd1);
                                unlink(tmpfil);
                                return -1;
                        }
-               if (i == -1)
+               }
+               if (i == -1) {
                        goto you_lose;
+               }
                lseek(fd1, (off_t) 0, SEEK_SET);
                return fd1;
        }
@@ -1334,7 +1153,7 @@ you_lose:
        }
 
        /* now create a FILE pointer for it */
-       if ((qfp = fdopen(fd2, "r")) == NULL) {
+       if (!(qfp = fdopen(fd2, "r"))) {
                close(fd1);
                close(fd2);
                return -1;
@@ -1348,7 +1167,7 @@ you_lose:
        }
 
        /* now create a FILE pointer for it */
-       if ((ffp = fdopen(fd2, "r+")) == NULL) {
+       if (!(ffp = fdopen(fd2, "r+"))) {
                close(fd1);
                close(fd2);
                fclose(qfp);
@@ -1364,69 +1183,26 @@ you_lose:
        while (fgets(buffer, sizeof(buffer), qfp)) {
                if (first) {
                        first = 0;
-                       if (!strncmp(buffer, "From ", i)) {
-#ifdef RPATHS
-                               char *fp, *cp, *hp, *ep;
-#endif
+                       if (strncmp(buffer, "From ", i)==0) {
                                /*
                                ** get copy of envelope information
                                ** ("From " line)
                                */
                                envelope = getcpy(buffer);
 
-#if 0
-                               /*
-                               ** First go ahead and put "From " line
-                               ** in message
-                               */
-                               fputs(buffer, ffp);
-                               if (ferror(ffp))
-                                       goto fputs_error;
-#endif
-
-#ifdef RPATHS
-                               /*
-                               ** Now create a "Return-Path:" line
-                               ** from the "From " line.
-                               */
-                               hp = cp = strchr(fp = envelope + i, ' ');
-                               while ((hp = strchr(++hp, 'r')))
-                                       if (uprf(hp, "remote from")) {
-                                               hp = strrchr(hp, ' ');
-                                               break;
-                                       }
-                               if (hp) {
-                                       /*
-                                       ** return path for UUCP style
-                                       ** addressing
-                                       */
-                                       ep = strchr(++hp, '\n');
-                                       snprintf(buffer, sizeof(buffer), "Return-Path: %.*s!%.*s\n", (int)(ep - hp), hp, (int)(cp - fp), fp);
-                               } else {
-                                       /*
-                                       ** return path for standard domain
-                                       ** addressing
-                                       */
-                                       snprintf(buffer, sizeof(buffer), "Return-Path: %.*s\n", (int)(cp - fp), fp);
-                               }
-
-                               /* Add Return-Path header to message */
-                               fputs(buffer, ffp);
-                               if (ferror(ffp))
-                                       goto fputs_error;
-#endif
                                /* Put the delivery date in message */
                                fputs(ddate, ffp);
-                               if (ferror(ffp))
+                               if (ferror(ffp)) {
                                        goto fputs_error;
-
+                               }
                                continue;
                        }
                }
 
                fputs(buffer, ffp);
-               if (ferror(ffp))
+               if (ferror(ffp)) {
                        goto fputs_error;
+               }
        }
 
        fclose(ffp);
@@ -1439,7 +1215,6 @@ you_lose:
        lseek(fd1, (off_t) 0, SEEK_SET);
        return fd1;
 
-
 fputs_error:
        close(fd1);
        fclose(ffp);
@@ -1450,45 +1225,45 @@ fputs_error:
 /*
 ** Trim strings for pretty printing of debugging output
 */
-
 static char *
-trim(char *cp)
+trimstr(char *cp)
 {
        char buffer[BUFSIZ*4];
        unsigned char *bp, *sp;
 
-       if (cp == NULL)
+       if (!cp) {
                return NULL;
+       }
 
        /* copy string into temp buffer */
        strncpy(buffer, cp, sizeof(buffer));
        bp = buffer;
 
        /* skip over leading whitespace */
-       while (isspace(*bp))
+       while (isspace(*bp)) {
                bp++;
-
+       }
        /* start at the end and zap trailing whitespace */
        for (sp = bp + strlen(bp) - 1; sp >= bp; sp--) {
-               if (isspace(*sp))
-                       *sp = 0;
-               else
+               if (isspace(*sp)) {
+                       *sp = '\0';
+               } else {
                        break;
+               }
        }
 
        /* replace remaining whitespace with spaces */
-       for (sp = bp; *sp; sp++)
-               if (isspace(*sp))
+       for (sp = bp; *sp; sp++) {
+               if (isspace(*sp)) {
                        *sp = ' ';
-
-       /* now return a copy */
+               }
+       }
        return getcpy(bp);
 }
 
 /*
 ** Function for printing `verbose' messages.
 */
-
 static void
 verbose_printf(char *fmt, ...)
 {
@@ -1497,8 +1272,7 @@ verbose_printf(char *fmt, ...)
        va_start(ap, fmt);
        vfprintf(stdout, fmt, ap);
        va_end(ap);
-
-       fflush(stdout);  /* now flush output */
+       fflush(stdout);
 }
 
 
@@ -1506,7 +1280,6 @@ verbose_printf(char *fmt, ...)
 ** Function for printing `verbose' delivery
 ** error messages.
 */
-
 static void
 adorn(char *what, char *fmt, ...)
 {
@@ -1522,12 +1295,14 @@ adorn(char *what, char *fmt, ...)
        va_end(ap);
 
        if (what) {
-               if (*what)
+               if (*what) {
                        fprintf(stdout, " %s: ", what);
-               if ((s = strerror(eindex)))
+               }
+               if ((s = strerror(eindex))) {
                        fprintf(stdout, "%s", s);
-               else
+               } else {
                        fprintf(stdout, "Error %d", eindex);
+               }
        }
 
        fputc('\n', stdout);
@@ -1538,7 +1313,6 @@ adorn(char *what, char *fmt, ...)
 /*
 ** Function for printing `debug' messages.
 */
-
 static void
 debug_printf(char *fmt, ...)
 {
@@ -1548,108 +1322,3 @@ debug_printf(char *fmt, ...)
        vfprintf(stderr, fmt, ap);
        va_end(ap);
 }
-
-
-/*
-** Check ndbm/db file(s) to see if the Message-Id of this
-** message matches the Message-Id of a previous message,
-** so we can discard it.  If it doesn't match, we add the
-** Message-Id of this message to the ndbm/db file.
-*/
-static int
-suppress_duplicates(int fd, char *file)
-{
-       int fd1, lockfd, state, result;
-       char *cp, buf[BUFSIZ], name[NAMESZ];
-       datum key, value;
-       DBM *db;
-       FILE *in;
-
-       if ((fd1 = dup(fd)) == -1)
-               return -1;
-       if (!(in = fdopen(fd1, "r"))) {
-               close(fd1);
-               return -1;
-       }
-       rewind(in);
-
-       for (state = FLD;;) {
-               state = m_getfld(state, name, buf, sizeof(buf), in);
-               switch (state) {
-                       case FLD:
-                       case FLDPLUS:
-                       case FLDEOF:
-                               /* Search for the message ID */
-                               if (mh_strcasecmp(name, "Message-ID")) {
-                                       while (state == FLDPLUS)
-                                               state = m_getfld(state, name, buf, sizeof(buf), in);
-                                       continue;
-                               }
-
-                               cp = getcpy(buf);
-                               while (state == FLDPLUS) {
-                                       state = m_getfld(state, name, buf, sizeof(buf), in);
-                                       cp = add(buf, cp);
-                               }
-                               key.dptr = trimcpy(cp);
-                               key.dsize = strlen(key.dptr) + 1;
-                               free(cp);
-                               cp = key.dptr;
-
-                               if (!(db = dbm_open(file, O_RDWR | O_CREAT,
-                                               0600))) {
-                                       advise(file, "unable to perform dbm_open on");
-                                       free(cp);
-                                       fclose(in);
-                                       return -1;
-                               }
-                               /*
-                               ** Since it is difficult to portable
-                               ** lock a ndbm file, we will open and
-                               ** lock the Maildelivery file instead.
-                               ** This will fail if your Maildelivery
-                               ** file doesn't exist.
-                               */
-                               if ((lockfd = lkopen(file, O_RDWR, 0)) == -1) {
-                                       advise(file, "unable to perform file locking on");
-                                       free(cp);
-                                       fclose(in);
-                                       return -1;
-                               }
-                               value = dbm_fetch(db, key);
-                               if (value.dptr) {
-                                       if (verbose)
-                                               verbose_printf("Message-ID: %s\n            already received on %s", cp, value.dptr);
-                                       result = DONE;
-                               } else {
-                                       value.dptr  = ddate + sizeof("Delivery-Date:");
-                                       value.dsize = strlen(value.dptr) + 1;
-                                       if (dbm_store(db, key, value, DBM_INSERT))
-                                               advise(file, "possibly corrupt file");
-                                       result = 0;
-                               }
-
-                               dbm_close(db);
-                               lkclose(lockfd, file);
-                               free(cp);
-                               fclose(in);
-                               return result;
-                               break;
-
-                  case BODY:
-                  case BODYEOF:
-                  case FILEEOF:
-                               break;
-
-                  case LENERR:
-                  case FMTERR:
-                  default:
-                               break;
-               }
-
-               break;
-       }
-
-       fclose(in);
-       return 0;
-}