Annotation of 42BSD/usr.lib/sendmail/aux/vacation.c, revision 1.1

1.1     ! root        1: # include <pwd.h>
        !             2: # include <stdio.h>
        !             3: # include <sysexits.h>
        !             4: # include <ctype.h>
        !             5: # include "useful.h"
        !             6: # include "userdbm.h"
        !             7: 
        !             8: SCCSID(@(#)vacation.c  4.1             7/25/83);
        !             9: 
        !            10: /*
        !            11: **  VACATION -- return a message to the sender when on vacation.
        !            12: **
        !            13: **     This program could be invoked as a message receiver
        !            14: **     when someone is on vacation.  It returns a message
        !            15: **     specified by the user to whoever sent the mail, taking
        !            16: **     care not to return a message too often to prevent
        !            17: **     "I am on vacation" loops.
        !            18: **
        !            19: **     For best operation, this program should run setuid to
        !            20: **     root or uucp or someone else that sendmail will believe
        !            21: **     a -f flag from.  Otherwise, the user must be careful
        !            22: **     to include a header on his .vacation.msg file.
        !            23: **
        !            24: **     Positional Parameters:
        !            25: **             the user to collect the vacation message from.
        !            26: **
        !            27: **     Flag Parameters:
        !            28: **             -I      initialize the database.
        !            29: **             -tT     set the timeout to T.  messages arriving more
        !            30: **                     often than T will be ignored to avoid loops.
        !            31: **
        !            32: **     Side Effects:
        !            33: **             A message is sent back to the sender.
        !            34: **
        !            35: **     Author:
        !            36: **             Eric Allman
        !            37: **             UCB/INGRES
        !            38: */
        !            39: 
        !            40: # define MAXLINE       256     /* max size of a line */
        !            41: # define MAXNAME       128     /* max size of one name */
        !            42: 
        !            43: # define ONEWEEK       (60L*60L*24L*7L)
        !            44: 
        !            45: time_t Timeout = ONEWEEK;      /* timeout between notices per user */
        !            46: 
        !            47: struct dbrec
        !            48: {
        !            49:        long    sentdate;
        !            50: };
        !            51: 
        !            52: main(argc, argv)
        !            53:        char **argv;
        !            54: {
        !            55:        char *from;
        !            56:        register char *p;
        !            57:        struct passwd *pw;
        !            58:        char *homedir;
        !            59:        char *myname;
        !            60:        char buf[MAXLINE];
        !            61:        extern struct passwd *getpwnam();
        !            62:        extern char *newstr();
        !            63:        extern char *getfrom();
        !            64:        extern bool knows();
        !            65:        extern time_t convtime();
        !            66: 
        !            67:        /* process arguments */
        !            68:        while (--argc > 0 && (p = *++argv) != NULL && *p == '-')
        !            69:        {
        !            70:                switch (*++p)
        !            71:                {
        !            72:                  case 'I':     /* initialize */
        !            73:                        initialize();
        !            74:                        exit(EX_OK);
        !            75: 
        !            76:                  case 't':     /* set timeout */
        !            77:                        Timeout = convtime(++p);
        !            78:                        break;
        !            79: 
        !            80:                  default:
        !            81:                        usrerr("Unknown flag -%s", p);
        !            82:                        exit(EX_USAGE);
        !            83:                }
        !            84:        }
        !            85: 
        !            86:        /* verify recipient argument */
        !            87:        if (argc != 1)
        !            88:        {
        !            89:                usrerr("Usage: vacation username (or) vacation -I");
        !            90:                exit(EX_USAGE);
        !            91:        }
        !            92: 
        !            93:        myname = p;
        !            94: 
        !            95:        /* find user's home directory */
        !            96:        pw = getpwnam(myname);
        !            97:        if (pw == NULL)
        !            98:        {
        !            99:                usrerr("Unknown user %s", myname);
        !           100:                exit(EX_NOUSER);
        !           101:        }
        !           102:        homedir = newstr(pw->pw_dir);
        !           103:        (void) strcpy(buf, homedir);
        !           104:        (void) strcat(buf, "/.vacation");
        !           105:        dbminit(buf);
        !           106: 
        !           107:        /* read message from standard input (just from line) */
        !           108:        from = getfrom();
        !           109: 
        !           110:        /* check if this person is already informed */
        !           111:        if (!knows(from))
        !           112:        {
        !           113:                /* mark this person as knowing */
        !           114:                setknows(from);
        !           115: 
        !           116:                /* send the message back */
        !           117:                (void) strcpy(buf, homedir);
        !           118:                (void) strcat(buf, "/.vacation.msg");
        !           119:                sendmessage(buf, from, myname);
        !           120:                /* never returns */
        !           121:        }
        !           122:        exit (EX_OK);
        !           123: }
        !           124: /*
        !           125: **  GETFROM -- read message from standard input and return sender
        !           126: **
        !           127: **     Parameters:
        !           128: **             none.
        !           129: **
        !           130: **     Returns:
        !           131: **             pointer to the sender address.
        !           132: **
        !           133: **     Side Effects:
        !           134: **             Reads first line from standard input.
        !           135: */
        !           136: 
        !           137: char *
        !           138: getfrom()
        !           139: {
        !           140:        static char line[MAXLINE];
        !           141:        register char *p;
        !           142: 
        !           143:        /* read the from line */
        !           144:        if (fgets(line, sizeof line, stdin) == NULL ||
        !           145:            strncmp(line, "From ", 5) != NULL)
        !           146:        {
        !           147:                usrerr("No initial From line");
        !           148:                exit(EX_USAGE);
        !           149:        }
        !           150: 
        !           151:        /* find the end of the sender address and terminate it */
        !           152:        p = index(&line[5], ' ');
        !           153:        if (p == NULL)
        !           154:        {
        !           155:                usrerr("Funny From line '%s'", line);
        !           156:                exit(EX_USAGE);
        !           157:        }
        !           158:        *p = '\0';
        !           159: 
        !           160:        /* return the sender address */
        !           161:        return (&line[5]);
        !           162: }
        !           163: /*
        !           164: **  KNOWS -- predicate telling if user has already been informed.
        !           165: **
        !           166: **     Parameters:
        !           167: **             user -- the user who sent this message.
        !           168: **
        !           169: **     Returns:
        !           170: **             TRUE if 'user' has already been informed that the
        !           171: **                     recipient is on vacation.
        !           172: **             FALSE otherwise.
        !           173: **
        !           174: **     Side Effects:
        !           175: **             none.
        !           176: */
        !           177: 
        !           178: bool
        !           179: knows(user)
        !           180:        char *user;
        !           181: {
        !           182:        DATUM k, d;
        !           183:        long now;
        !           184: 
        !           185:        time(&now);
        !           186:        k.dptr = user;
        !           187:        k.dsize = strlen(user) + 1;
        !           188:        d = fetch(k);
        !           189:        if (d.dptr == NULL || ((struct dbrec *) d.dptr)->sentdate + Timeout < now)
        !           190:                return (FALSE);
        !           191:        return (TRUE);
        !           192: }
        !           193: /*
        !           194: **  SETKNOWS -- set that this user knows about the vacation.
        !           195: **
        !           196: **     Parameters:
        !           197: **             user -- the user who should be marked.
        !           198: **
        !           199: **     Returns:
        !           200: **             none.
        !           201: **
        !           202: **     Side Effects:
        !           203: **             The dbm file is updated as appropriate.
        !           204: */
        !           205: 
        !           206: setknows(user)
        !           207:        char *user;
        !           208: {
        !           209:        DATUM k, d;
        !           210:        struct dbrec xrec;
        !           211: 
        !           212:        k.dptr = user;
        !           213:        k.dsize = strlen(user) + 1;
        !           214:        time(&xrec.sentdate);
        !           215:        d.dptr = (char *) &xrec;
        !           216:        d.dsize = sizeof xrec;
        !           217:        store(k, d);
        !           218: }
        !           219: /*
        !           220: **  SENDMESSAGE -- send a message to a particular user.
        !           221: **
        !           222: **     Parameters:
        !           223: **             msgf -- filename containing the message.
        !           224: **             user -- user who should receive it.
        !           225: **
        !           226: **     Returns:
        !           227: **             none.
        !           228: **
        !           229: **     Side Effects:
        !           230: **             sends mail to 'user' using /usr/lib/sendmail.
        !           231: */
        !           232: 
        !           233: sendmessage(msgf, user, myname)
        !           234:        char *msgf;
        !           235:        char *user;
        !           236:        char *myname;
        !           237: {
        !           238:        FILE *f;
        !           239: 
        !           240:        /* find the message to send */
        !           241:        f = freopen(msgf, "r", stdin);
        !           242:        if (f == NULL)
        !           243:        {
        !           244:                f = freopen("/usr/lib/vacation.def", "r", stdin);
        !           245:                if (f == NULL)
        !           246:                        syserr("No message to send");
        !           247:        }
        !           248: 
        !           249:        execl("/usr/lib/sendmail", "sendmail", "-f", myname, user, NULL);
        !           250:        syserr("Cannot exec /usr/lib/sendmail");
        !           251: }
        !           252: /*
        !           253: **  INITIALIZE -- initialize the database before leaving for vacation
        !           254: **
        !           255: **     Parameters:
        !           256: **             none.
        !           257: **
        !           258: **     Returns:
        !           259: **             none.
        !           260: **
        !           261: **     Side Effects:
        !           262: **             Initializes the files .vacation.{pag,dir} in the
        !           263: **             caller's home directory.
        !           264: */
        !           265: 
        !           266: initialize()
        !           267: {
        !           268:        char *homedir;
        !           269:        char buf[MAXLINE];
        !           270: 
        !           271:        setgid(getgid());
        !           272:        setuid(getuid());
        !           273:        homedir = getenv("HOME");
        !           274:        if (homedir == NULL)
        !           275:                syserr("No home!");
        !           276:        (void) strcpy(buf, homedir);
        !           277:        (void) strcat(buf, "/.vacation.dir");
        !           278:        if (close(creat(buf, 0644)) < 0)
        !           279:                syserr("Cannot create %s", buf);
        !           280:        (void) strcpy(buf, homedir);
        !           281:        (void) strcat(buf, "/.vacation.pag");
        !           282:        if (close(creat(buf, 0644)) < 0)
        !           283:                syserr("Cannot create %s", buf);
        !           284: }
        !           285: /*
        !           286: **  USRERR -- print user error
        !           287: **
        !           288: **     Parameters:
        !           289: **             f -- format.
        !           290: **             p -- first parameter.
        !           291: **
        !           292: **     Returns:
        !           293: **             none.
        !           294: **
        !           295: **     Side Effects:
        !           296: **             none.
        !           297: */
        !           298: 
        !           299: usrerr(f, p)
        !           300:        char *f;
        !           301:        char *p;
        !           302: {
        !           303:        fprintf(stderr, "vacation: ");
        !           304:        _doprnt(f, &p, stderr);
        !           305:        fprintf(stderr, "\n");
        !           306: }
        !           307: /*
        !           308: **  SYSERR -- print system error
        !           309: **
        !           310: **     Parameters:
        !           311: **             f -- format.
        !           312: **             p -- first parameter.
        !           313: **
        !           314: **     Returns:
        !           315: **             none.
        !           316: **
        !           317: **     Side Effects:
        !           318: **             none.
        !           319: */
        !           320: 
        !           321: syserr(f, p)
        !           322:        char *f;
        !           323:        char *p;
        !           324: {
        !           325:        fprintf(stderr, "vacation: ");
        !           326:        _doprnt(f, &p, stderr);
        !           327:        fprintf(stderr, "\n");
        !           328:        exit(EX_USAGE);
        !           329: }
        !           330: /*
        !           331: **  NEWSTR -- copy a string
        !           332: **
        !           333: **     Parameters:
        !           334: **             s -- the string to copy.
        !           335: **
        !           336: **     Returns:
        !           337: **             A copy of the string.
        !           338: **
        !           339: **     Side Effects:
        !           340: **             none.
        !           341: */
        !           342: 
        !           343: char *
        !           344: newstr(s)
        !           345:        char *s;
        !           346: {
        !           347:        char *p;
        !           348: 
        !           349:        p = malloc(strlen(s) + 1);
        !           350:        if (p == NULL)
        !           351:        {
        !           352:                syserr("newstr: cannot alloc memory");
        !           353:                exit(EX_OSERR);
        !           354:        }
        !           355:        strcpy(p, s);
        !           356:        return (p);
        !           357: }

unix.superglobalmegacorp.com

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