Mercurial > hg > Applications > mh
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 } |