changeset 24730:34258af32335

Add support for receiving MSN offline messages that were sent from a mobile device. Based on a patch from Maiku.
author Elliott Sales de Andrade <qulogic@pidgin.im>
date Mon, 15 Dec 2008 01:40:52 +0000
parents 1385d79ef68f
children ecbf95af2fa7
files ChangeLog libpurple/protocols/msn/oim.c
diffstat 2 files changed, 66 insertions(+), 15 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Mon Dec 15 00:49:35 2008 +0000
+++ b/ChangeLog	Mon Dec 15 01:40:52 2008 +0000
@@ -28,6 +28,8 @@
 	* On ICQ, advertise the ICQ 6 typing capability.  This should fix the
 	  reports of typing notifications not working with third-party clients
 	  (Jaromír Karmazín)
+	* On MSN, messages sent from a mobile device while you were offline are
+	  now correctly received.
 
 	Gadu-Gadu:
 	* Fix some problems with Gadu-Gadu buddy icons (Adam Strzelecki)
--- a/libpurple/protocols/msn/oim.c	Mon Dec 15 00:49:35 2008 +0000
+++ b/libpurple/protocols/msn/oim.c	Mon Dec 15 01:40:52 2008 +0000
@@ -596,11 +596,10 @@
 	MsnMessage *message;
 	const char *date;
 	const char *from;
-	char *decode_msg;
+	char *decode_msg = NULL;
 	gsize body_len;
 	char **tokens;
-	char *start, *end;
-	char *passport;
+	char *passport = NULL;
 	time_t stamp;
 
 	message = msn_message_new(MSN_MSG_UNKNOWN);
@@ -608,21 +607,72 @@
 	msn_message_parse_payload(message, msg_str, strlen(msg_str),
 	                          MSG_OIM_LINE_DEM, MSG_OIM_BODY_DEM);
 	purple_debug_info("msn", "oim body:{%s}\n", message->body);
-	decode_msg = (char *)purple_base64_decode(message->body, &body_len);
-	date = msn_message_get_attr(message, "Date");
-	from = msn_message_get_attr(message, "From");
+
+	if (!strcmp(msn_message_get_attr(message, "X-OIMProxy"), "MOSMS")) {
+		char *boundary;
+		char **part;
+
+		from = msn_message_get_attr(message, "X-OIM-originatingSource");
+
+		/* Match number to user's mobile number, FROM is a phone number
+		   if the other side pages you using your phone number */
+		if (!strncmp(passport, "tel:+", 5)) {
+			MsnUser *user =	msn_userlist_find_user_with_mobile_phone(
+					rdata->oim->session->userlist, from + 4);
 
-	tokens = g_strsplit(from, " ", 2);
-	if (tokens[1] != NULL)
-		from = (const char *)tokens[1];
+			if (user && user->passport)
+				passport = g_strdup(user->passport);
+		}
+		if (passport == NULL)
+			passport = g_strdup(from);
+
+		boundary = g_strdup_printf("--%s" MSG_OIM_LINE_DEM,
+		                           msn_message_get_attr(message, "boundary"));
+		tokens = g_strsplit(message->body, boundary, 0);
+
+		for (part = tokens; *part != NULL; part++) {
+			MsnMessage *multipart;
+			multipart = msn_message_new(MSN_MSG_UNKNOWN);
+			msn_message_parse_payload(multipart, *part, strlen(*part),
+			                          MSG_OIM_LINE_DEM, MSG_OIM_BODY_DEM);
 
-	start = strchr(from, '<') + 1;
-	end = strchr(from, '>');
-	passport = g_strndup(start, end - start);
-	purple_debug_info("msn", "oim Date:{%s},passport{%s},tokens[0]:{%s}\n",
-	                  date, passport, tokens[0]);
+			if (!strcmp(msn_message_get_content_type(multipart), "text/plain")) {
+				decode_msg = (char *)purple_base64_decode(multipart->body, &body_len);
+				msn_message_destroy(multipart);
+				break;
+			}
+			msn_message_destroy(multipart);
+		}
+
+		g_strfreev(tokens);
+		g_free(boundary);
+
+		if (decode_msg == NULL) {
+			purple_debug_error("msn", "Couldn't find text/plain OIM message.\n");
+			g_free(passport);
+			return;
+		}
+	} else {
+		char *start, *end;
 
+		from = msn_message_get_attr(message, "From");
+		decode_msg = (char *)purple_base64_decode(message->body, &body_len);
+
+		tokens = g_strsplit(from, " ", 2);
+		if (tokens[1] != NULL)
+			from = (const char *)tokens[1];
+
+		start = strchr(from, '<') + 1;
+		end = strchr(from, '>');
+		passport = g_strndup(start, end - start);
+
+		g_strfreev(tokens);
+	}
+
+	date = msn_message_get_attr(message, "Date");
 	stamp = msn_oim_parse_timestamp(date);
+	purple_debug_info("msn", "oim Date:{%s},passport{%s}\n",
+	                  date, passport);
 
 	serv_got_im(rdata->oim->session->account->gc, passport, decode_msg, 0,
 	            stamp);
@@ -632,7 +682,6 @@
 	 */
 	msn_oim_post_delete_msg(rdata);
 
-	g_strfreev(tokens);
 	g_free(passport);
 	g_free(decode_msg);
 }