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