|
|
1.1 root 1: /*
2: * digest - process ARPANET digests
3: *
4: * Alan Hastings 9/5/82
5: *
6: * digest(ifile, ofile, header)
7: * FILE *ifile, *ofile;
8: * struct header *header;
9: *
10: * returns: TRUE EOF reached, exit from readnews.
11: * FALSE normal exit, continue reading news.
12: */
13:
14: #include "rparams.h"
15:
16: struct art {
17: long a_hdr;
18: long a_bod;
19: int a_blen;
20: int a_hlen;
21: };
22:
23: #define loop for(;;)
24: #define getnum(p, n) for (n=0; *p>='0' && *p<='9'; p++) n = n*10 + *p-'0'
25: #define errchk(p) if (*p) goto badopt
26:
27: #define MAXART 128
28:
29: struct art *arts;
30: int lastart;
31:
32: digest(ifp, ofp, h)
33: FILE *ifp, *ofp;
34: struct hbuf *h;
35: {
36: register int n, curart;
37: struct art artbuf[MAXART];
38: int printh, eod, nomore;
39: char cbuf[BUFLEN], *cmd;
40:
41: arts = artbuf;
42: printh = TRUE;
43: nomore = eod = FALSE;
44: curart = 1;
45:
46: if (dscan(ifp))
47: return(FALSE);
48:
49: dprint(0, ifp, ofp);
50:
51: loop {
52: if (nomore) break;
53: if (curart < 1) {
54: curart = 1;
55: eod = nomore = FALSE;
56: }
57: if (curart > lastart) curart = lastart;
58: if (eod) nomore = TRUE;
59: if (printh && !nomore)
60: (void) dhprint(curart, ifp, ofp);
61: getcmd:
62: loop {
63: sigtrap = FALSE;
64: fprintf(ofp, "Digest article %d of %d ", curart, lastart);
65: if (curart==lastart && nomore)
66: fprintf(ofp, "Last digest article ");
67: fprintf(ofp, "(%d lines) More? [%s] ",
68: arts[curart].a_blen, nomore?"snq":"ynq");
69: (void) fflush(ofp);
70: cmd = cbuf;
71: if (fgets(cmd, BUFLEN, stdin))
72: break;
73: if (!sigtrap)
74: return(TRUE);
75: putc('\n', ofp);
76: }
77: nstrip(cmd);
78: while (*cmd==' ' || *cmd=='\t')
79: cmd++;
80: printh = TRUE;
81:
82: switch (*cmd++) {
83: case '#':
84: fprintf(ofp, "%d articles in digest\n", lastart);
85: (void) fflush(ofp);
86: printh = FALSE;
87: break;
88:
89: case '$':
90: curart = lastart;
91: break;
92:
93: case '!':
94: fwait(fsubr(ushell, cmd, (char *)NULL));
95: fprintf(ofp, "!\n");
96: printh = FALSE;
97: break;
98:
99: case '\0':
100: if (nomore) {
101: putc('\n', ofp);
102: return(FALSE);
103: }
104: cmd--;
105: case 'y':
106: case 'p':
107: errchk(cmd);
108: dprint(curart++, ifp, ofp);
109: if (curart > lastart)
110: eod = TRUE;
111: break;
112:
113: case 'n':
114: errchk(cmd);
115: if (++curart > lastart) {
116: putc('\n', ofp);
117: return(FALSE);
118: }
119: break;
120:
121: case '+':
122: getnum(cmd, n);
123: errchk(cmd);
124: if (nomore) {
125: putc('\n', ofp);
126: return(FALSE);
127: }
128: if (n) curart += n;
129: else {
130: curart += 1;
131: if (curart > lastart)
132: eod = TRUE;
133: }
134: break;
135:
136: case '-':
137: getnum(cmd, n);
138: errchk(cmd);
139: eod = nomore = FALSE;
140: curart -= (n) ? n : 1;
141: break;
142:
143: case '0': case '1': case '2': case '3': case '4':
144: case '5': case '6': case '7': case '8': case '9':
145: cmd--;
146: getnum(cmd, n);
147: errchk(cmd);
148: curart = n;
149: eod = nomore = FALSE;
150: break;
151:
152: case 'q':
153: case 'x':
154: putc('\n', ofp);
155: return(FALSE);
156:
157: case '?':
158: fprintf(ofp, "\nDigester options:\n\n");
159: fprintf(ofp, "y\tyes, print article.\n");
160: fprintf(ofp, "n\tno, go to next article.\n");
161: fprintf(ofp, "q\texit from digester.\n");
162: fprintf(ofp, "h\tprint article header.\n");
163: fprintf(ofp, "s file\tsave article in file.\n");
164: fprintf(ofp, "t\ttable of contents.\n");
165: fprintf(ofp, "+[n]\tforward n articles (1).\n");
166: fprintf(ofp, "-[n]\tback n articles (1).\n");
167: fprintf(ofp, "\nh and s may be followed by '-'\n");
168: (void) fflush(ofp);
169: break;
170:
171: case 'h':
172: n = curart;
173: if (*cmd=='-') {
174: cmd++;
175: if (n > 1) n--;
176: }
177: errchk(cmd);
178: (void) dhprint(n, ifp, ofp);
179: nomore = printh = FALSE;
180: if (n!=curart)
181: putc('\n', ofp);
182: break;
183:
184: case 's':
185: case 'w':
186: n = curart;
187: if (*cmd=='-') {
188: cmd++;
189: if (n > 1) n--;
190: }
191: while (*cmd==' ' || *cmd=='\t')
192: cmd++;
193: dsaveart(n, ifp, ofp, cmd);
194: nomore = printh = FALSE;
195: if (n!=curart)
196: putc('\n', ofp);
197: break;
198:
199: case 'H':
200: errchk(cmd);
201: hprint(h, !cflag, ofp, 1);
202: eod = nomore = FALSE;
203: break;
204:
205: case 'T':
206: case 't':
207: errchk(cmd);
208: if (cmd[-1]=='T')
209: hprint(h, !cflag, ofp, 0);
210: dprint(0, ifp, ofp);
211: eod = nomore = FALSE;
212: break;
213:
214: default:
215: badopt:
216: if (!nomore)
217: fprintf(ofp, "y (yes), n (no), ");
218: fprintf(ofp, "q (quit), s file (save), h (header), t (table of contents)\n");
219: fprintf(ofp, "? for help\n");
220: goto getcmd;
221: }
222: }
223: putc('\n', ofp);
224: return(FALSE);
225: }
226:
227: dscan(ifp)
228: register FILE *ifp;
229: {
230: char scanbuf[BUFLEN];
231: register int n, len;
232: register char *s;
233: register long pos;
234: short wasblank;
235:
236: n = len = 0;
237: wasblank = FALSE;
238: s = scanbuf;
239: arts[0].a_bod = arts[1].a_hdr = ftell(ifp);
240: arts[0].a_hdr = 0L;
241: arts[1].a_bod = -1L;
242:
243: loop {
244: if (sigtrap)
245: return(TRUE);
246: pos = ftell(ifp);
247: if (fgets(s, BUFLEN, ifp)==NULL)
248: *s = '\0';
249: if (wasblank && isheader(s)) {
250: long lastpos;
251: short isblank;
252: short nhlines;
253: arts[n++].a_blen = len;
254: len = 0;
255: nhlines = 0;
256: arts[n].a_hdr = pos;
257: isblank = FALSE;
258: do {
259: lastpos = pos;
260: wasblank = isblank;
261: nhlines++;
262: pos = ftell(ifp);
263: if (fgets(s, BUFLEN, ifp)==NULL)
264: *s = '\0';
265: else
266: len++;
267: isblank = (*s=='\n') ? TRUE : FALSE;
268: if (isblank && nhlines==1)
269: /* one liner--not a header */
270: break;
271: } while ((isblank && !wasblank) || isheader(s));
272: if ((!isblank && !wasblank) || nhlines < 2) {
273: /* oops! not a header... back off */
274: arts[n].a_hdr = arts[n-1].a_bod;
275: len += arts[--n].a_blen;
276: } else {
277: if (wasblank)
278: pos = lastpos;
279: arts[n].a_hlen = len;
280: arts[n].a_bod = arts[n+1].a_hdr = pos;
281: arts[n+1].a_bod = -1L;
282: arts[n+1].a_hlen = 3; /* average header len */
283: len = 0;
284: }
285: }
286: if (*s=='\0')
287: break;
288: wasblank = (*s=='\n') ? TRUE : FALSE;
289: len++;
290: }
291: arts[n].a_blen = len;
292: arts[n+1].a_hdr = pos;
293: lastart = n;
294: return(FALSE);
295: }
296:
297: dhprint(art, ifp, ofp)
298: register int art;
299: register FILE *ifp, *ofp;
300: {
301: register char c;
302: register long pos = arts[art].a_hdr;
303: register long epos = arts[art].a_bod;
304: register int nlines = 1;
305:
306: putc('\n', ofp);
307: fseek(ifp, pos, 0);
308: while (pos++ < epos && !sigtrap) {
309: if ((c = getc(ifp))=='\n')
310: nlines++;
311: putc(c, ofp);
312: }
313: (void) fflush(ofp);
314: sigtrap = FALSE;
315: return(nlines);
316: }
317:
318: dprint(art, ifp, ofp)
319: int art;
320: FILE *ifp, *ofp;
321: {
322: #ifdef PAGE
323: register int cnt;
324: FILE *pfp, *popen();
325:
326: if (art && arts[art].a_blen > 23-arts[art+1].a_hlen && *PAGER) {
327: if (!index(PAGER, FMETA)) {
328: if ((pfp = popen(PAGER, "w"))==NULL)
329: (void) dprinta(art, ifp, ofp);
330: else {
331: cnt = dprinta(art, ifp, pfp) % 23;
332: if (cnt > 23-arts[art+1].a_hlen)
333: while (cnt++ < 24)
334: putc('\n', pfp);
335: (void) pclose(pfp);
336: }
337: } else
338: pout(ofp);
339: } else
340: #endif PAGE
341: (void) dprinta(art, ifp, ofp);
342: }
343:
344: dprinta(art, ifp, ofp)
345: int art;
346: register FILE *ifp, *ofp;
347: {
348: register char c;
349: register long pos = arts[art].a_bod;
350: register long epos = arts[art+1].a_hdr;
351: register int nlines = 0;
352:
353: fseek(ifp, pos, 0);
354: while (pos++ < epos && !sigtrap) {
355: if ((c = getc(ifp))=='\n')
356: nlines++;
357: putc(c, ofp);
358: }
359: (void) fflush(ofp);
360: sigtrap = FALSE;
361: return(nlines);
362: }
363:
364: dsaveart(art, ifp, ofp, name)
365: int art;
366: register FILE *ifp, *ofp;
367: register char *name;
368: {
369: register FILE *nfp;
370: char fname[BUFLEN];
371: char *strcat(), *strcpy(), *getenv();
372: register char *nb;
373:
374: while (*name==' ' || *name=='\t')
375: name++;
376:
377: if (*name=='|') {
378: fprintf(ofp, "don't know how to pipe yet.\n");
379: (void) fflush(ofp);
380: return;
381: } else if (*name=='/')
382: (void) strcpy(fname, name);
383: else {
384: if (nb = getenv("NEWSBOX"))
385: (void) strcpy(fname, nb);
386: else
387: (void) strcpy(fname, userhome);
388: (void) strcat(fname, "/");
389: (void) strcat(fname, name);
390: }
391:
392: fprintf(ofp, "Save digest article %d in \"%s\"", art, fname);
393: (void) fflush(ofp);
394: if ((nfp = fopen(fname, "a"))!=NULL) {
395: int ln;
396: ln = dhprint(art, ifp, nfp);
397: ln += dprinta(art, ifp, nfp);
398: fprintf(ofp, " [Appended] %d lines\n", ln);
399: (void) fclose(nfp);
400: } else
401: fprintf(ofp, " cannot append to.\n");
402: }
403:
404: isheader(s)
405: register char *s;
406: {
407: if (isupper(*s) || islower(*s)) {
408: while (*s && *s!=':' && !isspace(*s))
409: s++;
410: if (*s==':' && *++s==' ')
411: return(TRUE);
412: }
413: return(FALSE);
414: }
415:
416:
417:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.