Mercurial > pidgin
view libpurple/protocols/msn/contact.c @ 20479:6a8463be5b23
Improve MSN_SOAP_DEBUG and workaround a Win32 bug which would case Pidgin to consume insane amounts of memory when printing a large string to the Debug Window.
author | Carlos Silva <typ0@pidgin.im> |
---|---|
date | Wed, 08 Aug 2007 23:01:44 +0000 |
parents | 9a2a4a0c0003 |
children | eb93710aec4d |
line wrap: on
line source
/** * @file contact.c * get MSN contacts via SOAP request * created by MaYuan<mayuan2006@gmail.com> * * purple * * Purple 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" #include "group.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,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(PurpleSslConnection *gsc, PurpleSslErrorType 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, PurpleSslConnection *gsc, PurpleInputCondition 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,NULL); } /*get MSN member role utility*/ static int msn_get_memberrole(char * role) { purple_debug_info("::","msn_get_memberrole()\n"); if(!strcmp(role,"Allow")){ return MSN_LIST_AL_OP; }else if(!strcmp(role,"Block")){ return MSN_LIST_BL_OP; }else if(!strcmp(role,"Reverse")){ return MSN_LIST_RL_OP; }else if(!strcmp(role,"Pending")){ return MSN_LIST_PL_OP; } return 0; } /*get User Type*/ static int msn_get_user_type(char * type) { if(!strcmp(type,"Regular")){ return MSN_USER_TYPE_PASSPORT; } if(!strcmp(type,"Live")){ return MSN_USER_TYPE_PASSPORT; } if(!strcmp(type,"LivePending")){ return MSN_USER_TYPE_PASSPORT; } return MSN_USER_TYPE_UNKNOWN; } /* Create the AddressBook in the server, if we don't have one */ static void msn_create_address_cb(gpointer data, gint source, PurpleInputCondition cond) { MsnSoapConn *soapconn = data; MsnContact *contact; contact = soapconn->parent; g_return_if_fail(contact != NULL); if ( g_strstr_len(soapconn->read_buf, soapconn->read_len, "HTTP/1.1 200") ) { purple_debug_info("MSN AddressBook", "Address Book successfully created!\n"); msn_get_address_book(contact, NULL, NULL); } else { purple_debug_warning("MSN AddressBook", "Failed to create the Address Book!\n"); } msn_soap_free_read_buf(soapconn); return; } static void msn_create_address_written_cb(gpointer data, gint source, PurpleInputCondition cond) { MsnSoapConn * soapconn = data; purple_debug_info("MSN AddressBook","AddressBookAdd written\n"); soapconn->read_cb = msn_create_address_cb; return; } static void msn_create_address_book(MsnContact * contact) { MsnSoapReq *soap_request; gchar *body; purple_debug_info("MSN AddressBook","Creating an Address Book.\n"); body = g_strdup_printf(MSN_ADD_ADDRESSBOOK_TEMPLATE, contact->session->user->passport); soap_request = msn_soap_request_new(MSN_CONTACT_SERVER, MSN_ADDRESS_BOOK_POST_URL,MSN_ADD_ADDRESSBOOK_SOAP_ACTION, body, msn_create_address_cb, msn_create_address_written_cb); msn_soap_post(contact->soapconn, soap_request, msn_contact_connect_init); g_free(body); return; } /*parse contact list*/ static void msn_parse_contact_list(MsnContact * contact) { MsnSession * session; int list_op = 0; char * passport, *typedata; xmlnode *fault, *faultstringnode, *faultdetail, *errorcode; xmlnode *node, *body, *response, *result, *services; xmlnode *service, *memberships, *info, *handle, *handletype; xmlnode *LastChangeNode; xmlnode *membershipnode, *members, *member, *passportNode; char *LastChangeStr; session = contact->session; node = xmlnode_from_str(contact->soapconn->body, contact->soapconn->body_len); if (node == NULL) { purple_debug_error("MSNCL","Unable to parse SOAP data!\n"); return; } purple_debug_misc("MSNCL","Parsing contact list with size %d\n", contact->soapconn->body_len); purple_debug_misc("MSNCL","Root node @ %p: Name: '%s', child: '%s', lastchild: '%s'\n",node,node->name,node->child->name,node->lastchild->name); body = xmlnode_get_child(node,"Body"); if (body == NULL) { purple_debug_warning("MSNCL", "Failed to parse contact list Body node\n"); xmlnode_free(node); return; } purple_debug_info("MSNCL","Body @ %p: Name: '%s'\n",body,body->name); /* Did we receive a <Fault> ? */ if ( (fault = xmlnode_get_child(body, "Fault")) != NULL) { purple_debug_info("MSNCL","Fault received from SOAP server!\n"); if ( (faultstringnode = xmlnode_get_child(fault, "faultstring")) != NULL ) { gchar * faultstring = xmlnode_get_data(faultstringnode); purple_debug_info("MSNCL","Faultstring: %s\n", faultstring); g_free(faultstring); } if ( (faultdetail = xmlnode_get_child(fault, "detail")) != NULL ) { purple_debug_info("MSNCL","detail @ %p, name: %s\n",faultdetail, faultdetail->name); if ( (errorcode = xmlnode_get_child(faultdetail, "errorcode")) != NULL ) { purple_debug_info("MSNCL","errorcode @ %p, name: %s\n",errorcode, errorcode->name); if (errorcode->child != NULL) { gchar *errorcodestring = xmlnode_get_data(errorcode); purple_debug_info("MSNCL", "Error Code: %s\n", errorcodestring); if ( !strncmp(errorcodestring, "ABDoesNotExist", 14) ) { xmlnode_free(node); g_free(errorcodestring); msn_create_address_book(contact); return; } g_free(errorcodestring); } } } xmlnode_free(node); msn_get_contact_list(contact, NULL); return; } response = xmlnode_get_child(body,"FindMembershipResponse"); if (response == NULL) { /* we may get a response if our cache data is too old: * * <faultstring>Need to do full sync. Can't sync deltas Client * has too old a copy for us to do a delta sync</faultstring> */ xmlnode_free(node); msn_get_contact_list(contact, NULL); return; } purple_debug_info("MSNCL","FindMembershipResponse @ %p: Name: '%s'\n",response,response->name); result = xmlnode_get_child(response,"FindMembershipResult"); if (result == NULL) { purple_debug_warning("MSNCL","Received No Update!\n"); xmlnode_free(node); return; } purple_debug_info("MSNCL","Result @ %p: Name: '%s'\n", result, result->name); if ( (services = xmlnode_get_child(result,"Services")) == NULL) { purple_debug_misc("MSNCL","No <Services> received.\n"); xmlnode_free(node); return; } purple_debug_info("MSNCL","Services @ %p\n",services); for (service = xmlnode_get_child(services, "Service"); service; service = xmlnode_get_next_twin(service)) { purple_debug_info("MSNCL","Service @ %p\n",service); if ( (info = xmlnode_get_child(service,"Info")) == NULL ) { purple_debug_error("MSNCL","Error getting 'Info' child node\n"); continue; } if ( (handle = xmlnode_get_child(info,"Handle")) == NULL ) { purple_debug_error("MSNCL","Error getting 'Handle' child node\n"); continue; } if ( (handletype = xmlnode_get_child(handle,"Type")) == NULL ) { purple_debug_error("MSNCL","Error getting 'Type' child node\n"); continue; } if ( (typedata = xmlnode_get_data(handletype)) == NULL) { purple_debug_error("MSNCL","Error retrieving data from 'Type' child node\n"); continue; } purple_debug_info("MSNCL","processing '%s' Service\n", typedata); if ( !g_strcasecmp(typedata, "Profile") ) { /* Process Windows Live 'Messenger Roaming Identity' */ g_free(typedata); continue; } if ( !g_strcasecmp(typedata, "Messenger") ) { /*Last Change Node*/ LastChangeNode = xmlnode_get_child(service, "LastChange"); LastChangeStr = xmlnode_get_data(LastChangeNode); purple_debug_info("MSNCL","LastChangeNode: '%s'\n",LastChangeStr); purple_account_set_string(session->account, "CLLastChange", LastChangeStr); g_free(LastChangeStr); memberships = xmlnode_get_child(service,"Memberships"); if (memberships == NULL) { purple_debug_warning("MSNCL","Memberships = NULL, cleaning up and returning.\n"); g_free(typedata); xmlnode_free(node); return; } purple_debug_info("MSNCL","Memberships @ %p: Name: '%s'\n",memberships,memberships->name); for (membershipnode = xmlnode_get_child(memberships, "Membership"); membershipnode; membershipnode = xmlnode_get_next_twin(membershipnode)){ xmlnode *roleNode; char *role; roleNode = xmlnode_get_child(membershipnode,"MemberRole"); role = xmlnode_get_data(roleNode); list_op = msn_get_memberrole(role); purple_debug_info("MSNCL","MemberRole role: %s, list_op: %d\n",role,list_op); g_free(role); members = xmlnode_get_child(membershipnode,"Members"); for (member = xmlnode_get_child(members, "Member"); member; member = xmlnode_get_next_twin(member)){ MsnUser *user; xmlnode * typeNode; char * type; purple_debug_info("MSNCL","Member type: %s\n", xmlnode_get_attrib(member,"type")); if( !g_strcasecmp(xmlnode_get_attrib(member,"type"), "PassportMember") ) { passportNode = xmlnode_get_child(member,"PassportName"); passport = xmlnode_get_data(passportNode); typeNode = xmlnode_get_child(member,"Type"); type = xmlnode_get_data(typeNode); purple_debug_info("MSNCL","Passport name: '%s', Type: %s\n",passport,type); g_free(type); user = msn_userlist_find_add_user(session->userlist,passport,NULL); msn_got_lst_user(session, user, list_op, NULL); g_free(passport); } if (!g_strcasecmp(xmlnode_get_attrib(member,"type"),"PhoneMember")) { } if (!g_strcasecmp(xmlnode_get_attrib(member,"type"),"EmailMember")) { xmlnode *emailNode; emailNode = xmlnode_get_child(member,"Email"); passport = xmlnode_get_data(emailNode); purple_debug_info("MSNCL","Email Member: Name: '%s', list_op: %d\n", passport, list_op); user = msn_userlist_find_add_user(session->userlist, passport, NULL); msn_got_lst_user(session, user, list_op, NULL); g_free(passport); } } } g_free(typedata); /* Free 'Type' node data after processing 'Messenger' Service */ } } xmlnode_free(node); /* Free the whole XML tree */ } static void msn_get_contact_list_cb(gpointer data, gint source, PurpleInputCondition cond) { MsnSoapConn *soapconn = data; MsnContact *contact; MsnSession *session; const char *abLastChange; const char *dynamicItemLastChange; purple_debug_misc("MSNCL","Got the contact list!\n"); contact = soapconn->parent; g_return_if_fail(contact != NULL); session = soapconn->session; g_return_if_fail(session != NULL); msn_parse_contact_list(contact); /*free the read buffer*/ msn_soap_free_read_buf(soapconn); abLastChange = purple_account_get_string(session->account, "ablastChange", NULL); dynamicItemLastChange = purple_account_get_string(session->account, "dynamicItemLastChange", NULL); #ifdef MSN_PARTIAL_LISTS /* XXX: this should be enabled when we can correctly do partial syncs with the server. Currently we need to retrieve the whole list to detect sync issues */ msn_get_address_book(contact, abLastChange, dynamicItemLastChange); #else msn_get_address_book(contact, NULL, NULL); #endif msn_soap_free_read_buf(soapconn); } static void msn_get_contact_written_cb(gpointer data, gint source, PurpleInputCondition cond) { 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*/ void msn_get_contact_list(MsnContact * contact, const char *update_time) { MsnSoapReq *soap_request; char *body = NULL; char * update_str; purple_debug_misc("MSNCL","Getting Contact List.\n"); if ( update_time != NULL ) { purple_debug_info("MSNCL","Last update time: %s\n",update_time); update_str = g_strdup_printf(MSN_GET_CONTACT_UPDATE_XML,update_time); } else { update_str = g_strdup(""); } body = g_strdup_printf(MSN_GET_CONTACT_TEMPLATE, update_str); g_free(update_str); soap_request = msn_soap_request_new(MSN_CONTACT_SERVER, MSN_GET_CONTACT_POST_URL,MSN_GET_CONTACT_SOAP_ACTION, body, msn_get_contact_list_cb, msn_get_contact_written_cb); msn_soap_post(contact->soapconn,soap_request,msn_contact_connect_init); g_free(body); } static void msn_parse_addressbook_groups(MsnContact *contact, xmlnode *node) { MsnSession *session = contact->session; xmlnode *group; purple_debug_info("MsnAb","msn_parse_addressbook_groups()\n"); for(group = xmlnode_get_child(node, "Group"); group; group = xmlnode_get_next_twin(group)){ xmlnode *groupId, *groupInfo, *groupname; char *group_id, *group_name; groupId = xmlnode_get_child(group,"groupId"); group_id = xmlnode_get_data(groupId); groupInfo = xmlnode_get_child(group,"groupInfo"); groupname = xmlnode_get_child(groupInfo,"name"); group_name = xmlnode_get_data(groupname); msn_group_new(session->userlist, group_id, group_name); if (group_id == NULL){ /* Group of ungroupped buddies */ g_free(group_name); continue; } purple_debug_info("MsnAB","group_id: %s, name: %s\n",group_id,group_name); if ((purple_find_group(group_name)) == NULL){ PurpleGroup *g = purple_group_new(group_name); purple_blist_add_group(g, NULL); } g_free(group_id); g_free(group_name); } } static void msn_parse_addressbook_contacts(MsnContact *contact, xmlnode *node) { MsnSession *session = contact->session; xmlnode *contactNode; for(contactNode = xmlnode_get_child(node, "Contact"); contactNode; contactNode = xmlnode_get_next_twin(contactNode)){ xmlnode *contactId,*contactInfo,*contactType,*passportName,*displayName,*guid; xmlnode *groupIds; MsnUser *user; MsnUserType usertype; char *passport,*Name,*uid,*type; passport = NULL; contactId= xmlnode_get_child(contactNode,"contactId"); uid = xmlnode_get_data(contactId); contactInfo = xmlnode_get_child(contactNode,"contactInfo"); contactType = xmlnode_get_child(contactInfo,"contactType"); type = xmlnode_get_data(contactType); /*setup the Display Name*/ if (!strcmp(type, "Me")){ char *friendly; friendly = xmlnode_get_data(xmlnode_get_child(contactInfo, "displayName")); purple_connection_set_display_name(session->account->gc, purple_url_decode(friendly)); g_free(friendly); g_free(uid); g_free(type); continue; /* Not adding own account as buddy to buddylist */ } usertype = msn_get_user_type(type); passportName = xmlnode_get_child(contactInfo,"passportName"); if (passportName == NULL) { xmlnode *emailsNode, *contactEmailNode, *emailNode; xmlnode *messengerEnabledNode; char *msnEnabled; /*TODO: add it to the none-instant Messenger group and recognize as email Membership*/ /*Yahoo User?*/ emailsNode = xmlnode_get_child(contactInfo,"emails"); if (emailsNode == NULL) { /*TODO: need to support the Mobile type*/ g_free(uid); g_free(type); continue; } for(contactEmailNode = xmlnode_get_child(emailsNode,"ContactEmail");contactEmailNode; contactEmailNode = xmlnode_get_next_twin(contactEmailNode) ){ messengerEnabledNode = xmlnode_get_child(contactEmailNode,"isMessengerEnabled"); if(messengerEnabledNode == NULL){ break; } msnEnabled = xmlnode_get_data(messengerEnabledNode); if(!strcmp(msnEnabled,"true")){ /*Messenger enabled, Get the Passport*/ emailNode = xmlnode_get_child(contactEmailNode,"email"); passport = xmlnode_get_data(emailNode); purple_debug_info("MsnAB","Yahoo User %s\n",passport); usertype = MSN_USER_TYPE_YAHOO; break; }else{ /*TODO maybe we can just ignore it in Purple?*/ emailNode = xmlnode_get_child(contactEmailNode,"email"); passport = xmlnode_get_data(emailNode); purple_debug_info("MSNAB","Other type user\n"); } g_free(msnEnabled); } } else { passport = xmlnode_get_data(passportName); } if (passport == NULL) { g_free(uid); g_free(type); continue; } displayName = xmlnode_get_child(contactInfo,"displayName"); if (displayName == NULL) { Name = g_strdup(passport); } else { Name =xmlnode_get_data(displayName); } purple_debug_misc("MsnAB","passport:{%s} uid:{%s} display:{%s}\n", passport,uid,Name); user = msn_userlist_find_add_user(session->userlist, passport,Name); msn_user_set_uid(user,uid); msn_user_set_type(user, usertype); g_free(Name); g_free(passport); g_free(uid); g_free(type); purple_debug_misc("MsnAB","parse guid...\n"); groupIds = xmlnode_get_child(contactInfo,"groupIds"); if (groupIds) { for (guid = xmlnode_get_child(groupIds, "guid");guid; guid = xmlnode_get_next_twin(guid)){ char *group_id; group_id = xmlnode_get_data(guid); msn_user_add_group_id(user,group_id); purple_debug_misc("MsnAB","guid:%s\n",group_id); g_free(group_id); } } else { /*not in any group,Then set default group*/ msn_user_add_group_id(user, MSN_INDIVIDUALS_GROUP_ID); } msn_got_lst_user(session, user, MSN_LIST_FL_OP, NULL); } } static gboolean msn_parse_addressbook(MsnContact * contact) { MsnSession * session; xmlnode * node,*body,*response,*result; xmlnode *groups; xmlnode *contacts; xmlnode *abNode; xmlnode *fault, *faultstringnode, *faultdetail, *errorcode; session = contact->session; node = xmlnode_from_str(contact->soapconn->body, contact->soapconn->body_len); if ( node == NULL ) { purple_debug_error("MSN AddressBook","Error parsing Address Book with size %d\n", contact->soapconn->body_len); return FALSE; } purple_debug_misc("MSN AddressBook", "Parsing Address Book with size %d\n", contact->soapconn->body_len); purple_debug_misc("MSN AddressBook","node{%p},name:%s,child:%s,last:%s\n",node,node->name,node->child->name,node->lastchild->name); body = xmlnode_get_child(node,"Body"); purple_debug_misc("MSN AddressBook","body{%p},name:%s\n",body,body->name); if ( (fault = xmlnode_get_child(body, "Fault")) != NULL) { purple_debug_info("MSN AddressBook","Fault received from SOAP server!\n"); if ( (faultstringnode = xmlnode_get_child(fault, "faultstring")) != NULL ) { gchar *faultstring = xmlnode_get_data(faultstringnode); purple_debug_info("MSN AddressBook","Faultstring: %s\n", faultstring); g_free(faultstring); } if ( (faultdetail = xmlnode_get_child(fault, "detail")) != NULL ) { purple_debug_info("MSN AddressBook","detail @ %p, name: %s\n",faultdetail, faultdetail->name); if ( (errorcode = xmlnode_get_child(faultdetail, "errorcode")) != NULL ) { gchar *errorcodestring; purple_debug_info("MSN AddressBook","errorcode @ %p, name: %s\n",errorcode, errorcode->name); errorcodestring = xmlnode_get_data(errorcode); purple_debug_info("MSN AddressBook", "Error Code: %s\n", errorcodestring); if ( !strncmp(errorcodestring, "ABDoesNotExist", 14) ) { g_free(errorcodestring); return TRUE; } g_free(errorcodestring); } } return FALSE; } response = xmlnode_get_child(body,"ABFindAllResponse"); if (response == NULL) { return FALSE; } purple_debug_misc("MSN SOAP","response{%p},name:%s\n",response,response->name); result = xmlnode_get_child(response,"ABFindAllResult"); if(result == NULL){ purple_debug_misc("MSNAB","receive no address book update\n"); return TRUE; } purple_debug_info("MSN SOAP","result{%p},name:%s\n",result,result->name); /*Process Group List*/ groups = xmlnode_get_child(result,"groups"); if (groups != NULL) { msn_parse_addressbook_groups(contact, groups); } /*add a default No group to set up the no group Membership*/ msn_group_new(session->userlist, MSN_INDIVIDUALS_GROUP_ID, MSN_INDIVIDUALS_GROUP_NAME); purple_debug_misc("MsnAB","group_id:%s name:%s\n", MSN_INDIVIDUALS_GROUP_ID, MSN_INDIVIDUALS_GROUP_NAME); if ((purple_find_group(MSN_INDIVIDUALS_GROUP_NAME)) == NULL){ PurpleGroup *g = purple_group_new(MSN_INDIVIDUALS_GROUP_NAME); purple_blist_add_group(g, NULL); } /*add a default No group to set up the no group Membership*/ msn_group_new(session->userlist, MSN_NON_IM_GROUP_ID, MSN_NON_IM_GROUP_NAME); purple_debug_misc("MsnAB","group_id:%s name:%s\n", MSN_NON_IM_GROUP_ID, MSN_NON_IM_GROUP_NAME); if ((purple_find_group(MSN_NON_IM_GROUP_NAME)) == NULL){ PurpleGroup *g = purple_group_new(MSN_NON_IM_GROUP_NAME); purple_blist_add_group(g, NULL); } /*Process contact List*/ purple_debug_info("MSNAB","process contact list...\n"); contacts =xmlnode_get_child(result,"contacts"); if (contacts != NULL) { msn_parse_addressbook_contacts(contact, contacts); } abNode =xmlnode_get_child(result,"ab"); if(abNode != NULL){ xmlnode *LastChangeNode, *DynamicItemLastChangedNode; char *lastchange, *dynamicChange; LastChangeNode = xmlnode_get_child(abNode,"lastChange"); lastchange = xmlnode_get_data(LastChangeNode); purple_debug_info("MsnAB"," lastchanged Time:{%s}\n",lastchange); purple_account_set_string(session->account, "ablastChange", lastchange); DynamicItemLastChangedNode = xmlnode_get_child(abNode,"DynamicItemLastChanged"); dynamicChange = xmlnode_get_data(DynamicItemLastChangedNode); purple_debug_info("MsnAB"," DynamicItemLastChanged :{%s}\n",dynamicChange); purple_account_set_string(session->account, "DynamicItemLastChanged", lastchange); g_free(dynamicChange); g_free(lastchange); } xmlnode_free(node); msn_soap_free_read_buf(contact->soapconn); return TRUE; } static void msn_get_address_cb(gpointer data, gint source, PurpleInputCondition 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); purple_debug_misc("MSN AddressBook", "Got the Address Book!\n"); if ( msn_parse_addressbook(contact) ) { msn_soap_free_read_buf(soapconn); msn_send_privacy(session->account->gc); msn_notification_dump_contact(session); } 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) */ /* msn_get_address_book(contact, NULL, NULL); */ msn_session_disconnect(session); purple_connection_error(session->account->gc, _("Unable to retrieve MSN Address Book")); } /*free the read buffer*/ msn_soap_free_read_buf(soapconn); } /**/ static void msn_address_written_cb(gpointer data, gint source, PurpleInputCondition cond) { MsnSoapConn * soapconn = data; purple_debug_misc("MSN AddressBook","Sent SOAP request for the Address Book.\n"); soapconn->read_cb = msn_get_address_cb; } /*get the address book*/ void msn_get_address_book(MsnContact *contact, const char *LastChanged, const char *dynamicItemLastChange) { MsnSoapReq *soap_request; char *body = NULL; char *ab_update_str,*update_str; purple_debug_misc("MSN AddressBook","Getting Address Book\n"); /*build SOAP and POST it*/ if ( LastChanged != NULL ) { ab_update_str = g_strdup_printf(MSN_GET_ADDRESS_UPDATE_XML,LastChanged); } else { ab_update_str = g_strdup(""); } if ( dynamicItemLastChange != NULL ) { update_str = g_strdup_printf(MSN_GET_ADDRESS_UPDATE_XML, dynamicItemLastChange); } else { update_str = g_strdup(ab_update_str); } g_free(ab_update_str); body = g_strdup_printf(MSN_GET_ADDRESS_TEMPLATE,update_str); g_free(update_str); soap_request = msn_soap_request_new(MSN_CONTACT_SERVER, MSN_ADDRESS_BOOK_POST_URL,MSN_GET_ADDRESS_SOAP_ACTION, body, msn_get_address_cb, msn_address_written_cb); msn_soap_post(contact->soapconn,soap_request,msn_contact_connect_init); g_free(body); } static void msn_add_contact_read_cb(gpointer data, gint source, PurpleInputCondition cond) { purple_debug_info("MSNCL","Add contact read done\n"); } static void msn_add_contact_written_cb(gpointer data, gint source, PurpleInputCondition cond) { MsnSoapConn * soapconn = data; purple_debug_info("MSNCL","Add contact request written\n"); soapconn->read_cb = msn_add_contact_read_cb; // msn_soap_read_cb(data,source,cond); } /*add a Contact */ void msn_add_contact(MsnContact *contact,const char *passport,const char *groupId) { MsnSoapReq *soap_request; char *body = NULL; char *contact_xml = NULL; char *soap_action; purple_debug_info("MSNCL","msn_add_contact()\n"); contact_xml = g_strdup_printf(MSN_CONTACT_XML,passport); if ( groupId == NULL ) { body = g_strdup_printf(MSN_ADD_CONTACT_TEMPLATE,contact_xml); g_free(contact_xml); /*build SOAP and POST it*/ soap_action = g_strdup(MSN_CONTACT_ADD_SOAP_ACTION); } else { body = g_strdup_printf(MSN_ADD_CONTACT_GROUP_TEMPLATE,groupId,contact_xml); g_free(contact_xml); /*build SOAP and POST it*/ soap_action = g_strdup(MSN_ADD_CONTACT_GROUP_SOAP_ACTION); } soap_request = msn_soap_request_new(MSN_CONTACT_SERVER, MSN_ADDRESS_BOOK_POST_URL,soap_action, body, msn_add_contact_read_cb, msn_add_contact_written_cb); msn_soap_post(contact->soapconn,soap_request,msn_contact_connect_init); g_free(soap_action); g_free(body); } static void msn_delete_contact_read_cb(gpointer data, gint source, PurpleInputCondition cond) { purple_debug_info("MSNCL","Delete contact read done\n"); } static void msn_delete_contact_written_cb(gpointer data, gint source, PurpleInputCondition cond) { MsnSoapConn * soapconn = data; purple_debug_info("MSNCL","Delete contact request written\n"); soapconn->read_cb = msn_delete_contact_read_cb; // msn_soap_read_cb(data,source,cond); } /*delete a Contact*/ void msn_delete_contact(MsnContact *contact,const char *contactId) { char *body = NULL; char *contact_xml = NULL ; MsnSoapReq *soap_request; g_return_if_fail(contactId != NULL); purple_debug_info("MSNP14","msn delete a contact,contactId:{%s}...\n",contactId); contact_xml = g_strdup_printf(MSN_CONTACTS_DEL_XML,contactId); body = g_strdup_printf(MSN_DEL_CONTACT_TEMPLATE,contact_xml); g_free(contact_xml); /*build SOAP and POST it*/ soap_request = msn_soap_request_new(MSN_CONTACT_SERVER, MSN_ADDRESS_BOOK_POST_URL,MSN_CONTACT_DEL_SOAP_ACTION, body, msn_delete_contact_read_cb, msn_delete_contact_written_cb); msn_soap_post(contact->soapconn,soap_request,msn_contact_connect_init); g_free(body); } #if 0 static void msn_update_contact_read_cb(gpointer data, gint source, PurpleInputCondition cond) { purple_debug_info("MSNP14","update contact read done\n"); } static void msn_update_contact_written_cb(gpointer data, gint source, PurpleInputCondition cond) { MsnSoapConn * soapconn = data; purple_debug_info("MSNP14","update contact written\n"); soapconn->read_cb = msn_update_contact_read_cb; // msn_soap_read_cb(data,source,cond); } /*update a contact's Nickname*/ void msn_update_contact(MsnContact *contact,const char* nickname) { MsnSoapReq *soap_request; char *body = NULL; purple_debug_info("MSNP14","msn unblock a contact...\n"); body = g_strdup_printf(MSN_CONTACT_UPDATE_TEMPLATE,nickname); /*build SOAP and POST it*/ soap_request = msn_soap_request_new(MSN_CONTACT_SERVER, MSN_ADDRESS_BOOK_POST_URL,MSN_CONTACT_UPDATE_SOAP_ACTION, body, msn_update_contact_read_cb, msn_update_contact_written_cb); msn_soap_post(contact->soapconn,soap_request,msn_contact_connect_init); g_free(body); } #endif static void msn_block_read_cb(gpointer data, gint source, PurpleInputCondition cond) { purple_debug_info("MSNP14","block read done\n"); } static void msn_block_written_cb(gpointer data, gint source, PurpleInputCondition cond) { MsnSoapConn * soapconn = data; purple_debug_info("MSNP14","finish unblock written\n"); soapconn->read_cb = msn_block_read_cb; } /*block a Contact*/ void msn_block_contact(MsnContact *contact,const char* membership_id) { MsnSoapReq *soap_request; char *body = NULL; purple_debug_info("MSNP14","msn block a contact...\n"); body = g_strdup_printf(MSN_CONTACT_DELECT_FROM_ALLOW_TEMPLATE,membership_id); /*build SOAP and POST it*/ soap_request = msn_soap_request_new(MSN_CONTACT_SERVER, MSN_SHARE_POST_URL,MSN_CONTACT_BLOCK_SOAP_ACTION, body, msn_block_read_cb, msn_block_written_cb); msn_soap_post(contact->soapconn,soap_request,msn_contact_connect_init); g_free(body); } static void msn_unblock_read_cb(gpointer data, gint source, PurpleInputCondition cond) { purple_debug_info("MSNP14","unblock read done\n"); } static void msn_unblock_written_cb(gpointer data, gint source, PurpleInputCondition cond) { MsnSoapConn * soapconn = data; purple_debug_info("MSNP14","finish unblock written\n"); soapconn->read_cb = msn_unblock_read_cb; } /*unblock a contact*/ void msn_unblock_contact(MsnContact *contact,const char* passport) { MsnSoapReq *soap_request; char *body = NULL; purple_debug_info("MSNP14","msn unblock a contact...\n"); body = g_strdup_printf(MSN_UNBLOCK_CONTACT_TEMPLATE,passport); /*build SOAP and POST it*/ soap_request = msn_soap_request_new(MSN_CONTACT_SERVER, MSN_SHARE_POST_URL,MSN_CONTACT_UNBLOCK_SOAP_ACTION, body, msn_unblock_read_cb, msn_unblock_written_cb); msn_soap_post(contact->soapconn,soap_request,msn_contact_connect_init); g_free(body); } #if 0 static void msn_gleams_read_cb(gpointer data, gint source, PurpleInputCondition cond) { purple_debug_info("MSNP14","Gleams read done\n"); } static void msn_gleams_written_cb(gpointer data, gint source, PurpleInputCondition cond) { 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); } /*get the gleams info*/ void msn_get_gleams(MsnContact *contact) { MsnSoapReq *soap_request; purple_debug_info("MSNP14","msn get gleams info...\n"); /*build SOAP and POST it*/ soap_request = msn_soap_request_new(MSN_CONTACT_SERVER, MSN_ADDRESS_BOOK_POST_URL,MSN_GET_GLEAMS_SOAP_ACTION, MSN_GLEAMS_TEMPLATE, msn_gleams_read_cb, msn_gleams_written_cb); msn_soap_post(contact->soapconn,soap_request,msn_contact_connect_init); } #endif /*************************************************************** * Group Operation ***************************************************************/ static void msn_group_read_cb(gpointer data, gint source, PurpleInputCondition cond) { MsnSoapConn * soapconn = data; purple_debug_info("MSNCL", "Add Group reply with the SOAP read_buf:\n%s\n",soapconn->read_buf); purple_debug_info("MSNCL", "Add Group reply with the SOAP body:\n%s\n",soapconn->body); } static void msn_group_written_cb(gpointer data, gint source, PurpleInputCondition cond) { MsnSoapConn * soapconn = data; purple_debug_info("MSNCL","Finished sending Add Group\n"); soapconn->read_cb = msn_group_read_cb; // msn_soap_read_cb(data,source,cond); } /*add group*/ void msn_add_group(MsnSession *session,const char* group_name) { MsnSoapReq *soap_request; MsnContact *contact ; char *body = NULL; g_return_if_fail(session != NULL); contact = session->contact; purple_debug_info("::","msn_add_group()\n"); body = g_strdup_printf(MSN_GROUP_ADD_TEMPLATE,group_name); /*build SOAP and POST it*/ soap_request = msn_soap_request_new(MSN_CONTACT_SERVER, MSN_ADDRESS_BOOK_POST_URL,MSN_GROUP_ADD_SOAP_ACTION, body, msn_group_read_cb, msn_group_written_cb); msn_soap_post(contact->soapconn,soap_request,msn_contact_connect_init); } /*delete a group*/ void msn_del_group(MsnSession *session, const char *guid) { MsnSoapReq *soap_request; MsnContact *contact; char *body = NULL; g_return_if_fail(session != NULL); /*if group uid we need to del is NULL, * we need to delete nothing */ g_return_if_fail(guid != NULL); contact = session->contact; purple_debug_info("::","msn_del_group()\n"); body = g_strdup_printf(MSN_GROUP_DEL_TEMPLATE,guid); /*build SOAP and POST it*/ soap_request = msn_soap_request_new(MSN_CONTACT_SERVER, MSN_ADDRESS_BOOK_POST_URL,MSN_GROUP_DEL_SOAP_ACTION, body, msn_group_read_cb, msn_group_written_cb); msn_soap_post(contact->soapconn,soap_request,msn_contact_connect_init); g_free(body); } void msn_contact_connect_init(MsnSoapConn *soapconn) { /* Authenticate via Windows Live ID. */ purple_debug_info("::","msn_contact_connect_init()\n"); msn_soap_init(soapconn,MSN_CONTACT_SERVER,1, msn_contact_login_connect_cb, msn_contact_login_error_cb); }