#include <h/mh.h>
#include <fcntl.h>
#include <h/signals.h>
-#include <h/md5.h>
#include <errno.h>
#include <setjmp.h>
#include <signal.h>
#include <h/tws.h>
#include <h/mime.h>
#include <h/mhparse.h>
-#include <h/mhcachesbr.h>
#include <h/utils.h>
static struct swit switches[] = {
{ "auto", 0 },
#define NAUTOSW 1
{ "noauto", 0 },
-#define CHECKSW 2
- { "check", 0 },
-#define NCHECKSW 3
- { "nocheck", 0 },
-#define FILESW 4 /* interface from show */
+#define FILESW 2 /* interface from show */
{ "file file", 0 },
-#define PARTSW 5
+#define PARTSW 3
{ "part number", 0 },
-#define TYPESW 6
+#define TYPESW 4
{ "type content", 0 },
-#define RCACHESW 7
- { "rcache policy", 0 },
-#define WCACHESW 8
- { "wcache policy", 0 },
-#define VERSIONSW 9
+#define VERSIONSW 5
{ "version", 0 },
-#define HELPSW 10
+#define HELPSW 6
{ "help", 0 },
-#define DEBUGSW 11
+#define DEBUGSW 7
{ "debug", -5 },
{ NULL, 0 }
};
/* mhparse.c */
extern char *tmp; /* directory to place temp files */
-/* mhcachesbr.c */
-extern int rcachesw;
-extern int wcachesw;
-extern char *cache_public;
-extern char *cache_private;
-
/* mhmisc.c */
extern int npart;
extern int ntype;
*/
static void pipeser(int);
-int autosw = 0;
+int autosw = 1;
/*
** Cache of current directory. This must be
void flush_errors(void);
/* mhshowsbr.c */
-int show_content_aux(CT, int, int, char *, char *);
+int show_content_aux(CT, int, char *, char *);
/*
** static prototypes
static void store_single_message(CT);
static int store_switch(CT);
static int store_generic(CT);
-static int store_application(CT);
static int store_multi(CT);
static int store_partial(CT);
static int store_external(CT);
static int output_content_file(CT, int);
static int output_content_folder(char *, char *);
static int parse_format_string(CT, char *, char *, int, char *);
-static void get_storeproc(CT);
static int copy_some_headers(FILE *, CT);
static void store_all_messages(CT *);
int
main(int argc, char **argv)
{
- int msgnum, *icachesw;
+ int msgnum;
char *cp, *file = NULL, *folder = NULL;
char *maildir, buf[100], **argp;
char **arguments;
autosw = 0;
continue;
- case RCACHESW:
- icachesw = &rcachesw;
- goto do_cache;
- case WCACHESW:
- icachesw = &wcachesw;
-do_cache:
- if (!(cp = *argp++) || *cp == '-')
- adios(NULL, "missing argument to %s",
- argp[-2]);
- switch (*icachesw = smatch(cp, caches)) {
- case AMBIGSW:
- ambigsw(cp, caches);
- done(1);
- case UNKWNSW:
- adios(NULL, "%s unknown", cp);
- default:
- break;
- }
- continue;
-
- case CHECKSW:
- checksw++;
- continue;
- case NCHECKSW:
- checksw = 0;
- continue;
-
case PARTSW:
if (!(cp = *argp++) || *cp == '-')
adios(NULL, "missing argument to %s",
fclose(fp);
}
- /* Check for public cache location */
- if ((cache_public = context_find(nmhcache)) && *cache_public != '/')
- cache_public = NULL;
-
- /* Check for private cache location */
- if (!(cache_private = context_find(nmhprivcache)))
- cache_private = ".cache";
- cache_private = getcpy(toabsdir(cache_private));
-
/*
** Cache the current directory before we do any chdirs()'s.
*/
** Check for the directory in which to
** store any contents.
*/
- if (autosw)
- dir = getcpy(cwd);
if ((cp = context_find(nmhstorage)) && *cp)
dir = getcpy(cp);
else
break;
case CT_APPLICATION:
- return store_application(ct);
- break;
-
case CT_TEXT:
case CT_AUDIO:
case CT_IMAGE:
/*
** Generic routine to store a MIME content.
-** (audio, video, image, text, message/rfc922)
+** (application, audio, video, image, text, message/rfc922)
*/
-
static int
store_generic(CT ct)
{
- /*
- ** Check if the content specifies a filename.
- ** Don't bother with this for type "message"
- ** (only "message/rfc822" will use store_generic).
- */
- if (autosw && ct->c_type != CT_MESSAGE)
- get_storeproc(ct);
-
- return store_content(ct, NULL);
-}
-
-
-/*
-** Store content of type "application"
-*/
-
-static int
-store_application(CT ct)
-{
- char **ap, **ep;
+ char **ap, **vp, *cp;
CI ci = &ct->c_ctinfo;
- /* Check if the content specifies a filename */
- if (autosw)
- get_storeproc(ct);
-
/*
- ** If storeproc is not defined, and the content is type
- ** "application/octet-stream", we also check for various
- ** attribute/value pairs which specify if this a tar file.
+ ** Check if the content specifies a filename in its MIME parameters.
+ ** Don't bother with this for type "message"
+ ** (only the "message" subtype "rfc822" will use store_generic).
*/
- if (!ct->c_storeproc && ct->c_subtype == APPLICATION_OCTETS) {
- int tarP = 0, zP = 0, gzP = 0;
-
- for (ap = ci->ci_attrs, ep = ci->ci_values; *ap; ap++, ep++) {
- /* check for "type=tar" attribute */
- if (!mh_strcasecmp(*ap, "type")) {
- if (mh_strcasecmp(*ep, "tar"))
- break;
-
- tarP = 1;
- continue;
- }
-
- /* check for "conversions=compress" attribute */
- if ((!mh_strcasecmp(*ap, "conversions") ||
- !mh_strcasecmp(*ap, "x-conversions"))
- && (!mh_strcasecmp(*ep, "compress") ||
- !mh_strcasecmp(*ep, "x-compress"))) {
- zP = 1;
- continue;
- }
- /* check for "conversions=gzip" attribute */
- if ((!mh_strcasecmp(*ap, "conversions") ||
- !mh_strcasecmp(*ap, "x-conversions"))
- && (!mh_strcasecmp(*ep, "gzip") ||
- !mh_strcasecmp(*ep, "x-gzip"))) {
- gzP = 1;
+ if (autosw && ct->c_type != CT_MESSAGE) {
+ /*
+ ** Check the attribute/value pairs, for the attribute "name".
+ ** If found, take the basename, do a few sanity checks and
+ ** copy the value into c_storeproc.
+ */
+ for (ap = ci->ci_attrs, vp = ci->ci_values; *ap; ap++,vp++) {
+ if (mh_strcasecmp(*ap, "name")!=0) {
continue;
}
- }
-
- if (tarP) {
- ct->c_showproc = getcpy(zP ? "%euncompress | tar tvf -" : (gzP ? "%egzip -dc | tar tvf -" : "%etar tvf -"));
- if (!ct->c_storeproc) {
- if (autosw) {
- ct->c_storeproc = getcpy(zP ? "| uncompress | tar xvpf -" : (gzP ? "| gzip -dc | tar xvpf -" : "| tar xvpf -"));
- ct->c_umask = 0022;
- } else {
- ct->c_storeproc= getcpy(zP ? "%m%P.tar.Z" : (gzP ? "%m%P.tar.gz" : "%m%P.tar"));
- }
+ cp = mhbasename(*vp);
+ if (*cp && *cp!='.' && *cp!='|' && *cp!='!' &&
+ !strchr(cp, '%')) {
+ /* filename looks good: use it */
+ ct->c_storeproc = getcpy(cp);
}
+ break;
}
}
/*
-** Store content from a message of type "message/external".
+** Show how to retrieve content of type "message/external".
*/
-
static int
store_external(CT ct)
{
- int result = NOTOK;
- struct exbody *e = (struct exbody *) ct->c_ctparams;
- CT p = e->eb_content;
-
- if (!type_ok(p, 1))
- return OK;
-
- /*
- ** Check if the parameters for the external body
- ** specified a filename.
- */
- if (autosw) {
- char *cp;
+ char **ap, **ep;
+ char *msg;
+ FILE *fp;
+ char buf[BUFSIZ];
- if ((cp = e->eb_name) && *cp != '/' && *cp != '.' &&
- *cp != '|' && *cp != '!' && !strchr(cp, '%')) {
- if (!ct->c_storeproc)
- ct->c_storeproc = getcpy(cp);
- if (!p->c_storeproc)
- p->c_storeproc = getcpy(cp);
+ msg = add("You need to fetch the contents yourself:", NULL);
+ ap = ct->c_ctinfo.ci_attrs;
+ ep = ct->c_ctinfo.ci_values;
+ for (; *ap; ap++, ep++) {
+ msg = add(concat("\n\t", *ap, ": ", *ep, NULL), msg);
+ }
+ if (!(fp = fopen(ct->c_file, "r"))) {
+ adios(ct->c_file, "unable to open");
+ }
+ fseek(fp, ct->c_begin, SEEK_SET);
+ while (!feof(fp) && ftell(fp) < ct->c_end) {
+ if (!fgets(buf, sizeof buf, fp)) {
+ adios(ct->c_file, "unable to read");
}
+ *strchr(buf, '\n') = '\0';
+ msg = add(concat("\n\t", buf, NULL), msg);
}
-
- /*
- ** Since we will let the Content structure for the
- ** external body substitute for the current content,
- ** we temporarily change its partno (number inside
- ** multipart), so everything looks right.
- */
- p->c_partno = ct->c_partno;
-
- /* we probably need to check if content is really there */
- result = store_switch(p);
-
- p->c_partno = NULL;
- return result;
+ fclose(fp);
+ advise(NULL, msg);
+ return OK;
}
** 4) Else if content is "message", use "+" (current folder)
** 5) Else use string "%m%P.%s".
*/
- if ((cp = ct->c_storeproc) == NULL || *cp == '\0') {
+ if (!(cp = ct->c_storeproc) || !*cp) {
CI ci = &ct->c_ctinfo;
snprintf(buffer, sizeof(buffer), "%s-store-%s/%s",
** content to standard input of a command and return.
*/
if (buffer[0] == '|' || buffer[0] == '!')
- return show_content_aux(ct, 1, 0, buffer + 1, dir);
+ return show_content_aux(ct, 0, buffer + 1, dir);
/* record the filename */
ct->c_storage = getcpy(buffer);
FILE *fp;
/*
- ** If the pathname is absolute, make sure
- ** all the relevant directories exist.
+ ** If the pathname contains directories, make sure
+ ** all of them exist.
*/
if (strchr(ct->c_storage, '/') && make_intermediates(ct->c_storage)
== NOTOK)
/*
-** Check if the content specifies a filename
-** in its MIME parameters.
-*/
-
-static void
-get_storeproc(CT ct)
-{
- char **ap, **ep, *cp;
- CI ci = &ct->c_ctinfo;
-
- /*
- ** If the storeproc has already been defined,
- ** we just return (for instance, if this content
- ** is part of a "message/external".
- */
- if (ct->c_storeproc)
- return;
-
- /*
- ** Check the attribute/value pairs, for the attribute "name".
- ** If found, do a few sanity checks and copy the value into
- ** the storeproc.
- */
- for (ap = ci->ci_attrs, ep = ci->ci_values; *ap; ap++, ep++) {
- if (!mh_strcasecmp(*ap, "name") && *(cp = *ep) != '/' &&
- *cp != '.' && *cp != '|' && *cp != '!' &&
- !strchr(cp, '%')) {
- ct->c_storeproc = getcpy(cp);
- return;
- }
- }
-}
-
-
-/*
** Copy some of the header fields of the initial message/partial
** message into the header of the reassembled message.
*/