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

unix.superglobalmegacorp.com

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