Mercurial > pidgin
changeset 24677:eae0e194658e
merge of '834b032b518f6b4ab9148b946ca635214a9388d8'
and 'fd954d6a415456dce86aa9443b24e1df25019bd7'
author | Elliott Sales de Andrade <qulogic@pidgin.im> |
---|---|
date | Wed, 10 Dec 2008 06:58:10 +0000 |
parents | 781723b2a170 (diff) 35d0ce5f319a (current diff) |
children | 2f84f888d3db |
files | ChangeLog libpurple/protocols/msn/msn.c |
diffstat | 9 files changed, 375 insertions(+), 75 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog Wed Dec 10 02:44:03 2008 +0000 +++ b/ChangeLog Wed Dec 10 06:58:10 2008 +0000 @@ -13,9 +13,6 @@ * The Buddy State Notification plugin no longer turns JID's, MSN Passport ID's, etc. into links (Florian Quèze) * Fix a crash in SIMPLE when a malformed message is received. - * On MSN, the Games and Office media can now be set and displayed (in - addition to the previous Music media). The Media status text now shows - the album, if possible. * purple-remote now has a "getstatusmessage" command to retrieve the text of the current status message. * Various fixes to the nullprpl (Paul Aurich) @@ -23,6 +20,9 @@ connected (Paul Aurich) * Fix a crash in purple_accounts_delete that happens when this function is called before the buddy list is initialized (Florian Quèze) + * On MSN, the Games and Office media can now be set and displayed (in + addition to the previous Music media). The Media status text now shows + the album, if possible. Gadu-Gadu: * Fix some problems with Gadu-Gadu buddy icons (Adam Strzelecki)
--- a/libpurple/protocols/msn/contact.c Wed Dec 10 02:44:03 2008 +0000 +++ b/libpurple/protocols/msn/contact.c Wed Dec 10 06:58:10 2008 +0000 @@ -870,7 +870,7 @@ gpointer data) { MsnCallbackState *state = data; - xmlnode *faultcode; + xmlnode *fault; char *faultcode_str; if (resp == NULL) { @@ -880,9 +880,9 @@ return; } - faultcode = xmlnode_get_child(resp->xml, "Body/Fault/faultcode"); + fault = xmlnode_get_child(resp->xml, "Body/Fault"); - if (faultcode == NULL) { + if (fault == NULL) { /* No errors */ if (state->cb) ((MsnSoapCallback)state->cb)(req, resp, data); @@ -890,7 +890,7 @@ return; } - faultcode_str = xmlnode_get_data(faultcode); + faultcode_str = xmlnode_get_data(xmlnode_get_child(fault, "faultcode")); if (faultcode_str && g_str_equal(faultcode_str, "q0:BadContextToken")) { purple_debug_info("msn", @@ -903,12 +903,15 @@ } else { - /* We don't know how to respond to this faultcode, so just log it */ - /* XXX: Probably should notify the user or undo the change or something? */ - char *str = xmlnode_to_str(xmlnode_get_child(resp->xml, "Body/Fault"), NULL); - purple_debug_error("msn", "Operation {%s} Failed, SOAP Fault was: %s\n", - msn_contact_operation_str(state->action), str); - g_free(str); + if (state->cb) { + ((MsnSoapCallback)state->cb)(req, resp, data); + } else { + /* We don't know how to respond to this faultcode, so log it */ + char *str = xmlnode_to_str(fault, NULL); + purple_debug_error("msn", "Operation {%s} Failed, SOAP Fault was: %s\n", + msn_contact_operation_str(state->action), str); + g_free(str); + } msn_callback_state_free(state); } @@ -943,21 +946,44 @@ MsnUser *user; xmlnode *guid; + xmlnode *fault; + g_return_if_fail(session != NULL); + userlist = session->userlist; + + fault = xmlnode_get_child(resp->xml, "Body/Fault"); + if (fault != NULL) { + char *errorcode = xmlnode_get_data(xmlnode_get_child(fault, "detail/errorcode")); + if (errorcode && !strcmp(errorcode, "EmailDomainIsFederated")) { + /* Do something special! */ + purple_debug_error("msn", "Contact is from a federated domain, but don't know what to do yet!\n"); - userlist = session->userlist; + } else if (errorcode && !strcmp(errorcode, "InvalidPassportUser")) { + PurpleBuddy *buddy = purple_find_buddy(session->account, state->who); + char *str = g_strdup_printf(_("Unable to add \"%s\"."), state->who); + purple_notify_error(state->session, _("Buddy Add error"), str, + _("The username specified does not exist.")); + g_free(str); + msn_userlist_rem_buddy(userlist, state->who); + if (buddy != NULL) + purple_blist_remove_buddy(buddy); + + } else { + /* We don't know how to respond to this faultcode, so log it */ + char *fault_str = xmlnode_to_str(fault, NULL); + if (fault_str != NULL) { + purple_debug_error("msn", "Operation {%s} Failed, SOAP Fault was: %s\n", + msn_contact_operation_str(state->action), fault_str); + g_free(fault_str); + } + } + return; + } purple_debug_info("msn", "Contact added successfully\n"); - /* the code this block is replacing didn't send ADL for yahoo contacts, - * but i haven't confirmed this is WLM's behaviour wrt yahoo contacts - */ - if ( !msn_user_is_yahoo(session->account, state->who) ) { - msn_userlist_add_buddy_to_list(userlist, state->who, MSN_LIST_AL); - msn_userlist_add_buddy_to_list(userlist, state->who, MSN_LIST_FL); - } - - msn_notification_send_fqy(session, state->who); + msn_userlist_add_buddy_to_list(userlist, state->who, MSN_LIST_AL); + msn_userlist_add_buddy_to_list(userlist, state->who, MSN_LIST_FL); user = msn_userlist_find_add_user(userlist, state->who, state->who); msn_user_add_group_id(user, state->guid); @@ -976,6 +1002,7 @@ void msn_add_contact(MsnSession *session, MsnCallbackState *state, const char *passport) { + MsnUser *user; gchar *body = NULL; gchar *contact_xml = NULL; @@ -993,7 +1020,21 @@ purple_debug_info("msn", "Adding contact %s to contact list\n", passport); - contact_xml = g_strdup_printf(MSN_CONTACT_XML, passport); + user = msn_userlist_find_user(session->userlist, passport); + if (user == NULL) { + purple_debug_warning("msn", "Unable to retrieve user %s from the userlist!\n", passport); + return; /* guess this never happened! */ + } + + if (user->networkid != MSN_NETWORK_PASSPORT) { + contact_xml = g_strdup_printf(MSN_CONTACT_EMAIL_XML, + user->networkid == MSN_NETWORK_YAHOO ? + "Messenger2" : + "Messenger3", + passport, 0); + } else { + contact_xml = g_strdup_printf(MSN_CONTACT_XML, passport); + } body = g_strdup_printf(MSN_ADD_CONTACT_TEMPLATE, contact_xml); state->body = xmlnode_from_str(body, -1); @@ -1011,11 +1052,41 @@ gpointer data) { MsnCallbackState *state = data; + MsnSession *session = state->session; MsnUserList *userlist; + xmlnode *fault; + + g_return_if_fail(session != NULL); + userlist = session->userlist; + + fault = xmlnode_get_child(resp->xml, "Body/Fault"); + if (fault != NULL) { + char *errorcode = xmlnode_get_data(xmlnode_get_child(fault, "detail/errorcode")); + if (errorcode && !strcmp(errorcode, "EmailDomainIsFederated")) { + /* Do something special! */ + purple_debug_error("msn", "Contact is from a federated domain, but don't know what to do yet!\n"); - g_return_if_fail(data != NULL); + } else if (errorcode && !strcmp(errorcode, "InvalidPassportUser")) { + PurpleBuddy *buddy = purple_find_buddy(session->account, state->who); + char *str = g_strdup_printf(_("Unable to add \"%s\"."), state->who); + purple_notify_error(session, _("Buddy Add error"), str, + _("The username specified does not exist.")); + g_free(str); + msn_userlist_rem_buddy(userlist, state->who); + if (buddy != NULL) + purple_blist_remove_buddy(buddy); - userlist = state->session->userlist; + } else { + /* We don't know how to respond to this faultcode, so log it */ + char *fault_str = xmlnode_to_str(fault, NULL); + if (fault_str != NULL) { + purple_debug_error("msn", "Operation {%s} Failed, SOAP Fault was: %s\n", + msn_contact_operation_str(state->action), fault_str); + g_free(fault_str); + } + } + return; + } if (msn_userlist_add_buddy_to_group(userlist, state->who, state->new_group_name)) { @@ -1036,11 +1107,8 @@ g_free(uid); } - if ( !msn_user_is_yahoo(state->session->account, state->who) ) { - msn_userlist_add_buddy_to_list(userlist, state->who, MSN_LIST_AL); - msn_userlist_add_buddy_to_list(userlist, state->who, MSN_LIST_FL); - } - msn_notification_send_fqy(state->session, state->who); + msn_userlist_add_buddy_to_list(userlist, state->who, MSN_LIST_AL); + msn_userlist_add_buddy_to_list(userlist, state->who, MSN_LIST_FL); if (msn_userlist_user_is_in_list(user, MSN_LIST_PL)) { msn_del_contact_from_list(state->session, NULL, state->who, MSN_LIST_PL); @@ -1095,8 +1163,14 @@ return; /* guess this never happened! */ } - if (user != NULL && user->uid != NULL) { + if (user->uid != NULL) { contact_xml = g_strdup_printf(MSN_CONTACT_ID_XML, user->uid); + } else if (user->networkid != MSN_NETWORK_PASSPORT) { + contact_xml = g_strdup_printf(MSN_CONTACT_EMAIL_XML, + user->networkid == MSN_NETWORK_YAHOO ? + "Messenger2" : + "Messenger3", + passport, 0); } else { contact_xml = g_strdup_printf(MSN_CONTACT_XML, passport); } @@ -1120,6 +1194,17 @@ MsnCallbackState *state = data; MsnUserList *userlist = state->session->userlist; MsnUser *user = msn_userlist_find_user_with_id(userlist, state->uid); + xmlnode *fault; + + /* We don't know how to respond to this faultcode, so log it */ + fault = xmlnode_get_child(resp->xml, "Body/Fault"); + if (fault != NULL) { + char *fault_str = xmlnode_to_str(fault, NULL); + purple_debug_error("msn", "Operation {%s} Failed, SOAP Fault was: %s\n", + msn_contact_operation_str(state->action), fault_str); + g_free(fault_str); + return; + } purple_debug_info("msn", "Delete contact successful\n"); @@ -1140,8 +1225,8 @@ contact_id_xml = g_strdup_printf(MSN_CONTACT_ID_XML, user->uid); purple_debug_info("msn", "Deleting contact with contactId: %s\n", user->uid); } else { - contact_id_xml = g_strdup_printf(MSN_CONTACT_XML, user->passport); - purple_debug_info("msn", "Deleting contact with passport: %s\n", user->passport); + purple_debug_info("msn", "Unable to delete contact %s without a ContactId\n", user->passport); + return; } state = msn_callback_state_new(session); @@ -1165,6 +1250,17 @@ gpointer data) { MsnCallbackState *state = data; + xmlnode *fault; + + /* We don't know how to respond to this faultcode, so log it */ + fault = xmlnode_get_child(resp->xml, "Body/Fault"); + if (fault != NULL) { + char *fault_str = xmlnode_to_str(fault, NULL); + purple_debug_error("msn", "Operation {%s} Failed, SOAP Fault was: %s\n", + msn_contact_operation_str(state->action), fault_str); + g_free(fault_str); + return; + } if (msn_userlist_rem_buddy_from_group(state->session->userlist, state->who, state->old_group_name)) { @@ -1235,6 +1331,19 @@ msn_update_contact_read_cb(MsnSoapMessage *req, MsnSoapMessage *resp, gpointer data) { + MsnCallbackState *state = (MsnCallbackState *)data; + xmlnode *fault; + + /* We don't know how to respond to this faultcode, so log it */ + fault = xmlnode_get_child(resp->xml, "Body/Fault"); + if (fault != NULL) { + char *fault_str = xmlnode_to_str(fault, NULL); + purple_debug_error("msn", "Operation {%s} Failed, SOAP Fault was: %s\n", + msn_contact_operation_str(state->action), fault_str); + g_free(fault_str); + return; + } + purple_debug_info("msn", "Contact updated successfully\n"); } @@ -1312,6 +1421,17 @@ { MsnCallbackState *state = data; MsnSession *session = state->session; + xmlnode *fault; + + /* We don't know how to respond to this faultcode, so log it */ + fault = xmlnode_get_child(resp->xml, "Body/Fault"); + if (fault != NULL) { + char *fault_str = xmlnode_to_str(fault, NULL); + purple_debug_error("msn", "Operation {%s} Failed, SOAP Fault was: %s\n", + msn_contact_operation_str(state->action), fault_str); + g_free(fault_str); + return; + } purple_debug_info("msn", "Contact %s deleted successfully from %s list on server!\n", state->who, MsnMemberRole[state->list_id]); @@ -1339,10 +1459,13 @@ const gchar *passport, const MsnListId list) { gchar *body = NULL, *member = NULL; + const char *type = "PassportMember"; + gchar *federate = NULL; MsnSoapPartnerScenario partner_scenario; MsnUser *user; g_return_if_fail(session != NULL); + g_return_if_fail(session->userlist != NULL); g_return_if_fail(passport != NULL); g_return_if_fail(list < 5); @@ -1354,21 +1477,27 @@ msn_callback_state_set_list_id(state, list); msn_callback_state_set_who(state, passport); + user = msn_userlist_find_user(session->userlist, passport); + if (user && user->networkid != MSN_NETWORK_PASSPORT) { + type = "EmailMember"; + federate = g_strdup_printf(MSN_MEMBER_FEDERATED_ANNOTATION_XML, + user->networkid); + } + if (list == MSN_LIST_PL) { - g_return_if_fail(session->userlist != NULL); - - user = msn_userlist_find_user(session->userlist, passport); - partner_scenario = MSN_PS_CONTACT_API; - member = g_strdup_printf(MSN_MEMBER_MEMBERSHIPID_XML, user->membership_id[MSN_LIST_PL]); + member = g_strdup_printf(MSN_MEMBER_MEMBERSHIPID_XML, + type, user->membership_id[MSN_LIST_PL], + federate ? federate : ""); } else { /* list == MSN_LIST_AL || list == MSN_LIST_BL */ partner_scenario = MSN_PS_BLOCK_UNBLOCK; - - member = g_strdup_printf(MSN_MEMBER_PASSPORT_XML, passport); + member = g_strdup_printf(MSN_MEMBER_PASSPORT_XML, + type, passport, + federate ? federate : ""); } - body = g_strdup_printf(MSN_CONTACT_DELECT_FROM_LIST_TEMPLATE, + body = g_strdup_printf(MSN_CONTACT_DELETE_FROM_LIST_TEMPLATE, MsnSoapPartnerScenarioText[partner_scenario], MsnMemberRole[list], member); @@ -1378,6 +1507,7 @@ state->cb = msn_del_contact_from_list_read_cb; msn_contact_request(state); + g_free(federate); g_free(member); g_free(body); } @@ -1387,8 +1517,18 @@ gpointer data) { MsnCallbackState *state = data; + xmlnode *fault; - g_return_if_fail(state != NULL); + /* We don't know how to respond to this faultcode, so log it */ + fault = xmlnode_get_child(resp->xml, "Body/Fault"); + if (fault != NULL) { + char *fault_str = xmlnode_to_str(fault, NULL); + purple_debug_error("msn", "Operation {%s} Failed, SOAP Fault was: %s\n", + msn_contact_operation_str(state->action), fault_str); + g_free(fault_str); + return; + } + g_return_if_fail(state->session != NULL); purple_debug_info("msn", "Contact %s added successfully to %s list on server!\n", state->who, MsnMemberRole[state->list_id]); @@ -1415,7 +1555,10 @@ const gchar *passport, const MsnListId list) { gchar *body = NULL, *member = NULL; + const char *type = "PassportMember"; + gchar *federate = NULL; MsnSoapPartnerScenario partner_scenario; + MsnUser *user; g_return_if_fail(session != NULL); g_return_if_fail(passport != NULL); @@ -1429,9 +1572,16 @@ msn_callback_state_set_list_id(state, list); msn_callback_state_set_who(state, passport); - partner_scenario = (list == MSN_LIST_RL) ? MSN_PS_CONTACT_API : MSN_PS_BLOCK_UNBLOCK; + user = msn_userlist_find_user(session->userlist, passport); + if (user && user->networkid != MSN_NETWORK_PASSPORT) { + type = "EmailMember"; + federate = g_strdup_printf(MSN_MEMBER_FEDERATED_ANNOTATION_XML, + user->networkid); + } - member = g_strdup_printf(MSN_MEMBER_PASSPORT_XML, state->who); + partner_scenario = (list == MSN_LIST_RL) ? MSN_PS_CONTACT_API : MSN_PS_BLOCK_UNBLOCK; + member = g_strdup_printf(MSN_MEMBER_PASSPORT_XML, + type, state->who, federate ? federate : ""); body = g_strdup_printf(MSN_CONTACT_ADD_TO_LIST_TEMPLATE, MsnSoapPartnerScenarioText[partner_scenario], @@ -1443,6 +1593,7 @@ state->cb = msn_add_contact_to_list_read_cb; msn_contact_request(state); + g_free(federate); g_free(member); g_free(body); } @@ -1482,6 +1633,17 @@ MsnCallbackState *state = data; MsnSession *session; MsnUserList *userlist; + xmlnode *fault; + + /* We don't know how to respond to this faultcode, so log it */ + fault = xmlnode_get_child(resp->xml, "Body/Fault"); + if (fault != NULL) { + char *fault_str = xmlnode_to_str(fault, NULL); + purple_debug_error("msn", "Operation {%s} Failed, SOAP Fault was: %s\n", + msn_contact_operation_str(state->action), fault_str); + g_free(fault_str); + return; + } purple_debug_info("msn", "Group request successful.\n"); @@ -1661,3 +1823,4 @@ g_free(escaped_group_name); g_free(body); } +
--- a/libpurple/protocols/msn/contact.h Wed Dec 10 02:44:03 2008 +0000 +++ b/libpurple/protocols/msn/contact.h Wed Dec 10 06:58:10 2008 +0000 @@ -211,6 +211,27 @@ "</contactInfo>"\ "</Contact>" +#define MSN_CONTACT_ID_XML \ + "<Contact>"\ + "<contactId>%s</contactId>"\ + "</Contact>" + +#define MSN_CONTACT_EMAIL_XML \ + "<Contact>"\ + "<contactInfo>"\ + "<emails>"\ + "<ContactEmail>"\ + "<contactEmailType>%s</contactEmailType>"\ + "<email>%s</email>"\ + "<isMessengerEnabled>true</isMessengerEnabled>"\ + "<Capability>%d</Capability>"\ + "<MessengerEnabledExternally>false</MessengerEnabledExternally>"\ + "<propertiesChanged/>"\ + "</ContactEmail>"\ + "</emails>"\ + "</contactInfo>"\ + "</Contact>" + #define MSN_ADD_CONTACT_TEMPLATE "<?xml version=\"1.0\" encoding=\"utf-8\"?>"\ "<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\""\ " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""\ @@ -275,7 +296,6 @@ /* Delete a contact from the Contact List */ #define MSN_CONTACT_DEL_SOAP_ACTION "http://www.msn.com/webservices/AddressBook/ABContactDelete" -#define MSN_CONTACT_ID_XML "<Contact><contactId>%s</contactId></Contact>" #define MSN_DEL_CONTACT_TEMPLATE "<?xml version=\"1.0\" encoding=\"utf-8\"?>"\ "<soap:Envelope"\ " xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\""\ @@ -376,22 +396,32 @@ #define MSN_DELETE_MEMBER_FROM_LIST_SOAP_ACTION "http://www.msn.com/webservices/AddressBook/DeleteMember" #define MSN_MEMBER_PASSPORT_XML \ - "<Member xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:type=\"PassportMember\">"\ + "<Member xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:type=\"%s\">"\ "<Type>Passport</Type>"\ "<State>Accepted</State>"\ "<PassportName>%s</PassportName>"\ + "%s"\ "</Member>" #define MSN_MEMBER_MEMBERSHIPID_XML \ - "<Member xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:type=\"PassportMember\">"\ + "<Member xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:type=\"%s\">"\ "<Type>Passport</Type>"\ "<MembershipId>%u</MembershipId>"\ "<State>Accepted</State>"\ + "%s"\ "</Member>" +#define MSN_MEMBER_FEDERATED_ANNOTATION_XML \ + "<Annotations>"\ + "<Annotation>"\ + "<Name>MSN.IM.BuddyType</Name>"\ + "<Value>%02d:</Value>"\ + "</Annotation>"\ + "</Annotations>" + /* first delete contact from allow list */ -#define MSN_CONTACT_DELECT_FROM_LIST_TEMPLATE "<?xml version=\"1.0\" encoding=\"utf-8\"?>"\ +#define MSN_CONTACT_DELETE_FROM_LIST_TEMPLATE "<?xml version=\"1.0\" encoding=\"utf-8\"?>"\ "<soap:Envelope"\ " xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\""\ " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""\
--- a/libpurple/protocols/msn/msn.c Wed Dec 10 02:44:03 2008 +0000 +++ b/libpurple/protocols/msn/msn.c Wed Dec 10 06:58:10 2008 +0000 @@ -1443,21 +1443,18 @@ purple_debug_info("msn", "msn_add_buddy: %s\n", who); #endif -#if 0 - /* Which is the max? */ - if (session->fl_users_count >= 150) - { - purple_debug_info("msn", "Too many buddies\n"); - /* Buddy list full */ - /* TODO: purple should be notified of this */ - return; - } -#endif - /* XXX - Would group ever be NULL here? I don't think so... * shx: Yes it should; MSN handles non-grouped buddies, and this is only * internal. */ - msn_userlist_add_buddy(userlist, who, group ? group->name : NULL); + if (msn_userlist_find_user(userlist, who) != NULL) { + /* We already know this buddy. This function takes care of users + already in the list and stuff... */ + msn_userlist_add_buddy(userlist, who, group ? group->name : NULL); + } else { + /* We need to check the network for this buddy first */ + msn_userlist_save_pending_buddy(userlist, who, group ? group->name : NULL); + msn_notification_send_fqy(session, who); + } } static void
--- a/libpurple/protocols/msn/notification.c Wed Dec 10 02:44:03 2008 +0000 +++ b/libpurple/protocols/msn/notification.c Wed Dec 10 06:58:10 2008 +0000 @@ -849,10 +849,35 @@ fqy_cmd_post(MsnCmdProc *cmdproc, MsnCommand *cmd, char *payload, size_t len) { - purple_debug_info("msn", "FQY payload:\n%s\n", payload); - g_return_if_fail(cmdproc->session != NULL); -/* msn_notification_post_adl(cmdproc, payload, len); */ -/* msn_get_address_book(cmdproc->session, MSN_AB_SAVE_CONTACT, NULL, NULL); */ + MsnUserList *userlist; + xmlnode *ml, *d, *c; + const char *domain; + const char *local; + const char *type; + char *passport; + MsnNetwork network = MSN_NETWORK_PASSPORT; + + userlist = cmdproc->session->userlist; + + /* FQY response: + <ml><d n="domain.com"><c n="local-node" t="network" /></d></ml> */ + ml = xmlnode_from_str(payload, len); + d = xmlnode_get_child(ml, "d"); + c = xmlnode_get_child(d, "c"); + domain = xmlnode_get_attrib(d, "n"); + local = xmlnode_get_attrib(c, "n"); + type = xmlnode_get_attrib(c, "t"); + + passport = g_strdup_printf("%s@%s", local, domain); + + if (type != NULL) + network = (MsnNetwork)strtoul(type, NULL, 10); + purple_debug_info("msn", "FQY response says %s is from network %d\n", + passport, network); + msn_userlist_add_pending_buddy(userlist, passport, network); + + g_free(passport); + xmlnode_free(ml); } static void
--- a/libpurple/protocols/msn/user.c Wed Dec 10 02:44:03 2008 +0000 +++ b/libpurple/protocols/msn/user.c Wed Dec 10 06:58:10 2008 +0000 @@ -340,6 +340,20 @@ } void +msn_user_set_pending_group(MsnUser *user, const char *group) +{ + user->pending_group = g_strdup(group); +} + +char * +msn_user_remove_pending_group(MsnUser *user) +{ + char *group = user->pending_group; + user->pending_group = NULL; + return group; +} + +void msn_user_set_home_phone(MsnUser *user, const char *number) { g_return_if_fail(user != NULL);
--- a/libpurple/protocols/msn/user.h Wed Dec 10 02:44:03 2008 +0000 +++ b/libpurple/protocols/msn/user.h Wed Dec 10 06:58:10 2008 +0000 @@ -91,6 +91,7 @@ gboolean mobile; /**< Signed up with MSN Mobile. */ GList *group_ids; /**< The group IDs. */ + char *pending_group; /**< A pending group to add. */ MsnObject *msnobj; /**< The user's MSN Object. */ @@ -213,6 +214,23 @@ void msn_user_remove_group_id(MsnUser *user, const char * id); /** + * Sets the pending group for a user. + * + * @param user The user. + * @param group The group name. + */ +void msn_user_set_pending_group(MsnUser *user, const char *group); + +/** + * Removes the pending group from a user. + * + * @param user The user. + * + * @return Returns the pending group name. + */ +char *msn_user_remove_pending_group(MsnUser *user); + +/** * Sets the home phone number for a user. * * @param user The user.
--- a/libpurple/protocols/msn/userlist.c Wed Dec 10 02:44:03 2008 +0000 +++ b/libpurple/protocols/msn/userlist.c Wed Dec 10 06:58:10 2008 +0000 @@ -184,10 +184,6 @@ { msn_user_add_group_id(user, group_id); } - else - { - /* session->sync->fl_users_count++; */ - } } else if (list_id == MSN_LIST_AL) { @@ -253,10 +249,6 @@ msn_user_remove_group_id(user, group_id); return; } - else - { - /* session->sync->fl_users_count--; */ - } } else if (list_id == MSN_LIST_AL) { @@ -756,6 +748,62 @@ msn_add_contact_to_group(userlist->session, state, who, group_id); } +/* + * Save a buddy address/group until we get back response from FQY + */ +void +msn_userlist_save_pending_buddy(MsnUserList *userlist, + const char *who, + const char *group_name) +{ + MsnUser *user; + + g_return_if_fail(userlist != NULL); + + user = msn_user_new(userlist, who, NULL); + msn_user_set_pending_group(user, group_name); + msn_user_set_network(user, MSN_NETWORK_UNKNOWN); + userlist->pending = g_list_prepend(userlist->pending, user); +} + +/* + * Actually adds a buddy once we have the response from FQY + */ +void +msn_userlist_add_pending_buddy(MsnUserList *userlist, + const char *who, + /*MsnNetwork*/ int network) +{ + MsnUser *user = NULL; + GList *l; + char *group; + + for (l = userlist->pending; l != NULL; l = l->next) + { + user = (MsnUser *)l->data; + + if (!g_strcasecmp(who, user->passport)) { + userlist->pending = g_list_delete_link(userlist->pending, l); + break; + } + } + + if (user == NULL) { + purple_debug_error("msn", "Attempting to add a pending user that does not exist.\n"); + return; + } + + /* Bit of a hack, but by adding to userlist now, the rest of the code + * will know what network to use. + */ + msn_user_set_network(user, network); + msn_userlist_add_user(userlist, user); + + group = msn_user_remove_pending_group(user); + msn_userlist_add_buddy(userlist, who, group); + g_free(group); +} + void msn_userlist_add_buddy_to_list(MsnUserList *userlist, const char *who, MsnListId list_id)
--- a/libpurple/protocols/msn/userlist.h Wed Dec 10 02:44:03 2008 +0000 +++ b/libpurple/protocols/msn/userlist.h Wed Dec 10 06:58:10 2008 +0000 @@ -47,13 +47,12 @@ GList *users; /* Contains MsnUsers */ GList *groups; /* Contains MsnGroups */ + GList *pending; /* MsnUsers pending addition (waiting for FQY response) */ GQueue *buddy_icon_requests; int buddy_icon_window; guint buddy_icon_request_timer; - int fl_users_count; - }; gboolean msn_userlist_user_is_in_group(MsnUser *user, const char * group_id); @@ -93,6 +92,12 @@ void msn_userlist_rem_buddy(MsnUserList *userlist, const char *who); void msn_userlist_add_buddy(MsnUserList *userlist, const char *who, const char *group_name); +void msn_userlist_save_pending_buddy(MsnUserList *userlist, + const char *who, + const char *group_name); +void msn_userlist_add_pending_buddy(MsnUserList *userlist, + const char *who, + /*MsnNetwork*/ int network); void msn_userlist_move_buddy(MsnUserList *userlist, const char *who, const char *old_group_name, const char *new_group_name);