]> diplodocus.org Git - nmh/blob - docs/historical/mh-6.8.5/uip/rcvdist.c
sbr/mts.c: Delete mmdlm2; use same-valued mmdlm1 instead.
[nmh] / docs / historical / mh-6.8.5 / uip / rcvdist.c
1 /* rcvdist.c - a rcvmail program to distribute messages */
2 #ifndef lint
3 static char ident[] = "@(#)$Id: rcvdist.c,v 1.10 1992/12/15 00:20:22 jromine Exp $";
4 #endif /* lint */
5
6 #include "../h/mh.h"
7 #include "../h/formatsbr.h"
8 #include "../h/rcvmail.h"
9 #include "../zotnet/tws.h"
10 #include <stdio.h>
11 #ifdef LOCALE
12 #include <locale.h>
13 #endif
14
15 /* \f */
16
17 static struct swit switches[] = {
18 #define FORMSW 0
19 "form formfile", 4,
20
21 #define HELPSW 1
22 "help", 4,
23
24 NULL, 0
25 };
26
27 /* \f */
28
29 static char backup[BUFSIZ] = "";
30 static char drft[BUFSIZ] = "";
31 static char tmpfil[BUFSIZ] = "";
32
33 static rcvdistout();
34 /* \f */
35
36 /* ARGSUSED */
37
38 main (argc, argv)
39 int argc;
40 char **argv;
41 {
42 int i,
43 child_id,
44 vecp = 1;
45 char *addrs = NULL,
46 *cp,
47 *form = NULL,
48 buf[100],
49 **ap,
50 **argp,
51 *arguments[MAXARGS],
52 *vec[MAXARGS];
53 register FILE * fp;
54
55 #ifdef LOCALE
56 setlocale(LC_ALL, "");
57 #endif
58 invo_name = r1bindex (argv[0], '/');
59 mts_init (invo_name);
60 if ((cp = m_find (invo_name)) != NULL) {
61 ap = brkstring (cp = getcpy (cp), " ", "\n");
62 ap = copyip (ap, arguments);
63 }
64 else
65 ap = arguments;
66 (void) copyip (argv + 1, ap);
67 argp = arguments;
68
69 /* \f */
70
71 while (cp = *argp++) {
72 if (*cp == '-')
73 switch (smatch (++cp, switches)) {
74 case AMBIGSW:
75 ambigsw (cp, switches);
76 done (1);
77 case UNKWNSW:
78 vec[vecp++] = --cp;
79 continue;
80 case HELPSW:
81 (void) sprintf (buf,
82 "%s [switches] [switches for postproc] address ...",
83 invo_name);
84 help (buf, switches);
85 done (1);
86
87 case FORMSW:
88 if (!(form = *argp++) || *form == '-')
89 adios (NULLCP, "missing argument to %s", argp[-2]);
90 continue;
91 }
92 addrs = addrs ? add (cp, add (", ", addrs)) : getcpy (cp);
93 }
94
95 /* \f */
96
97 if (addrs == NULL)
98 adios (NULLCP, "usage: %s [switches] [switches for postproc] address ...",
99 invo_name);
100
101 (void) umask (~m_gmprot ());
102 (void) strcpy (tmpfil, m_tmpfil (invo_name));
103 if ((fp = fopen (tmpfil, "w+")) == NULL)
104 adios (tmpfil, "unable to create");
105 (void) cpydata (fileno (stdin), fileno (fp), "message", tmpfil);
106 (void) fseek (fp, 0L, 0);
107 (void) strcpy (drft, m_tmpfil (invo_name));
108 rcvdistout (fp, form, addrs);
109 (void) fclose (fp);
110
111 if (distout (drft, tmpfil, backup) == NOTOK)
112 done (1);
113
114 vec[0] = r1bindex (postproc, '/');
115 vec[vecp++] = "-dist";
116 vec[vecp++] = drft;
117 vec[vecp] = NULL;
118
119 for (i = 0; (child_id = fork ()) == NOTOK && i < 5; i++)
120 sleep (5);
121 switch (child_id) {
122 case NOTOK:
123 admonish (NULLCP, "unable to fork");/* fall */
124 case OK:
125 execvp (postproc, vec);
126 fprintf (stderr, "unable to exec ");
127 perror (postproc);
128 _exit (1);
129
130 default:
131 done (pidXwait (child_id, postproc));
132 }
133 /* NOTREACHED */
134 }
135
136 /* \f */
137
138 /* very similar to routine in replsbr.c */
139
140 #define SBUFSIZ 256
141
142 static int outputlinelen = OUTPUTLINELEN;
143
144 static struct format *fmt;
145
146 static int ncomps = 0;
147 static char **compbuffers = 0;
148 static struct comp **used_buf = 0;
149
150 static int dat[5];
151
152 static char *addrcomps[] = {
153 "from",
154 "sender",
155 "reply-to",
156 "to",
157 "cc",
158 "bcc",
159 "resent-from",
160 "resent-sender",
161 "resent-reply-to",
162 "resent-to",
163 "resent-cc",
164 "resent-bcc",
165 NULL
166 };
167
168
169 static rcvdistout (inb, form, addrs)
170 register FILE *inb;
171 char *form,
172 *addrs;
173 {
174 register int char_read = 0,
175 format_len,
176 i,
177 state;
178 register char *tmpbuf,
179 **nxtbuf,
180 **ap;
181 char *cp,
182 *scanl,
183 name[NAMESZ];
184 register struct comp *cptr,
185 **savecomp;
186 FILE *out;
187
188 if ((out = fopen (drft, "w")) == NULL)
189 adios (drft, "unable to create");
190
191 cp = new_fs (form ? form : rcvdistcomps, NULLCP, NULLCP);
192 format_len = strlen (cp);
193 ncomps = fmt_compile (cp, &fmt) + 1;
194 if ((nxtbuf = compbuffers = (char **)
195 calloc ((unsigned) ncomps, sizeof (char *)))
196 == (char **)NULL)
197 adios (NULLCP, "unable to allocate component buffers");
198 if ((savecomp = used_buf = (struct comp **)
199 calloc ((unsigned) (ncomps + 1), sizeof (struct comp *)))
200 == (struct comp **) NULL)
201 adios (NULLCP, "unable to allocate component buffer stack");
202 savecomp += ncomps + 1;
203 *--savecomp = 0;
204
205 for (i = ncomps; i--;)
206 if ((*nxtbuf++ = malloc (SBUFSIZ)) == NULL)
207 adios (NULLCP, "unable to allocate component buffer");
208 nxtbuf = compbuffers;
209 tmpbuf = *nxtbuf++;
210
211 for (ap = addrcomps; *ap; ap++) {
212 FINDCOMP (cptr, *ap);
213 if (cptr)
214 cptr -> c_type |= CT_ADDR;
215 }
216
217 FINDCOMP (cptr, "addresses");
218 if (cptr)
219 cptr -> c_text = addrs;
220
221 for (state = FLD;;) {
222 switch (state = m_getfld (state, name, tmpbuf, SBUFSIZ, inb)) {
223 case FLD:
224 case FLDPLUS:
225 if (cptr = wantcomp[CHASH (name)])
226 do {
227 if (uleq (name, cptr -> c_name)) {
228 char_read += msg_count;
229 if (!cptr -> c_text) {
230 cptr -> c_text = tmpbuf;
231 *--savecomp = cptr;
232 tmpbuf = *nxtbuf++;
233 }
234 else {
235 i = strlen (cp = cptr -> c_text) - 1;
236 if (cp[i] == '\n')
237 if (cptr -> c_type & CT_ADDR) {
238 cp[i] = 0;
239 cp = add (",\n\t", cp);
240 }
241 else
242 cp = add ("\t", cp);
243 cptr -> c_text = add (tmpbuf, cp);
244 }
245 while (state == FLDPLUS) {
246 state = m_getfld (state, name, tmpbuf,
247 SBUFSIZ, inb);
248 cptr -> c_text = add (tmpbuf, cptr -> c_text);
249 char_read += msg_count;
250 }
251 break;
252 }
253 } while (cptr = cptr -> c_next);
254
255 while (state == FLDPLUS)
256 state = m_getfld (state, name, tmpbuf, SBUFSIZ, inb);
257 break;
258
259 case LENERR:
260 case FMTERR:
261 case BODY:
262 case FILEEOF:
263 goto finished;
264
265 default:
266 adios (NULLCP, "m_getfld() returned %d", state);
267 }
268 }
269 finished: ;
270
271 i = format_len + char_read + 256;
272 scanl = malloc ((unsigned) i + 2);
273 dat[0] = dat[1] = dat[2] = dat[4] = 0;
274 dat[3] = outputlinelen;
275 (void) fmtscan (fmt, scanl, i, dat);
276 fputs (scanl, out);
277
278 if (ferror (out))
279 adios (drft, "error writing");
280 (void) fclose (out);
281
282 free (scanl);
283 for (nxtbuf = compbuffers, i = ncomps; cptr = *savecomp++; nxtbuf++, i--)
284 free (cptr -> c_text);
285 while (i-- > 0)
286 free (*nxtbuf++);
287 free ((char *) compbuffers);
288 free ((char *) used_buf);
289 }
290
291 /* \f */
292
293 void done (status)
294 register int status;
295 {
296 if (backup[0])
297 (void) unlink (backup);
298 if (drft[0])
299 (void) unlink (drft);
300 if (tmpfil[0])
301 (void) unlink (tmpfil);
302
303 exit (status ? RCV_MBX : RCV_MOK);
304 }