Annotation of 43BSDReno/contrib/mh/uip/scansbr.c, revision 1.1

1.1     ! root        1: /* scansbr.c - routines to help scan along... */
        !             2: 
        !             3: #include "../h/mh.h"
        !             4: #include "../h/addrsbr.h"
        !             5: #include "../h/formatsbr.h"
        !             6: #include "../h/scansbr.h"
        !             7: #include "../zotnet/tws.h"
        !             8: #include <stdio.h>
        !             9: #include <ctype.h>
        !            10: #include <sys/types.h>
        !            11: #include <sys/stat.h>
        !            12: 
        !            13: 
        !            14: #define MAXSCANL 510           /* longest possible scan line */
        !            15: #define SBUFSIZ 256            
        !            16:                                /* buffer size for content part of header
        !            17:                                 * fields.  We want this to be large
        !            18:                                 * enough so that we don't do a lot of
        !            19:                                 * extra FLDPLUS calls on m_getfld but
        !            20:                                 * small enough so that we don't snarf
        !            21:                                 * the entire message body when we're
        !            22:                                 * only going to display 30 characters
        !            23:                                 * of it.
        !            24:                                 */
        !            25: 
        !            26: /*  */
        !            27: 
        !            28: static struct format *fmt;
        !            29: 
        !            30: static struct comp *datecomp;  /* pntr to "date" comp */
        !            31: static struct comp *bodycomp;  /* pntr to "body" pseudo-comp (if referenced) */
        !            32: static int ncomps = 0;         /* # of interesting components */
        !            33: static char **compbuffers = 0; /* buffers for component text */
        !            34: static struct comp **used_buf = 0; /* stack for comp that use buffers */
        !            35: 
        !            36: char *scanl = 0;               /* text of most recent scanline */
        !            37: 
        !            38: static int dat[4];             /* aux. data for format routine */
        !            39: 
        !            40: #ifdef RPATHS
        !            41: char *unixline();              /* info from UNIX From: line */
        !            42: #endif RPATHS
        !            43: 
        !            44: #define FPUTS(buf) {\
        !            45:                if (fputs(buf,scnout) == EOF)\
        !            46:                    adios (scnmsg, "write error on");\
        !            47:                }
        !            48: 
        !            49: /*  */
        !            50: 
        !            51: /* ARGSUSED */
        !            52: 
        !            53: scan(inb, innum, outnum, nfs, width, curflg, header, size, noisy, aud)
        !            54:        register FILE *inb;
        !            55:        char *nfs;
        !            56:        int innum, outnum, width, curflg, header;
        !            57:        long size;
        !            58:        int noisy, aud;
        !            59: {
        !            60:        int compnum, encrypted, state;
        !            61:        register int i;
        !            62:        register struct comp *cptr;
        !            63:        register char *tmpbuf;
        !            64:        register char **nxtbuf;
        !            65:        register struct comp **savecomp;
        !            66:        char *scnmsg;
        !            67:        FILE *scnout;
        !            68:        char name[NAMESZ];
        !            69:        static int slwidth;
        !            70: #ifdef RPATHS
        !            71:        char *cp;
        !            72: #endif RPATHS
        !            73: 
        !            74:        /* first-time only initialization */
        !            75:        if (scanl == NULLCP) {
        !            76:                if (width == 0) {
        !            77:                        if ((width = sc_width()) < WIDTH / 2)
        !            78:                                width = WIDTH / 2;
        !            79:                        else if (width > MAXSCANL)
        !            80:                                width = MAXSCANL;
        !            81:                }
        !            82:                dat[3] = slwidth = width;
        !            83:                scanl = (char *) malloc((unsigned)MAXSCANL+2);
        !            84:                if (outnum)
        !            85:                        (void) umask(~m_gmprot());
        !            86: 
        !            87:                ncomps = fmt_compile(nfs, &fmt) + 1;
        !            88:                FINDCOMP(bodycomp, "body");
        !            89:                FINDCOMP(datecomp, "date");
        !            90:                FINDCOMP(cptr, "encrypted");
        !            91:                if (!cptr)
        !            92:                        if (cptr = (struct comp *) calloc(1, sizeof *cptr)) {
        !            93:                                cptr->c_name = "encrypted";
        !            94:                                cptr->c_next =
        !            95:                                    wantcomp[i = CHASH(cptr->c_name)];
        !            96:                                wantcomp[i] = cptr;
        !            97:                                ncomps++;
        !            98:                        }
        !            99:                nxtbuf = compbuffers = (char **)
        !           100:                    calloc((unsigned) ncomps, sizeof(char *));
        !           101:                if (nxtbuf == NULL)
        !           102:                        adios(NULLCP, "unable to allocate component buffers");
        !           103:                used_buf = (struct comp **)
        !           104:                    calloc((unsigned) (ncomps + 1), sizeof(struct comp *));
        !           105:                if (used_buf == NULL)
        !           106:                        adios(NULLCP, "unable to allocate component buffer stack");
        !           107:                used_buf += ncomps + 1;
        !           108:                *--used_buf = 0;
        !           109:                for (i = ncomps; i--;)
        !           110:                        if ((*nxtbuf++ = malloc(SBUFSIZ)) == NULL)
        !           111:                                adios(NULLCP,
        !           112:                                    "unable to allocate component buffer");
        !           113:        }
        !           114:        /* each-message initialization */
        !           115:        nxtbuf = compbuffers;
        !           116:        savecomp = used_buf;
        !           117:        tmpbuf = *nxtbuf++;
        !           118:        dat[0] = innum ? innum : outnum;
        !           119:        dat[1] = curflg;
        !           120: 
        !           121:        /*
        !           122:         * get the first field.  If the msg is non-empty and we're doing
        !           123:         * an "inc", open the output file.
        !           124:         */
        !           125:        if ((state = m_getfld(FLD, name, tmpbuf, SBUFSIZ, inb)) == FILEEOF)
        !           126:                return SCNEOF;
        !           127: 
        !           128:        if (outnum) {
        !           129:                if (outnum > 0) {
        !           130:                        scnmsg = m_name(outnum);
        !           131:                        if (*scnmsg == '?')     /* msg num out of range */
        !           132:                                return SCNNUM;
        !           133:                } else
        !           134:                        scnmsg = "/dev/null";
        !           135:                if ((scnout = fopen(scnmsg, "w")) == NULL)
        !           136:                        adios(scnmsg, "unable to write");
        !           137: #ifdef RPATHS
        !           138:                if ((cp = unixline()) && *cp != '\n') {
        !           139:                        FPUTS("Return-Path: ");
        !           140:                        FPUTS(cp);
        !           141:                }
        !           142: #endif RPATHS
        !           143:        }
        !           144:        /* scan - main loop */
        !           145:        for (compnum = 1;;
        !           146:            state = m_getfld(state, name, tmpbuf, SBUFSIZ, inb)) {
        !           147:                switch (state) {
        !           148:                case FLD:
        !           149:                case FLDPLUS:
        !           150:                        compnum++;
        !           151:                        if (outnum) {
        !           152:                                FPUTS(name);
        !           153:                                (void) putc(':', scnout);
        !           154:                                FPUTS(tmpbuf);
        !           155:                        }
        !           156:                        /*
        !           157:                         * If we're interested in this component, save a
        !           158:                         * pointer to the component text, then start using
        !           159:                         * our next free buffer as the component temp buffer
        !           160:                         * (buffer switching saves an extra copy of the
        !           161:                         * component text).
        !           162:                         */
        !           163:                        if (cptr = wantcomp[CHASH(name)])
        !           164:                                do {
        !           165:                                        if (uleq(name, cptr->c_name)) {
        !           166:                                                if (!cptr->c_text) {
        !           167:                                                        cptr->c_text = tmpbuf;
        !           168:                                                        *--savecomp = cptr;
        !           169:                                                        tmpbuf = *nxtbuf++;
        !           170:                                                }
        !           171:                                                break;
        !           172:                                        }
        !           173:                                } while (cptr = cptr->c_next);
        !           174: 
        !           175:                        while (state == FLDPLUS) {
        !           176:                                state =
        !           177:                                    m_getfld(state, name, tmpbuf, SBUFSIZ, inb);
        !           178:                                if (outnum)
        !           179:                                        FPUTS(tmpbuf);
        !           180:                        }
        !           181:                        break;
        !           182: 
        !           183:                case BODY:
        !           184:                        compnum = -1;
        !           185:                        if (!outnum) {
        !           186:                                state = FILEEOF; /* stop now if scan cmd */
        !           187:                                goto finished;
        !           188:                        }
        !           189:                        (void) putc('\n', scnout);
        !           190:                        FPUTS(tmpbuf);
        !           191:                        /*
        !           192:                         * Performance hack: some people like to run "inc" on
        !           193:                         * things like net.sources or large digests.  We do a
        !           194:                         * copy directly into the output buffer rather than
        !           195:                         * going through an intermediate buffer.
        !           196:                         *
        !           197:                         * We need the amount of data m_getfld found & don't
        !           198:                         * want to do a strlen on the long buffer so there's
        !           199:                         * a hack in m_getfld to save the amount of data it
        !           200:                         * returned in the global "msg_count".
        !           201:                         */
        !           202: body:          
        !           203:                        while (state == BODY) {
        !           204:                                if (scnout->_cnt <= 0) {
        !           205:                                        if (fflush(scnout) == EOF)
        !           206:                                                adios(scnmsg, "write error on");
        !           207:                                }
        !           208:                                state = m_getfld(state, name,
        !           209:                                    scnout->_ptr, -(scnout->_cnt), inb);
        !           210:                                scnout->_cnt -= msg_count;
        !           211:                                scnout->_ptr += msg_count;
        !           212:                        }
        !           213:                        goto finished;
        !           214: 
        !           215:                case LENERR:
        !           216:                case FMTERR:
        !           217:                        fprintf(stderr,
        !           218:                                innum ? "??Format error (message %d) in "
        !           219:                                : "??Format error in ",
        !           220:                                outnum ? outnum : innum);
        !           221:                        fprintf(stderr, "component %d\n", compnum);
        !           222: 
        !           223:                        if (outnum) {
        !           224:                                FPUTS("\n\nBAD MSG:\n");
        !           225:                                FPUTS(name);
        !           226:                                (void) putc('\n', scnout);
        !           227:                                state = BODY;
        !           228:                                goto body;
        !           229:                        }
        !           230:                        /* fall through */
        !           231: 
        !           232:                case FILEEOF:
        !           233:                        goto finished;
        !           234: 
        !           235:                default:
        !           236:                        adios(NULLCP, "getfld() returned %d", state);
        !           237:                }
        !           238:        }
        !           239:        /* format and output the scan line. */
        !           240: finished:
        !           241:        if (noisy || aud) {
        !           242:                char *saved_c_text;
        !           243: 
        !           244:                if (bodycomp) {
        !           245:                        /* Save and restore buffer so we don't trash our
        !           246:                           dynamic pool! */
        !           247:                        saved_c_text = bodycomp->c_text;
        !           248:                        bodycomp->c_text = tmpbuf;
        !           249:                }
        !           250:                if (size)
        !           251:                        dat[2] = size;
        !           252:                else if (outnum > 0)
        !           253:                        dat[2] = ftell(scnout);
        !           254: 
        !           255:                if ((datecomp && !datecomp->c_text) || (!size && !outnum)) {
        !           256:                        struct stat st;
        !           257:                        (void) fstat(fileno(inb), &st);
        !           258:                        if (!size && !outnum)
        !           259:                                dat[2] = st.st_size;
        !           260:                        if (datecomp) {
        !           261:                                if (!datecomp->c_text) {
        !           262:                                        if (datecomp->c_tws == NULL)
        !           263:                                                datecomp->c_tws = (struct tws *)
        !           264:                                                    calloc((unsigned) 1,
        !           265:                                                    sizeof(*datecomp->c_tws));
        !           266:                                        if (datecomp->c_tws == NULL)
        !           267:                                                adios(NULLCP,
        !           268:                                            "unable to allocate tws buffer");
        !           269:                                        *datecomp->c_tws =
        !           270:                                            *dlocaltime((long *) &st.st_mtime);
        !           271:                                        datecomp->c_flags = -1;
        !           272:                                } else {
        !           273:                                        datecomp->c_flags = 0;
        !           274:                                }
        !           275:                        }
        !           276:                }
        !           277:                (void) fmtscan(fmt, scanl, slwidth, dat);
        !           278:                if (aud)
        !           279:                        (void) fputs(scanl, aud);
        !           280:                if (noisy)
        !           281:                        (void) fputs(scanl, stdout);
        !           282: 
        !           283:                if (bodycomp)
        !           284:                        bodycomp->c_text = saved_c_text;
        !           285:        }
        !           286:        FINDCOMP(cptr, "encrypted");
        !           287:        encrypted = cptr && cptr->c_text;
        !           288:        /* return dynamically allocated buffers to pool */
        !           289:        while (cptr = *savecomp++) {
        !           290:                *--nxtbuf = cptr->c_text;
        !           291:                cptr->c_text = NULLCP;
        !           292:        }
        !           293:        *--nxtbuf = tmpbuf;
        !           294: 
        !           295:        if (outnum && fclose(scnout) == EOF)
        !           296:                adios(scnmsg, "write error on");
        !           297: 
        !           298:        return (state != FILEEOF ? SCNERR : encrypted ? SCNENC : SCNMSG);
        !           299: }
        !           300: 
        !           301: /*  */
        !           302: 
        !           303: /*
        !           304:  * Cheat:  we are loaded with adrparse, which wants a routine called
        !           305:  * OfficialName().  We call adrparse:getm() with the correct arguments
        !           306:  * to prevent OfficialName() from being called.  Hence, the following
        !           307:  * is to keep the loader happy.
        !           308:  */
        !           309: 
        !           310: /* XXX don't bother if linking with the shared library */
        !           311: #ifndef SHARED
        !           312: char *
        !           313: OfficialName(name)
        !           314:        register char *name;
        !           315: {
        !           316:        return name;
        !           317: }
        !           318: 
        !           319: #endif

unix.superglobalmegacorp.com

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