Annotation of researchv10no/cmd/netnews/src/digest.c, revision 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.