* src/procmime.[ch]
authorLuke Plant <L.Plant.98@cantab.net>
Sat, 29 Nov 2003 00:36:02 +0000 (00:36 +0000)
committerLuke Plant <L.Plant.98@cantab.net>
Sat, 29 Nov 2003 00:36:02 +0000 (00:36 +0000)
        re-added parsing of Content-Disposition header
                - removes the old  'gchar* content_disposition'
                - adds a new field 'DispositionType disposition'
                - adds parameters to MimeInfo::parameters
* src/mimeview.c
        use the "filename" parameter for saving, and the new
        MimeInfo::disposition for save all.

src/mimeview.c
src/procmime.c
src/procmime.h

index 4abe8a0..ab6c89f 100644 (file)
@@ -394,25 +394,26 @@ static void mimeview_set_multipart_tree(MimeView *mimeview,
        }
 }
 
-static gchar *get_part_name(MimeInfo *partinfo)
+static const gchar *get_part_name(MimeInfo *partinfo)
 {
-       gchar *name;
+       const gchar *name;
 
-       name = g_hash_table_lookup(partinfo->parameters, "name");
-       if(name == NULL)
-               name = "";
+       name = procmime_mimeinfo_get_parameter(partinfo, "filename");
+       if (name == NULL) {
+               name = procmime_mimeinfo_get_parameter(partinfo, "name");
+               if (name == NULL)
+                       name = "";
+       }
 
        return name;
 }
 
-static gchar *get_part_description(MimeInfo *partinfo)
+static const gchar *get_part_description(MimeInfo *partinfo)
 {
        if (partinfo->description)
                return partinfo->description;
-       else if (g_hash_table_lookup(partinfo->parameters, "name") != NULL)
-               return g_hash_table_lookup(partinfo->parameters, "name");
        else
-               return "";
+               return get_part_name(partinfo);
 }
 
 static GtkCTreeNode *mimeview_append_part(MimeView *mimeview,
@@ -992,8 +993,7 @@ static void mimeview_save_all(MimeView *mimeview)
        while (attachment != NULL) {
                if (attachment->type != MIMETYPE_MESSAGE &&
                    attachment->type != MIMETYPE_MULTIPART &&
-                   (procmime_mimeinfo_get_parameter(attachment, "name") ||
-                    procmime_mimeinfo_get_parameter(attachment, "filename"))) {
+                   attachment->disposition == DISPOSITIONTYPE_ATTACHMENT) {
                        static guint subst_cnt = 1;
                        gchar *attachdir;
                        gchar *attachname = g_strdup(get_part_name(attachment));
@@ -1069,7 +1069,7 @@ static void mimeview_save_as(MimeView *mimeview)
        }                        
        g_return_if_fail(partinfo != NULL);
        
-       if ((partname = procmime_mimeinfo_get_parameter(partinfo, "name")) != NULL) {
+       if ((partname = get_part_name(partinfo)) != NULL) {
                Xstrdup_a(defname, partname, return);
                subst_for_filename(defname);
        }
@@ -1412,7 +1412,7 @@ static void icon_list_append_icon (MimeView *mimeview, MimeInfo *mimeinfo)
        GtkWidget *vbox;
        GtkWidget *button;
        gchar *tip;
-       gchar *desc = NULL;
+       const gchar *desc = NULL;
        StockPixmap stockp;
        
        vbox = mimeview->icon_vbox;
index f8ec7cc..59224d3 100644 (file)
@@ -77,7 +77,6 @@ static gboolean free_func(GNode *node, gpointer data)
 
        g_free(mimeinfo->encoding);
        g_free(mimeinfo->name);
-       g_free(mimeinfo->content_disposition);
        if(mimeinfo->tmpfile)
                unlink(mimeinfo->filename);
        g_free(mimeinfo->filename);
@@ -942,6 +941,7 @@ void procmime_parse_mimepart(MimeInfo *parent,
                             gchar *content_encoding,
                             gchar *content_description,
                             gchar *content_id,
+                            gchar *content_disposition,
                             const gchar *filename,
                             guint offset,
                             guint length);
@@ -955,6 +955,8 @@ void procmime_parse_message_rfc822(MimeInfo *mimeinfo)
                                                   NULL, TRUE},
                                {"Content-ID:",
                                                   NULL, TRUE},
+                               {"Content-Disposition:",
+                                                  NULL, TRUE},
                                {NULL,             NULL, FALSE}};
        guint content_start, i;
        FILE *fp;
@@ -973,9 +975,10 @@ void procmime_parse_message_rfc822(MimeInfo *mimeinfo)
        procmime_parse_mimepart(mimeinfo,
                                hentry[0].body, hentry[1].body,
                                hentry[2].body, hentry[3].body, 
+                               hentry[4].body, 
                                mimeinfo->filename, content_start,
                                mimeinfo->length - (content_start - mimeinfo->offset));
-       for (i = 0; i < 4; i++) {
+       for (i = 0; i < (sizeof hentry / sizeof hentry[0]); i++) {
                g_free(hentry[i].body);
                hentry[i].body = NULL;
        }
@@ -990,6 +993,8 @@ void procmime_parse_multipart(MimeInfo *mimeinfo)
                                                   NULL, TRUE},
                                {"Content-ID:",
                                                   NULL, TRUE},
+                               {"Content-Disposition:",
+                                                  NULL, TRUE},
                                {NULL,             NULL, FALSE}};
        gchar *p;
        gchar *boundary;
@@ -1018,6 +1023,7 @@ void procmime_parse_multipart(MimeInfo *mimeinfo)
                                procmime_parse_mimepart(mimeinfo,
                                                        hentry[0].body, hentry[1].body,
                                                        hentry[2].body, hentry[3].body, 
+                                                       hentry[4].body, 
                                                        mimeinfo->filename, lastoffset,
                                                        (ftell(fp) - strlen(buf)) - lastoffset);
                        }
@@ -1026,7 +1032,7 @@ void procmime_parse_multipart(MimeInfo *mimeinfo)
                            buf[2 + boundary_len + 1] == '-')
                                break;
 
-                       for (i = 0; i < 4; i++) {
+                       for (i = 0; i < (sizeof hentry / sizeof hentry[0]) ; i++) {
                                g_free(hentry[i].body);
                                hentry[i].body = NULL;
                        }
@@ -1034,13 +1040,41 @@ void procmime_parse_multipart(MimeInfo *mimeinfo)
                        lastoffset = ftell(fp);
                }
        }
-       for (i = 0; i < 4; i++) {
+       for (i = 0; i < (sizeof hentry / sizeof hentry[0]); i++) {
                g_free(hentry[i].body);
                hentry[i].body = NULL;
        }
        fclose(fp);
 }
 
+static void add_to_mimeinfo_parameters(gchar **parts, MimeInfo *mimeinfo)
+{
+       gchar **strarray;
+
+       for (strarray = parts; *strarray != NULL; strarray++) {
+               gchar **parameters_parts;
+
+               parameters_parts = g_strsplit(*strarray, "=", 1);
+               if ((parameters_parts[0] != NULL) && (parameters_parts[1] != NULL)) {
+                       gchar *firstspace;
+
+                       g_strstrip(parameters_parts[0]);
+                       g_strstrip(parameters_parts[1]);
+                       g_strdown(parameters_parts[0]);
+                       if(parameters_parts[1][0] == '"')
+                               extract_quote(parameters_parts[1], '"');
+                       else if ((firstspace = strchr(parameters_parts[1], ' ')) != NULL)
+                               *firstspace = '\0';
+                       if(g_hash_table_lookup(mimeinfo->parameters,
+                                              parameters_parts[0]) == NULL)
+                               g_hash_table_insert(mimeinfo->parameters,
+                                                   g_strdup(parameters_parts[0]),
+                                                   g_strdup(parameters_parts[1]));
+               }
+               g_strfreev(parameters_parts);
+       }
+}      
+
 static void procmime_parse_content_type(const gchar *content_type, MimeInfo *mimeinfo)
 {
        gchar **content_type_parts;
@@ -1075,31 +1109,43 @@ static void procmime_parse_content_type(const gchar *content_type, MimeInfo *mim
        }
 
        /* Get mimeinfo->parmeters */
-       for (strarray = &content_type_parts[1]; *strarray != NULL; strarray++) {
-               gchar **parameters_parts;
+       add_to_mimeinfo_parameters(&content_type_parts[1], mimeinfo);
+       g_strfreev(content_type_parts);
+}
 
-               parameters_parts = g_strsplit(*strarray, "=", 1);
-               if ((parameters_parts[0] != NULL) && (parameters_parts[1] != NULL)) {
-                       gchar *firstspace;
+static void procmime_parse_content_disposition(const gchar *content_disposition, MimeInfo *mimeinfo)
+{
+       gchar **content_disp_parts;
+       gchar **strarray;
+       gchar *str;
 
-                       g_strstrip(parameters_parts[0]);
-                       g_strstrip(parameters_parts[1]);
-                       g_strdown(parameters_parts[0]);
-                       if(parameters_parts[1][0] == '"')
-                               extract_quote(parameters_parts[1], '"');
-                       else if ((firstspace = strchr(parameters_parts[1], ' ')) != NULL)
-                               *firstspace = '\0';
+       g_return_if_fail(content_disposition != NULL);
+       g_return_if_fail(mimeinfo != NULL);
 
-                       g_hash_table_insert(mimeinfo->parameters,
-                                           g_strdup(parameters_parts[0]),
-                                           g_strdup(parameters_parts[1]));
-               }
-               g_strfreev(parameters_parts);
+       /* Split into parts and remove trailing
+          and leading whitespaces from all strings */
+       content_disp_parts = g_strsplit(content_disposition, ";", 0);
+       for (strarray = content_disp_parts; *strarray != NULL; strarray++) {
+               g_strstrip(*strarray);
+       }
+       /* Get mimeinfo->disposition */
+       str = content_disp_parts[0];
+       if (str == NULL) {
+               g_strfreev(content_disp_parts);
+               return;
        }
-
-       g_strfreev(content_type_parts);
+       if (!g_strcasecmp(str, "inline")) 
+               mimeinfo->disposition = DISPOSITIONTYPE_INLINE;
+       else if (!g_strcasecmp(str, "attachment"))
+               mimeinfo->disposition = DISPOSITIONTYPE_ATTACHMENT;
+       else
+               mimeinfo->disposition = DISPOSITIONTYPE_UNKNOWN;
+       
+       add_to_mimeinfo_parameters(&content_disp_parts[1], mimeinfo);
+       g_strfreev(content_disp_parts);
 }
 
+
 static void procmime_parse_content_encoding(const gchar *content_encoding, MimeInfo *mimeinfo)
 {
        struct EncodingTable *enc_table;
@@ -1119,6 +1165,7 @@ void procmime_parse_mimepart(MimeInfo *parent,
                             gchar *content_encoding,
                             gchar *content_description,
                             gchar *content_id,
+                            gchar *content_disposition,
                             const gchar *filename,
                             guint offset,
                             guint length)
@@ -1157,6 +1204,11 @@ void procmime_parse_mimepart(MimeInfo *parent,
        else
                mimeinfo->id = NULL;
 
+       if (content_disposition != NULL) 
+               procmime_parse_content_disposition(content_disposition, mimeinfo);
+       else
+               mimeinfo->disposition = DISPOSITIONTYPE_INLINE;
+
        /* Call parser for mime type */
        switch (mimeinfo->type) {
                case MIMETYPE_MESSAGE:
index 5143ee1..cd30951 100644 (file)
@@ -54,6 +54,13 @@ typedef enum
        MIMETYPE_UNKNOWN,
 } MimeMediaType;
 
+typedef enum
+{
+       DISPOSITIONTYPE_INLINE,
+       DISPOSITIONTYPE_ATTACHMENT,
+       DISPOSITIONTYPE_UNKNOWN
+} DispositionType;
+
 #include <glib.h>
 #include <stdio.h>
 
@@ -94,8 +101,6 @@ struct _MimeInfo
 
        gchar *name;
 
-       gchar *content_disposition;
-
        /* Internal data */
        gchar *filename;
        gboolean tmpfile;
@@ -121,6 +126,9 @@ struct _MimeInfo
        guint            offset;
        guint            length;
 
+       /* Content-Disposition */
+       DispositionType  disposition;
+
        /* Privacy */
        PrivacyData     *privacy;
 };