2004-10-29 [paul] 0.9.12cvs135.1
authorPaul Mangan <paul@claws-mail.org>
Fri, 29 Oct 2004 06:17:33 +0000 (06:17 +0000)
committerPaul Mangan <paul@claws-mail.org>
Fri, 29 Oct 2004 06:17:33 +0000 (06:17 +0000)
* configure.ac
* doc/src/rfc2231.txt
* src/procmime.c
* src/common/quoted-printable.c
* src/common/utils.c
* src/common/utils.h
sync with HEAD

ChangeLog-gtk2.claws
PATCHSETS
configure.ac
src/common/quoted-printable.c
src/common/utils.c
src/common/utils.h
src/procmime.c

index 58a3c81a411388678564e6a8aebe374a5d94f2a4..8c2e107148ce7833e8f5292bb1ab26f8265e14d8 100644 (file)
@@ -1,3 +1,13 @@
+2004-10-29 [paul]      0.9.12cvs135.1
+
+       * configure.ac
+       * doc/src/rfc2231.txt
+       * src/procmime.c
+       * src/common/quoted-printable.c
+       * src/common/utils.c
+       * src/common/utils.h
+               sync with HEAD
+
 2004-10-27 [paul]      0.9.12cvs134.1
 
        * configure.ac
index db8a3374db2bbaed0db61b7cdce6609043cf9cbd..3c0fe7d25512448db133a1f7c7039474beee24b2 100644 (file)
--- a/PATCHSETS
+++ b/PATCHSETS
 ( cvs diff -u -r 1.52.2.7 -r 1.52.2.8 src/prefs_folder_item.c; ) > 0.9.12cvs132.2.patchset
 ( cvs diff -u -r 1.61.2.13 -r 1.61.2.14 src/account.c; cvs diff -u -r 1.60.2.12 -r 1.60.2.13 src/addressbook.c; cvs diff -u -r 1.5.10.4 -r 1.5.10.5 src/addrgather.c; cvs diff -u -r 1.6 -r 1.7 src/addrharvest.c; cvs diff -u -r 1.65.2.16 -r 1.65.2.17 src/codeconv.c; cvs diff -u -r 1.382.2.56 -r 1.382.2.57 src/compose.c; cvs diff -u -r 1.5.2.3 -r 1.5.2.4 src/customheader.c; cvs diff -u -r 1.14.2.3 -r 1.14.2.4 src/editaddress.c; cvs diff -u -r 1.11.2.3 -r 1.11.2.4 src/editgroup.c; cvs diff -u -r 1.3.2.1 -r 1.3.2.2 src/enriched.c; cvs diff -u -r 1.1.4.4 -r 1.1.4.5 src/expldifdlg.c; cvs diff -u -r 1.5.2.1 -r 1.5.2.2 src/exporthtml.c; cvs diff -u -r 1.1.4.1 -r 1.1.4.2 src/exportldif.c; cvs diff -u -r 1.213.2.18 -r 1.213.2.19 src/folder.c; cvs diff -u -r 1.26.2.5 -r 1.26.2.6 src/foldersel.c; cvs diff -u -r 1.207.2.19 -r 1.207.2.20 src/folderview.c; cvs diff -u -r 1.14.2.5 -r 1.14.2.6 src/grouplistdialog.c; cvs diff -u -r 1.12.2.2 -r 1.12.2.3 src/html.c; cvs diff -u -r 1.179.2.9 -r 1.179.2.10 src/imap.c; cvs diff -u -r 1.18.2.3 -r 1.18.2.4 src/jpilot.c; cvs diff -u -r 1.4.2.2 -r 1.4.2.3 src/ldapserver.c; cvs diff -u -r 1.12 -r 1.13 src/ldif.c; cvs diff -u -r 1.83.2.22 -r 1.83.2.23 src/mimeview.c; cvs diff -u -r 1.101.2.6 -r 1.101.2.7 src/news.c; cvs diff -u -r 1.2.2.1 -r 1.2.2.2 src/news_gtk.c; cvs diff -u -r 1.56.2.26 -r 1.56.2.27 src/pop.c; cvs diff -u -r 1.16.2.4 -r 1.16.2.5 src/prefs_display_header.c; cvs diff -u -r 1.10.2.7 -r 1.10.2.8 src/prefs_gtk.c; cvs diff -u -r 1.1.2.5 -r 1.1.2.6 src/prefs_msg_colors.c; cvs diff -u -r 1.30.2.4 -r 1.30.2.5 src/prefs_toolbar.c; cvs diff -u -r 1.47.2.10 -r 1.47.2.11 src/procheader.c; cvs diff -u -r 1.49.2.11 -r 1.49.2.12 src/procmime.c; cvs diff -u -r 1.395.2.36 -r 1.395.2.37 src/summaryview.c; cvs diff -u -r 1.96.2.24 -r 1.96.2.25 src/textview.c; cvs diff -u -r 1.43.2.10 -r 1.43.2.11 src/toolbar.c; cvs diff -u -r 1.14.2.1 -r 1.14.2.2 src/vcard.c; cvs diff -u -r 1.1 -r 1.2 src/common/mgutils.c; cvs diff -u -r 1.6.2.3 -r 1.6.2.4 src/common/nntp.c; cvs diff -u -r 1.11.2.4 -r 1.11.2.5 src/common/smtp.c; cvs diff -u -r 1.2.4.1 -r 1.2.4.2 src/common/template.c; cvs diff -u -r 1.36.2.10 -r 1.36.2.11 src/common/utils.c; cvs diff -u -r 1.1 -r 1.2 src/common/xmlprops.c; cvs diff -u -r 1.1.2.6 -r 1.1.2.7 src/plugins/pgpmime/pgpmime.c; cvs diff -u -r 1.1.2.2 -r 1.1.2.3 src/plugins/pgpmime/select-keys.c; cvs diff -u -r 1.1.2.4 -r 1.1.2.5 src/plugins/pgpmime/sgpgme.c; ) > 0.9.12cvs132.3.patchset
 ( cvs diff -u -r 1.654.2.243 -r 1.654.2.244 configure.ac; cvs diff -u -r 1.115.2.21 -r 1.115.2.22 src/main.c; cvs diff -u -r 1.49.2.12 -r 1.49.2.13 src/procmime.c; cvs diff -u -r 1.1.2.7 -r 1.1.2.8 src/plugins/pgpmime/pgpmime.c; ) > 0.9.12cvs134.1.patchset
+( cvs diff -u -r 1.654.2.244 -r 1.654.2.245 configure.ac; cvs diff -u -r 0 -r 1 doc/src/rfc2231.txt; cvs diff -u -r 1.49.2.13 -r 1.49.2.14 src/procmime.c; cvs diff -u -r 1.3.2.1 -r 1.3.2.2 src/common/quoted-printable.c; cvs diff -u -r 1.36.2.11 -r 1.36.2.12 src/common/utils.c; cvs diff -u -r 1.20.2.8 -r 1.20.2.9 src/common/utils.h; ) > 0.9.12cvs135.1.patchset
index c165df12918624f796928632ce7aecc7b441b71d..ca44f6778466f88013f875ae2e308da512a40056 100644 (file)
@@ -11,7 +11,7 @@ MINOR_VERSION=9
 MICRO_VERSION=12
 INTERFACE_AGE=0
 BINARY_AGE=0
-EXTRA_VERSION=134
+EXTRA_VERSION=135
 EXTRA_RELEASE=
 EXTRA_GTK2_VERSION=.1
 
index bf99a234f927189859a67dd53a9f3bcc8cf527df..fd652bc2358f4955c314bbd663ca7a76c3d3e278 100644 (file)
@@ -20,8 +20,7 @@
 #include <glib.h>
 #include <ctype.h>
 
-static gboolean get_hex_value(guchar *out, gchar c1, gchar c2);
-static void get_hex_str(gchar *out, guchar ch);
+#include "utils.h"
 
 #define MAX_LINELEN    76
 
@@ -182,50 +181,3 @@ void qp_q_encode(gchar *out, const guchar *in)
 
        *outp = '\0';
 }
-
-#define HEX_TO_INT(val, hex)                   \
-{                                              \
-       gchar c = hex;                          \
-                                               \
-       if ('0' <= c && c <= '9') {             \
-               val = c - '0';                  \
-       } else if ('a' <= c && c <= 'f') {      \
-               val = c - 'a' + 10;             \
-       } else if ('A' <= c && c <= 'F') {      \
-               val = c - 'A' + 10;             \
-       } else {                                \
-               val = -1;                       \
-       }                                       \
-}
-
-static gboolean get_hex_value(guchar *out, gchar c1, gchar c2)
-{
-       gint hi, lo;
-
-       HEX_TO_INT(hi, c1);
-       HEX_TO_INT(lo, c2);
-
-       if (hi == -1 || lo == -1)
-               return FALSE;
-
-       *out = (hi << 4) + lo;
-       return TRUE;
-}
-
-#define INT_TO_HEX(hex, val)           \
-{                                      \
-       if ((val) < 10)                 \
-               hex = '0' + (val);      \
-       else                            \
-               hex = 'A' + (val) - 10; \
-}
-
-static void get_hex_str(gchar *out, guchar ch)
-{
-       gchar hex;
-
-       INT_TO_HEX(hex, ch >> 4);
-       *out++ = hex;
-       INT_TO_HEX(hex, ch & 0x0f);
-       *out++ = hex;
-}
index 147e0f8a9a11572a5c67538adb37cadc53627b38..ac31cd1e46f4529e82aab9038cd8005b9e5cbf67 100644 (file)
@@ -3662,3 +3662,50 @@ GNode *g_node_map(GNode *node, GNodeMapFunc func, gpointer data)
 
        return root;
 }
+
+#define HEX_TO_INT(val, hex)                   \
+{                                              \
+       gchar c = hex;                          \
+                                               \
+       if ('0' <= c && c <= '9') {             \
+               val = c - '0';                  \
+       } else if ('a' <= c && c <= 'f') {      \
+               val = c - 'a' + 10;             \
+       } else if ('A' <= c && c <= 'F') {      \
+               val = c - 'A' + 10;             \
+       } else {                                \
+               val = -1;                       \
+       }                                       \
+}
+
+gboolean get_hex_value(guchar *out, gchar c1, gchar c2)
+{
+       gint hi, lo;
+
+       HEX_TO_INT(hi, c1);
+       HEX_TO_INT(lo, c2);
+
+       if (hi == -1 || lo == -1)
+               return FALSE;
+
+       *out = (hi << 4) + lo;
+       return TRUE;
+}
+
+#define INT_TO_HEX(hex, val)           \
+{                                      \
+       if ((val) < 10)                 \
+               hex = '0' + (val);      \
+       else                            \
+               hex = 'A' + (val) - 10; \
+}
+
+void get_hex_str(gchar *out, guchar ch)
+{
+       gchar hex;
+
+       INT_TO_HEX(hex, ch >> 4);
+       *out++ = hex;
+       INT_TO_HEX(hex, ch & 0x0f);
+       *out++ = hex;
+}
index 59560aeff017d0db8a007a84c45748e0b83c1b6e..df8e57607c03b0fac71691f97f888c5200d67f4e 100644 (file)
@@ -458,6 +458,9 @@ gint quote_cmd_argument(gchar * result, guint size,
                        const gchar * path);
 GNode *g_node_map(GNode *node, GNodeMapFunc func, gpointer data);
 
+gboolean get_hex_value(guchar *out, gchar c1, gchar c2);
+void get_hex_str(gchar *out, guchar ch);
+
 #ifdef __cplusplus
 }
 #endif
index 48b80fd8072159b9d436f9824cf9b54083674daf..c0a5cce29e551c536fd076de73fa0e46b1d90a2c 100644 (file)
@@ -1239,54 +1239,160 @@ void procmime_parse_multipart(MimeInfo *mimeinfo)
        fclose(fp);
 }
 
-static void add_to_mimeinfo_parameters(gchar **parts, GHashTable *table)
+static void parse_parameters(const gchar *parameters, GHashTable *table)
 {
-       gchar **strarray;
-
-       for (strarray = parts; *strarray != NULL; strarray++) {
-               gchar **parameters_parts;
-
-               parameters_parts = g_strsplit(*strarray, "=", 2);
-               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(table, parameters_parts[0]) == NULL)
-                               g_hash_table_insert(table,
-                                                   g_strdup(parameters_parts[0]),
-                                                   g_strdup(parameters_parts[1]));
+       gchar *params, *param, *next;
+       GSList *convlist = NULL, *concatlist = NULL, *cur;
+
+       params = g_strdup(parameters);
+       param = params;
+       next = params;
+       for (; next != NULL; param = next) {
+               gchar *attribute, *value, *tmp;
+               gint len;
+               gboolean convert = FALSE;
+
+               next = strchr_with_skip_quote(param, '"', ';');
+               if (next != NULL) {
+                       next[0] = '\0';
+                       next++;
+               }
+
+               g_strstrip(param);
+
+               attribute = param;
+               value = strchr(attribute, '=');
+               if (value == NULL)
+                       continue;
+
+               value[0] = '\0';
+               value++;
+
+               g_strdown(attribute);
+
+               len = strlen(attribute);
+               if (attribute[len - 1] == '*') {
+                       gchar *srcpos, *dstpos, *endpos;
+
+                       convert = TRUE;
+                       attribute[len - 1] = '\0';
+
+                       srcpos = value;
+                       dstpos = value;
+                       endpos = value + strlen(value);
+                       while (srcpos < endpos) {
+                               if (*srcpos != '%')
+                                       *dstpos = *srcpos;
+                               else {
+                                       guchar dstvalue;
+
+                                       if (!get_hex_value(&dstvalue, srcpos[1], srcpos[2]))
+                                               *dstpos = '?';
+                                       else
+                                               *dstpos = dstvalue;
+                                       srcpos += 2;
+                               }
+                               srcpos++;
+                               dstpos++;
+                       }
+                       *dstpos = '\0';
+               } else {
+                       if (value[0] == '"')
+                               extract_quote(value, '"');
+                       else if ((tmp = strchr(value, ' ')) != NULL)
+                               *tmp = '\0';
                }
-               g_strfreev(parameters_parts);
+
+               if (strrchr(attribute, '*') != NULL) {
+                       gchar *tmpattr;
+
+                       tmpattr = g_strdup(attribute);
+                       tmp = strrchr(tmpattr, '*');
+                       tmp[0] = '\0';
+
+                       if ((tmp[1] == '0') && (tmp[2] == '\0') && 
+                           (g_slist_find_custom(concatlist, attribute, g_str_equal) == NULL))
+                               concatlist = g_slist_prepend(concatlist, g_strdup(tmpattr));
+
+                       if (convert && (g_slist_find_custom(convlist, attribute, g_str_equal) == NULL))
+                               convlist = g_slist_prepend(convlist, g_strdup(tmpattr));
+
+                       g_free(tmpattr);
+               } else if (convert) {
+                       if (g_slist_find_custom(convlist, attribute, g_str_equal) == NULL)
+                               convlist = g_slist_prepend(convlist, g_strdup(attribute));
+               }
+
+               if (g_hash_table_lookup(table, attribute) == NULL)
+                       g_hash_table_insert(table, g_strdup(attribute), g_strdup(value));
        }
+
+       for (cur = concatlist; cur != NULL; cur = g_slist_next(cur)) {
+               gchar *attribute, *attrwnum, *partvalue;
+               gint n = 0;
+               GString *value;
+
+               attribute = (gchar *) cur->data;
+               value = g_string_sized_new(64);
+
+               attrwnum = g_strdup_printf("%s*%d", attribute, n);
+               while ((partvalue = g_hash_table_lookup(table, attrwnum)) != NULL) {
+                       g_string_append(value, partvalue);
+
+                       g_free(attrwnum);
+                       n++;
+                       attrwnum = g_strdup_printf("%s*%d", attribute, n);
+               }
+               g_free(attrwnum);
+
+               g_hash_table_insert(table, g_strdup(attribute), g_strdup(value->str));
+               g_string_free(value, TRUE);
+       }
+       slist_free_strings(concatlist);
+       g_slist_free(concatlist);
+
+       for (cur = convlist; cur != NULL; cur = g_slist_next(cur)) {
+               gchar *attribute, *key, *value;
+               gchar *charset, *lang, *oldvalue, *newvalue;
+
+               attribute = (gchar *) cur->data;
+               if (!g_hash_table_lookup_extended(table, attribute, (gpointer *) &key, (gpointer *) &value))
+                       continue;
+
+               charset = value;
+               lang = strchr(charset, '\'');
+               if (lang == NULL)
+                       continue;
+               lang[0] = '\0';
+               lang++;
+               oldvalue = strchr(lang, '\'');
+               if (oldvalue == NULL)
+                       continue;
+               oldvalue[0] = '\0';
+               oldvalue++;
+
+               newvalue = conv_codeset_strdup(oldvalue, charset, conv_get_current_charset_str());
+
+               g_hash_table_remove(table, attribute);
+               g_free(key);
+               g_free(value);
+
+               g_hash_table_insert(table, g_strdup(attribute), newvalue);
+       }
+       slist_free_strings(convlist);
+       g_slist_free(convlist);
+
+       g_free(params);
 }      
 
 static void procmime_parse_content_type(const gchar *content_type, MimeInfo *mimeinfo)
 {
-       gchar **content_type_parts;
-       gchar **strarray;
-       gchar *str;
-       
        g_return_if_fail(content_type != NULL);
        g_return_if_fail(mimeinfo != NULL);
 
-       /* Split content type into parts and remove trailing
-          and leading whitespaces from all strings */
-       content_type_parts = g_strsplit(content_type, ";", 0);
-       for (strarray = content_type_parts; *strarray != NULL; strarray++) {
-               g_strstrip(*strarray);
-       }
-
-       /* Get mimeinfo->type and mimeinfo->subtype */
-       str = content_type_parts[0];
        /* RFC 2045, page 13 says that the mime subtype is MANDATORY;
         * if it's not available we use the default Content-Type */
-       if ((str == NULL) || (str[0] == '\0') || (strchr(str, '/') == NULL)) {
+       if ((content_type[0] == '\0') || (strchr(content_type, '/') == NULL)) {
                mimeinfo->type = MIMETYPE_TEXT;
                mimeinfo->subtype = g_strdup("plain");
                if (g_hash_table_lookup(mimeinfo->typeparameters,
@@ -1295,54 +1401,52 @@ static void procmime_parse_content_type(const gchar *content_type, MimeInfo *mim
                                            g_strdup("charset"),
                                            g_strdup("us-ascii"));
        } else {
-               gchar *type, *subtype;
+               gchar *type, *subtype, *params;
 
-               type = g_strdup(str);
+               type = g_strdup(content_type);
                subtype = strchr(type, '/') + 1;
                *(subtype - 1) = '\0';
+               if ((params = strchr(subtype, ';')) != NULL) {
+                       params[0] = '\0';
+                       params++;
+               }
 
                mimeinfo->type = procmime_get_media_type(type);
                mimeinfo->subtype = g_strdup(subtype);
 
-               g_free(type);
+               /* Get mimeinfo->typeparameters */
+               if (params != NULL)
+                       parse_parameters(params, mimeinfo->typeparameters);
 
-               /* Get mimeinfo->parmeters */
-               add_to_mimeinfo_parameters(&content_type_parts[1], mimeinfo->typeparameters);
+               g_free(type);
        }
-
-       g_strfreev(content_type_parts);
 }
 
 static void procmime_parse_content_disposition(const gchar *content_disposition, MimeInfo *mimeinfo)
 {
-       gchar **content_disp_parts;
-       gchar **strarray;
-       gchar *str;
+       gchar *tmp, *params;
 
        g_return_if_fail(content_disposition != NULL);
        g_return_if_fail(mimeinfo != NULL);
 
-       /* 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;
-       }
-       if (!g_ascii_strcasecmp(str, "inline")) 
+       tmp = g_strdup(content_disposition);
+       if ((params = strchr(tmp, ';')) != NULL) {
+               params[0] = '\0';
+               params++;
+       }       
+       g_strstrip(tmp);
+
+       if (!g_ascii_strcasecmp(tmp, "inline")) 
                mimeinfo->disposition = DISPOSITIONTYPE_INLINE;
-       else if (!g_ascii_strcasecmp(str, "attachment"))
+       else if (!g_ascii_strcasecmp(tmp, "attachment"))
                mimeinfo->disposition = DISPOSITIONTYPE_ATTACHMENT;
        else
                mimeinfo->disposition = DISPOSITIONTYPE_ATTACHMENT;
        
-       add_to_mimeinfo_parameters(&content_disp_parts[1], mimeinfo->dispositionparameters);
-       g_strfreev(content_disp_parts);
+       if (params != NULL)
+               parse_parameters(params, mimeinfo->dispositionparameters);
+
+       g_free(tmp);
 }
 
 
@@ -1518,7 +1622,7 @@ MimeInfo *procmime_scan_queue_file(const gchar *filename)
 typedef enum {
     ENC_AS_TOKEN,
     ENC_AS_QUOTED_STRING,
-    ENC_AS_ENCODED_WORD,
+    ENC_AS_EXTENDED,
 } EncodeAs;
 
 static void write_parameters(gpointer key, gpointer value, gpointer user_data)
@@ -1532,7 +1636,7 @@ static void write_parameters(gpointer key, gpointer value, gpointer user_data)
 
        for (valpos = val; *valpos != 0; valpos++) {
                if (!IS_ASCII(*valpos)) {
-                       encas = ENC_AS_ENCODED_WORD;
+                       encas = ENC_AS_EXTENDED;
                        break;
                }
            
@@ -1574,7 +1678,7 @@ static void write_parameters(gpointer key, gpointer value, gpointer user_data)
                fprintf(fp, "\"%s\"", val);
                break;
 
-       case ENC_AS_ENCODED_WORD:
+       case ENC_AS_EXTENDED:
                /* FIXME: not yet handled */
                fprintf(fp, "%s", val);
                break;