Activated Jon's attachment system by default and steamlined it.
[mmh] / uip / viamail.c
1 /*
2 ** viamail.c -- send multiple files in a MIME message
3 **
4 ** This code is Copyright (c) 2002, by the authors of nmh.  See the
5 ** COPYRIGHT file in the root directory of the nmh distribution for
6 ** complete copyright information.
7 */
8
9 #include <h/mh.h>
10 #include <fcntl.h>
11 #include <h/signals.h>
12 #include <h/md5.h>
13 #include <errno.h>
14 #include <signal.h>
15 #include <h/mts.h>
16 #include <h/tws.h>
17 #include <h/mime.h>
18 #include <h/mhparse.h>
19
20 #ifdef HAVE_SYS_WAIT_H
21 # include <sys/wait.h>
22 #endif
23
24 static struct swit switches[] = {
25 #define TOSW  0
26         { "to mailpath", 0 },
27 #define FROMSW  1
28         { "from mailpath", 0 },
29 #define SUBJECTSW  2
30         { "subject subject", 0 },
31 #define PARAMSW  3
32         { "parameters arguments", 0 },
33 #define DESCRIPTSW  4
34         { "description text", 0 },
35 #define COMMENTSW  5
36         { "comment text", 0 },
37 #define VERBSW  6
38         { "verbose", 0 },
39 #define NVERBSW  7
40         { "noverbose", 0 },
41 #define VERSIONSW  8
42         { "version", 0 },
43 #define HELPSW  9
44         { "help", 0 },
45 #define DEBUGSW  10
46         { "debug", -5 },
47         { NULL, 0 }
48 };
49
50 extern int debugsw;
51 extern int verbsw;
52
53 int ebcdicsw = 0;  /* hack for linking purposes */
54
55 /* mhmisc.c */
56 void set_endian(void);
57
58 /* mhoutsbr.c */
59 int writeBase64aux(FILE *, FILE *);
60
61 /*
62 ** static prototypes
63 */
64 static int via_mail(char *, char *, char *, char *, char *, char *);
65
66
67 int
68 main(int argc, char **argv)
69 {
70         char *f1 = NULL, *f2 = NULL, *f3 = NULL;
71         char *f4 = NULL, *f5 = NULL, *f7 = NULL;
72         char *cp, buf[BUFSIZ];
73         char **argp, **arguments;
74
75 #ifdef LOCALE
76         setlocale(LC_ALL, "");
77 #endif
78         invo_name = mhbasename(argv[0]);
79
80         /* foil search of user profile/context */
81         if (context_foil(NULL) == -1)
82                 done(1);
83
84         arguments = getarguments(invo_name, argc, argv, 0);
85         argp = arguments;
86
87         while ((cp = *argp++)) {
88                 if (*cp == '-') {
89                         switch (smatch(++cp, switches)) {
90                         case AMBIGSW:
91                                 ambigsw(cp, switches);
92                                 done(1);
93                         case UNKWNSW:
94                                 adios(NULL, "-%s unknown", cp);
95
96                         case HELPSW:
97                                 snprintf(buf, sizeof(buf), "%s [switches]",
98                                                 invo_name);
99                                 print_help(buf, switches, 1);
100                                 done(1);
101                         case VERSIONSW:
102                                 print_version(invo_name);
103                                 done(1);
104
105                         case TOSW:
106                                 if (!(f1 = *argp++))
107                                         adios(NULL, "missing argument to %s",
108                                                         argp[-2]);
109                                 continue;
110                         case SUBJECTSW:
111                                 if (!(f2 = *argp++))
112                                         adios(NULL, "missing argument to %s",
113                                                 argp[-2]);
114                                 continue;
115                         case PARAMSW:
116                                 if (!(f3 = *argp++))
117                                         adios(NULL, "missing argument to %s",
118                                                 argp[-2]);
119                                 continue;
120                         case DESCRIPTSW:
121                                 if (!(f4 = *argp++))
122                                         adios(NULL, "missing argument to %s",
123                                                 argp[-2]);
124                                 continue;
125                         case COMMENTSW:
126                                 if (!(f5 = *argp++))
127                                         adios(NULL, "missing argument to %s",
128                                                 argp[-2]);
129                                 continue;
130                         case FROMSW:
131                                 if (!(f7 = *argp++))
132                                         adios(NULL, "missing argument to %s",
133                                                 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         set_endian();
151
152         if (!f1)
153                 adios(NULL, "missing -viamail \"mailpath\" switch");
154
155         via_mail(f1, f2, f3, f4, f5, f7);
156         return 0;  /* dead code to satisfy the compiler */
157 }
158
159
160 /*
161 ** VIAMAIL
162 */
163
164 static int
165 via_mail(char *mailsw, char *subjsw, char *parmsw, char *descsw,
166         char *cmntsw, char *fromsw)
167 {
168         int status, vecp = 1;
169         char tmpfil[BUFSIZ];
170         char *vec[MAXARGS];
171         struct stat st;
172         FILE *fp;
173         char *tfile = NULL;
174
175         umask(~m_gmprot());
176
177         tfile = m_mktemp2(NULL, invo_name, NULL, &fp);
178         if (tfile == NULL)
179                 adios("viamail", "unable to create temporary file");
180         chmod(tfile, 0600);
181         strncpy(tmpfil, tfile, sizeof(tmpfil));
182
183         if (!strchr(mailsw, '@'))
184                 mailsw = concat(mailsw, "@", LocalName(), NULL);
185         fprintf(fp, "To: %s\n", mailsw);
186
187         if (subjsw)
188                 fprintf(fp, "Subject: %s\n", subjsw);
189
190         if (fromsw) {
191                 if (!strchr(fromsw, '@'))
192                         fromsw = concat(fromsw, "@", LocalName(), NULL);
193                 fprintf(fp, "From: %s\n", fromsw);
194         }
195
196         fprintf(fp, "%s: %s\n", VRSN_FIELD, VRSN_VALUE);
197         fprintf(fp, "%s: application/octet-stream", TYPE_FIELD);
198
199         if (parmsw)
200                 fprintf(fp, "; %s", parmsw);
201
202         if (cmntsw)
203                 fprintf(fp, "\n\t(%s)", cmntsw);
204
205         if (descsw)
206                 fprintf(fp, "\n%s: %s", DESCR_FIELD, descsw);
207
208         fprintf(fp, "\n%s: %s\n\n", ENCODING_FIELD, "base64");
209
210         if (fflush(fp))
211                 adios(tmpfil, "error writing to");
212
213         writeBase64aux(stdin, fp);
214         if (fflush(fp))
215                 adios(tmpfil, "error writing to");
216
217         if (fstat(fileno(fp), &st) == NOTOK)
218                 adios("failed", "fstat of %s", tmpfil);
219
220         status = 0;
221         vec[0] = mhbasename(postproc);
222         if (verbsw)
223                 vec[vecp++] = "-verbose";
224
225         switch (sendsbr(vec, vecp, tmpfil, &st, 0)) {
226         case DONE:
227         case NOTOK:
228                 status++;
229                 break;
230         case OK:
231                 break;
232         }
233
234         fclose(fp);
235         if (unlink(tmpfil) == -1)
236                 advise(NULL, "unable to remove temp file %s", tmpfil);
237         done(status);
238         return 1;
239 }