Annotation of 43BSD/contrib/news/src/digest.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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