|
|
1.1 ! root 1: /* ! 2: * This software is Copyright (c) 1986 by Rick Adams. ! 3: * ! 4: * Permission is hereby granted to copy, reproduce, redistribute or ! 5: * otherwise use this software as long as: there is no monetary ! 6: * profit gained specifically from the use or reproduction or this ! 7: * software, it is not sold, rented, traded or otherwise marketed, and ! 8: * this copyright notice is included prominently in any copy ! 9: * made. ! 10: * ! 11: * The author make no claims as to the fitness or correctness of ! 12: * this software for any use whatsoever, and it is provided as is. ! 13: * Any use of this software is at the user's own risk. ! 14: * ! 15: * readr - /bin/mail and msgs interface and associated functions. ! 16: */ ! 17: ! 18: #ifdef SCCSID ! 19: static char *SccsId = "@(#)readr.c 2.55 1/17/86"; ! 20: #endif /* SCCSID */ ! 21: ! 22: #include "rparams.h" ! 23: #if defined(BSD4_2) || defined(BSD4_1C) ! 24: #include <sys/dir.h> ! 25: #else ! 26: #include "ndir.h" ! 27: #endif /* !BSD4_2 && !BSD4_1C */ ! 28: #include <setjmp.h> ! 29: #include <errno.h> ! 30: ! 31: extern int errno; ! 32: ! 33: char *Progname = "readnews"; /* used by xerror to identify failing program */ ! 34: ! 35: static char lbuf[BUFLEN*2]; ! 36: long atol(); ! 37: ! 38: #define saveart oobit = bit;strcpy(ofilename1, filename);strcpy(ogroupdir, groupdir);hptr = h;h = hold;hold = hptr;ongsize = pngsize ! 39: #define NLINES(h, fp) (h->numlines[0] ? h->intnumlines : (h->intnumlines=linecnt(fp),sprintf(h->numlines, "%d", h->intnumlines), h->intnumlines)) ! 40: ! 41: char *tft = "/tmp/folXXXXXX"; ! 42: ! 43: /* ! 44: * These were made static for u370 with its buggy cc. ! 45: * I judged it better to have one copy with no ifdefs than ! 46: * to conditionally compile them as automatic variables ! 47: * in readr (which they originally were). Performance ! 48: * considerations might warrant moving some of the simple ! 49: * things into register variables, but I don't know what ! 50: * breaks the u370 cc. ! 51: */ ! 52: static char goodone[BUFLEN]; /* last decent article */ ! 53: static char ogroupdir[BUFLEN]; /* last groupdir */ ! 54: static char address[PATHLEN]; /* for reply copy */ ! 55: static char edcmdbuf[128]; ! 56: static int rfq = 0; /* for last article */ ! 57: static long ongsize; /* Previous ngsize */ ! 58: static long pngsize; /* Printing ngsize */ ! 59: static char *bptr; /* temp pointer. */ ! 60: static struct srec srec; /* srec for sys file entries */ ! 61: static char *tfilename; /* temporary file name */ ! 62: static char ofilename1[BUFLEN]; /* previous file name */ ! 63: static struct hbuf hbuf1, hbuf2, /* for minusing */ ! 64: *h = &hbuf1, /* current header */ ! 65: *hold = &hbuf2, /* previous header */ ! 66: *hptr; /* temporary */ ! 67: static char *ptr1, *ptr2, *ptr3; /* for reply manipulation */ ! 68: static int abs = FALSE; /* TRUE if we asked absolutely */ ! 69: static char tf[100]; ! 70: static long oobit; /* last bit, really */ ! 71: static int dgest = 0; ! 72: static FILE *ofp; /* Current output file to terminal*/ ! 73: static FILE *fp; /* current article to be printed*/ ! 74: static int holdup; /* 1 iff should stop before hdr */ ! 75: static int ignorenews; /* 1 iff readnews -p > /dev/null*/ ! 76: static time_t timelastsaved; /* time newsrc last written out */ ! 77: static jmp_buf sigjmpbuf; /* for signal processing */ ! 78: static int canlongjmp; /* TRUE if setjmp on sigjmp valid */ ! 79: ! 80: int catchcont(); ! 81: readr() ! 82: { ! 83: register char *m = getenv("MORE"); ! 84: register char *m2, cc; ! 85: ! 86: /* ! 87: * Turn of more's 'l' option, so \f kludge will work. ! 88: * This is really revolting! ! 89: */ ! 90: if (m2 = m) { ! 91: while (cc = *m++) ! 92: if (cc != 'l') ! 93: *m2++ = cc; ! 94: *m2 = '\0'; ! 95: } ! 96: ! 97: #ifdef DEBUG ! 98: fprintf(stderr, "readr()\n"); ! 99: #endif ! 100: if (aflag) { ! 101: if (*datebuf) { ! 102: if ((atime = cgtdate(datebuf)) == -1) ! 103: xerror("Cannot parse date string"); ! 104: } else ! 105: atime = 0; ! 106: } ! 107: ! 108: if (pflag && ignoring()) ! 109: ignorenews = TRUE; ! 110: ! 111: if (xflag) ! 112: uflag = 0; ! 113: if (uflag) ! 114: (void) time(&timelastsaved); ! 115: ! 116: ofp = stdout; ! 117: if (cflag && coptbuf[0] != '\0') { ! 118: (void) umask(022); ! 119: (void) mktemp(outfile); /* get "unique" file name */ ! 120: (void) close(creat(outfile,0666)); ! 121: ofp = xfopen(outfile, "w"); ! 122: (void) umask(N_UMASK); ! 123: cflag = FALSE; ! 124: pflag = TRUE; ! 125: } ! 126: ! 127: /* loop reading articles. */ ! 128: fp = NULL; ! 129: obit = -1; ! 130: nextng(); ! 131: for ( ;; ) { ! 132: if (getnextart(FALSE)) ! 133: break; ! 134: #ifdef DEBUG ! 135: fprintf(stderr,"after getnextart, fp %x, pos %ld, bit %ld, group '%s', filename '%s'\n", ! 136: fp, ftell(fp), bit, groupdir, filename); ! 137: #endif ! 138: (void) strcpy(goodone, filename); ! 139: if (pflag || lflag || eflag) { ! 140: /* This code should be gotten rid of */ ! 141: if (SigTrap) { ! 142: qfflush(ofp); ! 143: fprintf(ofp, "\n"); ! 144: cdump(ofp); ! 145: xxit(0); /* kludge! drop when qfflush works */ ! 146: return; ! 147: } ! 148: clear(bit); ! 149: nextbit(); ! 150: FCLOSE(fp); ! 151: continue; ! 152: } ! 153: for ( ;; ) { ! 154: char *pp; ! 155: int nlines; ! 156: int (*ointr)(); ! 157: #ifdef SIGCONT ! 158: int (*ocont)(); ! 159: #endif ! 160: (void) setjmp(sigjmpbuf); ! 161: canlongjmp = TRUE; ! 162: ! 163: SigTrap = FALSE; ! 164: if (!cflag) { ! 165: if (rfq) ! 166: (void) sprintf(bfr, "Last article. [qfr] "); ! 167: else { ! 168: nlines = NLINES(h, fp); ! 169: if (nlines <= 0) { ! 170: (void) sprintf(bfr, "(0 lines) Next? [nqfr] "); ! 171: FCLOSE(fp); ! 172: } else { ! 173: (void) sprintf(bfr, "(%d lines) More? [ynq] ", nlines); ! 174: } ! 175: } ! 176: } else ! 177: (void) sprintf(bfr, "? "); ! 178: fprintf(ofp, "%s", bfr); ! 179: (void) fflush(ofp); ! 180: bptr = lbuf; ! 181: ointr = signal(SIGINT, catchcont); ! 182: #ifdef SIGCONT ! 183: ocont = signal(SIGCONT, catchcont); ! 184: #endif ! 185: pp = fgets(bptr, BUFLEN, stdin); ! 186: canlongjmp = FALSE; ! 187: (void) signal(SIGINT, ointr); ! 188: #ifdef SIGCONT ! 189: (void) signal(SIGCONT, ocont); ! 190: #endif ! 191: if (pp != NULL) ! 192: break; ! 193: if (!SigTrap) ! 194: return; ! 195: #ifdef SIGCONT ! 196: if (SigTrap != SIGCONT) ! 197: #endif ! 198: fprintf(ofp, "\n"); ! 199: } ! 200: (void) nstrip(bptr); ! 201: while (*bptr == ' ' || *bptr == '\t') ! 202: bptr++; ! 203: if (command()) ! 204: break; ! 205: } ! 206: ! 207: if (!pflag && !news) { ! 208: if (!checkngs(header.nbuf, actfp)) ! 209: fprintf(stderr, "No news.\n"); ! 210: } ! 211: cout(ofp); ! 212: } ! 213: ! 214: #define EOL() if (*bptr != '\0') { fprintf(ofp, "? for commands.\n"); return FALSE; } ! 215: /* ! 216: * Process one command, which has already been typed in. ! 217: */ ! 218: command() ! 219: { ! 220: char *findhist(); ! 221: long i; ! 222: ! 223: switch (*bptr++) { ! 224: ! 225: /* No. Go on to next article. */ ! 226: case 'n': ! 227: EOL(); ! 228: readmode = NEXT; ! 229: if (!cflag) ! 230: FCLOSE(fp); ! 231: fprintf(ofp, "\n"); ! 232: clear(bit); ! 233: saveart; ! 234: nextbit(); ! 235: break; ! 236: ! 237: /* Undigestify the article. */ ! 238: case 'd': ! 239: dgest = 1; ! 240: /* fall through */ ! 241: ! 242: /* yes: print this article, go on. */ ! 243: case 'y': ! 244: EOL(); ! 245: /* fall through. */ ! 246: ! 247: /* The user hit return. Default is 'y' unless rfq, then it's 'q'. */ ! 248: case '\0': ! 249: if (!bptr[-1] && rfq) ! 250: return TRUE; ! 251: readmode = NEXT; ! 252: showtail(fp); ! 253: clear(bit); ! 254: saveart; ! 255: nextbit(); ! 256: break; ! 257: ! 258: /* ! 259: * Unsubscribe to the newsgroup and go on to next group ! 260: */ ! 261: case 'u': ! 262: fprintf(ofp, "To unsubscribe, use 'U'\n"); ! 263: break; ! 264: ! 265: case 'U': ! 266: fprintf(ofp, "Unsubscribing to newsgroup: %s\n", groupdir); ! 267: obit = -1; ! 268: FCLOSE(fp); ! 269: if (cflag) ! 270: clear(bit); ! 271: else ! 272: putc('\n', ofp); ! 273: rfq = 0; ! 274: zapng = TRUE; ! 275: saveart; ! 276: if (nextng()) { ! 277: if (actdirect == BACKWARD) ! 278: fprintf(ofp, "Can't back up.\n"); ! 279: else ! 280: return TRUE; ! 281: } ! 282: break; ! 283: ! 284: /* Print the current version of news */ ! 285: case 'v': ! 286: fprintf(ofp, "News version: %s\n", news_version); ! 287: break; ! 288: ! 289: /* reprint the article */ ! 290: case 'p': ! 291: EOL(); ! 292: if (!cflag) ! 293: goto minus; ! 294: readmode = NEXT; ! 295: if (!cflag) { ! 296: FCLOSE(fp); ! 297: bit = last; ! 298: putc('\n', ofp); ! 299: } ! 300: obit = -1; ! 301: break; ! 302: ! 303: /* decrypt joke */ ! 304: case 'D': ! 305: caesar_command(); ! 306: readmode = NEXT; ! 307: clear(bit); ! 308: saveart; ! 309: nextbit(); ! 310: break; ! 311: ! 312: /* write out the article someplace */ ! 313: case 's': ! 314: case 'w': ! 315: { ! 316: char *grn = groupdir; ! 317: tfilename = filename; ! 318: if (*bptr == '-') { ! 319: bptr++; ! 320: grn = ogroupdir; ! 321: if (*ofilename1) ! 322: tfilename = ofilename1; ! 323: } ! 324: if (*bptr != '\0' && *bptr != ' ') { ! 325: fprintf(ofp, "Bad file name.\n"); ! 326: break; ! 327: } ! 328: while (*bptr == ' ') ! 329: bptr++; ! 330: if (*bptr != '|' && *bptr != '/') { ! 331: char hetyped[BUFLEN]; ! 332: char *boxptr; ! 333: struct stat stbf; ! 334: (void) strcpy(hetyped, bptr); ! 335: if (hetyped[0] == '~' && hetyped[1] == '/') { ! 336: strcpy(hetyped, bptr+2); ! 337: strcpy(bptr, userhome); ! 338: } else if (boxptr = getenv("NEWSBOX")) { ! 339: if (index(boxptr, '%')) { ! 340: sprintf(bptr, boxptr, grn); ! 341: if (stat(bptr, &stbf) < 0) { ! 342: if (mkdir(bptr, 0777) < 0) { ! 343: fprintf(ofp, "Cannot create directory %s", bptr); ! 344: break; ! 345: } ! 346: } else if ((stbf.st_mode & S_IFMT) != S_IFDIR) { ! 347: fprintf(ofp, "%s is not a directory", bptr); ! 348: break; ! 349: } ! 350: } else ! 351: strcpy(bptr, boxptr); ! 352: } else ! 353: (void) strcpy(bptr, "."); ! 354: (void) strcat(bptr, "/"); ! 355: if (hetyped[0] != '\0') ! 356: (void) strcat(bptr, hetyped); ! 357: else ! 358: (void) strcat(bptr, "Articles"); ! 359: } ! 360: fwait(fsubr(save, tfilename, bptr)); ! 361: } ! 362: break; ! 363: ! 364: /* back up */ ! 365: case '-': ! 366: minus: ! 367: rfq = 0; ! 368: abs = TRUE; ! 369: if (!*ofilename1) { ! 370: fprintf(ofp, "Can't back up.\n"); ! 371: break; ! 372: } ! 373: if (cflag) ! 374: clear(bit); ! 375: else { ! 376: FCLOSE(fp); ! 377: putc('\n', ofp); ! 378: } ! 379: hptr = h; ! 380: h = hold; ! 381: hold = hptr; ! 382: (void) strcpy(bfr, filename); ! 383: (void) strcpy(filename, ofilename1); ! 384: (void) strcpy(ofilename1, bfr); ! 385: obit = bit; ! 386: if (strcmp(groupdir, ogroupdir)) { ! 387: (void) strcpy(bfr, groupdir); ! 388: selectng(ogroupdir, TRUE, FALSE); ! 389: (void) strcpy(groupdir, ogroupdir); ! 390: (void) strcpy(ogroupdir, bfr); ! 391: ngrp = 1; ! 392: back(); ! 393: } ! 394: bit = oobit; ! 395: oobit = obit; ! 396: obit = -1; ! 397: (void) getnextart(TRUE); ! 398: return FALSE; ! 399: ! 400: /* skip forwards */ ! 401: case '+': ! 402: caseplus: ! 403: if (*bptr == '\0') ! 404: (void) strcat(bptr, "1"); ! 405: rfq = 0; ! 406: if (cflag) ! 407: clear(bit); ! 408: saveart; ! 409: last = bit; ! 410: for (i = 0; i < atol(bptr); i++) { ! 411: nextbit(); ! 412: if ((bit > pngsize) || (rflag && bit < 1)) ! 413: break; ! 414: } ! 415: if (!cflag) { ! 416: putc('\n', ofp); ! 417: FCLOSE(fp); ! 418: } ! 419: obit = -1; ! 420: break; ! 421: ! 422: /* exit - time updated to that of most recently read article */ ! 423: case 'q': ! 424: EOL(); ! 425: return TRUE; ! 426: ! 427: /* exit - no time update. */ ! 428: case 'x': ! 429: EOL(); ! 430: xxit(0); ! 431: ! 432: /* cancel the article. */ ! 433: case 'c': ! 434: (void) cancel_command(); ! 435: break; ! 436: ! 437: /* escape to shell */ ! 438: case '!': ! 439: fwait(fsubr(ushell, bptr, (char *)NULL)); ! 440: fprintf(ofp, "\n"); ! 441: hdr(); ! 442: break; ! 443: ! 444: /* mail reply */ ! 445: case 'r': ! 446: (void) reply_command(); ! 447: break; ! 448: ! 449: /* send to some system */ ! 450: case 'X': ! 451: xmit_command(); ! 452: break; ! 453: /* mark the rest of the articles in this group as read */ ! 454: case 'K': ! 455: saveart; ! 456: while (bit <= pngsize && bit >= minartno) { ! 457: clear(bit); ! 458: nextbit(); ! 459: } ! 460: FCLOSE(fp); ! 461: break; ! 462: ! 463: /* next newsgroup */ ! 464: case 'P': ! 465: *bptr = '-'; ! 466: case 'N': ! 467: FCLOSE(fp); ! 468: if (next_ng_command()) ! 469: return TRUE; ! 470: break; ! 471: ! 472: case 'b': /* back up 1 article */ ! 473: i = bit - 1; ! 474: goto tryartnum; ! 475: case '0': /* specific no. */ ! 476: case '1': ! 477: case '2': ! 478: case '3': ! 479: case '4': ! 480: case '5': ! 481: case '6': ! 482: case '7': ! 483: case '8': ! 484: case '9': ! 485: (void) sscanf(--bptr, "%ld", &i); ! 486: if (i == 0) { ! 487: fprintf(ofp, "Bad article no.\n"); ! 488: break; ! 489: } ! 490: if (i > pngsize) { ! 491: fprintf(ofp, "Not that many articles.\n"); ! 492: break; ! 493: } ! 494: tryartnum: ! 495: readmode = SPEC; ! 496: abs = TRUE; ! 497: bit = i; ! 498: obit = -1; ! 499: if (!cflag) { ! 500: putc('\n', ofp); ! 501: FCLOSE(fp); ! 502: } ! 503: rfq = 0; ! 504: break; ! 505: ! 506: /* specific message ID. */ ! 507: case '<': ! 508: ptr1 = findhist(--bptr); ! 509: if (ptr1 == NULL) { ! 510: fprintf(ofp, "No such article: %s.\n", bptr); ! 511: break; ! 512: } ! 513: ptr2 = index(ptr1, '\t'); ! 514: ptr3 = index(++ptr2, '\t'); ! 515: ptr2 = index(++ptr3, ' '); ! 516: if (ptr2) ! 517: *ptr2 = '\0'; ! 518: ptr2 = index(ptr3, '/'); ! 519: if (!ptr2) { ! 520: *ptr3 = '\0'; ! 521: if (strcmp(++ptr3, "cancelled") == 0) { ! 522: fprintf(ofp, "Article %s has been cancelled.\n", ! 523: bptr); ! 524: break; ! 525: } ! 526: fprintf(ofp, "Article %s (dated %s) has expired.\n", ! 527: bptr, index(ptr1, '\t')+1); ! 528: break; ! 529: } ! 530: *ptr2++ = '\0'; ! 531: abs = TRUE; ! 532: if (cflag) ! 533: clear(bit); ! 534: else { ! 535: FCLOSE(fp); ! 536: putc('\n', ofp); ! 537: } ! 538: saveart; ! 539: (void) strcpy(ogroupdir, ptr3); ! 540: if (strcmp(groupdir, ogroupdir)) { ! 541: (void) strcpy(bfr, groupdir); ! 542: selectng(ogroupdir, TRUE, PERHAPS); ! 543: (void) strcpy(groupdir, ogroupdir); ! 544: (void) strcpy(ogroupdir, bfr); ! 545: ngrp = 1; ! 546: back(); ! 547: } ! 548: (void) sscanf(ptr2, "%ld", &bit); ! 549: oobit = obit; ! 550: obit = -1; ! 551: i = bit; ! 552: (void) getnextart(TRUE); ! 553: if (bit != i || strcmp(groupdir, ptr3) != 0) { ! 554: (void) fprintf(ofp, "Can't read %s/%ld.\n", ptr3, i); ! 555: goto minus; ! 556: } ! 557: rfq = 0; ! 558: break; ! 559: ! 560: /* follow-up article */ ! 561: case 'f': ! 562: if (strcmp(h->followto, "poster") == 0) { ! 563: (void) reply_command(); ! 564: break; ! 565: } ! 566: ! 567: if (*bptr == '-') ! 568: tfilename = ofilename1; ! 569: else ! 570: tfilename = filename; ! 571: (void) sprintf(bfr,"%s/%s %s", BIN, "postnews", tfilename); ! 572: (void) system(bfr); ! 573: break; ! 574: ! 575: /* erase - pretend we haven't seen this article. */ ! 576: case 'e': ! 577: if (rfq || *bptr == '-') { ! 578: if (strcmp(groupdir, ogroupdir)) { ! 579: i = bit; ! 580: (void) strcpy(bfr, groupdir); ! 581: selectng(ogroupdir, FALSE, PERHAPS); ! 582: set(oobit); ! 583: fprintf(ofp,"Holding article %ld newsgroup %s\n", oobit, ogroupdir), ! 584: (void) strcpy(groupdir, ogroupdir); ! 585: selectng(bfr, FALSE, FALSE); ! 586: bit = i; ! 587: } else { ! 588: fprintf(ofp,"Holding article %ld\n", oobit); ! 589: set(oobit); ! 590: } ! 591: } else { ! 592: fprintf(ofp,"Holding article %ld\n", bit); ! 593: set(bit); ! 594: goto caseplus; /* skip this article for now */ ! 595: } ! 596: break; ! 597: ! 598: case 'H': ! 599: case 'h': ! 600: if (!hflag) ! 601: dash(8, ofp); ! 602: if (*bptr == '-') { ! 603: if (oobit > 0) ! 604: fprintf(ofp, "Article %ld:\n", oobit); ! 605: hprint(hold, ofp, 1 + (bptr[-1]=='H')); ! 606: } else { ! 607: fprintf(ofp, "Article %ld of %ld: %s\n", ! 608: rfq ? oobit : bit, pngsize, h->ident); ! 609: hprint(h, ofp, 1 + (bptr[-1]=='H')); ! 610: } ! 611: if (!hflag) ! 612: dash(8, ofp); ! 613: break; ! 614: ! 615: case '#': ! 616: fprintf(ofp, "Article %ld of %ld: newsgroup %s\n", ! 617: rfq ? oobit : bit, pngsize, rfq ? ogroupdir : groupdir); ! 618: break; ! 619: ! 620: /* error */ ! 621: case '?': ! 622: help(ofp); ! 623: break; ! 624: default: ! 625: fprintf(ofp, "? for commands.\n"); ! 626: break; ! 627: } ! 628: ! 629: return FALSE; ! 630: } ! 631: ! 632: cancel_command() ! 633: { ! 634: int notauthor; ! 635: tfilename = filename; ! 636: hptr = h; ! 637: if (*bptr == '-') { ! 638: if (*ofilename1) { ! 639: tfilename = ofilename1; ! 640: hptr = hold; ! 641: } ! 642: bptr++; ! 643: } ! 644: EOL(); ! 645: readmode = SPEC; ! 646: (void) strcpy(rcbuf, hptr->path); ! 647: ptr1 = index(rcbuf, ' '); ! 648: if (ptr1) ! 649: *ptr1 = 0; ! 650: notauthor = strcmp(username, rcbuf); ! 651: if (uid != ROOTID && uid && notauthor) { ! 652: fprintf(ofp, "Can't cancel what you didn't write.\n"); ! 653: return FALSE; ! 654: } ! 655: if (!cancel(ofp, hptr, notauthor) && hptr == h) { ! 656: clear(bit); ! 657: saveart; ! 658: nextbit(); ! 659: obit = -1; ! 660: if (!cflag) ! 661: putc('\n', ofp); ! 662: FCLOSE(fp); ! 663: } ! 664: return TRUE; ! 665: } ! 666: ! 667: reply_command() ! 668: { ! 669: register char *pathptr; ! 670: int edit = 1; ! 671: char *ed, *fbp; ! 672: int idlen; ! 673: FILE *tfp; ! 674: char *replyname(); ! 675: char subj[BUFLEN]; ! 676: char folbuf[BUFLEN]; ! 677: struct stat statb; ! 678: long creatm; ! 679: ! 680: hptr = h; ! 681: while (*bptr && index("d-", *bptr)) { ! 682: switch (*bptr) { ! 683: /* Followup the previous article. */ ! 684: case '-': ! 685: hptr = hold; ! 686: break; ! 687: ! 688: /* Don't edit the headers */ ! 689: case 'd': ! 690: edit = 0; ! 691: break; ! 692: } ! 693: bptr++; ! 694: } ! 695: EOL(); ! 696: ptr1 = index(MAILPARSER, ' '); ! 697: if (ptr1) ! 698: *ptr1 = '\0'; ! 699: if (edit && access(MAILPARSER, 1)) { ! 700: #ifdef IHCC ! 701: fprintf(stderr, "Can't edit headers, 'recmail' missing.\n"); ! 702: #else ! 703: fprintf(stderr, "Can't edit headers without %s\n", MAILPARSER); ! 704: #endif ! 705: edit = 0; ! 706: } ! 707: if (ptr1) ! 708: *ptr1 = ' '; ! 709: ! 710: *rcbuf = '\0'; ! 711: pathptr = replyname(hptr);; ! 712: for (ptr1 = address, ptr2 = pathptr; *ptr2; ptr1++, ptr2++) { ! 713: if (index("\"\\$", *ptr2)) ! 714: *ptr1++ = '\\'; ! 715: *ptr1 = *ptr2; ! 716: } ! 717: *ptr1 = '\0'; ! 718: ! 719: folbuf[0] = '\0'; /* References */ ! 720: if (hptr->followid[0]) { ! 721: fbp = hptr->followid; ! 722: idlen = strlen(hptr->ident); ! 723: ! 724: /* ! 725: * If the references line is too long, truncate it. ! 726: * The "3" is for the comma, the space, and the '\0' at ! 727: * the end of the string. ! 728: */ ! 729: while (fbp && strlen(fbp) + idlen > BUFLEN - 3) ! 730: fbp = index(fbp + 1, '<'); ! 731: if (fbp != NULL) { ! 732: (void) strcpy(folbuf, fbp); ! 733: (void) strcat(folbuf, ", "); ! 734: } ! 735: } ! 736: (void) strcat(folbuf, hptr->ident); ! 737: ! 738: (void) strcpy(subj, hptr->title); /* Subject */ ! 739: while (isspace(*bptr)) ! 740: bptr++; ! 741: if (*bptr != '\0') ! 742: (void) strcpy(subj, bptr); ! 743: if (!prefix(subj, "Re:")){ ! 744: (void) strcpy(bfr, subj); ! 745: (void) sprintf(subj, "Re: %s", bfr); ! 746: } ! 747: if (!edit) { ! 748: fprintf(ofp, "To: %s\n", pathptr); ! 749: ed = index(MAILER, '%'); ! 750: if (ed && ed[1] == 's') ! 751: fprintf(ofp, "Subject: %s\n", subj); ! 752: (void) fflush(ofp); ! 753: } ! 754: ! 755: /* Put the user in the editor to create the body of the followup. */ ! 756: if (edit) { ! 757: int oumask; ! 758: ! 759: (void) strcpy(tf, tft); ! 760: (void) mktemp(tf); ! 761: ! 762: ed = getenv("EDITOR"); ! 763: if (ed == NULL) ! 764: ed = DFTEDITOR; ! 765: ! 766: oumask = umask(077); ! 767: if ((tfp = fopen(tf, "w")) == NULL) { ! 768: perror(tf); ! 769: creatm = 0L; ! 770: } else { ! 771: fprintf(tfp, "To: %s\n", pathptr); ! 772: fprintf(tfp, "Subject: %s\n", subj); ! 773: #ifdef INTERNET ! 774: fprintf(tfp, "News-Path: %s\n", hptr->path); ! 775: #endif /* INTERNET */ ! 776: fprintf(tfp, "References: %s\n\n", folbuf); ! 777: fstat(fileno(tfp), &statb); ! 778: creatm = statb.st_mtime; ! 779: (void) fclose(tfp); ! 780: } ! 781: (void) umask(oumask); ! 782: ! 783: (void) sprintf(edcmdbuf, "%s %s", ed, tf); ! 784: (void) system(edcmdbuf); ! 785: (void) strcpy(rcbuf, MAILPARSER); ! 786: (void) strcat(rcbuf, " -t"); ! 787: (void) strcat(rcbuf, " < "); ! 788: (void) strcat(rcbuf, tf); ! 789: if (access(tf, 4) || stat(tf, &statb)) { ! 790: fprintf(stderr, "Reply not sent: no input file.\n"); ! 791: return FALSE; ! 792: } ! 793: if (statb.st_mtime == creatm) { ! 794: fprintf(stderr, "Reply not sent: cancelled.\n"); ! 795: (void) unlink(tf); ! 796: return FALSE; ! 797: } ! 798: fprintf(ofp,"Sending reply.\n"); ! 799: (void) fflush(stdout); ! 800: if (fork() == 0) { ! 801: (void) system(rcbuf); ! 802: (void) unlink(tf); ! 803: _exit(0); ! 804: } ! 805: } else { ! 806: (void) sprintf(rcbuf, MAILER, hptr->title); ! 807: (void) sprintf(bfr, "%s %s", rcbuf, address); ! 808: (void) system(bfr); ! 809: } ! 810: hdr(); ! 811: return TRUE; ! 812: } ! 813: ! 814: xmit_command() ! 815: { ! 816: tfilename = filename; ! 817: if (*bptr == '-') { ! 818: if (*ofilename1) ! 819: tfilename = ofilename1; ! 820: bptr++; ! 821: } ! 822: if (*bptr != '\0' && *bptr != ' ') { ! 823: fprintf(ofp, "Bad system name.\n"); ! 824: return; ! 825: } ! 826: while (*bptr == ' ') ! 827: bptr++; ! 828: if (*bptr == '\0') { ! 829: fprintf(ofp, "Missing system name.\n"); ! 830: return; ! 831: } ! 832: if (s_find(&srec, bptr) == NULL) { ! 833: fprintf(ofp, "%s not in SYSFILE\n", bptr); ! 834: return; ! 835: } ! 836: (void) transmit(&srec, tfilename); ! 837: } ! 838: ! 839: next_ng_command() ! 840: { ! 841: obit = -1; ! 842: if (!*bptr || *bptr == '-') { ! 843: if (cflag) ! 844: clear(bit); ! 845: else ! 846: putc('\n', ofp); ! 847: if (*bptr) ! 848: actdirect = BACKWARD; ! 849: rfq = 0; ! 850: saveart; ! 851: if (nextng()) { ! 852: if (actdirect == BACKWARD) ! 853: fprintf(ofp, "Can't back up.\n"); ! 854: else ! 855: return TRUE; ! 856: } ! 857: return FALSE; ! 858: } ! 859: while (isspace(*bptr)) ! 860: bptr++; ! 861: if (!validng(bptr)) { ! 862: fprintf(ofp, "No such group.\n"); ! 863: return FALSE; ! 864: } ! 865: if (cflag) ! 866: clear(bit); ! 867: else ! 868: putc('\n', ofp); ! 869: readmode = SPEC; ! 870: rfq = 0; ! 871: saveart; ! 872: back(); ! 873: selectng(bptr, TRUE, TRUE); ! 874: return FALSE; ! 875: } ! 876: ! 877: caesar_command() ! 878: { ! 879: char temp[BUFLEN]; ! 880: FILE *pfp, *popen(); ! 881: ! 882: fprintf(stderr, "Caesar decoding:\n"); ! 883: (void) sprintf(temp, "%s/%s", LIB, "caesar"); ! 884: if (*bptr) { ! 885: (void) strcat(temp, " "); ! 886: (void) strcat(temp, bptr); ! 887: } ! 888: if (NLINES(h, fp) > LNCNT && *PAGER) { ! 889: (void) strcat(temp, " | "); ! 890: (void) strcat(temp, PAGER); ! 891: } ! 892: pfp = popen(temp, "w"); ! 893: tprint(fp, pfp, FALSE); ! 894: FCLOSE(fp); ! 895: (void) pclose(pfp); ! 896: } ! 897: ! 898: /* ! 899: * Show the user the tail, if any, of the message on file ! 900: * descriptor fd, and close fd. The digester is considered, ! 901: * and the pager is used if appropriate. ! 902: */ ! 903: showtail(fd) ! 904: FILE *fd; ! 905: { ! 906: if (fd == NULL) ! 907: return; ! 908: ! 909: if (dgest) { ! 910: digest(fd, ofp, h); ! 911: } else if (!lflag && !pflag && !eflag) { ! 912: pprint(fd); ! 913: } ! 914: (void) fclose(fd); ! 915: } ! 916: ! 917: /* ! 918: * Print out the rest of the article through the pager. ! 919: */ ! 920: pprint(fd) ! 921: FILE *fd; ! 922: { ! 923: #ifdef PAGE ! 924: /* Filter the tail of long messages through PAGER. */ ! 925: if (NLINES(h, fd) > LNCNT && *PAGER) { ! 926: if (!index(PAGER, FMETA)) { ! 927: FILE *pfp, *popen(); ! 928: ! 929: pfp = popen(PAGER, "w"); ! 930: if (pfp == NULL) ! 931: pfp = ofp; ! 932: /* ! 933: * What follows is an attempt to prevent the ! 934: * next message from scrolling part of this ! 935: * message off the top of the screen before ! 936: * the poor luser can read it. ! 937: */ ! 938: tprint(fd, pfp, FALSE); ! 939: putc('\f', pfp); ! 940: putc('\n', pfp); ! 941: putc(' ', pfp); ! 942: (void) pclose(pfp); ! 943: } ! 944: else ! 945: pout(ofp); ! 946: holdup = TRUE; ! 947: } ! 948: else ! 949: #endif ! 950: tprint(fd, ofp, FALSE); ! 951: } ! 952: ! 953: /* ! 954: * Find the next article we want to consider, if we're done with ! 955: * the last one, and show the header. ! 956: */ ! 957: getnextart(minus) ! 958: int minus; ! 959: { ! 960: int noaccess; ! 961: register DIR *dirp; ! 962: register struct direct *dir; ! 963: long nextnum, tnum; ! 964: ! 965: noaccess = 0; ! 966: ! 967: if (minus) ! 968: goto nextart2; /* Kludge for "-" command. */ ! 969: ! 970: if (bit == obit) /* Return if still on same article as last time */ ! 971: return 0; ! 972: ! 973: SigTrap = FALSE; ! 974: ! 975: nextart: ! 976: #ifdef DEBUG ! 977: fprintf(stderr,"nextart:\n"); ! 978: #endif /* DEBUG */ ! 979: dgest = 0; ! 980: ! 981: if (bit < minartno && !rflag) ! 982: bit = minartno; ! 983: ! 984: /* If done with this newsgroup, find the next one. */ ! 985: while (ngsize <= 0 || (!rflag && ((long) bit > ngsize)) || (rflag && bit < minartno)) { ! 986: if (nextng()) { ! 987: if (actdirect == BACKWARD) { ! 988: fprintf(ofp, "Can't back up.\n"); ! 989: actdirect = FORWARD; ! 990: continue; ! 991: } else ! 992: if (rfq++ || pflag || cflag) ! 993: return 1; ! 994: break; ! 995: } ! 996: if (rflag) ! 997: bit = ngsize + 1; ! 998: else ! 999: bit = minartno - 1; ! 1000: if (uflag && !xflag) { ! 1001: time_t now; ! 1002: (void) time(&now); ! 1003: if (now - timelastsaved > 5*60 /* 5 minutes */) { ! 1004: if (!xflag) ! 1005: fprintf(stderr,"[Saving .newsrc]\n"); ! 1006: writeoutrc(); ! 1007: timelastsaved = now; ! 1008: } ! 1009: } ! 1010: noaccess = 0; ! 1011: } ! 1012: ! 1013: nextart2: ! 1014: #ifdef DEBUG ! 1015: fprintf(stderr, "article: %s/%ld\n", groupdir, bit); ! 1016: #endif ! 1017: if (rcreadok) ! 1018: rcreadok = 2; /* have seen >= 1 article */ ! 1019: (void) sprintf(filename, "%s/%ld", dirname(groupdir), bit); ! 1020: if (rfq && goodone[0]) ! 1021: strcpy(filename, goodone); ! 1022: if (SigTrap) { ! 1023: if (SigTrap == SIGHUP) ! 1024: return 1; ! 1025: if (!rcreadok) ! 1026: xxit(0); ! 1027: fprintf(ofp, "Abort (n)? "); ! 1028: (void) fflush(ofp); ! 1029: (void) gets(bfr); ! 1030: if (*bfr == 'y' || *bfr == 'Y') ! 1031: xxit(0); ! 1032: SigTrap = FALSE; ! 1033: } ! 1034: #ifdef DEBUG ! 1035: fprintf(stderr, "filename = '%s'\n", filename); ! 1036: #endif ! 1037: /* Decide if we want to show this article. */ ! 1038: if (bit <= 0 || (fp = fopen(filename, "r")) == NULL) { ! 1039: /* don't show the header if the article was specifically ! 1040: * requested and it isn't there ! 1041: */ ! 1042: if (lbuf[0] == '<') { ! 1043: lbuf[0] = '\0'; ! 1044: bit = -1; ! 1045: return 1; ! 1046: } ! 1047: /* since there can be holes in legal article numbers, */ ! 1048: /* we wait till we hit 5 consecutive bad articles */ ! 1049: /* before we haul off and scan the directory */ ! 1050: if (++noaccess < 5) ! 1051: goto badart; ! 1052: noaccess = 0; ! 1053: dirp = opendir(dirname(groupdir)); ! 1054: if (dirp == NULL) { ! 1055: if (errno != EACCES) ! 1056: fprintf(stderr,"Can't open %s\n", dirname(groupdir)); ! 1057: goto badart; ! 1058: } ! 1059: nextnum = rflag ? minartno - 1 : ngsize + 1; ! 1060: while ((dir = readdir(dirp)) != NULL) { ! 1061: tnum = atol(dir->d_name); ! 1062: if (tnum <= 0) ! 1063: continue; ! 1064: if (rflag ? (tnum > nextnum && tnum < bit) ! 1065: : (tnum < nextnum && tnum > bit)) ! 1066: nextnum = tnum; ! 1067: } ! 1068: closedir(dirp); ! 1069: if (rflag ? (nextnum >= bit) : (nextnum <= bit)) ! 1070: goto badart; ! 1071: #ifdef DEBUG ! 1072: fprintf(stderr,"nextnum = %ld\n",nextnum); ! 1073: #endif /* DEBUG */ ! 1074: do { ! 1075: clear(bit); ! 1076: nextbit(); ! 1077: } while (rflag ? (nextnum < bit) : (nextnum > bit)); ! 1078: obit = -1; ! 1079: abs = FALSE; ! 1080: goto nextart; ! 1081: } else ! 1082: noaccess = 0; ! 1083: ! 1084: if (ignorenews || hread(h, fp, TRUE) == NULL ! 1085: || (!rfq && !aselect(h, abs))) { ! 1086: if (ignorenews) ! 1087: news = TRUE; ! 1088: badart: ! 1089: #ifdef DEBUG ! 1090: fprintf(stderr, "Bad article '%s'\n", filename); ! 1091: #endif ! 1092: FCLOSE(fp); ! 1093: clear(bit); ! 1094: obit = -1; ! 1095: nextbit(); ! 1096: abs = FALSE; ! 1097: goto nextart; ! 1098: } ! 1099: abs = FALSE; ! 1100: actdirect = FORWARD; ! 1101: news = TRUE; ! 1102: hdr(); ! 1103: if (pflag) ! 1104: tprint(fp, ofp, FALSE); ! 1105: else if (cflag && !lflag && !eflag) { ! 1106: (void) fflush(ofp); ! 1107: pprint(fp); ! 1108: } ! 1109: if (cflag || lflag || eflag || pflag) { ! 1110: SigTrap = FALSE; ! 1111: FCLOSE(fp); ! 1112: } ! 1113: obit = bit; ! 1114: return 0; ! 1115: } ! 1116: ! 1117: /* ! 1118: * Print out whatever the appropriate header is ! 1119: */ ! 1120: hdr() ! 1121: { ! 1122: char *briefdate(); ! 1123: ! 1124: if (rfq) ! 1125: return; ! 1126: ! 1127: if (lflag || eflag) { ! 1128: hprint(h, ofp, 0); ! 1129: return; ! 1130: } ! 1131: ! 1132: /* Print out a header */ ! 1133: if (ngrp) { ! 1134: pngsize = ngsize; ! 1135: ngrp--; ! 1136: nghprint(groupdir); ! 1137: } ! 1138: if (!hflag) ! 1139: fprintf(ofp, "Article %ld of %ld, %s.\n", ! 1140: bit, pngsize, briefdate(h->subdate)); ! 1141: hprint(h, ofp, pflag ? 1 : 0); ! 1142: } ! 1143: ! 1144: nghprint(title) ! 1145: char *title; ! 1146: { ! 1147: char *tstr = "Newsgroup "; ! 1148: int l = strlen(title) + strlen(tstr); ! 1149: ! 1150: fprintf(ofp, "\n"); ! 1151: if (!hflag) { ! 1152: dash(l, ofp); ! 1153: fprintf(ofp, "%s%s\n", tstr, title); ! 1154: dash(l, ofp); ! 1155: } else { ! 1156: fprintf(ofp, "%s%s, ", tstr, title); ! 1157: if (bit == pngsize) ! 1158: fprintf(ofp, "%ld\n", pngsize); ! 1159: else ! 1160: fprintf(ofp, "%ld-%ld\n", bit, pngsize); ! 1161: } ! 1162: fprintf(ofp, "\n"); ! 1163: } ! 1164: ! 1165: /* ! 1166: * Routine to catch a continue signal. ! 1167: */ ! 1168: catchcont(sig) ! 1169: int sig; ! 1170: { ! 1171: (void) signal(sig, catchcont); ! 1172: SigTrap = sig; ! 1173: (void) fflush(ofp); ! 1174: #ifdef SIGCONT ! 1175: if (fp && sig == SIGCONT) ! 1176: hdr(); ! 1177: if (sig != SIGCONT) ! 1178: #endif /* SIGCONT */ ! 1179: putc('\n', ofp); ! 1180: if (canlongjmp) ! 1181: longjmp(sigjmpbuf,1); ! 1182: } ! 1183: ! 1184: xxit(status) ! 1185: int status; ! 1186: { ! 1187: (void) unlink(infile); ! 1188: (void) unlink(outfile); ! 1189: #ifdef SORTACTIVE ! 1190: if (strncmp(ACTIVE,"/tmp/", 5) == 0) ! 1191: (void) unlink(ACTIVE); ! 1192: #endif /* SORTACTIVE */ ! 1193: exit(status); ! 1194: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.