9 date 95.12.06.23.47.26; author jromine; state Exp;
14 date 95.12.06.21.07.03; author jromine; state Exp;
19 date 93.09.04.19.31.32; author jromine; state Exp;
24 date 93.08.26.22.13.19; author jromine; state Exp;
29 date 93.08.25.17.27.35; author jromine; state Exp;
34 date 93.02.26.21.59.28; author jromine; state Exp;
39 date 92.12.15.00.20.22; author jromine; state Exp;
44 date 92.11.04.00.58.58; author jromine; state Exp;
49 date 92.02.05.07.26.30; author jromine; state Exp;
54 date 91.01.17.15.29.27; author mh; state Exp;
59 date 90.11.05.11.38.43; author mh; state Exp;
64 date 90.11.05.11.35.20; author mh; state Exp;
69 date 90.11.05.11.23.19; author mh; state Exp;
74 date 90.04.05.14.59.43; author sources; state Exp;
79 date 90.03.12.10.49.00; author sources; state Exp;
84 date 90.02.09.10.11.12; author sources; state Exp;
89 date 90.02.06.13.29.55; author sources; state Exp;
94 date 90.01.30.14.05.59; author sources; state Exp;
99 date 90.01.30.11.17.06; author sources; state Exp;
113 @/* replsbr.c - routines to help repl along... */
115 static char ident[] = "@@(#)$Id: replsbr.c,v 1.18 1995/12/06 21:07:03 jromine Exp jromine $";
119 #include "../h/addrsbr.h"
120 #include "../h/formatsbr.h"
123 #include <sys/types.h> /* off_t */
124 #include <sys/file.h> /* L_SET */
127 extern short ccto, /* from repl.c */
140 static char *badaddrs = NULL;
141 static char *dfhost=NULL;
143 static struct mailname mq={NULL};
147 /* buffer size for content part of header
148 * fields. We want this to be large
149 * enough so that we don't do a lot of
150 * extra FLDPLUS calls on m_getfld but
151 * small enough so that we don't snarf
152 * the entire message body when we're
153 * not going to use any of it.
156 static struct format *fmt;
158 static int ncomps = 0; /* # of interesting components */
159 static char **compbuffers = 0; /* buffers for component text */
160 static struct comp **used_buf = 0; /* stack for comp that use buffers */
162 static int dat[5]; /* aux. data for format routine */
164 static char *addrcomps[] = {
180 static insert(), replfilter();
185 replout (inb, msg, drft, mp)
193 register struct comp *cptr;
194 register char *tmpbuf;
195 register char **nxtbuf;
196 register struct comp **savecomp;
205 (void) umask( ~ m_gmprot() );
206 if ((out = fopen (drft, "w")) == NULL)
207 adios (drft, "unable to create");
209 cp = new_fs (form ? form : replcomps, NULLCP, NULLCP);
210 format_len = strlen (cp);
211 ncomps = fmt_compile (cp, &fmt) + 1;
212 if ((nxtbuf = compbuffers = (char **)
213 calloc((unsigned)ncomps,sizeof(char *)))
215 adios (NULLCP, "unable to allocate component buffers");
216 if ((savecomp = used_buf = (struct comp **)
217 calloc((unsigned)(ncomps+1),sizeof(struct comp *)))
218 == (struct comp **)NULL)
219 adios (NULLCP, "unable to allocate component buffer stack");
220 savecomp += ncomps + 1;
221 *--savecomp = (struct comp *)0; /* point at zero'd end minus 1 */
222 for (i = ncomps; i--; )
223 if ((*nxtbuf++ = malloc( SBUFSIZ )) == NULL)
224 adios (NULLCP, "unable to allocate component buffer");
226 nxtbuf = compbuffers; /* point at start */
229 for (ap = addrcomps; *ap; ap++) {
230 FINDCOMP (cptr, *ap);
232 cptr -> c_type |= CT_ADDR;
235 /* ignore any components killed by command line switches */
237 FINDCOMP (cptr, "to");
242 FINDCOMP (cptr, "cc");
246 /* set up the "fcc" pseudo-component */
248 FINDCOMP (cptr, "fcc");
250 cptr->c_text = getcpy (fcc);
252 if (cp = getenv("USER")) {
253 FINDCOMP (cptr, "user");
255 cptr->c_text = getcpy(cp);
258 (void) ismymbox ((struct mailname *)0); /* XXX */
260 /* pick any interesting stuff out of msg "inb" */
261 for (state = FLD;;) {
262 state = m_getfld (state, name, tmpbuf, SBUFSIZ, inb);
267 * if we're interested in this component, save a pointer
268 * to the component text, then start using our next free
269 * buffer as the component temp buffer (buffer switching
270 * saves an extra copy of the component text).
272 if (cptr = wantcomp[CHASH(name)])
274 if (uleq(name, cptr->c_name)) {
275 char_read += msg_count;
276 if (! cptr->c_text) {
277 cptr->c_text = tmpbuf;
281 i = strlen (cp = cptr->c_text) - 1;
283 if (cptr->c_type & CT_ADDR) {
285 cp = add (",\n\t", cp);
289 cptr->c_text = add (tmpbuf, cp);
291 while (state == FLDPLUS) {
292 state = m_getfld (state, name, tmpbuf,
294 cptr->c_text = add (tmpbuf, cptr->c_text);
295 char_read += msg_count;
299 } while (cptr = cptr->c_next);
301 while (state == FLDPLUS)
302 state = m_getfld (state, name, tmpbuf, SBUFSIZ, inb);
312 adios (NULLCP, "m_getfld() returned %d", state);
316 * format and output the header lines.
319 /* if there's a "subject" component, strip any "re:"s off it */
320 FINDCOMP (cptr, "subject")
321 if (cptr && (cp = cptr->c_text)) {
322 register char *sp = cp;
333 if (sp != cptr->c_text) {
335 cptr->c_text = getcpy (sp);
339 i = format_len + char_read + 256;
340 scanl = malloc ((unsigned)i + 2);
341 dat[0] = dat[1] = dat[2] = dat[4] = 0;
342 dat[3] = outputlinelen;
343 (void) fmtscan (fmt, scanl, i, dat);
346 fputs ("\nrepl: bad addresses:\n", out);
347 fputs ( badaddrs, out);
350 replfilter (inb, out);
354 (void) fprintf (out, "#forw [original message] +%s %s\n",
355 mp -> foldpath, m_name (mp -> lowsel));
359 adios (drft, "error writing");
362 /* return dynamically allocated buffers */
364 for (nxtbuf = compbuffers, i = ncomps;
365 cptr = *savecomp++; nxtbuf++, i--)
366 free (cptr->c_text); /* if not nxtbuf, nxtbuf already freed */
368 free (*nxtbuf++); /* free unused nxtbufs */
369 free ((char *) compbuffers);
370 free ((char *) used_buf);
375 static char *buf; /* our current working buffer */
376 static char *bufend; /* end of working buffer */
377 static char *last_dst; /* buf ptr at end of last call */
378 static unsigned int bufsiz=0; /* current size of buf */
380 #define BUFINCR 512 /* how much to expand buf when if fills */
382 #define CPY(s) { cp = (s); while (*dst++ = *cp++) ; --dst; }
384 /* check if there's enough room in buf for str. add more mem if needed */
385 #define CHECKMEM(str) \
386 if ((len = strlen (str) + 1) >= bufend - dst) {\
388 int n = last_dst - buf;\
389 bufsiz += ((dst + len - bufend) / BUFINCR + 1) * BUFINCR;\
390 buf = realloc (buf, bufsiz);\
394 adios (NULLCP, "formataddr: couldn't get buffer space");\
395 bufend = buf + bufsiz;\
399 /* fmtscan will call this routine if the user includes the function
400 * "(formataddr {component})" in a format string. "orig" is the
401 * original contents of the string register. "str" is the address
402 * string to be formatted and concatenated onto orig. This routine
403 * returns a pointer to the concatenated address string.
405 * We try to not do a lot of malloc/copy/free's (which is why we
406 * don't call "getcpy") but still place no upper limit on the
407 * length of the result string.
409 char *formataddr (orig, str)
416 register int isgroup;
420 register struct mailname *mp = NULL;
422 /* if we don't have a buffer yet, get one */
424 buf = malloc (BUFINCR);
426 adios (NULLCP, "formataddr: couldn't allocate buffer space");
427 last_dst = buf; /* XXX */
428 bufsiz = BUFINCR - 6; /* leave some slop */
429 bufend = buf + bufsiz;
432 * If "orig" points to our buffer we can just pick up where we
433 * left off. Otherwise we have to copy orig into our buffer.
437 else if (!orig || !*orig) {
441 dst = last_dst; /* XXX */
446 /* concatenate all the new addresses onto 'buf' */
447 for (isgroup = 0; cp = getname (str); ) {
448 if ((mp = getm (cp, dfhost, dftype, AD_NAME, error)) == NULL) {
449 (void) sprintf (baddr, "\t%s -- %s\n", cp, error);
450 badaddrs = add (baddr, badaddrs);
453 if (isgroup && (mp->m_gname || !mp->m_ingrp)) {
458 /* if we get here we're going to add an address */
464 CHECKMEM (mp->m_gname);
484 register struct mailname *np;
487 register struct mailname *mp;
489 if (np -> m_mbox == NULL)
492 for (mp = &mq; mp -> m_next; mp = mp -> m_next) {
494 if (uleq (np -> m_mbox, mp -> m_next -> m_mbox))
497 if (uleq (np -> m_host, mp -> m_next -> m_host)
498 && uleq (np -> m_mbox, mp -> m_next -> m_mbox))
502 if (!ccme && ismymbox (np))
506 (void) sprintf (buffer, "Reply to %s? ", adrformat (np));
507 if (!gans (buffer, anoyes))
520 static replfilter (in, out)
530 if (access (filter, 04) == NOTOK)
531 adios (filter, "unable to read");
533 mhl = r1bindex (mhlproc, '/');
536 (void) lseek (fileno(in), (off_t)0, L_SET);
539 switch (pid = vfork ()) {
541 adios ("fork", "unable to");
544 (void) dup2 (fileno (in), fileno (stdin));
545 (void) dup2 (fileno (out), fileno (stdout));
548 execlp (mhlproc, mhl, "-form", filter, "-noclear", NULLCP);
549 fprintf (stderr, "unable to exec ");
554 if (pidXwait (pid, mhl))
556 (void) fseek (out, 0L, 2);
570 static char ident[] = "@@(#)$Id: replsbr.c,v 1.17 1993/09/04 19:31:32 jromine Exp jromine $";
573 if ((len = strlen (str)) >= bufend - dst) {\
579 @use L_SET instead of SEEK_SET (for backward-compatibility)
580 include sys/types.h, sys/file.h for lseek
585 static char ident[] = "@@(#)$Id: replsbr.c,v 1.16 1993/08/26 22:13:19 jromine Exp jromine $";
589 replout (inb, msg, drft)
597 @always lseek after rewind (not only on _FSTDIO systems)
602 static char ident[] = "@@(#)$Id: replsbr.c,v 1.15 1993/08/25 17:27:35 jromine Exp jromine $";
606 (void) lseek (fileno(in), (off_t)0, SEEK_SET);
612 @off_t fixes for BSD44
617 static char ident[] = "@@(#)$Id: replsbr.c,v 1.14 1993/02/26 21:59:28 jromine Exp jromine $";
621 /* <sigh> the code assumed that rewind does this. */
622 (void) lseek (fileno(stdin), (off_t)0, SEEK_SET);
634 static char ident[] = "@@(#)$Id: replsbr.c,v 1.13 1992/12/15 00:20:22 jromine Exp jromine $";
637 lseek (fileno(stdin), 0, SEEK_SET);
648 static char ident[] = "@@(#)$Id: replsbr.c,v 1.12 1992/11/04 00:58:58 jromine Exp jromine $";
660 static char ident[] = "@@(#)$Id: replsbr.c,v 1.11 1992/02/05 07:26:30 jromine Exp jromine $";
676 @put unseen sequence in mh-format
681 static char ident[] = "@@(#)$Id: replsbr.c,v 1.10 1991/01/17 15:29:27 mh Exp jromine $";
684 while (isspace(i = *cp++))
686 if ((i | 0x20) != 'r' || (*cp++ | 0x20) != 'e' || *cp++ != ':')
692 @add pseudo-component {user} = $USER envariable
697 static char ident[] = "@@(#)$Id: replsbr.c,v 1.9 90/11/05 11:38:43 mh Exp Locker: mh $";
700 static int dat[4]; /* aux. data for format routine */
703 dat[0] = dat[1] = dat[2] = 0;
714 static char ident[] = "@@(#)$Id: replsbr.c,v 1.8 90/11/05 11:35:20 mh Exp Locker: mh $";
726 static char ident[] = "@@(#)$Id: replsbr.c,v 1.7 90/11/05 11:23:19 mh Exp Locker: mh $";
732 if ((nxtbuf = compbuffers = (char **)
733 calloc((unsigned)ncomps,sizeof(char *)))
735 adios (NULLCP, "unable to allocate component buffers");
742 @fix free'ing freed buf problem
747 static char ident[] = "@@(#)$Id: replsbr.c,v 1.6 90/04/05 14:59:43 sources Exp Locker: mh $";
750 cptr->c_text = tmpbuf; /* use a buf */
753 tmpbuf = *nxtbuf++; /* ready next buf */
764 static char ident[] = "@@(#)$Id:$";
766 struct comp **used_buf_fp;
769 nxtbuf = compbuffers = (char **)calloc((unsigned)ncomps,sizeof(char *));
772 used_buf_fp = used_buf =
773 (struct comp **)calloc((unsigned)(ncomps+1),sizeof(struct comp *));
774 if (used_buf == NULL)
775 adios (NULLCP, "unable to allocate component buffer stack");
776 used_buf += ncomps+1; *--used_buf = 0;
780 nxtbuf = compbuffers;
784 cptr->c_text = tmpbuf;
790 while ( cptr = *savecomp++ )
792 for (nxtbuf = compbuffers, i = ncomps; i--; )
796 free ((char *) used_buf_fp);
811 @Fixes from Van Jacobson
826 #define SBUFSIZ 256 /* buffer size for content part of header
832 @fix freeing incremented malloc pointer bug
847 used_buf = (struct comp **)calloc((unsigned)(ncomps+1),sizeof(struct comp *));
850 if (*used_buf) free ((char *) used_buf);