Mercurial > pidgin
changeset 19784:bc30c6270d9f
[gaim-migrate @ 16473]
add the Framework of SOAP request
Now can retrieve the Contact via SOAP Request.
so many bug still exist!
commited by MaYuan<mayuan2006@gmail.com>
committer: Ethan Blanton <elb@pidgin.im>
author | Ma Yuan <mayuan2006@gmail.com> |
---|---|
date | Sun, 09 Jul 2006 16:48:25 +0000 |
parents | 995aea35b05c |
children | 852b32710df0 |
files | src/protocols/msn/Makefile.am src/protocols/msn/cmdproc.c src/protocols/msn/command.c src/protocols/msn/contact.c src/protocols/msn/contact.h src/protocols/msn/msg.c src/protocols/msn/msn-utils.c src/protocols/msn/msn.c src/protocols/msn/nexus.c src/protocols/msn/nexus.h src/protocols/msn/notification.c src/protocols/msn/notification.h src/protocols/msn/session.c src/protocols/msn/session.h src/protocols/msn/soap.c src/protocols/msn/soap.h src/protocols/msn/table.c |
diffstat | 17 files changed, 875 insertions(+), 271 deletions(-) [+] |
line wrap: on
line diff
--- a/src/protocols/msn/Makefile.am Sat Jun 24 12:04:32 2006 +0000 +++ b/src/protocols/msn/Makefile.am Sun Jul 09 16:48:25 2006 +0000 @@ -8,6 +8,8 @@ cmdproc.h \ command.c \ command.h \ + contact.c\ + contact.h\ dialog.c \ dialog.h \ directconn.c \ @@ -46,6 +48,8 @@ slpmsg.h \ slpsession.c \ slpsession.h \ + soap.c\ + soap.h\ state.c \ state.h \ switchboard.c \
--- a/src/protocols/msn/cmdproc.c Sat Jun 24 12:04:32 2006 +0000 +++ b/src/protocols/msn/cmdproc.c Sun Jul 09 16:48:25 2006 +0000 @@ -127,8 +127,7 @@ trans->callbacks = g_hash_table_lookup(cmdproc->cbs_table->cmds, trans->command); - if (trans->payload != NULL) - { + if (trans->payload != NULL){ data = g_realloc(data, len + trans->payload_len); memcpy(data + len, trans->payload, trans->payload_len); len += trans->payload_len;
--- a/src/protocols/msn/command.c Sat Jun 24 12:04:32 2006 +0000 +++ b/src/protocols/msn/command.c Sun Jul 09 16:48:25 2006 +0000 @@ -42,7 +42,7 @@ * else return FALSE */ static gboolean -isPayloadCmd(char *str) +msn_check_payload_cmd(char *str) { if( (!strcmp(str,"ADL")) || (!strcmp(str,"GCF")) || @@ -60,7 +60,7 @@ } /*get the payload positon*/ -int getPayloadPosition(char *str) +int msn_get_payload_position(char *str) { /*because MSG has "MSG hotmail hotmail [payload length]"*/ if(!(strcmp(str,"MSG"))){ @@ -72,11 +72,11 @@ * set command Payload length */ int -setPayloadLen(MsnCommand *cmd) +msn_set_payload_len(MsnCommand *cmd) { char * param; - if(isPayloadCmd(cmd->command)){ + if(msn_check_payload_cmd(cmd->command)){ if(!(strcmp(cmd->command,"MSG"))){ param = cmd->params[2]; }else{ @@ -121,7 +121,7 @@ } /*add payload Length checking*/ - setPayloadLen(cmd); + msn_set_payload_len(cmd); gaim_debug_info("MaYuan","get payload len:%d\n",cmd->payload_len); msn_command_ref(cmd);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/protocols/msn/contact.c Sun Jul 09 16:48:25 2006 +0000 @@ -0,0 +1,220 @@ +/** + * @file contact.c + * get MSN contacts via SOAP request + * created by MaYuan<mayuan2006@gmail.com> + * + * gaim + * + * Gaim is the legal property of its developers, whose names are too numerous + * to list here. Please refer to the COPYRIGHT file distributed with this + * source distribution. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "msn.h" +#include "soap.h" +#include "contact.h" +#include "xmlnode.h" + +/*new a contact*/ +MsnContact * +msn_contact_new(MsnSession *session) +{ + MsnContact *contact; + + contact = g_new0(MsnContact, 1); + contact->session = session; + contact->soapconn = msn_soap_new(session); + contact->soapconn->parent = contact; + contact->soapconn->ssl_conn = 1; + + return contact; +} + +/*destroy the contact*/ +void +msn_contact_destroy(MsnContact *contact) +{ + msn_soap_destroy(contact->soapconn); + g_free(contact); +} + +/*contact SOAP server login error*/ +static void +msn_contact_login_error_cb(GaimSslConnection *gsc, GaimSslErrorType error, void *data) +{ + MsnSoapConn *soapconn = data; + MsnSession *session; + + session = soapconn->session; + g_return_if_fail(session != NULL); + + msn_session_set_error(session, MSN_ERROR_SERV_DOWN, _("Unable to connect to contact server")); +} + +/*msn contact SOAP server connect process*/ +static void +msn_contact_login_connect_cb(gpointer data, GaimSslConnection *gsc, + GaimInputCondition cond) +{ + MsnSoapConn *soapconn = data; + MsnSession * session; + MsnContact *contact; + + contact = soapconn->parent; + g_return_if_fail(contact != NULL); + + session = contact->session; + g_return_if_fail(session != NULL); + + /*login ok!We can retrieve the contact list*/ + msn_get_contact_list(contact); +} + +static void +msn_parse_contact_list(MsnContact * contact) +{ + xmlnode * node,*envelop,*body,*response,*result,*services,*service,*memberships; + xmlnode *membershipnode,*members,*member,*passport,*role; + int len; + + gaim_debug_misc("xml","parse contact list:{%s}\nsize:%d\n",contact->soapconn->body,contact->soapconn->body_len); + node = xmlnode_from_str(contact->soapconn->body, contact->soapconn->body_len); +// node = xmlnode_from_str(contact->soapconn->body, -1); + + if(node == NULL){ + gaim_debug_misc("xml","parse from str err!\n"); + return; + } + gaim_debug_misc("xml","node{%p},name:%s,child:%s,last:%s\n",node,node->name,node->child->name,node->lastchild->name); + body = xmlnode_get_child(node,"Body"); + gaim_debug_misc("xml","body{%p},name:%s\n",body,body->name); + response = xmlnode_get_child(body,"FindMembershipResponse"); + gaim_debug_misc("xml","response{%p},name:%s\n",response,response->name); + result =xmlnode_get_child(response,"FindMembershipResult"); + gaim_debug_misc("xml","result{%p},name:%s\n",result,result->name); + services =xmlnode_get_child(result,"Services"); + gaim_debug_misc("xml","services{%p},name:%s\n",services,services->name); + service =xmlnode_get_child(services,"Service"); + gaim_debug_misc("xml","service{%p},name:%s\n",service,service->name); + memberships =xmlnode_get_child(service,"Memberships"); + gaim_debug_misc("xml","memberships{%p},name:%s\n",memberships,memberships->name); + for(membershipnode = xmlnode_get_child(memberships, "Membership"); membershipnode; + membershipnode = xmlnode_get_next_twin(membershipnode)){ + role = xmlnode_get_child(membershipnode,"MemberRole"); + gaim_debug_misc("memberrole","role:%s\n",xmlnode_get_data(role)); + members = xmlnode_get_child(membershipnode,"Members"); + for(member = xmlnode_get_child(members, "Member"); member; + member = xmlnode_get_next_twin(member)){ + passport = xmlnode_get_child(member,"PassportName"); + gaim_debug_misc("Passport","name:%s\n",xmlnode_get_data(passport)); + } + } + + xmlnode_free(node); +} + +static void +msn_get_contact_list_cb(gpointer data, gint source, GaimInputCondition cond) +{ + MsnSoapConn * soapconn = data; + MsnContact *contact; + MsnSession *session; + + contact = soapconn->parent; + g_return_if_fail(contact != NULL); + session = soapconn->session; + g_return_if_fail(session != NULL); + +// gaim_debug_misc("msn", "soap contact server Reply: {%s}\n", soapconn->read_buf); + msn_parse_contact_list(contact); +} + +static void +msn_contact_written_cb(gpointer data, gint source, GaimInputCondition cond) +{ + MsnSoapConn * soapconn = data; + + gaim_debug_info("MaYuan","finish contact written\n"); + soapconn->read_cb = msn_get_contact_list_cb; + msn_soap_read_cb(data,source,cond); +} + +void +msn_get_contact_list(MsnContact * contact) +{ + char * soap_head = NULL; + char * soap_body = NULL; + char * request_str = NULL; + + gaim_debug_info("MaYuan","msn_get_contact_list()...\n"); + contact->soapconn->login_path = g_strdup(MSN_GET_CONTACT_POST_URL); + soap_body = g_strdup_printf(MSN_GET_CONTACT_TEMPLATE); + soap_head = g_strdup_printf( + "POST %s HTTP/1.1\r\n" + "SOAPAction: http://www.msn.com/webservices/AddressBook/FindMembership\r\n" + "Content-Type:text/xml; charset=utf-8\r\n" + "Cookie: MSPAuth=%s\r\n" + "User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)\r\n" + "Accept: text/*\r\n" + "Host: %s\r\n" + "Content-Length: %d\r\n" + "Connection: Keep-Alive\r\n" + "Cache-Control: no-cache\r\n\r\n", + contact->soapconn->login_path, + contact->session->passport_info.mspauth, + contact->soapconn->login_host, + strlen(soap_body) + ); + request_str = g_strdup_printf("%s%s", soap_head,soap_body); + g_free(soap_head); + g_free(soap_body); + +// gaim_debug_info("MaYuan","send to contact server{%s}\n",request_str); + msn_soap_write(contact->soapconn,request_str,msn_contact_written_cb); +} + +msn_add_contact() +{ +} + +msn_delete_contact() +{ +} + +msn_block_contact() +{ +} + +msn_unblock_contact() +{ +} + +msn_get_gleams() +{ +} + +void +msn_contact_connect(MsnContact *contact) +{ + /* Authenticate via Windows Live ID. */ + gaim_debug_info("MaYuan","msn_contact_connect...\n"); + + msn_soap_init(contact->soapconn,MSN_CONTACT_SERVER,1, + msn_contact_login_connect_cb, + msn_contact_login_error_cb); +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/protocols/msn/contact.h Sun Jul 09 16:48:25 2006 +0000 @@ -0,0 +1,118 @@ +/** + * @file contact.h Header file for contact.c + * Author + * MaYuan<mayuan2006@gmail.com> + * gaim + * + * Gaim is the legal property of its developers, whose names are too numerous + * to list here. Please refer to the COPYRIGHT file distributed with this + * source distribution. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef _MSN_CONTACT_H_ +#define _MSN_CONTACT_H_ + +#define MSN_CONTACT_SERVER "contacts.msn.com" + +#define MSN_GET_CONTACT_POST_URL "/abservice/SharingService.asmx" +#define MSN_GET_CONTACT_TEMPLATE "<?xml version='1.0' encoding='utf-8'?>"\ +"<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">"\ + "<soap:Header xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">"\ + "<ABApplicationHeader xmlns=\"http://www.msn.com/webservices/AddressBook\">"\ + "<ApplicationId xmlns=\"http://www.msn.com/webservices/AddressBook\">09607671-1C32-421F-A6A6-CBFAA51AB5F4</ApplicationId>"\ + "<IsMigration xmlns=\"http://www.msn.com/webservices/AddressBook\">false</IsMigration>"\ + "<PartnerScenario xmlns=\"http://www.msn.com/webservices/AddressBook\">Initial</PartnerScenario>"\ + "</ABApplicationHeader>"\ + "<ABAuthHeader xmlns=\"http://www.msn.com/webservices/AddressBook\">"\ + "<ManagedGroupRequest xmlns=\"http://www.msn.com/webservices/AddressBook\">false</ManagedGroupRequest>"\ + "</ABAuthHeader>"\ + "</soap:Header>"\ + "<soap:Body xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">"\ + "<FindMembership xmlns=\"http://www.msn.com/webservices/AddressBook\">"\ + "<serviceFilter xmlns=\"http://www.msn.com/webservices/AddressBook\">"\ + "<Types xmlns=\"http://www.msn.com/webservices/AddressBook\">"\ + "<ServiceType xmlns=\"http://www.msn.com/webservices/AddressBook\">Messenger</ServiceType>"\ + "<ServiceType xmlns=\"http://www.msn.com/webservices/AddressBook\">Invitation</ServiceType>"\ + "<ServiceType xmlns=\"http://www.msn.com/webservices/AddressBook\">SocialNetwork</ServiceType>"\ + "<ServiceType xmlns=\"http://www.msn.com/webservices/AddressBook\">Space</ServiceType>"\ + "<ServiceType xmlns=\"http://www.msn.com/webservices/AddressBook\">Profile</ServiceType>"\ + "</Types>"\ + "</serviceFilter>"\ + "</FindMembership>"\ + "</soap:Body>"\ +"</soap:Envelope>" + +#define MSN_ADDRESS_TEMPLATE "<?xml version=\"1.0\" encoding=\"utf-8\"?>"\ +"<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soapenc=\"http://schemas.xmlsoap.org/soap/encoding/\">"\ + "<soap:Header>"\ + "<ABApplicationHeader xmlns=\"http://www.msn.com/webservices/AddressBook\">"\ + "<ApplicationId>09607671-1C32-421F-A6A6-CBFAA51AB5F4</ApplicationId>"\ + "<IsMigration>false</IsMigration>"\ + "<PartnerScenario>Initial</PartnerScenario>"\ + "</ABApplicationHeader>"\ + "<ABAuthHeader xmlns=\"http://www.msn.com/webservices/AddressBook\">"\ + "<ManagedGroupRequest>false</ManagedGroupRequest>"\ + "</ABAuthHeader>"\ + "</soap:Header>"\ + "<soap:Body>"\ + "<ABFindAll xmlns=\"http://www.msn.com/webservices/AddressBook\">"\ + "<abId>00000000-0000-0000-0000-000000000000</abId>"\ + "<abView>Full</abView>"\ + "</ABFindAll>"\ + "</soap:Body>"\ +"</soap:Envelope>" + +#define MSN_GLEAMS_TEMPLATE = "<?xml version=\"1.0\" encoding=\"utf-8\"?>"\ +"<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soapenc=\"http://schemas.xmlsoap.org/soap/encoding/\">"\ + "<soap:Header>"\ + "<ABApplicationHeader xmlns=\"http://www.msn.com/webservices/AddressBook\">"\ + "<ApplicationId>09607671-1C32-421F-A6A6-CBFAA51AB5F4</ApplicationId>"\ + "<IsMigration>false</IsMigration>"\ + "<PartnerScenario>Initial</PartnerScenario>"\ + "</ABApplicationHeader>"\ + "<ABAuthHeader xmlns=\"http://www.msn.com/webservices/AddressBook\">"\ + "<ManagedGroupRequest>false</ManagedGroupRequest>"\ + "</ABAuthHeader>"\ + "</soap:Header>"\ + "<soap:Body>"\ + "<ABFindAll xmlns=\"http://www.msn.com/webservices/AddressBook\">"\ + "<abId>00000000-0000-0000-0000-000000000000</abId>"\ + "<abView>Full</abView>"\ + "<dynamicItemView>Gleam</dynamicItemView>"\ + "<dynamicItemLastChange>0001-01-01T00:00:00.0000000-08:00</dynamicItemLastChange>"\ + "</ABFindAll>"\ + "</soap:Body>"\ +"</soap:Envelope>" + +typedef struct _MsnContact MsnContact; + +struct _MsnContact +{ + MsnSession *session; + + MsnSoapConn *soapconn; +}; + +/*function prototype*/ +MsnContact * msn_contact_new(MsnSession *session); +void msn_get_contact_list(MsnContact * contact); +void msn_contact_connect(MsnContact *contact); + +void msn_contact_destroy(MsnContact *contact); +void msn_get_contact_list(MsnContact * contact); + +#endif/* _MSN_CMDPROC_H_*/ +
--- a/src/protocols/msn/msg.c Sat Jun 24 12:04:32 2006 +0000 +++ b/src/protocols/msn/msg.c Sun Jul 09 16:48:25 2006 +0000 @@ -231,8 +231,7 @@ elems = g_strsplit(tmp, "\r\n", 0); - for (cur = elems; *cur != NULL; cur++) - { + for (cur = elems; *cur != NULL; cur++){ const char *key, *value; tokens = g_strsplit(*cur, ": ", 2); @@ -240,20 +239,17 @@ key = tokens[0]; value = tokens[1]; - if (!strcmp(key, "MIME-Version")) - { + /*if not MIME content ,then return*/ + if (!strcmp(key, "MIME-Version")){ g_strfreev(tokens); continue; } - if (!strcmp(key, "Content-Type")) - { + if (!strcmp(key, "Content-Type")){ char *charset, *c; - if ((c = strchr(value, ';')) != NULL) - { - if ((charset = strchr(c, '=')) != NULL) - { + if ((c = strchr(value, ';')) != NULL){ + if ((charset = strchr(c, '=')) != NULL) { charset++; msn_message_set_charset(msg, charset); } @@ -262,9 +258,7 @@ } msn_message_set_content_type(msg, value); - } - else - { + }else{ msn_message_set_attr(msg, key, value); } @@ -280,8 +274,7 @@ content_type = msn_message_get_content_type(msg); if (content_type != NULL && - !strcmp(content_type, "application/x-msnmsgrp2p")) - { + !strcmp(content_type, "application/x-msnmsgrp2p")){ MsnSlpHeader header; MsnSlpFooter footer; int body_len; @@ -323,9 +316,7 @@ tmp += sizeof(footer); msg->msnslp_footer.value = GUINT32_FROM_BE(footer.value); } - } - else - { + }else{ if (payload_len - (tmp - tmp_base) > 0) { msg->body_len = payload_len - (tmp - tmp_base); msg->body = g_malloc0(msg->body_len + 1); @@ -785,3 +776,4 @@ g_string_free(str, TRUE); } +
--- a/src/protocols/msn/msn-utils.c Sat Jun 24 12:04:32 2006 +0000 +++ b/src/protocols/msn/msn-utils.c Sun Jul 09 16:48:25 2006 +0000 @@ -351,14 +351,14 @@ host = g_strdup(str); - if ((c = strchr(host, ':')) != NULL) - { + if ((c = strchr(host, ':')) != NULL){ *c = '\0'; port = atoi(c + 1); + }else{ + port = 1863; } - else - port = 1863; *ret_host = host; *ret_port = port; } +
--- a/src/protocols/msn/msn.c Sat Jun 24 12:04:32 2006 +0000 +++ b/src/protocols/msn/msn.c Sun Jul 09 16:48:25 2006 +0000 @@ -892,8 +892,7 @@ gc = gaim_account_get_connection(account); - if (gc != NULL) - { + if (gc != NULL){ session = gc->proto_data; msn_change_status(session); }
--- a/src/protocols/msn/nexus.c Sat Jun 24 12:04:32 2006 +0000 +++ b/src/protocols/msn/nexus.c Sun Jul 09 16:48:25 2006 +0000 @@ -22,6 +22,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "msn.h" +#include "soap.h" #include "nexus.h" #include "notification.h" @@ -36,6 +37,10 @@ nexus = g_new0(MsnNexus, 1); nexus->session = session; + nexus->soapconn = msn_soap_new(session); + nexus->soapconn->parent = nexus; + /*we must use SSL connection to do Windows Live ID authentication*/ + nexus->soapconn->ssl_conn = 1; nexus->challenge_data = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); @@ -45,90 +50,14 @@ void msn_nexus_destroy(MsnNexus *nexus) { - g_free(nexus->login_host); - - g_free(nexus->login_path); - if (nexus->challenge_data != NULL) g_hash_table_destroy(nexus->challenge_data); - if (nexus->input_handler > 0) - gaim_input_remove(nexus->input_handler); - g_free(nexus->write_buf); - g_free(nexus->read_buf); - + msn_soap_destroy(nexus->soapconn); g_free(nexus); } /************************************************************************** - * Util - **************************************************************************/ - -static gssize -msn_ssl_read(MsnNexus *nexus) -{ - gssize len; - gssize total_len = 0; - char temp_buf[4096]; - - if((len = gaim_ssl_read(nexus->gsc, temp_buf, - sizeof(temp_buf))) > 0) - { -#if 0 - g_string_append(nexus->read_buf,temp_buf); -#else - total_len += len; - nexus->read_buf = g_realloc(nexus->read_buf, - nexus->read_len + len + 1); - strncpy(nexus->read_buf + nexus->read_len, temp_buf, len); - nexus->read_len += len; - nexus->read_buf[nexus->read_len] = '\0'; -#endif - } -// gaim_debug_info("MaYuan","nexus ssl read:{%s}\n",nexus->read_buf); - return total_len; -} - -static void -nexus_write_cb(gpointer data, gint source, GaimInputCondition cond) -{ - MsnNexus *nexus = data; - int len, total_len; - - total_len = strlen(nexus->write_buf); - - /* - * write the content to SSL server, - * We use SOAP to request Windows Live ID authentication - */ - len = gaim_ssl_write(nexus->gsc, - nexus->write_buf + nexus->written_len, - total_len - nexus->written_len); - - if (len < 0 && errno == EAGAIN) - return; - else if (len <= 0) { - gaim_input_remove(nexus->input_handler); - nexus->input_handler = -1; - /* TODO: notify of the error */ - return; - } - nexus->written_len += len; - - if (nexus->written_len < total_len) - return; - - gaim_input_remove(nexus->input_handler); - nexus->input_handler = -1; - - g_free(nexus->write_buf); - nexus->write_buf = NULL; - nexus->written_len = 0; - - nexus->written_cb(nexus, source, 0); -} - -/************************************************************************** * Login **************************************************************************/ @@ -139,74 +68,38 @@ static void login_error_cb(GaimSslConnection *gsc, GaimSslErrorType error, void *data) { - MsnNexus *nexus; + MsnSoapConn * soapconn = data; MsnSession *session; - nexus = data; - g_return_if_fail(nexus != NULL); - - session = nexus->session; + session = soapconn->session; g_return_if_fail(session != NULL); - msn_session_set_error(session, MSN_ERROR_AUTH, _("Unable to connect")); + msn_session_set_error(session, MSN_ERROR_AUTH, _("Windows Live ID authentication:Unable to connect")); /* the above line will result in nexus being destroyed, so we don't want * to destroy it here, or we'd crash */ } static void -nexus_login_written_cb(gpointer data, gint source, GaimInputCondition cond) +nexus_login_read_cb(gpointer data, gint source, GaimInputCondition cond) { - MsnNexus *nexus = data; + MsnSoapConn * soapconn = data; + MsnNexus *nexus; MsnSession *session; - int len; + nexus = soapconn->parent; + g_return_if_fail(nexus != NULL); session = nexus->session; g_return_if_fail(session != NULL); - if (nexus->input_handler == -1) - nexus->input_handler = gaim_input_add(nexus->gsc->fd, - GAIM_INPUT_READ, nexus_login_written_cb, nexus); + gaim_debug_misc("msn", "TWN Server Reply: {%s}\n", soapconn->read_buf); - /*read the request header*/ - len = msn_ssl_read(nexus); - if (len < 0 && errno == EAGAIN){ - return; - }else if (len < 0) { - gaim_input_remove(nexus->input_handler); - nexus->input_handler = -1; - g_free(nexus->read_buf); - nexus->read_buf = NULL; - nexus->read_len = 0; - /* TODO: error handling */ - return; - } - - if(nexus->read_buf == NULL){ - return; - } - if (g_strstr_len(nexus->read_buf, nexus->read_len, - "</S:Envelope>") == NULL){ - return; - } - - gaim_input_remove(nexus->input_handler); - nexus->input_handler = -1; - gaim_ssl_close(nexus->gsc); - nexus->gsc = NULL; - -// gaim_debug_misc("msn", "TWN Server Reply: {%s}", nexus->read_buf); - - if (strstr(nexus->read_buf, "HTTP/1.1 302") != NULL){ + if (strstr(soapconn->read_buf, "HTTP/1.1 302") != NULL){ /* Redirect. */ char *location, *c; - location = strstr(nexus->read_buf, "Location: "); - if (location == NULL) - { - g_free(nexus->read_buf); - nexus->read_buf = NULL; - nexus->read_len = 0; - + location = strstr(soapconn->read_buf, "Location: "); + if (location == NULL){ + msn_soap_free_read_buf(soapconn); return; } location = strchr(location, ' ') + 1; @@ -218,24 +111,19 @@ if ((c = strchr(location, '/')) != NULL) location = c + 2; - if ((c = strchr(location, '/')) != NULL) - { - g_free(nexus->login_path); - nexus->login_path = g_strdup(c); + if ((c = strchr(location, '/')) != NULL){ + g_free(soapconn->login_path); + soapconn->login_path = g_strdup(c); *c = '\0'; } - - g_free(nexus->login_host); - nexus->login_host = g_strdup(location); + g_free(soapconn->login_host); - gaim_ssl_connect(session->account, nexus->login_host, - GAIM_SSL_DEFAULT_PORT, login_connect_cb, - login_error_cb, nexus); - }else if (strstr(nexus->read_buf, "HTTP/1.1 401 Unauthorized") != NULL){ + msn_soap_init(soapconn,location,1,login_connect_cb,login_error_cb); + }else if (strstr(soapconn->read_buf, "HTTP/1.1 401 Unauthorized") != NULL){ const char *error; - if ((error = strstr(nexus->read_buf, "WWW-Authenticate")) != NULL) { + if ((error = strstr(soapconn->read_buf, "WWW-Authenticate")) != NULL) { if ((error = strstr(error, "cbtxt=")) != NULL){ const char *c; char *temp; @@ -251,67 +139,70 @@ } } msn_session_set_error(session, MSN_ERROR_AUTH, error); - }else if (strstr(nexus->read_buf, "HTTP/1.1 200 OK")){ + }else if (strstr(soapconn->read_buf, "HTTP/1.1 200 OK")){ /*reply OK, we should process the SOAP body*/ char *base, *c; + char *msn_twn_t,*msn_twn_p; char *login_params; - char *length_start,*length_end,*body_len; char **elems, **cur, **tokens; - const char * cert_str; + char * cert_str; - gaim_debug_info("MaYuan","Receive 200\n"); -#if 0 - length_start = strstr(nexus->read_buf, "Content-Length: "); - length_start += strlen("Content-Length: "); - length_end = strstr(length_start, "\r\n"); - body_len = g_strndup(length_start,length_end - length_start); -// gaim_debug_info("MaYuan","body length is :%s\n",body_len); + gaim_debug_info("MaYuan","Windows Live ID Reply OK!\n"); - g_free(body_len); -// g_return_if_fail(body_len != NULL); -#endif //TODO: we should parse it using XML - base = strstr(base, TWN_START_TOKEN); + base = g_strstr_len(soapconn->read_buf, soapconn->read_len, TWN_START_TOKEN); base += strlen(TWN_START_TOKEN); -// gaim_debug_info("MaYuan","base is :%s\n",base); - c = strstr(base, TWN_END_TOKEN); -// gaim_debug_info("MaYuan","c is :%s\n",c); -// gaim_debug_info("MaYuan","len is :%d\n",c-base); + c = g_strstr_len(soapconn->read_buf, soapconn->read_len, TWN_END_TOKEN); login_params = g_strndup(base, c - base); - gaim_debug_info("msn", "TWN Cert: {%s}\n", login_params); +// gaim_debug_info("msn", "TWN Cert: {%s}\n", login_params); /* Parse the challenge data. */ elems = g_strsplit(login_params, "&", 0); for (cur = elems; *cur != NULL; cur++){ tokens = g_strsplit(*cur, "=", 2); - g_hash_table_insert(session->nexus->challenge_data, tokens[0], tokens[1]); + g_hash_table_insert(nexus->challenge_data, tokens[0], tokens[1]); /* Don't free each of the tokens, only the array. */ g_free(tokens); } g_strfreev(elems); - cert_str = g_strdup_printf("t=%s&p=%s", - (char *)g_hash_table_lookup(nexus->challenge_data, "t"), - (char *)g_hash_table_lookup(nexus->challenge_data, "p") - ); + msn_twn_t = (char *)g_hash_table_lookup(nexus->challenge_data, "t"); + msn_twn_p = (char *)g_hash_table_lookup(nexus->challenge_data, "p"); + + /*setup the t and p parameter for session*/ + if (session->passport_info.t != NULL){ + g_free(session->passport_info.t); + } + session->passport_info.t = g_strdup(msn_twn_t); + + if (session->passport_info.p != NULL) + g_free(session->passport_info.p); + session->passport_info.p = g_strdup(msn_twn_p); + + cert_str = g_strdup_printf("t=%s&p=%s",msn_twn_t,msn_twn_p); msn_got_login_params(session, cert_str); + gaim_debug_info("MaYuan","close nexus connection! \n"); g_free(cert_str); -// g_free(body_len); g_free(login_params); -// return; msn_nexus_destroy(nexus); session->nexus = NULL; return; } + msn_soap_free_read_buf(soapconn); +} - g_free(nexus->read_buf); - nexus->read_buf = NULL; - nexus->read_len = 0; +static void +nexus_login_written_cb(gpointer data, gint source, GaimInputCondition cond) +{ + MsnSoapConn * soapconn = data; + + soapconn->read_cb = nexus_login_read_cb; + msn_soap_read_cb(data,source,cond); } @@ -319,26 +210,27 @@ login_connect_cb(gpointer data, GaimSslConnection *gsc, GaimInputCondition cond) { - MsnNexus *nexus; + MsnSoapConn *soapconn; + MsnNexus * nexus; MsnSession *session; char *username, *password; char *request_str, *head, *tail,*challenge_str; - char *buffer = NULL; - guint32 ctint; gaim_debug_info("MaYuan","starting Windows Live ID authentication\n"); - nexus = data; + + soapconn = data; + g_return_if_fail(soapconn != NULL); + + nexus = soapconn->parent; g_return_if_fail(nexus != NULL); - session = nexus->session; + session = soapconn->session; g_return_if_fail(session != NULL); - nexus->gsc = gsc; - msn_session_set_login_step(session, MSN_LOGIN_STEP_GET_COOKIE); + /*prepare the Windows Live ID authentication token*/ username = g_strdup(gaim_account_get_username(session->account)); - password = g_strdup(gaim_connection_get_password(session->account->gc)); // g_strdup(gaim_url_encode(gaim_connection_get_password(session->account->gc))); @@ -360,7 +252,7 @@ /*build the SOAP windows Live ID XML body */ tail = g_strdup_printf(TWN_ENVELOP_TEMPLATE,username,password,challenge_str ); - nexus->login_path = g_strdup(TWN_POST_URL); + soapconn->login_path = g_strdup(TWN_POST_URL); head = g_strdup_printf( "POST %s HTTP/1.1\r\n" "Accept: text/*\r\n" @@ -369,29 +261,18 @@ "Content-Length: %d\r\n" "Connection: Keep-Alive\r\n" "Cache-Control: no-cache\r\n\r\n", - nexus->login_path,nexus->login_host,strlen(tail)); + soapconn->login_path,soapconn->login_host,strlen(tail)); request_str = g_strdup_printf("%s%s", head,tail); -// gaim_debug_misc("msn", "TWN Sending: {%s}\n", request_str); + gaim_debug_misc("msn", "TWN Sending: {%s}\n", request_str); -// g_free(nexus->login_path); - g_free(buffer); g_free(head); g_free(tail); g_free(username); g_free(password); - nexus->write_buf = request_str; - nexus->written_len = 0; - - nexus->read_len = 0; - - nexus->written_cb = nexus_login_written_cb; - - nexus->input_handler = gaim_input_add(gsc->fd, GAIM_INPUT_WRITE, - nexus_write_cb, nexus); - - nexus_write_cb(nexus, gsc->fd, GAIM_INPUT_WRITE); + /*prepare to send the SOAP request*/ + msn_soap_write(soapconn,request_str,nexus_login_written_cb); return; } @@ -404,8 +285,7 @@ { /* Authenticate via Windows Live ID. */ gaim_debug_info("MaYuan","msn_nexus_connect...\n"); - nexus->login_host = g_strdup(TWN_SERVER); - gaim_ssl_connect(nexus->session->account, nexus->login_host, - GAIM_SSL_DEFAULT_PORT, login_connect_cb, login_error_cb, - nexus); + + msn_soap_init(nexus->soapconn,MSN_TWN_SERVER,1,login_connect_cb,login_error_cb); } +
--- a/src/protocols/msn/nexus.h Sat Jun 24 12:04:32 2006 +0000 +++ b/src/protocols/msn/nexus.h Sun Jul 09 16:48:25 2006 +0000 @@ -24,7 +24,9 @@ #ifndef _MSN_NEXUS_H_ #define _MSN_NEXUS_H_ -#define TWN_SERVER "loginnet.passport.com" +#include "soap.h" + +#define MSN_TWN_SERVER "loginnet.passport.com" #define TWN_START_TOKEN "<wsse:BinarySecurityToken Id=\"PPToken1\">" #define TWN_END_TOKEN "</wsse:BinarySecurityToken>" @@ -75,20 +77,8 @@ struct _MsnNexus { MsnSession *session; - - char *login_host; - char *login_path; + MsnSoapConn *soapconn; GHashTable *challenge_data; - GaimSslConnection *gsc; - - guint input_handler; - - char *write_buf; - gsize written_len; - GaimInputFunction written_cb; - - char *read_buf; - gsize read_len; }; void msn_nexus_connect(MsnNexus *nexus);
--- a/src/protocols/msn/notification.c Sat Jun 24 12:04:32 2006 +0000 +++ b/src/protocols/msn/notification.c Sun Jul 09 16:48:25 2006 +0000 @@ -238,7 +238,8 @@ msn_session_set_login_step(session, MSN_LOGIN_STEP_SYN); - msn_cmdproc_send(cmdproc, "SYN", "%s", "0"); +// msn_cmdproc_send(cmdproc, "SYN", "%s", "0"); + //TODO we should use SOAP contact to fetch contact list }else if (!g_ascii_strcasecmp(cmd->params[1], "TWN")){ /* Passport authentication */ char **elems, **cur, **tokens; @@ -397,8 +398,8 @@ /************************************************************************** * Challenges + * we use MD5 to caculate the Chanllenges **************************************************************************/ - static void chl_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) { @@ -416,7 +417,7 @@ gaim_cipher_context_append(context, (const guchar *)cmd->params[1], strlen(cmd->params[1])); - challenge_resp = "VT6PX?UQTM4WM%YR"; + challenge_resp = MSNP13_WLM_PRODUCT_KEY; gaim_cipher_context_append(context, (const guchar *)challenge_resp, strlen(challenge_resp)); @@ -426,7 +427,7 @@ for (i = 0; i < 16; i++) g_snprintf(buf + (i*2), 3, "%02x", digest[i]); - trans = msn_transaction_new(cmdproc, "QRY", "%s 32", "PROD0038W!61ZTF9"); + trans = msn_transaction_new(cmdproc, "QRY", "%s 32", MSNP13_WLM_PRODUCT_ID); msn_transaction_set_payload(trans, buf, 32); @@ -436,7 +437,6 @@ /************************************************************************** * Buddy Lists **************************************************************************/ - static void add_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) { @@ -554,6 +554,10 @@ g_strfreev(params); } +static void adl_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) +{ +} + static void adg_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) { @@ -1100,12 +1104,9 @@ msn_parse_socket(cmd->params[2], &host, &port); - if (!strcmp(cmd->params[1], "SB")) - { + if (!strcmp(cmd->params[1], "SB")){ gaim_debug_error("msn", "This shouldn't be handled here.\n"); - } - else if (!strcmp(cmd->params[1], "NS")) - { + }else if (!strcmp(cmd->params[1], "NS")){ MsnSession *session; session = cmdproc->session; @@ -1123,7 +1124,6 @@ { gaim_debug_info("MaYuan","Processing GCF... \n"); if(cmd->payload_len == 0){ -// cmd->payload_len = is_num(cmd->params[1]) ? atoi(cmd->params[1]) : 0; return; } /*get the payload content*/ @@ -1149,49 +1149,53 @@ MsnSession *session; const char *value; + gaim_debug_info("MaYuan","profile_msg... \n"); session = cmdproc->session; if (strcmp(msg->remote_user, "Hotmail")) /* This isn't an official message. */ return; - if ((value = msn_message_get_attr(msg, "kv")) != NULL) - { + if ((value = msn_message_get_attr(msg, "kv")) != NULL){ if (session->passport_info.kv != NULL) g_free(session->passport_info.kv); session->passport_info.kv = g_strdup(value); } - if ((value = msn_message_get_attr(msg, "sid")) != NULL) - { + if ((value = msn_message_get_attr(msg, "sid")) != NULL){ if (session->passport_info.sid != NULL) g_free(session->passport_info.sid); session->passport_info.sid = g_strdup(value); } - if ((value = msn_message_get_attr(msg, "MSPAuth")) != NULL) - { + if ((value = msn_message_get_attr(msg, "MSPAuth")) != NULL){ if (session->passport_info.mspauth != NULL) g_free(session->passport_info.mspauth); + gaim_debug_info("MaYuan","MSPAuth:%s\n",value); session->passport_info.mspauth = g_strdup(value); } - if ((value = msn_message_get_attr(msg, "ClientIP")) != NULL) - { + if ((value = msn_message_get_attr(msg, "ClientIP")) != NULL){ if (session->passport_info.client_ip != NULL) g_free(session->passport_info.client_ip); session->passport_info.client_ip = g_strdup(value); } - if ((value = msn_message_get_attr(msg, "ClientPort")) != NULL) + if ((value = msn_message_get_attr(msg, "ClientPort")) != NULL){ session->passport_info.client_port = ntohs(atoi(value)); + } if ((value = msn_message_get_attr(msg, "LoginTime")) != NULL) session->passport_info.sl = atol(value); + + /*starting retrieve the contact list*/ + session->contact = msn_contact_new(session); + msn_contact_connect(session->contact); + } static void
--- a/src/protocols/msn/notification.h Sat Jun 24 12:04:32 2006 +0000 +++ b/src/protocols/msn/notification.h Sun Jul 09 16:48:25 2006 +0000 @@ -24,6 +24,14 @@ #ifndef _MSN_NOTIFICATION_H_ #define _MSN_NOTIFICATION_H_ +/*MSN protocol challenge info*/ +/*MSNP13 challenge*/ +#define MSNP13_WLM_PRODUCT_KEY "O4BG@C7BWLYQX?5G" +#define MSNP13_WLM_PRODUCT_ID "PROD01065C%ZFN6F" + +#define MSNP10_PRODUCT_KEY "VT6PX?UQTM4WM%YR" +#define MSNP10_PRODUCT_ID "PROD0038W!61ZTF9" + typedef struct _MsnNotification MsnNotification; #include "session.h"
--- a/src/protocols/msn/session.c Sat Jun 24 12:04:32 2006 +0000 +++ b/src/protocols/msn/session.c Sun Jul 09 16:48:25 2006 +0000 @@ -70,6 +70,8 @@ msn_userlist_destroy(session->userlist); + g_free(session->passport_info.t); + g_free(session->passport_info.p); g_free(session->passport_info.kv); g_free(session->passport_info.sid); g_free(session->passport_info.mspauth);
--- a/src/protocols/msn/session.h Sat Jun 24 12:04:32 2006 +0000 +++ b/src/protocols/msn/session.h Sun Jul 09 16:48:25 2006 +0000 @@ -38,6 +38,7 @@ #include "cmdproc.h" #include "nexus.h" #include "httpconn.h" +#include "contact.h" #include "userlist.h" #include "sync.h" @@ -94,6 +95,7 @@ MsnNotification *notification; MsnNexus *nexus; + MsnContact *contact; MsnSync *sync; MsnUserList *userlist; @@ -107,6 +109,10 @@ struct { + /*t and p, get via USR TWN*/ + char *t; + char *p; + char *kv; char *sid; char *mspauth; @@ -114,7 +120,6 @@ char *file; char *client_ip; int client_port; - } passport_info; };
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/protocols/msn/soap.c Sun Jul 09 16:48:25 2006 +0000 @@ -0,0 +1,302 @@ +/** + * @file soap.c + * SOAP connection related process + * Author + * MaYuan<mayuan2006@gmail.com> + * gaim + * + * Gaim is the legal property of its developers, whose names are too numerous + * to list here. Please refer to the COPYRIGHT file distributed with this + * source distribution. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include "msn.h" +#include "soap.h" + +/*new a soap connection*/ +MsnSoapConn * +msn_soap_new(MsnSession *session) +{ + MsnSoapConn *soapconn; + + soapconn = g_new0(MsnSoapConn, 1); + soapconn->session = session; + soapconn->input_handler = -1; + soapconn->output_handler = -1; + return soapconn; +} + +/*ssl soap connect callback*/ +void +msn_soap_connect_cb(gpointer data, GaimSslConnection *gsc, + GaimInputCondition cond) +{ + MsnSoapConn * soapconn; + MsnSession *session; + + gaim_debug_info("MaYuan","Soap connection connected!\n"); + soapconn = data; + g_return_if_fail(soapconn != NULL); + + session = soapconn->session; + g_return_if_fail(session != NULL); + + soapconn->gsc = gsc; + + /*connection callback*/ + if(soapconn->connect_cb != NULL){ + soapconn->connect_cb(data,gsc,cond); + } +} + +/*ssl soap error callback*/ +static void +msn_soap_error_cb(GaimSslConnection *gsc, GaimSslErrorType error, void *data) +{ + MsnSoapConn * soapconn = data; + g_return_if_fail(data != NULL); + gaim_debug_info("MaYuan","Soap connection error!\n"); + /*error callback*/ + if(soapconn->error_cb != NULL){ + soapconn->error_cb(gsc,error,data); + } +} + +/*init the soap connection*/ +void +msn_soap_init(MsnSoapConn *soapconn,char * host,int ssl, + GaimSslInputFunction connect_cb, + GaimSslErrorFunction error_cb) +{ + soapconn->login_host = g_strdup(host); + soapconn->ssl_conn = ssl; + soapconn->connect_cb = connect_cb; + soapconn->error_cb = error_cb; + if(soapconn->ssl_conn){ + gaim_ssl_connect(soapconn->session->account, soapconn->login_host, + GAIM_SSL_DEFAULT_PORT, msn_soap_connect_cb, msn_soap_error_cb, + soapconn); + }else{ + } +} + +/*destroy the soap connection*/ +void +msn_soap_destroy(MsnSoapConn *soapconn) +{ + g_free(soapconn->login_host); + g_free(soapconn->login_path); + + /*remove the write handler*/ + if (soapconn->output_handler > 0){ + gaim_input_remove(soapconn->output_handler); + } + /*remove the read handler*/ + if (soapconn->input_handler > 0){ + gaim_input_remove(soapconn->input_handler); + } + msn_soap_free_read_buf(soapconn); + msn_soap_free_write_buf(soapconn); + + /*close ssl connection*/ + gaim_ssl_close(soapconn->gsc); + soapconn->gsc = NULL; + + g_free(soapconn); +} + +/*read and append the content to the buffer*/ +static gssize +msn_soap_read(MsnSoapConn *soapconn) +{ + gssize len; + gssize total_len = 0; + char temp_buf[10240]; + + if(soapconn->ssl_conn){ + len = gaim_ssl_read(soapconn->gsc, temp_buf,sizeof(temp_buf)); + }else{ + len = read(soapconn->fd, temp_buf,sizeof(temp_buf)); + } + if(len >0){ + total_len += len; + soapconn->read_buf = g_realloc(soapconn->read_buf, + soapconn->read_len + len + 1); +// strncpy(soapconn->read_buf + soapconn->read_len, temp_buf, len); + memcpy(soapconn->read_buf + soapconn->read_len, temp_buf, len); + soapconn->read_len += len; + soapconn->read_buf[soapconn->read_len] = '\0'; + } +// gaim_debug_info("MaYuan","nexus ssl read:{%s}\n",soapconn->read_buf); + return total_len; +} + +/*read the whole SOAP server response*/ +void +msn_soap_read_cb(gpointer data, gint source, GaimInputCondition cond) +{ + MsnSoapConn *soapconn = data; + MsnSession *session; + int len; + char * body_start,*body_len; + char *length_start,*length_end; + + gaim_debug_misc("MaYuan", "soap read cb\n"); + session = soapconn->session; + g_return_if_fail(session != NULL); + + if (soapconn->input_handler == -1){ + soapconn->input_handler = gaim_input_add(soapconn->gsc->fd, + GAIM_INPUT_READ, msn_soap_read_cb, soapconn); + } + + /*read the request header*/ + len = msn_soap_read(soapconn); + if (len < 0 && errno == EAGAIN){ + return; + }else if (len < 0) { + gaim_debug_error("msn", "read Error!len:%d\n",len); + gaim_input_remove(soapconn->input_handler); + soapconn->input_handler = -1; + g_free(soapconn->read_buf); + soapconn->read_buf = NULL; + soapconn->read_len = 0; + /* TODO: error handling */ + return; + } + + if(soapconn->read_buf == NULL){ + return; + } + + body_start = (char *)g_strstr_len(soapconn->read_buf, soapconn->read_len,"\r\n\r\n"); + if(!body_start){ + return; + } + body_start += 4; + +// gaim_debug_misc("msn", "Soap Read: {%s}\n", soapconn->read_buf); + + /* we read the content-length*/ + length_start = strstr(soapconn->read_buf, "Content-Length: "); + 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); +// gaim_debug_misc("MaYuan","content length :%d",soapconn->body_len); + + if(soapconn->read_len < body_start - soapconn->read_buf + atoi(body_len)){ + return; + } + + g_free(body_len); + + /*call the read callback*/ + if(soapconn->read_cb != NULL){ + soapconn->read_cb(soapconn,source,0); + } +#if 0 + /*clear the read buffer*/ + msn_soap_free_read_buf(soapconn); + + /*remove the read handler*/ + gaim_input_remove(soapconn->input_handler); + soapconn->input_handler = -1; + gaim_ssl_close(soapconn->gsc); + soapconn->gsc = NULL; +#endif +} + +void +msn_soap_free_read_buf(MsnSoapConn *soapconn) +{ + if(soapconn->read_buf){ + g_free(soapconn->read_buf); + } + soapconn->read_buf = NULL; + soapconn->read_len = 0; +} + +void +msn_soap_free_write_buf(MsnSoapConn *soapconn) +{ + if(soapconn->write_buf){ + g_free(soapconn->write_buf); + } + soapconn->write_buf = NULL; + soapconn->written_len = 0; +} + +/*Soap write process func*/ +static void +msn_soap_write_cb(gpointer data, gint source, GaimInputCondition cond) +{ + MsnSoapConn *soapconn = data; + int len, total_len; + + total_len = strlen(soapconn->write_buf); + + /* + * write the content to SSL server, + */ + len = gaim_ssl_write(soapconn->gsc, + soapconn->write_buf + soapconn->written_len, + total_len - soapconn->written_len); + + if (len < 0 && errno == EAGAIN) + return; + else if (len <= 0){ + /*SSL write error!*/ + gaim_input_remove(soapconn->output_handler); + soapconn->output_handler = -1; + /* TODO: notify of the error */ + return; + } + soapconn->written_len += len; + + if (soapconn->written_len < total_len) + return; + + gaim_input_remove(soapconn->output_handler); + soapconn->output_handler = -1; + + /*clear the write buff*/ + msn_soap_free_write_buf(soapconn); + + /* Write finish! + * callback for write done + */ + if(soapconn->written_cb != NULL){ + soapconn->written_cb(soapconn, source, 0); + } +} + +/*write the buffer to SOAP connection*/ +void +msn_soap_write(MsnSoapConn * soapconn, char *write_buf, GaimInputFunction written_cb) +{ + soapconn->write_buf = write_buf; + soapconn->written_len = 0; + soapconn->written_cb = written_cb; + /*start the write*/ + soapconn->output_handler = gaim_input_add(soapconn->gsc->fd, GAIM_INPUT_WRITE, + msn_soap_write_cb, soapconn); + msn_soap_write_cb(soapconn, soapconn->gsc->fd, GAIM_INPUT_WRITE); +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/protocols/msn/soap.h Sun Jul 09 16:48:25 2006 +0000 @@ -0,0 +1,87 @@ +/** + * @file soap.h + * header file for SOAP connection related process + * Author + * MaYuan<mayuan2006@gmail.com> + * gaim + * + * Gaim is the legal property of its developers, whose names are too numerous + * to list here. Please refer to the COPYRIGHT file distributed with this + * source distribution. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef _MSN_SOAP_H_ +#define _MSN_SOAP_H_ + +/*MSN Https connection structure*/ +typedef struct _MsnSoapConn MsnSoapConn; + +struct _MsnSoapConn{ + MsnSession *session; + gpointer parent; + + char *login_host; + char *login_path; + + /*ssl connection?*/ + guint ssl_conn; + /*normal connection*/ + guint fd; + /*SSL connection*/ + GaimSslConnection *gsc; + /*ssl connection callback*/ + GaimSslInputFunction connect_cb; + /*ssl error callback*/ + GaimSslErrorFunction error_cb; + + /*read handler*/ + guint input_handler; + /*write handler*/ + guint output_handler; + + /*write buffer*/ + char *write_buf; + gsize written_len; + GaimInputFunction written_cb; + + /*read buffer*/ + char *read_buf; + gsize read_len; + GaimInputFunction read_cb; + + /*HTTP reply body part*/ + char *body; + int body_len; +}; + +/*Function Prototype*/ +/*new a soap conneciton */ +MsnSoapConn *msn_soap_new(MsnSession *session); +/*destroy */ +void msn_soap_destroy(MsnSoapConn *soapconn); + +/*init a soap conneciton */ +void msn_soap_init(MsnSoapConn *soapconn,char * host,int ssl,GaimSslInputFunction connect_cb,GaimSslErrorFunction error_cb); + +/*write to soap*/ +void msn_soap_write(MsnSoapConn * soapconn, char *write_buf, GaimInputFunction written_cb); +void msn_soap_free_read_buf(MsnSoapConn *soapconn); +void msn_soap_free_write_buf(MsnSoapConn *soapconn); +void msn_soap_connect_cb(gpointer data, GaimSslConnection *gsc, GaimInputCondition cond); +void msn_soap_read_cb(gpointer data, gint source, GaimInputCondition cond); + +#endif/*_MSN_SOAP_H_*/ +
--- a/src/protocols/msn/table.c Sat Jun 24 12:04:32 2006 +0000 +++ b/src/protocols/msn/table.c Sun Jul 09 16:48:25 2006 +0000 @@ -77,20 +77,14 @@ cbs = NULL; - if (command == NULL) - { + if (command == NULL){ cbs = table->async; - } - else if (strcmp(command, "fallback") == 0) - { + }else if (strcmp(command, "fallback") == 0) { cbs = table->fallback; - } - else - { + }else{ cbs = g_hash_table_lookup(table->cmds, command); - if (cbs == NULL) - { + if (cbs == NULL){ cbs = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, NULL); g_hash_table_insert(table->cmds, command, cbs); }