Annotation of 42BSD/usr.lib/sendmail/aux/vacation.c, revision 1.1.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.