|
|
1.1 ! root 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 *24*60*60 /* 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), 0); ! 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(0); ! 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.