# HG changeset patch # User Elliott Sales de Andrade # Date 1235718800 0 # Node ID fd5eedf131b42a7b3f62fe904366d2ab49f7ebf2 # Parent 14b927f45ec53168cbf265bd1ee88b9c4feb9081 Generalize the FQY command so it can be used by different callbacks based on the place that called it. Then automatically call an FQY when sending the buddy list ADL's for a buddy with an unknown network. Then we can send a corrected ADL later with the network from the FQY. This should make it easier for people with OCS/Yahoo contacts that were added incorrectly by previous versions, as they shouldn't need to mess with their address book outside of Pidgin (but if there are multiple buddy copies, that may need fixing externally). I should probably figure out how to permanently fix the Membership lists, eventually. References #6755. References #3322 diff -r 14b927f45ec5 -r fd5eedf131b4 libpurple/protocols/msn/msn.c --- a/libpurple/protocols/msn/msn.c Thu Feb 26 19:47:58 2009 +0000 +++ b/libpurple/protocols/msn/msn.c Fri Feb 27 07:13:20 2009 +0000 @@ -1466,9 +1466,18 @@ what to do with users already in the list and stuff... */ msn_userlist_add_buddy(userlist, who, group ? group->name : NULL); } else { + char **tokens; + char *fqy; /* 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); + tokens = g_strsplit(who, "@", 2); + fqy = g_strdup_printf("", + tokens[1], + tokens[0]); + msn_notification_send_fqy(session, fqy, strlen(fqy), + (MsnFqyCb)msn_userlist_add_pending_buddy); + g_free(fqy); + g_strfreev(tokens); } } diff -r 14b927f45ec5 -r fd5eedf131b4 libpurple/protocols/msn/notification.c --- a/libpurple/protocols/msn/notification.c Thu Feb 26 19:47:58 2009 +0000 +++ b/libpurple/protocols/msn/notification.c Fri Feb 27 07:13:20 2009 +0000 @@ -544,17 +544,16 @@ } /*find a domain Node*/ - for(d_node = xmlnode_get_child(mlNode,"d"); d_node; d_node = xmlnode_get_next_twin(d_node)) - { + for (d_node = xmlnode_get_child(mlNode, "d"); d_node; + d_node = xmlnode_get_next_twin(d_node)) { const char *attr = xmlnode_get_attrib(d_node,"n"); if (attr == NULL) continue; - if (!strcmp(attr,domain)) + if (!strcmp(attr, domain)) break; } - if(d_node == NULL) - { + if (d_node == NULL) { /*domain not found, create a new domain Node*/ purple_debug_info("msn", "Didn't find existing domain node, adding one.\n"); d_node = xmlnode_new("d"); @@ -566,20 +565,18 @@ c_node = xmlnode_new("c"); xmlnode_set_attrib(c_node, "n", email); - purple_debug_info("msn", "list_op: %d\n", list_op); - g_snprintf(fmt_str, sizeof(fmt_str), "%d", list_op); - xmlnode_set_attrib(c_node, "l", fmt_str); + if (list_op != 0) { + purple_debug_info("msn", "list_op: %d\n", list_op); + g_snprintf(fmt_str, sizeof(fmt_str), "%d", list_op); + xmlnode_set_attrib(c_node, "l", fmt_str); + } - if (networkId != MSN_NETWORK_UNKNOWN) + if (networkId != MSN_NETWORK_UNKNOWN) { g_snprintf(fmt_str, sizeof(fmt_str), "%d", networkId); - else if (msn_user_is_yahoo(session->account, passport)) - g_snprintf(fmt_str, sizeof(fmt_str), "%d", MSN_NETWORK_YAHOO); - else - g_snprintf(fmt_str, sizeof(fmt_str), "%d", MSN_NETWORK_PASSPORT); - - /*mobile*/ - /*type_str = g_strdup_printf("4");*/ - xmlnode_set_attrib(c_node, "t", fmt_str); + /*mobile*/ + /*type_str = g_strdup_printf("4");*/ + xmlnode_set_attrib(c_node, "t", fmt_str); + } xmlnode_insert_child(d_node, c_node); @@ -596,6 +593,48 @@ msn_cmdproc_send_trans(cmdproc, trans); } +void +msn_notification_send_fqy(MsnSession *session, + const char *payload, int payload_len, + MsnFqyCb cb) +{ + MsnTransaction *trans; + MsnCmdProc *cmdproc; + + cmdproc = session->notification->cmdproc; + + trans = msn_transaction_new(cmdproc, "FQY", "%d", payload_len); + msn_transaction_set_payload(trans, payload, payload_len); + msn_transaction_set_data(trans, cb); + msn_cmdproc_send_trans(cmdproc, trans); +} + +static void +update_contact_network(MsnSession *session, const char *passport, MsnNetwork network) +{ + MsnUser *user = msn_userlist_find_user(session->userlist, passport); + /* TODO: Also figure out how to update membership lists */ + if (user) { + xmlnode *adl_node; + char *payload; + int payload_len; + + msn_user_set_network(user, network); + + adl_node = xmlnode_new("ml"); + xmlnode_set_attrib(adl_node, "l", "1"); + msn_add_contact_xml(session, adl_node, passport, + user->list_op & MSN_LIST_OP_MASK, network); + payload = xmlnode_to_str(adl_node, &payload_len); + msn_notification_post_adl(session->notification->cmdproc, payload, payload_len); + + } else { + purple_debug_error("msn", + "Got FQY update for unkwown user %s on network %d.\n", + passport, network); + } +} + /*dump contact info to NS*/ void msn_notification_dump_contact(MsnSession *session) @@ -603,14 +642,17 @@ MsnUser *user; GList *l; xmlnode *adl_node; + xmlnode *fqy_node; char *payload; int payload_len; int adl_count = 0; + int fqy_count = 0; const char *display_name; adl_node = xmlnode_new("ml"); adl_node->child = NULL; xmlnode_set_attrib(adl_node, "l", "1"); + fqy_node = xmlnode_new("ml"); /*get the userlist*/ for (l = session->userlist->users; l != NULL; l = l->next) { @@ -635,36 +677,63 @@ msn_userlist_rem_buddy_from_list(session->userlist, user->passport, MSN_LIST_AL); } - msn_add_contact_xml(session, adl_node, user->passport, - user->list_op & MSN_LIST_OP_MASK, user->networkid); - - /* each ADL command may contain up to 150 contacts */ - if (++adl_count % 150 == 0 || l->next == NULL) { - payload = xmlnode_to_str(adl_node,&payload_len); + if (user->networkid != MSN_NETWORK_UNKNOWN) { + msn_add_contact_xml(session, adl_node, user->passport, + user->list_op & MSN_LIST_OP_MASK, user->networkid); - msn_notification_post_adl(session->notification->cmdproc, - payload, payload_len); + /* each ADL command may contain up to 150 contacts */ + if (++adl_count % 150 == 0) { + payload = xmlnode_to_str(adl_node, &payload_len); - g_free(payload); - xmlnode_free(adl_node); + msn_notification_post_adl(session->notification->cmdproc, + payload, payload_len); - if (l->next) { + g_free(payload); + xmlnode_free(adl_node); + adl_node = xmlnode_new("ml"); adl_node->child = NULL; xmlnode_set_attrib(adl_node, "l", "1"); } + } else { + msn_add_contact_xml(session, fqy_node, user->passport, + 0, user->networkid); + + /* each FQY command may contain up to 150 contacts, probably */ + if (++fqy_count % 150 == 0) { + payload = xmlnode_to_str(fqy_node, &payload_len); + + msn_notification_send_fqy(session, payload, payload_len, + update_contact_network); + + g_free(payload); + xmlnode_free(fqy_node); + fqy_node = xmlnode_new("ml"); + } } } - if (adl_count == 0) { - payload = xmlnode_to_str(adl_node,&payload_len); + /* Send the rest, or just an empty one to let the server set us online */ + if (adl_count == 0 || adl_count % 150 != 0) { + payload = xmlnode_to_str(adl_node, &payload_len); msn_notification_post_adl(session->notification->cmdproc, payload, payload_len); g_free(payload); - xmlnode_free(adl_node); } + if (fqy_count % 150 != 0) { + payload = xmlnode_to_str(fqy_node, &payload_len); + + msn_notification_send_fqy(session, payload, payload_len, + update_contact_network); + + g_free(payload); + } + + xmlnode_free(adl_node); + xmlnode_free(fqy_node); + display_name = purple_connection_get_display_name(session->account->gc); if (display_name && strcmp(display_name, @@ -674,30 +743,6 @@ } -/*Post FQY to NS,Inform add a Yahoo User*/ -void -msn_notification_send_fqy(MsnSession *session, const char *passport) -{ - MsnTransaction *trans; - MsnCmdProc *cmdproc; - char* email,*domain,*payload; - char **tokens; - - cmdproc = session->notification->cmdproc; - - tokens = g_strsplit(passport, "@", 2); - email = tokens[0]; - domain = tokens[1]; - - payload = g_strdup_printf("", domain, email); - trans = msn_transaction_new(cmdproc, "FQY","%" G_GSIZE_FORMAT, strlen(payload)); - msn_transaction_set_payload(trans, payload, strlen(payload)); - msn_cmdproc_send_trans(cmdproc, trans); - - g_free(payload); - g_strfreev(tokens); -} - static void blp_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) { @@ -861,7 +906,7 @@ fqy_cmd_post(MsnCmdProc *cmdproc, MsnCommand *cmd, char *payload, size_t len) { - MsnUserList *userlist; + MsnSession *session; xmlnode *ml, *d, *c; const char *domain; const char *local; @@ -869,26 +914,37 @@ char *passport; MsnNetwork network = MSN_NETWORK_PASSPORT; - userlist = cmdproc->session->userlist; + session = cmdproc->session; /* FQY response: */ 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"); + for (d = xmlnode_get_child(ml, "d"); + d != NULL; + d = xmlnode_get_next_twin(d)) { + domain = xmlnode_get_attrib(d, "n"); + for (c = xmlnode_get_child(d, "c"); + c != NULL; + c = xmlnode_get_next_twin(c)) { + local = xmlnode_get_attrib(c, "n"); + type = xmlnode_get_attrib(c, "t"); - passport = g_strdup_printf("%s@%s", local, domain); + 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); + if (type != NULL) + network = (MsnNetwork)strtoul(type, NULL, 10); + else + network = MSN_NETWORK_PASSPORT; - g_free(passport); + purple_debug_info("msn", "FQY response says %s is from network %d\n", + passport, network); + if (cmd->trans->data) + ((MsnFqyCb)cmd->trans->data)(session, passport, network); + + g_free(passport); + } + } + xmlnode_free(ml); } diff -r 14b927f45ec5 -r fd5eedf131b4 libpurple/protocols/msn/notification.h --- a/libpurple/protocols/msn/notification.h Thu Feb 26 19:47:58 2009 +0000 +++ b/libpurple/protocols/msn/notification.h Fri Feb 27 07:13:20 2009 +0000 @@ -58,6 +58,8 @@ gboolean in_use; }; +typedef void (*MsnFqyCb)(MsnSession *session, const char *passport, MsnNetwork network); + #include "state.h" void uum_send_msg(MsnSession *session,MsnMessage *msg); @@ -69,7 +71,9 @@ void msn_notification_rem_buddy_from_list(MsnNotification *notification, MsnListId list_id, MsnUser *user); -void msn_notification_send_fqy(MsnSession *session, const char *passport); +void msn_notification_send_fqy(MsnSession *session, + const char *payload, int payload_len, + MsnFqyCb cb); MsnNotification *msn_notification_new(MsnSession *session); void msn_notification_destroy(MsnNotification *notification); diff -r 14b927f45ec5 -r fd5eedf131b4 libpurple/protocols/msn/userlist.c --- a/libpurple/protocols/msn/userlist.c Thu Feb 26 19:47:58 2009 +0000 +++ b/libpurple/protocols/msn/userlist.c Fri Feb 27 07:13:20 2009 +0000 @@ -770,10 +770,11 @@ * Actually adds a buddy once we have the response from FQY */ void -msn_userlist_add_pending_buddy(MsnUserList *userlist, +msn_userlist_add_pending_buddy(MsnSession *session, const char *who, /*MsnNetwork*/ int network) { + MsnUserList *userlist = session->userlist; MsnUser *user = NULL; MsnUser *user2; GList *l; diff -r 14b927f45ec5 -r fd5eedf131b4 libpurple/protocols/msn/userlist.h --- a/libpurple/protocols/msn/userlist.h Thu Feb 26 19:47:58 2009 +0000 +++ b/libpurple/protocols/msn/userlist.h Fri Feb 27 07:13:20 2009 +0000 @@ -95,7 +95,7 @@ void msn_userlist_save_pending_buddy(MsnUserList *userlist, const char *who, const char *group_name); -void msn_userlist_add_pending_buddy(MsnUserList *userlist, +void msn_userlist_add_pending_buddy(MsnSession *session, const char *who, /*MsnNetwork*/ int network); void msn_userlist_move_buddy(MsnUserList *userlist, const char *who,