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: }

Defined functions

getfrom defined in line 137; used 2 times
initialize defined in line 266; used 1 times
  • in line 73
knows defined in line 178; used 2 times
main defined in line 52; never used
newstr defined in line 343; used 2 times
sendmessage defined in line 233; used 1 times
setknows defined in line 206; used 1 times
syserr defined in line 321; used 13 times

Defined variables

bool defined in line 178; used 1 times
  • in line 64

Defined struct's

dbrec defined in line 47; used 4 times

Defined macros

MAXLINE defined in line 40; used 3 times
MAXNAME defined in line 41; never used
ONEWEEK defined in line 43; used 1 times
  • in line 45
Last modified: 1983-12-09
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1294
Valid CSS Valid XHTML 1.0 Strict