changeset 31437:4635d84e3292

merged from im.pidgin.pidgin
author Yoshiki Yazawa <yaz@honeyplanet.jp>
date Thu, 02 Dec 2010 20:17:37 +0900
parents 8fd65bb260cf (current diff) 1546ad4f93b3 (diff)
children 62f6e6796e48
files libpurple/protocols/msn/msn.c libpurple/protocols/oscar/oscar.c pidgin/gtkimhtml.c
diffstat 13 files changed, 129 insertions(+), 50 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Thu Dec 02 20:16:47 2010 +0900
+++ b/ChangeLog	Thu Dec 02 20:17:37 2010 +0900
@@ -5,10 +5,20 @@
 	* Fix the exceptions in purple-remote on Python 2.6+. (Ari Pollak)
 	  (#12151)
 
+	Pidgin:
+	* When a conversation has reached the maximum limit on the number
+	  of smileys, display the text representation of the smiley properly
+	  when it contains HTML-escapable characters (e.g. "<3" was previously
+	  displayed as "&lt;3").
+
 	libpurple:
 	* Fix multipart parsing when '=' is included in the boundary for
 	  purple_mime_document_parse. (Jakub Adam) (#11598)
 
+	AIM and ICQ:
+	* Buddies who unset their status message will now be correctly shown
+	  without a message in your buddy list. (#12988)
+
 	Gadu-Gadu:
 	* Updated our bundled libgadu and minimum requirement for external
 	  libgadu to 1.9.0. (#12789)
@@ -18,6 +28,9 @@
 	  disconnected.
 	* Allow full-size display names, by not escaping (most) non-English
 	  characters. (#8508)
+	* Fix receiving messages from users on Yahoo and other federated
+	  services. (#13022)
+	* Correctly remove old endpoints when they sign out.
 
 version 2.7.7 (11/23/2010):
 	General:
--- a/libpurple/protocols/msn/contact.c	Thu Dec 02 20:16:47 2010 +0900
+++ b/libpurple/protocols/msn/contact.c	Thu Dec 02 20:17:37 2010 +0900
@@ -41,7 +41,8 @@
 	"ContactSave",
 	"MessengerPendingList",
 	"ContactMsgrAPI",
-	"BlockUnblock"
+	"BlockUnblock",
+	"Timer"
 };
 
 const char *MsnMemberRole[] =
@@ -709,8 +710,9 @@
 		uid = xmlnode_get_data(contactId);
 		type = xmlnode_get_data(contactType);
 
-		/*setup the Display Name*/
+		/* Find out our settings */
 		if (type && !strcmp(type, "Me")) {
+			/* setup the Display Name */
 			if (purple_connection_get_display_name(pc) == NULL) {
 				char *friendly = NULL;
 				if ((displayName = xmlnode_get_child(contactInfo, "displayName")))
@@ -719,6 +721,23 @@
 					friendly ? purple_url_decode(friendly) : NULL);
 				g_free(friendly);
 			}
+
+			for (annotation = xmlnode_get_child(contactInfo, "annotations/Annotation");
+			     annotation;
+			     annotation = xmlnode_get_next_twin(annotation)) {
+				char *name, *value;
+				name = xmlnode_get_data(xmlnode_get_child(annotation, "Name"));
+				value = xmlnode_get_data(xmlnode_get_child(annotation, "Value"));
+				if (!strcmp(name, "MSN.IM.MPOP")) {
+					if (!value || atoi(value) != 0)
+						purple_account_set_bool(session->account, "mpop", TRUE);
+					else
+						purple_account_set_bool(session->account, "mpop", FALSE);
+				}
+				g_free(name);
+				g_free(value);
+			}
+
 			continue; /* Not adding own account as buddy to buddylist */
 		}
 
@@ -1497,6 +1516,10 @@
 	xmlnode_insert_child(contact, contact_info);
 	xmlnode_insert_child(contact, changes);
 
+	xmlnode_insert_data(xmlnode_get_child(state->body,
+	                                      "Header/ABApplicationHeader/PartnerScenario"),
+	                    MsnSoapPartnerScenarioText[MSN_PS_SAVE_CONTACT], -1);
+
 	if (user) {
 		xmlnode *contactId = xmlnode_new_child(contact, "contactId");
 		msn_callback_state_set_uid(state, user->uid);
--- a/libpurple/protocols/msn/contact.h	Thu Dec 02 20:16:47 2010 +0900
+++ b/libpurple/protocols/msn/contact.h	Thu Dec 02 20:17:37 2010 +0900
@@ -52,7 +52,8 @@
 	MSN_PS_SAVE_CONTACT,
 	MSN_PS_PENDING_LIST,
 	MSN_PS_CONTACT_API,
-	MSN_PS_BLOCK_UNBLOCK
+	MSN_PS_BLOCK_UNBLOCK,
+	MSN_PS_TIMER
 } MsnSoapPartnerScenario;
 
 #include "session.h"
@@ -408,7 +409,7 @@
 		"<ABApplicationHeader xmlns=\"http://www.msn.com/webservices/AddressBook\">"\
 			"<ApplicationId>" MSN_APPLICATION_ID "</ApplicationId>"\
 			"<IsMigration>false</IsMigration>"\
-			"<PartnerScenario>Timer</PartnerScenario>"\
+			"<PartnerScenario></PartnerScenario>"\
 		"</ABApplicationHeader>"\
 		"<ABAuthHeader xmlns=\"http://www.msn.com/webservices/AddressBook\">"\
 			"<ManagedGroupRequest>false</ManagedGroupRequest>"\
--- a/libpurple/protocols/msn/msn.c	Thu Dec 02 20:16:47 2010 +0900
+++ b/libpurple/protocols/msn/msn.c	Thu Dec 02 20:17:37 2010 +0900
@@ -1200,7 +1200,8 @@
 	m = g_list_append(m, act);
 	m = g_list_append(m, NULL);
 
-	if (session->protocol_ver >= 16)
+	if (purple_account_get_bool(session->account, "mpop", TRUE)
+	 && session->protocol_ver >= 16)
 	{
 		act = purple_plugin_action_new(_("View Locations..."),
 		                               msn_show_locations);
@@ -3095,6 +3096,11 @@
 	prpl_info.protocol_options = g_list_append(prpl_info.protocol_options,
 											   option);
 
+	option = purple_account_option_bool_new(_("Allow connecting from multiple locations"),
+										  "mpop", TRUE);
+	prpl_info.protocol_options = g_list_append(prpl_info.protocol_options,
+											   option);
+
 	purple_cmd_register("nudge", "", PURPLE_CMD_P_PRPL,
 	                  PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_PRPL_ONLY,
 	                 "prpl-msn", msn_cmd_nudge,
--- a/libpurple/protocols/msn/notification.c	Thu Dec 02 20:16:47 2010 +0900
+++ b/libpurple/protocols/msn/notification.c	Thu Dec 02 20:17:37 2010 +0900
@@ -387,7 +387,10 @@
 	 * command and we are processing it */
 	if (cmd->payload == NULL) {
 		cmdproc->last_cmd->payload_cb = msg_cmd_post;
-		cmd->payload_len = atoi(cmd->params[3]);
+		if (cmdproc->session->protocol_ver >= 16)
+			cmd->payload_len = atoi(cmd->params[5]);
+		else
+			cmd->payload_len = atoi(cmd->params[3]);
 	} else {
 		g_return_if_fail(cmd->payload_cb != NULL);
 
@@ -1548,40 +1551,55 @@
 static void
 parse_user_endpoints(MsnUser *user, xmlnode *payloadNode)
 {
+	MsnSession *session;
 	xmlnode *epNode, *capsNode;
 	MsnUserEndpoint data;
 	const char *id;
 	char *caps, *tmp;
+	gboolean is_me;
 
 	purple_debug_info("msn", "Get EndpointData\n");
 
+	session = user->userlist->session;
+	is_me = (user == session->user);
+
+	msn_user_clear_endpoints(user);
 	for (epNode = xmlnode_get_child(payloadNode, "EndpointData");
 	     epNode;
 	     epNode = xmlnode_get_next_twin(epNode)) {
 		id = xmlnode_get_attrib(epNode, "id");
 		capsNode = xmlnode_get_child(epNode, "Capabilities");
 
-		if (capsNode != NULL) {
-			caps = xmlnode_get_data(capsNode);
-
-			data.clientid = strtoul(caps, &tmp, 10);
-			if (tmp && *tmp)
-				data.extcaps = strtoul(tmp + 1, NULL, 10);
-			else
+		/* Disconnect others, if MPOP is disabled */
+		if (is_me
+		 && !purple_account_get_bool(session->account, "mpop", TRUE)
+		 && strncasecmp(id + 1, session->guid, 36) != 0) {
+			purple_debug_info("msn", "Disconnecting Endpoint %s\n", id);
+
+			tmp = g_strdup_printf("%s;%s", user->passport, id);
+			msn_notification_send_uun(session, tmp, MSN_UNIFIED_NOTIFICATION_MPOP, "goawyplzthxbye");
+			g_free(tmp);
+		} else {
+			if (capsNode != NULL) {
+				caps = xmlnode_get_data(capsNode);
+
+				data.clientid = strtoul(caps, &tmp, 10);
+				if (tmp && *tmp)
+					data.extcaps = strtoul(tmp + 1, NULL, 10);
+				else
+					data.extcaps = 0;
+
+				g_free(caps);
+			} else {
+				data.clientid = 0;
 				data.extcaps = 0;
-
-			g_free(caps);
-
-		} else {
-			data.clientid = 0;
-			data.extcaps = 0;
+			}
+
+			msn_user_set_endpoint_data(user, id, &data);
 		}
-
-		msn_user_set_endpoint_data(user, id, &data);
 	}
 
-	/* Need to shortcut this check, probably... */
-	if (user == user->userlist->session->user) {
+	if (is_me && purple_account_get_bool(session->account, "mpop", TRUE)) {
 		for (epNode = xmlnode_get_child(payloadNode, "PrivateEndpointData");
 		     epNode;
 		     epNode = xmlnode_get_next_twin(epNode)) {
@@ -1939,12 +1957,6 @@
 		/* This isn't an official message. */
 		return;
 
-	if ((value = msn_message_get_header_value(msg, "kv")) != NULL)
-	{
-		g_free(session->passport_info.kv);
-		session->passport_info.kv = g_strdup(value);
-	}
-
 	if ((value = msn_message_get_header_value(msg, "sid")) != NULL)
 	{
 		g_free(session->passport_info.sid);
--- a/libpurple/protocols/msn/session.c	Thu Dec 02 20:16:47 2010 +0900
+++ b/libpurple/protocols/msn/session.c	Thu Dec 02 20:17:37 2010 +0900
@@ -103,7 +103,6 @@
 	g_free(session->blocked_text);
 #endif
 
-	g_free(session->passport_info.kv);
 	g_free(session->passport_info.sid);
 	g_free(session->passport_info.mspauth);
 	g_free(session->passport_info.client_ip);
--- a/libpurple/protocols/msn/session.h	Thu Dec 02 20:16:47 2010 +0900
+++ b/libpurple/protocols/msn/session.h	Thu Dec 02 20:17:37 2010 +0900
@@ -79,12 +79,12 @@
 
 	MsnLoginStep login_step; /**< The current step in the login process. */
 
-	gboolean connected;
-	gboolean logged_in; /**< A temporal flag to ignore local buddy list adds. */
+	gboolean connected:1;
+	gboolean logged_in:1; /**< A temporal flag to ignore local buddy list adds. */
+	gboolean destroying:1; /**< A flag that states if the session is being destroyed. */
+	gboolean http_method:1;
 	int      adl_fqy; /**< A count of ADL/FQY so status is only changed once. */
 	guint    login_timeout; /**< Timeout to force status change if ADL/FQY fail. */
-	gboolean destroying; /**< A flag that states if the session is being destroyed. */
-	gboolean http_method;
 
 	MsnNotification *notification;
 	MsnNexus        *nexus;
@@ -105,7 +105,6 @@
 
 	struct
 	{
-		char *kv;
 		char *sid;
 		char *mspauth;
 		unsigned long sl;
--- a/libpurple/protocols/msn/switchboard.c	Thu Dec 02 20:16:47 2010 +0900
+++ b/libpurple/protocols/msn/switchboard.c	Thu Dec 02 20:17:37 2010 +0900
@@ -743,7 +743,10 @@
 ubm_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
 {
 	purple_debug_misc("msn", "get UBM...\n");
-	cmd->payload_len = atoi(cmd->params[3]);
+	if (cmdproc->session->protocol_ver >= 16)
+		cmd->payload_len = atoi(cmd->params[5]);
+	else
+		cmd->payload_len = atoi(cmd->params[3]);
 	cmdproc->last_cmd->payload_cb = msg_cmd_post;
 }
 
--- a/libpurple/protocols/msn/user.c	Thu Dec 02 20:16:47 2010 +0900
+++ b/libpurple/protocols/msn/user.c	Thu Dec 02 20:17:37 2010 +0900
@@ -305,6 +305,22 @@
 }
 
 void
+msn_user_clear_endpoints(MsnUser *user)
+{
+	MsnUserEndpoint *ep;
+	GSList *l;
+
+	g_return_if_fail(user != NULL);
+
+	for (l = user->endpoints; l; l = g_slist_delete_link(l, l)) {
+		ep = l->data;
+		free_user_endpoint(ep);
+	}
+
+	user->endpoints = NULL;
+}
+
+void
 msn_user_set_op(MsnUser *user, MsnListOp list_op)
 {
 	g_return_if_fail(user != NULL);
--- a/libpurple/protocols/msn/user.h	Thu Dec 02 20:16:47 2010 +0900
+++ b/libpurple/protocols/msn/user.h	Thu Dec 02 20:17:37 2010 +0900
@@ -286,6 +286,14 @@
 msn_user_set_endpoint_data(MsnUser *user, const char *endpoint, MsnUserEndpoint *data);
 
 /**
+ * Clears all endpoint data for a user.
+ *
+ * @param user     The user.
+ */
+void
+msn_user_clear_endpoints(MsnUser *user);
+
+/**
  * Sets the client id for a user.
  *
  * @param user     The user.
--- a/libpurple/protocols/oscar/family_locate.c	Thu Dec 02 20:16:47 2010 +0900
+++ b/libpurple/protocols/oscar/family_locate.c	Thu Dec 02 20:17:37 2010 +0900
@@ -1043,7 +1043,7 @@
 						} else {
 							byte_stream_advance(bs, length2);
 							outinfo->status_len = 0;
-							outinfo->status = g_strdup("");
+							outinfo->status = NULL;
 							outinfo->status_encoding = NULL;
 						}
 					} break;
--- a/libpurple/protocols/oscar/oscar.c	Thu Dec 02 20:16:47 2010 +0900
+++ b/libpurple/protocols/oscar/oscar.c	Thu Dec 02 20:17:37 2010 +0900
@@ -1366,7 +1366,7 @@
 	const char *status_id;
 	va_list ap;
 	aim_userinfo_t *info;
-	char *message = NULL;
+	char *message;
 	char *itmsurl = NULL;
 
 	gc = od->gc;
@@ -1453,16 +1453,13 @@
 		purple_prpl_got_user_status_deactive(account, info->bn, OSCAR_STATUS_ID_MOBILE);
 	}
 
-	/* Empty status means we should unset the status message. NULL status means we should keep it from the previous active status.
-	 * Same goes for itmsurl (which is available only for the "available" status).
-	 */
-	if (info->status != NULL) {
-		message = (info->status_len > 0) ? oscar_encoding_to_utf8(info->status_encoding, info->status, info->status_len) : NULL;
-	} else if (previous_status != NULL) {
-		message = g_strdup(purple_status_get_attr_string(previous_status, "message"));
-	}
+	message = (info->status && info->status_len > 0)
+			? oscar_encoding_to_utf8(info->status_encoding, info->status, info->status_len)
+			: NULL;
 
 	if (strcmp(status_id, OSCAR_STATUS_ID_AVAILABLE) == 0) {
+		/* TODO: If itmsurl is NULL, does that mean the URL has been
+		   cleared?  Or does it mean the URL should remain unchanged? */
 		if (info->itmsurl != NULL) {
 			itmsurl = (info->itmsurl_len > 0) ? oscar_encoding_to_utf8(info->itmsurl_encoding, info->itmsurl, info->itmsurl_len) : NULL;
 		} else if (previous_status != NULL && purple_status_is_available(previous_status)) {
--- a/pidgin/gtkimhtml.c	Thu Dec 02 20:16:47 2010 +0900
+++ b/pidgin/gtkimhtml.c	Thu Dec 02 20:17:37 2010 +0900
@@ -4921,18 +4921,20 @@
 	 * are apparently pretty inefficient.  Hopefully we can remove this
 	 * restriction when we're using a better HTML widget.
 	 */
+	unescaped = purple_unescape_html(smiley);
 	numsmileys_thismsg = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(imhtml), "gtkimhtml_numsmileys_thismsg"));
 	if (numsmileys_thismsg >= 30) {
-		gtk_text_buffer_insert(imhtml->text_buffer, iter, smiley, -1);
+		gtk_text_buffer_insert(imhtml->text_buffer, iter, unescaped, -1);
+		g_free(unescaped);
 		return;
 	}
 	numsmileys_total = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(imhtml), "gtkimhtml_numsmileys_total"));
 	if (numsmileys_total >= 300) {
-		gtk_text_buffer_insert(imhtml->text_buffer, iter, smiley, -1);
+		gtk_text_buffer_insert(imhtml->text_buffer, iter, unescaped, -1);
+		g_free(unescaped);
 		return;
 	}
 
-	unescaped = purple_unescape_html(smiley);
 	imhtml_smiley = gtk_imhtml_smiley_get(imhtml, sml, unescaped);
 
 	if (imhtml->format_functions & GTK_IMHTML_SMILEY) {
@@ -5007,7 +5009,7 @@
 		g_object_set_data(G_OBJECT(imhtml), "gtkimhtml_numsmileys_thismsg", GINT_TO_POINTER(numsmileys_thismsg + 1));
 		g_object_set_data(G_OBJECT(imhtml), "gtkimhtml_numsmileys_total", GINT_TO_POINTER(numsmileys_total + 1));
 	} else {
-		gtk_text_buffer_insert(imhtml->text_buffer, iter, smiley, -1);
+		gtk_text_buffer_insert(imhtml->text_buffer, iter, unescaped, -1);
 	}
 
 	if (ebox) {