# 2.11BSD#431 - /usr/src/ucb/msgs/msgs.c

##### Functions

    ask               X
    gfrsub            X
    linecnt           X
    main              X
    next              X
    nxtfld            X
    onintr            X
    onsusp            X
    prmesg            X

##### Variables

    Lpp               X
    blankline         X
    clean             X
    cmdbuf            X
    copyright         X
    date              X
    fname             X
    from              X
    hdrs              X
    hush              X
    in                X
    inbuf             X
    intrpflg          X
    keep              X
    lastcmd           X
    lct               X
    local             X
    locomode          X
    mailing           X
    msg               X
    nlines            X
    otty              X
    pause             X
    prevmsg           X
    printing          X
    ptr               X
    qopt              X
    quitit            X
    ruptible          X
    seenfrom          X
    seensubj          X
    send              X
    sending           X
    sep               X
    subj              X
    t                 X
    totty             X
    tstpbuf           X
    tstpflag          X
    uid               X

##### Macros

    BOUNDS            X
    CMODE             X
    DAEMON            X
    DAYS              X
    MORE              X
    MSGSRC            X
    NDAYS             X
    NEXT              X
    NLINES            X
    NO                X
    NOMORE            X
    OBJECT            X
    SUPERUSER         X
    TEMP              X
    V7                X
    YES               X

##### typedef's

    bool              X

       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

- in line 486, 561, 703, 729, 746

gfrsub defined in line 750; used 1 times

- in line 428

linecnt defined in line 648; used 1 times

- in line 472

main defined in line 125; never used
next defined in line 662; used 1 times

- in line 523

nxtfld defined in line 826; used 5 times

- in line 105, 708, 770, 778, 810

onintr defined in line 613; used 4 times

- in line 106, 315, 416, 615

onsusp defined in line 637; used 3 times

- in line 107, 448, 643

prmesg defined in line 570; used 1 times

- in line 528

#### Defined variables

Lpp defined in line 99; used 7 times

- in line 401-410(5), 576-579(2)

blankline defined in line 87; used 7 times

- in line 327-336(5), 803, 813

clean defined in line 121; used 6 times

- in line 166, 218-221(2), 245, 253, 350

cmdbuf defined in line 76; used 4 times

- in line 579-580(2), 721, 742

copyright defined in line 8; never used
date defined in line 79; used 6 times

- in line 452, 757, 779-782(4)

fname defined in line 75; used 32 times

- in line 209-210(2), 280-285(3), 295-308(6), 343, 359-360(2), 376-378(2), 423-424(2), 617-619(2), 696-700(2), 711-726(8), 740-743(2)

from defined in line 78; used 3 times

- in line 452, 757, 769

hdrs defined in line 115; used 4 times

- in line 174, 439, 476, 625

hush defined in line 117; used 2 times

- in line 170, 565

in defined in line 81; used 22 times

- in line 492-493(2), 512-524(5), 708-711(4), 770-779(11)

inbuf defined in line 74; used 42 times

- in line 246, 254-258(2), 322-326(3), 332-337(5), 403, 465-467(4), 488-492(2), 562(2), 592-593(3), 682-693(6), 708, 733-734(3), 762-763(3), 770, 802-810(5)

intrpflg defined in line 92; used 3 times

- in line 630, 681-683(2)

keep defined in line 101; used 2 times

- in line 219, 256

lastcmd defined in line 122; used 2 times

- in line 182, 556

lct defined in line 97; used 5 times

- in line 472-474(3), 486, 528

local defined in line 82; used 3 times

- in line 429, 756, 773

locomode defined in line 119; used 2 times

- in line 178, 429

mailing defined in line 89; used 5 times

- in line 616, 644, 722-727(2), 744

msg defined in line 95; used 17 times

- in line 421-423(4), 452, 486, 506-507(2), 518-523(2), 529, 535-536(2), 550-551(2), 560, 695

nlines defined in line 98; used 7 times

- in line 450-468(6), 528

otty defined in line 102; used 2 times

- in line 139, 610

pause defined in line 120; used 5 times

- in line 186, 357(2), 512, 576

prevmsg defined in line 96; used 6 times

- in line 413, 507, 518, 529, 560, 691

printing defined in line 88; used 2 times

- in line 414, 623

ptr defined in line 80; used 9 times

- in line 155-156(3), 318-320(2), 326, 769-777(3)

qopt defined in line 116; used 3 times

- in line 190, 434, 565

quitit defined in line 90; used 3 times

- in line 500, 543, 556

ruptible defined in line 83; used 4 times

- in line 142-143(2), 314, 415

sccsid defined in line 14; never used
seenfrom defined in line 85; used 4 times

- in line 451, 460, 755, 767

seensubj defined in line 86; used 13 times

- in line 327-330(2), 336-340(3), 455, 474, 528, 589, 755, 807-808(2), 819

send defined in line 118; used 3 times

- in line 194, 279, 291

sending defined in line 91; used 2 times

- in line 313, 618

sep defined in line 73; used 6 times

- in line 506, 519-524(2), 533-534(2), 627

subj defined in line 77; used 6 times

- in line 456, 757, 810(2), 823(2)

t defined in line 100; used 4 times

- in line 140, 219, 320, 326

totty defined in line 84; used 7 times

- in line 356-357(2), 398, 447, 485-489(2), 556

tstpbuf defined in line 123; used 2 times

- in line 449, 645

tstpflag defined in line 93; never used
uid defined in line 94; used 4 times

- in line 141, 162(2), 318

#### Defined typedef's

bool defined in line 70; used 22 times

- in line 82-93(12), 115-122(8), 128, 224

#### Defined macros

BOUNDS defined in line 65; used 1 times

- in line 209

CMODE defined in line 55; used 1 times

- in line 285

DAEMON defined in line 59; used 1 times

- in line 162

DAYS defined in line 62; used 1 times

- in line 219

MORE defined in line 67; used 1 times

- in line 486

MSGSRC defined in line 64; used 1 times

- in line 359

NDAYS defined in line 61; used 1 times

- in line 219

NEXT defined in line 66; used 1 times

- in line 486

NLINES defined in line 60; used 1 times

- in line 405

NO defined in line 56; used 23 times

- in line 88-93(6), 115-122(8), 224, 330, 362, 412, 681, 727, 744, 755, 773

NOMORE defined in line 68; used 2 times

- in line 486, 561

OBJECT defined in line 39; used 1 times

- in line 339

SUPERUSER defined in line 58; used 1 times

- in line 162

TEMP defined in line 63; used 1 times

- in line 719

V7 defined in line 38; used 1 times

- in line 397

YES defined in line 57; used 21 times

- in line 166-194(8), 267, 313, 327, 369, 375, 414, 441, 500, 630, 722, 756, 767, 808

Last modified: 1987-03-21 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 3236 |