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