|
|
1.1 ! root 1: /* slocal.c - MH style mailer to write to a local user's mailbox */ ! 2: ! 3: /* This program implements mail delivery in the MH/MMDF style. ! 4: ! 5: Under SendMail, users should add the line ! 6: ! 7: "| /usr/local/lib/mh/slocal" ! 8: ! 9: to their $HOME/.forward file. ! 10: ! 11: Under MMDF-I, users should (symbolically) link /usr/local/lib/mh/slocal ! 12: to $HOME/bin/rcvmail. ! 13: ! 14: Under stand-alone MH, post will automatically run this during local ! 15: delivery. ! 16: ! 17: This program should be used ONLY if you have "mts sendmail" or "mts mh" ! 18: or "mts mmdf1" set in your MH configuration. ! 19: */ ! 20: ! 21: /* */ ! 22: ! 23: #include "../h/mh.h" ! 24: #include "../h/dropsbr.h" ! 25: #include "../h/rcvmail.h" ! 26: #include "../zotnet/tws.h" ! 27: #include "../zotnet/mts.h" ! 28: #include <pwd.h> ! 29: #include <signal.h> ! 30: #ifndef V7 ! 31: #include <sys/ioctl.h> ! 32: #endif not V7 ! 33: #include <sys/stat.h> ! 34: #include <utmp.h> ! 35: ! 36: ! 37: #define NVEC 100 ! 38: ! 39: /* */ ! 40: ! 41: static struct swit switches[] = { ! 42: #define ADDRSW 0 ! 43: "addr address", 0, ! 44: #define USERSW 1 ! 45: "user name", 0, ! 46: #define FILESW 2 ! 47: "file file", 0, ! 48: #define SENDSW 3 ! 49: "sender address", 0, ! 50: #define MBOXSW 4 ! 51: "mailbox file", 0, ! 52: #define HOMESW 5 ! 53: "home directory", 0, ! 54: ! 55: #define MAILSW 6 ! 56: "maildelivery file", 0, ! 57: ! 58: #define VERBSW 7 ! 59: "verbose", 0, ! 60: #define NVERBSW 8 ! 61: "noverbose", 0, ! 62: ! 63: #define DEBUGSW 9 ! 64: "debug", 0, ! 65: ! 66: #define HELPSW 10 ! 67: "help", 4, ! 68: ! 69: NULL, NULL ! 70: }; ! 71: ! 72: /* */ ! 73: ! 74: static int debug = 0; ! 75: static int globbed = 0; ! 76: static int parsed = 0; ! 77: static int utmped = 0; ! 78: static int verbose = 0; ! 79: ! 80: static char *addr = NULLCP; ! 81: static char *user = NULLCP; ! 82: static char *info = NULLCP; ! 83: static char *file = NULLCP; ! 84: static char *sender = NULLCP; ! 85: static char *mbox = NULLCP; ! 86: static char *home = NULLCP; ! 87: ! 88: ! 89: static struct passwd *pw; ! 90: ! 91: ! 92: static char ddate[BUFSIZ]; ! 93: ! 94: struct tws *now; ! 95: ! 96: ! 97: static jmp_buf myctx; ! 98: ! 99: /* */ ! 100: ! 101: static struct pair { ! 102: char *p_name; ! 103: char *p_value; ! 104: char p_flags; ! 105: #define P_NIL 0x00 ! 106: #define P_ADR 0x01 ! 107: #define P_HID 0x02 ! 108: #define P_CHK 0x04 ! 109: } hdrs[NVEC + 1] = { ! 110: "source", NULL, P_HID, ! 111: "addr", NULL, P_HID, ! 112: ! 113: "Return-Path", NULL, P_ADR, ! 114: "Reply-To", NULL, P_ADR, ! 115: "From", NULL, P_ADR, ! 116: "Sender", NULL, P_ADR, ! 117: "To", NULL, P_ADR, ! 118: "cc", NULL, P_ADR, ! 119: "Resent-Reply-To", NULL, P_ADR, ! 120: "Resent-From", NULL, P_ADR, ! 121: "Resent-Sender", NULL, P_ADR, ! 122: "Resent-To", NULL, P_ADR, ! 123: "Resent-cc", NULL, P_ADR, ! 124: ! 125: NULL ! 126: }; ! 127: ! 128: ! 129: static struct pair vars[] = { ! 130: "sender", NULL, P_NIL, ! 131: "address", NULL, P_NIL, ! 132: "size", NULL, P_NIL, ! 133: "reply-to", NULL, P_CHK, ! 134: "info", NULL, P_NIL, ! 135: ! 136: NULL ! 137: }; ! 138: ! 139: /* */ ! 140: ! 141: extern char **environ; ! 142: ! 143: ! 144: long lseek (); ! 145: #ifdef SYS5 ! 146: struct passwd *getpwnam (); ! 147: #endif SYS5 ! 148: ! 149: static int localmail(), usr_delivery(), split(), parse(), logged_in(), ! 150: timely(), usr_file(), usr_hook(), usr_pipe(), copyfile(); ! 151: static void expand(), glob(), copyinfo(), adorn(); ! 152: static struct pair *lookup(); ! 153: static SIGDECL alrmser(); ! 154: ! 155: /* */ ! 156: ! 157: /* ARGSUSED */ ! 158: ! 159: main(argc, argv) ! 160: int argc; ! 161: char **argv; ! 162: { ! 163: int fd; ! 164: FILE *fp = stdin; ! 165: char *cp, ! 166: *mdlvr = NULL, ! 167: buf[100], ! 168: from[BUFSIZ], ! 169: mailbox[BUFSIZ], ! 170: tmpfil[BUFSIZ], ! 171: **argp = argv + 1; ! 172: ! 173: invo_name = r1bindex (*argv, '/'); ! 174: m_foil (NULLCP); ! 175: mts_init (invo_name); ! 176: ! 177: /* */ ! 178: ! 179: while (cp = *argp++) { ! 180: if (*cp == '-') ! 181: switch (smatch (++cp, switches)) { ! 182: case AMBIGSW: ! 183: ambigsw (cp, switches); ! 184: done (1); ! 185: case UNKWNSW: ! 186: adios (NULLCP, "-%s unknown", cp); ! 187: case HELPSW: ! 188: (void) sprintf (buf, "%s [switches] [address info sender]", ! 189: invo_name); ! 190: help (buf, switches); ! 191: done (1); ! 192: ! 193: case ADDRSW: ! 194: if (!(addr = *argp++))/* allow -xyz arguments */ ! 195: adios (NULLCP, "missing argument to %s", argp[-2]); ! 196: continue; ! 197: case USERSW: ! 198: if (!(user = *argp++))/* allow -xyz arguments */ ! 199: adios (NULLCP, "missing argument to %s", argp[-2]); ! 200: continue; ! 201: case FILESW: ! 202: if (!(file = *argp++) || *file == '-') ! 203: adios (NULLCP, "missing argument to %s", argp[-2]); ! 204: continue; ! 205: case SENDSW: ! 206: if (!(sender = *argp++))/* allow -xyz arguments */ ! 207: adios (NULLCP, "missing argument to %s", argp[-2]); ! 208: continue; ! 209: case MBOXSW: ! 210: if (!(mbox = *argp++) || *mbox == '-') ! 211: adios (NULLCP, "missing argument to %s", argp[-2]); ! 212: continue; ! 213: case HOMESW: ! 214: if (!(home = *argp++) || *home == '-') ! 215: adios (NULLCP, "missing argument to %s", argp[-2]); ! 216: continue; ! 217: ! 218: case MAILSW: ! 219: if (!(cp = *argp++) || *cp == '-') ! 220: adios (NULLCP, "missing argument to %s", argp[-2]); ! 221: if (mdlvr) ! 222: adios (NULLCP, "only one maildelivery file at a time!"); ! 223: mdlvr = cp; ! 224: continue; ! 225: ! 226: case VERBSW: ! 227: verbose++; ! 228: continue; ! 229: case NVERBSW: ! 230: verbose = 0; ! 231: continue; ! 232: ! 233: case DEBUGSW: ! 234: debug++; ! 235: continue; ! 236: } ! 237: ! 238: switch (argp - (argv + 1)) { ! 239: case 1: ! 240: addr = cp; ! 241: break; ! 242: ! 243: case 2: ! 244: info = cp; ! 245: break; ! 246: ! 247: case 3: ! 248: sender = cp; ! 249: break; ! 250: } ! 251: } ! 252: ! 253: /* */ ! 254: ! 255: if (addr == NULL) ! 256: addr = getusr (); ! 257: if (user == NULL) ! 258: user = (cp = index (addr, '.')) ? ++cp : addr; ! 259: if ((pw = getpwnam (user)) == NULL) ! 260: adios (NULLCP, "no such local user as %s", user); ! 261: ! 262: if (chdir (pw -> pw_dir) == NOTOK) ! 263: (void) chdir ("/"); ! 264: (void) umask (0077); ! 265: ! 266: if (geteuid () == 0) { ! 267: #ifdef BSD41A ! 268: (void) inigrp (pw -> pw_name, pw -> pw_gid); ! 269: #endif BSD41A ! 270: (void) setgid (pw -> pw_gid); ! 271: #ifdef BSD42 ! 272: (void) initgroups (pw -> pw_name, pw -> pw_gid); ! 273: #endif BSD42 ! 274: (void) setuid (pw -> pw_uid); ! 275: } ! 276: ! 277: if (info == NULL) ! 278: info = ""; ! 279: ! 280: setbuf (stdin, NULLCP); ! 281: ! 282: if (file == NULL) { ! 283: if ((fd = copyfile (fileno (stdin), file = tmpfil, 1)) == NOTOK) ! 284: adios (NULLCP, "unable to create temporary file"); ! 285: if (debug) ! 286: fprintf (stderr, "temporary file \"%s\" selected\n", tmpfil); ! 287: else ! 288: (void) unlink (tmpfil); ! 289: if ((fp = fdopen (fd, "r+")) == NULL) ! 290: adios (NULLCP, "unable to access temporary file"); ! 291: } ! 292: else ! 293: fd = fileno (stdin); ! 294: ! 295: from[0] = NULL; ! 296: if (sender == NULL) ! 297: copyinfo (fp, from); ! 298: ! 299: ! 300: if (mbox == NULL) { ! 301: (void) sprintf (mailbox, "%s/%s", ! 302: mmdfldir[0] ? mmdfldir : pw -> pw_dir, ! 303: mmdflfil[0] ? mmdflfil : pw -> pw_name); ! 304: mbox = mailbox; ! 305: } ! 306: if (home == NULL) ! 307: home = pw -> pw_dir; ! 308: ! 309: if ((now = dtwstime ()) == NULL) ! 310: adios (NULLCP, "unable to ascertain local time"); ! 311: (void) sprintf (ddate, "Delivery-Date: %s\n", dtimenow ()); ! 312: ! 313: if (debug) { ! 314: fprintf (stderr, "addr=\"%s\" user=\"%s\" info=\"%s\" file=\"%s\"\n", ! 315: addr, user, info, file); ! 316: fprintf (stderr, "sender=\"%s\" mbox=\"%s\" home=\"%s\" from=\"%s\"\n", ! 317: sender, mbox, home, from); ! 318: fprintf (stderr, "ddate=\"%s\" now=%02d:%02d\n", ! 319: ddate, now -> tw_hour, now -> tw_min); ! 320: } ! 321: ! 322: done (localmail (fd, from, mdlvr) != NOTOK ? RCV_MOK : RCV_MBX); ! 323: } ! 324: ! 325: /* */ ! 326: ! 327: static int ! 328: localmail(fd, from, mdlvr) ! 329: int fd; ! 330: char *from, *mdlvr; ! 331: { ! 332: if (usr_delivery (fd, mdlvr ? mdlvr : ".maildelivery", 0) != NOTOK) ! 333: return OK; ! 334: ! 335: if (usr_delivery (fd, maildelivery, 1) != NOTOK) ! 336: return OK; ! 337: ! 338: #ifdef notdef ! 339: if (verbose) ! 340: printf ("(invoking hook)\n"); ! 341: if (usr_hook (fd, mbox) != NOTOK) ! 342: return OK; ! 343: #endif notdef ! 344: ! 345: if (verbose) ! 346: printf ("(trying normal delivery)\n"); ! 347: return usr_file (fd, mbox, from); ! 348: } ! 349: ! 350: /* */ ! 351: ! 352: #define matches(a,b) (stringdex (b, a) >= 0) ! 353: ! 354: static int ! 355: usr_delivery(fd, delivery, su) ! 356: int fd, su; ! 357: char *delivery; ! 358: { ! 359: int i, ! 360: accept, ! 361: status, ! 362: won, ! 363: vecp; ! 364: register char *cp, ! 365: *action, ! 366: *field, ! 367: *pattern, ! 368: *string; ! 369: char buffer[BUFSIZ], ! 370: tmpbuf[BUFSIZ], ! 371: *vec[NVEC]; ! 372: struct stat st; ! 373: register struct pair *p; ! 374: register FILE *fp; ! 375: ! 376: if ((fp = fopen (delivery, "r")) == NULL) ! 377: return NOTOK; ! 378: if (fstat (fileno (fp), &st) == NOTOK ! 379: || (st.st_uid != 0 && (su || st.st_uid != pw -> pw_uid)) ! 380: || st.st_mode & 0022) { ! 381: if (verbose) { ! 382: printf ("%s: ownership/modes bad (%d, %d,%d,0%o)\n", ! 383: delivery, su, pw -> pw_uid, st.st_uid, st.st_mode); ! 384: (void) fflush (stdout); ! 385: } ! 386: return NOTOK; ! 387: } ! 388: ! 389: won = 0; ! 390: while (fgets (buffer, sizeof buffer, fp) != NULL) { ! 391: if (*buffer == '#') ! 392: continue; ! 393: if (cp = index (buffer, '\n')) ! 394: *cp = NULL; ! 395: if ((vecp = split (buffer, vec)) < 5) ! 396: continue; ! 397: if (debug) ! 398: for (i = 0; vec[i]; i++) ! 399: fprintf (stderr, "vec[%d]: \"%s\"\n", i, vec[i]); ! 400: ! 401: field = vec[0]; ! 402: pattern = vec[1]; ! 403: action = vec[2]; ! 404: ! 405: switch (vec[3][0]) { ! 406: case '?': ! 407: if (won) ! 408: continue; /* else fall */ ! 409: case 'A': ! 410: case 'a': ! 411: accept = 1; ! 412: break; ! 413: ! 414: case 'R': ! 415: case 'r': ! 416: default: ! 417: accept = 0; ! 418: break; ! 419: } ! 420: ! 421: string = vec[4]; ! 422: ! 423: if (vecp > 5) { ! 424: if (uleq (vec[5], "select")) { ! 425: if (logged_in () != NOTOK) ! 426: continue; ! 427: if (vecp > 7 && timely (vec[6], vec[7]) == NOTOK) ! 428: continue; ! 429: } ! 430: } ! 431: ! 432: switch (*field) { ! 433: case '*': ! 434: break; ! 435: ! 436: case 'd': ! 437: if (uleq (field, "default")) { ! 438: if (won) ! 439: continue; ! 440: break; ! 441: } /* else fall */ ! 442: ! 443: default: ! 444: if (!parsed && parse (fd) == NOTOK) { ! 445: (void) fclose (fp); ! 446: return NOTOK; ! 447: } ! 448: if ((p = lookup (hdrs, field)) == NULL ! 449: || !matches (p -> p_value, pattern)) ! 450: continue; ! 451: break; ! 452: } ! 453: ! 454: switch (*action) { ! 455: case 'q': ! 456: if (!uleq (action, "qpipe")) ! 457: continue; /* else fall */ ! 458: case '^': ! 459: expand (tmpbuf, string, fd); ! 460: if (split (tmpbuf, vec) < 1) ! 461: continue; ! 462: status = usr_pipe (fd, tmpbuf, vec[0], vec); ! 463: break; ! 464: ! 465: case 'p': ! 466: if (!uleq (action, "pipe")) ! 467: continue; /* else fall */ ! 468: case '|': ! 469: vec[2] = "sh"; ! 470: vec[3] = "-c"; ! 471: expand (tmpbuf, string, fd); ! 472: vec[4] = tmpbuf; ! 473: vec[5] = NULL; ! 474: status = usr_pipe (fd, tmpbuf, "/bin/sh", vec + 2); ! 475: break; ! 476: ! 477: case 'f': ! 478: if (!uleq (action, "file")) ! 479: continue; /* else fall */ ! 480: case '>': ! 481: status = usr_file (fd, string, NULLCP); ! 482: break; ! 483: ! 484: case 'd': ! 485: if (!uleq (action, "destroy")) ! 486: continue; ! 487: status = OK; ! 488: break; ! 489: } ! 490: ! 491: if (accept) { ! 492: if (status == NOTOK) { ! 493: won = 0; ! 494: break; ! 495: } ! 496: won++; ! 497: } ! 498: } ! 499: ! 500: (void) fclose (fp); ! 501: return (won ? OK : NOTOK); ! 502: } ! 503: ! 504: /* */ ! 505: ! 506: #define QUOTE '\\' ! 507: ! 508: static int ! 509: split(cp, vec) ! 510: char *cp, **vec; ! 511: { ! 512: register int i; ! 513: register char *s; ! 514: ! 515: for (i = 0, s = cp; i <= NVEC;) { ! 516: vec[i] = NULL; ! 517: while (isspace (*s) || *s == ',') ! 518: *s++ = NULL; ! 519: if (*s == NULL) ! 520: break; ! 521: ! 522: if (*s == '"') { ! 523: for (vec[i++] = ++s; *s != NULL && *s != '"'; s++) ! 524: if (*s == QUOTE) { ! 525: if (*++s == '"') ! 526: (void) strcpy (s - 1, s); ! 527: s--; ! 528: } ! 529: if (*s == '"') ! 530: *s++ = NULL; ! 531: continue; ! 532: } ! 533: if (*s == QUOTE && *++s != '"') ! 534: s--; ! 535: vec[i++] = s++; ! 536: ! 537: while (*s != NULL && !isspace (*s) && *s != ',') ! 538: s++; ! 539: } ! 540: vec[i] = NULL; ! 541: ! 542: return i; ! 543: } ! 544: ! 545: /* */ ! 546: ! 547: static int ! 548: parse(fd) ! 549: register int fd; ! 550: { ! 551: register int i, ! 552: state; ! 553: int fd1; ! 554: register char *cp, ! 555: *dp, ! 556: *lp; ! 557: char name[NAMESZ], ! 558: field[BUFSIZ]; ! 559: register struct pair *p, ! 560: *q; ! 561: register FILE *in; ! 562: ! 563: if (parsed++) ! 564: return OK; ! 565: ! 566: if ((fd1 = dup (fd)) == NOTOK) ! 567: return NOTOK; ! 568: if ((in = fdopen (fd1, "r")) == NULL) { ! 569: (void) close (fd1); ! 570: return NOTOK; ! 571: } ! 572: rewind (in); ! 573: ! 574: if (p = lookup (hdrs, "source")) ! 575: p -> p_value = getcpy (sender); ! 576: if (p = lookup (hdrs, "addr")) ! 577: p -> p_value = getcpy (addr); ! 578: ! 579: for (i = 0, state = FLD;;) { ! 580: switch (state = m_getfld (state, name, field, sizeof field, in)) { ! 581: case FLD: ! 582: case FLDEOF: ! 583: case FLDPLUS: ! 584: lp = add (field, NULLCP); ! 585: while (state == FLDPLUS) { ! 586: state = m_getfld (state, name, field, sizeof field, in); ! 587: lp = add (field, lp); ! 588: } ! 589: for (p = hdrs; p -> p_name; p++) ! 590: if (uleq (p -> p_name, name)) { ! 591: if (!(p -> p_flags & P_HID)) { ! 592: if (cp = p -> p_value) ! 593: if (p -> p_flags & P_ADR) { ! 594: dp = cp + strlen (cp) - 1; ! 595: if (*dp == '\n') ! 596: *dp = NULL; ! 597: cp = add (",\n\t", cp); ! 598: } ! 599: else ! 600: cp = add ("\t", cp); ! 601: p -> p_value = add (lp, cp); ! 602: } ! 603: free (lp); ! 604: break; ! 605: } ! 606: if (p -> p_name == NULL && i < NVEC) { ! 607: p -> p_name = getcpy (name); ! 608: p -> p_value = lp; ! 609: p -> p_flags = P_NIL; ! 610: p++, i++; ! 611: p -> p_name = NULL; ! 612: } ! 613: if (state != FLDEOF) ! 614: continue; ! 615: break; ! 616: ! 617: case BODY: ! 618: case BODYEOF: ! 619: case FILEEOF: ! 620: break; ! 621: ! 622: case LENERR: ! 623: case FMTERR: ! 624: advise (NULLCP, "format error in message"); ! 625: break; ! 626: ! 627: default: ! 628: advise (NULLCP, "internal error"); ! 629: (void) fclose (in); ! 630: return NOTOK; ! 631: } ! 632: break; ! 633: } ! 634: (void) fclose (in); ! 635: ! 636: if (p = lookup (vars, "reply-to")) { ! 637: if ((q = lookup (hdrs, "reply-to")) == NULL || q -> p_value == NULL) ! 638: q = lookup (hdrs, "from"); ! 639: p -> p_value = getcpy (q ? q -> p_value : ""); ! 640: p -> p_flags &= ~P_CHK; ! 641: if (debug) ! 642: fprintf (stderr, "vars[%d]: name=\"%s\" value=\"%s\"\n", ! 643: p - vars, p -> p_name, p -> p_value); ! 644: } ! 645: if (debug) ! 646: for (p = hdrs; p -> p_name; p++) ! 647: fprintf (stderr, "hdrs[%d]: name=\"%s\" value=\"%s\"\n", ! 648: p - hdrs, p -> p_name, p -> p_value); ! 649: ! 650: return OK; ! 651: } ! 652: ! 653: /* */ ! 654: ! 655: #define LPAREN '(' ! 656: #define RPAREN ')' ! 657: ! 658: static void ! 659: expand(s1, s2, fd) ! 660: register char *s1, *s2; ! 661: int fd; ! 662: { ! 663: register char c, ! 664: *cp; ! 665: register struct pair *p; ! 666: ! 667: if (!globbed) ! 668: glob (fd); ! 669: ! 670: while (c = *s2++) ! 671: if (c != '$' || *s2 != LPAREN) ! 672: *s1++ = c; ! 673: else { ! 674: for (cp = ++s2; *s2 && *s2 != RPAREN; s2++) ! 675: continue; ! 676: if (*s2 != RPAREN) { ! 677: s2 = --cp; ! 678: continue; ! 679: } ! 680: *s2++ = NULL; ! 681: if (p = lookup (vars, cp)) { ! 682: if (!parsed && (p -> p_flags & P_CHK)) ! 683: (void) parse (fd); ! 684: ! 685: (void) strcpy (s1, p -> p_value); ! 686: s1 += strlen (s1); ! 687: } ! 688: } ! 689: *s1 = NULL; ! 690: } ! 691: ! 692: /* */ ! 693: ! 694: static void ! 695: glob(fd) ! 696: register int fd; ! 697: { ! 698: char buffer[BUFSIZ]; ! 699: struct stat st; ! 700: register struct pair *p; ! 701: ! 702: if (globbed++) ! 703: return; ! 704: ! 705: if (p = lookup (vars, "sender")) ! 706: p -> p_value = getcpy (sender); ! 707: if (p = lookup (vars, "address")) ! 708: p -> p_value = getcpy (addr); ! 709: if (p = lookup (vars, "size")) { ! 710: (void) sprintf (buffer, "%d", ! 711: fstat (fd, &st) != NOTOK ? (int) st.st_size : 0); ! 712: p -> p_value = getcpy (buffer); ! 713: } ! 714: if (p = lookup (vars, "info")) ! 715: p -> p_value = getcpy (info); ! 716: ! 717: if (debug) ! 718: for (p = vars; p -> p_name; p++) ! 719: fprintf (stderr, "vars[%d]: name=\"%s\" value=\"%s\"\n", ! 720: p - vars, p -> p_name, p -> p_value); ! 721: } ! 722: ! 723: /* */ ! 724: ! 725: static struct pair * ! 726: lookup(pairs, key) ! 727: register struct pair *pairs; ! 728: register char *key; ! 729: { ! 730: register char *cp; ! 731: ! 732: for (; cp = pairs -> p_name; pairs++) ! 733: if (uleq (cp, key)) ! 734: return pairs; ! 735: ! 736: return NULL; ! 737: } ! 738: ! 739: /* */ ! 740: ! 741: static int ! 742: logged_in() ! 743: { ! 744: struct utmp ut; ! 745: register FILE *uf; ! 746: ! 747: if (utmped) ! 748: return utmped; ! 749: ! 750: if ((uf = fopen ("/etc/utmp", "r")) == NULL) ! 751: return NOTOK; ! 752: ! 753: while (fread ((char *) &ut, sizeof ut, 1, uf) == 1) ! 754: if (ut.ut_name[0] != NULL ! 755: && strncmp (user, ut.ut_name, sizeof ut.ut_name) == 0) { ! 756: if (debug) ! 757: continue; ! 758: (void) fclose (uf); ! 759: return (utmped = DONE); ! 760: } ! 761: ! 762: (void) fclose (uf); ! 763: return (utmped = NOTOK); ! 764: } ! 765: ! 766: ! 767: static int ! 768: timely(t1, t2) ! 769: char *t1, *t2; ! 770: { ! 771: #define check(t,a,b) if (t < a || t > b) return NOTOK ! 772: #define cmpar(h1,m1,h2,m2) if (h1 < h2 || (h1 == h2 && m1 < m2)) return OK ! 773: ! 774: int t1hours, ! 775: t1mins, ! 776: t2hours, ! 777: t2mins; ! 778: ! 779: if (sscanf (t1, "%d:%d", &t1hours, &t1mins) != 2) ! 780: return NOTOK; ! 781: check (t1hours, 0, 23); ! 782: check (t1mins, 0, 59); ! 783: ! 784: if (sscanf (t2, "%d:%d", &t2hours, &t2mins) != 2) ! 785: return NOTOK; ! 786: check (t2hours, 0, 23); ! 787: check (t2mins, 0, 59); ! 788: ! 789: cmpar (now -> tw_hour, now -> tw_min, t1hours, t1mins); ! 790: cmpar (t2hours, t2mins, now -> tw_hour, now -> tw_min); ! 791: ! 792: return NOTOK; ! 793: } ! 794: ! 795: /* */ ! 796: ! 797: static int ! 798: usr_file(fd, mailbox, from) ! 799: int fd; ! 800: char *mailbox, *from; ! 801: { ! 802: int md, ! 803: mapping; ! 804: register char *bp; ! 805: char buffer[BUFSIZ]; ! 806: ! 807: if (verbose) ! 808: printf ("\tdelivering to file \"%s\"", mailbox); ! 809: if (from && *from) { ! 810: (void) mbx_uucp (); ! 811: if (verbose) ! 812: printf (" (uucp style)"); ! 813: (void) sprintf (buffer, "%s%s", from, ddate); ! 814: bp = buffer; ! 815: mapping = 0; ! 816: } ! 817: else { ! 818: bp = ddate; ! 819: mapping = 1; ! 820: } ! 821: if (verbose) ! 822: (void) fflush (stdout); ! 823: ! 824: if ((md = mbx_open (mailbox, pw -> pw_uid, pw -> pw_gid, m_gmprot ())) ! 825: == NOTOK) { ! 826: adorn ("", "unable to open:"); ! 827: return NOTOK; ! 828: } ! 829: ! 830: (void) lseek (fd, 0L, 0); ! 831: if (mbx_copy (mailbox, md, fd, mapping, bp, verbose) == NOTOK) { ! 832: adorn ("", "error writing to:"); ! 833: return NOTOK; ! 834: } ! 835: ! 836: (void) mbx_close (mailbox, md); ! 837: if (verbose) { ! 838: printf (", done.\n"); ! 839: (void) fflush (stdout); ! 840: } ! 841: return OK; ! 842: } ! 843: ! 844: /* */ ! 845: ! 846: #ifdef notdef ! 847: static int ! 848: usr_hook(fd, mailbox) ! 849: int fd; ! 850: char *mailbox; ! 851: { ! 852: int i, ! 853: vecp; ! 854: char receive[BUFSIZ], ! 855: tmpfil[BUFSIZ], ! 856: *vec[NVEC]; ! 857: ! 858: if ((fd = copyfile (fd, tmpfil, 0)) == NOTOK) { ! 859: if (verbose) ! 860: adorn ("unable to copy message; skipping hook\n"); ! 861: return NOTOK; ! 862: } ! 863: (void) chown (tmpfil, pw -> pw_uid, pw -> pw_gid); ! 864: ! 865: vecp = 1; ! 866: (void) sprintf (receive, "%s/.mh_receive", pw -> pw_dir); ! 867: switch (access (receive, 01)) { ! 868: case NOTOK: ! 869: (void) sprintf (receive, "%s/bin/rcvmail", pw -> pw_dir); ! 870: if (access (receive, 01) == NOTOK) { ! 871: (void) unlink (tmpfil); ! 872: if (verbose) { ! 873: printf ("\tnot present\n"); ! 874: (void) fflush (stdout); ! 875: } ! 876: return NOTOK; ! 877: } ! 878: vec[vecp++] = addr; ! 879: vec[vecp++] = tmpfil; ! 880: vec[vecp++] = sender; ! 881: break; ! 882: ! 883: default: ! 884: vec[vecp++] = tmpfil; ! 885: vec[vecp++] = mailbox; ! 886: vec[vecp++] = home; ! 887: vec[vecp++] = addr; ! 888: vec[vecp++] = sender; ! 889: break; ! 890: } ! 891: vec[0] = r1bindex (receive, '/'); ! 892: vec[vecp] = NULL; ! 893: ! 894: i = usr_pipe (fd, "rcvmail", receive, vec); ! 895: (void) unlink (tmpfil); ! 896: ! 897: return i; ! 898: } ! 899: #endif notdef ! 900: ! 901: /* */ ! 902: ! 903: static int ! 904: usr_pipe(fd, cmd, pgm, vec) ! 905: int fd; ! 906: char *cmd, *pgm, **vec; ! 907: { ! 908: int bytes, ! 909: i, ! 910: child_id, ! 911: status; ! 912: struct stat st; ! 913: ! 914: if (verbose) { ! 915: printf ("\tdelivering to pipe \"%s\"", cmd); ! 916: (void) fflush (stdout); ! 917: } ! 918: (void) lseek (fd, 0L, 0); ! 919: ! 920: for (i = 0; (child_id = fork ()) == NOTOK && i < 5; i++) ! 921: sleep (5); ! 922: switch (child_id) { ! 923: case NOTOK: ! 924: adorn ("fork", "unable to"); ! 925: return NOTOK; ! 926: ! 927: case OK: ! 928: if (fd != 0) ! 929: (void) dup2 (fd, 0); ! 930: (void) freopen ("/dev/null", "w", stdout); ! 931: (void) freopen ("/dev/null", "w", stderr); ! 932: if (fd != 3) ! 933: (void) dup2 (fd, 3); ! 934: closefds (4); ! 935: #ifdef TIOCNOTTY ! 936: if ((fd = open ("/dev/tty", 2)) != NOTOK) { ! 937: (void) ioctl (fd, TIOCNOTTY, NULLCP); ! 938: (void) close (fd); ! 939: } ! 940: #endif TIOCNOTTY ! 941: #ifdef BSD42 ! 942: (void) setpgrp (0, getpid ()); ! 943: #endif BSD42 ! 944: ! 945: *environ = NULL; ! 946: (void) putenv ("USER", pw -> pw_name); ! 947: (void) putenv ("HOME", pw -> pw_dir); ! 948: (void) putenv ("SHELL", pw -> pw_shell); ! 949: ! 950: execvp (pgm, vec); ! 951: _exit (-1); ! 952: ! 953: default: ! 954: switch (setjmp (myctx)) { ! 955: case OK: ! 956: (void) signal (SIGALRM, alrmser); ! 957: bytes = fstat (fd, &st) != NOTOK ? (int) st.st_size : 100; ! 958: if (bytes <= 0) ! 959: bytes = 100; ! 960: (void) alarm ((unsigned) (bytes * 60 + 300)); ! 961: ! 962: status = pidwait (child_id, OK); ! 963: ! 964: (void) alarm (0); ! 965: #ifdef MMDFI ! 966: if (status == RP_MOK || status == RP_OK) ! 967: status = 0; ! 968: #endif MMDFI ! 969: if (verbose) { ! 970: if (status == 0) ! 971: printf (", wins.\n"); ! 972: else ! 973: if ((status & 0xff00) == 0xff00) ! 974: printf (", system error\n"); ! 975: else ! 976: (void) pidstatus (status, stdout, ", loses"); ! 977: (void) fflush (stdout); ! 978: } ! 979: return (status == 0 ? OK : NOTOK); ! 980: ! 981: default: ! 982: #ifndef BSD42 ! 983: (void) kill (child_id, SIGKILL); ! 984: #else BSD42 ! 985: (void) killpg (child_id, SIGKILL); ! 986: #endif BSD42 ! 987: if (verbose) { ! 988: printf (", timed-out; terminated\n"); ! 989: (void) fflush (stdout); ! 990: } ! 991: return NOTOK; ! 992: } ! 993: } ! 994: } ! 995: ! 996: /* */ ! 997: ! 998: /* ARGSUSED */ ! 999: ! 1000: static SIGDECL ! 1001: alrmser(i) ! 1002: int i; ! 1003: { ! 1004: longjmp (myctx, DONE); ! 1005: } ! 1006: ! 1007: /* */ ! 1008: ! 1009: static void ! 1010: copyinfo(fp, from) ! 1011: register FILE *fp; ! 1012: char *from; ! 1013: { ! 1014: int i; ! 1015: register char *cp; ! 1016: static char buffer[BUFSIZ]; ! 1017: ! 1018: if (fgets (from, BUFSIZ, fp) == NULL) ! 1019: adios (NULLCP, "no message"); ! 1020: ! 1021: if (strncmp (from, "From ", i = strlen ("From "))) { ! 1022: rewind (fp); ! 1023: *from = NULL; ! 1024: return; ! 1025: } ! 1026: ! 1027: (void) strcpy (buffer, from + i); ! 1028: if (cp = index (buffer, '\n')) { ! 1029: *cp = NULL; ! 1030: cp -= 24; ! 1031: if (cp < buffer) ! 1032: cp = buffer; ! 1033: } ! 1034: else ! 1035: cp = buffer; ! 1036: *cp = NULL; ! 1037: ! 1038: for (cp = buffer + strlen (buffer) - 1; cp >= buffer; cp--) ! 1039: if (isspace (*cp)) ! 1040: *cp = NULL; ! 1041: else ! 1042: break; ! 1043: sender = buffer; ! 1044: rewind (fp); ! 1045: } ! 1046: ! 1047: /* */ ! 1048: ! 1049: static int ! 1050: copyfile(qd, tmpfil, fold) ! 1051: int qd, fold; ! 1052: register char *tmpfil; ! 1053: { ! 1054: register int i, ! 1055: fd1, ! 1056: fd2; ! 1057: char buffer[BUFSIZ]; ! 1058: register FILE *qfp, ! 1059: *ffp; ! 1060: ! 1061: (void) strcpy (tmpfil, m_tmpfil (invo_name)); ! 1062: if ((fd1 = creat (tmpfil, 0600)) == NOTOK) ! 1063: return NOTOK; ! 1064: (void) close (fd1); ! 1065: if ((fd1 = open (tmpfil, 2)) == NOTOK) ! 1066: return NOTOK; ! 1067: ! 1068: if (!fold) { ! 1069: while ((i = read (qd, buffer, sizeof buffer)) > 0) ! 1070: if (write (fd1, buffer, i) != i) { ! 1071: you_lose: ; ! 1072: (void) close (fd1); ! 1073: (void) unlink (tmpfil); ! 1074: return NOTOK; ! 1075: } ! 1076: if (i == NOTOK) ! 1077: goto you_lose; ! 1078: (void) lseek (fd1, 0L, 0); ! 1079: return fd1; ! 1080: } ! 1081: ! 1082: if ((fd2 = dup (qd)) == NOTOK) { ! 1083: (void) close (fd1); ! 1084: return NOTOK; ! 1085: } ! 1086: if ((qfp = fdopen (fd2, "r")) == NULL) { ! 1087: (void) close (fd1); ! 1088: (void) close (fd2); ! 1089: return NOTOK; ! 1090: } ! 1091: ! 1092: if ((fd2 = dup (fd1)) == NOTOK) { ! 1093: (void) close (fd1); ! 1094: (void) fclose (qfp); ! 1095: return NOTOK; ! 1096: } ! 1097: if ((ffp = fdopen (fd2, "r+")) == NULL) { ! 1098: (void) close (fd1); ! 1099: (void) close (fd2); ! 1100: (void) fclose (qfp); ! 1101: return NOTOK; ! 1102: } ! 1103: ! 1104: i = strlen ("From "); ! 1105: while (fgets (buffer, sizeof buffer, qfp)) { ! 1106: if (!strncmp (buffer, "From ", i)) ! 1107: putc ('>', ffp); ! 1108: fputs (buffer, ffp); ! 1109: if (ferror (ffp)) { ! 1110: (void) close (fd1); ! 1111: (void) fclose (ffp); ! 1112: (void) fclose (qfp); ! 1113: return NOTOK; ! 1114: } ! 1115: } ! 1116: ! 1117: (void) fclose (ffp); ! 1118: if (ferror (qfp)) { ! 1119: (void) close (fd1); ! 1120: (void) fclose (qfp); ! 1121: return NOTOK; ! 1122: } ! 1123: (void) fclose (qfp); ! 1124: ! 1125: (void) lseek (fd1, 0L, 0); ! 1126: ! 1127: return fd1; ! 1128: } ! 1129: ! 1130: /* */ ! 1131: ! 1132: /* VARARGS2 */ ! 1133: ! 1134: static void ! 1135: adorn(what, fmt, a, b, c, d, e, f) ! 1136: char *what, *fmt, *a, *b, *c, *d, *e, *f; ! 1137: { ! 1138: char *cp = invo_name; ! 1139: ! 1140: if (!verbose) ! 1141: return; ! 1142: printf (", "); ! 1143: ! 1144: invo_name = NULL; ! 1145: advise (what, fmt, a, b, c, d, e, f); ! 1146: invo_name = cp; ! 1147: } ! 1148: ! 1149: /* ! 1150: * XXX We need to force config.o to be linked in to get around ! 1151: * library order problems ! 1152: */ ! 1153: /* XXX don't bother if linking with the shared library */ ! 1154: #ifndef SHARED ! 1155: static void ! 1156: kludge() ! 1157: { ! 1158: (void)libpath((char *)0); ! 1159: } ! 1160: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.