# HG changeset patch # User Carlos Silva # Date 1190182122 0 # Node ID 2c8c6d77f12ceca5eee588accaa85f8aeab093fb # Parent 5bef3197383a28ecc19b2c02b5175ead38793500 Make use of the GQueue in MsnSoapConn to manage the SOAP requests, allowing them to work perfectly even when dispatching multiple requests at once. Delete a user from the userlist after the contact is deleted from the server. diff -r 5bef3197383a -r 2c8c6d77f12c libpurple/protocols/msn/contact.c --- a/libpurple/protocols/msn/contact.c Sun Sep 16 18:47:12 2007 +0000 +++ b/libpurple/protocols/msn/contact.c Wed Sep 19 06:08:42 2007 +0000 @@ -83,6 +83,9 @@ if (state->who != NULL) g_free(state->who); + if (state->uid != NULL) + g_free(state->uid); + if (state->old_group_name != NULL) g_free(state->old_group_name); @@ -91,7 +94,7 @@ if (state->guid != NULL) g_free(state->guid); - + g_free(state); } @@ -112,6 +115,22 @@ } void +msn_callback_state_set_uid(MsnCallbackState *state, const gchar *uid) +{ + gchar *new_str = NULL; + + g_return_if_fail(state != NULL); + + if (uid != NULL) + new_str = g_strdup(uid); + + if (state->uid != NULL) + g_free(state->uid); + + state->uid = new_str; +} + +void msn_callback_state_set_old_group_name(MsnCallbackState *state, const gchar *old_group_name) { gchar *new_str = NULL; @@ -178,9 +197,8 @@ /*contact SOAP server login error*/ static void -msn_contact_login_error_cb(PurpleSslConnection *gsc, PurpleSslErrorType error, void *data) +msn_contact_login_error_cb(MsnSoapConn *soapconn, PurpleSslConnection *gsc, PurpleSslErrorType error) { - MsnSoapConn *soapconn = data; MsnSession *session; session = soapconn->session; @@ -190,22 +208,21 @@ } /*msn contact SOAP server connect process*/ -static void -msn_contact_login_connect_cb(gpointer data, PurpleSslConnection *gsc, - PurpleInputCondition cond) +static gboolean +msn_contact_login_connect_cb(MsnSoapConn *soapconn, PurpleSslConnection *gsc) { - MsnSoapConn *soapconn = data; MsnSession * session; MsnContact *contact; contact = soapconn->parent; - g_return_if_fail(contact != NULL); + g_return_val_if_fail(contact != NULL, TRUE); session = contact->session; - g_return_if_fail(session != NULL); + g_return_val_if_fail(session != NULL, FALSE); /*login ok!We can retrieve the contact list*/ // msn_get_contact_list(contact, MSN_PS_INITIAL, NULL); + return TRUE; } /*get MSN member role utility*/ @@ -243,30 +260,27 @@ } /* Create the AddressBook in the server, if we don't have one */ -static void -msn_create_address_cb(gpointer data, gint source, PurpleInputCondition cond) +static gboolean +msn_create_address_cb(MsnSoapConn *soapconn) { - MsnSoapConn *soapconn = data; MsnContact *contact; if (soapconn->body == NULL) - return; + return TRUE; contact = soapconn->parent; - g_return_if_fail(contact != NULL); + g_return_val_if_fail(contact != NULL, TRUE); purple_debug_info("MSN AddressBook", "Address Book successfully created!\n"); msn_get_address_book(contact, MSN_PS_INITIAL, NULL, NULL); // msn_soap_free_read_buf(soapconn); - return; + return TRUE; } static void -msn_create_address_written_cb(gpointer data, gint source, PurpleInputCondition cond) +msn_create_address_written_cb(MsnSoapConn *soapconn) { - MsnSoapConn * soapconn = data; - purple_debug_info("MSN AddressBook","AddressBookAdd written\n"); soapconn->read_cb = msn_create_address_cb; @@ -293,8 +307,9 @@ body, NULL, msn_create_address_cb, - msn_create_address_written_cb); - msn_soap_post(contact->soapconn, soap_request, msn_contact_connect_init); + msn_create_address_written_cb, + msn_contact_connect_init); + msn_soap_post(contact->soapconn, soap_request); g_free(body); @@ -527,10 +542,9 @@ xmlnode_free(node); /* Free the whole XML tree */ } -static void -msn_get_contact_list_cb(gpointer data, gint source, PurpleInputCondition cond) +static gboolean +msn_get_contact_list_cb(MsnSoapConn *soapconn) { - MsnSoapConn *soapconn = data; MsnContact *contact; MsnSession *session; const char *abLastChange; @@ -538,15 +552,15 @@ gchar *partner_scenario; if (soapconn->body == NULL) - return; + return TRUE; purple_debug_misc("MSNCL","Got the contact list!\n"); contact = soapconn->parent; - g_return_if_fail(contact != NULL); + g_return_val_if_fail(contact != NULL, TRUE); session = soapconn->session; - g_return_if_fail(session != NULL); - g_return_if_fail(soapconn->data_cb != NULL); + g_return_val_if_fail(session != NULL, FALSE); + g_return_val_if_fail(soapconn->data_cb != NULL, TRUE); partner_scenario = soapconn->data_cb; @@ -570,19 +584,18 @@ } else { msn_soap_free_read_buf(soapconn); } + + return TRUE; } static void -msn_get_contact_written_cb(gpointer data, gint source, PurpleInputCondition cond) +msn_get_contact_written_cb(MsnSoapConn *soapconn) { - MsnSoapConn * soapconn = data; - purple_debug_misc("MSNCL","Sent SOAP request for the contact list.\n"); soapconn->read_cb = msn_get_contact_list_cb; -// msn_soap_read_cb(data,source,cond); } -/*SOAP get contact list*/ +/* SOAP get contact list*/ void msn_get_contact_list(MsnContact * contact, const MsnSoapPartnerScenario partner_scenario, const char *update_time) { @@ -609,8 +622,9 @@ body, (gpointer) partner_scenario_str, msn_get_contact_list_cb, - msn_get_contact_written_cb); - msn_soap_post(contact->soapconn,soap_request,msn_contact_connect_init); + msn_get_contact_written_cb, + msn_contact_connect_init); + msn_soap_post(contact->soapconn,soap_request); g_free(body); } @@ -902,20 +916,19 @@ return TRUE; } -static void -msn_get_address_cb(gpointer data, gint source, PurpleInputCondition cond) +static gboolean +msn_get_address_cb(MsnSoapConn *soapconn) { - MsnSoapConn * soapconn = data; MsnContact *contact; MsnSession *session; if (soapconn->body == NULL) - return; + return TRUE; contact = soapconn->parent; - g_return_if_fail(contact != NULL); + g_return_val_if_fail(contact != NULL, TRUE); session = soapconn->session; - g_return_if_fail(session != NULL); + g_return_val_if_fail(session != NULL, FALSE); purple_debug_misc("MSN AddressBook", "Got the Address Book!\n"); @@ -926,6 +939,10 @@ msn_send_privacy(session->account->gc); msn_notification_dump_contact(session); } + + /*free the read buffer*/ + msn_soap_free_read_buf(soapconn); + return TRUE; } else { /* This is making us loop infinitely when we fail to parse the address book, disable for now (we should re-enable when we send timestamps) @@ -935,18 +952,14 @@ */ msn_session_disconnect(session); purple_connection_error(session->account->gc, _("Unable to retrieve MSN Address Book")); + return FALSE; } - - /*free the read buffer*/ - msn_soap_free_read_buf(soapconn); } /**/ static void -msn_address_written_cb(gpointer data, gint source, PurpleInputCondition cond) +msn_address_written_cb(MsnSoapConn *soapconn) { - MsnSoapConn * soapconn = data; - purple_debug_misc("MSN AddressBook","Sent SOAP request for the Address Book.\n"); soapconn->read_cb = msn_get_address_cb; } @@ -984,28 +997,28 @@ body, NULL, msn_get_address_cb, - msn_address_written_cb); - msn_soap_post(contact->soapconn,soap_request,msn_contact_connect_init); + msn_address_written_cb, + msn_contact_connect_init); + msn_soap_post(contact->soapconn,soap_request); g_free(body); } -static void -msn_add_contact_read_cb(gpointer data, gint source, PurpleInputCondition cond) +static gboolean +msn_add_contact_read_cb(MsnSoapConn *soapconn) { - 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); - g_return_if_fail(soapconn->session->userlist != NULL); + g_return_val_if_fail(soapconn->data_cb != NULL, TRUE); + g_return_val_if_fail(soapconn->session != NULL, FALSE); + g_return_val_if_fail(soapconn->session->userlist != NULL, TRUE); state = (MsnCallbackState *) soapconn->data_cb; if (soapconn->body == NULL) { msn_callback_state_free(state); - return; + return TRUE; } userlist = soapconn->session->userlist; @@ -1032,13 +1045,13 @@ } msn_callback_state_free(state); + + return TRUE; } static void -msn_add_contact_written_cb(gpointer data, gint source, PurpleInputCondition cond) +msn_add_contact_written_cb(MsnSoapConn *soapconn) { - MsnSoapConn * soapconn = data; - purple_debug_info("MSNCL","Add contact request written\n"); soapconn->read_cb = msn_add_contact_read_cb; } @@ -1079,23 +1092,23 @@ body, state, msn_add_contact_read_cb, - msn_add_contact_written_cb); - msn_soap_post(contact->soapconn,soap_request,msn_contact_connect_init); + msn_add_contact_written_cb, + msn_contact_connect_init); + msn_soap_post(contact->soapconn,soap_request); g_free(soap_action); g_free(body); } -static void -msn_add_contact_to_group_read_cb(gpointer data, gint source, PurpleInputCondition cond) +static gboolean +msn_add_contact_to_group_read_cb(MsnSoapConn *soapconn) { - MsnSoapConn * soapconn = data; MsnCallbackState *state; MsnUserList *userlist; - g_return_if_fail(soapconn->data_cb != NULL); - g_return_if_fail(soapconn->session != NULL); - g_return_if_fail(soapconn->session->userlist != NULL); + g_return_val_if_fail(soapconn->data_cb != NULL, TRUE); + g_return_val_if_fail(soapconn->session != NULL, FALSE); + g_return_val_if_fail(soapconn->session->userlist != NULL, TRUE); userlist = soapconn->session->userlist; @@ -1103,7 +1116,7 @@ if (soapconn->body == NULL) { msn_callback_state_free(state); - return; + return TRUE; } if (msn_userlist_add_buddy_to_group(userlist, state->who, state->new_group_name) == TRUE) { @@ -1125,7 +1138,7 @@ if (msn_userlist_user_is_in_list(user, MSN_LIST_PL)) { msn_del_contact_from_list(soapconn->session->contact, NULL, state->who, MSN_LIST_PL); msn_callback_state_free(state); - return; + return TRUE; } } @@ -1135,13 +1148,12 @@ msn_callback_state_free(state); msn_soap_free_read_buf(soapconn); } + return TRUE; } static void -msn_add_contact_to_group_written_cb(gpointer data, gint source, PurpleInputCondition cond) +msn_add_contact_to_group_written_cb(MsnSoapConn *soapconn) { - MsnSoapConn * soapconn = data; - purple_debug_info("MSNCL","Add contact to group request sent!\n"); soapconn->read_cb = msn_add_contact_to_group_read_cb; } @@ -1210,8 +1222,9 @@ body, state, msn_add_contact_to_group_read_cb, - msn_add_contact_to_group_written_cb); - msn_soap_post(contact->soapconn,soap_request,msn_contact_connect_init); + msn_add_contact_to_group_written_cb, + msn_contact_connect_init); + msn_soap_post(contact->soapconn,soap_request); g_free(soap_action); g_free(body); @@ -1219,24 +1232,39 @@ -static void -msn_delete_contact_read_cb(gpointer data, gint source, PurpleInputCondition cond) +static gboolean +msn_delete_contact_read_cb(MsnSoapConn *soapconn) { - MsnSoapConn * soapconn = data; + MsnUser *user; + MsnCallbackState *state = (MsnCallbackState *) soapconn->data_cb; + MsnUserList *userlist; + + g_return_val_if_fail(soapconn->session != NULL, FALSE); + g_return_val_if_fail(soapconn->session->userlist != NULL, TRUE); + + userlist = soapconn->session->userlist; - if (soapconn->body == NULL) - return; + if (soapconn->body == NULL) { + msn_callback_state_free(state); + return TRUE; + } + + purple_debug_info("MSNCL","Delete contact successful\n"); - // we should probably delete it from the userlist aswell - purple_debug_info("MSNCL","Delete contact successful\n"); + user = msn_userlist_find_user_with_id(userlist, state->uid); + if (user != NULL) { + msn_userlist_remove_user(userlist, user); + } + + msn_callback_state_free(state); msn_soap_free_read_buf(soapconn); + + return TRUE; } static void -msn_delete_contact_written_cb(gpointer data, gint source, PurpleInputCondition cond) +msn_delete_contact_written_cb(MsnSoapConn *soapconn) { - MsnSoapConn * soapconn = data; - purple_debug_info("MSNCL","Delete contact request written\n"); soapconn->read_cb = msn_delete_contact_read_cb; } @@ -1248,10 +1276,14 @@ gchar *body = NULL; gchar *contact_id_xml = NULL ; MsnSoapReq *soap_request; + MsnCallbackState *state; g_return_if_fail(contactId != NULL); contact_id_xml = g_strdup_printf(MSN_CONTACT_ID_XML, contactId); + state = msn_callback_state_new(); + msn_callback_state_set_uid(state, contactId); + /* build SOAP request */ purple_debug_info("MSNCL","Deleting contact with contactId: %s\n", contactId); body = g_strdup_printf(MSN_DEL_CONTACT_TEMPLATE, contact_id_xml); @@ -1259,27 +1291,27 @@ MSN_ADDRESS_BOOK_POST_URL, MSN_CONTACT_DEL_SOAP_ACTION, body, - NULL, + state, msn_delete_contact_read_cb, - msn_delete_contact_written_cb); + msn_delete_contact_written_cb, + msn_contact_connect_init); g_free(contact_id_xml); /* POST the SOAP request */ - msn_soap_post(contact->soapconn, soap_request, msn_contact_connect_init); + msn_soap_post(contact->soapconn, soap_request); g_free(body); } -static void -msn_del_contact_from_group_read_cb(gpointer data, gint source, PurpleInputCondition cond) +static gboolean +msn_del_contact_from_group_read_cb(MsnSoapConn *soapconn) { - MsnSoapConn * soapconn = data; MsnCallbackState *state = (MsnCallbackState *) soapconn->data_cb; if (soapconn->body == NULL) { msn_callback_state_free(state); - return; + return TRUE; } if (msn_userlist_rem_buddy_from_group(soapconn->session->userlist, state->who, state->old_group_name)) { @@ -1290,14 +1322,13 @@ msn_callback_state_free(state); msn_soap_free_read_buf(soapconn); - return; + + return TRUE; } static void -msn_del_contact_from_group_written_cb(gpointer data, gint source, PurpleInputCondition cond) +msn_del_contact_from_group_written_cb(MsnSoapConn *soapconn) { - MsnSoapConn * soapconn = data; - purple_debug_info("MSN CL","Del contact from group request sent!\n"); soapconn->read_cb = msn_del_contact_from_group_read_cb; } @@ -1358,30 +1389,29 @@ body, state, msn_del_contact_from_group_read_cb, - msn_del_contact_from_group_written_cb); - msn_soap_post(contact->soapconn,soap_request,msn_contact_connect_init); + msn_del_contact_from_group_written_cb, + msn_contact_connect_init); + msn_soap_post(contact->soapconn,soap_request); g_free(soap_action); g_free(body); } -static void -msn_update_contact_read_cb(gpointer data, gint source, PurpleInputCondition cond) +static gboolean +msn_update_contact_read_cb(MsnSoapConn *soapconn) { - MsnSoapConn *soapconn = data; - if (soapconn->body == NULL) - return; + return TRUE; purple_debug_info("MSN CL","Contact updated successfully\n"); + + return TRUE; } static void -msn_update_contact_written_cb(gpointer data, gint source, PurpleInputCondition cond) +msn_update_contact_written_cb(MsnSoapConn *soapconn) { - MsnSoapConn * soapconn = data; - purple_debug_info("MSN CL","Update contact information request sent\n"); soapconn->read_cb = msn_update_contact_read_cb; } @@ -1408,60 +1438,60 @@ body, NULL, msn_update_contact_read_cb, - msn_update_contact_written_cb); - msn_soap_post(contact->soapconn, soap_request, msn_contact_connect_init); + msn_update_contact_written_cb, + msn_contact_connect_init); + msn_soap_post(contact->soapconn, soap_request); g_free(body); } -static void -msn_del_contact_from_list_read_cb(gpointer data, gint source, PurpleInputCondition cond) +static gboolean +msn_del_contact_from_list_read_cb(MsnSoapConn *soapconn) { - MsnSoapConn * soapconn = data; MsnCallbackState *state = NULL; - g_return_if_fail(soapconn->data_cb != NULL); - g_return_if_fail(soapconn->session != NULL); - g_return_if_fail(soapconn->session->contact != NULL); + g_return_val_if_fail(soapconn->data_cb != NULL, TRUE); + g_return_val_if_fail(soapconn->session != NULL, FALSE); + g_return_val_if_fail(soapconn->session->contact != NULL, FALSE); state = (MsnCallbackState *) soapconn->data_cb; if (soapconn->body == NULL) { msn_callback_state_free(state); - return; + return TRUE; } purple_debug_info("MSN CL", "Contact %s deleted successfully from %s list on server!\n", state->who, MsnMemberRole[state->list_id]); if (state->list_id == MSN_LIST_PL) { msn_add_contact_to_list(soapconn->session->contact, state, state->who, MSN_LIST_RL); - return; + return TRUE; } if (state->list_id == MSN_LIST_AL) { purple_privacy_permit_remove(soapconn->session->account, state->who, TRUE); msn_add_contact_to_list(soapconn->session->contact, NULL, state->who, MSN_LIST_BL); msn_callback_state_free(state); - return; + return TRUE; } if (state->list_id == MSN_LIST_BL) { purple_privacy_deny_remove(soapconn->session->account, state->who, TRUE); msn_add_contact_to_list(soapconn->session->contact, NULL, state->who, MSN_LIST_AL); msn_callback_state_free(state); - return; + return TRUE; } msn_callback_state_free(state); msn_soap_free_read_buf(soapconn); + + return TRUE; } static void -msn_del_contact_from_list_written_cb(gpointer data, gint source, PurpleInputCondition cond) +msn_del_contact_from_list_written_cb(MsnSoapConn *soapconn) { - MsnSoapConn * soapconn = data; - purple_debug_info("MSN CL","Delete contact from list SOAP request sent!\n"); soapconn->read_cb = msn_del_contact_from_list_read_cb; } @@ -1514,36 +1544,36 @@ body, state, msn_del_contact_from_list_read_cb, - msn_del_contact_from_list_written_cb); + msn_del_contact_from_list_written_cb, + msn_contact_connect_init); - msn_soap_post(contact->soapconn,soap_request,msn_contact_connect_init); + msn_soap_post(contact->soapconn,soap_request); g_free(body); } -static void -msn_add_contact_to_list_read_cb(gpointer data, gint source, PurpleInputCondition cond) +static gboolean +msn_add_contact_to_list_read_cb(MsnSoapConn *soapconn) { - MsnSoapConn * soapconn = data; MsnCallbackState *state = NULL; - g_return_if_fail(soapconn->data_cb != NULL); + g_return_val_if_fail(soapconn->data_cb != NULL, TRUE); state = (MsnCallbackState *) soapconn->data_cb; if (soapconn->body == NULL) { msn_callback_state_free(state); - return; + return TRUE; } purple_debug_info("MSN CL", "Contact %s added successfully to %s list on server!\n", state->who, MsnMemberRole[state->list_id]); if (state->list_id == MSN_LIST_RL && (state->action & MSN_DENIED_BUDDY) ) { - g_return_if_fail(soapconn->session != NULL); - g_return_if_fail(soapconn->session->contact != NULL); + g_return_val_if_fail(soapconn->session != NULL, FALSE); + g_return_val_if_fail(soapconn->session->contact != NULL, FALSE); msn_add_contact_to_list(soapconn->session->contact, NULL, state->who, MSN_LIST_BL); - return; + return TRUE; } if (state->list_id == MSN_LIST_AL) { @@ -1554,14 +1584,13 @@ msn_callback_state_free(state); msn_soap_free_read_buf(soapconn); + return TRUE; } static void -msn_add_contact_to_list_written_cb(gpointer data, gint source, PurpleInputCondition cond) +msn_add_contact_to_list_written_cb(MsnSoapConn *soapconn) { - MsnSoapConn * soapconn = data; - purple_debug_info("MSN CL","Add contact to list SOAP request sent!\n"); soapconn->read_cb = msn_add_contact_to_list_read_cb; } @@ -1603,26 +1632,26 @@ body, state, msn_add_contact_to_list_read_cb, - msn_add_contact_to_list_written_cb); + msn_add_contact_to_list_written_cb, + msn_contact_connect_init); - msn_soap_post(contact->soapconn, soap_request, msn_contact_connect_init); + msn_soap_post(contact->soapconn, soap_request); g_free(body); } #if 0 -static void -msn_gleams_read_cb(gpointer data, gint source, PurpleInputCondition cond) +static gboolean +msn_gleams_read_cb(MsnSoapConn * soapconn) { - purple_debug_info("MSNP14","Gleams read done\n"); + purple_debug_info("MSN CL","Gleams read done\n"); + return TRUE; } static void -msn_gleams_written_cb(gpointer data, gint source, PurpleInputCondition cond) +msn_gleams_written_cb(MsnSoapConn * soapconn) { - MsnSoapConn * soapconn = data; - purple_debug_info("MSNP14","finish Group written\n"); soapconn->read_cb = msn_gleams_read_cb; // msn_soap_read_cb(data,source,cond); @@ -1642,8 +1671,9 @@ MSN_GLEAMS_TEMPLATE, NULL, msn_gleams_read_cb, - msn_gleams_written_cb); - msn_soap_post(contact->soapconn,soap_request,msn_contact_connect_init); + msn_gleams_written_cb, + msn_contact_connect_init); + msn_soap_post(contact->soapconn,soap_request); } #endif @@ -1652,24 +1682,23 @@ * Group Operations ***************************************************************/ -static void -msn_group_read_cb(gpointer data, gint source, PurpleInputCondition cond) +static gboolean +msn_group_read_cb(MsnSoapConn *soapconn) { - MsnSoapConn * soapconn = data; MsnUserList *userlist; MsnCallbackState *state = NULL; purple_debug_info("MSN CL", "Group request successful.\n"); - g_return_if_fail(soapconn->session != NULL); - g_return_if_fail(soapconn->session->userlist != NULL); - g_return_if_fail(soapconn->session->contact != NULL); + g_return_val_if_fail(soapconn->session != NULL, FALSE); + g_return_val_if_fail(soapconn->session->userlist != NULL, TRUE); + g_return_val_if_fail(soapconn->session->contact != NULL, FALSE); state = (MsnCallbackState *) soapconn->data_cb; if (soapconn->body == NULL) { msn_callback_state_free(state); - return; + return TRUE; } if (state) { @@ -1697,12 +1726,12 @@ state->who, state->new_group_name); msn_callback_state_free(state); - return; + return TRUE; } if (state->action & MSN_MOVE_BUDDY) { msn_add_contact_to_group(soapconn->session->contact, state, state->who, guid); - return; + return TRUE; } } @@ -1720,13 +1749,12 @@ } msn_soap_free_read_buf(soapconn); + return TRUE; } static void -msn_group_written_cb(gpointer data, gint source, PurpleInputCondition cond) +msn_group_written_cb(MsnSoapConn *soapconn) { - MsnSoapConn * soapconn = data; - purple_debug_info("MSN CL","Sent group request.\n"); soapconn->read_cb = msn_group_read_cb; } @@ -1767,8 +1795,9 @@ body, state, msn_group_read_cb, - msn_group_written_cb); - msn_soap_post(contact->soapconn,soap_request,msn_contact_connect_init); + msn_group_written_cb, + msn_contact_connect_init); + msn_soap_post(contact->soapconn,soap_request); g_free(body); } @@ -1816,8 +1845,9 @@ body, state, msn_group_read_cb, - msn_group_written_cb); - msn_soap_post(contact->soapconn, soap_request, msn_contact_connect_init); + msn_group_written_cb, + msn_contact_connect_init); + msn_soap_post(contact->soapconn, soap_request); g_free(body); } @@ -1867,8 +1897,9 @@ body, state, msn_group_read_cb, - msn_group_written_cb); - msn_soap_post(contact->soapconn, soap_request, msn_contact_connect_init); + msn_group_written_cb, + msn_contact_connect_init); + msn_soap_post(contact->soapconn, soap_request); g_free(escaped_group_name); g_free(body); @@ -1878,6 +1909,6 @@ msn_contact_connect_init(MsnSoapConn *soapconn) { msn_soap_init(soapconn, MSN_CONTACT_SERVER, 1, - msn_contact_login_connect_cb, - msn_contact_login_error_cb); + msn_contact_login_connect_cb, + msn_contact_login_error_cb); } diff -r 5bef3197383a -r 2c8c6d77f12c libpurple/protocols/msn/contact.h --- a/libpurple/protocols/msn/contact.h Sun Sep 16 18:47:12 2007 +0000 +++ b/libpurple/protocols/msn/contact.h Wed Sep 19 06:08:42 2007 +0000 @@ -374,6 +374,7 @@ struct _MsnCallbackState { gchar * who; + gchar * uid; gchar * old_group_name; gchar * new_group_name; gchar * guid; @@ -399,6 +400,7 @@ MsnCallbackState * msn_callback_state_new(void); void msn_callback_state_free(MsnCallbackState *state); void msn_callback_state_set_who(MsnCallbackState *state, const gchar *who); +void msn_callback_state_set_uid(MsnCallbackState *state, const gchar *uid); void msn_callback_state_set_old_group_name(MsnCallbackState *state, const gchar *old_group_name); void msn_callback_state_set_new_group_name(MsnCallbackState *state, diff -r 5bef3197383a -r 2c8c6d77f12c libpurple/protocols/msn/nexus.c --- a/libpurple/protocols/msn/nexus.c Sun Sep 16 18:47:12 2007 +0000 +++ b/libpurple/protocols/msn/nexus.c Wed Sep 19 06:08:42 2007 +0000 @@ -29,7 +29,7 @@ #undef NEXUS_LOGIN_TWN /*Local Function Prototype*/ -static void nexus_login_connect_cb(gpointer data, PurpleSslConnection *gsc,PurpleInputCondition cond); +static gboolean nexus_login_connect_cb(MsnSoapConn *soapconn, PurpleSslConnection *gsc); /************************************************************************** * Main @@ -125,9 +125,8 @@ * Login **************************************************************************/ static void -nexus_login_error_cb(PurpleSslConnection *gsc, PurpleSslErrorType error, void *data) +nexus_login_error_cb(MsnSoapConn *soapconn, PurpleSslConnection *gsc, PurpleSslErrorType error) { - MsnSoapConn * soapconn = data; MsnSession *session; session = soapconn->session; @@ -141,10 +140,9 @@ } /*process the SOAP reply, get the Authentication Info*/ -static void -nexus_login_read_cb(gpointer data, gint source, PurpleInputCondition cond) +static gboolean +nexus_login_read_cb(MsnSoapConn *soapconn) { - MsnSoapConn * soapconn = data; MsnNexus *nexus; MsnSession *session; @@ -155,9 +153,9 @@ char * cert_str; nexus = soapconn->parent; - g_return_if_fail(nexus != NULL); + g_return_val_if_fail(nexus != NULL, TRUE); session = nexus->session; - g_return_if_fail(session != NULL); + g_return_val_if_fail(session != NULL, FALSE); /*reply OK, we should process the SOAP body*/ purple_debug_info("MSN Nexus","TWN Server Windows Live ID Reply OK!\n"); @@ -210,25 +208,21 @@ msn_nexus_destroy(nexus); session->nexus = NULL; - return; + return FALSE; } static void -nexus_login_written_cb(gpointer data, gint source, PurpleInputCondition cond) +nexus_login_written_cb(MsnSoapConn *soapconn) { - MsnSoapConn * soapconn = data; - soapconn->read_cb = nexus_login_read_cb; // msn_soap_read_cb(data,source,cond); } /*when connect, do the SOAP Style windows Live ID authentication */ -void -nexus_login_connect_cb(gpointer data, PurpleSslConnection *gsc, - PurpleInputCondition cond) +gboolean +nexus_login_connect_cb(MsnSoapConn *soapconn, PurpleSslConnection *gsc) { - MsnSoapConn *soapconn; MsnNexus * nexus; MsnSession *session; char *ru,*lc,*id,*tw,*ct,*kpp,*kv,*ver,*rn,*tpf; @@ -240,17 +234,18 @@ #else char *rst1_str,*rst2_str,*rst3_str; #endif - + purple_debug_info("MSN Nexus","Starting Windows Live ID authentication\n"); - soapconn = data; - g_return_if_fail(soapconn != NULL); + g_return_val_if_fail(soapconn != NULL, FALSE); nexus = soapconn->parent; - g_return_if_fail(nexus != NULL); + g_return_val_if_fail(nexus != NULL, TRUE); session = soapconn->session; - g_return_if_fail(session != NULL); + g_return_val_if_fail(session != NULL, FALSE); + + msn_soap_set_process_step(soapconn, MSN_SOAP_PROCESSING); msn_session_set_login_step(session, MSN_LOGIN_STEP_GET_COOKIE); @@ -283,7 +278,7 @@ purple_ssl_close(gsc); msn_nexus_destroy(nexus); session->nexus = NULL; - return; + return FALSE; } /* @@ -328,10 +323,10 @@ "Accept: text/*\r\n" "User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)\r\n" "Host: %s\r\n" - "Content-Length: %d\r\n" + "Content-Length: %" G_GSIZE_FORMAT "\r\n" "Connection: Keep-Alive\r\n" "Cache-Control: no-cache\r\n\r\n", - soapconn->login_path,soapconn->login_host,(int)strlen(tail)); + soapconn->login_path, soapconn->login_host, strlen(tail)); request_str = g_strdup_printf("%s%s", head,tail); @@ -344,9 +339,9 @@ g_free(password); /*prepare to send the SOAP request*/ - msn_soap_write(soapconn,request_str,nexus_login_written_cb); + msn_soap_write(soapconn, request_str, nexus_login_written_cb); - return; + return TRUE; } #if 0 /* khc */ @@ -468,7 +463,6 @@ msn_nexus_connect(MsnNexus *nexus) { /* Authenticate via Windows Live ID. */ - purple_debug_info("MSN Nexus","msn_nexus_connect()\n"); - msn_soap_init(nexus->soapconn,MSN_TWN_SERVER,1,nexus_login_connect_cb,nexus_login_error_cb); + msn_soap_init(nexus->soapconn, MSN_TWN_SERVER, 1, nexus_login_connect_cb, nexus_login_error_cb); msn_soap_connect(nexus->soapconn); } diff -r 5bef3197383a -r 2c8c6d77f12c libpurple/protocols/msn/oim.c --- a/libpurple/protocols/msn/oim.c Sun Sep 16 18:47:12 2007 +0000 +++ b/libpurple/protocols/msn/oim.c Wed Sep 19 06:08:42 2007 +0000 @@ -31,10 +31,10 @@ /*Local Function Prototype*/ static void msn_oim_post_single_get_msg(MsnOim *oim,const char *msgid); static MsnOimSendReq *msn_oim_new_send_req(const char *from_member, - const char *friendname, - const char* to_member, - gint send_seq, - const char *msg); + const char *friendname, + const char* to_member, + gint send_seq, + const char *msg); static void msn_oim_retrieve_connect_init(MsnSoapConn *soapconn); static void msn_oim_send_connect_init(MsnSoapConn *soapconn); static void msn_oim_free_send_req(MsnOimSendReq *req); @@ -120,9 +120,9 @@ { char *oim_body,*oim_base64; - purple_debug_info("MSNP14","encode OIM Message...\n"); + purple_debug_info("MSN OIM","encode OIM Message...\n"); oim_base64 = purple_base64_encode((const guchar *)body, strlen(body)); - purple_debug_info("MSNP14","encoded base64 body:{%s}\n",oim_base64); + purple_debug_info("MSN OIM","encoded base64 body:{%s}\n",oim_base64); oim_body = g_strdup_printf(MSN_OIM_MSG_TEMPLATE, oim->run_id,oim->send_seq,oim_base64); @@ -131,9 +131,8 @@ /*oim SOAP server login error*/ static void -msn_oim_send_error_cb(PurpleSslConnection *gsc, PurpleSslErrorType error, void *data) +msn_oim_send_error_cb(MsnSoapConn *soapconn, PurpleSslConnection *gsc, PurpleSslErrorType error) { - MsnSoapConn *soapconn = data; MsnSession *session; session = soapconn->session; @@ -143,19 +142,19 @@ } /*msn oim SOAP server connect process*/ -static void -msn_oim_send_connect_cb(gpointer data, PurpleSslConnection *gsc, - PurpleInputCondition cond) +static gboolean +msn_oim_send_connect_cb(MsnSoapConn *soapconn, PurpleSslConnection *gsc) { - MsnSoapConn *soapconn = data; MsnSession * session; MsnOim *oim; oim = soapconn->parent; - g_return_if_fail(oim != NULL); + g_return_val_if_fail(oim != NULL, TRUE); session = oim->session; - g_return_if_fail(session != NULL); + g_return_val_if_fail(session != NULL, FALSE); + + return TRUE; } /* @@ -178,22 +177,22 @@ /*Send OK! return*/ MsnOimSendReq *request; - purple_debug_info("MSNP14","send OIM OK!"); + purple_debug_info("MSN OIM","send OIM OK!"); xmlnode_free(responseNode); request = g_queue_pop_head(oim->send_queue); msn_oim_free_send_req(request); /*send next buffered Offline Message*/ - msn_soap_post(oim->sendconn,NULL,msn_oim_send_connect_init); + msn_soap_post(oim->sendconn, NULL); return; } /*get the challenge,and repost it*/ faultCodeNode = xmlnode_get_child(faultNode,"faultcode"); if(faultCodeNode == NULL){ - purple_debug_info("MSNP14","faultcode Node is NULL\n"); + purple_debug_info("MSN OIM","faultcode Node is NULL\n"); goto oim_send_process_fail; } faultCodeStr = xmlnode_get_data(faultCodeNode); - purple_debug_info("MSNP14","fault code:{%s}\n",faultCodeStr); + purple_debug_info("MSN OIM","fault code:{%s}\n",faultCodeStr); #if 0 if(!strcmp(faultCodeStr,"q0:AuthenticationFailed")){ /*other Fault Reason?*/ @@ -203,7 +202,7 @@ faultstringNode = xmlnode_get_child(faultNode,"faultstring"); faultstring = xmlnode_get_data(faultstringNode); - purple_debug_info("MSNP14","fault string :{%s}\n",faultstring); + purple_debug_info("MSN OIM","fault string :{%s}\n",faultstring); /* lock key fault reason, * compute the challenge and resend it @@ -219,10 +218,10 @@ g_free(oim->challenge); oim->challenge = xmlnode_get_data(challengeNode); - purple_debug_info("MSNP14","lockkey:{%s}\n",oim->challenge); + purple_debug_info("MSN OIM","lockkey:{%s}\n",oim->challenge); /*repost the send*/ - purple_debug_info("MSNP14","prepare to repost the send...\n"); + purple_debug_info("MSN OIM","prepare to repost the send...\n"); msn_oim_send_msg(oim); oim_send_process_fail: @@ -232,29 +231,28 @@ return ; } -static void -msn_oim_send_read_cb(gpointer data, gint source, PurpleInputCondition cond) +static gboolean +msn_oim_send_read_cb(MsnSoapConn *soapconn) { - MsnSoapConn * soapconn = data; MsnSession *session = soapconn->session; MsnOim * oim; if (soapconn->body == NULL) - return; + return TRUE; - g_return_if_fail(session != NULL); + g_return_val_if_fail(session != NULL, FALSE); oim = soapconn->session->oim; - g_return_if_fail(oim != NULL); + g_return_val_if_fail(oim != NULL, TRUE); - purple_debug_info("MSNP14","read buffer:{%s}\n",soapconn->body); + purple_debug_info("MSN OIM","read buffer:{%s}\n", soapconn->body); msn_oim_send_process(oim,soapconn->body,soapconn->body_len); + + return TRUE; } static void -msn_oim_send_written_cb(gpointer data, gint source, PurpleInputCondition cond) +msn_oim_send_written_cb(MsnSoapConn *soapconn) { - MsnSoapConn * soapconn = data; - soapconn->read_cb = msn_oim_send_read_cb; // msn_soap_read_cb(data,source,cond); } @@ -286,7 +284,7 @@ oim_request = g_queue_pop_head(oim->send_queue); g_return_if_fail(oim_request != NULL); - purple_debug_info("MSNP14","send single OIM Message\n"); + purple_debug_info("MSN OIM","send single OIM Message\n"); mspauth = g_strdup_printf("t=%s&p=%s", oim->session->passport_info.t, oim->session->passport_info.p @@ -299,10 +297,10 @@ if(oim->challenge != NULL){ msn_handle_chl(oim->challenge, buf); }else{ - purple_debug_info("MSNP14","no lock key challenge,wait for SOAP Fault and Resend\n"); + purple_debug_info("MSN OIM","no lock key challenge,wait for SOAP Fault and Resend\n"); buf[0]='\0'; } - purple_debug_info("MSNP14","get the lock key challenge {%s}\n",buf); + purple_debug_info("MSN OIM","get the lock key challenge {%s}\n",buf); msg_body = msn_oim_msg_to_str(oim, oim_request->oim_msg); soap_body = g_strdup_printf(MSN_OIM_SEND_TEMPLATE, @@ -321,7 +319,8 @@ soap_body, NULL, msn_oim_send_read_cb, - msn_oim_send_written_cb); + msn_oim_send_written_cb, + msn_oim_send_connect_init); g_free(mspauth); g_free(msg_body); g_free(soap_body); @@ -330,31 +329,28 @@ if(oim->challenge != NULL){ oim->send_seq++; } - msn_soap_post(oim->sendconn,soap_request,msn_oim_send_connect_init); + msn_soap_post(oim->sendconn,soap_request); } /**************************************** * OIM delete SOAP request * **************************************/ -static void -msn_oim_delete_read_cb(gpointer data, gint source, PurpleInputCondition cond) +static gboolean +msn_oim_delete_read_cb(MsnSoapConn *soapconn) { - MsnSoapConn * soapconn = data; - if (soapconn->body == NULL) - return; - purple_debug_info("MSNP14","OIM delete read buffer:{%s}\n",soapconn->body); + return TRUE; + purple_debug_info("MSN OIM","OIM delete read buffer:{%s}\n",soapconn->body); msn_soap_free_read_buf(soapconn); /*get next single Offline Message*/ - msn_soap_post(soapconn,NULL,msn_oim_retrieve_connect_init); +// msn_soap_post(soapconn,NULL); /* we already do this in soap.c */ + return TRUE; } static void -msn_oim_delete_written_cb(gpointer data, gint source, PurpleInputCondition cond) +msn_oim_delete_written_cb(MsnSoapConn *soapconn) { - MsnSoapConn * soapconn = data; - soapconn->read_cb = msn_oim_delete_read_cb; } @@ -368,7 +364,7 @@ g_return_if_fail(oim != NULL); g_return_if_fail(msgid != NULL); - purple_debug_info("MSNP14","Delete single OIM Message {%s}\n",msgid); + purple_debug_info("MSN OIM","Delete single OIM Message {%s}\n",msgid); t = oim->session->passport_info.t; p = oim->session->passport_info.p; @@ -383,8 +379,9 @@ soap_body, NULL, msn_oim_delete_read_cb, - msn_oim_delete_written_cb); - msn_soap_post(oim->retrieveconn,soap_request,msn_oim_retrieve_connect_init); + msn_oim_delete_written_cb, + msn_oim_retrieve_connect_init); + msn_soap_post(oim->retrieveconn,soap_request); } /**************************************** @@ -392,34 +389,33 @@ * **************************************/ /*oim SOAP server login error*/ static void -msn_oim_get_error_cb(PurpleSslConnection *gsc, PurpleSslErrorType error, void *data) +msn_oim_get_error_cb(MsnSoapConn *soapconn, PurpleSslConnection *gsc, PurpleSslErrorType error) { - MsnSoapConn *soapconn = data; MsnSession *session; session = soapconn->session; g_return_if_fail(session != NULL); - msn_soap_clean_unhandled_request(soapconn); + msn_soap_clean_unhandled_requests(soapconn); // msn_session_set_error(session, MSN_ERROR_SERV_DOWN, _("Unable to connect to OIM server")); } /*msn oim SOAP server connect process*/ -static void -msn_oim_get_connect_cb(gpointer data, PurpleSslConnection *gsc, - PurpleInputCondition cond) +static gboolean +msn_oim_get_connect_cb(MsnSoapConn *soapconn, PurpleSslConnection *gsc) { - MsnSoapConn *soapconn = data; MsnSession * session; MsnOim *oim; oim = soapconn->parent; - g_return_if_fail(oim != NULL); + g_return_val_if_fail(oim != NULL, TRUE); session = oim->session; - g_return_if_fail(session != NULL); + g_return_val_if_fail(session != NULL, FALSE); - purple_debug_info("MSNP14","oim get SOAP Server connected!\n"); + purple_debug_info("MSN OIM","Connected and ready to get OIM!\n"); + + return TRUE; } /* like purple_str_to_time, but different. The format of the timestamp @@ -485,7 +481,7 @@ } } - purple_debug_info("MSNP14:OIM", "Can't parse timestamp %s\n", timestamp); + purple_debug_info("MSN OIM:OIM", "Can't parse timestamp %s\n", timestamp); return time(NULL); } @@ -507,7 +503,7 @@ msn_message_parse_payload(message, msg_str, strlen(msg_str), MSG_OIM_LINE_DEM, MSG_OIM_BODY_DEM); - purple_debug_info("MSNP14","oim body:{%s}\n",message->body); + purple_debug_info("MSN OIM","oim body:{%s}\n",message->body); decode_msg = (char *)purple_base64_decode(message->body,&body_len); date = (char *)g_hash_table_lookup(message->attr_table, "Date"); from = (char *)g_hash_table_lookup(message->attr_table, "From"); @@ -517,12 +513,12 @@ if(has_nick){ tokens = g_strsplit(from , " " , 2); passport_str = g_strdup(tokens[1]); - purple_debug_info("MSNP14","oim Date:{%s},nickname:{%s},tokens[1]:{%s} passport{%s}\n", + purple_debug_info("MSN OIM","oim Date:{%s},nickname:{%s},tokens[1]:{%s} passport{%s}\n", date,tokens[0],tokens[1],passport_str); g_strfreev(tokens); }else{ passport_str = g_strdup(from); - purple_debug_info("MSNP14","oim Date:{%s},passport{%s}\n", + purple_debug_info("MSN OIM","oim Date:{%s},passport{%s}\n", date,passport_str); } start = strstr(passport_str,"<"); @@ -530,7 +526,7 @@ end = strstr(passport_str,">"); passport = g_strndup(start,end - start); g_free(passport_str); - purple_debug_info("MSNP14","oim Date:{%s},passport{%s}\n",date,passport); + purple_debug_info("MSN OIM","oim Date:{%s},passport{%s}\n",date,passport); stamp = msn_oim_parse_timestamp(date); @@ -570,30 +566,28 @@ xmlnode_free(oim_node); } -static void -msn_oim_get_read_cb(gpointer data, gint source, PurpleInputCondition cond) +static gboolean +msn_oim_get_read_cb(MsnSoapConn *soapconn) { - MsnSoapConn * soapconn = data; MsnOim * oim = soapconn->session->oim; if (soapconn->body == NULL) - return; + return TRUE; - purple_debug_info("MSNP14","OIM get read buffer:{%s}\n",soapconn->body); + purple_debug_info("MSN OIM","OIM get read buffer:{%s}\n",soapconn->body); /*we need to process the read message!*/ msn_oim_get_process(oim,soapconn->body); msn_soap_free_read_buf(soapconn); /*get next single Offline Message*/ - msn_soap_post(soapconn,NULL,msn_oim_retrieve_connect_init); +// msn_soap_post(soapconn,NULL); /* we already do this in soap.c */ + return TRUE; } static void -msn_oim_get_written_cb(gpointer data, gint source, PurpleInputCondition cond) +msn_oim_get_written_cb(MsnSoapConn *soapconn) { - MsnSoapConn * soapconn = data; - soapconn->read_cb = msn_oim_get_read_cb; // msn_soap_read_cb(data,source,cond); } @@ -608,7 +602,7 @@ char *passport,*msgid,*nickname, *unread, *rTime = NULL; MsnSession *session = oim->session; - purple_debug_info("MSNP14:OIM", "%s", xmlmsg); + purple_debug_info("MSN OIM:OIM", "%s", xmlmsg); node = xmlnode_from_str(xmlmsg, strlen(xmlmsg)); if (strcmp(node->name, "MD") != 0) { @@ -654,7 +648,7 @@ rTime = xmlnode_get_data(rtNode); rtNode = NULL; } -/* purple_debug_info("MSNP14","E:{%s},I:{%s},rTime:{%s}\n",passport,msgid,rTime); */ +/* purple_debug_info("MSN OIM","E:{%s},I:{%s},rTime:{%s}\n",passport,msgid,rTime); */ oim->oim_list = g_list_append(oim->oim_list,strdup(msgid)); msn_oim_post_single_get_msg(oim,msgid); @@ -675,7 +669,7 @@ MsnSoapReq *soap_request; const char *soap_body,*t,*p; - purple_debug_info("MSNP14","Get single OIM Message\n"); + purple_debug_info("MSN OIM","Get single OIM Message\n"); t = oim->session->passport_info.t; p = oim->session->passport_info.p; @@ -690,28 +684,29 @@ soap_body, NULL, msn_oim_get_read_cb, - msn_oim_get_written_cb); - msn_soap_post(oim->retrieveconn,soap_request,msn_oim_retrieve_connect_init); + msn_oim_get_written_cb, + msn_oim_retrieve_connect_init); + msn_soap_post(oim->retrieveconn,soap_request); } /*msn oim retrieve server connect init */ static void msn_oim_retrieve_connect_init(MsnSoapConn *soapconn) { - purple_debug_info("MSNP14","msn_oim_connect...\n"); - msn_soap_init(soapconn,MSN_OIM_RETRIEVE_HOST,1, - msn_oim_get_connect_cb, - msn_oim_get_error_cb); + purple_debug_info("MSN OIM","Initializing OIM retrieve connection\n"); + msn_soap_init(soapconn, MSN_OIM_RETRIEVE_HOST, 1, + msn_oim_get_connect_cb, + msn_oim_get_error_cb); } /*Msn OIM Send Server Connect Init Function*/ static void msn_oim_send_connect_init(MsnSoapConn *sendconn) { - purple_debug_info("MSNP14","msn oim send connect init...\n"); - msn_soap_init(sendconn,MSN_OIM_SEND_HOST,1, - msn_oim_send_connect_cb, - msn_oim_send_error_cb); + purple_debug_info("MSN OIM","Initializing OIM send connection\n"); + msn_soap_init(sendconn, MSN_OIM_SEND_HOST, 1, + msn_oim_send_connect_cb, + msn_oim_send_error_cb); } -/*endof oim.c*/ +/* EOF oim.c*/ diff -r 5bef3197383a -r 2c8c6d77f12c libpurple/protocols/msn/soap.c --- a/libpurple/protocols/msn/soap.c Sun Sep 16 18:47:12 2007 +0000 +++ b/libpurple/protocols/msn/soap.c Wed Sep 19 06:08:42 2007 +0000 @@ -34,6 +34,18 @@ void msn_soap_set_process_step(MsnSoapConn *soapconn, MsnSoapStep step) { +#ifdef MSN_SOAP_DEBUG + const char *MsnSoapStepText[] = + { + "Unconnected", + "Connecting", + "Connected", + "Processing", + "Connected Idle" + }; + + purple_debug_info("MSN SOAP", "Setting SOAP process step to %s\n", MsnSoapStepText[step]); +#endif soapconn->step = step; } @@ -53,8 +65,9 @@ soapconn->input_handler = 0; soapconn->output_handler = 0; - msn_soap_set_process_step(soapconn,MSN_SOAP_UNCONNECTED); + msn_soap_set_process_step(soapconn, MSN_SOAP_UNCONNECTED); soapconn->soap_queue = g_queue_new(); + return soapconn; } @@ -65,6 +78,7 @@ { MsnSoapConn * soapconn; MsnSession *session; + gboolean soapconn_is_valid = FALSE; purple_debug_misc("MSN SOAP","SOAP server connection established!\n"); @@ -76,12 +90,17 @@ soapconn->gsc = gsc; + msn_soap_set_process_step(soapconn, MSN_SOAP_CONNECTED); + /*connection callback*/ - if(soapconn->connect_cb != NULL){ - soapconn->connect_cb(data,gsc,cond); + if (soapconn->connect_cb != NULL) { + soapconn_is_valid = soapconn->connect_cb(soapconn, gsc); } - msn_soap_set_process_step(soapconn,MSN_SOAP_CONNECTED); + if (!soapconn_is_valid) { + return; + } + /*we do the SOAP request here*/ msn_soap_post_head_request(soapconn); } @@ -93,20 +112,24 @@ MsnSoapConn * soapconn = data; g_return_if_fail(data != NULL); + purple_debug_warning("MSN SOAP","Soap connection error!\n"); + msn_soap_set_process_step(soapconn, MSN_SOAP_UNCONNECTED); /*error callback*/ - if(soapconn->error_cb != NULL){ - soapconn->error_cb(gsc,error,data); + if (soapconn->error_cb != NULL) { + soapconn->error_cb(soapconn, gsc, error); + } else { + msn_soap_post(soapconn, NULL); } } /*init the soap connection*/ void msn_soap_init(MsnSoapConn *soapconn,char * host,int ssl, - PurpleSslInputFunction connect_cb, - PurpleSslErrorFunction error_cb) + MsnSoapSslConnectCbFunction connect_cb, + MsnSoapSslErrorCbFunction error_cb) { purple_debug_misc("MSN SOAP","Initializing SOAP connection\n"); soapconn->login_host = g_strdup(host); @@ -119,32 +142,50 @@ void msn_soap_connect(MsnSoapConn *soapconn) { - if(soapconn->ssl_conn){ + if (soapconn->ssl_conn) { purple_ssl_connect(soapconn->session->account, soapconn->login_host, PURPLE_SSL_DEFAULT_PORT, msn_soap_connect_cb, msn_soap_error_cb, soapconn); - }else{ + } else { } - msn_soap_set_process_step(soapconn,MSN_SOAP_CONNECTING); + + msn_soap_set_process_step(soapconn, MSN_SOAP_CONNECTING); } + +static void +msn_soap_close_handler(guint *handler) +{ + if (*handler > 0) { + purple_input_remove(*handler); + *handler = 0; + } +#ifdef MSN_SOAP_DEBUG + else { + purple_debug_misc("MSN SOAP", "Handler inactive, not removing\n"); + } +#endif + +} + + /*close the soap connection*/ void msn_soap_close(MsnSoapConn *soapconn) { - if(soapconn->ssl_conn){ - if(soapconn->gsc != NULL){ + if (soapconn->ssl_conn) { + if (soapconn->gsc != NULL) { purple_ssl_close(soapconn->gsc); soapconn->gsc = NULL; } - }else{ + } else { } - msn_soap_set_process_step(soapconn,MSN_SOAP_UNCONNECTED); + msn_soap_set_process_step(soapconn, MSN_SOAP_UNCONNECTED); } /*clean the unhandled SOAP request*/ void -msn_soap_clean_unhandled_request(MsnSoapConn *soapconn) +msn_soap_clean_unhandled_requests(MsnSoapConn *soapconn) { MsnSoapReq *request; @@ -154,7 +195,7 @@ while ((request = g_queue_pop_head(soapconn->soap_queue)) != NULL){ if (soapconn->read_cb) { - soapconn->read_cb(soapconn, -1, 0); + soapconn->read_cb(soapconn); } msn_soap_request_free(request); } @@ -187,7 +228,7 @@ msn_soap_close(soapconn); /*process the unhandled soap request*/ - msn_soap_clean_unhandled_request(soapconn); + msn_soap_clean_unhandled_requests(soapconn); g_queue_free(soapconn->soap_queue); g_free(soapconn); @@ -199,10 +240,10 @@ int msn_soap_connected(MsnSoapConn *soapconn) { - if(soapconn->ssl_conn){ - return (soapconn->gsc == NULL? 0 : 1); + if (soapconn->ssl_conn) { + return (soapconn->gsc == NULL ? 0 : 1); } - return(soapconn->fd>0? 1 : 0); + return (soapconn->fd > 0 ? 1 : 0); } /*read and append the content to the buffer*/ @@ -237,7 +278,7 @@ "read len: %d, error = %s\n", len, strerror(errno)); purple_input_remove(soapconn->input_handler); - soapconn->input_handler = 0; + //soapconn->input_handler = 0; g_free(soapconn->read_buf); soapconn->read_buf = NULL; soapconn->read_len = 0; @@ -309,7 +350,12 @@ location = strstr(soapconn->read_buf, "Location: "); if (location == NULL) { - msn_soap_free_read_buf(soapconn); + c = (char *) g_strstr_len(soapconn->read_buf, soapconn->read_len,"\r\n\r\n"); + if (c != NULL) { + /* we have read the whole HTTP headers and found no Location: */ + msn_soap_free_read_buf(soapconn); + msn_soap_post(soapconn, NULL); + } return; } @@ -317,6 +363,8 @@ if ((c = strchr(location, '\r')) != NULL) *c = '\0'; + else + return; /* Skip the http:// */ if ((c = strchr(location, '/')) != NULL) @@ -332,10 +380,18 @@ g_free(soapconn->login_host); soapconn->login_host = g_strdup(location); + + msn_soap_close_handler( &(soapconn->input_handler) ); + msn_soap_close(soapconn); - purple_ssl_connect(session->account, soapconn->login_host, + if (purple_ssl_connect(session->account, soapconn->login_host, PURPLE_SSL_DEFAULT_PORT, msn_soap_connect_cb, - msn_soap_error_cb, soapconn); + msn_soap_error_cb, soapconn) == NULL) { + + purple_debug_error("MSN SOAP", "Unable to connect to %s !\n", soapconn->login_host); + // dispatch next request + msn_soap_post(soapconn, NULL); + } } /* Another case of redirection, active on May, 2007 See http://msnpiki.msnfanatic.com/index.php/MSNP13:SOAPTweener#Redirect @@ -345,20 +401,22 @@ { char *location, *c; - location = strstr(soapconn->read_buf, ""); + if ( (location = strstr(soapconn->read_buf, "") ) == NULL) + return; + /* Omit the tag preceding the URL */ location += strlen(""); - location = strstr(location, ":/"); - if (location == NULL) - { - msn_soap_free_read_buf(soapconn); + if (location > soapconn->read_buf + soapconn->read_len) return; - } + if ( (location = strstr(location, "://")) == NULL) + return; location += strlen("://"); /* Skip http:// or https:// */ if ( (c = strstr(location, "")) != NULL ) *c = '\0'; + else + return; if ( (c = strstr(location, "/")) != NULL ) { @@ -369,10 +427,18 @@ g_free(soapconn->login_host); soapconn->login_host = g_strdup(location); + + msn_soap_close_handler( &(soapconn->input_handler) ); + msn_soap_close(soapconn); - purple_ssl_connect(session->account, soapconn->login_host, - PURPLE_SSL_DEFAULT_PORT, msn_soap_connect_cb, - msn_soap_error_cb, soapconn); + if (purple_ssl_connect(session->account, soapconn->login_host, + PURPLE_SSL_DEFAULT_PORT, msn_soap_connect_cb, + msn_soap_error_cb, soapconn) == NULL) { + + purple_debug_error("MSN SOAP", "Unable to connect to %s !\n", soapconn->login_host); + // dispatch next request + msn_soap_post(soapconn, NULL); + } } else if (strstr(soapconn->read_buf, "HTTP/1.1 401 Unauthorized") != NULL) { @@ -405,17 +471,23 @@ else if (strstr(soapconn->read_buf, "wsse:FailedAuthentication") != NULL) { - char *faultstring; + gchar *faultstring; faultstring = strstr(soapconn->read_buf, ""); if (faultstring != NULL) { + gchar *c; faultstring += strlen(""); - *strstr(soapconn->read_buf, "") = '\0'; + if (faultstring < soapconn->read_buf + soapconn->read_len) { + c = strstr(soapconn->read_buf, ""); + if (c != NULL) { + *c = '\0'; + msn_session_set_error(session, MSN_ERROR_AUTH, faultstring); + } + } } - msn_session_set_error(session, MSN_ERROR_AUTH, faultstring); } else if (strstr(soapconn->read_buf, "HTTP/1.1 503 Service Unavailable")) { @@ -424,69 +496,86 @@ else if ((strstr(soapconn->read_buf, "HTTP/1.1 200 OK")) ||(strstr(soapconn->read_buf, "HTTP/1.1 500"))) { - /*OK! process the SOAP body*/ - body_start = (char *)g_strstr_len(soapconn->read_buf, soapconn->read_len,"\r\n\r\n"); - if (!body_start) { - return; - } - body_start += 4; + gboolean soapconn_is_valid = FALSE; - // purple_debug_misc("msn", "Soap Read: {%s}\n", soapconn->read_buf); + /*OK! process the SOAP body*/ + body_start = (char *)g_strstr_len(soapconn->read_buf, soapconn->read_len,"\r\n\r\n"); + if (!body_start) { + return; + } + body_start += 4; - /* we read the content-length*/ - length_start = strstr(soapconn->read_buf, "Content-Length: "); + if (body_start > soapconn->read_buf + soapconn->read_len) + return; + + /* we read the content-length*/ + if ( (length_start = g_strstr_len(soapconn->read_buf, soapconn->read_len, "Content-Length: ")) != NULL) length_start += strlen("Content-Length: "); - length_end = strstr(length_start, "\r\n"); - body_len = g_strndup(length_start, length_end - length_start); + + if (length_start > soapconn->read_buf + soapconn->read_len) + return; + + if ( (length_end = strstr(length_start, "\r\n")) == NULL ) + return; + + body_len = g_strndup(length_start, length_end - length_start); - /*setup the conn body */ - soapconn->body = body_start; - soapconn->body_len = atoi(body_len); - g_free(body_len); + /*setup the conn body */ + soapconn->body = body_start; + soapconn->body_len = atoi(body_len); + g_free(body_len); #ifdef MSN_SOAP_DEBUG - purple_debug_misc("MSN SOAP","SOAP bytes read so far: %d, Content-Length: %d\n", soapconn->read_len, soapconn->body_len); + purple_debug_misc("MSN SOAP","SOAP bytes read so far: %d, Content-Length: %d\n", soapconn->read_len, soapconn->body_len); #endif - soapconn->need_to_read = (body_start - soapconn->read_buf + soapconn->body_len) - soapconn->read_len; - if ( soapconn->need_to_read > 0 ) { - return; - } + soapconn->need_to_read = (body_start - soapconn->read_buf + soapconn->body_len) - soapconn->read_len; + if ( soapconn->need_to_read > 0 ) { + return; + } #if defined(MSN_SOAP_DEBUG) && !defined(_WIN32) - node = xmlnode_from_str(soapconn->body, soapconn->body_len); + node = xmlnode_from_str(soapconn->body, soapconn->body_len); - if (node != NULL) { - formattedxml = xmlnode_to_formatted_str(node, NULL); - http_headers = g_strndup(soapconn->read_buf, soapconn->body - soapconn->read_buf); + if (node != NULL) { + formattedxml = xmlnode_to_formatted_str(node, NULL); + http_headers = g_strndup(soapconn->read_buf, soapconn->body - soapconn->read_buf); - purple_debug_info("MSN SOAP","Data with XML payload received from the SOAP server:\n%s%s\n", http_headers, formattedxml); - g_free(http_headers); - g_free(formattedxml); - xmlnode_free(node); - } - else - purple_debug_info("MSN SOAP","Data received from the SOAP server:\n%s\n", soapconn->read_buf); + purple_debug_info("MSN SOAP","Data with XML payload received from the SOAP server:\n%s%s\n", http_headers, formattedxml); + g_free(http_headers); + g_free(formattedxml); + xmlnode_free(node); + } + else + purple_debug_info("MSN SOAP","Data received from the SOAP server:\n%s\n", soapconn->read_buf); #endif - /*remove the read handler*/ - purple_input_remove(soapconn->input_handler); - soapconn->input_handler = 0; - /* - * close the soap connection,if more soap request came, - * Just reconnect to do it, - * - * To solve the problem described below: - * When I post the soap request in one socket one after the other, - * The first read is ok, But the second soap read always got 0 bytes, - * Weird! - * */ - msn_soap_close(soapconn); + /*remove the read handler*/ + msn_soap_close_handler( &(soapconn->input_handler) ); +// purple_input_remove(soapconn->input_handler); +// soapconn->input_handler = 0; + /* + * close the soap connection,if more soap request came, + * Just reconnect to do it, + * + * To solve the problem described below: + * When I post the soap request in one socket one after the other, + * The first read is ok, But the second soap read always got 0 bytes, + * Weird! + * */ + msn_soap_close(soapconn); - /*call the read callback*/ - if ( soapconn->read_cb != NULL ) { - soapconn->read_cb(soapconn, source, 0); - } - } + /*call the read callback*/ + if ( soapconn->read_cb != NULL ) { + soapconn_is_valid = soapconn->read_cb(soapconn); + } + + if (!soapconn_is_valid) { + return; + } + + /* dispatch next request in queue */ + msn_soap_post(soapconn, NULL); + } return; } @@ -524,9 +613,11 @@ g_return_if_fail(soapconn != NULL); if ( soapconn->write_buf == NULL ) { - purple_debug_error("MSN SOAP","SOAP buffer is NULL\n"); - purple_input_remove(soapconn->output_handler); - soapconn->output_handler = -1; + purple_debug_error("MSN SOAP","SOAP write buffer is NULL\n"); + // msn_soap_check_conn_errors(soapconn); + // purple_input_remove(soapconn->output_handler); + // soapconn->output_handler = 0; + msn_soap_close_handler( &(soapconn->output_handler) ); return; } total_len = strlen(soapconn->write_buf); @@ -542,10 +633,17 @@ return; else if (len <= 0){ /*SSL write error!*/ - purple_input_remove(soapconn->output_handler); - soapconn->output_handler = -1; +// msn_soap_check_conn_errors(soapconn); + + msn_soap_close_handler( &(soapconn->output_handler) ); +// purple_input_remove(soapconn->output_handler); +// soapconn->output_handler = 0; + + msn_soap_close(soapconn); + /* TODO: notify of the error */ - purple_debug_error("MSN SOAP","Error writing to SSL connection!\n"); + purple_debug_error("MSN SOAP", "Error writing to SSL connection!\n"); + msn_soap_post(soapconn, NULL); return; } soapconn->written_len += len; @@ -553,8 +651,9 @@ if (soapconn->written_len < total_len) return; - purple_input_remove(soapconn->output_handler); - soapconn->output_handler = -1; + msn_soap_close_handler( &(soapconn->output_handler) ); +// purple_input_remove(soapconn->output_handler); +// soapconn->output_handler = 0; /*clear the write buff*/ msn_soap_free_write_buf(soapconn); @@ -563,20 +662,25 @@ * callback for write done */ if(soapconn->written_cb != NULL){ - soapconn->written_cb(soapconn, source, 0); + soapconn->written_cb(soapconn); } /*maybe we need to read the input?*/ - if (soapconn->input_handler == 0) { + if ( soapconn->input_handler == 0 ) { soapconn->input_handler = purple_input_add(soapconn->gsc->fd, PURPLE_INPUT_READ, msn_soap_read_cb, soapconn); } -// msn_soap_read_cb(soapconn,source,0); } /*write the buffer to SOAP connection*/ void -msn_soap_write(MsnSoapConn * soapconn, char *write_buf, PurpleInputFunction written_cb) +msn_soap_write(MsnSoapConn * soapconn, char *write_buf, MsnSoapWrittenCbFunction written_cb) { + if (soapconn == NULL) { + return; + } + + msn_soap_set_process_step(soapconn, MSN_SOAP_PROCESSING); + soapconn->write_buf = write_buf; soapconn->written_len = 0; soapconn->written_cb = written_cb; @@ -586,7 +690,7 @@ /*clear the read buffer first*/ /*start the write*/ soapconn->output_handler = purple_input_add(soapconn->gsc->fd, PURPLE_INPUT_WRITE, - msn_soap_write_cb, soapconn); + msn_soap_write_cb, soapconn); msn_soap_write_cb(soapconn, soapconn->gsc->fd, PURPLE_INPUT_WRITE); } @@ -594,7 +698,9 @@ MsnSoapReq * msn_soap_request_new(const char *host,const char *post_url,const char *soap_action, const char *body, const gpointer data_cb, - PurpleInputFunction read_cb,PurpleInputFunction written_cb) + MsnSoapReadCbFunction read_cb, + MsnSoapWrittenCbFunction written_cb, + MsnSoapConnectInitFunction connect_init) { MsnSoapReq *request; @@ -608,6 +714,7 @@ request->data_cb = data_cb; request->read_cb = read_cb; request->written_cb = written_cb; + request->connect_init = connect_init; return request; } @@ -624,6 +731,7 @@ g_free(request->body); request->read_cb = NULL; request->written_cb = NULL; + request->connect_init = NULL; g_free(request); } @@ -632,18 +740,24 @@ void msn_soap_post_head_request(MsnSoapConn *soapconn) { - purple_debug_info("MSN SOAP", "Posting new request from head of the queue\n"); + g_return_if_fail(soapconn != NULL); + g_return_if_fail(soapconn->soap_queue != NULL); - g_return_if_fail(soapconn->soap_queue != NULL); + if (soapconn->step == MSN_SOAP_CONNECTED || + soapconn->step == MSN_SOAP_CONNECTED_IDLE) { + + purple_debug_info("MSN SOAP", "Posting new request from head of the queue\n"); - if(!g_queue_is_empty(soapconn->soap_queue)){ - MsnSoapReq *request; - if((request = g_queue_pop_head(soapconn->soap_queue)) != NULL){ - msn_soap_post_request(soapconn,request); + if ( !g_queue_is_empty(soapconn->soap_queue) ) { + MsnSoapReq *request; + + if ( (request = g_queue_pop_head(soapconn->soap_queue)) != NULL ) { + msn_soap_post_request(soapconn,request); + } + } else { + purple_debug_info("MSN SOAP", "No requests to process found.\n"); + msn_soap_set_process_step(soapconn, MSN_SOAP_CONNECTED_IDLE); } - } else { - purple_debug_info("MSN SOAP", "No requests to process found.\n"); - msn_soap_set_process_step(soapconn,MSN_SOAP_CONNECTED_IDLE); } } @@ -651,35 +765,59 @@ * if not connected, Connected first. */ void -msn_soap_post(MsnSoapConn *soapconn,MsnSoapReq *request, - MsnSoapConnectInitFunction msn_soap_init_func) +msn_soap_post(MsnSoapConn *soapconn,MsnSoapReq *request) { + MsnSoapReq *head_request; + + if (soapconn == NULL) + return; + if (request != NULL) { +#ifdef MSN_SOAP_DEBUG + purple_debug_misc("MSN SOAP", "Request added to the queue\n"); +#endif g_queue_push_tail(soapconn->soap_queue, request); } - if (!msn_soap_connected(soapconn) && (soapconn->step == MSN_SOAP_UNCONNECTED) - &&(!g_queue_is_empty(soapconn->soap_queue))) { - /*not connected?and we have something to process connect it first*/ - purple_debug_misc("MSN SOAP","No connection to SOAP server. Connecting...\n"); - msn_soap_init_func(soapconn); - msn_soap_connect(soapconn); - return; - } - purple_debug_misc("MSN SOAP","Connected to SOAP server\n"); + + if ( !g_queue_is_empty(soapconn->soap_queue)) { + + /* we may have to reinitialize the soap connection, so avoid + * reusing the connection for now */ + + if (soapconn->step == MSN_SOAP_CONNECTED_IDLE) { + purple_debug_misc("MSN SOAP","Already connected to SOAP server, re-initializing\n"); + msn_soap_close_handler( &(soapconn->input_handler) ); + msn_soap_close_handler( &(soapconn->output_handler) ); + msn_soap_close(soapconn); + } + + if (!msn_soap_connected(soapconn) && (soapconn->step == MSN_SOAP_UNCONNECTED)) { - /*if connected, what we only needed to do is to queue the request, - * when SOAP request in the queue processed done, will do this command. - * we just waiting... - * If we send the request this time,error may occure - */ - if (soapconn->step == MSN_SOAP_CONNECTED_IDLE){ - msn_soap_post_head_request(soapconn); + /*not connected?and we have something to process connect it first*/ + purple_debug_misc("MSN SOAP","No connection to SOAP server. Connecting...\n"); + head_request = g_queue_peek_head(soapconn->soap_queue); + + if (head_request == NULL) { + purple_debug_error("MSN SOAP", "Queue is not empty, but failed to peek the head request!\n"); + return; + } + + if (head_request->connect_init != NULL) { + head_request->connect_init(soapconn); + } + msn_soap_connect(soapconn); + return; + } + + purple_debug_info("MSN SOAP", "Currently processing another SOAP request\n"); + } else { + purple_debug_info("MSN SOAP", "No requests left to dispatch\n"); } } /*Post the soap request action*/ void -msn_soap_post_request(MsnSoapConn *soapconn,MsnSoapReq *request) +msn_soap_post_request(MsnSoapConn *soapconn, MsnSoapReq *request) { char * soap_head = NULL; char * request_str = NULL; diff -r 5bef3197383a -r 2c8c6d77f12c libpurple/protocols/msn/soap.h --- a/libpurple/protocols/msn/soap.h Sun Sep 16 18:47:12 2007 +0000 +++ b/libpurple/protocols/msn/soap.h Wed Sep 19 06:08:42 2007 +0000 @@ -29,8 +29,10 @@ #define MSN_SOAP_READ_BUFF_SIZE 8192 /* define this to debug the communications with the SOAP server */ -/* #define MSN_SOAP_DEBUG */ +/* #define MSN_SOAP_DEBUG */ +#define MSN_SOAP_READ 1 +#define MSN_SOAP_WRITE 2 typedef enum { @@ -41,13 +43,18 @@ MSN_SOAP_CONNECTED_IDLE }MsnSoapStep; -/*MSN SoapRequest structure*/ +/* MSN SoapRequest structure*/ typedef struct _MsnSoapReq MsnSoapReq; -/*MSN Https connection structure*/ +/* MSN Https connection structure*/ typedef struct _MsnSoapConn MsnSoapConn; typedef void (*MsnSoapConnectInitFunction)(MsnSoapConn *); +typedef gboolean (*MsnSoapReadCbFunction)(MsnSoapConn *); +typedef void (*MsnSoapWrittenCbFunction)(MsnSoapConn *); + +typedef gboolean (*MsnSoapSslConnectCbFunction)(MsnSoapConn *, PurpleSslConnection *); +typedef void (*MsnSoapSslErrorCbFunction)(MsnSoapConn *, PurpleSslConnection *, PurpleSslErrorType); struct _MsnSoapReq{ @@ -61,8 +68,9 @@ char *body; gpointer data_cb; - PurpleInputFunction read_cb; - PurpleInputFunction written_cb; + MsnSoapReadCbFunction read_cb; + MsnSoapWrittenCbFunction written_cb; + MsnSoapConnectInitFunction connect_init; }; struct _MsnSoapConn{ @@ -81,9 +89,9 @@ /*SSL connection*/ PurpleSslConnection *gsc; /*ssl connection callback*/ - PurpleSslInputFunction connect_cb; + MsnSoapSslConnectCbFunction connect_cb; /*ssl error callback*/ - PurpleSslErrorFunction error_cb; + MsnSoapSslErrorCbFunction error_cb; /*read handler*/ guint input_handler; @@ -97,13 +105,13 @@ /*write buffer*/ char *write_buf; gsize written_len; - PurpleInputFunction written_cb; + MsnSoapWrittenCbFunction written_cb; /*read buffer*/ char *read_buf; gsize read_len; gsize need_to_read; - PurpleInputFunction read_cb; + MsnSoapReadCbFunction read_cb; gpointer data_cb; @@ -118,8 +126,9 @@ MsnSoapReq *msn_soap_request_new(const char *host, const char *post_url, const char *soap_action, const char *body, const gpointer data_cb, - PurpleInputFunction read_cb, - PurpleInputFunction written_cb); + MsnSoapReadCbFunction read_cb, + MsnSoapWrittenCbFunction written_cb, + MsnSoapConnectInitFunction connect_init); void msn_soap_request_free(MsnSoapReq *request); void msn_soap_post_request(MsnSoapConn *soapconn,MsnSoapReq *request); @@ -132,24 +141,27 @@ void msn_soap_destroy(MsnSoapConn *soapconn); /*init a soap conneciton */ -void msn_soap_init(MsnSoapConn *soapconn,char * host,int ssl,PurpleSslInputFunction connect_cb,PurpleSslErrorFunction error_cb); +void msn_soap_init(MsnSoapConn *soapconn, char * host, int ssl, + MsnSoapSslConnectCbFunction connect_cb, + MsnSoapSslErrorCbFunction error_cb); void msn_soap_connect(MsnSoapConn *soapconn); void msn_soap_close(MsnSoapConn *soapconn); /*write to soap*/ -void msn_soap_write(MsnSoapConn * soapconn, char *write_buf, PurpleInputFunction written_cb); -void msn_soap_post(MsnSoapConn *soapconn,MsnSoapReq *request,MsnSoapConnectInitFunction msn_soap_init_func); +void msn_soap_write(MsnSoapConn * soapconn, char *write_buf, MsnSoapWrittenCbFunction written_cb); +void msn_soap_post(MsnSoapConn *soapconn,MsnSoapReq *request); void msn_soap_free_read_buf(MsnSoapConn *soapconn); void msn_soap_free_write_buf(MsnSoapConn *soapconn); void msn_soap_connect_cb(gpointer data, PurpleSslConnection *gsc, PurpleInputCondition cond); void msn_soap_read_cb(gpointer data, gint source, PurpleInputCondition cond); -/*clean the unhandled request*/ -void msn_soap_clean_unhandled_request(MsnSoapConn *soapconn); +/*clean the unhandled requests*/ +void msn_soap_clean_unhandled_requests(MsnSoapConn *soapconn); /*check if the soap connection is connected*/ int msn_soap_connected(MsnSoapConn *soapconn); +void msn_soap_set_process_step(MsnSoapConn *soapconn, MsnSoapStep step); #endif/*_MSN_SOAP_H_*/ diff -r 5bef3197383a -r 2c8c6d77f12c libpurple/protocols/msn/userlist.c --- a/libpurple/protocols/msn/userlist.c Sun Sep 16 18:47:12 2007 +0000 +++ b/libpurple/protocols/msn/userlist.c Wed Sep 19 06:08:42 2007 +0000 @@ -493,6 +493,29 @@ return NULL; } +MsnUser * +msn_userlist_find_user_with_id(MsnUserList *userlist, const char *uid) +{ + GList *l; + + g_return_val_if_fail(uid != NULL, NULL); + + for (l = userlist->users; l != NULL; l = l->next) + { + MsnUser *user = (MsnUser *)l->data; + + if (user->uid == NULL) { + continue; + } + + if ( !g_strcasecmp(uid, user->uid) ) { + return user; + } + } + + return NULL; +} + void msn_userlist_add_group(MsnUserList *userlist, MsnGroup *group) { diff -r 5bef3197383a -r 2c8c6d77f12c libpurple/protocols/msn/userlist.h --- a/libpurple/protocols/msn/userlist.h Sun Sep 16 18:47:12 2007 +0000 +++ b/libpurple/protocols/msn/userlist.h Wed Sep 19 06:08:42 2007 +0000 @@ -79,6 +79,7 @@ MsnUser * msn_userlist_find_user(MsnUserList *userlist, const char *passport); MsnUser * msn_userlist_find_add_user(MsnUserList *userlist, const char *passport, const char *userName); +MsnUser * msn_userlist_find_user_with_id(MsnUserList *userlist, const char *uid); void msn_userlist_add_group(MsnUserList *userlist, MsnGroup *group); void msn_userlist_remove_group(MsnUserList *userlist, MsnGroup *group);