Annotation of 43BSD/ucb/vacation.c, revision 1.1

1.1     ! root        1: /*
        !             2: **  Vacation
        !             3: **  Copyright (c) 1983  Eric P. Allman
        !             4: **  Berkeley, California
        !             5: **
        !             6: **  Copyright (c) 1983 Regents of the University of California.
        !             7: **  All rights reserved.  The Berkeley software License Agreement
        !             8: **  specifies the terms and conditions for redistribution.
        !             9: */
        !            10: 
        !            11: #ifndef lint
        !            12: static char    SccsId[] = "@(#)vacation.c      5.3 (Berkeley) 7/1/85";
        !            13: #endif not lint
        !            14: 
        !            15: # include <sys/types.h>
        !            16: # include <pwd.h>
        !            17: # include <stdio.h>
        !            18: # include <sysexits.h>
        !            19: # include <ctype.h>
        !            20: 
        !            21: /*
        !            22: **  VACATION -- return a message to the sender when on vacation.
        !            23: **
        !            24: **     This program could be invoked as a message receiver
        !            25: **     when someone is on vacation.  It returns a message
        !            26: **     specified by the user to whoever sent the mail, taking
        !            27: **     care not to return a message too often to prevent
        !            28: **     "I am on vacation" loops.
        !            29: **
        !            30: **     Positional Parameters:
        !            31: **             the user to collect the vacation message from.
        !            32: **
        !            33: **     Flag Parameters:
        !            34: **             -I      initialize the database.
        !            35: **             -d      turn on debugging.
        !            36: **
        !            37: **     Side Effects:
        !            38: **             A message is sent back to the sender.
        !            39: **
        !            40: **     Author:
        !            41: **             Eric Allman
        !            42: **             UCB/INGRES
        !            43: */
        !            44: 
        !            45: typedef int    bool;
        !            46: 
        !            47: # define TRUE          1
        !            48: # define FALSE         0
        !            49: 
        !            50: # define MAXLINE       256     /* max size of a line */
        !            51: # define MAXNAME       128     /* max size of one name */
        !            52: 
        !            53: # define ONEWEEK       (60L*60L*24L*7L)
        !            54: 
        !            55: time_t Timeout = ONEWEEK;      /* timeout between notices per user */
        !            56: 
        !            57: struct dbrec
        !            58: {
        !            59:        long    sentdate;
        !            60: };
        !            61: 
        !            62: typedef struct
        !            63: {
        !            64:        char    *dptr;
        !            65:        int     dsize;
        !            66: } DATUM;
        !            67: 
        !            68: extern DATUM fetch();
        !            69: 
        !            70: 
        !            71: 
        !            72: bool   Debug = FALSE;
        !            73: 
        !            74: main(argc, argv)
        !            75:        char **argv;
        !            76: {
        !            77:        char *from;
        !            78:        register char *p;
        !            79:        struct passwd *pw;
        !            80:        char *homedir;
        !            81:        char *myname;
        !            82:        char buf[MAXLINE];
        !            83:        extern struct passwd *getpwnam();
        !            84:        extern char *newstr();
        !            85:        extern char *getfrom();
        !            86:        extern bool knows();
        !            87:        extern bool junkmail();
        !            88:        extern time_t convtime();
        !            89: 
        !            90:        /* process arguments */
        !            91:        while (--argc > 0 && (p = *++argv) != NULL && *p == '-')
        !            92:        {
        !            93:                switch (*++p)
        !            94:                {
        !            95:                  case 'I':     /* initialize */
        !            96:                        initialize();
        !            97:                        exit(EX_OK);
        !            98: 
        !            99:                  case 'd':     /* debug */
        !           100:                        Debug = TRUE;
        !           101:                        break;
        !           102: 
        !           103:                  default:
        !           104:                        usrerr("Unknown flag -%s", p);
        !           105:                        exit(EX_USAGE);
        !           106:                }
        !           107:        }
        !           108: 
        !           109:        /* verify recipient argument */
        !           110:        if (argc != 1)
        !           111:        {
        !           112:                usrerr("Usage: vacation username (or) vacation -I");
        !           113:                exit(EX_USAGE);
        !           114:        }
        !           115: 
        !           116:        myname = p;
        !           117: 
        !           118:        /* find user's home directory */
        !           119:        pw = getpwnam(myname);
        !           120:        if (pw == NULL)
        !           121:        {
        !           122:                usrerr("Unknown user %s", myname);
        !           123:                exit(EX_NOUSER);
        !           124:        }
        !           125:        homedir = newstr(pw->pw_dir);
        !           126:        (void) strcpy(buf, homedir);
        !           127:        (void) strcat(buf, "/.vacation");
        !           128:        dbminit(buf);
        !           129: 
        !           130:        /* read message from standard input (just from line) */
        !           131:        from = getfrom();
        !           132: 
        !           133:        /* check if junk mail or this person is already informed */
        !           134:        if (!junkmail(from) && !knows(from))
        !           135:        {
        !           136:                /* mark this person as knowing */
        !           137:                setknows(from);
        !           138: 
        !           139:                /* send the message back */
        !           140:                (void) strcpy(buf, homedir);
        !           141:                (void) strcat(buf, "/.vacation.msg");
        !           142:                if (Debug)
        !           143:                        printf("Sending %s to %s\n", buf, from);
        !           144:                else
        !           145:                {
        !           146:                        sendmessage(buf, from, myname);
        !           147:                        /*NOTREACHED*/
        !           148:                }
        !           149:        }
        !           150:        exit (EX_OK);
        !           151: }
        !           152: /*
        !           153: **  GETFROM -- read message from standard input and return sender
        !           154: **
        !           155: **     Parameters:
        !           156: **             none.
        !           157: **
        !           158: **     Returns:
        !           159: **             pointer to the sender address.
        !           160: **
        !           161: **     Side Effects:
        !           162: **             Reads first line from standard input.
        !           163: */
        !           164: 
        !           165: char *
        !           166: getfrom()
        !           167: {
        !           168:        static char line[MAXLINE];
        !           169:        register char *p;
        !           170:        extern char *index();
        !           171: 
        !           172:        /* read the from line */
        !           173:        if (fgets(line, sizeof line, stdin) == NULL ||
        !           174:            strncmp(line, "From ", 5) != NULL)
        !           175:        {
        !           176:                usrerr("No initial From line");
        !           177:                exit(EX_USAGE);
        !           178:        }
        !           179: 
        !           180:        /* find the end of the sender address and terminate it */
        !           181:        p = index(&line[5], ' ');
        !           182:        if (p == NULL)
        !           183:        {
        !           184:                usrerr("Funny From line '%s'", line);
        !           185:                exit(EX_USAGE);
        !           186:        }
        !           187:        *p = '\0';
        !           188: 
        !           189:        /* return the sender address */
        !           190:        return (&line[5]);
        !           191: }
        !           192: /*
        !           193: **  JUNKMAIL -- read the header and tell us if this is junk/bulk mail.
        !           194: **
        !           195: **     Parameters:
        !           196: **             from -- the Return-Path of the sender.  We assume that
        !           197: **                     anything from "*-REQUEST@*" is bulk mail.
        !           198: **
        !           199: **     Returns:
        !           200: **             TRUE -- if this is junk or bulk mail (that is, if the
        !           201: **                     sender shouldn't receive a response).
        !           202: **             FALSE -- if the sender deserves a response.
        !           203: **
        !           204: **     Side Effects:
        !           205: **             May read the header from standard input.  When this
        !           206: **             returns the position on stdin is undefined.
        !           207: */
        !           208: 
        !           209: bool
        !           210: junkmail(from)
        !           211:        char *from;
        !           212: {
        !           213:        register char *p;
        !           214:        char buf[MAXLINE+1];
        !           215:        extern char *index();
        !           216:        extern char *rindex();
        !           217:        extern bool sameword();
        !           218: 
        !           219:        /* test for inhuman sender */
        !           220:        p = rindex(from, '@');
        !           221:        if (p != NULL)
        !           222:        {
        !           223:                *p = '\0';
        !           224:                if (sameword(&p[-8],  "-REQUEST") ||
        !           225:                    sameword(&p[-10], "Postmaster") ||
        !           226:                    sameword(&p[-13], "MAILER-DAEMON"))
        !           227:                {
        !           228:                        *p = '@';
        !           229:                        return (TRUE);
        !           230:                }
        !           231:                *p = '@';
        !           232:        }
        !           233: 
        !           234:        /* read the header looking for a "Precedence:" line */
        !           235:        while (fgets(buf, MAXLINE, stdin) != NULL && buf[0] != '\n')
        !           236:        {
        !           237:                /* should ignore case, but this is reasonably safe */
        !           238:                if (strncmp(buf, "Precedence", 10) != 0 ||
        !           239:                    !(buf[10] == ':' || buf[10] == ' ' || buf[10] == '\t'))
        !           240:                {
        !           241:                        continue;
        !           242:                }
        !           243: 
        !           244:                /* find the value of this field */
        !           245:                p = index(buf, ':');
        !           246:                if (p == NULL)
        !           247:                        continue;
        !           248:                while (*++p != '\0' && isspace(*p))
        !           249:                        continue;
        !           250:                if (*p == '\0')
        !           251:                        continue;
        !           252: 
        !           253:                /* see if it is "junk" or "bulk" */
        !           254:                p[4] = '\0';
        !           255:                if (sameword(p, "junk") || sameword(p, "bulk"))
        !           256:                        return (TRUE);
        !           257:        }
        !           258:        return (FALSE);
        !           259: }
        !           260: /*
        !           261: **  KNOWS -- predicate telling if user has already been informed.
        !           262: **
        !           263: **     Parameters:
        !           264: **             user -- the user who sent this message.
        !           265: **
        !           266: **     Returns:
        !           267: **             TRUE if 'user' has already been informed that the
        !           268: **                     recipient is on vacation.
        !           269: **             FALSE otherwise.
        !           270: **
        !           271: **     Side Effects:
        !           272: **             none.
        !           273: */
        !           274: 
        !           275: bool
        !           276: knows(user)
        !           277:        char *user;
        !           278: {
        !           279:        DATUM k, d;
        !           280:        long now;
        !           281:        auto long then;
        !           282: 
        !           283:        time(&now);
        !           284:        k.dptr = user;
        !           285:        k.dsize = strlen(user) + 1;
        !           286:        d = fetch(k);
        !           287:        if (d.dptr == NULL)
        !           288:                return (FALSE);
        !           289:        
        !           290:        /* be careful on 68k's and others with alignment restrictions */
        !           291:        bcopy((char *) &((struct dbrec *) d.dptr)->sentdate, (char *) &then, sizeof then);
        !           292:        if (then + Timeout < now)
        !           293:                return (FALSE);
        !           294:        return (TRUE);
        !           295: }
        !           296: /*
        !           297: **  SETKNOWS -- set that this user knows about the vacation.
        !           298: **
        !           299: **     Parameters:
        !           300: **             user -- the user who should be marked.
        !           301: **
        !           302: **     Returns:
        !           303: **             none.
        !           304: **
        !           305: **     Side Effects:
        !           306: **             The dbm file is updated as appropriate.
        !           307: */
        !           308: 
        !           309: setknows(user)
        !           310:        char *user;
        !           311: {
        !           312:        DATUM k, d;
        !           313:        struct dbrec xrec;
        !           314: 
        !           315:        k.dptr = user;
        !           316:        k.dsize = strlen(user) + 1;
        !           317:        time(&xrec.sentdate);
        !           318:        d.dptr = (char *) &xrec;
        !           319:        d.dsize = sizeof xrec;
        !           320:        store(k, d);
        !           321: }
        !           322: /*
        !           323: **  SENDMESSAGE -- send a message to a particular user.
        !           324: **
        !           325: **     Parameters:
        !           326: **             msgf -- filename containing the message.
        !           327: **             user -- user who should receive it.
        !           328: **
        !           329: **     Returns:
        !           330: **             none.
        !           331: **
        !           332: **     Side Effects:
        !           333: **             sends mail to 'user' using /usr/lib/sendmail.
        !           334: */
        !           335: 
        !           336: sendmessage(msgf, user, myname)
        !           337:        char *msgf;
        !           338:        char *user;
        !           339:        char *myname;
        !           340: {
        !           341:        FILE *f;
        !           342: 
        !           343:        /* find the message to send */
        !           344:        f = freopen(msgf, "r", stdin);
        !           345:        if (f == NULL)
        !           346:        {
        !           347:                f = freopen("/usr/lib/vacation.def", "r", stdin);
        !           348:                if (f == NULL)
        !           349:                        syserr("No message to send");
        !           350:        }
        !           351: 
        !           352:        execl("/usr/lib/sendmail", "sendmail", "-f", myname, user, NULL);
        !           353:        syserr("Cannot exec /usr/lib/sendmail");
        !           354: }
        !           355: /*
        !           356: **  INITIALIZE -- initialize the database before leaving for vacation
        !           357: **
        !           358: **     Parameters:
        !           359: **             none.
        !           360: **
        !           361: **     Returns:
        !           362: **             none.
        !           363: **
        !           364: **     Side Effects:
        !           365: **             Initializes the files .vacation.{pag,dir} in the
        !           366: **             caller's home directory.
        !           367: */
        !           368: 
        !           369: initialize()
        !           370: {
        !           371:        char *homedir;
        !           372:        char buf[MAXLINE];
        !           373:        extern char *getenv();
        !           374: 
        !           375:        setgid(getgid());
        !           376:        setuid(getuid());
        !           377:        homedir = getenv("HOME");
        !           378:        if (homedir == NULL)
        !           379:                syserr("No home!");
        !           380:        (void) strcpy(buf, homedir);
        !           381:        (void) strcat(buf, "/.vacation.dir");
        !           382:        if (close(creat(buf, 0644)) < 0)
        !           383:                syserr("Cannot create %s", buf);
        !           384:        (void) strcpy(buf, homedir);
        !           385:        (void) strcat(buf, "/.vacation.pag");
        !           386:        if (close(creat(buf, 0644)) < 0)
        !           387:                syserr("Cannot create %s", buf);
        !           388: }
        !           389: /*
        !           390: **  USRERR -- print user error
        !           391: **
        !           392: **     Parameters:
        !           393: **             f -- format.
        !           394: **             p -- first parameter.
        !           395: **
        !           396: **     Returns:
        !           397: **             none.
        !           398: **
        !           399: **     Side Effects:
        !           400: **             none.
        !           401: */
        !           402: 
        !           403: usrerr(f, p)
        !           404:        char *f;
        !           405:        char *p;
        !           406: {
        !           407:        fprintf(stderr, "vacation: ");
        !           408:        _doprnt(f, &p, stderr);
        !           409:        fprintf(stderr, "\n");
        !           410: }
        !           411: /*
        !           412: **  SYSERR -- print system error
        !           413: **
        !           414: **     Parameters:
        !           415: **             f -- format.
        !           416: **             p -- first parameter.
        !           417: **
        !           418: **     Returns:
        !           419: **             none.
        !           420: **
        !           421: **     Side Effects:
        !           422: **             none.
        !           423: */
        !           424: 
        !           425: syserr(f, p)
        !           426:        char *f;
        !           427:        char *p;
        !           428: {
        !           429:        fprintf(stderr, "vacation: ");
        !           430:        _doprnt(f, &p, stderr);
        !           431:        fprintf(stderr, "\n");
        !           432:        exit(EX_USAGE);
        !           433: }
        !           434: /*
        !           435: **  NEWSTR -- copy a string
        !           436: **
        !           437: **     Parameters:
        !           438: **             s -- the string to copy.
        !           439: **
        !           440: **     Returns:
        !           441: **             A copy of the string.
        !           442: **
        !           443: **     Side Effects:
        !           444: **             none.
        !           445: */
        !           446: 
        !           447: char *
        !           448: newstr(s)
        !           449:        char *s;
        !           450: {
        !           451:        char *p;
        !           452:        extern char *malloc();
        !           453: 
        !           454:        p = malloc(strlen(s) + 1);
        !           455:        if (p == NULL)
        !           456:        {
        !           457:                syserr("newstr: cannot alloc memory");
        !           458:                exit(EX_OSERR);
        !           459:        }
        !           460:        strcpy(p, s);
        !           461:        return (p);
        !           462: }
        !           463: /*
        !           464: **  SAMEWORD -- return TRUE if the words are the same
        !           465: **
        !           466: **     Ignores case.
        !           467: **
        !           468: **     Parameters:
        !           469: **             a, b -- the words to compare.
        !           470: **
        !           471: **     Returns:
        !           472: **             TRUE if a & b match exactly (modulo case)
        !           473: **             FALSE otherwise.
        !           474: **
        !           475: **     Side Effects:
        !           476: **             none.
        !           477: */
        !           478: 
        !           479: bool
        !           480: sameword(a, b)
        !           481:        register char *a, *b;
        !           482: {
        !           483:        char ca, cb;
        !           484: 
        !           485:        do
        !           486:        {
        !           487:                ca = *a++;
        !           488:                cb = *b++;
        !           489:                if (isascii(ca) && isupper(ca))
        !           490:                        ca = ca - 'A' + 'a';
        !           491:                if (isascii(cb) && isupper(cb))
        !           492:                        cb = cb - 'A' + 'a';
        !           493:        } while (ca != '\0' && ca == cb);
        !           494:        return (ca == cb);
        !           495: }

unix.superglobalmegacorp.com

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