1: /*
   2:  * Copyright (c) 1980 Regents of the University of California.
   3:  * All rights reserved.  The Berkeley software License Agreement
   4:  * specifies the terms and conditions for redistribution.
   5:  */
   6: 
   7: #ifndef lint
   8: char copyright[] =
   9: "@(#) Copyright (c) 1980 Regents of the University of California.\n\
  10:  All rights reserved.\n";
  11: #endif not lint
  12: 
  13: #ifndef lint
  14: static char sccsid[] = "@(#)msgs.c	5.2 (Berkeley) 4/10/86";
  15: #endif not lint
  16: 
  17: /*
  18:  * msgs - a user bulletin board program
  19:  *
  20:  * usage:
  21:  *	msgs [fhlopq] [[-]number]	to read messages
  22:  *	msgs -s				to place messages
  23:  *	msgs -c [-days]			to clean up the bulletin board
  24:  *
  25:  * prompt commands are:
  26:  *	y	print message
  27:  *	n	flush message, go to next message
  28:  *	q	flush message, quit
  29:  *	p	print message, turn on 'pipe thru more' mode
  30:  *	P	print message, turn off 'pipe thru more' mode
  31:  *	-	reprint last message
  32:  *	s[-][<num>] [<filename>]	save message
  33:  *	m[-][<num>]	mail with message in temp mbox
  34:  *	x	exit without flushing this message
  35:  *	<num>	print message number <num>
  36:  */
  37: 
  38: #define V7      /* will look for TERM in the environment */
  39: #define OBJECT      /* will object to messages without Subjects */
  40: /* #define REJECT	/* will reject messages without Subjects
  41: 			   (OBJECT must be defined also) */
  42: /* #define UNBUFFERED	/* use unbuffered output */
  43: 
  44: #include <stdio.h>
  45: #include <sys/param.h>
  46: #include <signal.h>
  47: #include <sys/dir.h>
  48: #include <sys/stat.h>
  49: #include <ctype.h>
  50: #include <pwd.h>
  51: #include <sgtty.h>
  52: #include <setjmp.h>
  53: #include "msgs.h"
  54: 
  55: #define CMODE   0666        /* bounds file creation mode */
  56: #define NO  0
  57: #define YES 1
  58: #define SUPERUSER   0   /* superuser uid */
  59: #define DAEMON      1   /* daemon uid */
  60: #define NLINES  24      /* default number of lines/crt screen */
  61: #define NDAYS   21      /* default keep time for messages */
  62: #define DAYS    *24L*60L*60L    /* seconds/day */
  63: #define TEMP    "/tmp/msgXXXXXX"
  64: #define MSGSRC  ".msgsrc"   /* user's rc file */
  65: #define BOUNDS  "bounds"    /* message bounds file */
  66: #define NEXT    "Next message? [yq]"
  67: #define MORE    "More? [ynq]"
  68: #define NOMORE  "(No more) [q] ?"
  69: 
  70: typedef char    bool;
  71: 
  72: FILE    *newmsg;
  73: char    *sep = "-";
  74: char    inbuf[BUFSIZ];
  75: char    fname[128];
  76: char    cmdbuf[128];
  77: char    subj[128];
  78: char    from[128];
  79: char    date[128];
  80: char    *ptr;
  81: char    *in;
  82: bool    local;
  83: bool    ruptible;
  84: bool    totty;
  85: bool    seenfrom;
  86: bool    seensubj;
  87: bool    blankline;
  88: bool    printing = NO;
  89: bool    mailing = NO;
  90: bool    quitit = NO;
  91: bool    sending = NO;
  92: bool    intrpflg = NO;
  93: bool    tstpflag = NO;
  94: int uid;
  95: int msg;
  96: int prevmsg;
  97: int lct;
  98: int nlines;
  99: int Lpp = 0;
 100: time_t  t;
 101: time_t  keep;
 102: struct  sgttyb  otty;
 103: 
 104: char    *ctime();
 105: char    *nxtfld();
 106: int onintr();
 107: int onsusp();
 108: off_t   ftell();
 109: FILE    *popen();
 110: struct  passwd  *getpwuid();
 111: 
 112: extern  int errno;
 113: 
 114: /* option initialization */
 115: bool    hdrs = NO;
 116: bool    qopt = NO;
 117: bool    hush = NO;
 118: bool    send = NO;
 119: bool    locomode = NO;
 120: bool    pause = NO;
 121: bool    clean = NO;
 122: bool    lastcmd = NO;
 123: jmp_buf tstpbuf;
 124: 
 125: main(argc, argv)
 126: int argc; char *argv[];
 127: {
 128:     bool newrc, already;
 129:     int rcfirst = 0;        /* first message to print (from .rc) */
 130:     int rcback = 0;         /* amount to back off of rcfirst */
 131:     int firstmsg, nextmsg, lastmsg = 0;
 132:     int blast = 0;
 133:     FILE *bounds, *msgsrc;
 134: 
 135: #ifdef UNBUFFERED
 136:     setbuf(stdout, NULL);
 137: #endif
 138: 
 139:     gtty(fileno(stdout), &otty);
 140:     time(&t);
 141:     setuid(uid = getuid());
 142:     ruptible = (signal(SIGINT, SIG_IGN) == SIG_DFL);
 143:     if (ruptible)
 144:         signal(SIGINT, SIG_DFL);
 145: 
 146:     argc--, argv++;
 147:     while (argc > 0) {
 148:         if (isdigit(argv[0][0])) {  /* starting message # */
 149:             rcfirst = atoi(argv[0]);
 150:         }
 151:         else if (isdigit(argv[0][1])) { /* backward offset */
 152:             rcback = atoi( &( argv[0][1] ) );
 153:         }
 154:         else {
 155:             ptr = *argv;
 156:             while (*ptr) switch (*ptr++) {
 157: 
 158:             case '-':
 159:                 break;
 160: 
 161:             case 'c':
 162:                 if (uid != SUPERUSER && uid != DAEMON) {
 163:                     fprintf(stderr, "Sorry\n");
 164:                     exit(1);
 165:                 }
 166:                 clean = YES;
 167:                 break;
 168: 
 169:             case 'f':       /* silently */
 170:                 hush = YES;
 171:                 break;
 172: 
 173:             case 'h':       /* headers only */
 174:                 hdrs = YES;
 175:                 break;
 176: 
 177:             case 'l':       /* local msgs only */
 178:                 locomode = YES;
 179:                 break;
 180: 
 181:             case 'o':       /* option to save last message */
 182:                 lastcmd = YES;
 183:                 break;
 184: 
 185:             case 'p':       /* pipe thru 'more' during long msgs */
 186:                 pause = YES;
 187:                 break;
 188: 
 189:             case 'q':       /* query only */
 190:                 qopt = YES;
 191:                 break;
 192: 
 193:             case 's':       /* sending TO msgs */
 194:                 send = YES;
 195:                 break;
 196: 
 197:             default:
 198:                 fprintf(stderr,
 199:                     "usage: msgs [fhlopq] [[-]number]\n");
 200:                 exit(1);
 201:             }
 202:         }
 203:         argc--, argv++;
 204:     }
 205: 
 206:     /*
 207: 	 * determine current message bounds
 208: 	 */
 209:     sprintf(fname, "%s/%s", USRMSGS, BOUNDS);
 210:     bounds = fopen(fname, "r");
 211: 
 212:     if (bounds != NULL) {
 213:         fscanf(bounds, "%d %d\n", &firstmsg, &lastmsg);
 214:         fclose(bounds);
 215:         blast = lastmsg;    /* save upper bound */
 216:     }
 217: 
 218:     if (clean)
 219:         keep = t - (rcback? rcback : NDAYS) DAYS;
 220: 
 221:     if (clean || bounds == NULL) {  /* relocate message bounds */
 222:         struct direct *dp;
 223:         struct stat stbuf;
 224:         bool seenany = NO;
 225:         DIR *dirp;
 226: 
 227:         dirp = opendir(USRMSGS);
 228:         if (dirp == NULL) {
 229:             perror(USRMSGS);
 230:             exit(errno);
 231:         }
 232: 
 233:         firstmsg = 32767;
 234:         lastmsg = 0;
 235: 
 236:         for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)){
 237:             register char *cp = dp->d_name;
 238:             register int i = 0;
 239: 
 240:             if (dp->d_ino == 0)
 241:                 continue;
 242:             if (dp->d_namlen == 0)
 243:                 continue;
 244: 
 245:             if (clean)
 246:                 sprintf(inbuf, "%s/%s", USRMSGS, cp);
 247: 
 248:             while (isdigit(*cp))
 249:                 i = i * 10 + *cp++ - '0';
 250:             if (*cp)
 251:                 continue;   /* not a message! */
 252: 
 253:             if (clean) {
 254:                 if (stat(inbuf, &stbuf) != 0)
 255:                     continue;
 256:                 if (stbuf.st_mtime < keep
 257:                     && stbuf.st_mode&S_IWRITE) {
 258:                     unlink(inbuf);
 259:                     continue;
 260:                 }
 261:             }
 262: 
 263:             if (i > lastmsg)
 264:                 lastmsg = i;
 265:             if (i < firstmsg)
 266:                 firstmsg = i;
 267:             seenany = YES;
 268:         }
 269:         closedir(dirp);
 270: 
 271:         if (!seenany) {
 272:             if (blast != 0) /* never lower the upper bound! */
 273:                 lastmsg = blast;
 274:             firstmsg = lastmsg + 1;
 275:         }
 276:         else if (blast > lastmsg)
 277:             lastmsg = blast;
 278: 
 279:         if (!send) {
 280:             bounds = fopen(fname, "w");
 281:             if (bounds == NULL) {
 282:                 perror(fname);
 283:                 exit(errno);
 284:             }
 285:             chmod(fname, CMODE);
 286:             fprintf(bounds, "%d %d\n", firstmsg, lastmsg);
 287:             fclose(bounds);
 288:         }
 289:     }
 290: 
 291:     if (send) {
 292:         /*
 293: 		 * Send mode - place msgs in USRMSGS
 294: 		 */
 295:         bounds = fopen(fname, "w");
 296:         if (bounds == NULL) {
 297:             perror(fname);
 298:             exit(errno);
 299:         }
 300: 
 301:         nextmsg = lastmsg + 1;
 302:         sprintf(fname, "%s/%d", USRMSGS, nextmsg);
 303:         newmsg = fopen(fname, "w");
 304:         if (newmsg == NULL) {
 305:             perror(fname);
 306:             exit(errno);
 307:         }
 308:         chmod(fname, 0644);
 309: 
 310:         fprintf(bounds, "%d %d\n", firstmsg, nextmsg);
 311:         fclose(bounds);
 312: 
 313:         sending = YES;
 314:         if (ruptible)
 315:             signal(SIGINT, onintr);
 316: 
 317:         if (isatty(fileno(stdin))) {
 318:             ptr = getpwuid(uid)->pw_name;
 319:             printf("Message %d:\nFrom %s %sSubject: ",
 320:                 nextmsg, ptr, ctime(&t));
 321:             fflush(stdout);
 322:             fgets(inbuf, sizeof inbuf, stdin);
 323:             putchar('\n');
 324:             fflush(stdout);
 325:             fprintf(newmsg, "From %s %sSubject: %s\n",
 326:                 ptr, ctime(&t), inbuf);
 327:             blankline = seensubj = YES;
 328:         }
 329:         else
 330:             blankline = seensubj = NO;
 331:         for (;;) {
 332:             fgets(inbuf, sizeof inbuf, stdin);
 333:             if (feof(stdin) || ferror(stdin))
 334:                 break;
 335:             blankline = (blankline || (inbuf[0] == '\n'));
 336:             seensubj = (seensubj || (!blankline && (strncmp(inbuf, "Subj", 4) == 0)));
 337:             fputs(inbuf, newmsg);
 338:         }
 339: #ifdef OBJECT
 340:         if (!seensubj) {
 341:             printf("NOTICE: Messages should have a Subject field!\n");
 342: #ifdef REJECT
 343:             unlink(fname);
 344: #endif
 345:             exit(1);
 346:         }
 347: #endif
 348:         exit(ferror(stdin));
 349:     }
 350:     if (clean)
 351:         exit(0);
 352: 
 353:     /*
 354: 	 * prepare to display messages
 355: 	 */
 356:     totty = (isatty(fileno(stdout)) != 0);
 357:     pause = pause && totty;
 358: 
 359:     sprintf(fname, "%s/%s", getenv("HOME"), MSGSRC);
 360:     msgsrc = fopen(fname, "r");
 361:     if (msgsrc) {
 362:         newrc = NO;
 363:         fscanf(msgsrc, "%d\n", &nextmsg);
 364:         fclose(msgsrc);
 365:         if (nextmsg > lastmsg+1) {
 366:             printf("Warning: bounds have been reset (%d, %d)\n",
 367:                 firstmsg, lastmsg);
 368:             ftruncate(fileno(msgsrc), 0L);
 369:             newrc = YES;
 370:         }
 371:         else if (!rcfirst)
 372:             rcfirst = nextmsg - rcback;
 373:     }
 374:     else
 375:         newrc = YES;
 376:     msgsrc = fopen(fname, "a");
 377:     if (msgsrc == NULL) {
 378:         perror(fname);
 379:         exit(errno);
 380:     }
 381:     if (rcfirst) {
 382:         if (rcfirst > lastmsg+1) {
 383:             printf("Warning: the last message is number %d.\n",
 384:                 lastmsg);
 385:             rcfirst = nextmsg;
 386:         }
 387:         if (rcfirst > firstmsg)
 388:             firstmsg = rcfirst; /* don't set below first msg */
 389:     }
 390:     if (newrc) {
 391:         nextmsg = firstmsg;
 392:         fseek(msgsrc, 0L, 0);
 393:         fprintf(msgsrc, "%d\n", nextmsg);
 394:         fflush(msgsrc);
 395:     }
 396: 
 397: #ifdef V7
 398:     if (totty) {
 399:         struct winsize win;
 400:         if (ioctl(fileno(stdout), TIOCGWINSZ, &win) != -1)
 401:             Lpp = win.ws_row;
 402:         if (Lpp <= 0) {
 403:             if (tgetent(inbuf, getenv("TERM")) <= 0
 404:                 || (Lpp = tgetnum("li")) <= 0) {
 405:                 Lpp = NLINES;
 406:             }
 407:         }
 408:     }
 409: #endif
 410:     Lpp -= 6;   /* for headers, etc. */
 411: 
 412:     already = NO;
 413:     prevmsg = firstmsg;
 414:     printing = YES;
 415:     if (ruptible)
 416:         signal(SIGINT, onintr);
 417: 
 418:     /*
 419: 	 * Main program loop
 420: 	 */
 421:     for (msg = firstmsg; msg <= lastmsg; msg++) {
 422: 
 423:         sprintf(fname, "%s/%d", USRMSGS, msg);
 424:         newmsg = fopen(fname, "r");
 425:         if (newmsg == NULL)
 426:             continue;
 427: 
 428:         gfrsub(newmsg);     /* get From and Subject fields */
 429:         if (locomode && !local) {
 430:             fclose(newmsg);
 431:             continue;
 432:         }
 433: 
 434:         if (qopt) { /* This has to be located here */
 435:             printf("There are new messages.\n");
 436:             exit(0);
 437:         }
 438: 
 439:         if (already && !hdrs)
 440:             putchar('\n');
 441:         already = YES;
 442: 
 443:         /*
 444: 		 * Print header
 445: 		 */
 446: again:
 447:         if (totty)
 448:             signal(SIGTSTP, onsusp);
 449:         (void) setjmp(tstpbuf);
 450:         nlines = 2;
 451:         if (seenfrom) {
 452:             printf("Message %d:\nFrom %s %s", msg, from, date);
 453:             nlines++;
 454:         }
 455:         if (seensubj) {
 456:             printf("Subject: %s", subj);
 457:             nlines++;
 458:         }
 459:         else {
 460:             if (seenfrom) {
 461:                 putchar('\n');
 462:                 nlines++;
 463:             }
 464:             while (nlines < 6
 465:                 && fgets(inbuf, sizeof inbuf, newmsg)
 466:                 && inbuf[0] != '\n') {
 467:                 fputs(inbuf, stdout);
 468:                 nlines++;
 469:             }
 470:         }
 471: 
 472:         lct = linecnt(newmsg);
 473:         if (lct)
 474:             printf("(%d%slines) ", lct, seensubj? " " : " more ");
 475: 
 476:         if (hdrs) {
 477:             printf("\n-----\n");
 478:             fclose(newmsg);
 479:             continue;
 480:         }
 481: 
 482:         /*
 483: 		 * Ask user for command
 484: 		 */
 485:         if (totty)
 486:             ask(lct? MORE : (msg==lastmsg? NOMORE : NEXT));
 487:         else
 488:             inbuf[0] = 'y';
 489:         if (totty)
 490:             signal(SIGTSTP, SIG_DFL);
 491: cmnd:
 492:         in = inbuf;
 493:         switch (*in) {
 494:             case 'x':
 495:             case 'X':
 496:                 exit(0);
 497: 
 498:             case 'q':
 499:             case 'Q':
 500:                 quitit = YES;
 501:                 printf("--Postponed--\n");
 502:                 exit(0);
 503:                 /* intentional fall-thru */
 504:             case 'n':
 505:             case 'N':
 506:                 if (msg >= nextmsg) sep = "Flushed";
 507:                 prevmsg = msg;
 508:                 break;
 509: 
 510:             case 'p':
 511:             case 'P':
 512:                 pause = (*in++ == 'p');
 513:                 /* intentional fallthru */
 514:             case '\n':
 515:             case 'y':
 516:             default:
 517:                 if (*in == '-') {
 518:                     msg = prevmsg-1;
 519:                     sep = "replay";
 520:                     break;
 521:                 }
 522:                 if (isdigit(*in)) {
 523:                     msg = next(in);
 524:                     sep = in;
 525:                     break;
 526:                 }
 527: 
 528:                 prmesg(nlines + lct + (seensubj? 1 : 0));
 529:                 prevmsg = msg;
 530: 
 531:         }
 532: 
 533:         printf("--%s--\n", sep);
 534:         sep = "-";
 535:         if (msg >= nextmsg) {
 536:             nextmsg = msg + 1;
 537:             fseek(msgsrc, 0L, 0);
 538:             fprintf(msgsrc, "%d\n", nextmsg);
 539:             fflush(msgsrc);
 540:         }
 541:         if (newmsg)
 542:             fclose(newmsg);
 543:         if (quitit)
 544:             break;
 545:     }
 546: 
 547:     /*
 548: 	 * Make sure .rc file gets updated
 549: 	 */
 550:     if (--msg >= nextmsg) {
 551:         nextmsg = msg + 1;
 552:         fseek(msgsrc, 0L, 0);
 553:         fprintf(msgsrc, "%d\n", nextmsg);
 554:         fflush(msgsrc);
 555:     }
 556:     if (already && !quitit && lastcmd && totty) {
 557:         /*
 558: 		 * save or reply to last message?
 559: 		 */
 560:         msg = prevmsg;
 561:         ask(NOMORE);
 562:         if (inbuf[0] == '-' || isdigit(inbuf[0]))
 563:             goto cmnd;
 564:     }
 565:     if (!(already || hush || qopt))
 566:         printf("No new messages.\n");
 567:     exit(0);
 568: }
 569: 
 570: prmesg(length)
 571: int length;
 572: {
 573:     FILE *outf, *inf;
 574:     int c;
 575: 
 576:     if (pause && length > Lpp) {
 577:         signal(SIGPIPE, SIG_IGN);
 578:         signal(SIGQUIT, SIG_IGN);
 579:         sprintf(cmdbuf, PAGE, Lpp);
 580:         outf = popen(cmdbuf, "w");
 581:         if (!outf)
 582:             outf = stdout;
 583:         else
 584:             setbuf(outf, NULL);
 585:     }
 586:     else
 587:         outf = stdout;
 588: 
 589:     if (seensubj)
 590:         putc('\n', outf);
 591: 
 592:     while (fgets(inbuf, sizeof inbuf, newmsg)) {
 593:         fputs(inbuf, outf);
 594:         if (ferror(outf)) {
 595:             clearerr(outf);
 596:             break;
 597:         }
 598:     }
 599: 
 600:     if (outf != stdout) {
 601:         pclose(outf);
 602:         signal(SIGPIPE, SIG_DFL);
 603:         signal(SIGQUIT, SIG_DFL);
 604:     }
 605:     else {
 606:         fflush(stdout);
 607:     }
 608: 
 609:     /* trick to force wait on output */
 610:     stty(fileno(stdout), &otty);
 611: }
 612: 
 613: onintr()
 614: {
 615:     signal(SIGINT, onintr);
 616:     if (mailing)
 617:         unlink(fname);
 618:     if (sending) {
 619:         unlink(fname);
 620:         puts("--Killed--");
 621:         exit(1);
 622:     }
 623:     if (printing) {
 624:         putchar('\n');
 625:         if (hdrs)
 626:             exit(0);
 627:         sep = "Interrupt";
 628:         if (newmsg)
 629:             fseek(newmsg, 0L, 2);
 630:         intrpflg = YES;
 631:     }
 632: }
 633: 
 634: /*
 635:  * We have just gotten a susp.  Suspend and prepare to resume.
 636:  */
 637: onsusp()
 638: {
 639: 
 640:     signal(SIGTSTP, SIG_DFL);
 641:     sigsetmask(0L);
 642:     kill(0, SIGTSTP);
 643:     signal(SIGTSTP, onsusp);
 644:     if (!mailing)
 645:         longjmp(tstpbuf);
 646: }
 647: 
 648: linecnt(f)
 649: FILE *f;
 650: {
 651:     off_t oldpos = ftell(f);
 652:     int l = 0;
 653:     char lbuf[BUFSIZ];
 654: 
 655:     while (fgets(lbuf, sizeof lbuf, f))
 656:         l++;
 657:     clearerr(f);
 658:     fseek(f, oldpos, 0);
 659:     return (l);
 660: }
 661: 
 662: next(buf)
 663: char *buf;
 664: {
 665:     int i;
 666:     sscanf(buf, "%d", &i);
 667:     sprintf(buf, "Goto %d", i);
 668:     return(--i);
 669: }
 670: 
 671: ask(prompt)
 672: char *prompt;
 673: {
 674:     char    inch;
 675:     int n, cmsg;
 676:     off_t   oldpos;
 677:     FILE    *cpfrom, *cpto;
 678: 
 679:     printf("%s ", prompt);
 680:     fflush(stdout);
 681:     intrpflg = NO;
 682:     gets(inbuf);
 683:     if (intrpflg)
 684:         inbuf[0] = 'x';
 685: 
 686:     /*
 687: 	 * Handle 'mail' and 'save' here.
 688: 	 */
 689:     if ((inch = inbuf[0]) == 's' || inch == 'm') {
 690:         if (inbuf[1] == '-')
 691:             cmsg = prevmsg;
 692:         else if (isdigit(inbuf[1]))
 693:             cmsg = atoi(&inbuf[1]);
 694:         else
 695:             cmsg = msg;
 696:         sprintf(fname, "%s/%d", USRMSGS, cmsg);
 697: 
 698:         oldpos = ftell(newmsg);
 699: 
 700:         cpfrom = fopen(fname, "r");
 701:         if (!cpfrom) {
 702:             printf("Message %d not found\n", cmsg);
 703:             ask (prompt);
 704:             return;
 705:         }
 706: 
 707:         if (inch == 's') {
 708:             in = nxtfld(inbuf);
 709:             if (*in) {
 710:                 for (n=0; in[n] > ' '; n++) { /* sizeof fname? */
 711:                     fname[n] = in[n];
 712:                 }
 713:                 fname[n] = NULL;
 714:             }
 715:             else
 716:                 strcpy(fname, "Messages");
 717:         }
 718:         else {
 719:             strcpy(fname, TEMP);
 720:             mktemp(fname);
 721:             sprintf(cmdbuf, MAIL, fname);
 722:             mailing = YES;
 723:         }
 724:         cpto = fopen(fname, "a");
 725:         if (!cpto) {
 726:             perror(fname);
 727:             mailing = NO;
 728:             fseek(newmsg, oldpos, 0);
 729:             ask(prompt);
 730:             return;
 731:         }
 732: 
 733:         while (n = fread(inbuf, 1, sizeof inbuf, cpfrom))
 734:             fwrite(inbuf, 1, n, cpto);
 735: 
 736:         fclose(cpfrom);
 737:         fclose(cpto);
 738:         fseek(newmsg, oldpos, 0);   /* reposition current message */
 739:         if (inch == 's')
 740:             printf("Message %d saved in \"%s\"\n", cmsg, fname);
 741:         else {
 742:             system(cmdbuf);
 743:             unlink(fname);
 744:             mailing = NO;
 745:         }
 746:         ask(prompt);
 747:     }
 748: }
 749: 
 750: gfrsub(infile)
 751: FILE *infile;
 752: {
 753:     off_t frompos;
 754: 
 755:     seensubj = seenfrom = NO;
 756:     local = YES;
 757:     subj[0] = from[0] = date[0] = NULL;
 758: 
 759:     /*
 760: 	 * Is this a normal message?
 761: 	 */
 762:     if (fgets(inbuf, sizeof inbuf, infile)) {
 763:         if (strncmp(inbuf, "From", 4)==0) {
 764:             /*
 765: 			 * expected form starts with From
 766: 			 */
 767:             seenfrom = YES;
 768:             frompos = ftell(infile);
 769:             ptr = from;
 770:             in = nxtfld(inbuf);
 771:             if (*in) while (*in && *in > ' ') {
 772:                 if (*in == ':' || *in == '@' || *in == '!')
 773:                     local = NO;
 774:                 *ptr++ = *in++;
 775:                 /* what about sizeof from ? */
 776:             }
 777:             *ptr = NULL;
 778:             if (*(in = nxtfld(in)))
 779:                 strncpy(date, in, sizeof date);
 780:             else {
 781:                 date[0] = '\n';
 782:                 date[1] = NULL;
 783:             }
 784:         }
 785:         else {
 786:             /*
 787: 			 * not the expected form
 788: 			 */
 789:             fseek(infile, 0L, 0);
 790:             return;
 791:         }
 792:     }
 793:     else
 794:         /*
 795: 		 * empty file ?
 796: 		 */
 797:         return;
 798: 
 799:     /*
 800: 	 * look for Subject line until EOF or a blank line
 801: 	 */
 802:     while (fgets(inbuf, sizeof inbuf, infile)
 803:         && !(blankline = (inbuf[0] == '\n'))) {
 804:         /*
 805: 		 * extract Subject line
 806: 		 */
 807:         if (!seensubj && strncmp(inbuf, "Subj", 4)==0) {
 808:             seensubj = YES;
 809:             frompos = ftell(infile);
 810:             strncpy(subj, nxtfld(inbuf), sizeof subj);
 811:         }
 812:     }
 813:     if (!blankline)
 814:         /*
 815: 		 * ran into EOF
 816: 		 */
 817:         fseek(infile, frompos, 0);
 818: 
 819:     if (!seensubj)
 820:         /*
 821: 		 * for possible use with Mail
 822: 		 */
 823:         strncpy(subj, "(No Subject)\n", sizeof subj);
 824: }
 825: 
 826: char *
 827: nxtfld(s)
 828: char *s;
 829: {
 830:     if (*s) while (*s && *s > ' ') s++; /* skip over this field */
 831:     if (*s) while (*s && *s <= ' ') s++;    /* find start of next field */
 832:     return (s);
 833: }

Defined functions

ask defined in line 671; used 5 times
gfrsub defined in line 750; used 1 times
linecnt defined in line 648; used 1 times
main defined in line 125; never used
next defined in line 662; used 1 times
nxtfld defined in line 826; used 5 times
onintr defined in line 613; used 4 times
onsusp defined in line 637; used 3 times
prmesg defined in line 570; used 1 times

Defined variables

Lpp defined in line 99; used 7 times
blankline defined in line 87; used 7 times
clean defined in line 121; used 6 times
cmdbuf defined in line 76; used 4 times
copyright defined in line 8; never used
date defined in line 79; used 6 times
fname defined in line 75; used 32 times
from defined in line 78; used 3 times
hdrs defined in line 115; used 4 times
hush defined in line 117; used 2 times
in defined in line 81; used 22 times
inbuf defined in line 74; used 42 times
intrpflg defined in line 92; used 3 times
keep defined in line 101; used 2 times
lastcmd defined in line 122; used 2 times
lct defined in line 97; used 5 times
local defined in line 82; used 3 times
locomode defined in line 119; used 2 times
mailing defined in line 89; used 5 times
msg defined in line 95; used 17 times
nlines defined in line 98; used 7 times
otty defined in line 102; used 2 times
pause defined in line 120; used 5 times
prevmsg defined in line 96; used 6 times
printing defined in line 88; used 2 times
ptr defined in line 80; used 9 times
qopt defined in line 116; used 3 times
quitit defined in line 90; used 3 times
ruptible defined in line 83; used 4 times
sccsid defined in line 14; never used
seenfrom defined in line 85; used 4 times
seensubj defined in line 86; used 13 times
send defined in line 118; used 3 times
sending defined in line 91; used 2 times
sep defined in line 73; used 6 times
subj defined in line 77; used 6 times
t defined in line 100; used 4 times
totty defined in line 84; used 7 times
tstpbuf defined in line 123; used 2 times
tstpflag defined in line 93; never used
uid defined in line 94; used 4 times

Defined typedef's

bool defined in line 70; used 22 times

Defined macros

BOUNDS defined in line 65; used 1 times
CMODE defined in line 55; used 1 times
DAEMON defined in line 59; used 1 times
DAYS defined in line 62; used 1 times
MORE defined in line 67; used 1 times
MSGSRC defined in line 64; used 1 times
NDAYS defined in line 61; used 1 times
NEXT defined in line 66; used 1 times
NLINES defined in line 60; used 1 times
NO defined in line 56; used 23 times
NOMORE defined in line 68; used 2 times
OBJECT defined in line 39; used 1 times
SUPERUSER defined in line 58; used 1 times
TEMP defined in line 63; used 1 times
V7 defined in line 38; used 1 times
YES defined in line 57; used 21 times
Last modified: 1987-03-21
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 8767
Valid CSS Valid XHTML 1.0 Strict