2008-11-25 [colin] 3.6.1cvs42
[claws.git] / src / procmime.c
index 8ed67addf86c5c3ee62fba64890462d002e5d4ea..951fdd8ea134ad8630fb0c03b36c39fc81cc94db 100644 (file)
@@ -436,7 +436,7 @@ gboolean procmime_decode_content(MimeInfo *mimeinfo)
                return FALSE;
        }
 
-       stat(tmpfilename, &statbuf);
+       g_stat(tmpfilename, &statbuf);
        if (mimeinfo->tmp && (mimeinfo->data.filename != NULL))
                claws_unlink(mimeinfo->data.filename);
        g_free(mimeinfo->data.filename);
@@ -586,7 +586,7 @@ gboolean procmime_encode_content(MimeInfo *mimeinfo, EncodingType encoding)
                        g_free(mimeinfo->data.mem);
        }
 
-       stat(tmpfilename, &statbuf);
+       g_stat(tmpfilename, &statbuf);
        mimeinfo->content = MIMECONTENT_FILE;
        mimeinfo->data.filename = tmpfilename;
        mimeinfo->tmp = TRUE;
@@ -691,6 +691,9 @@ static FILE *procmime_get_text_content(MimeInfo *mimeinfo)
                      ? forced_charset : 
                      procmime_mimeinfo_get_parameter(mimeinfo, "charset");
 
+       if (!forced_charset && src_codeset && !strcasecmp(src_codeset, CS_ISO_8859_1))
+               src_codeset = CS_WINDOWS_1252;
+
        if (mimeinfo->type == MIMETYPE_TEXT && !g_ascii_strcasecmp(mimeinfo->subtype, "html")) {
                SC_HTMLParser *parser;
                CodeConverter *conv;
@@ -841,6 +844,8 @@ FILE *procmime_get_first_encrypted_text_content(MsgInfo *msginfo)
        partinfo = mimeinfo;
        while (partinfo && partinfo->type != MIMETYPE_TEXT) {
                partinfo = procmime_mimeinfo_next(partinfo);
+               if (privacy_mimeinfo_is_signed(partinfo))
+                       procmsg_msginfo_set_flags(msginfo, 0, MSG_SIGNED);
        }
 
        if (partinfo)
@@ -973,33 +978,45 @@ static GList *mime_type_list = NULL;
 
 gchar *procmime_get_mime_type(const gchar *filename)
 {
-       static GHashTable *mime_type_table = NULL;
-       MimeType *mime_type;
        const gchar *p;
-       gchar *ext = NULL, *ext_down;
+       gchar *ext = NULL;
        gchar *base;
+#ifndef G_OS_WIN32
+       static GHashTable *mime_type_table = NULL;
+       MimeType *mime_type;
 
        if (!mime_type_table) {
                mime_type_table = procmime_get_mime_type_table();
                if (!mime_type_table) return NULL;
        }
+#endif
+
+       if (filename == NULL)
+               return NULL;
 
        base = g_path_get_basename(filename);
        if ((p = strrchr(base, '.')) != NULL)
                ext = g_utf8_strdown(p + 1, -1);
        g_free(base);
 
+#ifndef G_OS_WIN32
        mime_type = g_hash_table_lookup(mime_type_table, ext);
-       g_free(ext);
+       
        if (mime_type) {
                gchar *str;
-
                str = g_strconcat(mime_type->type, "/", mime_type->sub_type,
                                  NULL);
+               debug_print("got type %s for %s\n", str, ext);
+               g_free(ext);
                return str;
-       }
-
+       } 
        return NULL;
+#else
+       gchar *str = get_content_type_from_registry_with_ext(ext);
+
+       g_free(ext);
+       return str;
+#endif
 }
 
 static guint procmime_str_hash(gconstpointer gptr)
@@ -1583,7 +1600,7 @@ static void parse_parameters(const gchar *parameters, GHashTable *table)
        param = params;
        next = params;
        for (; next != NULL; param = next) {
-               gchar *attribute, *value, *tmp, *down_attr;
+               gchar *attribute, *value, *tmp, *down_attr, *orig_down_attr;
                gint len;
                gboolean convert = FALSE;
 
@@ -1606,7 +1623,8 @@ static void parse_parameters(const gchar *parameters, GHashTable *table)
                        value++;
 
                down_attr = g_utf8_strdown(attribute, -1);
-               
+               orig_down_attr = down_attr;
+       
                len = strlen(down_attr);
                if (down_attr[len - 1] == '*') {
                        gchar *srcpos, *dstpos, *endpos;
@@ -1674,7 +1692,7 @@ static void parse_parameters(const gchar *parameters, GHashTable *table)
 
                if (g_hash_table_lookup(table, down_attr) == NULL)
                        g_hash_table_insert(table, g_strdup(down_attr), g_strdup(value));
-               g_free(down_attr);
+               g_free(orig_down_attr);
        }
 
        for (cur = concatlist; cur != NULL; cur = g_slist_next(cur)) {
@@ -2001,7 +2019,7 @@ static MimeInfo *procmime_scan_file_with_offset(const gchar *filename, int offse
        MimeInfo *mimeinfo;
        struct stat buf;
 
-       stat(filename, &buf);
+       g_stat(filename, &buf);
 
        mimeinfo = procmime_mimeinfo_new();
        mimeinfo->content = MIMECONTENT_FILE;
@@ -2093,13 +2111,12 @@ typedef enum {
     ENC_AS_TOKEN,
     ENC_AS_QUOTED_STRING,
     ENC_AS_EXTENDED,
-    ENC_TO_ASCII,
+    ENC_AS_ENCWORD
 } EncodeAs;
 
 typedef struct _ParametersData {
        FILE *fp;
        guint len;
-       guint ascii_only;
        gint error;
 } ParametersData;
 
@@ -2109,12 +2126,13 @@ static void write_parameters(gpointer key, gpointer value, gpointer user_data)
        gchar *val = value, *valpos, *tmp;
        ParametersData *pdata = (ParametersData *)user_data;
        GString *buf = g_string_new("");
+       gint len;
 
        EncodeAs encas = ENC_AS_TOKEN;
 
        for (valpos = val; *valpos != 0; valpos++) {
-               if (!IS_ASCII(*valpos) || *valpos == '"') {
-                       encas = ENC_AS_EXTENDED;
+               if (!IS_ASCII(*valpos)) {
+                       encas = ENC_AS_ENCWORD;
                        break;
                }
            
@@ -2136,7 +2154,7 @@ static void write_parameters(gpointer key, gpointer value, gpointer user_data)
                case ';':
                case ':':
                case '\\':
-               case '\'':
+               case '"':
                case '/':
                case '[':
                case ']':
@@ -2147,25 +2165,11 @@ static void write_parameters(gpointer key, gpointer value, gpointer user_data)
                }
        }
        
-       if (encas == ENC_AS_EXTENDED && pdata->ascii_only == TRUE) 
-               encas = ENC_TO_ASCII;
-
        switch (encas) {
        case ENC_AS_TOKEN:
                g_string_append_printf(buf, "%s=%s", param, val);
                break;
 
-       case ENC_TO_ASCII:
-               tmp = g_strdup(val);
-               g_strcanon(tmp, 
-                       " ()<>@,';:\\/[]?=.0123456789"
-                       "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
-                       "abcdefghijklmnopqrstuvwxyz",
-                       '_');
-               g_string_append_printf(buf, "%s=\"%s\"", param, tmp);
-               g_free(tmp);
-               break;
-
        case ENC_AS_QUOTED_STRING:
                g_string_append_printf(buf, "%s=\"%s\"", param, val);
                break;
@@ -2187,10 +2191,43 @@ static void write_parameters(gpointer key, gpointer value, gpointer user_data)
                        }
                }
                break;          
+
+       case ENC_AS_ENCWORD:
+               len = MAX(strlen(val)*6, 512);
+               tmp = g_malloc(len+1);
+               codeconv_set_strict(TRUE);
+               conv_encode_header_full(tmp, len, val, pdata->len + strlen(param) + 4 , FALSE,
+                       prefs_common.outgoing_charset);
+               codeconv_set_strict(FALSE);
+               if (!tmp || !*tmp) {
+                       codeconv_set_strict(TRUE);
+                       conv_encode_header_full(tmp, len, val, pdata->len + strlen(param) + 4 , FALSE,
+                               conv_get_outgoing_charset_str());
+                       codeconv_set_strict(FALSE);
+               }
+               if (!tmp || !*tmp) {
+                       codeconv_set_strict(TRUE);
+                       conv_encode_header_full(tmp, len, val, pdata->len + strlen(param) + 4 , FALSE,
+                               CS_UTF_8);
+                       codeconv_set_strict(FALSE);
+               }
+               if (!tmp || !*tmp) {
+                       conv_encode_header_full(tmp, len, val, pdata->len + strlen(param) + 4 , FALSE,
+                               CS_UTF_8);
+               }
+               g_string_append_printf(buf, "%s=\"%s\"", param, tmp);
+               g_free(tmp);
+               break;
+
        }
        
        if (buf->str && strlen(buf->str)) {
-               if (pdata->len + strlen(buf->str) + 2 > 76) {
+               tmp = strstr(buf->str, "\n");
+               if (tmp)
+                       len = (tmp - buf->str);
+               else
+                       len = strlen(buf->str);
+               if (pdata->len + len > 76) {
                        if (fprintf(pdata->fp, ";\n %s", buf->str) < 0)
                                pdata->error = TRUE;
                        pdata->len = strlen(buf->str) + 1;
@@ -2216,7 +2253,6 @@ int procmime_write_mime_header(MimeInfo *mimeinfo, FILE *fp)
        debug_print("procmime_write_mime_header\n");
        
        pdata->fp = fp;
-       pdata->ascii_only = FALSE;
        pdata->error = FALSE;
        for (type_table = mime_type_table; type_table->str != NULL; type_table++)
                if (mimeinfo->type == type_table->type) {
@@ -2228,7 +2264,6 @@ int procmime_write_mime_header(MimeInfo *mimeinfo, FILE *fp)
                                return -1;
                        }
                        pdata->len = strlen(buf);
-                       pdata->ascii_only = TRUE;
                        g_free(buf);
                        break;
                }
@@ -2272,7 +2307,6 @@ int procmime_write_mime_header(MimeInfo *mimeinfo, FILE *fp)
                g_free(buf);
 
                pdata->fp = fp;
-               pdata->ascii_only = FALSE;
                pdata->error = FALSE;
                g_hash_table_foreach(mimeinfo->dispositionparameters, write_parameters, pdata);
                if (pdata->error == TRUE) {