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

unix.superglobalmegacorp.com

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