|
|
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.