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