X-Git-Url: https://diplodocus.org/git/nmh/blobdiff_plain/c703902741e0f7ce55f87e48ef0d00901195f1bc..b4f2851d4:/uip/mhstoresbr.c diff --git a/uip/mhstoresbr.c b/uip/mhstoresbr.c index b978dbfb..93d3e902 100644 --- a/uip/mhstoresbr.c +++ b/uip/mhstoresbr.c @@ -11,8 +11,6 @@ #include #include #include -#include -#include #include #include #include @@ -137,13 +135,11 @@ store_switch (CT ct) 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); @@ -151,24 +147,19 @@ store_switch (CT 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 */ @@ -219,8 +210,8 @@ store_application (CT ct) 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; @@ -228,14 +219,14 @@ store_application (CT ct) } /* 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; } @@ -280,7 +271,15 @@ store_multi (CT ct) 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; } @@ -440,7 +439,13 @@ store_external (CT ct) 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; @@ -514,11 +519,13 @@ store_content (CT ct, CT p) */ 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; } @@ -546,51 +553,59 @@ store_content (CT ct, CT p) } } - /* - * 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: @@ -872,7 +887,7 @@ output_content_folder (char *folder, char *filename) struct msgs *mp; /* Read the folder. */ - if ((mp = folder_read (folder))) { + if ((mp = folder_read (folder, 0))) { /* Link file into folder */ msgnum = folder_addmsg (&mp, filename, 0, 0, 0, 0, (char *)0); } else { @@ -1021,7 +1036,7 @@ static void get_storeproc (CT ct) { char **ap, **ep, *cp; - CI ci = &ct->c_ctinfo; + CI ci; /* * If the storeproc has already been defined, @@ -1031,13 +1046,44 @@ get_storeproc (CT ct) 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 != '|' @@ -1068,10 +1114,10 @@ copy_some_headers (FILE *out, CT ct) * 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 */ } @@ -1096,15 +1142,15 @@ int files_not_clobbered = 0; 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; @@ -1181,11 +1227,11 @@ static char * clobber_check (char *original_file) { /* clobber policy return value * -------------- ------------ - * -always file - * -auto file-.extension - * -suffix file. - * -ask file, 0, or another filename/path - * -never 0 + * -always original_file + * -auto original_file-.extension + * -suffix original_file. + * -ask original_file, 0, or another filename/path + * -never 0 */ char *file;