Annotation of 43BSD/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 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.