Renamed the mbx_* functions to mbox_*, because mbx is another mail box format.
[mmh] / uip / slocal.c
index ac9225b..4e8c30d 100644 (file)
@@ -9,7 +9,7 @@
 /*
 **  Under sendmail, users should add the line
 **
-**      "| /usr/local/nmh/lib/slocal"
+**      "| /usr/local/mmh/bin/slocal"
 **
 **  to their $HOME/.forward file.
 **
@@ -25,7 +25,6 @@
 #include <h/rcvmail.h>
 #include <h/signals.h>
 #include <h/tws.h>
-#include <h/mts.h>
 #include <h/utils.h>
 
 #include <pwd.h>
 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
@@ -89,23 +77,23 @@ static struct swit switches[] = {
        { "verbose", 0 },
 #define NVERBSW  9
        { "noverbose", 0 },
-#define SUPPRESSDUP   10
-       { "suppressdup", 0 },
-#define NSUPPRESSDUP 11
-       { "nosuppressdup", 0 },
-#define DEBUGSW  12
+#define DEBUGSW  10
        { "debug", 0 },
-#define VERSIONSW  13
+#define VERSIONSW  11
        { "version", 0 },
-#define HELPSW  14
+#define HELPSW  12
        { "help", 0 },
        { NULL, 0 }
 };
 
+
+/* global maildelivery file */
+char *maildelivery = NMHETCDIR"/maildelivery";
+
+
 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 verbose = 0;
 static int debug = 0;
@@ -189,7 +177,7 @@ 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);
@@ -198,7 +186,6 @@ 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 *);
 
 
@@ -220,7 +207,6 @@ main(int argc, char **argv)
        if (context_foil(NULL) == -1)
                done(1);
 
-       mts_init(invo_name);
        arguments = getarguments(invo_name, argc, argv, 0);
        argp = arguments;
 
@@ -228,92 +214,92 @@ 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);
+                               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 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(NULL, "missing argument to %s",
+                                                       argp[-2]);
+                               if (mdlvr)
+                                       adios(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;
                }
        }
 
@@ -399,8 +385,7 @@ main(int argc, char **argv)
 
        if (mbox == NULL) {
                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)
@@ -434,11 +419,6 @@ main(int argc, char **argv)
 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;
-
        /* delivery according to personal Maildelivery file */
        if (usr_delivery(fd, mdlvr ? mdlvr : ".maildelivery", 0) != -1)
                return 0;
@@ -451,11 +431,7 @@ localmail(int fd, char *mdlvr)
                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);
 }
 
 
@@ -527,42 +503,42 @@ 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 '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 '?':
+                       /*
+                       ** If already delivered, skip this action.
+                       ** Else consider delivered if action is
+                       ** successful.
+                       */
+                       if (won)
+                               continue;  /* else fall */
 
-                       case 'A':
-                       case 'a':
-                               /*
-                               ** Take action, and consider delivered if
-                               ** action is successful.
-                               */
-                               accept = 1;
-                               break;
+               case 'A':
+               case 'a':
+                       /*
+                       ** Take action, and consider delivered if
+                       ** action is successful.
+                       */
+                       accept = 1;
+                       break;
 
-                       case 'R':
-                       case 'r':
-                       default:
-                               /*
-                               ** Take action, but don't consider delivered,
-                               ** even if action is successful
-                               */
-                               accept = 0;
-                               break;
+               case 'R':
+               case 'r':
+               default:
+                       /*
+                       ** Take action, but don't consider delivered,
+                       ** even if action is successful
+                       */
+                       accept = 0;
+                       break;
                }
 
                if (vecp > 5) {
@@ -576,106 +552,97 @@ usr_delivery(int fd, char *delivery, int su)
 
                /* check if the field matches */
                switch (*field) {
-                       case '*':
-                       /* always matches */
+               case '*':
+               /* always matches */
+                       break;
+
+               case 'd':
+               /*
+               ** "default" matches only if the message hasn't
+               ** been delivered yet.
+               */
+                       if (!mh_strcasecmp(field, "default")) {
+                               if (won)
+                                       continue;
                                break;
+                       }  /* else fall */
 
-                       case 'd':
+               default:
+                       /* parse message and build lookup table */
+                       if (!parsed && parse(fd) == -1) {
+                               fclose(fp);
+                               return -1;
+                       }
                        /*
-                       ** "default" matches only if the message hasn't
-                       ** been delivered yet.
+                       ** find header field in lookup table, and
+                       ** see if the pattern matches.
                        */
-                               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;
-                                       continue;
-                               }
-                               break;
+                       if ((p = lookup(hdrs, field)) && (p->p_value != NULL)
+                                       && 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;  /* else 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;  /* 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 'f':
-                               /* 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);
+               case 'f':
+                       /* mbox format */
+                       if (!mh_strcasecmp(action, "file")) {
+                               status = usr_file(fd, string);
                                break;
+                       }
+                       /* deliver to nmh folder */
+                       else if (mh_strcasecmp(action, "folder"))
+                               continue;  /* else fall */
+               case '+':
+                       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 'm':
+                       /* mbox format */
+                       if (mh_strcasecmp(action, "mbox"))
+                               continue;  /* else fall */
 
-                       case '>':
-                               /* mbox format */
-                               status = usr_file(fd, string, MBOX_FORMAT);
-                               break;
+               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"))
+                               continue;
+                       status = 0;
+                       break;
                }
 
                if (status)
@@ -789,59 +756,59 @@ parse(int fd)
        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);
-                                                               }
+               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);
                                                        }
-                                                       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 == 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;
 
-                       case BODY:
-                       case BODYEOF:
-                       case FILEEOF:
-                               break;
+               case BODY:
+               case BODYEOF:
+               case FILEEOF:
+                       break;
 
-                       case LENERR:
-                       case FMTERR:
-                               advise(NULL, "format error in message");
-                               break;
+               case LENERR:
+               case FMTERR:
+                       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;
        }
@@ -860,7 +827,8 @@ parse(int fd)
        if (debug) {
                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 ? trim(p->p_value) : "");
        }
 
        return 0;
@@ -1054,25 +1022,18 @@ timely(char *t1, char *t2)
 */
 
 static int
-usr_file(int fd, char *mailbox, int mbx_style)
+usr_file(int fd, char *mailbox)
 {
-       int md, mapping;
+       int md;
 
        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;
-       }
+       if (verbose)
+               verbose_printf(" (mbox style)");
 
        /* open and lock the file */
-       if ((md = mbx_open(mailbox, mbx_style, pw->pw_uid, pw->pw_gid,
+       if ((md = mbox_open(mailbox, pw->pw_uid, pw->pw_gid,
                        m_gmprot())) == -1) {
                if (verbose)
                        adorn("", "unable to open:");
@@ -1082,15 +1043,14 @@ usr_file(int fd, char *mailbox, int mbx_style)
        lseek(fd, (off_t) 0, SEEK_SET);
 
        /* append message to file */
-       if (mbx_copy(mailbox, mbx_style, md, fd, mapping, NULL, verbose)
-                       == -1) {
+       if (mbox_copy(md, fd) == -1) {
                if (verbose)
                        adorn("", "error writing to:");
                return -1;
        }
 
        /* close and unlock file */
-       if (mbx_close(mailbox, md) == NOTOK) {
+       if (mbox_close(mailbox, md) == NOTOK) {
                if (verbose)
                        adorn("", "error closing:");
                return -1;
@@ -1163,84 +1123,84 @@ usr_pipe(int fd, char *cmd, char *pgm, char **vec, int suppress)
                sleep(5);
 
        switch (child_id) {
-               case -1:
-                       /* fork error */
-                       if (verbose)
-                               adorn("fork", "unable to");
-                       return -1;
+       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);
+               closefds(4);
 
 #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());
+               /* 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);
+               *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);
+               execvp(pgm, vec);
+               _exit(-1);
 
-               default:
-                       /* parent process */
-                       if (!setjmp(myctx)) {
-                               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 (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);
+                       /*
+                       ** 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 {
-                               /*
-                               ** 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;
+                               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);
+               } 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;
+               }
        }
 }
 
@@ -1364,7 +1324,7 @@ you_lose:
        while (fgets(buffer, sizeof(buffer), qfp)) {
                if (first) {
                        first = 0;
-                       if (!strncmp(buffer, "From ", i)) {
+                       if (strncmp(buffer, "From ", i)==0) {
 #ifdef RPATHS
                                char *fp, *cp, *hp, *ep;
 #endif
@@ -1548,108 +1508,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;
-}