New address book.
[claws.git] / src / procmime.c
index af71a81e392d645311049d261496322854b5c870..c2b47ee25f56f85af306867ae355bb9e65f4c58f 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999,2000 Hiroyuki Yamamoto
+ * Copyright (C) 1999-2001 Hiroyuki Yamamoto
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -44,8 +44,6 @@
 #endif
 
 static GHashTable *procmime_get_mime_type_table        (void);
-static GList *procmime_get_mime_type_list      (void);
-
 
 MimeInfo *procmime_mimeinfo_new(void)
 {
@@ -270,15 +268,14 @@ void procmime_scan_multipart_message(MimeInfo *mimeinfo, FILE *fp)
 
                if (eom) break;
        }
-       //g_message ("** at " __PRETTY_FUNCTION__ ":%d:", __LINE__);
+       /*g_message ("** at " __PRETTY_FUNCTION__ ":%d:", __LINE__);*/
 }
 
 void procmime_scan_encoding(MimeInfo *mimeinfo, const gchar *encoding)
 {
        gchar *buf;
 
-       Xalloca(buf, strlen(encoding) + 1, return);
-       strcpy(buf, encoding);
+       Xstrdup_a(buf, encoding, return);
 
        g_free(mimeinfo->encoding);
 
@@ -303,8 +300,14 @@ void procmime_scan_content_type(MimeInfo *mimeinfo, const gchar *content_type)
        gchar *delim, *p, *cnttype;
        gchar *buf;
 
-       Xalloca(buf, strlen(content_type) + 1, return);
-       strcpy(buf, content_type);
+       if (conv_get_current_charset() == C_EUC_JP &&
+           strchr(content_type, '\033')) {
+               gint len;
+               len = strlen(content_type) * 2 + 1;
+               Xalloca(buf, len, return);
+               conv_jistoeuc(buf, len, content_type);
+       } else
+               Xstrdup_a(buf, content_type, return);
 
        g_free(mimeinfo->content_type);
        g_free(mimeinfo->charset);
@@ -316,28 +319,7 @@ void procmime_scan_content_type(MimeInfo *mimeinfo, const gchar *content_type)
        if ((delim = strchr(buf, ';'))) *delim = '\0';
        mimeinfo->content_type = cnttype = g_strdup(g_strstrip(buf));
 
-       if (!strncasecmp(cnttype, "text/html", 9))
-               mimeinfo->mime_type = MIME_TEXT_HTML;
-       else if (!strncasecmp(cnttype, "text/", 5))
-               mimeinfo->mime_type = MIME_TEXT;
-       else if (!strncasecmp(cnttype, "message/rfc822", 14))
-               mimeinfo->mime_type = MIME_MESSAGE_RFC822;
-       else if (!strncasecmp(cnttype, "message/", 8))
-               mimeinfo->mime_type = MIME_TEXT;
-       else if (!strncasecmp(cnttype, "application/octet-stream", 24))
-               mimeinfo->mime_type = MIME_APPLICATION_OCTET_STREAM;
-       else if (!strncasecmp(cnttype, "application/", 12))
-               mimeinfo->mime_type = MIME_APPLICATION;
-       else if (!strncasecmp(cnttype, "multipart/", 10))
-               mimeinfo->mime_type = MIME_MULTIPART;
-       else if (!strncasecmp(cnttype, "image/", 6))
-               mimeinfo->mime_type = MIME_IMAGE;
-       else if (!strncasecmp(cnttype, "audio/", 6))
-               mimeinfo->mime_type = MIME_AUDIO;
-       else if (!strcasecmp(cnttype, "text"))
-               mimeinfo->mime_type = MIME_TEXT;
-       else
-               mimeinfo->mime_type = MIME_UNKNOWN;
+       mimeinfo->mime_type = procmime_scan_mime_type(cnttype);
 
        if (!delim) return;
        p = delim + 1;
@@ -392,8 +374,14 @@ void procmime_scan_content_disposition(MimeInfo *mimeinfo,
        gchar *delim, *p, *dispos;
        gchar *buf;
 
-       Xalloca(buf, strlen(content_disposition) + 1, return);
-       strcpy(buf, content_disposition);
+       if (conv_get_current_charset() == C_EUC_JP &&
+           strchr(content_disposition, '\033')) {
+               gint len;
+               len = strlen(content_disposition) * 2 + 1;
+               Xalloca(buf, len, return);
+               conv_jistoeuc(buf, len, content_disposition);
+       } else
+               Xstrdup_a(buf, content_disposition, return);
 
        if ((delim = strchr(buf, ';'))) *delim = '\0';
        mimeinfo->content_disposition = dispos = g_strdup(g_strstrip(buf));
@@ -484,6 +472,14 @@ MimeInfo *procmime_scan_mime_header(FILE *fp)
                }
        }
 
+       if (mimeinfo->mime_type == MIME_APPLICATION_OCTET_STREAM &&
+           mimeinfo->name) {
+               const gchar *type;
+               type = procmime_get_mime_type(mimeinfo->name);
+               if (type)
+                       mimeinfo->mime_type = procmime_scan_mime_type(type);
+       }
+
        if (!mimeinfo->content_type)
                mimeinfo->content_type = g_strdup("text/plain");
 
@@ -721,6 +717,36 @@ gchar *procmime_get_tmp_file_name(MimeInfo *mimeinfo)
        return filename;
 }
 
+ContentType procmime_scan_mime_type(const gchar *mime_type)
+{
+       ContentType type;
+
+       if (!strncasecmp(mime_type, "text/html", 9))
+               type = MIME_TEXT_HTML;
+       else if (!strncasecmp(mime_type, "text/", 5))
+               type = MIME_TEXT;
+       else if (!strncasecmp(mime_type, "message/rfc822", 14))
+               type = MIME_MESSAGE_RFC822;
+       else if (!strncasecmp(mime_type, "message/", 8))
+               type = MIME_TEXT;
+       else if (!strncasecmp(mime_type, "application/octet-stream", 24))
+               type = MIME_APPLICATION_OCTET_STREAM;
+       else if (!strncasecmp(mime_type, "application/", 12))
+               type = MIME_APPLICATION;
+       else if (!strncasecmp(mime_type, "multipart/", 10))
+               type = MIME_MULTIPART;
+       else if (!strncasecmp(mime_type, "image/", 6))
+               type = MIME_IMAGE;
+       else if (!strncasecmp(mime_type, "audio/", 6))
+               type = MIME_AUDIO;
+       else if (!strcasecmp(mime_type, "text"))
+               type = MIME_TEXT;
+       else
+               type = MIME_UNKNOWN;
+
+       return type;
+}
+
 static GList *mime_type_list = NULL;
 
 gchar *procmime_get_mime_type(const gchar *filename)
@@ -753,6 +779,27 @@ gchar *procmime_get_mime_type(const gchar *filename)
        return NULL;
 }
 
+static guint procmime_str_hash(gconstpointer gptr)
+{
+       guint hash_result = 0;
+       const char *str;
+
+       for (str = gptr; str && *str; str++) {
+               if (isupper(*str)) hash_result += (*str + ' ');
+               else hash_result += *str;
+       }
+
+       return hash_result;
+}
+
+static gint procmime_str_equal(gconstpointer gptr1, gconstpointer gptr2)
+{
+       const char *str1 = gptr1;
+       const char *str2 = gptr2;
+
+       return !strcasecmp(str1, str2);
+}
+
 static GHashTable *procmime_get_mime_type_table(void)
 {
        GHashTable *table = NULL;
@@ -765,7 +812,7 @@ static GHashTable *procmime_get_mime_type_table(void)
                if (!mime_type_list) return NULL;
        }
 
-       table = g_hash_table_new(g_str_hash, g_str_equal);
+       table = g_hash_table_new(procmime_str_hash, procmime_str_equal);
 
        for (cur = mime_type_list; cur != NULL; cur = cur->next) {
                gint i;
@@ -784,7 +831,7 @@ static GHashTable *procmime_get_mime_type_table(void)
        return table;
 }
 
-static GList *procmime_get_mime_type_list(void)
+GList *procmime_get_mime_type_list(void)
 {
        GList *list = NULL;
        FILE *fp;
@@ -792,9 +839,14 @@ static GList *procmime_get_mime_type_list(void)
        gchar *p, *delim;
        MimeType *mime_type;
 
-       if ((fp = fopen(SYSCONFDIR "/mime.types", "r")) == NULL) {
-               FILE_OP_ERROR(SYSCONFDIR "/mime.types", "fopen");
-               return NULL;
+       if (mime_type_list) 
+               return mime_type_list;
+
+       if ((fp = fopen("/etc/mime.types", "r")) == NULL) {
+               if ((fp = fopen(SYSCONFDIR "/mime.types", "r")) == NULL) {
+                       FILE_OP_ERROR(SYSCONFDIR "/mime.types", "fopen");
+                       return NULL;
+               }
        }
 
        while (fgets(buf, sizeof(buf), fp) != NULL) {