Annotation of 43BSDReno/contrib/mh/uip/umhook.c, revision 1.1

1.1     ! root        1: /* umhook.c - one attempt at a rcvmail hook for UUCP mail */
        !             2: 
        !             3: /* I don't comment my code heavily, so read this...
        !             4: 
        !             5:     You run this program from your .login file.  The invocation is simply
        !             6:     "umhook".  The program "detaches" itself and runs unattended until you
        !             7:     logout.  Whenever you get UUCP mail (or upto a minute afterwards),
        !             8:     umhook will filter your UUCP mail drop to a temporary file.  The mail
        !             9:     drop is *NOT* touched beyond this (even the access time remains the
        !            10:     same).  For each message that was new in the mail drop, umhook will
        !            11:     fork a process to interpret your .maildelivery file.
        !            12: 
        !            13:     The umhook program uses the -ljobs control facility to do two things:
        !            14:        - determine when the controlling tty has gone away
        !            15:        - kill a child that's run away (the child sets up a process group)
        !            16:  */
        !            17: 
        !            18: #include "../h/mh.h"
        !            19: #include "../zotnet/mf.h"
        !            20: #include <stdio.h>
        !            21: #include "../zotnet/mts.h"
        !            22: #include <pwd.h>
        !            23: #include <signal.h>
        !            24: #include <sys/ioctl.h>
        !            25: #include <sys/types.h>
        !            26: #include <sys/stat.h>
        !            27: 
        !            28: /*  */
        !            29: 
        !            30: static struct swit switches[] = {
        !            31: #define        SLEEPSW 0
        !            32:     "sleep seconds", 0,
        !            33: 
        !            34: #define        HELPSW  1
        !            35:     "help", 4,
        !            36: 
        !            37:     NULL, NULL
        !            38: };
        !            39: 
        !            40: /*  */
        !            41: 
        !            42: static int  snooze = 60;
        !            43: 
        !            44: static int  uucp = NOTOK;
        !            45: 
        !            46: extern char *environ;
        !            47: 
        !            48: static char myhome[BUFSIZ] = "";
        !            49: static char mymail[BUFSIZ] = "";
        !            50: static char myaddr[BUFSIZ] = "";
        !            51: static char mystat[BUFSIZ] = "";
        !            52: static char myuser[BUFSIZ] = "";
        !            53: 
        !            54: long    lseek ();
        !            55: #ifdef SYS5
        !            56: struct passwd  *getpwuid ();
        !            57: #endif SYS5
        !            58: 
        !            59: 
        !            60: static void umhook(), process(), seeksndr(), seekaddr(), st_init(),
        !            61:     st_update(), done();
        !            62: static int hook();
        !            63: static SIGDECL sigser();
        !            64: 
        !            65: /*  */
        !            66: 
        !            67: /* ARGSUSED */
        !            68: 
        !            69: main(argc, argv)
        !            70:        int argc;
        !            71:        char **argv;
        !            72: {
        !            73:     char   *cp,
        !            74:           **ap,
        !            75:           **argp,
        !            76:             buf[100],
        !            77:            *arguments[MAXARGS];
        !            78:     struct passwd  *pw;
        !            79: 
        !            80:     invo_name = r1bindex (argv[0], '/');
        !            81:     mts_init (invo_name);
        !            82:     if ((cp = m_find (invo_name)) != NULL) {
        !            83:        ap = brkstring (cp = getcpy (cp), " ", "\n");
        !            84:        ap = copyip (ap, arguments);
        !            85:     }
        !            86:     else
        !            87:        ap = arguments;
        !            88:     (void) copyip (argv + 1, ap);
        !            89:     argp = arguments;
        !            90: 
        !            91: /*  */
        !            92: 
        !            93:     while (cp = *argp++) {
        !            94:        if (*cp == '-')
        !            95:            switch (smatch (++cp, switches)) {
        !            96:                case AMBIGSW:
        !            97:                    ambigsw (cp, switches);
        !            98:                    done (1);
        !            99:                case UNKWNSW:
        !           100:                    adios (NULLCP, "-%s unknown", cp);
        !           101:                case HELPSW:
        !           102:                    (void) sprintf (buf, "%s [switches]", invo_name);
        !           103:                    help (buf, switches);
        !           104:                    done (1);
        !           105: 
        !           106:                case SLEEPSW:
        !           107:                    if (!(cp = *argp++) || *cp == '-')
        !           108:                        adios (NULLCP, "missing argument to %s", argp[-2]);
        !           109:                    if ((snooze = atoi (cp)) < 0)
        !           110:                        adios (NULLCP, "bad argument %s %s", argp[-2], cp);
        !           111:                    continue;
        !           112:            }
        !           113:        adios (NULLCP, "usage: %s [switches]", invo_name);
        !           114:     }
        !           115: 
        !           116: /*  */
        !           117: 
        !           118:     if ((pw = getpwuid (getuid ())) == NULL)
        !           119:        adios (NULLCP, "you lose big");
        !           120: 
        !           121:     *environ = NULL;
        !           122:     (void) putenv ("USER", pw -> pw_name);
        !           123:     (void) putenv ("HOME", pw -> pw_dir);
        !           124:     (void) putenv ("SHELL", pw -> pw_shell);
        !           125:     if (chdir (pw -> pw_dir) == NOTOK)
        !           126:        (void) chdir ("/");
        !           127:     (void) umask (0077);
        !           128: 
        !           129:     if (geteuid () == 0) {
        !           130: #ifdef BSD41A
        !           131:        (void) inigrp (pw -> pw_name, pw -> pw_gid);
        !           132: #endif BSD41A
        !           133:        (void) setgid (pw -> pw_gid);
        !           134: #ifdef BSD42
        !           135:        (void) initgroups (pw -> pw_name, pw -> pw_gid);
        !           136: #endif BSD42
        !           137:        (void) setuid (pw -> pw_uid);
        !           138:     }
        !           139: 
        !           140:     (void) sprintf (mymail, "%s/%s",
        !           141:            uucpldir[0] ? uucpldir : pw -> pw_dir,
        !           142:            uucplfil[0] ? uucplfil : pw -> pw_name);
        !           143:     (void) strcpy (myuser, pw -> pw_name);
        !           144:     (void) sprintf (myaddr, "%s@%s", pw -> pw_name, LocalName ());
        !           145:     (void) strcpy (myhome, pw -> pw_dir);
        !           146:     (void) sprintf (mystat, ".%s_%d", invo_name, pw -> pw_uid);
        !           147: 
        !           148:     if (access (slocalproc, 1) == NOTOK)
        !           149:        adios (slocalproc, "unable to execute");
        !           150: 
        !           151:     closefds (fileno (stderr) + 1);
        !           152: 
        !           153:     (void) signal (SIGINT, SIG_IGN);
        !           154:     (void) signal (SIGHUP, sigser);
        !           155:     (void) signal (SIGQUIT, SIG_IGN);
        !           156:     (void) signal (SIGTERM, sigser);
        !           157: 
        !           158:     switch (fork ()) {
        !           159:        case NOTOK:
        !           160:        case OK:
        !           161:            umhook ();
        !           162:            break;
        !           163: 
        !           164:        default:
        !           165:            break;
        !           166:     }
        !           167: 
        !           168:     exit (0);
        !           169: }
        !           170: 
        !           171: /*  */
        !           172: 
        !           173: #ifndef        TIOCGPGRP
        !           174: #define        pgrp_ok(pg)     1
        !           175: #else  TIOCGPGRP
        !           176: #define        pgrp_ok(pg)     (ioctl (2, TIOCGPGRP, (char *) &pg) != NOTOK)
        !           177: #endif TIOCGPGRP
        !           178: 
        !           179: static void
        !           180: umhook()
        !           181: {
        !           182:     int     pg;
        !           183:     struct stat st1,
        !           184:                 st2;
        !           185: 
        !           186:     st_init (&st1);
        !           187: 
        !           188:     for (; pgrp_ok (pg);) {
        !           189:        if (stat (mymail, &st2) == NOTOK) {
        !           190:            st2.st_ino = (ino_t) 0;
        !           191:            st2.st_size = (off_t) 0;
        !           192:            st2.st_mtime = (time_t) 0;
        !           193:        }
        !           194:        else
        !           195:            if (st1.st_mtime != st2.st_mtime)
        !           196:                if (st1.st_ino != st2.st_ino)
        !           197:                    process ((off_t) 0, &st2);
        !           198:                else
        !           199:                    if (st1.st_size < st2.st_size)
        !           200:                        process (st1.st_size, &st2);
        !           201: 
        !           202:        st1.st_ino = st2.st_ino;
        !           203:        st1.st_size = st2.st_size;
        !           204:        st1.st_mtime = st2.st_mtime;
        !           205: 
        !           206:        sleep ((unsigned) snooze);
        !           207:     }
        !           208: }
        !           209: 
        !           210: /*  */
        !           211: 
        !           212: static void
        !           213: process(offset, st)
        !           214:        off_t offset;
        !           215:        struct stat *st;
        !           216: {
        !           217:     int            td1,
        !           218:             td2;
        !           219:     time_t timep[2];
        !           220:     char    tmpfil[BUFSIZ];
        !           221:     register FILE *fp;
        !           222: 
        !           223:     if ((uucp = lkopen (mymail, 0)) == NOTOK)
        !           224:        adios (NULLCP, "unable to lock and open %s", mymail);
        !           225:     if (lseek (uucp, (long) offset, 0) == (long) NOTOK)
        !           226:        adios (mymail, "unable to position to %ld offset on", offset);
        !           227: 
        !           228:     (void) strcpy (tmpfil, m_tmpfil (invo_name));
        !           229:     if ((td1 = creat (tmpfil, TMPMODE)) == NOTOK)
        !           230:        adios (tmpfil, "unable to create");
        !           231:     (void) close (td1);
        !           232: 
        !           233:     if ((td1 = open (tmpfil, 2)) == NOTOK)
        !           234:        adios (tmpfil, "unable to open");
        !           235:     (void) unlink (tmpfil);
        !           236:     if ((td2 = dup (td1)) == NOTOK)
        !           237:        adios ("file descriptor", "unable to dup");
        !           238: 
        !           239:     switch (uucp2mmdf (uucp, td1, FALSE)) {
        !           240:        case MFPRM:
        !           241:            adios (NULLCP, "internal error while filtering UUCP mail");
        !           242: 
        !           243:        case MFSIO:
        !           244:            adios (NULLCP, "no free file pointers");
        !           245: 
        !           246:        case MFERR:
        !           247:            adios ("UUCP mail", "i/o error while filtering");
        !           248: 
        !           249:        case MFOK:
        !           250:        case MFROM:
        !           251:        case MFHDR:
        !           252:        case MFTXT:
        !           253:            timep[0] = st -> st_atime;
        !           254:            timep[1] = st -> st_mtime;
        !           255:            utime (mymail, timep);
        !           256:            st_update (st);
        !           257:            break;
        !           258:     }
        !           259:     (void) lkclose (uucp, mymail), uucp = NOTOK;
        !           260: 
        !           261: /*  */
        !           262: 
        !           263:     (void) close (td1);
        !           264: 
        !           265:     (void) lseek (td2, 0L, 0);
        !           266:     if ((fp = fdopen (td2, "r")) == NULL)
        !           267:        adios (NULLCP, "no free file pointers");
        !           268: 
        !           269:     while (hook (fp))
        !           270:        continue;
        !           271:     (void) fclose (fp);
        !           272: }
        !           273: 
        !           274: /*  */
        !           275: 
        !           276: static int
        !           277: hook(in)
        !           278:        register FILE *in;
        !           279: {
        !           280:     int     child_id,
        !           281:             done,
        !           282:             fd1,
        !           283:             fd2,
        !           284:             i;
        !           285:     char    buffer[BUFSIZ],
        !           286:             mysndr[BUFSIZ],
        !           287:             myfile[BUFSIZ];
        !           288:     register FILE *out;
        !           289: 
        !           290:     if (fgets (buffer, sizeof buffer, in) == NULL)
        !           291:        return FALSE;
        !           292: 
        !           293: /* should insist on isdlm1 (buffer) here... */
        !           294: 
        !           295:     (void) strcpy (myfile, m_tmpfil (invo_name));
        !           296:     if ((fd1 = creat (myfile, TMPMODE)) == NOTOK)
        !           297:        adios (myfile, "unable to create");
        !           298:     (void) close (fd1);
        !           299: 
        !           300:     if ((fd1 = open (myfile, 2)) == NOTOK)
        !           301:        adios (myfile, "unable to open");
        !           302:     (void) unlink (myfile);
        !           303:     if ((fd2 = dup (fd1)) == NOTOK)
        !           304:        adios ("file descriptor", "unable to dup");
        !           305: 
        !           306:     if ((out = fdopen (fd1, "w")) == NULL)
        !           307:        adios (NULLCP, "no free file pointers");
        !           308: 
        !           309:     for (done = TRUE;;) {
        !           310:        if (fgets (buffer, sizeof buffer, in) == NULL)
        !           311:            break;              /* should be error */
        !           312:        if (done && isdlm2 (buffer))
        !           313:            break;
        !           314:        done = buffer[strlen (buffer) - 1] == '\n';
        !           315:        fputs (buffer, out);
        !           316:     }
        !           317:     (void) fclose (out);
        !           318: 
        !           319:     (void) lseek (fd2, 0L, 0);
        !           320:     seeksndr (fd2, mysndr);
        !           321: 
        !           322: /*  */
        !           323: 
        !           324:     switch (child_id = fork ()) {
        !           325:        case NOTOK:
        !           326:            adios ("fork", "unable to");/* NOTREACHED */
        !           327: 
        !           328:        case OK:
        !           329:            (void) lseek (fd2, 0L, 0);
        !           330:            if (fd2 != 0)
        !           331:                (void) dup2 (fd2, 0);
        !           332:            (void) freopen ("/dev/null", "w", stdout);
        !           333:            (void) freopen ("/dev/null", "w", stderr);
        !           334:            if (fd2 != 3)
        !           335:                (void) dup2 (fd2, 3);
        !           336:            closefds (4);
        !           337: #ifdef TIOCNOTTY
        !           338:            if ((i = open ("/dev/tty", 2)) != NOTOK) {
        !           339:                (void) ioctl (i, TIOCNOTTY, NULLCP);
        !           340:                (void) close (i);
        !           341:            }
        !           342: #endif TIOCNOTTY
        !           343: #ifdef BSD42
        !           344:            (void) setpgrp (0, getpid ());
        !           345: #endif BSD42
        !           346: 
        !           347:            execlp (slocalproc, r1bindex (slocalproc, '/'),
        !           348:                    "-file", myfile, "-mailbox", mymail,
        !           349:                    "-home", myhome, "-addr", myaddr,
        !           350:                    "-user", myuser, "-sender", mysndr, NULLCP);
        !           351:            adios (slocalproc, "unable to exec");/* NOTREACHED */
        !           352: 
        !           353:        default:
        !           354:            (void) close (fd2);
        !           355:            (void) pidwait (child_id, OK);
        !           356:            return TRUE;
        !           357:     }
        !           358: }
        !           359: 
        !           360: /*  */
        !           361: 
        !           362: static void
        !           363: seeksndr(fd1, mysndr)
        !           364:        int fd1;
        !           365:        char *mysndr;
        !           366: {
        !           367:     int     fd2;
        !           368:     char   *bp,
        !           369:            *hp,
        !           370:             from[BUFSIZ],
        !           371:             sender[BUFSIZ];
        !           372:     register FILE *in;
        !           373: 
        !           374:     if ((fd2 = dup (fd1)) == NOTOK)
        !           375:        adios ("file descriptor", "unable to dup");
        !           376:     if ((in = fdopen (fd2, "r")) == NULL)
        !           377:        adios (NULLCP, "no free file pointers");
        !           378: 
        !           379:     for (from[0] = sender[0] = NULL; mfgets (in, &hp) != DONE;)
        !           380:        if ((bp = index (hp, ':')) != NULL) {
        !           381:            *bp++ = NULL;
        !           382:            if (lequal (hp, "From"))
        !           383:                seekaddr (from, bp);
        !           384:            else
        !           385:                if (lequal (hp, "Sender"))
        !           386:                    seekaddr (sender, bp);
        !           387:        }
        !           388:     (void) fclose (in);
        !           389: 
        !           390:     (void) strcpy (mysndr, sender[0] ? sender : from[0] ? from : myaddr);
        !           391: }
        !           392: 
        !           393: /*  */
        !           394: 
        !           395: static void
        !           396: seekaddr(addr, bp)
        !           397:        char *addr, *bp;
        !           398: {
        !           399:     struct adrx *adrxp;
        !           400: 
        !           401:     if ((adrxp = seekadrx (bp)) == NULL)
        !           402:        return;
        !           403:     if (adrxp -> err || !adrxp -> mbox)
        !           404:        return;
        !           405: 
        !           406:     if (adrxp -> host)
        !           407:        (void) sprintf (addr, "%s@%s", adrxp -> mbox, adrxp -> host);
        !           408:     else
        !           409:        (void) strcpy (addr, adrxp -> mbox);
        !           410: 
        !           411:     while (seekadrx (NULLCP))
        !           412:        continue;
        !           413: }
        !           414: 
        !           415: /*  */
        !           416: 
        !           417: static void
        !           418: st_init(st)
        !           419:        struct stat *st;
        !           420: {
        !           421:     int     fd;
        !           422: 
        !           423:     if ((fd = open (mystat, 0)) == NOTOK
        !           424:            || read (fd, (char *) st, sizeof *st) != (sizeof *st)) {
        !           425:        st -> st_ino = (ino_t) 0;
        !           426:        st -> st_size = (off_t) 0;
        !           427:        st -> st_mtime = (time_t) 0;
        !           428:     }
        !           429:     if (fd != NOTOK)
        !           430:        (void) close (fd);
        !           431: }
        !           432: 
        !           433: static void
        !           434: st_update(st)
        !           435:        struct stat *st;
        !           436: {
        !           437:     static int  fd = NOTOK;
        !           438: 
        !           439:     if (fd == NOTOK
        !           440:            && (fd = creat (mystat, TMPMODE)) == NOTOK)
        !           441:        adios (mystat, "unable to write");
        !           442: 
        !           443:     (void) lseek (fd, 0L, 0);
        !           444:     if (write (fd, (char *) st, sizeof *st) != (sizeof *st))
        !           445:        adios (mystat, "error writing");
        !           446: }
        !           447: 
        !           448: /*  */
        !           449: 
        !           450: #ifdef BSD42
        !           451: /* ARGSUSED */
        !           452: #endif BSD42
        !           453: 
        !           454: static SIGDECL
        !           455: sigser(sig)
        !           456:        int sig;
        !           457: {
        !           458: #ifndef        BSD42
        !           459:     (void) signal (sig, SIG_IGN);
        !           460: #endif BSD42
        !           461: 
        !           462:     done (1);
        !           463: }
        !           464: 
        !           465: /*  */
        !           466: 
        !           467: static void
        !           468: done(status)
        !           469:        int status;
        !           470: {
        !           471:     (void) lkclose (uucp, mymail), uucp = NOTOK;
        !           472:     exit (status);
        !           473: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.