Fix uip/whom.c for C89 compatibility
[mmh] / uip / slocal.c
index 107117f..df0dc7f 100644 (file)
 **
 */
 
-
 #include <h/mh.h>
 #include <h/rcvmail.h>
 #include <h/signals.h>
 #include <h/tws.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
@@ -69,6 +72,7 @@ static struct swit switches[] = {
        { NULL, 0 }
 };
 
+char *version=VERSION;
 
 static int globbed = 0;  /* have we built "vars" table yet? */
 static int parsed = 0;  /* have we built header field table yet */
@@ -90,7 +94,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
@@ -162,7 +167,7 @@ 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 char *trim(char *);
+static char *trimstr(char *);
 
 
 int
@@ -186,72 +191,72 @@ main(int argc, char **argv)
                        switch (smatch(++cp, switches)) {
                        case AMBIGSW:
                                ambigsw(cp, switches);
-                               done(1);
+                               exit(EX_USAGE);
                        case UNKWNSW:
-                               adios(NULL, "-%s unknown", cp);
+                               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);
-                               done(1);
+                               exit(argc == 2 ? EX_OK : EX_USAGE);
                        case VERSIONSW:
                                print_version(invo_name);
-                               done(1);
+                               exit(argc == 2 ? EX_OK : EX_USAGE);
 
                        case ADDRSW:
                                if (!(addr = *argp++)) {
                                        /* allow -xyz arguments */
-                                       adios(NULL, "missing argument to %s",
+                                       adios(EX_USAGE, NULL, "missing argument to %s",
                                                        argp[-2]);
                                }
                                continue;
                        case INFOSW:
                                if (!(info = *argp++)) {
                                        /* allow -xyz arguments */
-                                       adios(NULL, "missing argument to %s",
+                                       adios(EX_USAGE, NULL, "missing argument to %s",
                                                        argp[-2]);
                                }
                                continue;
                        case USERSW:
                                if (!(user = *argp++)) {
                                        /* allow -xyz arguments */
-                                       adios(NULL, "missing argument to %s",
+                                       adios(EX_USAGE, NULL, "missing argument to %s",
                                                        argp[-2]);
                                }
                                continue;
                        case FILESW:
                                if (!(file = *argp++) || *file == '-') {
-                                       adios(NULL, "missing argument to %s",
+                                       adios(EX_USAGE, NULL, "missing argument to %s",
                                                        argp[-2]);
                                }
                                continue;
                        case SENDERSW:
                                if (!(sender = *argp++)) {
                                        /* allow -xyz arguments */
-                                       adios(NULL, "missing argument to %s",
+                                       adios(EX_USAGE, NULL, "missing argument to %s",
                                                        argp[-2]);
                                }
                                continue;
                        case MAILBOXSW:
                                if (!(mbox = *argp++) || *mbox == '-') {
-                                       adios(NULL, "missing argument to %s",
+                                       adios(EX_USAGE, NULL, "missing argument to %s",
                                                        argp[-2]);
                                }
                                continue;
                        case HOMESW:
                                if (!(home = *argp++) || *home == '-') {
-                                       adios(NULL, "missing argument to %s",
+                                       adios(EX_USAGE, NULL, "missing argument to %s",
                                                        argp[-2]);
                                }
                                continue;
 
                        case MAILSW:
                                if (!(cp = *argp++) || *cp == '-') {
-                                       adios(NULL, "missing argument to %s",
+                                       adios(EX_USAGE, NULL, "missing argument to %s",
                                                        argp[-2]);
                                }
                                if (mdlvr) {
-                                       adios(NULL, "only one maildelivery file at a time!");
+                                       adios(EX_USAGE, NULL, "only one maildelivery file at a time!");
                                }
                                mdlvr = cp;
                                continue;
@@ -289,7 +294,7 @@ main(int argc, char **argv)
                user = (cp = strchr(addr, '.')) ? ++cp : addr;
        }
        if (!(pw = getpwnam(user))) {
-               adios(NULL, "no such local user as %s", user);
+               adios(EX_NOUSER, NULL, "no such local user as %s", user);
        }
 
        if (chdir(pw->pw_dir) == -1) {
@@ -311,7 +316,7 @@ main(int argc, char **argv)
 
        /* Record the delivery time */
        if (!(now = dlocaltimenow())) {
-               adios(NULL, "unable to ascertain local time");
+               adios(EX_OSERR, NULL, "unable to ascertain local time");
        }
        snprintf(ddate, sizeof(ddate), "Delivery-Date: %s\n", dtimenow());
 
@@ -323,14 +328,14 @@ main(int argc, char **argv)
 
                /* getting message from file */
                if ((tempfd = open(file, O_RDONLY)) == -1) {
-                       adios(file, "unable to open");
+                       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");
+                       adios(EX_CANTCREAT, NULL, "unable to create temporary file");
                }
                close(tempfd);
        } else {
@@ -339,7 +344,7 @@ main(int argc, char **argv)
                        debug_printf("retrieving message from stdin\n");
                }
                if ((fd = copy_message(fileno(stdin), tmpfil, 1)) == -1) {
-                       adios(NULL, "unable to create temporary file");
+                       adios(EX_CANTCREAT, NULL, "unable to create temporary file");
                }
        }
 
@@ -365,7 +370,7 @@ main(int argc, char **argv)
        unlink(tmpfil);
 
        if (!(fp = fdopen(fd, "r+"))) {
-               adios(NULL, "unable to access temporary file");
+               adios(EX_IOERR, NULL, "unable to access temporary file");
        }
 
        /* If no sender given, extract it from envelope information. */
@@ -382,23 +387,22 @@ main(int argc, char **argv)
        }
 
        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);
 }
 
 
@@ -483,7 +487,7 @@ usr_delivery(int fd, char *delivery, int su)
                if (debug) {
                        for (i = 0; vec[i]; i++) {
                                debug_printf("vec[%d]: \"%s\"\n",
-                                               i, trim(vec[i]));
+                                               i, trimstr(vec[i]));
                        }
                }
 
@@ -721,10 +725,10 @@ split(char *cp, char **vec)
 static int
 parse(int fd)
 {
-       int i, state;
-       int fd1;
+       enum state state;
+       struct field f = {{0}};
+       int i, fd1;
        char *cp, *dp, *lp;
-       char name[NAMESZ], field[BUFSIZ];
        struct pair *p, *q;
        FILE  *in;
 
@@ -744,29 +748,25 @@ parse(int fd)
 
        /* add special entries to lookup table */
        if ((p = lookup(hdrs, "source"))) {
-               p->p_value = getcpy(sender);
+               p->p_value = mh_xstrdup(sender);
        }
        if ((p = lookup(hdrs, "addr"))) {
-               p->p_value = getcpy(addr);
+               p->p_value = mh_xstrdup(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 (i = 0, state = FLD2;;) {
+               switch (state = m_getfld2(state, &f, in)) {
+               case LENERR2:
+                       state = FLD2;
+                       /* FALL */
+
+               case FLD2:
+                       lp = mh_xstrdup(f.value);
                        for (p = hdrs; p->p_name; p++) {
-                               if (mh_strcasecmp(p->p_name, name)!=0) {
+                               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) {
@@ -781,29 +781,25 @@ parse(int fd)
                                                }
                                                p->p_value = add(lp, cp);
                                        }
-                                       free(lp);
+                                       mh_free0(&lp);
                                        break;
                                }
                        }
                        if (!p->p_name && i < NVEC) {
-                               p->p_name = getcpy(name);
+                               p->p_name = mh_xstrdup(f.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:
+               case BODY2:
+               case FILEEOF2:
                        break;
 
-               case LENERR:
-               case FMTERR:
+               case FMTERR2:
+               case IOERR2:
                        advise(NULL, "format error in message");
                        break;
 
@@ -820,18 +816,18 @@ parse(int fd)
                if (!(q = lookup(hdrs, "reply-to")) || !q->p_value) {
                        q = lookup(hdrs, "from");
                }
-               p->p_value = getcpy(q ? q->p_value : "");
+               p->p_value = mh_xstrdup(q ? q->p_value : "");
                p->p_flags &= ~P_CHK;
                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++) {
                        debug_printf("hdrs[%d]: name=\"%s\" value=\"%s\"\n",
                                        p - hdrs, p->p_name,
-                                       p->p_value ? trim(p->p_value) : "");
+                                       p->p_value ? trimstr(p->p_value) : "");
                }
        }
        return 0;
@@ -893,23 +889,23 @@ glob(int fd)
                return;
        }
        if ((p = lookup(vars, "sender"))) {
-               p->p_value = getcpy(sender);
+               p->p_value = mh_xstrdup(sender);
        }
        if ((p = lookup(vars, "address"))) {
-               p->p_value = getcpy(addr);
+               p->p_value = mh_xstrdup(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);
+               p->p_value = mh_xstrdup(buffer);
        }
        if ((p = lookup(vars, "info"))) {
-               p->p_value = getcpy(info);
+               p->p_value = mh_xstrdup(info);
        }
        if (debug) {
                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));
                }
        }
 }
@@ -981,7 +977,6 @@ usr_folder(int fd, char *string)
 static int
 usr_pipe(int fd, char *cmd, char *pgm, char **vec, int suppress)
 {
-       pid_t child_id;
        int bytes, seconds, status, n;
        struct stat st;
        char *path;
@@ -1031,20 +1026,10 @@ usr_pipe(int fd, char *cmd, char *pgm, char **vec, int suppress)
                m_putenv("PATH", path);
 
                execvp(pgm, vec);
-               _exit(-1);
+               _exit(EX_OSERR);
 
        default:
                /* parent process */
-               if (setjmp(myctx)) {
-                       /*
-                       ** Ruthlessly kill the child and anything
-                       ** else in its process group.
-                       */
-                       kill(-child_id, SIGKILL);
-                       if (verbose)
-                               verbose_printf(", timed-out; terminated\n");
-                       return -1;
-               }
                SIGNAL(SIGALRM, alrmser);
                bytes = fstat(fd, &st) != -1 ? (int) st.st_size : 100;
 
@@ -1062,6 +1047,13 @@ usr_pipe(int fd, char *cmd, char *pgm, char **vec, int suppress)
                status = pidwait(child_id, 0);
                alarm(0);
 
+               if (eflag) {
+                       if (verbose) {
+                               verbose_printf(", timed-out; terminated\n");
+                       }
+                       return -1;
+               }
+
                if (verbose) {
                        if (!status) {
                                verbose_printf(", success.\n");
@@ -1079,7 +1071,8 @@ usr_pipe(int fd, char *cmd, char *pgm, char **vec, int suppress)
 static void
 alrmser(int i)
 {
-       longjmp(myctx, DONE);
+       eflag = 1;
+       kill(-child_id, SIGKILL);
 }
 
 
@@ -1095,7 +1088,7 @@ get_sender(char *envelope, char **sender)
        unsigned char buffer[BUFSIZ];
 
        if (!envelope) {
-               *sender = getcpy("");
+               *sender = mh_xstrdup("");
                return;
        }
 
@@ -1119,7 +1112,7 @@ get_sender(char *envelope, char **sender)
                } else {
                        break;
                }
-       *sender = getcpy(buffer);
+       *sender = mh_xstrdup(buffer);
 }
 
 
@@ -1199,7 +1192,7 @@ you_lose:
                                ** get copy of envelope information
                                ** ("From " line)
                                */
-                               envelope = getcpy(buffer);
+                               envelope = mh_xstrdup(buffer);
 
                                /* Put the delivery date in message */
                                fputs(ddate, ffp);
@@ -1237,7 +1230,7 @@ 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;
@@ -1269,7 +1262,7 @@ trim(char *cp)
                        *sp = ' ';
                }
        }
-       return getcpy(bp);
+       return mh_xstrdup(bp);
 }
 
 /*