comparison uip/rcvdist.c @ 0:bce86c4163a3

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