# 2.11BSD#431 - /usr/src/ucb/vacation.c

##### Functions

    getfrom           X
    initialize        X
    junkmail          X
    knows             X
    main              X
    newstr            X
    sameword          X
    sendmessage       X
    setknows          X
    syserr            X
    usrerr            X

##### Variables

    Debug             X
    Timeout           X

##### Macros

    FALSE             X
    MAXLINE           X
    MAXNAME           X
    ONEWEEK           X
    TRUE              X

##### struct's

    dbrec             X

##### typedef's

    bool              X

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

#### Defined functions

getfrom defined in line 166; used 2 times

- in line 86, 132

initialize defined in line 370; used 1 times

- in line 97

junkmail defined in line 210; used 2 times

- in line 88, 135

knows defined in line 276; used 2 times

- in line 87, 135

main defined in line 75; never used
newstr defined in line 448; used 2 times

- in line 85, 126

sameword defined in line 480; used 6 times

- in line 218, 225-227(3), 256(2)

sendmessage defined in line 337; used 1 times

- in line 147

setknows defined in line 310; used 1 times

- in line 138

syserr defined in line 426; used 6 times

- in line 350-354(2), 380-388(3), 458

usrerr defined in line 404; used 5 times

- in line 105, 113, 123, 177, 185

#### Defined variables

Debug defined in line 73; used 2 times

- in line 101, 143

SccsId defined in line 12; never used
Timeout defined in line 56; used 1 times

- in line 293

#### Defined struct's

dbrec defined in line 58; used 4 times

- in line 292(2), 314(2)

#### Defined typedef's

bool defined in line 46; used 7 times

- in line 73, 210, 276, 480-88(3), 218

#### Defined macros

FALSE defined in line 49; used 4 times

- in line 73, 259, 289-294(2)

MAXLINE defined in line 51; used 5 times

- in line 83, 169, 215, 236, 373

MAXNAME defined in line 52; never used
ONEWEEK defined in line 54; used 1 times

- in line 56

TRUE defined in line 48; used 4 times

- in line 101, 230, 257, 295

Last modified: 1996-10-24 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1283 |