Removed the split feature of send.
[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  7
38         { "verbose", 0 },
39 #define NVERBSW  8
40         { "noverbose", 0 },
41 #define VERSIONSW  9
42         { "version", 0 },
43 #define HELPSW  10
44         { "help", 0 },
45 #define DEBUGSW  11
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 = r1bindex (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]", invo_name);
98                                 print_help (buf, switches, 1);
99                                 done (1);
100                         case VERSIONSW:
101                                 print_version(invo_name);
102                                 done (1);
103
104                         case TOSW:
105                                 if (!(f1 = *argp++))
106                                         adios (NULL, "missing argument to %s", argp[-2]);
107                                 continue;
108                         case SUBJECTSW:
109                                 if (!(f2 = *argp++))
110                                         adios (NULL, "missing argument to %s", argp[-2]);
111                                 continue;
112                         case PARAMSW:
113                                 if (!(f3 = *argp++))
114                                         adios (NULL, "missing argument to %s", argp[-2]);
115                                 continue;
116                         case DESCRIPTSW:
117                                 if (!(f4 = *argp++))
118                                         adios (NULL, "missing argument to %s", argp[-2]);
119                                 continue;
120                         case COMMENTSW:
121                                 if (!(f5 = *argp++))
122                                         adios (NULL, "missing argument to %s", argp[-2]);
123                                 continue;
124                         case FROMSW:
125                                 if (!(f7 = *argp++))
126                                         adios (NULL, "missing argument to %s", argp[-2]);
127                                 continue;
128
129                         case VERBSW:
130                                 verbsw = 1;
131                                 continue;
132                         case NVERBSW:
133                                 verbsw = 0;
134                                 continue;
135
136                         case DEBUGSW:
137                                 debugsw = 1;
138                                 continue;
139                         }
140                 }
141         }
142
143         set_endian ();
144
145         if (!f1)
146                 adios (NULL, "missing -viamail \"mailpath\" switch");
147
148         via_mail (f1, f2, f3, f4, f5, f7);
149         return 0;  /* dead code to satisfy the compiler */
150 }
151
152
153 /*
154  * VIAMAIL
155  */
156
157 static int
158 via_mail (char *mailsw, char *subjsw, char *parmsw, char *descsw,
159         char *cmntsw, char *fromsw)
160 {
161         int status, vecp = 1;
162         char tmpfil[BUFSIZ];
163         char *vec[MAXARGS];
164         struct stat st;
165         FILE *fp;
166         char *tfile = NULL;
167
168         umask (~m_gmprot ());
169
170         tfile = m_mktemp2(NULL, invo_name, NULL, &fp);
171         if (tfile == NULL) adios("viamail", "unable to create temporary file");
172         chmod(tfile, 0600);
173         strncpy (tmpfil, tfile, sizeof(tmpfil));
174
175         if (!strchr(mailsw, '@'))
176                 mailsw = concat (mailsw, "@", LocalName (), NULL);
177         fprintf (fp, "To: %s\n", mailsw);
178
179         if (subjsw)
180                 fprintf (fp, "Subject: %s\n", subjsw);
181
182         if (fromsw) {
183                 if (!strchr(fromsw, '@'))
184                         fromsw = concat (fromsw, "@", LocalName (), NULL);
185                 fprintf (fp, "From: %s\n", fromsw);
186         }
187
188         fprintf (fp, "%s: %s\n", VRSN_FIELD, VRSN_VALUE);
189         fprintf (fp, "%s: application/octet-stream", TYPE_FIELD);
190
191         if (parmsw)
192                 fprintf (fp, "; %s", parmsw);
193
194         if (cmntsw)
195                 fprintf (fp, "\n\t(%s)", cmntsw);
196
197         if (descsw)
198                 fprintf (fp, "\n%s: %s", DESCR_FIELD, descsw);
199
200         fprintf (fp, "\n%s: %s\n\n", ENCODING_FIELD, "base64");
201
202         if (fflush (fp))
203                 adios (tmpfil, "error writing to");
204
205         writeBase64aux (stdin, fp);
206         if (fflush (fp))
207                 adios (tmpfil, "error writing to");
208
209         if (fstat (fileno (fp), &st) == NOTOK)
210                 adios ("failed", "fstat of %s", tmpfil);
211
212         status = 0;
213         vec[0] = r1bindex (postproc, '/');
214         if (verbsw)
215                 vec[vecp++] = "-verbose";
216
217         switch (sendsbr (vec, vecp, tmpfil, &st, 0, (char *)0, 0)) {
218                 case DONE:
219                 case NOTOK:
220                         status++;
221                         break;
222                 case OK:
223                         break;
224         }
225
226         fclose (fp);
227         if (unlink (tmpfil) == -1)
228                 advise (NULL, "unable to remove temp file %s", tmpfil);
229         done (status);
230         return 1;
231 }