]> diplodocus.org Git - nmh/blob - uip/viamail.c
Removed temporary probes added in commit
[nmh] / uip / viamail.c
1
2 /*
3 * viamail.c -- send multiple files in a MIME message
4 *
5 * This code is Copyright (c) 2002, by the authors of nmh. See the
6 * COPYRIGHT file in the root directory of the nmh distribution for
7 * complete copyright information.
8 */
9
10 #include <h/mh.h>
11 #include <fcntl.h>
12 #include <h/signals.h>
13 #include <h/md5.h>
14 #include <h/mts.h>
15 #include <h/tws.h>
16 #include <h/mime.h>
17 #include <h/mhparse.h>
18
19 #define VIAMAIL_SWITCHES \
20 X("to mailpath", 0, TOSW) \
21 X("from mailpath", 0, FROMSW) \
22 X("subject subject", 0, SUBJECTSW) \
23 X("parameters arguments", 0, PARAMSW) \
24 X("description text", 0, DESCRIPTSW) \
25 X("comment text", 0, COMMENTSW) \
26 X("delay seconds", 0, DELAYSW) \
27 X("verbose", 0, VERBSW) \
28 X("noverbose", 0, NVERBSW) \
29 X("version", 0, VERSIONSW) \
30 X("help", 0, HELPSW) \
31 X("debug", -5, DEBUGSW) \
32
33 #define X(sw, minchars, id) id,
34 DEFINE_SWITCH_ENUM(VIAMAIL);
35 #undef X
36
37 #define X(sw, minchars, id) { sw, minchars, id },
38 DEFINE_SWITCH_ARRAY(VIAMAIL, switches);
39 #undef X
40
41 extern int debugsw;
42 extern int splitsw;
43 extern int verbsw;
44
45 /*
46 * static prototypes
47 */
48 static int via_mail (char *, char *, char *, char *, char *, int, char *);
49
50
51 int
52 main (int argc, char **argv)
53 {
54 int delay = 0;
55 char *f1 = NULL, *f2 = NULL, *f3 = NULL;
56 char *f4 = NULL, *f5 = NULL, *f7 = NULL;
57 static char postpath[PATH_MAX];
58 char *cp, buf[BUFSIZ];
59 char **argp, **arguments;
60
61 #ifdef LOCALE
62 setlocale(LC_ALL, "");
63 #endif
64 invo_name = r1bindex (argv[0], '/');
65
66 /* foil search of user profile/context */
67 if (context_foil (NULL) == -1)
68 done (1);
69
70 arguments = getarguments (invo_name, argc, argv, 0);
71 argp = arguments;
72
73 while ((cp = *argp++)) {
74 if (*cp == '-') {
75 switch (smatch (++cp, switches)) {
76 case AMBIGSW:
77 ambigsw (cp, switches);
78 done (1);
79 case UNKWNSW:
80 adios (NULL, "-%s unknown", cp);
81
82 case HELPSW:
83 snprintf (buf, sizeof(buf), "%s [switches]", invo_name);
84 print_help (buf, switches, 1);
85 done (0);
86 case VERSIONSW:
87 print_version(invo_name);
88 done (0);
89
90 case TOSW:
91 if (!(f1 = *argp++))
92 adios (NULL, "missing argument to %s", argp[-2]);
93 continue;
94 case SUBJECTSW:
95 if (!(f2 = *argp++))
96 adios (NULL, "missing argument to %s", argp[-2]);
97 continue;
98 case PARAMSW:
99 if (!(f3 = *argp++))
100 adios (NULL, "missing argument to %s", argp[-2]);
101 continue;
102 case DESCRIPTSW:
103 if (!(f4 = *argp++))
104 adios (NULL, "missing argument to %s", argp[-2]);
105 continue;
106 case COMMENTSW:
107 if (!(f5 = *argp++))
108 adios (NULL, "missing argument to %s", argp[-2]);
109 continue;
110 case DELAYSW:
111 if (!(cp = *argp++) || *cp == '-')
112 adios (NULL, "missing argument to %s", argp[-2]);
113
114 /*
115 * If there is an error, just reset the delay parameter
116 * to -1. We will set a default delay later.
117 */
118 if (sscanf (cp, "%d", &delay) != 1)
119 delay = -1;
120 continue;
121 case FROMSW:
122 if (!(f7 = *argp++))
123 adios (NULL, "missing argument to %s", argp[-2]);
124 continue;
125
126 case VERBSW:
127 verbsw = 1;
128 continue;
129 case NVERBSW:
130 verbsw = 0;
131 continue;
132
133 case DEBUGSW:
134 debugsw = 1;
135 continue;
136 }
137 }
138 }
139
140 if (!f1)
141 adios (NULL, "missing -viamail \"mailpath\" switch");
142
143 /* viamail doesn't read the context and postproc isn't always what
144 we want, such as when running make distcheck. If we have the
145 absolute path, set postproc to point to post in the same
146 directory as this executable.
147 This could be generalized to handle relative paths (by
148 converting to absolute), to find the full path from PATH given
149 just the basename, and to squash out ../ but it's only needed
150 here. viamail is typically called from sendfiles, which
151 provides the absolute path.
152 */
153 if (argv[0] && argv[0][0] == '/' &&
154 strlen(argv[0]) - 3 < sizeof postpath) {
155 strncpy (postpath, argv[0], sizeof postpath - 1);
156 postpath[sizeof postpath - 1] = '\0';
157 if ((cp = strrchr (postpath, '/'))) {
158 struct stat st;
159
160 *(cp + 1) = '\0';
161 /* strlen ("post") <= sizeof postpath - (cp - postpath) - 2
162 but use strncat just in case the code above changes. */
163 strncat (postpath, "post", sizeof postpath - (cp - postpath) - 2);
164
165 if (stat (postpath, &st) == OK) {
166 postproc = postpath;
167 }
168 }
169 }
170
171 via_mail (f1, f2, f3, f4, f5, delay, f7);
172 return 0; /* dead code to satisfy the compiler */
173 }
174
175
176 /*
177 * VIAMAIL
178 */
179
180 static int
181 via_mail (char *mailsw, char *subjsw, char *parmsw, char *descsw,
182 char *cmntsw, int delay, char *fromsw)
183 {
184 int status, vecp;
185 char tmpfil[BUFSIZ], *program;
186 char **vec;
187 struct stat st;
188 FILE *fp;
189 char *tfile = NULL;
190 char *cp;
191
192 umask (~m_gmprot ());
193
194 tfile = m_mktemp2(NULL, invo_name, NULL, &fp);
195 if (tfile == NULL) adios("viamail", "unable to create temporary file");
196 chmod(tfile, 0600);
197 strncpy (tmpfil, tfile, sizeof(tmpfil));
198
199 if (!strchr(mailsw, '@'))
200 mailsw = concat (mailsw, "@", LocalName (0), NULL);
201 fprintf (fp, "To: %s\n", mailsw);
202
203 if (subjsw)
204 fprintf (fp, "Subject: %s\n", subjsw);
205
206 if (fromsw) {
207 if (!strchr(fromsw, '@'))
208 fromsw = concat (fromsw, "@", LocalName (0), NULL);
209 fprintf (fp, "From: %s\n", fromsw);
210 }
211
212 fprintf (fp, "%s: %s\n", VRSN_FIELD, VRSN_VALUE);
213 fprintf (fp, "%s: application/octet-stream", TYPE_FIELD);
214
215 if (parmsw)
216 fprintf (fp, "; %s", parmsw);
217
218 if (cmntsw)
219 fprintf (fp, "\n\t(%s)", cmntsw);
220
221 if (descsw)
222 fprintf (fp, "\n%s: %s", DESCR_FIELD, descsw);
223
224 fprintf (fp, "\n%s: %s\n\n", ENCODING_FIELD, "base64");
225
226 if (fflush (fp))
227 adios (tmpfil, "error writing to");
228
229 writeBase64aux (stdin, fp);
230 if (fflush (fp))
231 adios (tmpfil, "error writing to");
232
233 if (fstat (fileno (fp), &st) == NOTOK)
234 adios ("failed", "fstat of %s", tmpfil);
235
236 if (delay < 0)
237 splitsw = 10;
238 else
239 splitsw = delay;
240
241 status = 0;
242
243 vec = argsplit(postproc, &program, &vecp);
244 if (verbsw)
245 vec[vecp++] = "-verbose";
246
247 if ((cp = context_find ("credentials"))) {
248 /* post doesn't read context so need to pass credentials. */
249 vec[vecp++] = "-credentials";
250 vec[vecp++] = cp;
251 }
252
253 switch (sendsbr (vec, vecp, program, tmpfil, &st, 0, (char *)0, 0)) {
254 case DONE:
255 case NOTOK:
256 status++;
257 break;
258 case OK:
259 break;
260 }
261
262 fclose (fp);
263 if (unlink (tmpfil) == -1)
264 advise (NULL, "unable to remove temp file %s", tmpfil);
265 done (status);
266 return 1;
267 }