# HG changeset patch # User Carlos Silva # Date 1188583955 0 # Node ID 98613886411a872fc0b01e232680bc45bf1cfc93 # Parent 115290ce3b923b151a94b47a64e954c3ea72a564 Handle special cases in buddy/group management (wrt MSN_INDIVIDUALS_GROUP and MSN_NON_IM_GROUP). Deprecate now unused MSNP protocol commands. diff -r 115290ce3b92 -r 98613886411a libpurple/protocols/msn/contact.c --- a/libpurple/protocols/msn/contact.c Tue Aug 28 05:21:17 2007 +0000 +++ b/libpurple/protocols/msn/contact.c Fri Aug 31 18:12:35 2007 +0000 @@ -31,10 +31,11 @@ #include "group.h" -const char *MsnAddressBookActionText[] = +const char *MsnSoapPartnerScenarioText[] = { "Initial", - "ContactSave" + "ContactSave", + "MessengerPendingList" }; @@ -175,7 +176,7 @@ g_return_if_fail(session != NULL); /*login ok!We can retrieve the contact list*/ -// msn_get_contact_list(contact,NULL); +// msn_get_contact_list(contact, MSN_PS_INITIAL, NULL); } /*get MSN member role utility*/ @@ -223,7 +224,7 @@ g_return_if_fail(contact != NULL); purple_debug_info("MSN AddressBook", "Address Book successfully created!\n"); - msn_get_address_book(contact, MSN_AB_INITIAL, NULL, NULL); + msn_get_address_book(contact, MSN_PS_INITIAL, NULL, NULL); // msn_soap_free_read_buf(soapconn); return; @@ -332,7 +333,7 @@ } } xmlnode_free(node); - msn_get_contact_list(contact, NULL); + msn_get_contact_list(contact, MSN_PS_INITIAL, NULL); return; } @@ -345,7 +346,7 @@ * has too old a copy for us to do a delta sync */ xmlnode_free(node); - msn_get_contact_list(contact, NULL); + msn_get_contact_list(contact, MSN_PS_INITIAL, NULL); return; } purple_debug_info("MSNCL","FindMembershipResponse @ %p: Name: '%s'\n",response,response->name); @@ -496,9 +497,9 @@ /* XXX: this should be enabled when we can correctly do partial syncs with the server. Currently we need to retrieve the whole list to detect sync issues */ - msn_get_address_book(contact, MSN_AB_INITIAL, abLastChange, dynamicItemLastChange); + msn_get_address_book(contact, MSN_PS_INITIAL, abLastChange, dynamicItemLastChange); #else - msn_get_address_book(contact, MSN_AB_INITIAL, NULL, NULL); + msn_get_address_book(contact, MSN_PS_INITIAL, NULL, NULL); #endif msn_soap_free_read_buf(soapconn); } @@ -515,7 +516,7 @@ /*SOAP get contact list*/ void -msn_get_contact_list(MsnContact * contact, const char *update_time) +msn_get_contact_list(MsnContact * contact, const MsnSoapPartnerScenario partner_scenario, const char *update_time) { MsnSoapReq *soap_request; char *body = NULL; @@ -528,7 +529,7 @@ } else { update_str = g_strdup(""); } - body = g_strdup_printf(MSN_GET_CONTACT_TEMPLATE, update_str); + body = g_strdup_printf(MSN_GET_CONTACT_TEMPLATE, MsnSoapPartnerScenarioText[partner_scenario], update_str); g_free(update_str); soap_request = msn_soap_request_new(MSN_CONTACT_SERVER, @@ -836,7 +837,7 @@ purple_debug_misc("MSN AddressBook", "Got the Address Book!\n"); if ( msn_parse_addressbook(contact) ) { - msn_soap_free_read_buf(soapconn); + //msn_soap_free_read_buf(soapconn); if (!session->logged_in) { msn_send_privacy(session->account->gc); @@ -869,11 +870,11 @@ /*get the address book*/ void -msn_get_address_book(MsnContact *contact, const MsnAddressBookAction abaction, const char *LastChanged, const char *dynamicItemLastChange) +msn_get_address_book(MsnContact *contact, const MsnSoapPartnerScenario partner_scenario, const char *LastChanged, const char *dynamicItemLastChange) { MsnSoapReq *soap_request; char *body = NULL; - char *ab_update_str,*update_str, *partner_scenario; + char *ab_update_str,*update_str; purple_debug_misc("MSN AddressBook","Getting Address Book\n"); @@ -891,13 +892,9 @@ } g_free(ab_update_str); - partner_scenario = g_strdup(MsnAddressBookActionText[abaction]); - purple_debug_misc("MSN CL", "Get Address Book PartnerScenario parameter: %s\n", partner_scenario); - - body = g_strdup_printf(MSN_GET_ADDRESS_TEMPLATE, partner_scenario, update_str); + body = g_strdup_printf(MSN_GET_ADDRESS_TEMPLATE, MsnSoapPartnerScenarioText[partner_scenario], update_str); g_free(update_str); - g_free(partner_scenario); soap_request = msn_soap_request_new(MSN_CONTACT_SERVER, MSN_ADDRESS_BOOK_POST_URL,MSN_GET_ADDRESS_SOAP_ACTION, @@ -909,15 +906,13 @@ g_free(body); } -/* We don't need this as libpurple doesn't support ungroupped buddies, so we - * can add buddies directly to a group with msn_add_contact_to_group() */ -#if 0 static void msn_add_contact_read_cb(gpointer data, gint source, PurpleInputCondition cond) { MsnSoapConn * soapconn = data; MsnCallbackState *state = NULL; MsnUserList *userlist; + MsnUser *user; g_return_if_fail(soapconn->data_cb != NULL); g_return_if_fail(soapconn->session != NULL); @@ -939,17 +934,11 @@ } msn_notification_send_fqy(soapconn->session, state->who); + user = msn_userlist_find_add_user(userlist, state->who, state->who); + msn_user_add_group_id(user, state->guid); - if (state->action & MSN_ADD_BUDDY_TO_GROUP) { - msn_add_contact_to_group(soapconn->session->contact, - state, - state->who, - state->guid); - } else { - msn_callback_state_free(state); - msn_soap_free_read_buf(soapconn); - } - + msn_callback_state_free(state); + msn_soap_free_read_buf(soapconn); } static void @@ -961,26 +950,29 @@ soapconn->read_cb = msn_add_contact_read_cb; } -/* add a Contact */ +/* add a Contact in MSN_INDIVIDUALS_GROUP */ void -msn_add_contact(MsnContact *contact, MsnCallbackState *state, const char *passport, const char *displayname) +msn_add_contact(MsnContact *contact, MsnCallbackState *state, const char *passport) { MsnSoapReq *soap_request; gchar *body = NULL; gchar *contact_xml = NULL; gchar *soap_action; -// gchar *escaped_displayname; +/* gchar *escaped_displayname; + + if (displayname != NULL) { + escaped_displayname = g_markup_decode_text(displayname, -1); + } else { + escaped_displayname = passport; + } + contact_xml = g_strdup_printf(MSN_XML_ADD_CONTACT, escaped_displayname, passport); +*/ purple_debug_info("MSNCL","Adding contact %s to contact list\n", passport); - // if (displayname != NULL) { - // escaped_displayname = g_markup_decode_text(displayname, -1); - // } else { - // escaped_displayname = passport; - // } - // contact_xml = g_strdup_printf(MSN_XML_ADD_CONTACT, escaped_displayname, passport); - - contact_xml = g_strdup_printf(MSN_CONTACT_XML, passport); +// if ( !strcmp(state->guid, MSN_INDIVIDUALS_GROUP_ID) ) { + contact_xml = g_strdup_printf(MSN_CONTACT_XML, passport); +// } body = g_strdup_printf(MSN_ADD_CONTACT_TEMPLATE, contact_xml); g_free(contact_xml); @@ -1000,7 +992,6 @@ g_free(soap_action); g_free(body); } -#endif static void msn_add_contact_to_group_read_cb(gpointer data, gint source, PurpleInputCondition cond) @@ -1066,7 +1057,27 @@ g_return_if_fail(contact->session->userlist != NULL); userlist = contact->session->userlist; - + + if (!strcmp(groupId, MSN_INDIVIDUALS_GROUP_ID) || !strcmp(groupId, MSN_NON_IM_GROUP_ID)) { + + user = msn_userlist_find_add_user(userlist, passport, passport); + + if (state->action & MSN_ADD_BUDDY) { + msn_add_contact(contact, state, passport); + return; + } + + if (state->action & MSN_MOVE_BUDDY) { + msn_user_add_group_id(user, groupId); + msn_del_contact_from_group(contact, passport, state->old_group_name); + } else { + msn_callback_state_free(state); + } + + return; + } + + purple_debug_info("MSNCL", "Adding user %s to group %s\n", passport, msn_userlist_find_group_name(userlist, groupId)); @@ -1209,7 +1220,12 @@ purple_debug_warning("MSN CL", "Unable to retrieve user from passport %s!\n", passport); return; } - + + if ( !strcmp(groupId, MSN_INDIVIDUALS_GROUP_ID) || !strcmp(groupId, MSN_NON_IM_GROUP_ID)) { + msn_user_remove_group_id(user, groupId); + return; + } + state = msn_callback_state_new(); msn_callback_state_set_who(state, passport); msn_callback_state_set_guid(state, groupId); @@ -1296,13 +1312,13 @@ /*block a Contact*/ void -msn_block_contact(MsnContact *contact,const char* membership_id) +msn_block_contact(MsnContact *contact, const char* membership_id) { MsnSoapReq *soap_request; char *body = NULL; purple_debug_info("MSNP14","msn block a contact...\n"); - body = g_strdup_printf(MSN_CONTACT_DELECT_FROM_ALLOW_TEMPLATE,membership_id); + body = g_strdup_printf(MSN_CONTACT_DELECT_FROM_ALLOW_TEMPLATE, membership_id); /*build SOAP and POST it*/ soap_request = msn_soap_request_new(MSN_CONTACT_SERVER, MSN_SHARE_POST_URL, @@ -1534,6 +1550,12 @@ purple_debug_info("MSN CL", "Group %s guid not found, returning.\n", group_name); return; } + + if ( !strcmp(guid, MSN_INDIVIDUALS_GROUP_ID) || !strcmp(guid, MSN_NON_IM_GROUP_ID) ) { + // add back PurpleGroup since it isn't really removed in the server? + return; + } + state = msn_callback_state_new(); msn_callback_state_set_action(state, MSN_DEL_GROUP); msn_callback_state_set_guid(state, guid); @@ -1573,10 +1595,16 @@ guid = msn_userlist_find_group_id(session->userlist, old_group_name); if (guid == NULL) return; - - msn_callback_state_set_action(state, MSN_RENAME_GROUP); + msn_callback_state_set_guid(state, guid); msn_callback_state_set_new_group_name(state, new_group_name); + + if ( !strcmp(guid, MSN_INDIVIDUALS_GROUP_ID) || !strcmp(guid, MSN_NON_IM_GROUP_ID) ) { + msn_add_group(session, state, new_group_name); + // XXX move every buddy there (we probably need to fix concurrent SOAP reqs first) + } + + msn_callback_state_set_action(state, MSN_RENAME_GROUP); /* escape group name's html special chars so it can safely be sent * in a XML SOAP request diff -r 115290ce3b92 -r 98613886411a libpurple/protocols/msn/contact.h --- a/libpurple/protocols/msn/contact.h Tue Aug 28 05:21:17 2007 +0000 +++ b/libpurple/protocols/msn/contact.h Fri Aug 31 18:12:35 2007 +0000 @@ -40,22 +40,22 @@ ""\ "09607671-1C32-421F-A6A6-CBFAA51AB5F4"\ "false"\ - "Initial"\ + "%s"\ ""\ ""\ - "false"\ + "false"\ ""\ ""\ ""\ ""\ ""\ - ""\ - "Messenger"\ - "Invitation"\ - "SocialNetwork"\ - "Space"\ - "Profile"\ - ""\ + ""\ + "Messenger"\ + "Invitation"\ + "SocialNetwork"\ + "Space"\ + "Profile"\ + ""\ ""\ "%s"\ ""\ @@ -128,32 +128,6 @@ "" -/* Send this shit after adding a contact (with ABGroupContactAdd or something) damnit! - - - - - 09607671-1C32-421F-A6A6-CBFAA51AB5F4 - false - ContactSave - - - false - - - - - 00000000-0000-0000-0000-000000000000 - Full - true - 2007-08-22T06:19:36.84-07:00 - Gleam - 0001-01-01T00:00:00 - - - -*/ - /*Gleams SOAP request template*/ #define MSN_GET_GLEAMS_SOAP_ACTION "http://www.msn.com/webservices/AddressBook/ABFindAll" #define MSN_GLEAMS_TEMPLATE ""\ @@ -342,9 +316,10 @@ typedef enum { - MSN_AB_INITIAL, - MSN_AB_SAVE_CONTACT -} MsnAddressBookAction; + MSN_PS_INITIAL, + MSN_PS_SAVE_CONTACT, + MSN_PS_PENDING_LIST +} MsnSoapPartnerScenario; /************************************************ @@ -366,15 +341,18 @@ MsnCallbackAction action); void msn_contact_connect(MsnContact *contact); -void msn_get_contact_list(MsnContact * contact, const char *update); -void msn_get_address_book(MsnContact *contact, MsnAddressBookAction abaction, +void msn_get_contact_list(MsnContact * contact, + const MsnSoapPartnerScenario partner_scenario, + const char *update); +void msn_get_address_book(MsnContact *contact, + const MsnSoapPartnerScenario partner_scenario, const char * update, const char * gupdate); /*contact SOAP Operation*/ void msn_update_contact(MsnContact *contact, const char* nickname); void msn_add_contact(MsnContact *contact, MsnCallbackState *state, - const char *passport, const char *displayname); + const char *passport); void msn_delete_contact(MsnContact *contact, const char *contactId); void msn_add_contact_to_group(MsnContact *contact, MsnCallbackState *state, diff -r 115290ce3b92 -r 98613886411a libpurple/protocols/msn/msn.c --- a/libpurple/protocols/msn/msn.c Tue Aug 28 05:21:17 2007 +0000 +++ b/libpurple/protocols/msn/msn.c Fri Aug 31 18:12:35 2007 +0000 @@ -1450,10 +1450,12 @@ session = gc->proto_data; cmdproc = session->notification->cmdproc; + purple_debug_info("MSN", "Remove group %s\n", group->name); /*we can't delete the default group*/ if(!strcmp(group->name, MSN_INDIVIDUALS_GROUP_NAME)|| !strcmp(group->name, MSN_NON_IM_GROUP_NAME)) { + purple_debug_info("MSN", "This group can't be removed, returning.\n"); return ; } diff -r 115290ce3b92 -r 98613886411a libpurple/protocols/msn/notification.c --- a/libpurple/protocols/msn/notification.c Tue Aug 28 05:21:17 2007 +0000 +++ b/libpurple/protocols/msn/notification.c Fri Aug 31 18:12:35 2007 +0000 @@ -593,7 +593,6 @@ char *email,*domain; char *list_op_str,*type_str; - purple_debug_info("::","msn_add_contact_xml()\n"); purple_debug_info("MSNP14","Passport: %s, type: %d\n", passport, type); tokens = g_strsplit(passport, "@", 2); email = tokens[0]; @@ -652,8 +651,7 @@ msn_notification_post_adl(MsnCmdProc *cmdproc, const char *payload, int payload_len) { MsnTransaction *trans; - purple_debug_info("::","msn_notification_post_adl()\n"); - purple_debug_info("MSNP14","Sending ADL with payload: %s\n", payload); + purple_debug_info("MSN Notification","Sending ADL with payload: %s\n", payload); trans = msn_transaction_new(cmdproc, "ADL","%d", strlen(payload)); msn_transaction_set_payload(trans, payload, strlen(payload)); msn_cmdproc_send_trans(cmdproc, trans); @@ -676,17 +674,6 @@ adl_node->child = NULL; xmlnode_set_attrib(adl_node, "l", "1"); - -/* if ( session->userlist->users == NULL ) { - 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); - } - else { */ /*get the userlist*/ for (l = session->userlist->users; l != NULL; l = l->next){ user = l->data; @@ -764,9 +751,79 @@ } static void +adl_cmd_parse(MsnCmdProc *cmdproc, MsnCommand *cmd, char *payload, + size_t len) +{ + xmlnode *root, *domain_node; + + purple_debug_misc("MSN Notification", "Parsing received ADL XML data\n"); + + g_return_if_fail(payload != NULL); + + root = xmlnode_from_str(payload, (gssize) len); + + if (root == NULL) { + purple_debug_info("MSN Notification", "Invalid XML!\n"); + return; + } + for (domain_node = xmlnode_get_child(root, "d"); domain_node; domain_node = xmlnode_get_next_twin(domain_node)) { + const gchar * domain = NULL; + xmlnode *contact_node = NULL; + + domain = xmlnode_get_attrib(domain_node, "n"); + + for (contact_node = xmlnode_get_child(domain_node, "c"); contact_node; contact_node = xmlnode_get_next_twin(contact_node)) { +// gchar *name = NULL, *friendlyname = NULL, *passport= NULL; + const gchar *list; + gint list_op = 0; + +// name = xmlnode_get_attrib(contact_node, "n"); + list = xmlnode_get_attrib(contact_node, "l"); + if (list != NULL) { + list_op = atoi(list); + } +// friendlyname = xmlnode_get_attrib(contact_node, "f"); + +// passport = g_strdup_printf("%s@%s", name, domain); + +// if (friendlyname != NULL) { +// decoded_friendlyname = g_strdup(purple_url_decode(friendlyname)); +// } else { +// decoded_friendlyname = g_strdup(passport); +// } + + if (list_op & MSN_LIST_RL_OP) { + /* someone is adding us */ +// got_new_entry(cmdproc->session->account->gc, passport, decoded_friendly_name); + msn_get_contact_list(cmdproc->session->contact, MSN_PS_PENDING_LIST, NULL); + } + +// g_free(decoded_friendly_name); +// g_free(passport); + } + } + + xmlnode_free(root); +} + +static void adl_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) { - msn_session_finish_login(cmdproc->session); + MsnSession *session; + + g_return_if_fail(cmdproc != NULL); + g_return_if_fail(cmdproc->session != NULL); + g_return_if_fail(cmdproc->last_cmd != NULL); + g_return_if_fail(cmd != NULL); + + session = cmdproc->session; + + if ( !strcmp(cmd->params[1], "OK")) { + /* ADL ack */ + msn_session_finish_login(session); + } else { + cmdproc->last_cmd->payload_cb = adl_cmd_parse; + } return; } @@ -797,7 +854,7 @@ g_return_if_fail(cmdproc->session != NULL); g_return_if_fail(cmdproc->session->contact != NULL); // msn_notification_post_adl(cmdproc, payload, len); - msn_get_address_book(cmdproc->session->contact, MSN_AB_SAVE_CONTACT, NULL, NULL); +// msn_get_address_book(cmdproc->session->contact, MSN_AB_SAVE_CONTACT, NULL, NULL); } static void @@ -1663,10 +1720,10 @@ #ifdef MSN_PARTIAL_LISTS /* msn_userlist_load defeats all attempts at trying to detect blist sync issues */ msn_userlist_load(session); - msn_get_contact_list(session->contact, clLastChange); + msn_get_contact_list(session->contact, MSN_PS_INITIAL, clLastChange); #else /* always get the full list? */ - msn_get_contact_list(session->contact, NULL); + msn_get_contact_list(session->contact, MSN_PS_INITIAL, NULL); #endif #if 0 msn_contact_connect(session->contact); @@ -1972,11 +2029,11 @@ msn_table_add_cmd(cbs_table, "CHG", "CHG", NULL); msn_table_add_cmd(cbs_table, "CHG", "ILN", iln_cmd); msn_table_add_cmd(cbs_table, "ADL", "ILN", iln_cmd); - msn_table_add_cmd(cbs_table, "REM", "REM", rem_cmd); +// msn_table_add_cmd(cbs_table, "REM", "REM", rem_cmd); /* Removed as of MSNP13 */ msn_table_add_cmd(cbs_table, "USR", "USR", usr_cmd); msn_table_add_cmd(cbs_table, "USR", "XFR", xfr_cmd); msn_table_add_cmd(cbs_table, "USR", "GCF", gcf_cmd); - msn_table_add_cmd(cbs_table, "SYN", "SYN", syn_cmd); +// msn_table_add_cmd(cbs_table, "SYN", "SYN", syn_cmd); /* Removed as of MSNP13 */ msn_table_add_cmd(cbs_table, "CVR", "CVR", cvr_cmd); msn_table_add_cmd(cbs_table, "VER", "VER", ver_cmd); msn_table_add_cmd(cbs_table, "REA", "REA", rea_cmd); diff -r 115290ce3b92 -r 98613886411a libpurple/protocols/msn/soap.h --- a/libpurple/protocols/msn/soap.h Tue Aug 28 05:21:17 2007 +0000 +++ b/libpurple/protocols/msn/soap.h Fri Aug 31 18:12:35 2007 +0000 @@ -29,7 +29,7 @@ #define MSN_SOAP_READ_BUFF_SIZE 8192 /* define this to debug the communications with the SOAP server */ -#undef MSN_SOAP_DEBUG +/* #define MSN_SOAP_DEBUG */ typedef enum diff -r 115290ce3b92 -r 98613886411a libpurple/protocols/msn/userlist.c --- a/libpurple/protocols/msn/userlist.c Tue Aug 28 05:21:17 2007 +0000 +++ b/libpurple/protocols/msn/userlist.c Fri Aug 31 18:12:35 2007 +0000 @@ -106,7 +106,7 @@ } static gboolean -msn_userlist_user_is_in_list(MsnUser *user, int list_id) +msn_userlist_user_is_in_list(MsnUser *user, MsnListId list_id) { int list_op; @@ -373,6 +373,11 @@ } } + if (list_op & MSN_LIST_PL_OP) + { + got_new_entry(gc, passport, store); + } + user->list_op |= list_op; } @@ -629,6 +634,7 @@ new_group_name = group_name == NULL ? MSN_INDIVIDUALS_GROUP_NAME : group_name; + g_return_if_fail(userlist != NULL); g_return_if_fail(userlist->session != NULL); @@ -669,6 +675,9 @@ msn_callback_state_set_guid(state, group_id); } + /* XXX: adding user here may not be correct (should add them in the + * ACK to the ADL command), but for now we need to make sure they exist + * early enough that the ILN command doesn't screw us up */ user = msn_userlist_find_add_user(userlist, who, who); @@ -787,12 +796,13 @@ const char *old_group_name, const char *new_group_name) { const char *new_group_id; - MsnCallbackState *state = msn_callback_state_new(); + MsnCallbackState *state; g_return_if_fail(userlist != NULL); g_return_if_fail(userlist->session != NULL); g_return_if_fail(userlist->session->contact != NULL); - + + state = msn_callback_state_new(); msn_callback_state_set_who(state, who); msn_callback_state_set_action(state, MSN_MOVE_BUDDY); msn_callback_state_set_old_group_name(state, old_group_name);