Annotation of researchv10no/cmd/netnews/src/digest.c, revision 1.1.1.1

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: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.