|
|
1.1 root 1: /* sendsbr.c - routines to help WhatNow/Send along */
2:
3: #include "../h/mh.h"
4: #include <setjmp.h>
5: #include <stdio.h>
6: #include <signal.h>
7: #include <sys/types.h>
8: #include <sys/stat.h>
9:
10: /* */
11:
12: int debugsw = 0; /* global */
13: int forwsw = 1;
14: int inplace = 0;
15: int pushsw = 0;
16: int unique = 0;
17:
18: char *altmsg = NULL; /* .. */
19: char *annotext = NULL;
20: char *distfile = NULL;
21:
22:
23: static int armed = 0;
24: static jmp_buf env;
25:
26:
27: char *getusr();
28: long lseek();
29:
30: static void alert(), anno(), annoaux();
31: void senddone();
32: static int tmp_fd();
33:
34: /* */
35:
36: sendsbr(vec, vecp, drft, st)
37: register char **vec, *drft;
38: int vecp;
39: register struct stat *st;
40: {
41: int status;
42:
43: armed++;
44: switch (setjmp (env)) {
45: case OK:
46: status = sendaux (vec, vecp, drft, st) ? NOTOK : OK;
47: break;
48:
49: default:
50: status = DONE;
51: break;
52: }
53: armed = 0;
54: if (distfile)
55: (void) unlink (distfile);
56:
57: return status;
58: }
59:
60: /* */
61:
62: sendaux(vec, vecp, drft, st)
63: register char **vec, *drft;
64: int vecp;
65: register struct stat *st;
66: {
67: int child_id,
68: i,
69: status,
70: fd,
71: fd2;
72: char backup[BUFSIZ],
73: buf[BUFSIZ],
74: file[BUFSIZ];
75:
76: fd = pushsw ? tmp_fd () : NOTOK;
77: fd2 = NOTOK;
78:
79: if (pushsw && unique) {
80: if (rename (drft, strcpy (file, m_scratch (drft, invo_name)))
81: == NOTOK)
82: adios (file, "unable to rename %s to", drft);
83: drft = file;
84: }
85: vec[vecp++] = drft;
86: if (annotext)
87: if ((fd2 = tmp_fd ()) != NOTOK) {
88: vec[vecp++] = "-idanno";
89: (void) sprintf (buf, "%d", fd2);
90: vec[vecp++] = buf;
91: }
92: else
93: admonish (NULLCP, "unable to create file for annotation list");
94: if (distfile && distout (drft, distfile, backup) == NOTOK)
95: senddone (1);
96: vec[vecp] = NULL;
97:
98: for (i = 0; (child_id = vfork ()) == NOTOK && i < 5; i++)
99: sleep (5);
100: switch (child_id) {
101: case NOTOK: /* oops */
102: adios ("fork", "unable to");
103:
104: case OK: /* send it */
105: if (fd != NOTOK) {
106: (void) dup2 (fd, fileno (stdout));
107: (void) dup2 (fd, fileno (stderr));
108: (void) close (fd);
109: }
110: execvp (postproc, vec);
111: fprintf (stderr, "unable to exec ");
112: perror (postproc);
113: _exit (-1);
114:
115: default: /* wait for it */
116: if ((status = pidwait (child_id, NOTOK)) == 0) {
117: if (annotext && fd2 != NOTOK)
118: anno (fd2, st);
119: if (rename (drft, strcpy (buf, m_backup (drft))) == NOTOK)
120: advise (buf, "unable to rename %s to", drft);
121: }
122: else {
123: if (fd != NOTOK) {
124: alert (drft, fd);
125: (void) close (fd);
126: }
127: else
128: advise (NULLCP, "message not delivered to anyone");
129: if (fd2 != NOTOK)
130: (void) close (fd2);
131: if (distfile) {
132: (void) unlink (drft);
133: if (rename (backup, drft) == NOTOK)
134: advise (drft, "unable to rename %s to", backup);
135: }
136: }
137: break;
138: }
139:
140: return status;
141: }
142:
143: /* */
144:
145: static void
146: alert(file, out)
147: register char *file;
148: int out;
149: {
150: int child_id,
151: i,
152: in;
153: char buf[BUFSIZ];
154:
155: for (i = 0; (child_id = fork ()) == NOTOK && i < 5; i++)
156: sleep (5);
157: switch (child_id) {
158: case NOTOK: /* oops */
159: advise ("fork", "unable to");
160:
161: case OK: /* send it */
162: (void) signal (SIGHUP, SIG_IGN);
163: (void) signal (SIGINT, SIG_IGN);
164: (void) signal (SIGQUIT, SIG_IGN);
165: (void) signal (SIGTERM, SIG_IGN);
166: if (forwsw)
167: if ((in = open (file, 0)) == NOTOK)
168: admonish (file, "unable to re-open");
169: else {
170: (void) lseek (out, 0L, 2);
171: (void) strcpy (buf, "\nMessage not delivered to anyone.\n");
172: (void) write (out, buf, strlen (buf));
173: (void) strcpy (buf, "\n------- Unsent Draft\n\n");
174: (void) write (out, buf, strlen (buf));
175: cpydgst (in, out, file, "temporary file");
176: (void) close (in);
177: (void) strcpy (buf, "\n------- End of Unsent Draft\n");
178: (void) write (out, buf, strlen (buf));
179: if (rename (file, strcpy (buf, m_backup (file))) == NOTOK)
180: admonish (buf, "unable to rename %s to", file);
181: }
182: (void) lseek (out, 0L, 0);
183: (void) dup2 (out, fileno (stdin));
184: (void) close (out);
185: (void) sprintf (buf, "send failed on %s",
186: forwsw ? "enclosed draft" : file);
187:
188: execlp (mailproc, r1bindex (mailproc, '/'), getusr (),
189: "-subject", buf, NULLCP);
190: fprintf (stderr, "unable to exec ");
191: perror (mailproc);
192: _exit (-1);
193:
194: default: /* no waiting... */
195: break;
196: }
197: }
198:
199: /* */
200:
201: static int
202: tmp_fd()
203: {
204: int fd;
205: char tmpfil[BUFSIZ];
206:
207: (void) strcpy (tmpfil, m_tmpfil (invo_name));
208: if ((fd = creat (tmpfil, 0600)) == NOTOK)
209: return NOTOK;
210: (void) close (fd);
211:
212: if ((fd = open (tmpfil, 2)) == NOTOK)
213: return NOTOK;
214: if (debugsw)
215: advise (NULLCP, "temporary file %s selected", tmpfil);
216: else
217: if (unlink (tmpfil) == NOTOK)
218: advise (tmpfil, "unable to remove");
219:
220: return fd;
221: }
222:
223: /* */
224:
225: static void
226: anno(fd, st)
227: int fd;
228: register struct stat *st;
229: {
230: int child_id;
231: SIGDECL (*hstat)(), (*istat)(), (*qstat)(), (*tstat)();
232: static char *cwd = NULL;
233: struct stat st2;
234:
235: if (altmsg &&
236: (stat (altmsg, &st2) == NOTOK
237: || st -> st_mtime != st2.st_mtime
238: || st -> st_dev != st2.st_dev
239: || st -> st_ino != st2.st_ino)) {
240: if (debugsw)
241: admonish (NULLCP, "$mhaltmsg mismatch");
242: return;
243: }
244:
245: child_id = debugsw ? NOTOK : fork ();
246: switch (child_id) {
247: case NOTOK: /* oops */
248: if (!debugsw)
249: advise (NULLCP,
250: "unable to fork, so doing annotations by hand...");
251: if (cwd == NULL)
252: cwd = getcpy (pwd ());
253:
254: case OK:
255: hstat = signal (SIGHUP, SIG_IGN);
256: istat = signal (SIGINT, SIG_IGN);
257: qstat = signal (SIGQUIT, SIG_IGN);
258: tstat = signal (SIGTERM, SIG_IGN);
259:
260: annoaux (fd);
261: if (child_id == OK)
262: _exit (0);
263:
264: (void) signal (SIGHUP, hstat);
265: (void) signal (SIGINT, istat);
266: (void) signal (SIGQUIT, qstat);
267: (void) signal (SIGTERM, tstat);
268:
269: (void) chdir (cwd);
270: break;
271:
272: default: /* no waiting... */
273: (void) close (fd);
274: break;
275: }
276: }
277:
278: /* */
279:
280: static void
281: annoaux(fd)
282: int fd;
283: {
284: int fd2,
285: fd3,
286: msgnum;
287: char *cp,
288: *folder,
289: *maildir,
290: buffer[BUFSIZ],
291: **ap;
292: FILE *fp;
293: struct msgs *mp;
294:
295: if ((folder = getenv ("mhfolder")) == NULL || *folder == NULL) {
296: if (debugsw)
297: admonish (NULLCP, "$mhfolder not set");
298: return;
299: }
300: maildir = m_maildir (folder);
301: if (chdir (maildir) == NOTOK) {
302: if (debugsw)
303: admonish (maildir, "unable to change directory to");
304: return;
305: }
306: if (!(mp = m_gmsg (folder))) {
307: if (debugsw)
308: admonish (NULLCP, "unable to read folder %s");
309: return;
310: }
311: if (mp -> hghmsg == 0) {
312: if (debugsw)
313: admonish (NULLCP, "no messages in %s", folder);
314: goto oops;
315: }
316:
317: if ((cp = getenv ("mhmessages")) == NULL || *cp == NULL) {
318: if (debugsw)
319: admonish (NULLCP, "$mhmessages not set");
320: goto oops;
321: }
322: if (!debugsw /* MOBY HACK... */
323: && pushsw
324: && (fd3 = open ("/dev/null", 2)) != NOTOK
325: && (fd2 = dup (fileno (stderr))) != NOTOK) {
326: (void) dup2 (fd3, fileno (stderr));
327: (void) close (fd3);
328: }
329: else
330: fd2 = NOTOK;
331: for (ap = brkstring (cp = getcpy (cp), " ", NULLCP); *ap; ap++)
332: (void) m_convert (mp, *ap);
333: free (cp);
334: if (fd2 != NOTOK)
335: (void) dup2 (fd2, fileno (stderr));
336: if (mp -> numsel == 0) {
337: if (debugsw)
338: admonish (NULLCP, "no messages to annotate");
339: goto oops;
340: }
341:
342: (void) lseek (fd, 0L, 0);
343: if ((fp = fdopen (fd, "r")) == NULL) {
344: if (debugsw)
345: admonish (NULLCP, "unable to fdopen annotation list");
346: goto oops;
347: }
348: cp = NULL;
349: while (fgets (buffer, sizeof buffer, fp) != NULL)
350: cp = add (buffer, cp);
351: (void) fclose (fp);
352:
353: if (debugsw)
354: advise (NULLCP, "annotate%s with %s: \"%s\"",
355: inplace ? " inplace" : "", annotext, cp);
356: for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++)
357: if (mp -> msgstats[msgnum] & SELECTED) {
358: if (debugsw)
359: advise (NULLCP, "annotate message %d", msgnum);
360: (void) annotate (m_name (msgnum), annotext, cp, inplace);
361: }
362:
363: free (cp);
364:
365: oops: ;
366: m_fmsg (mp);
367: }
368:
369: /* */
370:
371: void
372: senddone(status)
373: int status;
374: {
375: if (armed)
376: longjmp (env, status ? status : NOTOK);
377:
378: exit (status);
379: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.