1 | |
---|
2 | /* |
---|
3 | * mhmail.c -- simple mail program |
---|
4 | * |
---|
5 | * $Id: mhmail.c,v 1.1.1.1 1999-02-07 18:14:14 danw Exp $ |
---|
6 | */ |
---|
7 | |
---|
8 | #include <h/mh.h> |
---|
9 | #include <h/signals.h> |
---|
10 | #include <signal.h> |
---|
11 | |
---|
12 | static struct swit switches[] = { |
---|
13 | #define BODYSW 0 |
---|
14 | { "body text", 0 }, |
---|
15 | #define CCSW 1 |
---|
16 | { "cc addrs ...", 0 }, |
---|
17 | #define FROMSW 2 |
---|
18 | { "from addr", 0 }, |
---|
19 | #define SUBJSW 3 |
---|
20 | { "subject text", 0 }, |
---|
21 | #define VERSIONSW 4 |
---|
22 | { "version", 0 }, |
---|
23 | #define HELPSW 5 |
---|
24 | { "help", 4 }, |
---|
25 | #define RESNDSW 6 |
---|
26 | { "resent", -6 }, |
---|
27 | #define QUEUESW 7 |
---|
28 | { "queued", -6 }, |
---|
29 | { NULL, 0 } |
---|
30 | }; |
---|
31 | |
---|
32 | static char tmpfil[BUFSIZ]; |
---|
33 | |
---|
34 | /* |
---|
35 | * static prototypes |
---|
36 | */ |
---|
37 | static RETSIGTYPE intrser (int); |
---|
38 | |
---|
39 | |
---|
40 | int |
---|
41 | main (int argc, char **argv) |
---|
42 | { |
---|
43 | pid_t child_id; |
---|
44 | int status, i, iscc = 0, nvec; |
---|
45 | int queued = 0, resent = 0, somebody; |
---|
46 | char *cp, *tolist = NULL, *cclist = NULL, *subject = NULL; |
---|
47 | char *from = NULL, *body = NULL, **argp, **arguments; |
---|
48 | char *vec[5], buf[BUFSIZ]; |
---|
49 | FILE *out; |
---|
50 | |
---|
51 | #ifdef LOCALE |
---|
52 | setlocale(LC_ALL, ""); |
---|
53 | #endif |
---|
54 | invo_name = r1bindex (argv[0], '/'); |
---|
55 | |
---|
56 | /* foil search of user profile/context */ |
---|
57 | if (context_foil (NULL) == -1) |
---|
58 | done (1); |
---|
59 | |
---|
60 | /* If no arguments, just incorporate new mail */ |
---|
61 | if (argc == 1) { |
---|
62 | execlp (incproc, r1bindex (incproc, '/'), NULL); |
---|
63 | adios (incproc, "unable to exec"); |
---|
64 | } |
---|
65 | |
---|
66 | arguments = getarguments (invo_name, argc, argv, 0); |
---|
67 | argp = arguments; |
---|
68 | |
---|
69 | while ((cp = *argp++)) { |
---|
70 | if (*cp == '-') { |
---|
71 | switch (smatch (++cp, switches)) { |
---|
72 | case AMBIGSW: |
---|
73 | ambigsw (cp, switches); |
---|
74 | done (1); |
---|
75 | case UNKWNSW: |
---|
76 | adios (NULL, "-%s unknown", cp); |
---|
77 | |
---|
78 | case HELPSW: |
---|
79 | snprintf (buf, sizeof(buf), "%s [addrs ... [switches]]", |
---|
80 | invo_name); |
---|
81 | print_help (buf, switches, 0); |
---|
82 | done (1); |
---|
83 | case VERSIONSW: |
---|
84 | print_version(invo_name); |
---|
85 | done (1); |
---|
86 | |
---|
87 | case FROMSW: |
---|
88 | if (!(from = *argp++) || *from == '-') |
---|
89 | adios (NULL, "missing argument to %s", argp[-2]); |
---|
90 | continue; |
---|
91 | |
---|
92 | case BODYSW: |
---|
93 | if (!(body = *argp++) || *body == '-') |
---|
94 | adios (NULL, "missing argument to %s", argp[-2]); |
---|
95 | continue; |
---|
96 | |
---|
97 | case CCSW: |
---|
98 | iscc++; |
---|
99 | continue; |
---|
100 | |
---|
101 | case SUBJSW: |
---|
102 | if (!(subject = *argp++) || *subject == '-') |
---|
103 | adios (NULL, "missing argument to %s", argp[-2]); |
---|
104 | continue; |
---|
105 | |
---|
106 | case RESNDSW: |
---|
107 | resent++; |
---|
108 | continue; |
---|
109 | |
---|
110 | case QUEUESW: |
---|
111 | queued++; |
---|
112 | continue; |
---|
113 | } |
---|
114 | } |
---|
115 | if (iscc) |
---|
116 | cclist = cclist ? add (cp, add (", ", cclist)) : getcpy (cp); |
---|
117 | else |
---|
118 | tolist = tolist ? add (cp, add (", ", tolist)) : getcpy (cp); |
---|
119 | } |
---|
120 | |
---|
121 | if (tolist == NULL) |
---|
122 | adios (NULL, "usage: %s addrs ... [switches]", invo_name); |
---|
123 | strncpy (tmpfil, m_tmpfil (invo_name), sizeof(tmpfil)); |
---|
124 | if ((out = fopen (tmpfil, "w")) == NULL) |
---|
125 | adios (tmpfil, "unable to write"); |
---|
126 | chmod (tmpfil, 0600); |
---|
127 | |
---|
128 | SIGNAL2 (SIGINT, intrser); |
---|
129 | |
---|
130 | fprintf (out, "%sTo: %s\n", resent ? "Resent-" : "", tolist); |
---|
131 | if (cclist) |
---|
132 | fprintf (out, "%scc: %s\n", resent ? "Resent-" : "", cclist); |
---|
133 | if (subject) |
---|
134 | fprintf (out, "%sSubject: %s\n", resent ? "Resent-" : "", subject); |
---|
135 | if (from) |
---|
136 | fprintf (out, "%sFrom: %s\n", resent ? "Resent-" : "", from); |
---|
137 | if (!resent) |
---|
138 | fputs ("\n", out); |
---|
139 | |
---|
140 | if (body) { |
---|
141 | fprintf (out, "%s", body); |
---|
142 | if (*body && *(body + strlen (body) - 1) != '\n') |
---|
143 | fputs ("\n", out); |
---|
144 | } else { |
---|
145 | for (somebody = 0; |
---|
146 | (i = fread (buf, sizeof(*buf), sizeof(buf), stdin)) > 0; |
---|
147 | somebody++) |
---|
148 | if (fwrite (buf, sizeof(*buf), i, out) != i) |
---|
149 | adios (tmpfil, "error writing"); |
---|
150 | if (!somebody) { |
---|
151 | unlink (tmpfil); |
---|
152 | done (1); |
---|
153 | } |
---|
154 | } |
---|
155 | fclose (out); |
---|
156 | |
---|
157 | nvec = 0; |
---|
158 | vec[nvec++] = r1bindex (postproc, '/'); |
---|
159 | vec[nvec++] = tmpfil; |
---|
160 | if (resent) |
---|
161 | vec[nvec++] = "-dist"; |
---|
162 | if (queued) |
---|
163 | vec[nvec++] = "-queued"; |
---|
164 | vec[nvec] = NULL; |
---|
165 | |
---|
166 | for (i = 0; (child_id = fork()) == NOTOK && i < 5; i++) |
---|
167 | sleep (5); |
---|
168 | |
---|
169 | if (child_id == NOTOK) { |
---|
170 | /* report failure and then send it */ |
---|
171 | admonish (NULL, "unable to fork"); |
---|
172 | } else if (child_id) { |
---|
173 | /* parent process */ |
---|
174 | if ((status = pidXwait(child_id, postproc))) { |
---|
175 | fprintf (stderr, "Letter saved in dead.letter\n"); |
---|
176 | execl ("/bin/mv", "mv", tmpfil, "dead.letter", NULL); |
---|
177 | execl ("/usr/bin/mv", "mv", tmpfil, "dead.letter", NULL); |
---|
178 | perror ("mv"); |
---|
179 | _exit (-1); |
---|
180 | } |
---|
181 | unlink (tmpfil); |
---|
182 | done (status ? 1 : 0); |
---|
183 | } else { |
---|
184 | /* child process */ |
---|
185 | execvp (postproc, vec); |
---|
186 | fprintf (stderr, "unable to exec "); |
---|
187 | perror (postproc); |
---|
188 | _exit (-1); |
---|
189 | } |
---|
190 | } |
---|
191 | |
---|
192 | |
---|
193 | static RETSIGTYPE |
---|
194 | intrser (int i) |
---|
195 | { |
---|
196 | #ifndef RELIABLE_SIGNALS |
---|
197 | if (i) |
---|
198 | SIGNAL (i, SIG_IGN); |
---|
199 | #endif |
---|
200 | |
---|
201 | unlink (tmpfil); |
---|
202 | done (i != 0 ? 1 : 0); |
---|
203 | } |
---|
204 | |
---|