3 * viamail.c -- send multiple files in a MIME message
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.
12 #include <h/signals.h>
19 #include <h/mhparse.h>
21 static struct swit switches[] = {
25 { "from mailpath", 0 },
27 { "subject subject", 0 },
29 { "parameters arguments", 0 },
31 { "description text", 0 },
33 { "comment text", 0 },
35 { "delay seconds", 0 },
53 int ebcdicsw = 0; /* hack for linking purposes */
58 static int via_mail (char *, char *, char *, char *, char *, int, char *);
62 main (int argc, char **argv)
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;
72 setlocale(LC_ALL, "");
74 invo_name = r1bindex (argv[0], '/');
76 /* foil search of user profile/context */
77 if (context_foil (NULL) == -1)
80 arguments = getarguments (invo_name, argc, argv, 0);
83 while ((cp = *argp++)) {
85 switch (smatch (++cp, switches)) {
87 ambigsw (cp, switches);
90 adios (NULL, "-%s unknown", cp);
93 snprintf (buf, sizeof(buf), "%s [switches]", invo_name);
94 print_help (buf, switches, 1);
97 print_version(invo_name);
102 adios (NULL, "missing argument to %s", argp[-2]);
106 adios (NULL, "missing argument to %s", argp[-2]);
110 adios (NULL, "missing argument to %s", argp[-2]);
114 adios (NULL, "missing argument to %s", argp[-2]);
118 adios (NULL, "missing argument to %s", argp[-2]);
121 if (!(cp = *argp++) || *cp == '-')
122 adios (NULL, "missing argument to %s", argp[-2]);
125 * If there is an error, just reset the delay parameter
126 * to -1. We will set a default delay later.
128 if (sscanf (cp, "%d", &delay) != 1)
133 adios (NULL, "missing argument to %s", argp[-2]);
151 adios (NULL, "missing -viamail \"mailpath\" switch");
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.
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, '/'))) {
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);
175 if (stat (postpath, &st) == OK) {
181 via_mail (f1, f2, f3, f4, f5, delay, f7);
182 return 0; /* dead code to satisfy the compiler */
191 via_mail (char *mailsw, char *subjsw, char *parmsw, char *descsw,
192 char *cmntsw, int delay, char *fromsw)
194 int status, vecp = 1;
201 umask (~m_gmprot ());
203 tfile = m_mktemp2(NULL, invo_name, NULL, &fp);
204 if (tfile == NULL) adios("viamail", "unable to create temporary file");
206 strncpy (tmpfil, tfile, sizeof(tmpfil));
208 if (!strchr(mailsw, '@'))
209 mailsw = concat (mailsw, "@", LocalName (0), NULL);
210 fprintf (fp, "To: %s\n", mailsw);
213 fprintf (fp, "Subject: %s\n", subjsw);
216 if (!strchr(fromsw, '@'))
217 fromsw = concat (fromsw, "@", LocalName (0), NULL);
218 fprintf (fp, "From: %s\n", fromsw);
221 fprintf (fp, "%s: %s\n", VRSN_FIELD, VRSN_VALUE);
222 fprintf (fp, "%s: application/octet-stream", TYPE_FIELD);
225 fprintf (fp, "; %s", parmsw);
228 fprintf (fp, "\n\t(%s)", cmntsw);
231 fprintf (fp, "\n%s: %s", DESCR_FIELD, descsw);
233 fprintf (fp, "\n%s: %s\n\n", ENCODING_FIELD, "base64");
236 adios (tmpfil, "error writing to");
238 writeBase64aux (stdin, fp);
240 adios (tmpfil, "error writing to");
242 if (fstat (fileno (fp), &st) == NOTOK)
243 adios ("failed", "fstat of %s", tmpfil);
251 vec[0] = r1bindex (postproc, '/');
253 vec[vecp++] = "-verbose";
255 switch (sendsbr (vec, vecp, tmpfil, &st, 0, (char *)0, 0)) {
265 if (unlink (tmpfil) == -1)
266 advise (NULL, "unable to remove temp file %s", tmpfil);