changeset 7665:0351ff7030d0

[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 <tailor@pidgin.im>
author Luke Schierer <lschiere@pidgin.im>
date Sun, 30 Nov 2003 04:17:17 +0000
parents e4264f71fac7
children 25488bd0d461
files src/gtknotify.c src/util.c src/util.h
diffstat 3 files changed, 143 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- 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(
-				_("<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	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
--- 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                                             */