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