]> diplodocus.org Git - nmh/blobdiff - uip/slocal.c
Alter HasSuffixC()'s char * to be const.
[nmh] / uip / slocal.c
index a306cadaefe6c96767b8310675be6f1380de291b..772c4e2bb0fc55dd88abdf60021c4cf0dc5f0b16 100644 (file)
@@ -2,7 +2,9 @@
 /*
  * slocal.c -- asynchronously filter and deliver new mail
  *
- * $Id$
+ * This code is Copyright (c) 2002, by the authors of nmh.  See the
+ * COPYRIGHT file in the root directory of the nmh distribution for
+ * complete copyright information.
  */
 
 /*
  *
  *  to their $HOME/.forward file.
  *
- *  Under MMDF-I, users should (symbolically) link
- *  /usr/local/nmh/lib/slocal to $HOME/bin/rcvmail.
- *
+ */
+
+/* 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 <zotnet/tws/tws.h>
-#include <zotnet/mts/mts.h>
+#include <setjmp.h>
+#include <h/tws.h>
+#include <h/mts.h>
+#include <h/utils.h>
 
 #include <pwd.h>
-#include <signal.h>
 #include <sys/ioctl.h>
-#include <ndbm.h>
 #include <fcntl.h>
 
-#include <utmp.h>
+/* Hopefully, grp.h declares initgroups().  If we run into a platform
+   where it doesn't, we could consider declaring it here as well. */
+#include <grp.h>
 
-#ifndef UTMP_FILE
-# ifdef _PATH_UTMP
-#  define UTMP_FILE _PATH_UTMP
-# else
-#  define UTMP_FILE "/etc/utmp"
-# 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 DB_DBM_HSEARCH
+#endif /* Use DB_DBM_HSEARCH to prevent warning from gcc -Wunused-macros. */
+#ifdef NDBM_HEADER
+#include NDBM_HEADER
 #endif
 
-static struct swit switches[] = {
-#define        ADDRSW         0
-    { "addr address", 0 },
-#define        USERSW         1
-    { "user name", 0 },
-#define        FILESW         2
-    { "file file", 0 },
-#define        SENDERSW       3
-    { "sender address", 0 },
-#define        MAILBOXSW      4
-    { "mailbox file", 0 },
-#define        HOMESW         5
-    { "home directory", -4 },
-#define        INFOSW         6
-    { "info data", 0 },
-#define        MAILSW         7
-    { "maildelivery file", 0 },
-#define        VERBSW         8
-    { "verbose", 0 },
-#define        NVERBSW        9
-    { "noverbose", 0 },
-#define SUPPRESSDUP   10
-    { "suppressdup", 0 },
-#define NSUPPRESSDUP 11
-    { "nosuppressdup", 0 },
-#define        DEBUGSW       12
-    { "debug", 0 },
-#define VERSIONSW     13
-    { "version", 0 },
-#define        HELPSW        14
-    { "help", 4 },
-    { NULL, 0 }
-};
+#ifdef HAVE_GETUTXENT
+#include <utmpx.h>
+#endif /* HAVE_GETUTXENT */
+
+#define SLOCAL_SWITCHES \
+    X("addr address", 0, ADDRSW) \
+    X("user name", 0, USERSW) \
+    X("file file", 0, FILESW) \
+    X("sender address", 0, SENDERSW) \
+    X("mailbox file", 0, MAILBOXSW) \
+    X("home directory", -4, HOMESW) \
+    X("info data", 0, INFOSW) \
+    X("maildelivery file", 0, MAILSW) \
+    X("verbose", 0, VERBSW) \
+    X("noverbose", 0, NVERBSW) \
+    X("suppressdup", 0, SUPPRESSDUP) \
+    X("nosuppressdup", 0, NSUPPRESSDUP) \
+    X("debug", 0, DEBUGSW) \
+    X("version", 0, VERSIONSW) \
+    X("help", 0, HELPSW) \
+
+#define X(sw, minchars, id) id,
+DEFINE_SWITCH_ENUM(SLOCAL);
+#undef X
+
+#define X(sw, minchars, id) { sw, minchars, id },
+DEFINE_SWITCH_ARRAY(SLOCAL, switches);
+#undef X
 
 static int globbed = 0;                /* have we built "vars" table yet?        */
 static int parsed = 0;         /* have we built header field table yet   */
@@ -164,7 +169,7 @@ static int timely (char *, char *);
 static int usr_file (int, char *, int);
 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, ...);
@@ -178,21 +183,14 @@ int
 main (int argc, char **argv)
 {
     int fd, status;
-    FILE *fp = stdin;
+    FILE *fp;
     char *cp, *mdlvr = NULL, buf[BUFSIZ];
     char mailbox[BUFSIZ], tmpfil[BUFSIZ];
     char **argp, **arguments;
 
-#ifdef LOCALE
-    setlocale(LC_ALL, "");
-#endif
-    invo_name = r1bindex (*argv, '/');
-
-    /* foil search of user profile/context */
-    if (context_foil (NULL) == -1)
-       done (1);
+    if (nmh_init(argv[0], 0 /* use context_foil() */)) { return 1; }
 
-    mts_init (invo_name);
+    mts_init ();
     arguments = getarguments (invo_name, argc, argv, 0);
     argp = arguments;
 
@@ -207,13 +205,12 @@ main (int argc, char **argv)
                    adios (NULL, "-%s unknown", cp);
 
                case HELPSW: 
-                   snprintf (buf, sizeof(buf),
-                       "%s [switches] [address info sender]", invo_name);
+                   snprintf (buf, sizeof(buf), "%s [switches]", invo_name);
                    print_help (buf, switches, 0);
-                   done (1);
+                   done (0);
                case VERSIONSW:
                    print_version(invo_name);
-                   done (1);
+                   done (0);
 
                case ADDRSW: 
                    if (!(addr = *argp++))/* allow -xyz arguments */
@@ -269,40 +266,35 @@ main (int argc, char **argv)
                    debug++;
                    continue;
            }
-       }
-
-       switch (argp - (argv + 1)) {
-           case 1: 
-               addr = cp;
-               break;
-
-           case 2: 
-               info = cp;
-               break;
-
-           case 3: 
-               sender = cp;
-               break;
+       } else {
+               adios (NULL, "only switch arguments are supported");
        }
     }
 
     if (addr == NULL)
        addr = getusername ();
-    if (user == NULL)
-       user = (cp = strchr(addr, '.')) ? ++cp : addr;
+    if (user == NULL) {
+       user = getusername ();
+    }
     if ((pw = getpwnam (user)) == NULL)
        adios (NULL, "no such local user as %s", user);
 
     if (chdir (pw->pw_dir) == -1)
-       chdir ("/");
+       if (chdir ("/") < 0) {
+           advise ("/", "chdir");
+       }
     umask (0077);
 
     if (geteuid() == 0) {
-       setgid (pw->pw_gid);
+       if (setgid (pw->pw_gid) != 0) {
+           adios ("setgid", "unable to set group to %ld", (long) pw->pw_gid);
+       }
        initgroups (pw->pw_name, pw->pw_gid);
-       setuid (pw->pw_uid);
+       if (setuid (pw->pw_uid) != 0) {
+           adios ("setuid", "unable to set user to %ld", (long) pw->pw_uid);
+       }
     }
-    
+
     if (info == NULL)
        info = "";
 
@@ -325,14 +317,16 @@ main (int argc, char **argv)
        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");
+           adios(NULL, "unable to create temporary file in %s",
+                  get_temp_dir());
        close (tempfd);
     } else {
        /* getting message from stdin */
        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");
+           adios(NULL, "unable to create temporary file in %s",
+                  get_temp_dir());
     }
 
     if (debug)
@@ -349,7 +343,7 @@ main (int argc, char **argv)
        thing would be to delay this unlink() until later if debug == 1, but I'll
        leave that for someone who cares about the temp-file-accessing
        functionality (they'll have to watch out for cases where we adios()). */
-    unlink (tmpfil);
+    (void) m_unlink (tmpfil);
 
     if (!(fp = fdopen (fd, "r+")))
        adios (NULL, "unable to access temporary file");
@@ -384,7 +378,8 @@ main (int argc, char **argv)
     /* deliver the message */
     status = localmail (fd, mdlvr);
 
-    return done (status != -1 ? RCV_MOK : RCV_MBX);
+    done (status != -1 ? RCV_MOK : RCV_MBX);
+    return 1;
 }
 
 
@@ -412,11 +407,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
 }
 
 
@@ -429,10 +420,10 @@ localmail (int fd, char *mdlvr)
 static int
 usr_delivery (int fd, char *delivery, int su)
 {
-    int i, accept, status, won, vecp, next;
+    int i, accept, status=1, won, vecp, next;
     char *field, *pattern, *action, *result, *string;
     char buffer[BUFSIZ], tmpbuf[BUFSIZ];
-    char *cp, *vec[NVEC];
+    char *vec[NVEC];
     struct stat st;
     struct pair *p;
     FILE *fp;
@@ -461,9 +452,7 @@ usr_delivery (int fd, char *delivery, int su)
        if (*buffer == '#' || *buffer == '\n')
            continue;
 
-       /* zap trailing newline */
-       if ((cp = strchr(buffer, '\n')))
-           *cp = 0;
+        TrimSuffixC(buffer, '\n');
 
        /* split buffer into fields */
        vecp = split (buffer, vec);
@@ -633,6 +622,8 @@ usr_delivery (int fd, char *delivery, int su)
                break;
        }
 
+       if (status) next = 0;   /* action failed, mark for 'N' result */
+
        if (accept && status == 0)
            won++;
     }
@@ -662,7 +653,7 @@ split (char *cp, char **vec)
        vec[i] = NULL;
 
        /* zap any whitespace and comma's */
-       while (isspace (*s) || *s == ',')
+       while (isspace ((unsigned char) *s) || *s == ',')
            *s++ = 0;
 
        /* end of buffer, time to leave */
@@ -692,7 +683,7 @@ split (char *cp, char **vec)
        vec[i++] = s++;
 
        /* move forward to next field delimiter */
-       while (*s && !isspace (*s) && *s != ',')
+       while (*s && !isspace ((unsigned char) *s) && *s != ',')
            s++;
     }
     vec[i] = NULL;
@@ -715,6 +706,7 @@ parse (int fd)
     char name[NAMESZ], field[BUFSIZ];
     struct pair *p, *q;
     FILE  *in;
+    m_getfld_state_t gstate = 0;
 
     if (parsed++)
        return 0;
@@ -738,14 +730,15 @@ parse (int fd)
      * 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)) {
+    for (i = 0;;) {
+       int fieldsz = sizeof field;
+       switch (state = m_getfld (&gstate, name, field, &fieldsz, in)) {
            case FLD: 
-           case FLDEOF: 
            case FLDPLUS: 
                lp = add (field, NULL);
                while (state == FLDPLUS) {
-                   state = m_getfld (state, name, field, sizeof(field), in);
+                   fieldsz = sizeof field;
+                   state = m_getfld (&gstate, name, field, &fieldsz, in);
                    lp = add (field, lp);
                }
                for (p = hdrs; p->p_name; p++) {
@@ -768,18 +761,15 @@ parse (int fd)
                    }
                }
                if (p->p_name == NULL && i < NVEC) {
-                   p->p_name = getcpy (name);
+                   p->p_name = mh_xstrdup(name);
                    p->p_value = lp;
                    p->p_flags = P_NIL;
                    p++, i++;
                    p->p_name = NULL;
                }
-               if (state != FLDEOF)
-                   continue;
-               break;
+               continue;
 
            case BODY: 
-           case BODYEOF: 
            case FILEEOF: 
                break;
 
@@ -795,6 +785,7 @@ parse (int fd)
        }
        break;
     }
+    m_getfld_state_destroy (&gstate);
     fclose (in);
 
     if ((p = lookup (vars, "reply-to"))) {
@@ -881,7 +872,7 @@ glob (int fd)
     if ((p = lookup (vars, "size"))) {
        snprintf (buffer, sizeof(buffer), "%d",
                fstat (fd, &st) != -1 ? (int) st.st_size : 0);
-       p->p_value = getcpy (buffer);
+       p->p_value = mh_xstrdup(buffer);
     }
     if ((p = lookup (vars, "info")))
        p->p_value = getcpy (info);
@@ -918,30 +909,29 @@ lookup (struct pair *pairs, char *key)
 static int
 logged_in (void)
 {
-    struct utmp ut;
-    FILE *uf;
+#if HAVE_GETUTXENT
+    struct utmpx *utp;
 
     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);
-       }
+        return utmped;
+
+    setutxent();
+
+    while ((utp = getutxent()) != NULL) {
+        if ( utp->ut_type == USER_PROCESS && utp->ut_user[0] != 0
+                && strncmp (user, utp->ut_user, sizeof(utp->ut_user)) == 0) {
+            if (debug)
+                continue;
+            endutxent();
+            return (utmped = DONE);
+        }
     }
 
-    fclose (uf);
+    endutxent();
+#endif /* HAVE_GETUTXENT */
     return (utmped = NOTOK);
 }
 
-
 #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
 
@@ -1006,7 +996,11 @@ usr_file (int fd, char *mailbox, int mbx_style)
     }
 
     /* close and unlock file */
-    mbx_close (mailbox, md);
+    if (mbx_close (mailbox, md) == NOTOK) {
+        if (verbose)
+           adorn ("", "error closing:");
+        return -1;
+    }
 
     if (verbose)
        verbose_printf (", success.\n");
@@ -1040,18 +1034,6 @@ usr_folder (int fd, char *string)
     /* 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;
 }
 
@@ -1060,8 +1042,9 @@ usr_folder (int fd, char *string)
  */
 
 static int
-usr_pipe (int fd, char *cmd, char *pgm, char **vec, int suppress)
+usr_pipe (int fd_arg, char *cmd, char *pgm, char **vec, int suppress)
 {
+    volatile int fd = fd_arg;
     pid_t child_id;
     int i, bytes, seconds, status;
     struct stat st;
@@ -1085,8 +1068,12 @@ usr_pipe (int fd, char *cmd, char *pgm, char **vec, int suppress)
            /* child process */
            if (fd != 0)
                dup2 (fd, 0);
-           freopen ("/dev/null", "w", stdout);
-           freopen ("/dev/null", "w", stderr);
+           if (freopen ("/dev/null", "w", stdout) == NULL) {
+               advise ("stdout", "freopen");
+           }
+           if (freopen ("/dev/null", "w", stderr) == NULL) {
+               advise ("stderr", "freopen");
+           }
            if (fd != 3)
                dup2 (fd, 3);
            closefds (4);
@@ -1110,7 +1097,7 @@ usr_pipe (int fd, char *cmd, char *pgm, char **vec, int suppress)
 
        default: 
            /* parent process */
-           if (!setjmp (myctx)) {
+           if (! setjmp (myctx)) {
                SIGNAL (SIGALRM, alrmser);
                bytes = fstat (fd, &st) != -1 ? (int) st.st_size : 100;
 
@@ -1128,10 +1115,6 @@ usr_pipe (int fd, char *cmd, char *pgm, char **vec, int suppress)
                status = pidwait (child_id, 0);
                alarm (0);
 
-#ifdef MMDFI
-               if (status == RP_MOK || status == RP_OK)
-                   status = 0;
-#endif
                if (verbose) {
                    if (status == 0)
                        verbose_printf (", success.\n");
@@ -1142,26 +1125,23 @@ usr_pipe (int fd, char *cmd, char *pgm, char **vec, int suppress)
                            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;
            }
+            /*
+             * 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;
     }
 }
 
 
-static RETSIGTYPE
+static void
 alrmser (int i)
 {
-#ifndef RELIABLE_SIGNALS
-    SIGNAL (SIGALRM, alrmser);
-#endif
+    NMH_UNUSED (i);
 
     longjmp (myctx, DONE);
 }
@@ -1180,11 +1160,11 @@ get_sender (char *envelope, char **sender)
     char buffer[BUFSIZ];
 
     if (envelope == NULL) {
-       *sender = getcpy ("");
+       *sender = mh_xstrdup("");
        return;
     }
 
-    i = strlen ("From ");
+    i = LEN("From ");
     strncpy (buffer, envelope + i, sizeof(buffer));
     if ((cp = strchr(buffer, '\n'))) {
        *cp = 0;
@@ -1197,11 +1177,11 @@ get_sender (char *envelope, char **sender)
     *cp = 0;
 
     for (cp = buffer + strlen (buffer) - 1; cp >= buffer; cp--)
-       if (isspace (*cp))
+       if (isspace ((unsigned char) *cp))
            *cp = 0;
        else
            break;
-    *sender = getcpy (buffer);
+    *sender = mh_xstrdup(buffer);
 }
 
 
@@ -1217,19 +1197,18 @@ copy_message (int qd, char *tmpfil, int fold)
     int i, first = 1, fd1, fd2;
     char buffer[BUFSIZ];
     FILE *qfp, *ffp;
+    char *tfile = NULL;
 
-    strcpy (tmpfil, m_tmpfil (invo_name));
-
-    /* open temporary file to put message in */
-    if ((fd1 = open (tmpfil, O_RDWR | O_CREAT | O_TRUNC, 0600)) == -1)
-       return -1;
+    tfile = m_mktemp2(NULL, invo_name, &fd1, NULL);
+    if (tfile == NULL) return -1;
+    strncpy (tmpfil, tfile, BUFSIZ);
 
     if (!fold) {
        while ((i = read (qd, buffer, sizeof(buffer))) > 0)
            if (write (fd1, buffer, i) != i) {
 you_lose:
                close (fd1);
-               unlink (tmpfil);
+               (void) m_unlink (tmpfil);
                return -1;
            }
        if (i == -1)
@@ -1271,51 +1250,14 @@ you_lose:
      * and massage the headers.  Save
      * a copy of the "From " line for later.
      */
-    i = strlen ("From ");
+    i = LEN("From ");
     while (fgets (buffer, sizeof(buffer), qfp)) {
        if (first) {
            first = 0;
            if (!strncmp (buffer, "From ", i)) {
-#ifdef RPATHS
-               char *fp, *cp, *hp, *ep;
-#endif
                /* 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
+               envelope = mh_xstrdup(buffer);
 
-#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",
-                       ep - hp, hp, cp - fp, fp);
-               } else {
-                   /* return path for standard domain addressing */
-                   snprintf (buffer, sizeof(buffer), "Return-Path: %.*s\n",
-                       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))
@@ -1366,12 +1308,12 @@ trim (char *cp)
     bp = buffer;
 
     /* skip over leading whitespace */
-    while (isspace(*bp))
+    while (isspace((unsigned char) *bp))
        bp++;
 
     /* start at the end and zap trailing whitespace */
     for (sp = bp + strlen(bp) - 1; sp >= bp; sp--) {
-       if (isspace(*sp))
+       if (isspace((unsigned char) *sp))
            *sp = 0;
        else
            break;
@@ -1379,11 +1321,11 @@ trim (char *cp)
 
     /* replace remaining whitespace with spaces */
     for (sp = bp; *sp; sp++)
-       if (isspace(*sp))
+       if (isspace((unsigned char) *sp))
            *sp = ' ';
 
     /* now return a copy */
-    return getcpy(bp);
+    return mh_xstrdup(bp);
 }
 
 /*
@@ -1465,6 +1407,7 @@ suppress_duplicates (int fd, char *file)
     datum key, value;
     DBM *db;
     FILE *in;
+    m_getfld_state_t gstate = 0;
 
     if ((fd1 = dup (fd)) == -1)
        return -1;
@@ -1474,22 +1417,26 @@ suppress_duplicates (int fd, char *file)
     }
     rewind (in);
 
-    for (state = FLD;;) {
-       state = m_getfld (state, name, buf, sizeof(buf), in);
+    for (;;) {
+        int failed_to_lock = 0;
+       int bufsz = sizeof buf;
+       state = m_getfld (&gstate, name, buf, &bufsz, in);
        switch (state) {
            case FLD:
            case FLDPLUS:
-           case FLDEOF:
                /* Search for the message ID */
                if (strcasecmp (name, "Message-ID")) {
-                   while (state == FLDPLUS)
-                       state = m_getfld (state, name, buf, sizeof(buf), in);
+                   while (state == FLDPLUS) {
+                       bufsz = sizeof buf;
+                       state = m_getfld (&gstate, name, buf, &bufsz, in);
+                   }
                    continue;
                }
 
                cp = add (buf, NULL);
                while (state == FLDPLUS) {
-                   state = m_getfld (state, name, buf, sizeof(buf), in);
+                   bufsz = sizeof buf;
+                   state = m_getfld (&gstate, name, buf, &bufsz, in);
                    cp = add (buf, cp);
                }
                key.dptr = trimcpy (cp);
@@ -1509,7 +1456,8 @@ suppress_duplicates (int fd, char *file)
                 * This will fail if your Maildelivery file doesn't
                 * exist.
                 */
-               if ((lockfd = lkopen(file, O_RDWR, 0)) == -1) {
+               if ((lockfd = lkopendata(file, O_RDWR, 0, &failed_to_lock))
+                   == -1) {
                    advise (file, "unable to perform file locking on");
                    free (cp);
                    fclose (in);
@@ -1530,14 +1478,12 @@ suppress_duplicates (int fd, char *file)
                }
 
                dbm_close (db);
-               lkclose(lockfd, file);
+               lkclosedata(lockfd, file);
                free (cp);
                fclose (in);
                return result;
-               break;
 
           case BODY:
-          case BODYEOF:
           case FILEEOF:
                break;
 
@@ -1549,6 +1495,7 @@ suppress_duplicates (int fd, char *file)
 
        break;
     }
+    m_getfld_state_destroy (&gstate);
 
     fclose (in);
     return 0;