|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.