|
|
1.1 ! root 1: #include <ctype.h> ! 2: #include <stdio.h> ! 3: #include <pwd.h> ! 4: #include <utmp.h> ! 5: #include <signal.h> ! 6: #include <sys/types.h> ! 7: #include <sys/stat.h> ! 8: #include <setjmp.h> ! 9: #include <whoami.h> ! 10: #include <sysexits.h> ! 11: ! 12: static char SccsId[] = "@(#)mail.c 4.1 10/1/80"; ! 13: ! 14: #define DELIVERMAIL "/etc/delivermail" ! 15: ! 16: ! 17: /*copylet flags */ ! 18: /*remote mail, add rmtmsg */ ! 19: #define REMOTE 1 ! 20: /* zap header and trailing empty line */ ! 21: #define ZAP 3 ! 22: #define ORDINARY 2 ! 23: #define FORWARD 4 ! 24: #define LSIZE 256 ! 25: #define MAXLET 300 /* maximum number of letters */ ! 26: #define MAILMODE (~0644) /* mode of created mail */ ! 27: # ifndef DELIVERMAIL ! 28: #define RMAIL "/usr/net/bin/sendberkmail" ! 29: #define LOCNAM1 "csvax" ! 30: #define LOCNAM2 "ucbvax" ! 31: #define LOCNAM3 "vax" ! 32: #define LOCNAM4 "v" ! 33: # endif ! 34: ! 35: char line[LSIZE]; ! 36: char resp[LSIZE]; ! 37: struct let { ! 38: long adr; ! 39: char change; ! 40: } let[MAXLET]; ! 41: int nlet = 0; ! 42: char lfil[50]; ! 43: long iop, time(); ! 44: char *getenv(); ! 45: char *index(); ! 46: char lettmp[] = "/tmp/maXXXXX"; ! 47: char maildir[] = "/usr/spool/mail/"; ! 48: char mailfile[] = "/usr/spool/mail/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; ! 49: char dead[] = "dead.letter"; ! 50: char *thissys = sysname; ! 51: char *netname = "vax"; ! 52: char forwmsg[] = " forwarded\n"; ! 53: FILE *tmpf; ! 54: FILE *malf; ! 55: char *my_name; ! 56: char *getlogin(); ! 57: struct passwd *getpwuid(); ! 58: int error; ! 59: int changed; ! 60: int forward; ! 61: char from[] = "From "; ! 62: long ftell(); ! 63: int delete(); ! 64: char *ctime(); ! 65: int flgf; ! 66: int flgp; ! 67: int delflg = 1; ! 68: int hseqno; ! 69: jmp_buf sjbuf; ! 70: int rmail; ! 71: ! 72: main(argc, argv) ! 73: char **argv; ! 74: { ! 75: register i; ! 76: char sobuf[BUFSIZ]; ! 77: ! 78: setbuf(stdout, sobuf); ! 79: mktemp(lettmp); ! 80: unlink(lettmp); ! 81: my_name = getlogin(); ! 82: if (my_name == NULL || strlen(my_name) == 0) { ! 83: struct passwd *pwent; ! 84: pwent = getpwuid(getuid()); ! 85: if (pwent==NULL) ! 86: my_name = "???"; ! 87: else ! 88: my_name = pwent->pw_name; ! 89: } ! 90: if(setjmp(sjbuf)) done(); ! 91: for (i=0; i<20; i++) ! 92: setsig(i, delete); ! 93: tmpf = fopen(lettmp, "w"); ! 94: if (tmpf == NULL) { ! 95: fprintf(stderr, "mail: cannot open %s for writing\n", lettmp); ! 96: done(); ! 97: } ! 98: if (argv[0][0] == 'r') ! 99: rmail++; ! 100: if (argv[0][0] != 'r' && /* no favors for rmail*/ ! 101: (argc == 1 || argv[1][0] == '-' && !any(argv[1][1], "rhd"))) ! 102: printmail(argc, argv); ! 103: else ! 104: sendmail(argc, argv); ! 105: done(); ! 106: } ! 107: ! 108: setsig(i, f) ! 109: int i; ! 110: int (*f)(); ! 111: { ! 112: if(signal(i, SIG_IGN)!=SIG_IGN) ! 113: signal(i, f); ! 114: } ! 115: ! 116: any(c, str) ! 117: register int c; ! 118: register char *str; ! 119: { ! 120: ! 121: while (*str) ! 122: if (c == *str++) ! 123: return(1); ! 124: return(0); ! 125: } ! 126: ! 127: printmail(argc, argv) ! 128: char **argv; ! 129: { ! 130: int flg, i, j, print; ! 131: char *p, *getarg(); ! 132: struct stat statb; ! 133: ! 134: setuid(getuid()); ! 135: cat(mailfile, maildir, my_name); ! 136: if (stat(mailfile, &statb) >= 0 ! 137: && (statb.st_mode & S_IFMT) == S_IFDIR) { ! 138: strcat(mailfile, "/"); ! 139: strcat(mailfile, my_name); ! 140: } ! 141: for (; argc>1; argv++, argc--) { ! 142: if (argv[1][0]=='-') { ! 143: if (argv[1][1]=='q') ! 144: delflg = 0; ! 145: else if (argv[1][1]=='p') { ! 146: flgp++; ! 147: delflg = 0; ! 148: } else if (argv[1][1]=='f') { ! 149: if (argc>=3) { ! 150: strcpy(mailfile, argv[2]); ! 151: argv++; ! 152: argc--; ! 153: } ! 154: } else if (argv[1][1]=='r') { ! 155: forward = 1; ! 156: } else if (argv[1][1]=='h') { ! 157: forward = 1; ! 158: } else { ! 159: fprintf(stderr, "mail: unknown option %c\n", argv[1][1]); ! 160: done(); ! 161: } ! 162: } else ! 163: break; ! 164: } ! 165: malf = fopen(mailfile, "r"); ! 166: if (malf == NULL) { ! 167: fprintf(stdout, "No mail.\n"); ! 168: return; ! 169: } ! 170: lock(mailfile); ! 171: copymt(malf, tmpf); ! 172: fclose(malf); ! 173: fclose(tmpf); ! 174: unlock(); ! 175: tmpf = fopen(lettmp, "r"); ! 176: ! 177: changed = 0; ! 178: print = 1; ! 179: for (i = 0; i < nlet; ) { ! 180: j = forward ? i : nlet - i - 1; ! 181: if(setjmp(sjbuf)) { ! 182: print=0; ! 183: } else { ! 184: if (print) ! 185: copylet(j, stdout, ORDINARY); ! 186: print = 1; ! 187: } ! 188: if (flgp) { ! 189: i++; ! 190: continue; ! 191: } ! 192: setjmp(sjbuf); ! 193: fprintf(stdout, "? "); ! 194: fflush(stdout); ! 195: if (fgets(resp, LSIZE, stdin) == NULL) ! 196: break; ! 197: switch (resp[0]) { ! 198: ! 199: default: ! 200: fprintf(stderr, "usage\n"); ! 201: case '?': ! 202: print = 0; ! 203: fprintf(stderr, "q\tquit\n"); ! 204: fprintf(stderr, "x\texit without changing mail\n"); ! 205: fprintf(stderr, "p\tprint\n"); ! 206: fprintf(stderr, "s[file]\tsave (default mbox)\n"); ! 207: fprintf(stderr, "w[file]\tsame without header\n"); ! 208: fprintf(stderr, "-\tprint previous\n"); ! 209: fprintf(stderr, "d\tdelete\n"); ! 210: fprintf(stderr, "+\tnext (no delete)\n"); ! 211: fprintf(stderr, "m user\tmail to user\n"); ! 212: fprintf(stderr, "! cmd\texecute cmd\n"); ! 213: break; ! 214: ! 215: case '+': ! 216: case 'n': ! 217: case '\n': ! 218: i++; ! 219: break; ! 220: case 'x': ! 221: changed = 0; ! 222: case 'q': ! 223: goto donep; ! 224: case 'p': ! 225: break; ! 226: case '^': ! 227: case '-': ! 228: if (--i < 0) ! 229: i = 0; ! 230: break; ! 231: case 'y': ! 232: case 'w': ! 233: case 's': ! 234: flg = 0; ! 235: if (resp[1] != '\n' && resp[1] != ' ') { ! 236: printf("illegal\n"); ! 237: flg++; ! 238: print = 0; ! 239: continue; ! 240: } ! 241: if (resp[1] == '\n' || resp[1] == '\0') { ! 242: p = getenv("HOME"); ! 243: if(p != 0) ! 244: cat(resp+1, p, "/mbox"); ! 245: else ! 246: cat(resp+1, "", "mbox"); ! 247: } ! 248: for (p = resp+1; (p = getarg(lfil, p)) != NULL; ) { ! 249: malf = fopen(lfil, "a"); ! 250: if (malf == NULL) { ! 251: fprintf(stdout, "mail: cannot append to %s\n", lfil); ! 252: flg++; ! 253: continue; ! 254: } ! 255: copylet(j, malf, resp[0]=='w'? ZAP: ORDINARY); ! 256: fclose(malf); ! 257: } ! 258: if (flg) ! 259: print = 0; ! 260: else { ! 261: let[j].change = 'd'; ! 262: changed++; ! 263: i++; ! 264: } ! 265: break; ! 266: case 'm': ! 267: flg = 0; ! 268: if (resp[1] == '\n' || resp[1] == '\0') { ! 269: i++; ! 270: continue; ! 271: } ! 272: if (resp[1] != ' ') { ! 273: printf("invalid command\n"); ! 274: flg++; ! 275: print = 0; ! 276: continue; ! 277: } ! 278: for (p = resp+1; (p = getarg(lfil, p)) != NULL; ) ! 279: if (!sendrmt(j, lfil, "/bin/mail")) /* couldn't send it */ ! 280: flg++; ! 281: if (flg) ! 282: print = 0; ! 283: else { ! 284: let[j].change = 'd'; ! 285: changed++; ! 286: i++; ! 287: } ! 288: break; ! 289: case '!': ! 290: system(resp+1); ! 291: printf("!\n"); ! 292: print = 0; ! 293: break; ! 294: case 'd': ! 295: let[j].change = 'd'; ! 296: changed++; ! 297: i++; ! 298: if (resp[1] == 'q') ! 299: goto donep; ! 300: break; ! 301: } ! 302: } ! 303: donep: ! 304: if (changed) ! 305: copyback(); ! 306: } ! 307: ! 308: copyback() /* copy temp or whatever back to /usr/spool/mail */ ! 309: { ! 310: register i, n, c; ! 311: int new = 0; ! 312: struct stat stbuf; ! 313: ! 314: signal(SIGINT, SIG_IGN); ! 315: signal(SIGHUP, SIG_IGN); ! 316: signal(SIGQUIT, SIG_IGN); ! 317: lock(mailfile); ! 318: stat(mailfile, &stbuf); ! 319: if (stbuf.st_size != let[nlet].adr) { /* new mail has arrived */ ! 320: malf = fopen(mailfile, "r"); ! 321: if (malf == NULL) { ! 322: fprintf(stdout, "mail: can't re-read %s\n", mailfile); ! 323: done(); ! 324: } ! 325: fseek(malf, let[nlet].adr, 0); ! 326: fclose(tmpf); ! 327: tmpf = fopen(lettmp, "a"); ! 328: fseek(tmpf, let[nlet].adr, 0); ! 329: while ((c = fgetc(malf)) != EOF) ! 330: fputc(c, tmpf); ! 331: fclose(malf); ! 332: fclose(tmpf); ! 333: tmpf = fopen(lettmp, "r"); ! 334: let[++nlet].adr = stbuf.st_size; ! 335: new = 1; ! 336: } ! 337: malf = fopen(mailfile, "w"); ! 338: if (malf == NULL) { ! 339: fprintf(stderr, "mail: can't rewrite %s\n", lfil); ! 340: done(); ! 341: } ! 342: n = 0; ! 343: for (i = 0; i < nlet; i++) ! 344: if (let[i].change != 'd') { ! 345: copylet(i, malf, ORDINARY); ! 346: n++; ! 347: } ! 348: fclose(malf); ! 349: if (new) ! 350: fprintf(stdout, "new mail arrived\n"); ! 351: unlock(); ! 352: } ! 353: ! 354: copymt(f1, f2) /* copy mail (f1) to temp (f2) */ ! 355: FILE *f1, *f2; ! 356: { ! 357: long nextadr; ! 358: ! 359: nlet = nextadr = 0; ! 360: let[0].adr = 0; ! 361: while (fgets(line, LSIZE, f1) != NULL) { ! 362: if (isfrom(line)) ! 363: let[nlet++].adr = nextadr; ! 364: nextadr += strlen(line); ! 365: fputs(line, f2); ! 366: } ! 367: let[nlet].adr = nextadr; /* last plus 1 */ ! 368: } ! 369: ! 370: copylet(n, f, type) FILE *f; ! 371: { int ch, k; ! 372: fseek(tmpf, let[n].adr, 0); ! 373: k = let[n+1].adr - let[n].adr; ! 374: while(k-- > 1 && (ch=fgetc(tmpf))!='\n') ! 375: if(type!=ZAP) fputc(ch,f); ! 376: if(type==REMOTE) ! 377: fprintf(f, " remote from %s\n", thissys); ! 378: else if (type==FORWARD) ! 379: fprintf(f, forwmsg); ! 380: else if(type==ORDINARY) ! 381: fputc(ch,f); ! 382: while(k-->1) ! 383: fputc(ch=fgetc(tmpf), f); ! 384: if(type!=ZAP || ch!= '\n') ! 385: fputc(fgetc(tmpf), f); ! 386: } ! 387: ! 388: isfrom(lp) ! 389: register char *lp; ! 390: { ! 391: register char *p; ! 392: ! 393: for (p = from; *p; ) ! 394: if (*lp++ != *p++) ! 395: return(0); ! 396: return(1); ! 397: } ! 398: ! 399: sendmail(argc, argv) ! 400: char **argv; ! 401: { ! 402: char truename[100]; ! 403: int first; ! 404: register char *cp; ! 405: int gaver = 0; ! 406: # ifdef DELIVERMAIL ! 407: char *newargv[1000]; ! 408: register char **ap; ! 409: register char **vp; ! 410: int dflag; ! 411: ! 412: dflag = 0; ! 413: if (argc < 1) ! 414: fprintf(stderr, "puke\n"); ! 415: for (vp = argv, ap = newargv + 1; (*ap = *vp++) != 0; ap++) ! 416: { ! 417: if (ap[0][0] == '-' && ap[0][1] == 'd') ! 418: dflag++; ! 419: } ! 420: if (!dflag) ! 421: { ! 422: /* give it to delivermail, rah rah! */ ! 423: unlink(lettmp); ! 424: ap = newargv+1; ! 425: if (rmail) ! 426: *ap-- = "-s"; ! 427: *ap = "-delivermail"; ! 428: execv(DELIVERMAIL, ap); ! 429: perror(DELIVERMAIL); ! 430: exit(EX_UNAVAILABLE); ! 431: } ! 432: # endif DELIVERMAIL ! 433: ! 434: truename[0] = 0; ! 435: line[0] = '\0'; ! 436: ! 437: /* ! 438: * When we fall out of this, argv[1] should be first name, ! 439: * argc should be number of names + 1. ! 440: */ ! 441: ! 442: while (argc > 1 && *argv[1] == '-') { ! 443: cp = *++argv; ! 444: argc--; ! 445: switch (cp[1]) { ! 446: case 'r': ! 447: if (argc <= 0) { ! 448: usage(); ! 449: done(); ! 450: } ! 451: gaver++; ! 452: strcpy(truename, argv[1]); ! 453: fgets(line, LSIZE, stdin); ! 454: if (strcmpn("From", line, 4) == 0) ! 455: line[0] = '\0'; ! 456: argv++; ! 457: argc--; ! 458: break; ! 459: ! 460: case 'h': ! 461: if (argc <= 0) { ! 462: usage(); ! 463: done(); ! 464: } ! 465: hseqno = atoi(argv[1]); ! 466: argv++; ! 467: argc--; ! 468: break; ! 469: ! 470: # ifdef DELIVERMAIL ! 471: case 'd': ! 472: break; ! 473: # endif DELIVERMAIL ! 474: ! 475: default: ! 476: usage(); ! 477: done(); ! 478: } ! 479: } ! 480: if (argc <= 1) { ! 481: usage(); ! 482: done(); ! 483: } ! 484: if (gaver == 0) ! 485: strcpy(truename, my_name); ! 486: /* ! 487: if (argc > 4 && strcmp(argv[1], "-r") == 0) { ! 488: strcpy(truename, argv[2]); ! 489: argc -= 2; ! 490: argv += 2; ! 491: fgets(line, LSIZE, stdin); ! 492: if (strcmpn("From", line, 4) == 0) ! 493: line[0] = '\0'; ! 494: } else ! 495: strcpy(truename, my_name); ! 496: */ ! 497: time(&iop); ! 498: fprintf(tmpf, "%s%s %s", from, truename, ctime(&iop)); ! 499: iop = ftell(tmpf); ! 500: flgf = 1; ! 501: for (first = 1;; first = 0) { ! 502: if (first && line[0] == '\0' && fgets(line, LSIZE, stdin) == NULL) ! 503: break; ! 504: if (!first && fgets(line, LSIZE, stdin) == NULL) ! 505: break; ! 506: if (line[0] == '.' && line[1] == '\n' && isatty(fileno(stdin))) ! 507: break; ! 508: if (isfrom(line)) ! 509: fputs(">", tmpf); ! 510: fputs(line, tmpf); ! 511: flgf = 0; ! 512: } ! 513: fputs("\n", tmpf); ! 514: nlet = 1; ! 515: let[0].adr = 0; ! 516: let[1].adr = ftell(tmpf); ! 517: fclose(tmpf); ! 518: if (flgf) ! 519: return; ! 520: tmpf = fopen(lettmp, "r"); ! 521: if (tmpf == NULL) { ! 522: fprintf(stderr, "mail: cannot reopen %s for reading\n", lettmp); ! 523: return; ! 524: } ! 525: while (--argc > 0) ! 526: if (!send(0, *++argv, truename)) ! 527: error++; ! 528: if (error) { ! 529: setuid(getuid()); ! 530: malf = fopen(dead, "w"); ! 531: if (malf == NULL) { ! 532: fprintf(stdout, "mail: cannot open %s\n", dead); ! 533: fclose(tmpf); ! 534: return; ! 535: } ! 536: copylet(0, malf, ZAP); ! 537: fclose(malf); ! 538: fprintf(stdout, "Mail saved in %s\n", dead); ! 539: } ! 540: fclose(tmpf); ! 541: } ! 542: ! 543: sendrmt(n, name, rcmd) ! 544: char *name; ! 545: char *rcmd; ! 546: { ! 547: FILE *rmf, *popen(); ! 548: register char *p; ! 549: char rsys[64], cmd[64]; ! 550: register local, pid; ! 551: int sts; ! 552: ! 553: local = 0; ! 554: if (index(name, '^')) { ! 555: while (p = index(name, '^')) ! 556: *p = '!'; ! 557: if (strncmp(name, "researc", 7)) { ! 558: strcpy(rsys, "research"); ! 559: if (*name != '!') ! 560: --name; ! 561: goto skip; ! 562: } ! 563: } ! 564: if (*name=='!') ! 565: name++; ! 566: for(p=rsys; *name!='!'; *p++ = *name++) ! 567: if (*name=='\0') { ! 568: local++; ! 569: break; ! 570: } ! 571: *p = '\0'; ! 572: if ((!local && *name=='\0') || (local && *rsys=='\0')) { ! 573: fprintf(stdout, "null name\n"); ! 574: return(0); ! 575: } ! 576: skip: ! 577: if ((pid = fork()) == -1) { ! 578: fprintf(stderr, "mail: can't create proc for remote\n"); ! 579: return(0); ! 580: } ! 581: if (pid) { ! 582: while (wait(&sts) != pid) { ! 583: if (wait(&sts)==-1) ! 584: return(0); ! 585: } ! 586: return(!sts); ! 587: } ! 588: setuid(getuid()); ! 589: if (local) ! 590: sprintf(cmd, "%s %s", rcmd, rsys); ! 591: else { ! 592: if (index(name+1, '!')) ! 593: sprintf(cmd, "uux - %s!rmail \\(%s\\)", rsys, name+1); ! 594: else ! 595: sprintf(cmd, "uux - %s!rmail %s", rsys, name+1); ! 596: } ! 597: if ((rmf=popen(cmd, "w")) == NULL) ! 598: exit(1); ! 599: copylet(n, rmf, local ? !strcmp(rcmd, "/bin/mail") ? FORWARD : ORDINARY : REMOTE); ! 600: pclose(rmf); ! 601: exit(0); ! 602: } ! 603: ! 604: # ifndef DELIVERMAIL ! 605: /* ! 606: * Send mail on the Berkeley network. ! 607: * Sorry Bill, sendrmt() is so awful we just gave up. ! 608: */ ! 609: ! 610: sendberkmail(n, name, fromaddr) ! 611: char name[]; ! 612: char fromaddr[]; ! 613: { ! 614: char cmd[200]; ! 615: register FILE *cmdf; ! 616: ! 617: sprintf(cmd, "%s -h %d -f %s -t %s", RMAIL, hseqno, fromaddr, name); ! 618: if ((cmdf = popen(cmd, "w")) == NULL) { ! 619: perror(RMAIL); ! 620: return(0); ! 621: } ! 622: copylet(n, cmdf, ORDINARY); ! 623: pclose(cmdf); ! 624: return(9); ! 625: } ! 626: # endif ! 627: ! 628: usage() ! 629: { ! 630: ! 631: fprintf(stderr, "Usage: mail [ -f ] people . . .\n"); ! 632: } ! 633: ! 634: send(n, name, fromaddr) ! 635: int n; ! 636: char *name; ! 637: char *fromaddr; ! 638: { ! 639: char file[100]; ! 640: register char *p; ! 641: register mask; ! 642: struct passwd *pw, *getpwnam(); ! 643: struct stat statb; ! 644: ! 645: # ifndef DELIVERMAIL ! 646: stripfx(LOCNAM1, &name); ! 647: stripfx(LOCNAM2, &name); ! 648: stripfx(LOCNAM3, &name); ! 649: stripfx(LOCNAM4, &name); ! 650: if(*name == ':')name++; /* skip colon in to-name */ ! 651: for(p=name; *p!=':' && *p!='!' && *p!='^' &&*p!='\0'; p++); ! 652: /* if(*p == ':') return(sendrmt(n, name, RMAIL)); */ ! 653: if (*p == ':') ! 654: return(sendberkmail(n, name, fromaddr)); ! 655: else if (*p=='\0' && strcmp(name, "msgs") == 0) ! 656: return(sendrmt(n, "-s", "/usr/ucb/msgs")); ! 657: # endif ! 658: for(p=name; *p!='!'&&*p!='^' &&*p!='\0'; p++) ! 659: ; ! 660: if (*p == '!'|| *p=='^') ! 661: return(sendrmt(n, name, 0)); ! 662: if ((pw = getpwnam(name)) == NULL) { ! 663: fprintf(stdout, "mail: can't send to %s\n", name); ! 664: return(0); ! 665: } ! 666: cat(file, maildir, name); ! 667: if (stat(file, &statb) >= 0 && (statb.st_mode & S_IFMT) == S_IFDIR) { ! 668: strcat(file, "/"); ! 669: strcat(file, name); ! 670: } ! 671: mask = umask(MAILMODE); ! 672: malf = fopen(file, "a"); ! 673: umask(mask); ! 674: if (malf == NULL) { ! 675: fprintf(stdout, "mail: cannot append to %s\n", file); ! 676: return(0); ! 677: } ! 678: lock(file); ! 679: chown(file, pw->pw_uid, pw->pw_gid); ! 680: copylet(n, malf, ORDINARY); ! 681: fclose(malf); ! 682: unlock(); ! 683: return(1); ! 684: } ! 685: ! 686: delete(i) ! 687: { ! 688: setsig(i, delete); ! 689: fprintf(stderr, "\n"); ! 690: if(delflg) ! 691: longjmp(sjbuf, 1); ! 692: done(); ! 693: } ! 694: ! 695: /* ! 696: * Lock the specified mail file by setting the file mailfile.lock. ! 697: * We must, of course, be careful to unlink the lock file by a call ! 698: * to unlock before we stop. The algorithm used here is to see if ! 699: * the lock exists, and if it does, to check its modify time. If it ! 700: * is older than 30 seconds, we assume error and set our own file. ! 701: * Otherwise, we wait for 5 seconds and try again. ! 702: */ ! 703: ! 704: char *maillock = ".lock"; /* Lock suffix for mailname */ ! 705: char *lockname = "/usr/spool/mail/tmXXXXXX"; ! 706: char locktmp[30]; /* Usable lock temporary */ ! 707: char curlock[50]; /* Last used name of lock */ ! 708: int locked; /* To note that we locked it */ ! 709: ! 710: lock(file) ! 711: char *file; ! 712: { ! 713: register int f; ! 714: struct stat sbuf; ! 715: long curtime; ! 716: int statfailed; ! 717: ! 718: if (locked || flgf) ! 719: return(0); ! 720: strcpy(curlock, file); ! 721: strcat(curlock, maillock); ! 722: strcpy(locktmp, lockname); ! 723: mktemp(locktmp); ! 724: unlink(locktmp); ! 725: statfailed = 0; ! 726: for (;;) { ! 727: f = lock1(locktmp, curlock); ! 728: if (f == 0) { ! 729: locked = 1; ! 730: return(0); ! 731: } ! 732: if (stat(curlock, &sbuf) < 0) { ! 733: if (statfailed++ > 5) ! 734: return(-1); ! 735: sleep(5); ! 736: continue; ! 737: } ! 738: statfailed = 0; ! 739: time(&curtime); ! 740: if (curtime < sbuf.st_ctime + 30) { ! 741: sleep(5); ! 742: continue; ! 743: } ! 744: unlink(curlock); ! 745: } ! 746: } ! 747: ! 748: /* ! 749: * Remove the mail lock, and note that we no longer ! 750: * have it locked. ! 751: */ ! 752: ! 753: unlock() ! 754: { ! 755: ! 756: unlink(curlock); ! 757: locked = 0; ! 758: } ! 759: ! 760: /* ! 761: * Attempt to set the lock by creating the temporary file, ! 762: * then doing a link/unlink. If it fails, return -1 else 0 ! 763: */ ! 764: ! 765: lock1(tempfile, name) ! 766: char tempfile[], name[]; ! 767: { ! 768: register int fd; ! 769: ! 770: fd = creat(tempfile, 0); ! 771: if (fd < 0) ! 772: return(-1); ! 773: close(fd); ! 774: if (link(tempfile, name) < 0) { ! 775: unlink(tempfile); ! 776: return(-1); ! 777: } ! 778: unlink(tempfile); ! 779: return(0); ! 780: } ! 781: ! 782: done() ! 783: { ! 784: if(locked) ! 785: unlock(); ! 786: unlink(lettmp); ! 787: unlink(locktmp); ! 788: exit(error); ! 789: } ! 790: ! 791: cat(to, from1, from2) ! 792: char *to, *from1, *from2; ! 793: { ! 794: int i, j; ! 795: ! 796: j = 0; ! 797: for (i=0; from1[i]; i++) ! 798: to[j++] = from1[i]; ! 799: for (i=0; from2[i]; i++) ! 800: to[j++] = from2[i]; ! 801: to[j] = 0; ! 802: } ! 803: ! 804: char *getarg(s, p) /* copy p... into s, update p */ ! 805: register char *s, *p; ! 806: { ! 807: while (*p == ' ' || *p == '\t') ! 808: p++; ! 809: if (*p == '\n' || *p == '\0') ! 810: return(NULL); ! 811: while (*p != ' ' && *p != '\t' && *p != '\n' && *p != '\0') ! 812: *s++ = *p++; ! 813: *s = '\0'; ! 814: return(p); ! 815: } ! 816: # ifndef DELIVERMAIL ! 817: /* ! 818: stripfx(prefix string, pointer to string) ! 819: ! 820: takes a ptr to string and compares it to prefix string. ! 821: may be called multiple times ! 822: */ ! 823: stripfx(pfx, name) ! 824: char *pfx; ! 825: char **name; ! 826: { ! 827: register char *cp = *name; ! 828: ! 829: while (*pfx && (*cp == *pfx || *cp == toupper(*pfx))) ! 830: cp++, pfx++; ! 831: if (*cp != ':' || *pfx != 0) ! 832: return; ! 833: *name = cp; ! 834: } ! 835: # endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.