summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos Silva <typ0@pidgin.im>2007-09-19 06:08:42 +0000
committerCarlos Silva <typ0@pidgin.im>2007-09-19 06:08:42 +0000
commitac446d6a2a766d4efda28c894163591fc4f5513e (patch)
tree30c732abc9b3260f063dfa811aa64ebb793f6e70
parent37d1d2f51724beb32ce14030ef53a828ae82617d (diff)
downloadpidgin-ac446d6a2a766d4efda28c894163591fc4f5513e.tar.gz
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.
-rw-r--r--libpurple/protocols/msn/contact.c353
-rw-r--r--libpurple/protocols/msn/contact.h2
-rw-r--r--libpurple/protocols/msn/nexus.c50
-rw-r--r--libpurple/protocols/msn/oim.c169
-rw-r--r--libpurple/protocols/msn/soap.c394
-rw-r--r--libpurple/protocols/msn/soap.h44
-rw-r--r--libpurple/protocols/msn/userlist.c23
-rw-r--r--libpurple/protocols/msn/userlist.h1
8 files changed, 616 insertions, 420 deletions
diff --git a/libpurple/protocols/msn/contact.c b/libpurple/protocols/msn/contact.c
index b8e60bdbd5..3e4f9dc00b 100644
--- a/libpurple/protocols/msn/contact.c
+++ b/libpurple/protocols/msn/contact.c
@@ -83,6 +83,9 @@ msn_callback_state_free(MsnCallbackState *state)
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 @@ msn_callback_state_free(MsnCallbackState *state)
if (state->guid != NULL)
g_free(state->guid);
-
+
g_free(state);
}
@@ -112,6 +115,22 @@ msn_callback_state_set_who(MsnCallbackState *state, const gchar *who)
}
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 @@ msn_callback_state_set_action(MsnCallbackState *state, MsnCallbackAction action)
/*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_login_error_cb(PurpleSslConnection *gsc, PurpleSslErrorType error, v
}
/*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 @@ msn_get_user_type(char * type)
}
/* 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 @@ msn_create_address_book(MsnContact * contact)
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 @@ msn_parse_contact_list(MsnContact * contact)
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 @@ msn_get_contact_list_cb(gpointer data, gint source, PurpleInputCondition cond)
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 @@ msn_get_contact_list_cb(gpointer data, gint source, PurpleInputCondition cond)
} 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 @@ msn_get_contact_list(MsnContact * contact, const MsnSoapPartnerScenario partner_
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 @@ msn_parse_addressbook(MsnContact * contact)
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_get_address_cb(gpointer data, gint source, PurpleInputCondition cond)
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_get_address_cb(gpointer data, gint source, PurpleInputCondition cond)
*/
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 @@ msn_get_address_book(MsnContact *contact, const MsnSoapPartnerScenario partner_s
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_add_contact_read_cb(gpointer data, gint source, PurpleInputCondition cond)
}
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 @@ msn_add_contact(MsnContact *contact, MsnCallbackState *state, const char *passpo
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 @@ msn_add_contact_to_group_read_cb(gpointer data, gint source, PurpleInputConditio
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 @@ msn_add_contact_to_group_read_cb(gpointer data, gint source, PurpleInputConditio
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_add_contact_to_group_read_cb(gpointer data, gint source, PurpleInputConditio
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 @@ msn_add_contact_to_group(MsnContact *contact, MsnCallbackState *state,
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 @@ msn_add_contact_to_group(MsnContact *contact, MsnCallbackState *state,
-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;
- if (soapconn->body == NULL)
- return;
+ 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) {
+ msn_callback_state_free(state);
+ return TRUE;
+ }
- // 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 @@ msn_delete_contact(MsnContact *contact, const char *contactId)
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_delete_contact(MsnContact *contact, const char *contactId)
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_del_contact_from_group_read_cb(gpointer data, gint source, PurpleInputCondit
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 @@ msn_del_contact_from_group(MsnContact *contact, const char *passport, const char
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 @@ msn_update_contact(MsnContact *contact, const char* nickname)
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 @@ msn_del_contact_from_list(MsnContact *contact, MsnCallbackState *state,
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_add_contact_to_list_read_cb(gpointer data, gint source, PurpleInputCondition
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 @@ msn_add_contact_to_list(MsnContact *contact, MsnCallbackState *state,
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_get_gleams(MsnContact *contact)
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 @@ msn_get_gleams(MsnContact *contact)
* 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 @@ msn_group_read_cb(gpointer data, gint source, PurpleInputCondition cond)
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_group_read_cb(gpointer data, gint source, PurpleInputCondition cond)
}
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 @@ msn_add_group(MsnSession *session, MsnCallbackState *state, const char* group_na
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 @@ msn_del_group(MsnSession *session, const gchar *group_name)
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 @@ msn_contact_rename_group(MsnSession *session, const char *old_group_name, const
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 @@ void
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 --git a/libpurple/protocols/msn/contact.h b/libpurple/protocols/msn/contact.h
index ebea72f40f..1a70e08f41 100644
--- a/libpurple/protocols/msn/contact.h
+++ b/libpurple/protocols/msn/contact.h
@@ -374,6 +374,7 @@ typedef struct _MsnCallbackState MsnCallbackState;
struct _MsnCallbackState
{
gchar * who;
+ gchar * uid;
gchar * old_group_name;
gchar * new_group_name;
gchar * guid;
@@ -399,6 +400,7 @@ void msn_contact_destroy(MsnContact *contact);
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 --git a/libpurple/protocols/msn/nexus.c b/libpurple/protocols/msn/nexus.c
index 761c7f473a..676ff60181 100644
--- a/libpurple/protocols/msn/nexus.c
+++ b/libpurple/protocols/msn/nexus.c
@@ -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 @@ nexus_write_cb(gpointer data, gint source, PurpleInputCondition cond)
* 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 @@ nexus_login_error_cb(PurpleSslConnection *gsc, PurpleSslErrorType error, void *d
}
/*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 @@ nexus_login_read_cb(gpointer data, gint source, PurpleInputCondition cond)
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 @@ nexus_login_read_cb(gpointer data, gint source, PurpleInputCondition cond)
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 @@ nexus_login_connect_cb(gpointer data, PurpleSslConnection *gsc,
#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 @@ nexus_login_connect_cb(gpointer data, PurpleSslConnection *gsc,
purple_ssl_close(gsc);
msn_nexus_destroy(nexus);
session->nexus = NULL;
- return;
+ return FALSE;
}
/*
@@ -328,10 +323,10 @@ nexus_login_connect_cb(gpointer data, PurpleSslConnection *gsc,
"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 @@ nexus_login_connect_cb(gpointer data, PurpleSslConnection *gsc,
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 @@ void
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 --git a/libpurple/protocols/msn/oim.c b/libpurple/protocols/msn/oim.c
index 3054d26920..1b639d5a89 100644
--- a/libpurple/protocols/msn/oim.c
+++ b/libpurple/protocols/msn/oim.c
@@ -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 @@ msn_oim_msg_to_str(MsnOim *oim, const char *body)
{
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 @@ msn_oim_msg_to_str(MsnOim *oim, const char *body)
/*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_send_error_cb(PurpleSslConnection *gsc, PurpleSslErrorType error, void *
}
/*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 @@ msn_oim_send_process(MsnOim *oim, const char *body, int len)
/*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 @@ msn_oim_send_process(MsnOim *oim, const char *body, int len)
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 @@ msn_oim_send_process(MsnOim *oim, const char *body, int len)
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 @@ oim_send_process_fail:
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 @@ msn_oim_send_msg(MsnOim *oim)
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&amp;p=%s",
oim->session->passport_info.t,
oim->session->passport_info.p
@@ -299,10 +297,10 @@ msn_oim_send_msg(MsnOim *oim)
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 @@ msn_oim_send_msg(MsnOim *oim)
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 @@ msn_oim_send_msg(MsnOim *oim)
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 @@ msn_oim_post_delete_msg(MsnOim *oim,const char *msgid)
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 @@ msn_oim_post_delete_msg(MsnOim *oim,const char *msgid)
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 @@ msn_oim_post_delete_msg(MsnOim *oim,const char *msgid)
* **************************************/
/*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("MSN OIM","Connected and ready to get OIM!\n");
- purple_debug_info("MSNP14","oim get SOAP Server connected!\n");
+ return TRUE;
}
/* like purple_str_to_time, but different. The format of the timestamp
@@ -485,7 +481,7 @@ msn_oim_parse_timestamp(const char *timestamp)
}
}
- 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_oim_report_to_user(MsnOim *oim, const char *msg_str)
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 @@ msn_oim_report_to_user(MsnOim *oim, const char *msg_str)
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 @@ msn_oim_report_to_user(MsnOim *oim, const char *msg_str)
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 @@ msn_oim_get_process(MsnOim *oim, const char *oim_msg)
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 @@ msn_parse_oim_msg(MsnOim *oim,const char *xmlmsg)
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 @@ msn_parse_oim_msg(MsnOim *oim,const char *xmlmsg)
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 @@ msn_oim_post_single_get_msg(MsnOim *oim,const char *msgid)
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 @@ msn_oim_post_single_get_msg(MsnOim *oim,const char *msgid)
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 --git a/libpurple/protocols/msn/soap.c b/libpurple/protocols/msn/soap.c
index d013462db7..a2109e8061 100644
--- a/libpurple/protocols/msn/soap.c
+++ b/libpurple/protocols/msn/soap.c
@@ -34,6 +34,18 @@ void msn_soap_set_process_step(MsnSoapConn *soapconn, MsnSoapStep step);
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 @@ msn_soap_new(MsnSession *session,gpointer data,int sslconn)
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 @@ msn_soap_connect_cb(gpointer data, PurpleSslConnection *gsc,
{
MsnSoapConn * soapconn;
MsnSession *session;
+ gboolean soapconn_is_valid = FALSE;
purple_debug_misc("MSN SOAP","SOAP server connection established!\n");
@@ -76,12 +90,17 @@ msn_soap_connect_cb(gpointer data, PurpleSslConnection *gsc,
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);
+ }
+
+ if (!soapconn_is_valid) {
+ return;
}
- msn_soap_set_process_step(soapconn,MSN_SOAP_CONNECTED);
/*we do the SOAP request here*/
msn_soap_post_head_request(soapconn);
}
@@ -93,20 +112,24 @@ msn_soap_error_cb(PurpleSslConnection *gsc, PurpleSslErrorType error, void *data
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 @@ msn_soap_init(MsnSoapConn *soapconn,char * host,int ssl,
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 @@ msn_soap_clean_unhandled_request(MsnSoapConn *soapconn)
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_destroy(MsnSoapConn *soapconn)
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 @@ msn_soap_destroy(MsnSoapConn *soapconn)
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 @@ msn_soap_read(MsnSoapConn *soapconn)
"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 @@ msn_soap_read_cb(gpointer data, gint source, PurpleInputCondition cond)
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 @@ msn_soap_read_cb(gpointer data, gint source, PurpleInputCondition cond)
if ((c = strchr(location, '\r')) != NULL)
*c = '\0';
+ else
+ return;
/* Skip the http:// */
if ((c = strchr(location, '/')) != NULL)
@@ -332,10 +380,18 @@ msn_soap_read_cb(gpointer data, gint source, PurpleInputCondition cond)
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 @@ msn_soap_read_cb(gpointer data, gint source, PurpleInputCondition cond)
{
char *location, *c;
- location = strstr(soapconn->read_buf, "<psf:redirectUrl>");
+ if ( (location = strstr(soapconn->read_buf, "<psf:redirectUrl>") ) == NULL)
+ return;
+
/* Omit the tag preceding the URL */
location += strlen("<psf:redirectUrl>");
- 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, "</psf:redirectUrl>")) != NULL )
*c = '\0';
+ else
+ return;
if ( (c = strstr(location, "/")) != NULL )
{
@@ -369,10 +427,18 @@ msn_soap_read_cb(gpointer data, gint source, PurpleInputCondition cond)
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 @@ msn_soap_read_cb(gpointer data, gint source, PurpleInputCondition cond)
else if (strstr(soapconn->read_buf,
"<faultcode>wsse:FailedAuthentication</faultcode>") != NULL)
{
- char *faultstring;
+ gchar *faultstring;
faultstring = strstr(soapconn->read_buf, "<faultstring>");
if (faultstring != NULL)
{
+ gchar *c;
faultstring += strlen("<faultstring>");
- *strstr(soapconn->read_buf, "</faultstring>") = '\0';
+ if (faultstring < soapconn->read_buf + soapconn->read_len) {
+ c = strstr(soapconn->read_buf, "</faultstring>");
+ 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 @@ msn_soap_read_cb(gpointer data, gint source, PurpleInputCondition cond)
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);
- /*setup the conn body */
- soapconn->body = body_start;
- soapconn->body_len = atoi(body_len);
- g_free(body_len);
+ 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);
#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_is_valid = soapconn->read_cb(soapconn);
+ }
+
+ if (!soapconn_is_valid) {
+ return;
+ }
- /*call the read callback*/
- if ( soapconn->read_cb != NULL ) {
- soapconn->read_cb(soapconn, source, 0);
- }
- }
+ /* dispatch next request in queue */
+ msn_soap_post(soapconn, NULL);
+ }
return;
}
@@ -524,9 +613,11 @@ msn_soap_write_cb(gpointer data, gint source, PurpleInputCondition cond)
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 @@ msn_soap_write_cb(gpointer data, gint source, PurpleInputCondition cond)
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 @@ msn_soap_write_cb(gpointer data, gint source, PurpleInputCondition cond)
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 @@ msn_soap_write_cb(gpointer data, gint source, PurpleInputCondition cond)
* 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 @@ msn_soap_write(MsnSoapConn * soapconn, char *write_buf, PurpleInputFunction writ
/*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 @@ msn_soap_write(MsnSoapConn * soapconn, char *write_buf, PurpleInputFunction writ
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 @@ msn_soap_request_new(const char *host,const char *post_url,const char *soap_acti
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 @@ msn_soap_request_free(MsnSoapReq *request)
g_free(request->body);
request->read_cb = NULL;
request->written_cb = NULL;
+ request->connect_init = NULL;
g_free(request);
}
@@ -632,18 +740,24 @@ msn_soap_request_free(MsnSoapReq *request)
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);
+
+ if (soapconn->step == MSN_SOAP_CONNECTED ||
+ soapconn->step == MSN_SOAP_CONNECTED_IDLE) {
- 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);
+ 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);
+ }
+ } 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 @@ msn_soap_post_head_request(MsnSoapConn *soapconn)
* 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 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);
+ 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)) {
+
+ /*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 --git a/libpurple/protocols/msn/soap.h b/libpurple/protocols/msn/soap.h
index 373a12809e..679f0ac987 100644
--- a/libpurple/protocols/msn/soap.h
+++ b/libpurple/protocols/msn/soap.h
@@ -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 @@ typedef enum
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 @@ struct _MsnSoapReq{
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 @@ struct _MsnSoapConn{
/*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 @@ struct _MsnSoapConn{
/*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 @@ struct _MsnSoapConn{
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 @@ MsnSoapConn *msn_soap_new(MsnSession *session,gpointer data,int sslconn);
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 --git a/libpurple/protocols/msn/userlist.c b/libpurple/protocols/msn/userlist.c
index b0bc83f4ec..5fc505eedd 100644
--- a/libpurple/protocols/msn/userlist.c
+++ b/libpurple/protocols/msn/userlist.c
@@ -493,6 +493,29 @@ msn_userlist_find_user(MsnUserList *userlist, const char *passport)
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 --git a/libpurple/protocols/msn/userlist.h b/libpurple/protocols/msn/userlist.h
index a9ad55b00e..2893b13d9e 100644
--- a/libpurple/protocols/msn/userlist.h
+++ b/libpurple/protocols/msn/userlist.h
@@ -79,6 +79,7 @@ void msn_userlist_remove_user(MsnUserList *userlist, MsnUser *user);
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);