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: }

Defined functions

dhprint defined in line 302; used 3 times
digest defined in line 34; used 1 times
dprint defined in line 323; used 3 times
dprinta defined in line 349; used 4 times
dsaveart defined in line 369; used 1 times
dscan defined in line 229; used 1 times
  • in line 48
isheader defined in line 409; used 2 times

Defined variables

SccsId defined in line 13; never used
arts defined in line 31; used 25 times
lastart defined in line 32; used 10 times

Defined struct's

art defined in line 18; used 4 times
  • in line 31(2), 39(2)

Defined macros

MAXART defined in line 29; used 1 times
  • in line 39
errchk defined in line 27; used 8 times
getnum defined in line 26; used 3 times
loop defined in line 25; used 3 times
Last modified: 1986-01-20
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1711
Valid CSS Valid XHTML 1.0 Strict