Annotation of 43BSDReno/contrib/mh/uip/scansbr.c, revision 1.1.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.