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