1: #ifndef lint
   2: static char sccsid[] = "@(#)mail.c	4.18 (Berkeley) 9/9/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 <whoami.h>
  14: #include <sysexits.h>
  15: 
  16: #define DELIVERMAIL "/etc/delivermail"
  17: 
  18: 
  19: /*copylet flags */
  20:     /*remote mail, add rmtmsg */
  21: #define REMOTE  1
  22:     /* zap header and trailing empty line */
  23: #define ZAP 3
  24: #define ORDINARY 2
  25: #define FORWARD 4
  26: #define LSIZE   256
  27: #define MAXLET  300 /* maximum number of letters */
  28: #define MAILMODE (~0600)        /* mode of created mail */
  29: # ifndef DELIVERMAIL
  30: #define MSGS    "/usr/ucb/msgs"
  31: #define RMAIL   "/usr/net/bin/sendberkmail"
  32: #define LOCNAM1 "csvax"
  33: #define LOCNAM2 "ucbvax"
  34: #define LOCNAM3 "vax"
  35: #define LOCNAM4 "v"
  36: # endif
  37: 
  38: char    line[LSIZE];
  39: char    resp[LSIZE];
  40: struct let {
  41:     long    adr;
  42:     char    change;
  43: } let[MAXLET];
  44: int nlet    = 0;
  45: char    lfil[50];
  46: long    iop, time();
  47: char    *getenv();
  48: char    *index();
  49: char    lettmp[] = "/tmp/maXXXXX";
  50: char    maildir[] = "/usr/spool/mail/";
  51: char    mailfile[] = "/usr/spool/mail/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
  52: char    dead[] = "dead.letter";
  53: char    forwmsg[] = " forwarded\n";
  54: FILE    *tmpf;
  55: FILE    *malf;
  56: char    *my_name;
  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: char    hostname[32];
  72: 
  73: main(argc, argv)
  74: char **argv;
  75: {
  76:     register i;
  77:     char sobuf[BUFSIZ];
  78: 
  79:     setbuf(stdout, sobuf);
  80:     mktemp(lettmp);
  81:     unlink(lettmp);
  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 = SIGHUP; i <= SIGTERM; 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;
 372:     long    k;
 373:     fseek(tmpf, let[n].adr, 0);
 374:     k = let[n+1].adr - let[n].adr;
 375:     while(k-- > 1L && (ch=fgetc(tmpf))!='\n')
 376:         if(type!=ZAP) fputc(ch,f);
 377:     if(type==REMOTE) {
 378:         gethostname(hostname, sizeof (hostname));
 379:         fprintf(f, " remote from %s\n", hostname);
 380:     }
 381:     else if (type==FORWARD)
 382:         fprintf(f, forwmsg);
 383:     else if(type==ORDINARY)
 384:         fputc(ch,f);
 385:     while(k-->1L)
 386:         fputc(ch=fgetc(tmpf), f);
 387:     if(type!=ZAP || ch!= '\n')
 388:         fputc(fgetc(tmpf), f);
 389: }
 390: 
 391: isfrom(lp)
 392: register char *lp;
 393: {
 394:     register char *p;
 395: 
 396:     for (p = from; *p; )
 397:         if (*lp++ != *p++)
 398:             return(0);
 399:     return(1);
 400: }
 401: 
 402: sendmail(argc, argv)
 403: char **argv;
 404: {
 405:     char truename[100];
 406:     int first;
 407:     register char *cp;
 408:     int gaver = 0;
 409: # ifdef DELIVERMAIL
 410:     char *newargv[1000];
 411:     register char **ap;
 412:     register char **vp;
 413:     int dflag;
 414: 
 415:     dflag = 0;
 416:     if (argc < 1)
 417:         fprintf(stderr, "puke\n");
 418:     for (vp = argv, ap = newargv + 1; (*ap = *vp++) != 0; ap++)
 419:     {
 420:         if (ap[0][0] == '-' && ap[0][1] == 'd')
 421:             dflag++;
 422:     }
 423:     if (!dflag)
 424:     {
 425:         /* give it to delivermail, rah rah! */
 426:         unlink(lettmp);
 427:         ap = newargv+1;
 428:         if (rmail)
 429:             *ap-- = "-s";
 430:         *ap = "-delivermail";
 431:         execv(DELIVERMAIL, ap);
 432:         perror(DELIVERMAIL);
 433:         exit(EX_UNAVAILABLE);
 434:     }
 435: # endif DELIVERMAIL
 436: 
 437:     truename[0] = 0;
 438:     line[0] = '\0';
 439: 
 440:     /*
 441: 	 * When we fall out of this, argv[1] should be first name,
 442: 	 * argc should be number of names + 1.
 443: 	 */
 444: 
 445:     while (argc > 1 && *argv[1] == '-') {
 446:         cp = *++argv;
 447:         argc--;
 448:         switch (cp[1]) {
 449:         case 'r':
 450:             if (argc <= 0) {
 451:                 usage();
 452:                 done();
 453:             }
 454:             if (strcmp(my_name, "root") &&
 455:                 strcmp(my_name, "daemon") &&
 456:                 strcmp(my_name, "uucp") &&
 457:                 strcmp(my_name, "network")) {
 458:                 usage();
 459:                 done();
 460:             }
 461:             gaver++;
 462:             strcpy(truename, argv[1]);
 463:             fgets(line, LSIZE, stdin);
 464:             if (strncmp("From", line, 4) == 0)
 465:                 line[0] = '\0';
 466:             argv++;
 467:             argc--;
 468:             break;
 469: 
 470:         case 'h':
 471:             if (argc <= 0) {
 472:                 usage();
 473:                 done();
 474:             }
 475:             hseqno = atoi(argv[1]);
 476:             argv++;
 477:             argc--;
 478:             break;
 479: 
 480: # ifdef DELIVERMAIL
 481:         case 'd':
 482:             break;
 483: # endif DELIVERMAIL
 484: 
 485:         default:
 486:             usage();
 487:             done();
 488:         }
 489:     }
 490:     if (argc <= 1) {
 491:         usage();
 492:         done();
 493:     }
 494:     if (gaver == 0)
 495:         strcpy(truename, my_name);
 496:     /*
 497: 	if (argc > 4 && strcmp(argv[1], "-r") == 0) {
 498: 		strcpy(truename, argv[2]);
 499: 		argc -= 2;
 500: 		argv += 2;
 501: 		fgets(line, LSIZE, stdin);
 502: 		if (strncmp("From", line, 4) == 0)
 503: 			line[0] = '\0';
 504: 	} else
 505: 		strcpy(truename, my_name);
 506: 	*/
 507:     time(&iop);
 508:     fprintf(tmpf, "%s%s %s", from, truename, ctime(&iop));
 509:     iop = ftell(tmpf);
 510:     flgf = 1;
 511:     for (first = 1;; first = 0) {
 512:         if (first && line[0] == '\0' && fgets(line, LSIZE, stdin) == NULL)
 513:             break;
 514:         if (!first && fgets(line, LSIZE, stdin) == NULL)
 515:             break;
 516:         if (line[0] == '.' && line[1] == '\n' && isatty(fileno(stdin)))
 517:             break;
 518:         if (isfrom(line))
 519:             fputs(">", tmpf);
 520:         fputs(line, tmpf);
 521:         flgf = 0;
 522:     }
 523:     fputs("\n", tmpf);
 524:     nlet = 1;
 525:     let[0].adr = 0;
 526:     let[1].adr = ftell(tmpf);
 527:     fclose(tmpf);
 528:     if (flgf)
 529:         return;
 530:     tmpf = fopen(lettmp, "r");
 531:     if (tmpf == NULL) {
 532:         fprintf(stderr, "mail: cannot reopen %s for reading\n", lettmp);
 533:         return;
 534:     }
 535:     while (--argc > 0)
 536:         if (!send(0, *++argv, truename))
 537:             error++;
 538:     if (error && safefile(dead)) {
 539:         setuid(getuid());
 540:         malf = fopen(dead, "w");
 541:         if (malf == NULL) {
 542:             fprintf(stdout, "mail: cannot open %s\n", dead);
 543:             fclose(tmpf);
 544:             return;
 545:         }
 546:         copylet(0, malf, ZAP);
 547:         fclose(malf);
 548:         fprintf(stdout, "Mail saved in %s\n", dead);
 549:     }
 550:     fclose(tmpf);
 551: }
 552: 
 553: sendrmt(n, name, rcmd)
 554: char *name;
 555: char *rcmd;
 556: {
 557:     FILE *rmf, *popen();
 558:     register char *p;
 559:     char rsys[64], cmd[64];
 560:     register local, pid;
 561:     int ret, sts;
 562: 
 563:     local = 0;
 564:     if (index(name, '^')) {
 565:         while (p = index(name, '^'))
 566:             *p = '!';
 567:         if (strncmp(name, "researc", 7)) {
 568:             strcpy(rsys, "research");
 569:             if (*name != '!')
 570:                 --name;
 571:             goto skip;
 572:         }
 573:     }
 574:     if (*name=='!')
 575:         name++;
 576:     for(p=rsys; *name!='!'; *p++ = *name++)
 577:         if (*name=='\0') {
 578:             local++;
 579:             break;
 580:         }
 581:     *p = '\0';
 582:     if ((!local && *name=='\0') || (local && *rsys=='\0')) {
 583:         fprintf(stdout, "null name\n");
 584:         return(0);
 585:     }
 586: skip:
 587:     if ((pid = fork()) == -1) {
 588:         fprintf(stderr, "mail: can't create proc for remote\n");
 589:         return(0);
 590:     }
 591:     if (pid) {
 592:         while ((ret = wait(&sts)) != pid) {
 593:             if (ret == -1)
 594:                 return(0);
 595:         }
 596:         return(!sts);
 597:     }
 598:     setuid(getuid());
 599:     if (local)
 600:         sprintf(cmd, "%s %s", rcmd, rsys);
 601:     else {
 602:         if (index(name+1, '!'))
 603:             sprintf(cmd, "uux - %s!rmail \\(%s\\)", rsys, name+1);
 604:         else
 605:             sprintf(cmd, "uux - %s!rmail %s", rsys, name+1);
 606:     }
 607:     if ((rmf=popen(cmd, "w")) == NULL)
 608:         exit(1);
 609:     copylet(n, rmf, local ? (!strcmp(rcmd, "/bin/mail") ? FORWARD : ORDINARY) : REMOTE);
 610:     exit(pclose(rmf) != 0);
 611: }
 612: 
 613: # ifndef DELIVERMAIL
 614: /*
 615:  * Send mail on the Berkeley network.
 616:  * Sorry Bill, sendrmt() is so awful we just gave up.
 617:  */
 618: 
 619: sendberkmail(n, name, fromaddr)
 620:     char name[];
 621:     char fromaddr[];
 622: {
 623:     char cmd[200];
 624:     register FILE *cmdf;
 625: 
 626:     sprintf(cmd, "%s -h %d -f %s -t %s", RMAIL, hseqno, fromaddr, name);
 627:     if ((cmdf = popen(cmd, "w")) == NULL) {
 628:         perror(RMAIL);
 629:         return(0);
 630:     }
 631:     copylet(n, cmdf, ORDINARY);
 632:     pclose(cmdf);
 633:     return(9);
 634: }
 635: # endif
 636: 
 637: usage()
 638: {
 639:     fprintf(stderr, "Usage: mail [ -f ] people . . .\n");
 640:     error = EX_USAGE;
 641: }
 642: 
 643: send(n, name, fromaddr)
 644: int n;
 645: char *name;
 646: char *fromaddr;
 647: {
 648:     char file[100];
 649:     register char *p;
 650:     register mask;
 651:     struct passwd *pw, *getpwnam();
 652:     struct stat statb;
 653: 
 654: # ifndef DELIVERMAIL
 655:     stripfx(LOCNAM1, &name);
 656:     stripfx(LOCNAM2, &name);
 657:     stripfx(LOCNAM3, &name);
 658:     stripfx(LOCNAM4, &name);
 659:     if(*name == ':')
 660:         name++;     /* skip colon in to-name */
 661:     for(p=name; *p!=':' && *p!='!' && *p!='^' &&*p!='\0'; p++)
 662:         ;
 663:     /* if(*p == ':') return(sendrmt(n, name, RMAIL)); */
 664:     if (*p == ':')
 665:         return(sendberkmail(n, name, fromaddr));
 666:     else if (*p=='\0' && strcmp(name, "msgs") == 0)
 667:         return(sendrmt(n, "-s", MSGS));
 668: # endif
 669:     for(p=name; *p!='!'&&*p!='^' &&*p!='\0'; p++)
 670:         ;
 671:     if (*p == '!'|| *p=='^')
 672:         return(sendrmt(n, name, 0));
 673:     if ((pw = getpwnam(name)) == NULL) {
 674:         fprintf(stdout, "mail: can't send to %s\n", name);
 675:         return(0);
 676:     }
 677:     cat(file, maildir, name);
 678:     if (stat(file, &statb) >= 0 && (statb.st_mode & S_IFMT) == S_IFDIR) {
 679:         strcat(file, "/");
 680:         strcat(file, name);
 681:     }
 682:     mask = umask(MAILMODE);
 683:     if (!safefile(file))
 684:         return(0);
 685:     lock(file);
 686:     malf = fopen(file, "a");
 687:     umask(mask);
 688:     if (malf == NULL) {
 689:         unlock();
 690:         fprintf(stdout, "mail: cannot append to %s\n", file);
 691:         return(0);
 692:     }
 693:     chown(file, pw->pw_uid, pw->pw_gid);
 694:     copylet(n, malf, ORDINARY);
 695:     fclose(malf);
 696:     unlock();
 697:     return(1);
 698: }
 699: 
 700: delete(i)
 701: {
 702:     setsig(i, delete);
 703:     fprintf(stderr, "\n");
 704:     if(delflg)
 705:         longjmp(sjbuf, 1);
 706:     done();
 707: }
 708: 
 709: /*
 710:  * Lock the specified mail file by setting the file mailfile.lock.
 711:  * We must, of course, be careful to unlink the lock file by a call
 712:  * to unlock before we stop.  The algorithm used here is to see if
 713:  * the lock exists, and if it does, to check its modify time.  If it
 714:  * is older than 30 seconds, we assume error and set our own file.
 715:  * Otherwise, we wait for 5 seconds and try again.
 716:  */
 717: 
 718: char    *maillock   = ".lock";      /* Lock suffix for mailname */
 719: char    *lockname   = "/usr/spool/mail/tmXXXXXX";
 720: char    locktmp[30];                /* Usable lock temporary */
 721: char    curlock[50];                /* Last used name of lock */
 722: int locked;                 /* To note that we locked it */
 723: 
 724: lock(file)
 725: char *file;
 726: {
 727:     register int f;
 728:     struct stat sbuf;
 729:     long curtime;
 730:     int statfailed;
 731: 
 732:     if (locked || flgf)
 733:         return(0);
 734:     strcpy(curlock, file);
 735:     strcat(curlock, maillock);
 736:     strcpy(locktmp, lockname);
 737:     mktemp(locktmp);
 738:     unlink(locktmp);
 739:     statfailed = 0;
 740:     for (;;) {
 741:         f = lock1(locktmp, curlock);
 742:         if (f == 0) {
 743:             locked = 1;
 744:             return(0);
 745:         }
 746:         if (stat(curlock, &sbuf) < 0) {
 747:             if (statfailed++ > 5)
 748:                 return(-1);
 749:             sleep(5);
 750:             continue;
 751:         }
 752:         statfailed = 0;
 753:         time(&curtime);
 754:         if (curtime < sbuf.st_ctime + 30) {
 755:             sleep(5);
 756:             continue;
 757:         }
 758:         unlink(curlock);
 759:     }
 760: }
 761: 
 762: /*
 763:  * Remove the mail lock, and note that we no longer
 764:  * have it locked.
 765:  */
 766: 
 767: unlock()
 768: {
 769: 
 770:     unlink(curlock);
 771:     locked = 0;
 772: }
 773: 
 774: /*
 775:  * Attempt to set the lock by creating the temporary file,
 776:  * then doing a link/unlink.  If it fails, return -1 else 0
 777:  */
 778: 
 779: lock1(tempfile, name)
 780:     char tempfile[], name[];
 781: {
 782:     register int fd;
 783: 
 784:     fd = creat(tempfile, 0);
 785:     if (fd < 0)
 786:         return(-1);
 787:     close(fd);
 788:     if (link(tempfile, name) < 0) {
 789:         unlink(tempfile);
 790:         return(-1);
 791:     }
 792:     unlink(tempfile);
 793:     return(0);
 794: }
 795: 
 796: done()
 797: {
 798:     if(locked)
 799:         unlock();
 800:     unlink(lettmp);
 801:     unlink(locktmp);
 802:     exit(error);
 803: }
 804: 
 805: cat(to, from1, from2)
 806: char *to, *from1, *from2;
 807: {
 808:     int i, j;
 809: 
 810:     j = 0;
 811:     for (i=0; from1[i]; i++)
 812:         to[j++] = from1[i];
 813:     for (i=0; from2[i]; i++)
 814:         to[j++] = from2[i];
 815:     to[j] = 0;
 816: }
 817: 
 818: char *getarg(s, p)  /* copy p... into s, update p */
 819: register char *s, *p;
 820: {
 821:     while (*p == ' ' || *p == '\t')
 822:         p++;
 823:     if (*p == '\n' || *p == '\0')
 824:         return(NULL);
 825:     while (*p != ' ' && *p != '\t' && *p != '\n' && *p != '\0')
 826:         *s++ = *p++;
 827:     *s = '\0';
 828:     return(p);
 829: }
 830: # ifndef DELIVERMAIL
 831: /*
 832: 	stripfx(prefix string, pointer to string)
 833: 
 834: 	takes a ptr to string and compares it to prefix string.
 835: 	may be called multiple times
 836: */
 837: stripfx(pfx, name)
 838:     char *pfx;
 839:     char **name;
 840: {
 841:     register char *cp = *name;
 842: 
 843:     while (*pfx && (*cp == *pfx || *cp == toupper(*pfx)))
 844:         cp++, pfx++;
 845:     if (*cp != ':' || *pfx != 0)
 846:         return;
 847:     *name = cp;
 848: }
 849: # endif
 850: 
 851: safefile(f)
 852:     char *f;
 853: {
 854:     struct stat statb;
 855: 
 856: #ifdef  UCB_SYMLINKS
 857:     if (lstat(f, &statb) < 0)
 858: #else
 859:     if (stat(f, &statb) < 0)
 860: #endif
 861:         return(1);
 862:     if (statb.st_nlink != 1 || (statb.st_mode & S_IFMT) == S_IFLNK) {
 863:         fprintf(stderr, "mail:  %s has more than one link or is a symbolic link\n", f);
 864:         return(0);
 865:     }
 866:     return(1);
 867: }

Defined functions

any defined in line 116; used 1 times
cat defined in line 805; used 4 times
copyback defined in line 308; used 1 times
copylet defined in line 370; used 7 times
copymt defined in line 354; used 1 times
delete defined in line 700; used 3 times
done defined in line 796; used 12 times
getarg defined in line 818; used 3 times
isfrom defined in line 391; used 2 times
lock defined in line 724; used 3 times
lock1 defined in line 779; used 1 times
main defined in line 73; never used
printmail defined in line 127; used 1 times
safefile defined in line 851; used 2 times
send defined in line 643; used 1 times
sendberkmail defined in line 619; used 1 times
sendmail defined in line 402; used 1 times
sendrmt defined in line 553; used 3 times
setsig defined in line 108; used 2 times
stripfx defined in line 837; used 4 times
unlock defined in line 767; used 5 times
usage defined in line 637; used 5 times

Defined variables

changed defined in line 59; used 6 times
curlock defined in line 721; used 6 times
dead defined in line 52; used 4 times
delflg defined in line 67; used 3 times
error defined in line 58; used 4 times
flgf defined in line 65; used 4 times
flgp defined in line 66; used 2 times
forward defined in line 60; used 3 times
forwmsg defined in line 53; used 1 times
from defined in line 61; used 2 times
hostname defined in line 71; used 3 times
hseqno defined in line 68; used 2 times
iop defined in line 46; used 3 times
let defined in line 43; used 16 times
lettmp defined in line 49; used 11 times
lfil defined in line 45; used 6 times
line defined in line 38; used 15 times
locked defined in line 722; used 4 times
lockname defined in line 719; used 1 times
locktmp defined in line 720; used 5 times
maildir defined in line 50; used 2 times
mailfile defined in line 51; used 12 times
maillock defined in line 718; used 1 times
my_name defined in line 56; used 11 times
nlet defined in line 44; used 11 times
resp defined in line 39; used 16 times
rmail defined in line 70; used 2 times
sccsid defined in line 2; never used
sjbuf defined in line 69; used 4 times

Defined struct's

let defined in line 40; never used

Defined macros

DELIVERMAIL defined in line 16; used 8 times
FORWARD defined in line 25; used 2 times
LOCNAM1 defined in line 32; used 1 times
LOCNAM2 defined in line 33; used 1 times
LOCNAM3 defined in line 34; used 1 times
LOCNAM4 defined in line 35; used 1 times
LSIZE defined in line 26; used 7 times
MAILMODE defined in line 28; used 1 times
MAXLET defined in line 27; used 1 times
  • in line 43
MSGS defined in line 30; used 1 times
ORDINARY defined in line 24; used 7 times
REMOTE defined in line 21; used 2 times
RMAIL defined in line 31; used 2 times
ZAP defined in line 23; used 4 times
Last modified: 1983-11-21
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: ?E00
Valid CSS Valid XHTML 1.0 Strict