#include <fcntl.h>
#include <h/signals.h>
#include <h/md5.h>
-#include <errno.h>
-#include <signal.h>
#include <h/mts.h>
#include <h/tws.h>
#include <h/mime.h>
switch (ct->c_type) {
case CT_MULTIPART:
return store_multi (ct);
- break;
case CT_MESSAGE:
switch (ct->c_subtype) {
case MESSAGE_PARTIAL:
return store_partial (ct);
- break;
case MESSAGE_EXTERNAL:
return store_external (ct);
case MESSAGE_RFC822:
default:
return store_generic (ct);
- break;
}
- break;
case CT_APPLICATION:
return store_application (ct);
- break;
case CT_TEXT:
case CT_AUDIO:
case CT_IMAGE:
case CT_VIDEO:
return store_generic (ct);
- break;
default:
adios (NULL, "unknown content type %d", ct->c_type);
- break;
}
return OK; /* NOT REACHED */
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"))
+ if (!strcasecmp (*ap, "type")) {
+ if (strcasecmp (*ep, "tar"))
break;
tarP = 1;
}
/* check for "conversions=compress" attribute */
- if ((!mh_strcasecmp (*ap, "conversions") || !mh_strcasecmp (*ap, "x-conversions"))
- && (!mh_strcasecmp (*ep, "compress") || !mh_strcasecmp (*ep, "x-compress"))) {
+ if ((!strcasecmp (*ap, "conversions") || !strcasecmp (*ap, "x-conversions"))
+ && (!strcasecmp (*ep, "compress") || !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"))) {
+ if ((!strcasecmp (*ap, "conversions") || !strcasecmp (*ap, "x-conversions"))
+ && (!strcasecmp (*ep, "gzip") || !strcasecmp (*ep, "x-gzip"))) {
gzP = 1;
continue;
}
CT p = part->mp_part;
if (part_ok (p, 1) && type_ok (p, 1)) {
+ if (ct->c_storage) {
+ /* Support mhstore -outfile. The MIME parser doesn't
+ load c_storage, so we know that p->c_storage is
+ NULL here. */
+ p->c_storage = ct->c_storage;
+ }
result = store_switch (p);
+ p->c_storage = NULL;
+
if (result == OK && ct->c_subtype == MULTI_ALTERNATE)
break;
}
p->c_partno = ct->c_partno;
/* we probably need to check if content is really there */
+ if (ct->c_storage) {
+ /* Support mhstore -outfile. The MIME parser doesn't load
+ c_storage, so we know that p->c_storage is NULL here. */
+ p->c_storage = ct->c_storage;
+ }
result = store_switch (p);
+ p->c_storage = NULL;
p->c_partno = NULL;
return result;
*/
if (p) {
appending = 1;
- ct->c_storage = add (p->c_storage, NULL);
+ if (! ct->c_storage) {
+ ct->c_storage = add (p->c_storage, NULL);
- /* record the folder name */
- if (p->c_folder) {
- ct->c_folder = add (p->c_folder, NULL);
+ /* record the folder name */
+ if (p->c_folder) {
+ ct->c_folder = add (p->c_folder, NULL);
+ }
}
goto got_filename;
}
}
}
- /*
- * Check the beginning of storage formatting string
- * to see if we are saving content to a folder.
- */
- if (*cp == '+' || *cp == '@') {
- char *tmpfilenam, *folder;
+ if (! ct->c_storage) {
+ /*
+ * Check the beginning of storage formatting string
+ * to see if we are saving content to a folder.
+ */
+ if (*cp == '+' || *cp == '@') {
+ char *tmpfilenam, *folder;
- /* Store content in temporary file for now */
- tmpfilenam = m_mktemp(invo_name, NULL, NULL);
- ct->c_storage = add (tmpfilenam, NULL);
+ /* Store content in temporary file for now */
+ tmpfilenam = m_mktemp(invo_name, NULL, NULL);
+ ct->c_storage = add (tmpfilenam, NULL);
- /* Get the folder name */
- if (cp[1])
- folder = pluspath (cp);
- else
- folder = getfolder (1);
+ /* Get the folder name */
+ if (cp[1])
+ folder = pluspath (cp);
+ else
+ folder = getfolder (1);
- /* Check if folder exists */
- create_folder(m_mailpath(folder), 0, exit);
+ /* Check if folder exists */
+ create_folder(m_mailpath(folder), 0, exit);
- /* Record the folder name */
- ct->c_folder = add (folder, NULL);
+ /* Record the folder name */
+ ct->c_folder = add (folder, NULL);
- if (cp[1])
- free (folder);
+ if (cp[1])
+ free (folder);
- goto got_filename;
- }
+ goto got_filename;
+ }
- /*
- * Parse and expand the storage formatting string
- * in `cp' into `buffer'.
- */
- parse_format_string (ct, cp, buffer, sizeof(buffer), dir);
+ /*
+ * Parse and expand the storage formatting string
+ * in `cp' into `buffer'.
+ */
+ parse_format_string (ct, cp, buffer, sizeof(buffer), dir);
- /*
- * If formatting begins with '|' or '!', then pass
- * content to standard input of a command and return.
- */
- if (buffer[0] == '|' || buffer[0] == '!')
- return show_content_aux (ct, 1, 0, buffer + 1, dir);
+ /*
+ * If formatting begins with '|' or '!', then pass
+ * content to standard input of a command and return.
+ */
+ if (buffer[0] == '|' || buffer[0] == '!')
+ return show_content_aux (ct, 1, 0, buffer + 1, dir);
- /* record the filename */
- if ((ct->c_storage = clobber_check (add (buffer, NULL))) == NULL) {
- return NOTOK;
+ /* record the filename */
+ if ((ct->c_storage = clobber_check (add (buffer, NULL))) == NULL) {
+ return NOTOK;
+ }
+ } else {
+ /* The output filename was explicitly specified, so use it. */
+ if ((ct->c_storage = clobber_check (add (ct->c_storage, NULL))) ==
+ NULL) {
+ return NOTOK;
+ }
}
got_filename:
get_storeproc (CT ct)
{
char **ap, **ep, *cp;
- CI ci = &ct->c_ctinfo;
+ CI ci;
/*
* If the storeproc has already been defined,
if (ct->c_storeproc)
return;
+ /*
+ * If there's a Content-Disposition header and it has a filename,
+ * use that (RFC-2183).
+ */
+ if (ct->c_dispo) {
+ char *cp = strchr (ct->c_dispo, ';');
+ CI ci = calloc (1, sizeof *ci);
+ int status;
+ int found_filename = 0;
+
+ if (cp && parse_header_attrs (ct->c_file, strlen (invo_name) + 2, &cp,
+ ci, &status) == OK) {
+ for (ap = ci->ci_attrs, ep = ci->ci_values; *ap; ap++, ep++) {
+ if (! strcasecmp (*ap, "filename")
+ && *(cp = *ep) != '/'
+ && *cp != '.'
+ && *cp != '|'
+ && *cp != '!'
+ && !strchr (cp, '%')) {
+ ct->c_storeproc = add (cp, NULL);
+ found_filename = 1;
+ }
+ free (*ap);
+ }
+ }
+
+ free (ci);
+ if (found_filename) return;
+ }
+
/*
* Check the attribute/value pairs, for the attribute "name".
* If found, do a few sanity checks and copy the value into
* the storeproc.
*/
+ ci = &ct->c_ctinfo;
for (ap = ci->ci_attrs, ep = ci->ci_values; *ap; ap++, ep++) {
- if (!mh_strcasecmp (*ap, "name")
+ if (! strcasecmp (*ap, "name")
&& *(cp = *ep) != '/'
&& *cp != '.'
&& *cp != '|'
* messages are not copied.
*/
if (!uprf (hp->name, XXX_FIELD_PRF)
- && mh_strcasecmp (hp->name, VRSN_FIELD)
- && mh_strcasecmp (hp->name, "Subject")
- && mh_strcasecmp (hp->name, "Encrypted")
- && mh_strcasecmp (hp->name, "Message-ID"))
+ && strcasecmp (hp->name, VRSN_FIELD)
+ && strcasecmp (hp->name, "Subject")
+ && strcasecmp (hp->name, "Encrypted")
+ && strcasecmp (hp->name, "Message-ID"))
fprintf (out, "%s:%s", hp->name, hp->value);
hp = hp->next; /* next header field */
}
int
save_clobber_policy (const char *value) {
- if (! mh_strcasecmp (value, "always")) {
+ if (! strcasecmp (value, "always")) {
clobber_policy = NMH_CLOBBER_ALWAYS;
- } else if (! mh_strcasecmp (value, "auto")) {
+ } else if (! strcasecmp (value, "auto")) {
clobber_policy = NMH_CLOBBER_AUTO;
- } else if (! mh_strcasecmp (value, "suffix")) {
+ } else if (! strcasecmp (value, "suffix")) {
clobber_policy = NMH_CLOBBER_SUFFIX;
- } else if (! mh_strcasecmp (value, "ask")) {
+ } else if (! strcasecmp (value, "ask")) {
clobber_policy = NMH_CLOBBER_ASK;
- } else if (! mh_strcasecmp (value, "never")) {
+ } else if (! strcasecmp (value, "never")) {
clobber_policy = NMH_CLOBBER_NEVER;
} else {
return 1;
clobber_check (char *original_file) {
/* clobber policy return value
* -------------- ------------
- * -always file
- * -auto file-<digits>.extension
- * -suffix file.<digits>
- * -ask file, 0, or another filename/path
- * -never 0
+ * -always original_file
+ * -auto original_file-<digits>.extension
+ * -suffix original_file.<digits>
+ * -ask original_file, 0, or another filename/path
+ * -never 0
*/
char *file;