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