# HG changeset patch # User Mark Doliner # Date 1070250110 0 # Node ID 1363f91da9cc5797c1fb078c7f6d634fa25895f1 # Parent cf6a7939af78bd302ef4beec9b5e4a73fad24859 [gaim-migrate @ 8323] The real patch that handles mime email stuff from Felipe Contreras (revo)(shx), after I nagged him a bunch to change some stuff. Thanks! committer: Tailor Script diff -r cf6a7939af78 -r 1363f91da9cc ChangeLog --- a/ChangeLog Mon Dec 01 02:36:51 2003 +0000 +++ b/ChangeLog Mon Dec 01 03:41:50 2003 +0000 @@ -1,10 +1,10 @@ Gaim: The Pimpin' Penguin IM Clone that's good for the soul! version 0.75cvs : - * Yahoo file transfer (Tim Ringenbach) + * Yahoo! file transfer (Tim Ringenbach) + * Improved i18n support for MSN email notification (Felipe Contreras) * Chinese (Simplified) translation updated (Funda Wang) * Chinese (Traditional) translation updated (Ambrose C. Li) - * Esperanto translation added (Anthony Ehrhardt (cguru)) * Italian translation updated (Claudio Satriano) * Portuguese (Brazilian) translation updated (Mauricio de Lemos Rodrigues Collares Neto) diff -r cf6a7939af78 -r 1363f91da9cc src/gtknotify.c --- a/src/gtknotify.c Mon Dec 01 02:36:51 2003 +0000 +++ b/src/gtknotify.c Mon Dec 01 03:41:50 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 cf6a7939af78 -r 1363f91da9cc src/util.c --- a/src/util.c Mon Dec 01 02:36:51 2003 +0000 +++ b/src/util.c Mon Dec 01 03:41:50 2003 +0000 @@ -244,6 +244,141 @@ *size = len; } +/************************************************************************** + * Quoted Printable Functions + **************************************************************************/ +void +gaim_quotedp_decode(const char *str, char **ret_str, int *ret_len) +{ + char *p, *n, *new; + + n = new = malloc(strlen (str)); + + for (p = (char *)str; *p; p++, n++) { + if (*p == '=') { + sscanf(p + 1, "%2x\n", (int *)n); + p += 2; + } + else if (*p == '_') + *n = ' '; + else + *n = *p; + } + + *n = '\0'; + + if (ret_len) + *ret_len = n - new; + + /* Resize to take less space */ + /* new = realloc(new, n - new); */ + + *ret_str = new; +} + +/************************************************************************** + * MIME Functions + **************************************************************************/ +#define OUT_CHARSET "utf-8" + +char * +gaim_mime_decode_word(const char *charset, const char *encoding, const char *str) +{ + /* TODO: We need to check for nulls */ + char *decoded, *converted; + int len = 0; + + if (g_ascii_strcasecmp(encoding, "Q") == 0) + gaim_quotedp_decode(str, &decoded, &len); + else if (g_ascii_strcasecmp(encoding, "B") == 0) + gaim_base64_decode(str, &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, *word, *decoded; + char *n, *new; + + n = new = malloc(strlen(str)); + charset = word = 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[0] == '=' && mark[1] == '\0') + 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); + word = g_queue_pop_tail(tokens); + + if ((decoded = gaim_mime_decode_word(charset, encoding, word))) { + len = strlen(decoded); + n = strncpy(n, decoded, len) + len; + g_free(decoded); + } + + g_free(charset); + g_free(encoding); + g_free(word); + } 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); + } + + *n = '\0'; + + if (*unencoded_start) + n = strcpy(n, unencoded_start); + + return new; +} /************************************************************************** * Date/Time Functions diff -r cf6a7939af78 -r 1363f91da9cc src/util.h --- a/src/util.h Mon Dec 01 02:36:51 2003 +0000 +++ b/src/util.h Mon Dec 01 03:41:50 2003 +0000 @@ -96,6 +96,39 @@ /*@}*/ +/**************************************************************************/ +/** @name Quoted Printable Functions */ +/**************************************************************************/ +/*@{*/ + +/** + * Converts a quoted printable string back to its readable equivalent. + * + * @param str The string to convert back. + * @param ret_str The returned, readable string. + * @param ret_len The returned string length. + */ +void gaim_quotedp_decode (const char *str, char **ret_str, int *ret_len); + +/*@}*/ + +/**************************************************************************/ +/** @name MIME Functions */ +/**************************************************************************/ +/*@{*/ + +/** + * Converts a MIME header field string back to its readable equivalent + * according to RFC 2047. + * + * @param str The string to convert back. + * + * @return The readble string. + */ +char *gaim_mime_decode_field (const char *str); + +/*@}*/ + /**************************************************************************/ /** @name Date/Time Functions */