Updating user programs to use <h/tws> instead of <zotnet/tws/tws.h>
[mmh] / uip / viamail.c
1
2 /*
3  * viamail.c -- send multiple files in a MIME message
4  *
5  * $Id$
6  */
7
8 #include <h/mh.h>
9 #include <fcntl.h>
10 #include <h/signals.h>
11 #include <h/md5.h>
12 #include <errno.h>
13 #include <signal.h>
14 #include <zotnet/mts/mts.h>
15 #include <h/tws.h>
16 #include <h/mime.h>
17 #include <h/mhparse.h>
18
19 #ifdef HAVE_SYS_WAIT_H
20 # include <sys/wait.h>
21 #endif
22
23 static struct swit switches[] = {
24 #define TOSW                    0
25     { "to mailpath", 0 },
26 #define FROMSW                  1
27     { "from mailpath", 0 },
28 #define SUBJECTSW               2
29     { "subject subject", 0 },
30 #define PARAMSW                 3
31     { "parameters arguments", 0 },
32 #define DESCRIPTSW              4
33     { "description text", 0 },
34 #define COMMENTSW               5
35     { "comment text", 0 },
36 #define DELAYSW                 6
37     { "delay seconds", 0 },
38 #define VERBSW                  7
39     { "verbose", 0 },
40 #define NVERBSW                 8
41     { "noverbose", 0 },
42 #define VERSIONSW               9
43     { "version", 0 },
44 #define HELPSW                 10
45     { "help", 0 },
46 #define DEBUGSW                11
47     { "debug", -5 },
48     { NULL, 0 }
49 };
50
51 extern int errno;
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 delay parameter
134                  * to -1.  We will set a default delay later.
135                  */
136                 if (sscanf (cp, "%d", &delay) != 1)
137                     delay = -1;
138                 continue;
139             case FROMSW:
140                 if (!(f7 = *argp++))
141                     adios (NULL, "missing argument to %s", argp[-2]);
142                 continue;
143
144             case VERBSW: 
145                 verbsw = 1;
146                 continue;
147             case NVERBSW: 
148                 verbsw = 0;
149                 continue;
150
151             case DEBUGSW:
152                 debugsw = 1;
153                 continue;
154             }
155         }
156     }
157
158     set_endian ();
159
160     if (!f1)
161         adios (NULL, "missing -viamail \"mailpath\" switch");
162
163     via_mail (f1, f2, f3, f4, f5, delay, f7);
164     return 0;  /* dead code to satisfy the compiler */
165 }
166
167
168 /*
169  * VIAMAIL
170  */
171
172 static int
173 via_mail (char *mailsw, char *subjsw, char *parmsw, char *descsw,
174           char *cmntsw, int delay, char *fromsw)
175 {
176     int status, vecp = 1;
177     char tmpfil[BUFSIZ];
178     char *vec[MAXARGS];
179     struct stat st;
180     FILE *fp;
181
182     umask (~m_gmprot ());
183
184     strncpy (tmpfil, m_tmpfil (invo_name), sizeof(tmpfil));
185     if ((fp = fopen (tmpfil, "w+")) == NULL)
186         adios (tmpfil, "unable to open for writing");
187     chmod (tmpfil, 0600);
188
189     if (!strchr(mailsw, '@'))
190         mailsw = concat (mailsw, "@", LocalName (), NULL);
191     fprintf (fp, "To: %s\n", mailsw);
192
193     if (subjsw)
194         fprintf (fp, "Subject: %s\n", subjsw);
195
196     if (fromsw) {
197         if (!strchr(fromsw, '@'))
198             fromsw = concat (fromsw, "@", LocalName (), NULL);
199         fprintf (fp, "From: %s\n", fromsw);
200     }
201
202     fprintf (fp, "%s: %s\n", VRSN_FIELD, VRSN_VALUE);
203     fprintf (fp, "%s: application/octet-stream", TYPE_FIELD);
204
205     if (parmsw)
206         fprintf (fp, "; %s", parmsw);
207
208     if (cmntsw)
209         fprintf (fp, "\n\t(%s)", cmntsw);
210
211     if (descsw)
212         fprintf (fp, "\n%s: %s", DESCR_FIELD, descsw);
213
214     fprintf (fp, "\n%s: %s\n\n", ENCODING_FIELD, "base64");
215
216     if (fflush (fp))
217         adios (tmpfil, "error writing to");
218
219     writeBase64aux (stdin, fp);
220     if (fflush (fp))
221         adios (tmpfil, "error writing to");
222
223     if (fstat (fileno (fp), &st) == NOTOK)
224         adios ("failed", "fstat of %s", tmpfil);
225
226     if (delay < 0)
227         splitsw = 10;
228     else
229         splitsw = delay;
230
231     status = 0;
232     vec[0] = r1bindex (postproc, '/');
233     if (verbsw)
234         vec[vecp++] = "-verbose";
235
236     switch (sendsbr (vec, vecp, tmpfil, &st, 0)) {
237         case DONE:
238         case NOTOK:
239             status++;
240             break;
241         case OK:
242             break;
243     }
244
245     fclose (fp);
246     if (unlink (tmpfil) == -1)
247         advise (NULL, "unable to remove temp file %s", tmpfil);
248     return done (status);
249 }