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

Defined functions

ask defined in line 649; used 5 times
gfrsub defined in line 728; used 1 times
linecnt defined in line 626; used 1 times
main defined in line 118; never used
next defined in line 640; used 1 times
nxtfld defined in line 804; used 5 times
onintr defined in line 592; used 4 times
onsusp defined in line 617; used 3 times
prmesg defined in line 551; used 1 times

Defined variables

Lpp defined in line 88; used 5 times
blankline defined in line 74; used 7 times
clean defined in line 112; used 6 times
cmdbuf defined in line 63; used 4 times
date defined in line 66; used 6 times
fname defined in line 62; used 32 times
from defined in line 65; used 3 times
hdrs defined in line 106; used 4 times
hush defined in line 108; used 2 times
in defined in line 68; used 22 times
inbuf defined in line 61; used 42 times
intrpflg defined in line 79; used 3 times
keep defined in line 90; used 2 times
lastcmd defined in line 113; used 2 times
lct defined in line 86; used 5 times
local defined in line 69; used 3 times
locomode defined in line 110; used 2 times
mailing defined in line 76; used 4 times
msg defined in line 84; used 17 times
nlines defined in line 87; used 7 times
otty defined in line 91; used 2 times
pause defined in line 111; used 5 times
prevmsg defined in line 85; used 6 times
printing defined in line 75; used 2 times
ptr defined in line 67; used 9 times
qopt defined in line 107; used 3 times
quitit defined in line 77; used 3 times
ruptible defined in line 70; used 4 times
sccsid defined in line 2; never used
seenfrom defined in line 72; used 4 times
seensubj defined in line 73; used 13 times
send defined in line 109; used 3 times
sending defined in line 78; used 2 times
sep defined in line 60; used 6 times
subj defined in line 64; used 6 times
t defined in line 89; used 4 times
totty defined in line 71; used 7 times
tstpbuf defined in line 115; used 2 times
tstpflg defined in line 81; never used
uid defined in line 83; used 4 times

Defined typedef's

bool defined in line 57; used 22 times

Defined macros

BOUNDS defined in line 52; used 1 times
CMODE defined in line 42; used 1 times
DAEMON defined in line 46; used 1 times
DAYS defined in line 49; used 1 times
MORE defined in line 54; used 1 times
MSGSRC defined in line 51; used 1 times
NDAYS defined in line 48; used 1 times
NEXT defined in line 53; used 1 times
NLINES defined in line 47; used 2 times
NO defined in line 43; used 23 times
NOMORE defined in line 55; used 2 times
OBJECT defined in line 25; used 1 times
SUPERUSER defined in line 45; used 1 times
TEMP defined in line 50; used 1 times
V7 defined in line 24; used 1 times
YES defined in line 44; used 20 times
Last modified: 1983-09-14
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2208
Valid CSS Valid XHTML 1.0 Strict