remove longjmp in signalhandler of slocal
[mmh] / uip / slocal.c
index c8af725..cf9a9b0 100644 (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/rcvmail.h>
 extern int  initgroups(char*, int);
 #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 },
@@ -75,11 +59,11 @@ static struct swit switches[] = {
 #define VERBSW  8
        { "verbose", 0 },
 #define NVERBSW  9
-       { "noverbose", 0 },
+       { "noverbose", 2 },
 #define DEBUGSW  10
        { "debug", 0 },
 #define VERSIONSW  11
-       { "version", 0 },
+       { "Version", 0 },
 #define HELPSW  12
        { "help", 0 },
        { NULL, 0 }
@@ -88,7 +72,6 @@ static struct swit switches[] = {
 
 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 verbose = 0;
 static int debug = 0;
@@ -107,7 +90,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 pid_t child_id;
 
 /* flags for pair->p_flags */
 #define P_NIL  0x00
@@ -170,18 +154,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 *);
 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 char *trim(char *);
+static char *trimstr(char *);
 
 
 int
@@ -193,15 +175,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);
-       }
        arguments = getarguments(invo_name, argc, argv, 0);
        argp = arguments;
 
@@ -211,17 +187,17 @@ main(int argc, char **argv)
                        switch (smatch(++cp, switches)) {
                        case AMBIGSW:
                                ambigsw(cp, switches);
-                               done(1);
+                               exit(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);
+                               exit(0);
                        case VERSIONSW:
                                print_version(invo_name);
-                               done(1);
+                               exit(0);
 
                        case ADDRSW:
                                if (!(addr = *argp++)) {
@@ -338,7 +314,7 @@ main(int argc, char **argv)
        if (!(now = dlocaltimenow())) {
                adios(NULL, "unable to ascertain local time");
        }
-       snprintf(ddate, sizeof(ddate), "Delivery-Date: %s\n", dtimenow(0));
+       snprintf(ddate, sizeof(ddate), "Delivery-Date: %s\n", dtimenow());
 
        /*
        ** Copy the message to a temporary file
@@ -407,23 +383,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);
 }
 
 
@@ -508,7 +483,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]));
                        }
                }
 
@@ -562,15 +537,6 @@ usr_delivery(int fd, char *delivery, int su)
                        break;
                }
 
-               if (vecp > 5 && mh_strcasecmp(vec[5], "select")==0) {
-                       if (logged_in() != -1) {
-                               continue;
-                       }
-                       if (vecp > 7 && timely(vec[6], vec[7]) == -1) {
-                               continue;
-                       }
-               }
-
                /* check if the field matches */
                switch (*field) {
                case '*':
@@ -858,14 +824,14 @@ parse(int fd)
                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;
@@ -943,7 +909,7 @@ glob(int fd)
        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));
                }
        }
 }
@@ -966,96 +932,6 @@ lookup(struct pair *pairs, char *key)
 
 
 /*
-** 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())) {
-               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"))) {
-               return NOTOK;
-       }
-       while (fread((char *) &ut, sizeof(ut), 1, uf) == 1) {
-               if (ut.ut_name[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;
-}
-
-
-/*
 ** Deliver message by appending to a file, using rcvpack(1).
 */
 static int
@@ -1159,16 +1035,6 @@ usr_pipe(int fd, char *cmd, char *pgm, char **vec, int suppress)
 
        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;
 
@@ -1186,6 +1052,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");
@@ -1200,14 +1073,11 @@ usr_pipe(int fd, char *cmd, char *pgm, char **vec, int suppress)
 }
 
 
-static RETSIGTYPE
+static void
 alrmser(int i)
 {
-#ifndef RELIABLE_SIGNALS
-       SIGNAL(SIGALRM, alrmser);
-#endif
-
-       longjmp(myctx, DONE);
+       eflag = 1;
+       kill(-child_id, SIGKILL);
 }
 
 
@@ -1229,6 +1099,7 @@ get_sender(char *envelope, char **sender)
 
        i = strlen("From ");
        strncpy(buffer, envelope + i, sizeof(buffer));
+       buffer[sizeof buffer -1] = '\0';  /* ensure termination */
        if ((cp = strchr(buffer, '\n'))) {
                *cp = '\0';
                cp -= 24;
@@ -1364,7 +1235,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;