Rearranged whitespace (and comments) in all the code!
[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 DELAYSW  6
38         { "delay seconds", 0 },
39 #define VERBSW  7
40         { "verbose", 0 },
41 #define NVERBSW  8
42         { "noverbose", 0 },
43 #define VERSIONSW  9
44         { "version", 0 },
45 #define HELPSW  10
46         { "help", 0 },
47 #define DEBUGSW  11
48         { "debug", -5 },
49         { NULL, 0 }
50 };
51
52 extern int debugsw;
53 extern int splitsw;
54 extern int verbsw;
55
56 int ebcdicsw = 0;  /* hack for linking purposes */
57
58 /* mhmisc.c */
59 void set_endian (void);
60
61 /* mhoutsbr.c */
62 int writeBase64aux (FILE *, FILE *);
63
64 /*
65  * static prototypes
66  */
67 static int via_mail (char *, char *, char *, char *, char *, int, char *);
68
69
70 int
71 main (int argc, char **argv)
72 {
73         int delay = 0;
74         char *f1 = NULL, *f2 = NULL, *f3 = NULL;
75         char *f4 = NULL, *f5 = NULL, *f7 = NULL;
76         char *cp, buf[BUFSIZ];
77         char **argp, **arguments;
78
79 #ifdef LOCALE
80         setlocale(LC_ALL, "");
81 #endif
82         invo_name = r1bindex (argv[0], '/');
83
84         /* foil search of user profile/context */
85         if (context_foil (NULL) == -1)
86                 done (1);
87
88         arguments = getarguments (invo_name, argc, argv, 0);
89         argp = arguments;
90
91         while ((cp = *argp++)) {
92                 if (*cp == '-') {
93                         switch (smatch (++cp, switches)) {
94                         case AMBIGSW:
95                                 ambigsw (cp, switches);
96                                 done (1);
97                         case UNKWNSW:
98                                 adios (NULL, "-%s unknown", cp);
99
100                         case HELPSW:
101                                 snprintf (buf, sizeof(buf), "%s [switches]", invo_name);
102                                 print_help (buf, switches, 1);
103                                 done (1);
104                         case VERSIONSW:
105                                 print_version(invo_name);
106                                 done (1);
107
108                         case TOSW:
109                                 if (!(f1 = *argp++))
110                                         adios (NULL, "missing argument to %s", argp[-2]);
111                                 continue;
112                         case SUBJECTSW:
113                                 if (!(f2 = *argp++))
114                                         adios (NULL, "missing argument to %s", argp[-2]);
115                                 continue;
116                         case PARAMSW:
117                                 if (!(f3 = *argp++))
118                                         adios (NULL, "missing argument to %s", argp[-2]);
119                                 continue;
120                         case DESCRIPTSW:
121                                 if (!(f4 = *argp++))
122                                         adios (NULL, "missing argument to %s", argp[-2]);
123                                 continue;
124                         case COMMENTSW:
125                                 if (!(f5 = *argp++))
126                                         adios (NULL, "missing argument to %s", argp[-2]);
127                                 continue;
128                         case DELAYSW:
129                                 if (!(cp = *argp++) || *cp == '-')
130                                         adios (NULL, "missing argument to %s", argp[-2]);
131
132                                 /*
133                                  * If there is an error, just reset the
134                                  * delay parameter to -1.  We will set
135                                  * a default delay later.
136                                  */
137                                 if (sscanf (cp, "%d", &delay) != 1)
138                                         delay = -1;
139                                 continue;
140                         case FROMSW:
141                                 if (!(f7 = *argp++))
142                                         adios (NULL, "missing argument to %s", argp[-2]);
143                                 continue;
144
145                         case VERBSW:
146                                 verbsw = 1;
147                                 continue;
148                         case NVERBSW:
149                                 verbsw = 0;
150                                 continue;
151
152                         case DEBUGSW:
153                                 debugsw = 1;
154                                 continue;
155                         }
156                 }
157         }
158
159         set_endian ();
160
161         if (!f1)
162                 adios (NULL, "missing -viamail \"mailpath\" switch");
163
164         via_mail (f1, f2, f3, f4, f5, delay, f7);
165         return 0;  /* dead code to satisfy the compiler */
166 }
167
168
169 /*
170  * VIAMAIL
171  */
172
173 static int
174 via_mail (char *mailsw, char *subjsw, char *parmsw, char *descsw,
175         char *cmntsw, int delay, char *fromsw)
176 {
177         int status, vecp = 1;
178         char tmpfil[BUFSIZ];
179         char *vec[MAXARGS];
180         struct stat st;
181         FILE *fp;
182         char *tfile = NULL;
183
184         umask (~m_gmprot ());
185
186         tfile = m_mktemp2(NULL, invo_name, NULL, &fp);
187         if (tfile == NULL) adios("viamail", "unable to create temporary file");
188         chmod(tfile, 0600);
189         strncpy (tmpfil, tfile, sizeof(tmpfil));
190
191         if (!strchr(mailsw, '@'))
192                 mailsw = concat (mailsw, "@", LocalName (), NULL);
193         fprintf (fp, "To: %s\n", mailsw);
194
195         if (subjsw)
196                 fprintf (fp, "Subject: %s\n", subjsw);
197
198         if (fromsw) {
199                 if (!strchr(fromsw, '@'))
200                         fromsw = concat (fromsw, "@", LocalName (), NULL);
201                 fprintf (fp, "From: %s\n", fromsw);
202         }
203
204         fprintf (fp, "%s: %s\n", VRSN_FIELD, VRSN_VALUE);
205         fprintf (fp, "%s: application/octet-stream", TYPE_FIELD);
206
207         if (parmsw)
208                 fprintf (fp, "; %s", parmsw);
209
210         if (cmntsw)
211                 fprintf (fp, "\n\t(%s)", cmntsw);
212
213         if (descsw)
214                 fprintf (fp, "\n%s: %s", DESCR_FIELD, descsw);
215
216         fprintf (fp, "\n%s: %s\n\n", ENCODING_FIELD, "base64");
217
218         if (fflush (fp))
219                 adios (tmpfil, "error writing to");
220
221         writeBase64aux (stdin, fp);
222         if (fflush (fp))
223                 adios (tmpfil, "error writing to");
224
225         if (fstat (fileno (fp), &st) == NOTOK)
226                 adios ("failed", "fstat of %s", tmpfil);
227
228         if (delay < 0)
229                 splitsw = 10;
230         else
231                 splitsw = delay;
232
233         status = 0;
234         vec[0] = r1bindex (postproc, '/');
235         if (verbsw)
236                 vec[vecp++] = "-verbose";
237
238         switch (sendsbr (vec, vecp, tmpfil, &st, 0, (char *)0, 0)) {
239                 case DONE:
240                 case NOTOK:
241                         status++;
242                         break;
243                 case OK:
244                         break;
245         }
246
247         fclose (fp);
248         if (unlink (tmpfil) == -1)
249                 advise (NULL, "unable to remove temp file %s", tmpfil);
250         done (status);
251         return 1;
252 }