changeset 7679:1363f91da9cc

[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 <tailor@pidgin.im>
author Mark Doliner <mark@kingant.net>
date Mon, 01 Dec 2003 03:41:50 +0000
parents cf6a7939af78
children 4995ad0ada66
files ChangeLog src/gtknotify.c src/util.c src/util.h
diffstat 4 files changed, 176 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- 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)
--- 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(
-				_("<span weight=\"bold\">From:</span> %s\n"), *froms);
+				_("<span weight=\"bold\">From:</span> %s\n"), from_decoded);
+			g_free(from_decoded);
 		}
 
 		if (subjects != NULL) {
+			char *subject_decoded = gaim_mime_decode_field(*subjects);
 			subject_text = g_strdup_printf(
-				_("<span weight=\"bold\">Subject:</span> %s\n"), *subjects);
+				_("<span weight=\"bold\">Subject:</span> %s\n"), subject_decoded);
+			g_free(subject_decoded);
 		}
 
 		label_text = g_strdup_printf(
--- 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
--- 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                                             */