2 ** mhtest.c -- test harness for MIME routines
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.
11 #include <h/signals.h>
16 #include <h/mhparse.h>
17 #include <h/mhcachesbr.h>
20 static struct swit switches[] = {
28 { "outfile file", 0 },
32 { "type content", 0 },
34 { "rcache policy", 0 },
36 { "wcache policy", 0 },
47 int ebcdicsw = 0; /* hack for linking purposes */
50 extern char *tmp; /* directory to place temp files */
55 extern char *cache_public;
56 extern char *cache_private;
61 extern char *parts[NPARTS + 1];
62 extern char *types[NTYPES + 1];
66 ** This is currently needed to keep mhparse happy.
67 ** This needs to be changed.
74 #define quitser pipeser
77 CT parse_mime(char *);
80 int output_message(CT, char *);
85 void set_endian(void);
86 void flush_errors(void);
89 void free_content(CT);
91 void freects_done(int) NORETURN;
96 static int write_content(CT *, char *);
97 static void pipeser(int);
101 main(int argc, char **argv)
103 int msgnum, *icachesw;
104 char *cp, *file = NULL, *folder = NULL;
105 char *maildir, buf[100], *outfile = NULL;
106 char **argp, **arguments;
107 struct msgs_array msgs = { 0, 0, NULL };
108 struct msgs *mp = NULL;
114 setlocale(LC_ALL, "");
116 invo_name = mhbasename(argv[0]);
118 /* read user profile/context */
121 arguments = getarguments(invo_name, argc, argv, 1);
127 while ((cp = *argp++)) {
129 switch (smatch(++cp, switches)) {
131 ambigsw(cp, switches);
134 adios(NULL, "-%s unknown", cp);
137 snprintf(buf, sizeof(buf), "%s [+folder] [msgs] [switches]", invo_name);
138 print_help(buf, switches, 1);
141 print_version(invo_name);
145 icachesw = &rcachesw;
148 icachesw = &wcachesw;
150 if (!(cp = *argp++) || *cp == '-')
151 adios(NULL, "missing argument to %s",
153 switch (*icachesw = smatch(cp, caches)) {
158 adios(NULL, "%s unknown", cp);
165 if (!(cp = *argp++) || *cp == '-')
166 adios(NULL, "missing argument to %s", argp[-2]);
168 adios(NULL, "too many parts (starting with %s), %d max", cp, NPARTS);
173 if (!(cp = *argp++) || *cp == '-')
174 adios(NULL, "missing argument to %s", argp[-2]);
176 adios(NULL, "too many types (starting with %s), %d max",
182 if (!(cp = *argp++) || (*cp == '-' && cp[1]))
183 adios(NULL, "missing argument to %s",
185 file = *cp == '-' ? cp : getcpy(expanddir(cp));
189 if (!(cp = *argp++) || (*cp == '-' && cp[1]))
190 adios(NULL, "missing argument to %s",
192 outfile = *cp == '-' ? cp : getcpy(expanddir(cp));
206 if (*cp == '+' || *cp == '@') {
208 adios(NULL, "only one folder at a time!");
210 folder = getcpy(expandfol(cp));
212 app_msgarg(&msgs, cp);
215 /* null terminate the list of acceptable parts/types */
222 adios(NULL, "must specify output file");
224 /* Check for public cache location */
225 if ((cache_public = context_find(nmhcache)) && *cache_public != '/')
228 /* Check for private cache location */
229 if (!(cache_private = context_find(nmhprivcache)))
230 cache_private = ".cache";
231 cache_private = getcpy(toabsdir(cache_private));
234 ** Check for storage directory. If specified,
235 ** then store temporary files there. Else we
236 ** store them in standard nmh directory.
238 if ((cp = context_find(nmhstorage)) && *cp)
239 tmp = concat(cp, "/", invo_name, NULL);
241 tmp = getcpy(toabsdir(invo_name));
243 if (file && msgs.size)
244 adios(NULL, "cannot specify msg and file at same time!");
247 ** check if message is coming from file
250 if (!(cts = (CT *) calloc((size_t) 2, sizeof(*cts))))
251 adios(NULL, "out of memory");
254 if ((ct = parse_mime(file)))
258 ** message(s) are coming from a folder
261 app_msgarg(&msgs, seq_cur);
263 folder = getcurfol();
264 maildir = toabsdir(folder);
266 if (chdir(maildir) == NOTOK)
267 adios(maildir, "unable to change directory to");
269 /* read folder and create message structure */
270 if (!(mp = folder_read(folder)))
271 adios(NULL, "unable to read folder %s", folder);
273 /* check for empty folder */
275 adios(NULL, "no messages in %s", folder);
277 /* parse all the message ranges/sequences and set SELECTED */
278 for (msgnum = 0; msgnum < msgs.size; msgnum++)
279 if (!m_convert(mp, msgs.msgs[msgnum]))
281 seq_setprev(mp); /* set the previous-sequence */
283 if (!(cts = (CT *) calloc((size_t) (mp->numsel + 1),
285 adios(NULL, "out of memory");
288 for (msgnum = mp->lowsel; msgnum <= mp->hghsel; msgnum++) {
289 if (is_selected(mp, msgnum)) {
292 msgnam = m_name(msgnum);
293 if ((ct = parse_mime(msgnam)))
303 SIGNAL(SIGQUIT, quitser);
304 SIGNAL(SIGPIPE, pipeser);
307 ** Get the associated umask for the relevant contents.
309 for (ctp = cts; *ctp; ctp++) {
313 if (type_ok(ct, 1) && !ct->c_umask) {
314 if (stat(ct->c_file, &st) != NOTOK)
315 ct->c_umask = ~(st.st_mode & 0777);
317 ct->c_umask = ~m_gmprot();
322 ** Write the content to a file
324 write_content(cts, outfile);
326 /* Now free all the structures for the content */
327 for (ctp = cts; *ctp; ctp++)
333 /* If reading from a folder, do some updating */
335 context_replace(curfolder, folder); /* update current folder */
336 seq_setcur(mp, mp->hghsel); /* update current message */
337 seq_save(mp); /* synchronize sequences */
338 context_save(); /* save the context file */
347 write_content(CT *cts, char *outfile)
351 for (ctp = cts; *ctp; ctp++) {
353 output_message(ct, outfile);
367 fprintf(stderr, "\n");