# HG changeset patch # User Luke Schierer # Date 1070165837 0 # Node ID 0351ff7030d0e2d482bcbee44d420e46bca88d4a # Parent e4264f71fac71dc746abd4c0e32933383dd0f63d [gaim-migrate @ 8309] Felipe Contreras (aka revo aka shx) writes: " Basically that, currently gaim will not display international "subjects" or "from" fields from emails, like "a??a" or "Pa?l". This implements the propper RFC that specify the format for those fields." committer: Tailor Script diff -r e4264f71fac7 -r 0351ff7030d0 src/gtknotify.c --- a/src/gtknotify.c Sun Nov 30 02:53:05 2003 +0000 +++ b/src/gtknotify.c Sun Nov 30 04:17:17 2003 +0000 @@ -215,13 +215,17 @@ char *from_text = NULL, *subject_text = NULL; if (froms != NULL) { + char *from_decoded = gaim_mime_decode_field(*froms); from_text = g_strdup_printf( - _("From: %s\n"), *froms); + _("From: %s\n"), from_decoded); + g_free(from_decoded); } if (subjects != NULL) { + char *subject_decoded = gaim_mime_decode_field(*subjects); subject_text = g_strdup_printf( - _("Subject: %s\n"), *subjects); + _("Subject: %s\n"), subject_decoded); + g_free(subject_decoded); } label_text = g_strdup_printf( diff -r e4264f71fac7 -r 0351ff7030d0 src/util.c --- a/src/util.c Sun Nov 30 02:53:05 2003 +0000 +++ b/src/util.c Sun Nov 30 04:17:17 2003 +0000 @@ -244,6 +244,140 @@ *size = len; } +/************************************************************************** + * Quoted Printable Functions + **************************************************************************/ +void +gaim_quotedp_decode(const char *text, char **data, int *size) +{ + char *p, *n, *new; + + n = new = malloc(strlen (text)); + + for (p = (char *)text; *p; p++, n++) { + if (*p == '=') { + sscanf(p + 1, "%2x\n", (int *)n); + p += 2; + } + else if (*p == '_') + *n = ' '; + else + *n = *p; + } + + *n = '\0'; + + if (size) + *size = n - new; + + /* Resize to take less space */ + /* new = realloc(new, n - new); */ + + *data = new; +} + +/************************************************************************** + * MIME Functions + **************************************************************************/ +#define OUT_CHARSET "utf-8" + +char * +gaim_mime_decode_word(const char *charset, const char *encoding, const char *text) +{ + /* TODO: We need to check for nulls */ + char *decoded, *converted; + int len = 0; + + if (g_ascii_strcasecmp(encoding, "Q") == 0) + gaim_quotedp_decode(text, &decoded, &len); + else if (g_ascii_strcasecmp(encoding, "B") == 0) + gaim_base64_decode(text, &decoded, &len); + else + return NULL; + + + converted = g_convert(decoded, len, OUT_CHARSET, charset, NULL, NULL, NULL); + g_free(decoded); + + return converted; +} + +char * +gaim_mime_decode_field(const char *str) +{ + char *cur, *mark; + char *unencoded_start, *unencoded_end; + char *charset, *encoding, *text, *decoded; + char *new, *n; + + n = new = malloc(strlen(str)); + charset = text = NULL; + + /* Here we will be looking for encoded words and if they seem to be + * valid then decode them */ + + for ( unencoded_start = cur = (char *)str; + (unencoded_end = cur = strstr(cur, "=?")); + unencoded_start = cur) + { + int len; + char *token; + GQueue *tokens = g_queue_new(); + + for (cur += 2, mark = cur; *cur; cur++) { + if (*cur == '?') { + token = g_strndup(mark, cur - mark); + g_queue_push_head(tokens, token); + + mark = (cur + 1); + + if (*mark == '=') + break; + } else { + if ((tokens->length == 2) && (*cur == ' ')) + break; + else if ((tokens->length < 2) && (strchr("()<>@,;:/[]", *cur))) + break; + else if (tokens->length > 2) + break; + } + } + + cur += 2; + + if ((tokens->length == 3) && (*mark == '=')) { + len = unencoded_end - unencoded_start; + n = strncpy(n, unencoded_start, len) + len; + + charset = g_queue_pop_tail(tokens); + encoding = g_queue_pop_tail(tokens); + text = g_queue_pop_tail(tokens); + + if ((decoded = gaim_mime_decode_word(charset, encoding, text))) { + len = strlen(decoded); + n = strncpy(n, decoded, len) + len; + g_free(decoded); + } + + g_free(charset); + g_free(encoding); + g_free(text); + } else { + len = cur - unencoded_start; + n = strncpy(n, unencoded_start, len) + len; + + while ((token = g_queue_pop_tail(tokens))) + g_free(token); + } + + g_queue_free(tokens); + } + + if (*unencoded_start) + n = strcpy(n, unencoded_start); + + return new; +} /************************************************************************** * Date/Time Functions diff -r e4264f71fac7 -r 0351ff7030d0 src/util.h --- a/src/util.h Sun Nov 30 02:53:05 2003 +0000 +++ b/src/util.h Sun Nov 30 04:17:17 2003 +0000 @@ -96,6 +96,9 @@ /*@}*/ +void gaim_quotedp_decode (const char *text, char **data, int *size); +char *gaim_mime_decode_field (const char *str); + /**************************************************************************/ /** @name Date/Time Functions */