aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorhiro <hiro@ee746299-78ed-0310-b773-934348b2243d>2005-03-03 10:46:03 +0000
committerhiro <hiro@ee746299-78ed-0310-b773-934348b2243d>2005-03-03 10:46:03 +0000
commita80cf7559e18da4e89fae15c2ff10966b1983ffa (patch)
tree29c77b69a7cf2acff7a06c41a8369253e3773e63 /src
parented32db180ae51bb50d6d819962f188173ed2c8b1 (diff)
use Content-Type's charset as a fallback encoding of broken header strings.
git-svn-id: svn://sylpheed.sraoss.jp/sylpheed/trunk@144 ee746299-78ed-0310-b773-934348b2243d
Diffstat (limited to 'src')
-rw-r--r--src/codeconv.c45
-rw-r--r--src/procheader.c72
-rw-r--r--src/procheader.h6
-rw-r--r--src/procmime.c48
-rw-r--r--src/procmime.h5
-rw-r--r--src/textview.c48
-rw-r--r--src/unmime.c2
-rw-r--r--src/unmime.h3
8 files changed, 143 insertions, 86 deletions
diff --git a/src/codeconv.c b/src/codeconv.c
index 906ecdfb..36e158c0 100644
--- a/src/codeconv.c
+++ b/src/codeconv.c
@@ -979,18 +979,10 @@ gchar *conv_iconv_strdup(const gchar *inbuf,
gchar *outbuf;
if (!src_code)
- src_code = conv_get_outgoing_charset_str();
+ src_code = conv_get_locale_charset_str();
if (!dest_code)
dest_code = CS_INTERNAL;
- /* don't convert if src and dest codeset are identical */
- if (!strcasecmp(src_code, dest_code))
- return g_strdup(inbuf);
-
- /* don't convert if current codeset is US-ASCII */
- if (!strcasecmp(dest_code, CS_US_ASCII))
- return g_strdup(inbuf);
-
cd = iconv_open(dest_code, src_code);
if (cd == (iconv_t)-1)
return NULL;
@@ -1534,15 +1526,17 @@ gboolean conv_is_multibyte_encoding(CharSet encoding)
const gchar *conv_get_current_locale(void)
{
- const gchar *cur_locale;
+ static const gchar *cur_locale;
- cur_locale = g_getenv("LC_ALL");
- if (!cur_locale) cur_locale = g_getenv("LC_CTYPE");
- if (!cur_locale) cur_locale = g_getenv("LANG");
- if (!cur_locale) cur_locale = setlocale(LC_CTYPE, NULL);
+ if (!cur_locale) {
+ cur_locale = g_getenv("LC_ALL");
+ if (!cur_locale) cur_locale = g_getenv("LC_CTYPE");
+ if (!cur_locale) cur_locale = g_getenv("LANG");
+ if (!cur_locale) cur_locale = setlocale(LC_CTYPE, NULL);
- debug_print("current locale: %s\n",
- cur_locale ? cur_locale : "(none)");
+ debug_print("current locale: %s\n",
+ cur_locale ? cur_locale : "(none)");
+ }
return cur_locale;
}
@@ -1564,11 +1558,28 @@ void conv_unmime_header_overwrite(gchar *str)
}
void conv_unmime_header(gchar *outbuf, gint outlen, const gchar *str,
- const gchar *charset)
+ const gchar *default_encoding)
{
gchar *buf;
gint buflen;
+ if (is_ascii_str(str)) {
+ unmime_header(outbuf, str);
+ return;
+ }
+
+ if (default_encoding) {
+ gchar *utf8_str;
+
+ utf8_str = conv_codeset_strdup
+ (str, default_encoding, CS_INTERNAL);
+ if (utf8_str) {
+ unmime_header(outbuf, utf8_str);
+ g_free(utf8_str);
+ return;
+ }
+ }
+
buflen = strlen(str) * 2 + 1;
Xalloca(buf, buflen, return);
diff --git a/src/procheader.c b/src/procheader.c
index ea611ff2..e76ad802 100644
--- a/src/procheader.c
+++ b/src/procheader.c
@@ -296,7 +296,7 @@ gint procheader_find_header_list(GSList *hlist, const gchar *header_name)
return -1;
}
-GPtrArray *procheader_get_header_array(FILE *fp)
+GPtrArray *procheader_get_header_array(FILE *fp, const gchar *encoding)
{
gchar buf[BUFFSIZE], tmp[BUFFSIZE];
gchar *p;
@@ -315,7 +315,8 @@ GPtrArray *procheader_get_header_array(FILE *fp)
header->name = g_strndup(buf, p - buf);
p++;
while (*p == ' ' || *p == '\t') p++;
- conv_unmime_header(tmp, sizeof(tmp), p, NULL);
+ conv_unmime_header(tmp, sizeof(tmp), p,
+ encoding);
header->body = g_strdup(tmp);
g_ptr_array_add(headers, header);
@@ -327,7 +328,7 @@ GPtrArray *procheader_get_header_array(FILE *fp)
return headers;
}
-GPtrArray *procheader_get_header_array_asis(FILE *fp)
+GPtrArray *procheader_get_header_array_asis(FILE *fp, const gchar *encoding)
{
gchar buf[BUFFSIZE], tmp[BUFFSIZE];
gchar *p;
@@ -345,7 +346,8 @@ GPtrArray *procheader_get_header_array_asis(FILE *fp)
header = g_new(Header, 1);
header->name = g_strndup(buf, p - buf);
p++;
- conv_unmime_header(tmp, sizeof(tmp), p, NULL);
+ conv_unmime_header(tmp, sizeof(tmp), p,
+ encoding);
header->body = g_strdup(tmp);
g_ptr_array_add(headers, header);
@@ -511,6 +513,8 @@ MsgInfo *procheader_parse_stream(FILE *fp, MsgFlags flags, gboolean full)
gchar *hp;
HeaderEntry *hentry;
gint hnum;
+ gchar *from = NULL, *to = NULL, *subject = NULL, *cc = NULL;
+ gchar *charset = NULL;
hentry = full ? hentry_full : hentry_short;
@@ -536,20 +540,16 @@ MsgInfo *procheader_parse_stream(FILE *fp, MsgFlags flags, gboolean full)
msginfo->date = g_strdup(hp);
break;
case H_FROM:
- if (msginfo->from) break;
- conv_unmime_header(tmp, sizeof(tmp), hp, NULL);
- msginfo->from = g_strdup(tmp);
- msginfo->fromname = procheader_get_fromname(tmp);
+ if (from) break;
+ from = g_strdup(hp);
break;
case H_TO:
- conv_unmime_header(tmp, sizeof(tmp), hp, NULL);
- if (msginfo->to) {
- p = msginfo->to;
- msginfo->to =
- g_strconcat(p, ", ", tmp, NULL);
+ if (to) {
+ p = to;
+ to = g_strconcat(p, ", ", hp, NULL);
g_free(p);
} else
- msginfo->to = g_strdup(tmp);
+ to = g_strdup(hp);
break;
case H_NEWSGROUPS:
if (msginfo->newsgroups) {
@@ -562,8 +562,7 @@ MsgInfo *procheader_parse_stream(FILE *fp, MsgFlags flags, gboolean full)
break;
case H_SUBJECT:
if (msginfo->subject) break;
- conv_unmime_header(tmp, sizeof(tmp), hp, NULL);
- msginfo->subject = g_strdup(tmp);
+ subject = g_strdup(hp);
break;
case H_MSG_ID:
if (msginfo->msgid) break;
@@ -586,22 +585,24 @@ MsgInfo *procheader_parse_stream(FILE *fp, MsgFlags flags, gboolean full)
}
break;
case H_CONTENT_TYPE:
- if (!strncasecmp(hp, "multipart", 9))
+ if (!g_strncasecmp(hp, "multipart", 9)) {
MSG_SET_TMP_FLAGS(msginfo->flags, MSG_MIME);
+ } else if (!charset) {
+ procmime_scan_content_type_str
+ (hp, NULL, &charset, NULL, NULL);
+ }
break;
case H_SEEN:
/* mnews Seen header */
MSG_UNSET_PERM_FLAGS(msginfo->flags, MSG_NEW|MSG_UNREAD);
break;
case H_CC:
- conv_unmime_header(tmp, sizeof(tmp), hp, NULL);
- if (msginfo->cc) {
- p = msginfo->cc;
- msginfo->cc =
- g_strconcat(p, ", ", tmp, NULL);
+ if (cc) {
+ p = cc;
+ cc = g_strconcat(p, ", ", hp, NULL);
g_free(p);
} else
- msginfo->cc = g_strdup(tmp);
+ cc = g_strdup(hp);
break;
case H_X_FACE:
if (msginfo->xface) break;
@@ -611,8 +612,33 @@ MsgInfo *procheader_parse_stream(FILE *fp, MsgFlags flags, gboolean full)
break;
}
}
+
+ if (from) {
+ conv_unmime_header(tmp, sizeof(tmp), from, charset);
+ msginfo->from = g_strdup(tmp);
+ msginfo->fromname = procheader_get_fromname(tmp);
+ g_free(from);
+ }
+ if (to) {
+ conv_unmime_header(tmp, sizeof(tmp), to, charset);
+ msginfo->to = g_strdup(tmp);
+ g_free(to);
+ }
+ if (subject) {
+ conv_unmime_header(tmp, sizeof(tmp), subject, charset);
+ msginfo->subject = g_strdup(tmp);
+ g_free(subject);
+ }
+ if (cc) {
+ conv_unmime_header(tmp, sizeof(tmp), cc, charset);
+ msginfo->cc = g_strdup(tmp);
+ g_free(cc);
+ }
+
msginfo->inreplyto = reference;
+ g_free(charset);
+
return msginfo;
}
diff --git a/src/procheader.h b/src/procheader.h
index 599324e1..1667b4ed 100644
--- a/src/procheader.h
+++ b/src/procheader.h
@@ -61,8 +61,10 @@ gint procheader_find_header_list (GSList *hlist,
const gchar *header_name);
void procheader_header_list_destroy (GSList *hlist);
-GPtrArray *procheader_get_header_array (FILE *fp);
-GPtrArray *procheader_get_header_array_asis (FILE *fp);
+GPtrArray *procheader_get_header_array (FILE *fp,
+ const gchar *encoding);
+GPtrArray *procheader_get_header_array_asis (FILE *fp,
+ const gchar *encoding);
void procheader_header_array_destroy (GPtrArray *harray);
void procheader_header_free (Header *header);
diff --git a/src/procmime.c b/src/procmime.c
index 2dd27c7d..39e5fde9 100644
--- a/src/procmime.c
+++ b/src/procmime.c
@@ -1,6 +1,6 @@
/*
* Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2004 Hiroyuki Yamamoto
+ * Copyright (C) 1999-2005 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
@@ -35,7 +35,6 @@
#include "base64.h"
#include "quoted-printable.h"
#include "uuencode.h"
-#include "unmime.h"
#include "html.h"
#include "codeconv.h"
#include "utils.h"
@@ -346,22 +345,36 @@ void procmime_scan_encoding(MimeInfo *mimeinfo, const gchar *encoding)
void procmime_scan_content_type(MimeInfo *mimeinfo, const gchar *content_type)
{
- gchar *delim, *p, *cnttype;
- gchar *buf;
-
- Xstrdup_a(buf, content_type, return);
-
g_free(mimeinfo->content_type);
g_free(mimeinfo->charset);
g_free(mimeinfo->name);
+ g_free(mimeinfo->boundary);
mimeinfo->content_type = NULL;
mimeinfo->charset = NULL;
mimeinfo->name = NULL;
+ mimeinfo->boundary = NULL;
- if ((delim = strchr(buf, ';'))) *delim = '\0';
- mimeinfo->content_type = cnttype = g_strdup(g_strstrip(buf));
+ procmime_scan_content_type_str(content_type, &mimeinfo->content_type,
+ &mimeinfo->charset, &mimeinfo->name,
+ &mimeinfo->boundary);
+
+ mimeinfo->mime_type = procmime_scan_mime_type(mimeinfo->content_type);
+ if (mimeinfo->mime_type == MIME_MULTIPART && !mimeinfo->boundary)
+ mimeinfo->mime_type = MIME_TEXT;
+}
- mimeinfo->mime_type = procmime_scan_mime_type(cnttype);
+void procmime_scan_content_type_str(const gchar *content_type,
+ gchar **mime_type, gchar **charset,
+ gchar **name, gchar **boundary)
+{
+ gchar *delim, *p;
+ gchar *buf;
+
+ Xstrdup_a(buf, content_type, return);
+
+ if ((delim = strchr(buf, ';'))) *delim = '\0';
+ if (mime_type)
+ *mime_type = g_strdup(g_strstrip(buf));
if (!delim) return;
p = delim + 1;
@@ -388,26 +401,23 @@ void procmime_scan_content_type(MimeInfo *mimeinfo, const gchar *content_type)
}
if (*value) {
- if (!strcasecmp(attr, "charset"))
- mimeinfo->charset = g_strdup(value);
- else if (!strcasecmp(attr, "name")) {
+ if (charset && !g_strcasecmp(attr, "charset"))
+ *charset = g_strdup(value);
+ else if (name && !g_strcasecmp(attr, "name")) {
gchar *tmp;
size_t len;
len = strlen(value) + 1;
Xalloca(tmp, len, return);
conv_unmime_header(tmp, len, value, NULL);
- mimeinfo->name = g_strdup(tmp);
- } else if (!strcasecmp(attr, "boundary"))
- mimeinfo->boundary = g_strdup(value);
+ *name = g_strdup(tmp);
+ } else if (boundary && !g_strcasecmp(attr, "boundary"))
+ *boundary = g_strdup(value);
}
if (!delim) break;
p = delim + 1;
}
-
- if (mimeinfo->mime_type == MIME_MULTIPART && !mimeinfo->boundary)
- mimeinfo->mime_type = MIME_TEXT;
}
void procmime_scan_content_disposition(MimeInfo *mimeinfo,
diff --git a/src/procmime.h b/src/procmime.h
index e4014bb2..735f59eb 100644
--- a/src/procmime.h
+++ b/src/procmime.h
@@ -142,6 +142,11 @@ void procmime_scan_encoding (MimeInfo *mimeinfo,
const gchar *encoding);
void procmime_scan_content_type (MimeInfo *mimeinfo,
const gchar *content_type);
+void procmime_scan_content_type_str (const gchar *content_type,
+ gchar **mime_type,
+ gchar **charset,
+ gchar **name,
+ gchar **boundary);
void procmime_scan_content_disposition (MimeInfo *mimeinfo,
const gchar *content_disposition);
MimeInfo *procmime_scan_mime_header (FILE *fp);
diff --git a/src/textview.c b/src/textview.c
index 1f221491..f31b2483 100644
--- a/src/textview.c
+++ b/src/textview.c
@@ -158,7 +158,8 @@ static void textview_write_link (TextView *textview,
CodeConverter *conv);
static GPtrArray *textview_scan_header (TextView *textview,
- FILE *fp);
+ FILE *fp,
+ const gchar *encoding);
static void textview_show_header (TextView *textview,
GPtrArray *headers);
@@ -391,7 +392,7 @@ void textview_show_message(TextView *textview, MimeInfo *mimeinfo,
textview_clear(textview);
if (fseek(fp, mimeinfo->fpos, SEEK_SET) < 0) perror("fseek");
- headers = textview_scan_header(textview, fp);
+ headers = textview_scan_header(textview, fp, charset);
if (headers) {
GtkTextView *text = GTK_TEXT_VIEW(textview->text);
GtkTextBuffer *buffer;
@@ -435,10 +436,17 @@ void textview_show_part(TextView *textview, MimeInfo *mimeinfo, FILE *fp)
boundary_len = strlen(boundary);
}
+ if (textview->messageview->forced_charset)
+ charset = textview->messageview->forced_charset;
+ else if (prefs_common.force_charset)
+ charset = prefs_common.force_charset;
+ else if (mimeinfo->charset)
+ charset = mimeinfo->charset;
+
if (!boundary && mimeinfo->mime_type == MIME_TEXT) {
if (fseek(fp, mimeinfo->fpos, SEEK_SET) < 0)
perror("fseek");
- headers = textview_scan_header(textview, fp);
+ headers = textview_scan_header(textview, fp, charset);
} else {
if (mimeinfo->mime_type == MIME_TEXT && mimeinfo->parent) {
glong fpos;
@@ -457,7 +465,8 @@ void textview_show_part(TextView *textview, MimeInfo *mimeinfo, FILE *fp)
else if (fseek(fp, parent->fpos, SEEK_SET) < 0)
perror("fseek");
else {
- headers = textview_scan_header(textview, fp);
+ headers = textview_scan_header
+ (textview, fp, charset);
if (fseek(fp, fpos, SEEK_SET) < 0)
perror("fseek");
}
@@ -474,18 +483,11 @@ void textview_show_part(TextView *textview, MimeInfo *mimeinfo, FILE *fp)
textview_clear(textview);
return;
}
- headers = textview_scan_header(textview, fp);
+ headers = textview_scan_header(textview, fp, charset);
mimeinfo = mimeinfo->sub;
is_rfc822_part = TRUE;
}
- if (textview->messageview->forced_charset)
- charset = textview->messageview->forced_charset;
- else if (prefs_common.force_charset)
- charset = prefs_common.force_charset;
- else if (mimeinfo->charset)
- charset = mimeinfo->charset;
-
textview_set_font(textview, charset);
textview_clear(textview);
@@ -543,8 +545,15 @@ static void textview_add_part(TextView *textview, MimeInfo *mimeinfo, FILE *fp)
while (fgets(buf, sizeof(buf), fp) != NULL)
if (buf[0] == '\r' || buf[0] == '\n') break;
+ if (textview->messageview->forced_charset)
+ charset = textview->messageview->forced_charset;
+ else if (prefs_common.force_charset)
+ charset = prefs_common.force_charset;
+ else if (mimeinfo->charset)
+ charset = mimeinfo->charset;
+
if (mimeinfo->mime_type == MIME_MESSAGE_RFC822) {
- headers = textview_scan_header(textview, fp);
+ headers = textview_scan_header(textview, fp, charset);
if (headers) {
gtk_text_buffer_insert(buffer, &iter, "\n", 1);
textview_show_header(textview, headers);
@@ -622,12 +631,6 @@ static void textview_add_part(TextView *textview, MimeInfo *mimeinfo, FILE *fp)
gtk_text_buffer_insert(buffer, &iter, buf, -1);
else
gtk_text_buffer_insert(buffer, &iter, "\n", 1);
- if (textview->messageview->forced_charset)
- charset = textview->messageview->forced_charset;
- else if (prefs_common.force_charset)
- charset = prefs_common.force_charset;
- else if (mimeinfo->charset)
- charset = mimeinfo->charset;
textview_write_body(textview, mimeinfo, fp, charset);
}
}
@@ -1107,7 +1110,8 @@ void textview_set_position(TextView *textview, gint pos)
gtk_text_buffer_place_cursor(buffer, &iter);
}
-static GPtrArray *textview_scan_header(TextView *textview, FILE *fp)
+static GPtrArray *textview_scan_header(TextView *textview, FILE *fp,
+ const gchar *encoding)
{
gchar buf[BUFFSIZE];
GPtrArray *headers, *sorted_headers;
@@ -1118,7 +1122,7 @@ static GPtrArray *textview_scan_header(TextView *textview, FILE *fp)
g_return_val_if_fail(fp != NULL, NULL);
if (textview->show_all_headers)
- return procheader_get_header_array_asis(fp);
+ return procheader_get_header_array_asis(fp, encoding);
if (!prefs_common.display_header) {
while (fgets(buf, sizeof(buf), fp) != NULL)
@@ -1126,7 +1130,7 @@ static GPtrArray *textview_scan_header(TextView *textview, FILE *fp)
return NULL;
}
- headers = procheader_get_header_array_asis(fp);
+ headers = procheader_get_header_array_asis(fp, encoding);
sorted_headers = g_ptr_array_new();
diff --git a/src/unmime.c b/src/unmime.c
index 65d279f6..e4742afd 100644
--- a/src/unmime.c
+++ b/src/unmime.c
@@ -1,6 +1,6 @@
/*
* Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2003 Hiroyuki Yamamoto
+ * Copyright (C) 1999-2005 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
diff --git a/src/unmime.h b/src/unmime.h
index 8e6d8397..363dd219 100644
--- a/src/unmime.h
+++ b/src/unmime.h
@@ -1,6 +1,6 @@
/*
* Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2002 Hiroyuki Yamamoto
+ * Copyright (C) 1999-2005 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
@@ -24,6 +24,5 @@
void unmime_header (gchar *out,
const gchar *str);
-gint unmime_quoted_printable_line (gchar *str);
#endif /* __UNMIME_H__ */