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