# HG changeset patch # User Yoshiki Yazawa # Date 1291288657 -32400 # Node ID 4635d84e329221ca38b74da2e0e7656329db360c # Parent 8fd65bb260cf0e9762d8b667afeb6b6fd26df17f# Parent 1546ad4f93b3936bb078d92f81dd18b34a813ec1 merged from im.pidgin.pidgin diff -r 8fd65bb260cf -r 4635d84e3292 ChangeLog --- 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 "<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: diff -r 8fd65bb260cf -r 4635d84e3292 libpurple/protocols/msn/contact.c --- 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); diff -r 8fd65bb260cf -r 4635d84e3292 libpurple/protocols/msn/contact.h --- 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 @@ ""\ "" MSN_APPLICATION_ID ""\ "false"\ - "Timer"\ + ""\ ""\ ""\ "false"\ diff -r 8fd65bb260cf -r 4635d84e3292 libpurple/protocols/msn/msn.c --- 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, diff -r 8fd65bb260cf -r 4635d84e3292 libpurple/protocols/msn/notification.c --- 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); diff -r 8fd65bb260cf -r 4635d84e3292 libpurple/protocols/msn/session.c --- 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); diff -r 8fd65bb260cf -r 4635d84e3292 libpurple/protocols/msn/session.h --- 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; diff -r 8fd65bb260cf -r 4635d84e3292 libpurple/protocols/msn/switchboard.c --- 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; } diff -r 8fd65bb260cf -r 4635d84e3292 libpurple/protocols/msn/user.c --- 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); diff -r 8fd65bb260cf -r 4635d84e3292 libpurple/protocols/msn/user.h --- 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. diff -r 8fd65bb260cf -r 4635d84e3292 libpurple/protocols/oscar/family_locate.c --- 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; diff -r 8fd65bb260cf -r 4635d84e3292 libpurple/protocols/oscar/oscar.c --- 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)) { diff -r 8fd65bb260cf -r 4635d84e3292 pidgin/gtkimhtml.c --- 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) {