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