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

unix.superglobalmegacorp.com

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