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: }

Defined functions

formataddr defined in line 246; never used
insert defined in line 317; used 1 times
replfilter defined in line 354; used 1 times
replout defined in line 49; used 1 times

Defined variables

badaddrs defined in line 22; used 4 times
buf defined in line 216; used 11 times
bufend defined in line 217; used 4 times
bufsiz defined in line 219; used 6 times
compbuffers defined in line 40; used 3 times
dat defined in line 43; used 5 times
dfhost defined in line 23; used 1 times
dftype defined in line 20; used 1 times
fmt defined in line 37; used 2 times
last_dst defined in line 218; used 2 times
mq defined in line 25; used 1 times
ncomps defined in line 39; used 5 times
used_buf defined in line 41; used 6 times

Defined macros

BUFINCR defined in line 221; used 4 times
CHECKMEM defined in line 226; used 3 times
CPY defined in line 223; used 3 times
SBUFSIZ defined in line 28; used 4 times
Last modified: 1986-05-13
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1939
Valid CSS Valid XHTML 1.0 Strict