Annotation of 43BSD/contrib/news/src/digest.c, revision 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.