|
|
1.1 ! root 1: static char sccsid[] = "@(#)v6mail.c 4.4 (Berkeley) 1/9/83"; ! 2: ! 3: /* ! 4: * Version 6 Cory mail-- ! 5: * a clean and simple mail program ! 6: * machine and version independent ! 7: * Eric Schmidt ! 8: * must run as setuid root to chown the destination mailbox ! 9: * if NOTROOT defined, doesn't need to run as root ! 10: * ! 11: * DON'T CHANGE THIS CODE ! 12: * bitch to "csvax:schmidt" instead ! 13: */ ! 14: ! 15: /* ! 16: * mail command usage ! 17: * mail [-yn] ! 18: * prints your mail ! 19: * mail people ! 20: * sends standard input to people ! 21: * ! 22: * mail -r fromaddr people ! 23: * sends mail from the network ! 24: * ! 25: * mail -d people ! 26: * don't call sendmail, send mail directly ! 27: * mail msgs ! 28: * send to "msgs" ! 29: * mail filename ! 30: * mail to filename instead of user (must be at least one /) ! 31: * mail -D ! 32: * delete the invokers mailbox (more efficient than ! 33: * mail -n >/dev/null) ! 34: */ ! 35: ! 36: /* ! 37: * bugs: ! 38: * Ingres 11/70 multiple names/uid? ! 39: * additions: ! 40: * Save? type 'x' - doesn't unlink the mail file ! 41: */ ! 42: /* ! 43: * BIFF is an immediate notification flag using the IPC stuff ! 44: */ ! 45: # include "local.h" ! 46: # include <stdio.h> ! 47: # include "mach.h" ! 48: ! 49: # ifdef RAND ! 50: ! 51: /* for all machines at RAND */ ! 52: # define MAILMODE 0644 ! 53: ! 54: # endif RAND ! 55: ! 56: # ifdef NOSC ! 57: ! 58: /* for all machines at NOSC */ ! 59: # define MAILMODE 0644 ! 60: ! 61: # endif NOSC ! 62: ! 63: # ifdef BERKELEY ! 64: /* for Berkeley */ ! 65: /* for each machine */ ! 66: /* lump the CC machines into one */ ! 67: # ifdef CCV7 ! 68: # define MAILMODE 0600 ! 69: # define MSGSCMD "/usr/ucb/bin/msgs" ! 70: # endif ! 71: ! 72: # ifdef CCV6 ! 73: # define MSGSCMD "/usr/bin/eecs/msgs" ! 74: # define MAILMODE 0600 ! 75: # endif ! 76: ! 77: # ifdef ING70 ! 78: # define MAILMODE 0666 ! 79: # define MSGSCMD "/usr/bin/msgs" ! 80: # define NOTROOT ! 81: # endif ! 82: ! 83: # ifdef INGVAX ! 84: # define MAILMODE 0644 ! 85: # define MSGSCMD "/usr/ucb/msgs" ! 86: # endif ! 87: ! 88: /* ! 89: # ifdef VIRUS ! 90: # define MAILMODE 0644 ! 91: # define MSGSCMD "/usr/bin/msgs" ! 92: # endif ! 93: */ ! 94: ! 95: # ifdef UCBVAX ! 96: # define MAILMODE 0644 ! 97: # define MSGSCMD "/usr/ucb/msgs" ! 98: # define BIFF ! 99: # endif ! 100: ! 101: # ifdef IMAGE ! 102: # define MAILMODE 0644 ! 103: # define MSGSCMD "/usr/bin/msgs" ! 104: # endif ! 105: ! 106: # ifdef KIM ! 107: # define MAILMODE 0644 ! 108: # define MSGSCMD "/usr/ucb/msgs" ! 109: # endif ! 110: ! 111: # ifdef ESVAX ! 112: # define MAILMODE 0644 ! 113: # define MSGSCMD "/usr/ucb/msgs" ! 114: # endif ! 115: ! 116: # ifdef Q ! 117: # define MAILMODE 0600 ! 118: # define MSGSCMD "/usr/bin/eecs/msgs" ! 119: # endif ! 120: ! 121: # ifdef ARPAVAX ! 122: # define MAILMODE 0644 ! 123: # define MSGSCMD "/usr/ucb/msgs" ! 124: # define BIFF ! 125: # endif ! 126: ! 127: # ifdef SRC ! 128: # define MAILMODE 0600 ! 129: # define MSGSCMD "/usr/bin/msgs" ! 130: # endif ! 131: ! 132: # ifdef MATHSTAT ! 133: # define MAILMODE 0600 ! 134: # define MSGSCMD "/usr/bin/msgs" ! 135: # endif ! 136: ! 137: # ifdef CSVAX ! 138: # define MAILMODE 0644 ! 139: # define MSGSCMD "/usr/ucb/msgs" ! 140: # define BIFF ! 141: # endif ! 142: ! 143: # ifdef ONYX ! 144: # define MAILMODE 0644 ! 145: # define MSGSCMD "/usr/ucb/bin/msgs" ! 146: # endif ! 147: ! 148: # ifdef CORY ! 149: # define MAILMODE 0600 ! 150: # define MSGSCMD "/usr/bin/eecs/msgs" ! 151: # endif ! 152: ! 153: # ifdef EECS40 ! 154: # define MAILMODE 0644 ! 155: # define MSGSCMD "/usr/bin/msgs" ! 156: # endif ! 157: /* end of berkeley defsn */ ! 158: ! 159: # endif ! 160: /* end of per-machine ifdefs */ ! 161: ! 162: # ifdef USRMAIL ! 163: # define MAILDIR "/usr/mail" ! 164: # else ! 165: # define MAILDIR "/usr/spool/mail" ! 166: # endif ! 167: ! 168: char lettmp[] = "/tmp/MaXXXXX"; /* keep letter before sending it */ ! 169: char preptmp[] = "/tmp/mbXXXXX"; /* if prepending msg, use this file */ ! 170: int chew; /* if true, strip extra from lines */ ! 171: int dflag; /* if true, don't call sendmail */ ! 172: char shopcnt[30] = "0"; /* hop count parameter for rmt mail */ ! 173: int errs; /* no of errs in sending */ ! 174: char deleteonly; /* if true, just delete mailbox */ ! 175: char remname[50]; /* if non-empty, from line extra */ ! 176: ! 177: char _sobuf[BUFSIZ]; ! 178: main(argc, argv) ! 179: char **argv; ! 180: { ! 181: register int myuid; ! 182: int delexit(); ! 183: char namebuf[128], *sn = NULL, logindir[60]; ! 184: struct passwd *pwd; ! 185: ! 186: setbuf(stdout,_sobuf); ! 187: mktemp(lettmp); ! 188: mktemp(preptmp); ! 189: unlink(lettmp); ! 190: unlink(preptmp); ! 191: myuid = getuid(); ! 192: logindir[0] = 0; ! 193: sn = getlogin(); ! 194: if(sn == NULL || *sn == 0 || *sn == ' '){ ! 195: pwd = getpwuid(myuid); /* will read passwd file */ ! 196: if(pwd != NULL){ ! 197: sn = pwd->pw_name; ! 198: strcpy(logindir,pwd->pw_dir); ! 199: } ! 200: if(sn == NULL){ ! 201: fprintf(stderr,"Who are you?\n"); ! 202: delexit(EX_OSFILE); ! 203: } ! 204: } ! 205: strcpy(namebuf,sn); ! 206: if (argc < 2) ! 207: goto hitit; ! 208: for (argc--, argv++; argc > 0 && argv[0][0] == '-'; argc--, argv++) ! 209: switch(argv[0][1]) { ! 210: case 'y': ! 211: case 'n': ! 212: argc++, argv--; ! 213: hitit: ! 214: printmail(argc, argv, namebuf,logindir); ! 215: delexit(EX_OK); ! 216: ! 217: case 'r': /* one-arg -r-- -r addr */ ! 218: if (argc < 2) ! 219: continue; ! 220: /* ignore -r if not network or root */ ! 221: if (strcmp("network", namebuf) == 0 || myuid == 0 || ! 222: strcmp("uucp", namebuf) == 0 || index(argv[1], '!') != NULL) { ! 223: strcpy(namebuf,argv[1]); ! 224: chew++; /* eat From lines */ ! 225: } ! 226: else strcpy(remname, argv[1]); ! 227: argc--, argv++; ! 228: continue; ! 229: case 'h': /* hop count - used by network */ ! 230: if(argc < 2) continue; ! 231: strcpy(shopcnt,argv[1]); ! 232: argc--, argv++; ! 233: continue; ! 234: case 'd': /* really deliver this message */ ! 235: dflag++; ! 236: continue; ! 237: case 'D': /* only delete the invokers mailbox */ ! 238: deleteonly++; ! 239: goto hitit; /* delete mail box, thats all */ ! 240: } ! 241: /* if we are already ignoring signals, catch sigint */ ! 242: if(signal(SIGINT,SIG_IGN) != SIG_IGN) ! 243: signal(SIGINT, delexit); ! 244: argc++, argv--; ! 245: bulkmail(argc, argv, namebuf); ! 246: delexit(EX_OK); ! 247: } ! 248: ! 249: printmail(argc, argv, name, logindir) ! 250: char **argv; ! 251: char *name, *logindir; ! 252: { ! 253: register int c; ! 254: FILE *fdin; ! 255: char sfnmail[60], mbox[120]; ! 256: struct stat statbuf; ! 257: ! 258: # ifdef OLDMAIL ! 259: if(logindir[0] == 0){ ! 260: pwd = getpwuid(getuid()); ! 261: if(pwd == NULL){ ! 262: fprintf(stderr,"Can't get directory\n"); ! 263: exit(EX_OSFILE); ! 264: } ! 265: strcpy(logindir, pwd->pw_dir); ! 266: } ! 267: sprintf(sfnmail,"%s/.mail",logindir); ! 268: # else ! 269: sprintf(sfnmail,"%s/%s",MAILDIR,name); ! 270: # endif ! 271: if(deleteonly){ ! 272: remove(sfnmail); ! 273: return; ! 274: } ! 275: if (stat(sfnmail, &statbuf)>=0 && statbuf.st_nlink==1 && ! 276: getsize(&statbuf) > 0L && (fdin = fopen(sfnmail, "r")) != NULL){ ! 277: getput(fdin, stdout); ! 278: fclose(fdin); ! 279: fflush(stdout); ! 280: c = 'y'; ! 281: if (argc<2) { ! 282: if(isatty(0)){ ! 283: printf("Save(y-n) ?"); ! 284: fflush(stdout); ! 285: c = getchar(); ! 286: } ! 287: } else ! 288: c = argv[1][1]; ! 289: if (!any(c, "xyn")) ! 290: delexit(EX_OK); ! 291: if (c == 'y') { ! 292: sprintf(mbox,"%s/mbox",logindir); ! 293: if (accesss(mbox)) { ! 294: printf("Saved mail in 'mbox'\n"); ! 295: if(insert(sfnmail, mbox, getuid(),getgid())) ! 296: remove(sfnmail); ! 297: } ! 298: else printf("In wrong directory\n"); ! 299: } ! 300: else if(c != 'x') remove(sfnmail); ! 301: } else ! 302: printf("No mail.\n"); ! 303: } ! 304: ! 305: bulkmail(argc, argv, from) ! 306: char **argv, *from; ! 307: { ! 308: extern int errno; ! 309: char linebuf[BUFSIZ]; ! 310: char *getdate(); ! 311: FILE *fdout; ! 312: ! 313: # ifdef SENDMAIL ! 314: /* ! 315: ** Ship off to sendmail if appropriate (and possible) ! 316: */ ! 317: ! 318: if (!dflag) ! 319: { ! 320: argv[0] = "-sendmail"; ! 321: argv[argc] = 0; ! 322: execv("/usr/lib/sendmail", argv); ! 323: /* oops... better just deliver it. */ ! 324: fprintf(stderr, "Not using sendmail\n"); ! 325: errno = 0; ! 326: argv[argc] = (char *)-1; ! 327: } ! 328: # endif ! 329: ! 330: fdout = fopen(lettmp, "w"); ! 331: if (fdout == NULL) { ! 332: perror(lettmp); ! 333: delexit(EX_OSFILE); ! 334: } ! 335: /* ! 336: * If delivering mail from the network via mail -r, ! 337: * Strip the leading line and throw it away, as long ! 338: * as it begins with "From ..." (and preserve the date if poss.) ! 339: */ ! 340: if (chew) { ! 341: fgets(linebuf,BUFSIZ,stdin); ! 342: if(strncmp(linebuf,"From ",5) != 0){ ! 343: fline(fdout,NULL,from); ! 344: fprintf(fdout,"%s", linebuf); ! 345: } ! 346: else fline(fdout,getdate(linebuf),from); ! 347: } ! 348: else fline(fdout,NULL,from); ! 349: if(remname[0]) fprintf(fdout,"(from %s)\n",remname); ! 350: ! 351: /* on the image machine, promt with subj */ ! 352: if(getput(stdin,fdout) == 0) ! 353: delexit(EX_OSERR); ! 354: putc('\n',fdout); ! 355: fclose(fdout); ! 356: while (--argc > 0) ! 357: sendto(*++argv,from); ! 358: delexit(errs); ! 359: } ! 360: /* print from line, with date date, if date = NULL, compute it */ ! 361: fline(fdout,date,from) ! 362: FILE *fdout; ! 363: char *date; ! 364: char *from; ! 365: { ! 366: int tbuf[2]; ! 367: ! 368: if(date == NULL){ ! 369: time(tbuf); ! 370: date = ctime(tbuf); ! 371: } ! 372: fprintf(fdout,"From %s %s", from, date); ! 373: } ! 374: /* look over linebuf and return ptr to date, NULL if error */ ! 375: char *getdate(linebuf) ! 376: char *linebuf; ! 377: { ! 378: register char *s; ! 379: s = linebuf; ! 380: while(*s){ ! 381: if(strncmp(s," Sun ",5) == 0 ! 382: || strncmp(s," Mon ",5) == 0 ! 383: || strncmp(s," Tue ",5) == 0 ! 384: || strncmp(s," Wed ",5) == 0 ! 385: || strncmp(s," Thu ",5) == 0 ! 386: || strncmp(s," Fri ",5) == 0 ! 387: || strncmp(s," Sat ",5) == 0) ! 388: return(++s); ! 389: s++; ! 390: } ! 391: return(NULL); ! 392: } ! 393: ! 394: sendto(person, fromaddr) ! 395: char *person; ! 396: char *fromaddr; ! 397: { ! 398: static int saved = 0; ! 399: register int hisuid, hisgid; ! 400: char sfnmail[60], logindir[60]; ! 401: struct passwd *pwd; ! 402: ! 403: stripmach(&person); ! 404: if(person[0] == ':')person++; ! 405: /* sendmail provides these services */ ! 406: if(any(':',person) ! 407: # ifdef MSGSCMD ! 408: || strcmp(person,"msgs") == 0 ! 409: # endif ! 410: ){ ! 411: int pid; ! 412: int pidchild; ! 413: ! 414: while((pid = fork()) == -1)sleep(2); ! 415: if (pid < 0) { ! 416: perror("fork"); ! 417: goto assback; ! 418: } ! 419: if (pid == 0) { ! 420: fclose(stdin); ! 421: freopen(lettmp,"r",stdin); ! 422: setuid(getuid()); /* insure no security hole*/ ! 423: if (strcmp(person,"msgs") != 0) { ! 424: /* ! 425: sendberkmail will add the machine, e.g. ! 426: CSVAX:schmidt, if the -f flag is not set ! 427: */ ! 428: execl("/usr/net/bin/sendberkmail", ! 429: "sendberkmail", "-t",person,"-h",shopcnt, ! 430: chew ? "-f" : 0,fromaddr,0); ! 431: perror("/usr/net/bin/sendberkmail"); ! 432: } ! 433: # ifdef MSGSCMD ! 434: else { ! 435: execl(MSGSCMD, "msgs", "-s", 0); ! 436: perror(MSGSCMD); ! 437: } ! 438: # endif ! 439: exit(EX_UNAVAILABLE); ! 440: } ! 441: for (;;) { ! 442: register int rcode = wait(&pidchild); ! 443: if (rcode == -1) ! 444: goto assback; ! 445: if (rcode == pid) ! 446: break; ! 447: } ! 448: if ((pidchild & 0377) != 0 || (pidchild >> 8) != 0) ! 449: goto assback; ! 450: return; ! 451: } ! 452: ! 453: if(!any('/',person)){ ! 454: /* if name has no / in it, we assume it is a user's name */ ! 455: # ifdef HPASSWD ! 456: hisuid = uidfromsn(person); ! 457: # else ! 458: pwd = getpwnam(person); ! 459: if(pwd != NULL){ ! 460: hisuid = guid(pwd->pw_uid,pwd->pw_gid); ! 461: hisgid = pwd->pw_gid; ! 462: strcpy(logindir,pwd->pw_dir); ! 463: } ! 464: else hisuid = -1; ! 465: # endif ! 466: if(hisuid == -1){ ! 467: assback: ! 468: fflush(stdout); ! 469: fprintf(stderr,"Can't send to %s.\n", person); ! 470: errs++; ! 471: if (isatty(0) && saved==0) { ! 472: saved++; ! 473: if (accesss("dead.letter")) { ! 474: printf("Letter saved in 'dead.letter'\n"); ! 475: insert(lettmp, "dead.letter", ! 476: getuid(),getgid()); ! 477: } else ! 478: printf("In wrong directory\n"); ! 479: } ! 480: return; ! 481: } ! 482: # ifdef OLDMAIL ! 483: sprintf(sfnmail,"%s/.mail",logindir); ! 484: # else ! 485: sprintf(sfnmail,"%s/%s",MAILDIR,person); ! 486: # endif ! 487: lock(sfnmail); ! 488: insert(lettmp, sfnmail, hisuid, hisgid); ! 489: unlock(); ! 490: } ! 491: else { /* it has / in it, "person" is a file */ ! 492: if(accesss(person)){ ! 493: lock(person); ! 494: insert(lettmp, person, -1, -1); ! 495: unlock(); ! 496: } ! 497: else ! 498: fprintf(stderr,"Can't access %s\n",person); ! 499: } ! 500: } ! 501: ! 502: /* return 1 if success, 0 otherwise */ ! 503: insert(from, to, uid, gid) ! 504: char *from, *to; ! 505: { ! 506: # ifdef V6 ! 507: return(prepend(from,to,uid, gid)); ! 508: # else ! 509: return(append(from,to,uid, gid)); ! 510: # endif ! 511: } ! 512: ! 513: #ifdef BIFF ! 514: #include <sys/socket.h> ! 515: #include <netinet/in.h> ! 516: #include <netdb.h> ! 517: #endif ! 518: ! 519: /* return 1 if success, 0 otherwise */ ! 520: append(from,to,uid, gid) ! 521: char *from, *to; ! 522: { ! 523: register FILE *fdin, *fdout; ! 524: int ret; ! 525: struct stat statbuf; ! 526: #ifdef BIFF ! 527: char *cp, buf[100], *rindex(); ! 528: int s; ! 529: struct hostent *hp; ! 530: struct sockaddr_in sin; ! 531: struct servent *sp; ! 532: #endif ! 533: if (stat(to, &statbuf) >= 0 && (statbuf.st_mode&S_IFDIR) != 0) { ! 534: fprintf(stderr, "Exotic destination %s\n", to); ! 535: errs++; ! 536: return(0); ! 537: } ! 538: if ((fdout = fopen(to, "a")) == NULL) { ! 539: perror(to); ! 540: errs++; ! 541: return(0); ! 542: } ! 543: # ifndef NOTROOT ! 544: if(uid != -1)mchown(to, uid, gid); ! 545: # endif ! 546: if(uid != -1)chmod(to, MAILMODE); ! 547: if ((fdin = fopen(from, "r")) == NULL) { ! 548: perror(from); ! 549: return(0); ! 550: } ! 551: #ifdef BIFF ! 552: { s = socket(AF_INET, SOCK_STREAM, 0, 0); ! 553: cp = rindex(to, '/'); ! 554: if (cp) ! 555: sprintf(buf, "%s@%d\n", cp+1, ftell(fdout)); ! 556: } ! 557: #endif ! 558: ret = getput(fdin,fdout); ! 559: fclose(fdin); ! 560: fclose(fdout); ! 561: #ifdef BIFF ! 562: if (cp && s >= 0) { ! 563: hp = gethostbyname("localhost"); ! 564: sp = getservent("biff", "udp"); ! 565: if (hp && sp) { ! 566: bcopy(hp->h_addr, &sin.sin_addr, hp->h_length); ! 567: sin.sin_family = hp->h_addrtype; ! 568: sin.sin_port = sp->s_port; ! 569: (void) sendto(s, buf, strlen(buf) + 1, 0, ! 570: &sin, sizeof (sin)); ! 571: } ! 572: close(s); ! 573: } ! 574: #endif ! 575: return(ret); ! 576: } ! 577: ! 578: /* return 1 if success, 0 otherwise */ ! 579: prepend(from, to, uid, gid) ! 580: char *from, *to; ! 581: { ! 582: register int (*sig)(); ! 583: struct stat statbuf; ! 584: FILE *fdout, *fdin; ! 585: int ret; ! 586: ! 587: if (stat(to, &statbuf) >= 0 && (statbuf.st_mode&S_IFDIR) != 0) { ! 588: fprintf(stderr, "Exotic destination %s\n", to); ! 589: goto badexit; ! 590: } ! 591: unlink(preptmp); ! 592: if ((fdout = fopen(preptmp, "w")) == NULL) { ! 593: perror("mail"); ! 594: goto badexit; ! 595: } ! 596: chmod(preptmp, MAILMODE); ! 597: if ((fdin = fopen(from, "r")) == NULL) { ! 598: perror("mail"); ! 599: goto badexit; ! 600: } ! 601: if(getput(fdin,fdout) == 0){ ! 602: perror("file i/o"); ! 603: goto badexit; ! 604: } ! 605: fclose(fdin); ! 606: fdin = fopen(to, "r"); ! 607: /* ignore error since may not exist */ ! 608: if(fdin != NULL && getput(fdin,fdout) == 0){ ! 609: perror("file i/o"); ! 610: goto badexit; ! 611: } ! 612: if(fdin != NULL)fclose(fdin); ! 613: fclose(fdout); ! 614: sig = signal(SIGINT, SIG_IGN); ! 615: remove(to); ! 616: if ((fdout = fopen(to, "w")) == NULL) { ! 617: perror(to); ! 618: unlink(preptmp); ! 619: signal(SIGINT, sig); ! 620: goto badexit; ! 621: } ! 622: # ifdef NOTROOT ! 623: if(uid != -1)chmod(to,0666); ! 624: # else ! 625: if(uid != -1)mchown(to, uid, gid); ! 626: # endif ! 627: if(stat(to, &statbuf) < 0 || statbuf.st_nlink != 1) { ! 628: fclose(fdout); ! 629: signal(SIGINT, sig); ! 630: goto badexit; ! 631: } ! 632: if ((fdin = fopen(preptmp, "r")) == NULL) { ! 633: perror("mail"); ! 634: signal(SIGINT, sig); ! 635: goto badexit; ! 636: } ! 637: ret = getput(fdin,fdout); ! 638: fclose(fdout); ! 639: fclose(fdin); ! 640: signal(SIGINT, sig); ! 641: return(ret); ! 642: badexit: ! 643: unlink(preptmp); ! 644: errs++; ! 645: return(0); ! 646: } ! 647: ! 648: delexit(ex) ! 649: { ! 650: unlink(lettmp); ! 651: unlink(preptmp); ! 652: exit(ex); ! 653: } ! 654: ! 655: /* return 1 if ok, 0 otherwise */ ! 656: getput(fdin, fdout) ! 657: register FILE *fdin, *fdout; ! 658: { ! 659: extern int errno; ! 660: register int c; ! 661: ! 662: while((c = getc(fdin)) != EOF) { ! 663: errno = 0; ! 664: putc(c,fdout); ! 665: if(errno) { ! 666: perror("mail"); ! 667: return(0); ! 668: } ! 669: } ! 670: return(1); ! 671: } ! 672: ! 673: accesss(s1) ! 674: register char *s1; ! 675: { ! 676: struct stat statbuf; ! 677: if(stat(s1,&statbuf)<0 || access(s1,2) == 0) ! 678: return(1); ! 679: return(0); ! 680: } ! 681: ! 682: any(c, str) ! 683: register char *str, c; ! 684: { ! 685: register char *f; ! 686: ! 687: f = str; ! 688: while (*f) ! 689: if (c == *f++) ! 690: return(1); ! 691: return(0); ! 692: } ! 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: /* ! 698: * Lock the specified mail file by setting the file mailfile.lock. ! 699: * We must, of course, be careful to unlink the lock file by a call ! 700: * to unlock before we stop. The algorithm used here is to see if ! 701: * the lock exists, and if it does, to check its modify time. If it ! 702: * is older than 30 seconds, we assume error and set our own file. ! 703: * Otherwise, we wait for 5 seconds and try again. ! 704: */ ! 705: ! 706: lock(file) ! 707: char *file; ! 708: { ! 709: register int f; ! 710: struct stat statbuf; ! 711: long curtime; ! 712: /* ! 713: if using OLDMAIL, and NOTROOT, cann't lock since can't necessarily ! 714: write on user's login directory ! 715: */ ! 716: # ifdef OLDMAIL ! 717: return; ! 718: # endif ! 719: ! 720: if (file == NULL) { ! 721: printf("Locked = %d\n", locked); ! 722: return(0); ! 723: } ! 724: if (locked) ! 725: return(0); ! 726: sprintf(curlock,"%s%s",file,".lock"); ! 727: sprintf(locktmp,"%s/tmXXXXXX",MAILDIR); ! 728: mktemp(locktmp); ! 729: unlink(locktmp); ! 730: for (;;) { ! 731: f = lock1(locktmp, curlock); ! 732: if (f == 0) { ! 733: locked = 1; ! 734: return(0); ! 735: } ! 736: if (stat(curlock, &statbuf) < 0) ! 737: return(0); ! 738: time(&curtime); ! 739: if (curtime < statbuf.st_mtime + 30) { ! 740: sleep(5); ! 741: continue; ! 742: } ! 743: unlink(curlock); ! 744: } ! 745: } ! 746: ! 747: /* ! 748: * Remove the mail lock, and note that we no longer ! 749: * have it locked. ! 750: */ ! 751: ! 752: unlock() ! 753: { ! 754: ! 755: if (locked) ! 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: int fno; ! 769: ! 770: fno = creat(tempfile, 0400); ! 771: if (fno < 0) ! 772: return(-1); ! 773: close(fno); ! 774: if (link(tempfile, name) < 0) { ! 775: unlink(tempfile); ! 776: return(-1); ! 777: } ! 778: unlink(tempfile); ! 779: return(0); ! 780: } ! 781: ! 782: /* ! 783: stripfx(prefix string, pointer to string) ! 784: ! 785: takes a ptr to string and compares it to prefix string. ! 786: may be called multiple times ! 787: returns ":username" ! 788: */ ! 789: stripfx(pfx, name) ! 790: register char *pfx; ! 791: register char **name; ! 792: { ! 793: register char *cp = *name; ! 794: ! 795: while (*pfx && (*cp == *pfx || *cp == toupper(*pfx))) ! 796: cp++, pfx++; ! 797: if (*cp != ':' || *pfx != 0) ! 798: return; ! 799: *name = cp; ! 800: } ! 801: stripmach(pperson) ! 802: register char **pperson; ! 803: { ! 804: # ifdef RAND ! 805: /* for machines at RAND */ ! 806: # ifdef GRAPHICS ! 807: stripfx("g",pperson); ! 808: stripfx("graphics",pperson); ! 809: # endif ! 810: # ifdef TP ! 811: stripfx("t",pperson); ! 812: stripfx("tp",pperson); ! 813: # endif ! 814: # ifdef VAX ! 815: stripfx("v",pperson); ! 816: stripfx("vax",pperson); ! 817: # endif ! 818: /* end of defns for Rand */ ! 819: # endif ! 820: ! 821: # ifdef NOSC ! 822: /* for machines at NOSC */ ! 823: # ifdef ATTS ! 824: stripfx("a",pperson); ! 825: stripfx("atts",pperson); ! 826: # endif ! 827: # ifdef CCMM ! 828: stripfx("c",pperson); ! 829: stripfx("ccmm",pperson); ! 830: # endif ! 831: # ifdef MSSF ! 832: stripfx("m",pperson); ! 833: stripfx("mssf",pperson); ! 834: # endif ! 835: /* end of defns for NOSC */ ! 836: # endif ! 837: ! 838: # ifdef BERKELEY ! 839: ! 840: /* for Berkeley */ ! 841: # ifdef A ! 842: stripfx("a",pperson); ! 843: # endif ! 844: # ifdef B ! 845: stripfx("b",pperson); ! 846: # endif ! 847: # ifdef C ! 848: stripfx("c",pperson); ! 849: # endif ! 850: # ifdef D ! 851: stripfx("d",pperson); ! 852: # endif ! 853: # ifdef E ! 854: stripfx("e",pperson); ! 855: # endif ! 856: # ifdef ING70 ! 857: stripfx("i",pperson); ! 858: stripfx("ing70",pperson); ! 859: stripfx("ingres",pperson); ! 860: # endif ! 861: # ifdef INGVAX ! 862: stripfx("j",pperson); ! 863: stripfx("ingvax",pperson); ! 864: # endif ! 865: # ifdef VIRUS ! 866: stripfx("k",pperson); ! 867: stripfx("virus",pperson); ! 868: # endif ! 869: # ifdef IMAGE ! 870: stripfx("m",pperson); ! 871: stripfx("image",pperson); ! 872: # endif ! 873: # ifdef KIM ! 874: stripfx("n",pperson); ! 875: stripfx("kim",pperson); ! 876: # endif ! 877: # ifdef ESVAX ! 878: stripfx("o",pperson); ! 879: stripfx("esvax",pperson); ! 880: # endif ! 881: # ifdef Q ! 882: stripfx("q",pperson); ! 883: # endif ! 884: # ifdef ARPAVAX ! 885: stripfx("r",pperson); ! 886: stripfx("arpavax",pperson); ! 887: # endif ! 888: # ifdef SRC ! 889: stripfx("s",pperson); ! 890: stripfx("src",pperson); ! 891: # endif ! 892: # ifdef MATHSTAT ! 893: stripfx("t",pperson); ! 894: stripfx("mathstat",pperson); ! 895: # endif ! 896: # ifdef CSVAX ! 897: stripfx("v",pperson); ! 898: stripfx("vax",pperson); ! 899: stripfx("csvax",pperson); ! 900: # endif ! 901: # ifdef CORY ! 902: stripfx("y",pperson); ! 903: stripfx("cory",pperson); ! 904: # endif ! 905: # ifdef EECS40 ! 906: stripfx("z",pperson); ! 907: stripfx("eecs40",pperson); ! 908: # endif ! 909: /* end of berkeley defns */ ! 910: # endif ! 911: } ! 912: /* ! 913: this removes the mail file sfn by either truncating it, as required ! 914: on OLDMAIL systems, or unlinking it. If the unlink fails, we truncate it. ! 915: */ ! 916: remove(sfn) ! 917: char *sfn; ! 918: { ! 919: int i; ! 920: # ifdef OLDMAIL ! 921: i = creat(sfn,0666); ! 922: if(i >= 0)close(i); ! 923: # else ! 924: if(unlink(sfn) < 0){ ! 925: i = creat(sfn,MAILMODE); ! 926: if(i >= 0)close(i); ! 927: } ! 928: # endif ! 929: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.