Annotation of 43BSDReno/contrib/mh/uip/replsbr.c, revision 1.1.1.1

1.1       root        1: /* replsbr.c - routines to help repl along... */
                      2: 
                      3: #include "../h/mh.h"
                      4: #include "../h/addrsbr.h"
                      5: #include "../h/formatsbr.h"
                      6: #include <ctype.h>
                      7: #include <stdio.h>
                      8: 
                      9: 
                     10: extern short    ccto,          /* from repl.c */
                     11:                 cccc,
                     12:                 ccme,
                     13:                 format,
                     14:                 outputlinelen,
                     15:                querysw;
                     16: extern char *fcc,
                     17:            *filter,
                     18:             *form;
                     19: 
                     20: static int   dftype;
                     21: 
                     22: static char *badaddrs = NULL;
                     23: static char *dfhost;
                     24: 
                     25: static struct mailname  mq;
                     26: 
                     27: 
                     28: #define SBUFSIZ 256
                     29:                                /* buffer size for content part of header
                     30:                                 * fields.  We want this to be large
                     31:                                 * enough so that we don't do a lot of
                     32:                                 * extra FLDPLUS calls on m_getfld but
                     33:                                 * small enough so that we don't snarf
                     34:                                 * the entire message body when we're
                     35:                                 * not going to use any of it.
                     36:                                 */
                     37: 
                     38: static struct format *fmt;
                     39: 
                     40: static int     ncomps = 0;             /* # of interesting components */
                     41: static char    **compbuffers = 0;      /* buffers for component text */
                     42: static struct comp **used_buf = 0;     /* stack for comp that use buffers */
                     43: 
                     44: static int dat[4];                     /* aux. data for format routine */
                     45: 
                     46: static void replfilter();
                     47: static int insert();
                     48: 
                     49: /*  */
                     50: 
                     51: /* ARGSUSED */
                     52: 
                     53: replout(inb, msg, drft)
                     54:        register FILE *inb;
                     55:        char *msg, *drft;
                     56: {
                     57:     register int  state;
                     58:     register int  i;
                     59:     register struct comp *cptr;
                     60:     register char *tmpbuf;
                     61:     register char **nxtbuf;
                     62:     register struct comp **savecomp;
                     63:     FILE    *out;
                     64:     char    name[NAMESZ];
                     65:     char    *scanl;
                     66:     int            char_read = 0;
                     67:     char    *cp;
                     68:     int      format_len;
                     69: 
                     70:     (void) umask( ~ m_gmprot() );
                     71:     if ((out = fopen (drft, "w")) == NULL)
                     72:        adios (drft, "unable to create");
                     73: 
                     74:     cp = new_fs (form ? form : replcomps, NULLCP, NULLCP);
                     75:     format_len = strlen (cp);
                     76:     ncomps = fmt_compile (cp, &fmt) + 1;
                     77:     nxtbuf = compbuffers = (char **)calloc((unsigned)ncomps,sizeof(char *));
                     78:     if (nxtbuf == NULL)
                     79:        adios (NULLCP, "unable to allocate component buffers");
                     80:     savecomp = used_buf = (struct comp **)calloc((unsigned)(ncomps+1),
                     81:        sizeof(struct comp *));
                     82:     if (used_buf == NULL)
                     83:        adios (NULLCP, "unable to allocate component buffer stack");
                     84:     savecomp += ncomps+1; *--savecomp = 0;
                     85:     for (i = ncomps; i--; )
                     86:        if ((*nxtbuf++ = malloc( SBUFSIZ )) == NULL)
                     87:            adios (NULLCP, "unable to allocate component buffer");
                     88: 
                     89:     nxtbuf = compbuffers;
                     90:     tmpbuf = *nxtbuf++;
                     91: 
                     92:     /* ignore any components killed by command line switches */
                     93:     if (!ccto) {
                     94:        FINDCOMP (cptr, "to");
                     95:        if (cptr)
                     96:            cptr->c_name = "";
                     97:     }
                     98:     if (!cccc) {
                     99:        FINDCOMP (cptr, "cc");
                    100:        if (cptr)
                    101:            cptr->c_name = "";
                    102:     }
                    103:     /* set up the "fcc" pseudo-component */
                    104:     if (fcc) {
                    105:        FINDCOMP (cptr, "fcc");
                    106:        if (cptr)
                    107:            cptr->c_text = getcpy (fcc);
                    108:     }
                    109:     if (!ccme)
                    110:        (void) ismymbox ((struct mailname *)0); /* XXX */
                    111: 
                    112:     /* pick any interesting stuff out of msg "inb" */
                    113:     for (state = FLD;;) {
                    114:        state = m_getfld (state, name, tmpbuf, SBUFSIZ, inb);
                    115:        switch (state) {
                    116:            case FLD:
                    117:            case FLDPLUS:
                    118:                /*
                    119:                 * if we're interested in this component, save a pointer
                    120:                 * to the component text, then start using our next free
                    121:                 * buffer as the component temp buffer (buffer switching
                    122:                 * saves an extra copy of the component text).
                    123:                 */
                    124:                if (cptr = wantcomp[CHASH(name)])
                    125:                    do {
                    126:                        if (uleq(name, cptr->c_name)) {
                    127:                            char_read += msg_count;
                    128:                            if (! cptr->c_text) {
                    129:                                cptr->c_text = tmpbuf;
                    130:                                *--savecomp = cptr;
                    131:                                /* Zero pointer to avoid freeing memory twice */
                    132:                                nxtbuf--;
                    133:                                *nxtbuf = 0;
                    134:                                nxtbuf++;
                    135:                                tmpbuf = *nxtbuf++;
                    136:                            } else {
                    137:                                i = strlen (cp = cptr->c_text) - 1;
                    138:                                if (cp[i] == '\n')
                    139:                                    if (cptr->c_type & CT_ADDR) {
                    140:                                        cp[i] = '\0';
                    141:                                        cp = add (",\n\t", cp);
                    142:                                    } else {
                    143:                                        cp = add ("\t", cp);
                    144:                                    }
                    145:                                cptr->c_text = add (tmpbuf, cp);
                    146:                            }
                    147:                            while (state == FLDPLUS) {
                    148:                                state = m_getfld (state, name, tmpbuf,
                    149:                                                  SBUFSIZ, inb);
                    150:                                cptr->c_text = add (tmpbuf, cptr->c_text);
                    151:                                char_read += msg_count;
                    152:                            }
                    153:                            break;
                    154:                        }
                    155:                    } while (cptr = cptr->c_next);
                    156: 
                    157:                while (state == FLDPLUS)
                    158:                    state = m_getfld (state, name, tmpbuf, SBUFSIZ, inb);
                    159:                break;
                    160: 
                    161:            case LENERR:
                    162:            case FMTERR:
                    163:            case BODY:
                    164:            case FILEEOF:
                    165:                goto finished;
                    166: 
                    167:            default:
                    168:                adios (NULLCP, "m_getfld() returned %d", state);
                    169:        }
                    170:     }
                    171:     /*
                    172:      * format and output the header lines.
                    173:      */
                    174: finished:
                    175:     /* if there's a "subject" component, strip any "re:"s off it */
                    176:     FINDCOMP (cptr, "subject")
                    177:     if (cptr && (cp = cptr->c_text)) {
                    178:        register char *sp = cp;
                    179: 
                    180:        for (;;) {
                    181:            while (isspace(i = *cp++))
                    182:                ;
                    183:            if ((i | 0x20) != 'r' || (*cp++ | 0x20) != 'e' || *cp++ != ':')
                    184:                break;
                    185:            sp = cp;
                    186:        }
                    187:        if (sp != cptr->c_text) {
                    188:            cp = cptr->c_text;
                    189:            cptr->c_text = getcpy (sp);
                    190:            free (cp);
                    191:        }
                    192:     }
                    193:     i = format_len + char_read + 256;
                    194:     scanl = malloc ((unsigned)i + 2);
                    195:     dat[0] = dat[1] = dat[2] = 0;
                    196:     dat[3] = outputlinelen;
                    197:     (void) fmtscan (fmt, scanl, i, dat);
                    198:     fputs (scanl, out);
                    199:     if (badaddrs) {
                    200:        fputs ("\nrepl: bad addresses:\n", out);
                    201:        fputs ( badaddrs, out);
                    202:     }
                    203:     if (filter)
                    204:        replfilter (inb, out);
                    205: 
                    206:     if (ferror (out))
                    207:        adios (drft, "error writing");
                    208:     (void) fclose (out);
                    209: 
                    210:     /* return dynamically allocated buffers */
                    211:     free (scanl);
                    212:     while ( cptr = *savecomp++ )
                    213:        free (cptr->c_text);
                    214:     for (nxtbuf = compbuffers, i = ncomps; i--; )
                    215:        if (*nxtbuf)
                    216:            free (*nxtbuf++);
                    217:     free ((char *) compbuffers);
                    218:     free ((char *) used_buf);
                    219: }
                    220: 
                    221: /*  */
                    222: 
                    223: static char *buf;              /* our current working buffer */
                    224: static char *bufend;           /* end of working buffer */
                    225: static char *last_dst;         /* buf ptr at end of last call */
                    226: static unsigned int bufsiz;    /* current size of buf */
                    227: 
                    228: #define BUFINCR 512            /* how much to expand buf when if fills */
                    229: 
                    230: #define CPY(s) { cp = (s); while (*dst++ = *cp++) ; --dst; }
                    231: 
                    232: /* check if there's enough room in buf for str.  add more mem if needed */
                    233: 
                    234: #define CHECKMEM(str) \
                    235:            if ((len = strlen (str) + 1) >= bufend - dst) {\
                    236:                bufsiz += ((dst + len - bufend) / BUFINCR + 1) * BUFINCR;\
                    237:                dst -= (unsigned int)buf;\
                    238:                last_dst -= (unsigned int)buf;\
                    239:                buf = realloc (buf, bufsiz);\
                    240:                if (! buf)\
                    241:                    adios (NULLCP, "formataddr: couldn't get buffer space");\
                    242:                dst += (unsigned int)buf;\
                    243:                last_dst += (unsigned int)buf;\
                    244:                bufend = buf + bufsiz;\
                    245:            }
                    246: 
                    247: 
                    248: /* fmtscan will call this routine if the user includes the function
                    249:  * "(formataddr {component})" in a format string.  "orig" is the
                    250:  * original contents of the string register.  "str" is the address
                    251:  * string to be formatted and concatenated onto orig.  This routine
                    252:  * returns a pointer to the concatenated address string.
                    253:  *
                    254:  * We try to not do a lot of malloc/copy/free's (which is why we
                    255:  * don't call "getcpy") but still place no upper limit on the
                    256:  * length of the result string.
                    257:  */
                    258: char *
                    259: formataddr(orig, str)
                    260:        char *orig, *str;
                    261: {
                    262:     register int  len;
                    263:     char    baddr[BUFSIZ],
                    264:            error[BUFSIZ];
                    265:     register int  isgroup;
                    266:     register char  *dst;
                    267:     register char  *cp;
                    268:     register char  *sp;
                    269:     register struct mailname *mp = NULL;
                    270: 
                    271:     /* if we don't have a buffer yet, get one */
                    272:     if (bufsiz == 0) {
                    273:        buf = malloc (BUFINCR);
                    274:        if (! buf)
                    275:            adios (NULLCP, "formataddr: couldn't allocate buffer space");
                    276:        bufsiz = BUFINCR - 6;  /* leave some slop */
                    277:        bufend = buf + bufsiz;
                    278:     }
                    279:     /*
                    280:      * If "orig" points to our buffer we can just pick up where we
                    281:      * left off.  Otherwise we have to copy orig into our buffer.
                    282:      */
                    283:     if (orig == buf)
                    284:        dst = last_dst;
                    285:     else if (!orig || !*orig) {
                    286:        dst = buf;
                    287:        *dst = '\0';
                    288:     } else {
                    289:        CHECKMEM (orig);
                    290:        CPY (orig);
                    291:     }
                    292: 
                    293:     /* concatenate all the new addresses onto 'buf' */
                    294:     for (isgroup = 0; cp = getname (str); ) {
                    295:        if ((mp = getm (cp, dfhost, dftype, AD_NAME, error)) == NULL) {
                    296:            (void) sprintf (baddr, "\t%s -- %s\n", cp, error);
                    297:            badaddrs = add (baddr, badaddrs);
                    298:            continue;
                    299:        }
                    300:        if (isgroup && (mp->m_gname || !mp->m_ingrp)) {
                    301:            *dst++ = ';';
                    302:            isgroup = 0;
                    303:        }
                    304:        if (insert (mp)) {
                    305:            /* if we get here we're going to add an address */
                    306:            if (dst != buf) {
                    307:                *dst++ = ',';
                    308:                *dst++ = ' ';
                    309:            }
                    310:            if (mp->m_gname) {
                    311:                CHECKMEM (mp->m_gname);
                    312:                CPY (mp->m_gname);
                    313:                isgroup++;
                    314:            }
                    315:            sp = adrformat (mp);
                    316:            CHECKMEM (sp);
                    317:            CPY (sp);
                    318:        }
                    319:     }
                    320: 
                    321:     if (isgroup)
                    322:        *dst++ = ';';
                    323: 
                    324:     *dst = '\0';
                    325:     last_dst = dst;
                    326:     return (buf);
                    327: }
                    328: /*  */
                    329: 
                    330: static int
                    331: insert(np)
                    332:        register struct mailname *np;
                    333: {
                    334:     char    buffer[BUFSIZ];
                    335:     register struct mailname *mp;
                    336: 
                    337:     if (np -> m_mbox == NULL)
                    338:        return 0;
                    339: 
                    340:     for (mp = &mq; mp -> m_next; mp = mp -> m_next) {
                    341: #ifdef BERK
                    342:        if (uleq (np -> m_mbox, mp -> m_next -> m_mbox))
                    343:            return 0;
                    344: #else not BERK
                    345:        if (uleq (np -> m_host, mp -> m_next -> m_host)
                    346:                && uleq (np -> m_mbox, mp -> m_next -> m_mbox))
                    347:            return 0;
                    348: #endif BERK
                    349:     }
                    350:     if (!ccme && ismymbox (np))
                    351:        return 0;
                    352: 
                    353:     if (querysw) {
                    354:        (void) sprintf (buffer, "Reply to %s? ", adrformat (np));
                    355:        if (!gans (buffer, anoyes))
                    356:        return 0;
                    357:     }
                    358:     mp -> m_next = np;
                    359: #ifdef ISI
                    360:     if (ismymbox (np))
                    361:        ccme = 0;
                    362: #endif ISI
                    363:     return 1;
                    364: }
                    365: 
                    366: /*  */
                    367: 
                    368: static void
                    369: replfilter(in, out)
                    370:        register FILE *in, *out;
                    371: {
                    372:     int            pid;
                    373:     char   *mhl;
                    374: 
                    375:     if (filter == NULL)
                    376:        return;
                    377: 
                    378:     if (access (filter, 04) == NOTOK)
                    379:        adios (filter, "unable to read");
                    380: 
                    381:     mhl = r1bindex (mhlproc, '/');
                    382: 
                    383:     rewind (in);
                    384:     (void) fflush (out);
                    385: 
                    386:     switch (pid = vfork ()) {
                    387:        case NOTOK:
                    388:            adios ("fork", "unable to");
                    389: 
                    390:        case OK:
                    391:            (void) dup2 (fileno (in), fileno (stdin));
                    392:            (void) dup2 (fileno (out), fileno (stdout));
                    393:            closefds (3);
                    394: 
                    395:            execlp (mhlproc, mhl, "-form", filter, "-noclear", NULLCP);
                    396:            fprintf (stderr, "unable to exec ");
                    397:            perror (mhlproc);
                    398:            _exit (-1);
                    399: 
                    400:        default:
                    401:            if (pidXwait (pid, mhl))
                    402:                done (1);
                    403:            (void) fseek (out, 0L, 2);
                    404:            break;
                    405:     }
                    406: }

unix.superglobalmegacorp.com

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