]>
diplodocus.org Git - nmh/blob - docs/historical/mh-6.8.5/uip/replsbr.c
1 /* replsbr.c - routines to help repl along... */
3 static char ident
[] = "@(#)$Id: replsbr.c,v 1.19 1995/12/06 23:47:26 jromine Exp $";
7 #include "../h/addrsbr.h"
8 #include "../h/formatsbr.h"
11 #include <sys/types.h> /* off_t */
12 #include <sys/file.h> /* L_SET */
15 extern short ccto
, /* from repl.c */
28 static char *badaddrs
= NULL
;
29 static char *dfhost
=NULL
;
31 static struct mailname mq
={NULL
};
35 /* buffer size for content part of header
36 * fields. We want this to be large
37 * enough so that we don't do a lot of
38 * extra FLDPLUS calls on m_getfld but
39 * small enough so that we don't snarf
40 * the entire message body when we're
41 * not going to use any of it.
44 static struct format
*fmt
;
46 static int ncomps
= 0; /* # of interesting components */
47 static char **compbuffers
= 0; /* buffers for component text */
48 static struct comp
**used_buf
= 0; /* stack for comp that use buffers */
50 static int dat
[5]; /* aux. data for format routine */
52 static char *addrcomps
[] = {
68 static insert(), replfilter();
73 replout (inb
, msg
, drft
, mp
)
81 register struct comp
*cptr
;
82 register char *tmpbuf
;
83 register char **nxtbuf
;
84 register struct comp
**savecomp
;
93 (void) umask( ~ m_gmprot() );
94 if ((out
= fopen (drft
, "w")) == NULL
)
95 adios (drft
, "unable to create");
97 cp
= new_fs (form
? form
: replcomps
, NULLCP
, NULLCP
);
98 format_len
= strlen (cp
);
99 ncomps
= fmt_compile (cp
, &fmt
) + 1;
100 if ((nxtbuf
= compbuffers
= (char **)
101 calloc((unsigned)ncomps
,sizeof(char *)))
103 adios (NULLCP
, "unable to allocate component buffers");
104 if ((savecomp
= used_buf
= (struct comp
**)
105 calloc((unsigned)(ncomps
+1),sizeof(struct comp
*)))
106 == (struct comp
**)NULL
)
107 adios (NULLCP
, "unable to allocate component buffer stack");
108 savecomp
+= ncomps
+ 1;
109 *--savecomp
= (struct comp
*)0; /* point at zero'd end minus 1 */
110 for (i
= ncomps
; i
--; )
111 if ((*nxtbuf
++ = malloc( SBUFSIZ
)) == NULL
)
112 adios (NULLCP
, "unable to allocate component buffer");
114 nxtbuf
= compbuffers
; /* point at start */
117 for (ap
= addrcomps
; *ap
; ap
++) {
118 FINDCOMP (cptr
, *ap
);
120 cptr
-> c_type
|= CT_ADDR
;
123 /* ignore any components killed by command line switches */
125 FINDCOMP (cptr
, "to");
130 FINDCOMP (cptr
, "cc");
134 /* set up the "fcc" pseudo-component */
136 FINDCOMP (cptr
, "fcc");
138 cptr
->c_text
= getcpy (fcc
);
140 if (cp
= getenv("USER")) {
141 FINDCOMP (cptr
, "user");
143 cptr
->c_text
= getcpy(cp
);
146 (void) ismymbox ((struct mailname
*)0); /* XXX */
148 /* pick any interesting stuff out of msg "inb" */
149 for (state
= FLD
;;) {
150 state
= m_getfld (state
, name
, tmpbuf
, SBUFSIZ
, inb
);
155 * if we're interested in this component, save a pointer
156 * to the component text, then start using our next free
157 * buffer as the component temp buffer (buffer switching
158 * saves an extra copy of the component text).
160 if (cptr
= wantcomp
[CHASH(name
)])
162 if (uleq(name
, cptr
->c_name
)) {
163 char_read
+= msg_count
;
164 if (! cptr
->c_text
) {
165 cptr
->c_text
= tmpbuf
;
169 i
= strlen (cp
= cptr
->c_text
) - 1;
171 if (cptr
->c_type
& CT_ADDR
) {
173 cp
= add (",\n\t", cp
);
177 cptr
->c_text
= add (tmpbuf
, cp
);
179 while (state
== FLDPLUS
) {
180 state
= m_getfld (state
, name
, tmpbuf
,
182 cptr
->c_text
= add (tmpbuf
, cptr
->c_text
);
183 char_read
+= msg_count
;
187 } while (cptr
= cptr
->c_next
);
189 while (state
== FLDPLUS
)
190 state
= m_getfld (state
, name
, tmpbuf
, SBUFSIZ
, inb
);
200 adios (NULLCP
, "m_getfld() returned %d", state
);
204 * format and output the header lines.
207 /* if there's a "subject" component, strip any "re:"s off it */
208 FINDCOMP (cptr
, "subject")
209 if (cptr
&& (cp
= cptr
->c_text
)) {
210 register char *sp
= cp
;
221 if (sp
!= cptr
->c_text
) {
223 cptr
->c_text
= getcpy (sp
);
227 i
= format_len
+ char_read
+ 256;
228 scanl
= malloc ((unsigned)i
+ 2);
229 dat
[0] = dat
[1] = dat
[2] = dat
[4] = 0;
230 dat
[3] = outputlinelen
;
231 (void) fmtscan (fmt
, scanl
, i
, dat
);
234 fputs ("\nrepl: bad addresses:\n", out
);
235 fputs ( badaddrs
, out
);
238 replfilter (inb
, out
);
242 (void) fprintf (out
, "#forw [original message] +%s %s\n",
243 mp
-> foldpath
, m_name (mp
-> lowsel
));
247 adios (drft
, "error writing");
250 /* return dynamically allocated buffers */
252 for (nxtbuf
= compbuffers
, i
= ncomps
;
253 cptr
= *savecomp
++; nxtbuf
++, i
--)
254 free (cptr
->c_text
); /* if not nxtbuf, nxtbuf already freed */
256 free (*nxtbuf
++); /* free unused nxtbufs */
257 free ((char *) compbuffers
);
258 free ((char *) used_buf
);
263 static char *buf
; /* our current working buffer */
264 static char *bufend
; /* end of working buffer */
265 static char *last_dst
; /* buf ptr at end of last call */
266 static unsigned int bufsiz
=0; /* current size of buf */
268 #define BUFINCR 512 /* how much to expand buf when if fills */
270 #define CPY(s) { cp = (s); while (*dst++ = *cp++) ; --dst; }
272 /* check if there's enough room in buf for str. add more mem if needed */
273 #define CHECKMEM(str) \
274 if ((len = strlen (str) + 1) >= bufend - dst) {\
276 int n = last_dst - buf;\
277 bufsiz += ((dst + len - bufend) / BUFINCR + 1) * BUFINCR;\
278 buf = realloc (buf, bufsiz);\
282 adios (NULLCP, "formataddr: couldn't get buffer space");\
283 bufend = buf + bufsiz;\
287 /* fmtscan will call this routine if the user includes the function
288 * "(formataddr {component})" in a format string. "orig" is the
289 * original contents of the string register. "str" is the address
290 * string to be formatted and concatenated onto orig. This routine
291 * returns a pointer to the concatenated address string.
293 * We try to not do a lot of malloc/copy/free's (which is why we
294 * don't call "getcpy") but still place no upper limit on the
295 * length of the result string.
297 char *formataddr (orig
, str
)
304 register int isgroup
;
308 register struct mailname
*mp
= NULL
;
310 /* if we don't have a buffer yet, get one */
312 buf
= malloc (BUFINCR
);
314 adios (NULLCP
, "formataddr: couldn't allocate buffer space");
315 last_dst
= buf
; /* XXX */
316 bufsiz
= BUFINCR
- 6; /* leave some slop */
317 bufend
= buf
+ bufsiz
;
320 * If "orig" points to our buffer we can just pick up where we
321 * left off. Otherwise we have to copy orig into our buffer.
325 else if (!orig
|| !*orig
) {
329 dst
= last_dst
; /* XXX */
334 /* concatenate all the new addresses onto 'buf' */
335 for (isgroup
= 0; cp
= getname (str
); ) {
336 if ((mp
= getm (cp
, dfhost
, dftype
, AD_NAME
, error
)) == NULL
) {
337 (void) sprintf (baddr
, "\t%s -- %s\n", cp
, error
);
338 badaddrs
= add (baddr
, badaddrs
);
341 if (isgroup
&& (mp
->m_gname
|| !mp
->m_ingrp
)) {
346 /* if we get here we're going to add an address */
352 CHECKMEM (mp
->m_gname
);
372 register struct mailname
*np
;
375 register struct mailname
*mp
;
377 if (np
-> m_mbox
== NULL
)
380 for (mp
= &mq
; mp
-> m_next
; mp
= mp
-> m_next
) {
382 if (uleq (np
-> m_mbox
, mp
-> m_next
-> m_mbox
))
385 if (uleq (np
-> m_host
, mp
-> m_next
-> m_host
)
386 && uleq (np
-> m_mbox
, mp
-> m_next
-> m_mbox
))
390 if (!ccme
&& ismymbox (np
))
394 (void) sprintf (buffer
, "Reply to %s? ", adrformat (np
));
395 if (!gans (buffer
, anoyes
))
408 static replfilter (in
, out
)
418 if (access (filter
, 04) == NOTOK
)
419 adios (filter
, "unable to read");
421 mhl
= r1bindex (mhlproc
, '/');
424 (void) lseek (fileno(in
), (off_t
)0, L_SET
);
427 switch (pid
= vfork ()) {
429 adios ("fork", "unable to");
432 (void) dup2 (fileno (in
), fileno (stdin
));
433 (void) dup2 (fileno (out
), fileno (stdout
));
436 execlp (mhlproc
, mhl
, "-form", filter
, "-noclear", NULLCP
);
437 fprintf (stderr
, "unable to exec ");
442 if (pidXwait (pid
, mhl
))
444 (void) fseek (out
, 0L, 2);