Make mhstore(1) use "filename" attr of Content-Disposition
authormarkus schnalke <meillo@marmaro.de>
Mon, 5 Sep 2016 09:51:00 +0000 (11:51 +0200)
committermarkus schnalke <meillo@marmaro.de>
Mon, 5 Sep 2016 09:51:00 +0000 (11:51 +0200)
Before, only the "name" attr of Content-Type was used as the filename
to store attachments. The "filename" attr of Content-Disposition
(which is the much more appropriate value) was ignored, thus often
resulting in the attachment being stored with a default name like
20.2.pdf, for instance.

h/mhparse.h
uip/mhparse.c
uip/mhstore.c

index 1954d89..782ab51 100644 (file)
@@ -251,3 +251,4 @@ int add_header(CT, char *, char *);
 int get_ctinfo(unsigned char *, CT, int);
 int open7Bit(CT, char **);
 void close_encoding(CT);
 int get_ctinfo(unsigned char *, CT, int);
 int open7Bit(CT, char **);
 void close_encoding(CT);
+char *extract_name_value(char *, char *);
index b860dcf..da19123 100644 (file)
@@ -550,7 +550,7 @@ incl_name_value(unsigned char *buf, char *name, char *value) {
 ** one, return the entire value.  Note that, for example, a name_suffix
 ** of name will match filename="foo", and return foo.
 */
 ** one, return the entire value.  Note that, for example, a name_suffix
 ** of name will match filename="foo", and return foo.
 */
-static char *
+char *
 extract_name_value(char *name_suffix, char *value) {
        char *extracted_name_value = value;
        char *name_suffix_plus_quote = concat(name_suffix, "=\"", NULL);
 extract_name_value(char *name_suffix, char *value) {
        char *extracted_name_value = value;
        char *name_suffix_plus_quote = concat(name_suffix, "=\"", NULL);
index adaca77..2b909ef 100644 (file)
@@ -468,7 +468,7 @@ store_switch(CT ct)
 static int
 store_generic(CT ct)
 {
 static int
 store_generic(CT ct)
 {
-       char **ap, **vp, *cp;
+       char **ap, **vp, *cp, *filename;
        CI ci = &ct->c_ctinfo;
 
        /*
        CI ci = &ct->c_ctinfo;
 
        /*
@@ -477,6 +477,18 @@ store_generic(CT ct)
        ** (only the "message" subtype "rfc822" will use store_generic).
        */
        if (autosw && ct->c_type != CT_MESSAGE) {
        ** (only the "message" subtype "rfc822" will use store_generic).
        */
        if (autosw && ct->c_type != CT_MESSAGE) {
+               /* First check for "filename" in Content-Disposition header */
+               filename = extract_name_value("filename", ct->c_dispo);
+               if (strcmp(filename, ct->c_dispo)!=0) {
+                       /* We found "filename" */
+                       cp = mhbasename(filename);
+                       if (*cp && *cp!='.' && *cp!='|' && *cp!='!' &&
+                                       !strchr(cp, '%')) {
+                               /* filename looks good: use it */
+                               ct->c_storeproc = mh_xstrdup(cp);
+                               goto finished;
+                       }
+               }
                /*
                ** Check the attribute/value pairs, for the attribute "name".
                ** If found, take the basename, do a few sanity checks and
                /*
                ** Check the attribute/value pairs, for the attribute "name".
                ** If found, take the basename, do a few sanity checks and
@@ -496,6 +508,7 @@ store_generic(CT ct)
                }
        }
 
                }
        }
 
+finished:
        return store_content(ct, NULL);
 }
 
        return store_content(ct, NULL);
 }