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