comparison libpurple/protocols/msn/contact.c @ 21104:d31843a6b3bb

explicit merge of '3380c786d272dcd9ab1360f49c3e4e51227af663' and 'c0e79d15a4fe4c5b0129fcae5060754b25f72a56' to branch 'im.pidgin.cpw.khc.soap'
author Ka-Hing Cheung <khc@hxbc.us>
date Thu, 25 Oct 2007 08:13:42 +0000
parents c8f99cb61dc9 90fd0826c6ce
children 66424ff7b9db
comparison
equal deleted inserted replaced
21102:f387e8c671a4 21104:d31843a6b3bb
26 26
27 #include "msn.h" 27 #include "msn.h"
28 #include "contact.h" 28 #include "contact.h"
29 #include "xmlnode.h" 29 #include "xmlnode.h"
30 #include "group.h" 30 #include "group.h"
31 #include "soap2.h"
31 32
32 const char *MsnSoapPartnerScenarioText[] = 33 const char *MsnSoapPartnerScenarioText[] =
33 { 34 {
34 "Initial", 35 "Initial",
35 "ContactSave", 36 "ContactSave",
45 "Block", 46 "Block",
46 "Reverse", 47 "Reverse",
47 "Pending" 48 "Pending"
48 }; 49 };
49 50
51 typedef struct {
52 MsnContact *contact;
53 MsnSoapPartnerScenario which;
54 } GetContactListCbData;
55
50 /* new a contact */ 56 /* new a contact */
51 MsnContact * 57 MsnContact *
52 msn_contact_new(MsnSession *session) 58 msn_contact_new(MsnSession *session)
53 { 59 {
54 MsnContact *contact; 60 MsnContact *contact;
55 61
56 contact = g_new0(MsnContact, 1); 62 contact = g_new0(MsnContact, 1);
57 contact->session = session; 63 contact->session = session;
58 contact->soapconn = msn_soap_new(session,contact,1);
59 64
60 return contact; 65 return contact;
61 } 66 }
62 67
63 /* destroy the contact */ 68 /* destroy the contact */
64 void 69 void
65 msn_contact_destroy(MsnContact *contact) 70 msn_contact_destroy(MsnContact *contact)
66 { 71 {
67 msn_soap_destroy(contact->soapconn);
68 g_free(contact); 72 g_free(contact);
69 } 73 }
70 74
71 MsnCallbackState * 75 MsnCallbackState *
72 msn_callback_state_new(void) 76 msn_callback_state_new(MsnSession *session)
73 { 77 {
74 return g_new0(MsnCallbackState, 1); 78 MsnCallbackState *state = g_new0(MsnCallbackState, 1);
75 } 79
80 state->session = session;
81
82 return state;
83 }
76 84
77 void 85 void
78 msn_callback_state_free(MsnCallbackState *state) 86 msn_callback_state_free(MsnCallbackState *state)
79 { 87 {
80 if (state == NULL) 88 if (state == NULL)
147 msn_callback_state_set_action(MsnCallbackState *state, MsnCallbackAction action) 155 msn_callback_state_set_action(MsnCallbackState *state, MsnCallbackAction action)
148 { 156 {
149 g_return_if_fail(state != NULL); 157 g_return_if_fail(state != NULL);
150 158
151 state->action |= action; 159 state->action |= action;
152 }
153
154 /*contact SOAP server login error*/
155 static void
156 msn_contact_login_error_cb(MsnSoapConn *soapconn, PurpleSslConnection *gsc, PurpleSslErrorType error)
157 {
158 MsnSession *session;
159
160 session = soapconn->session;
161 g_return_if_fail(session != NULL);
162
163 msn_session_set_error(session, MSN_ERROR_SERV_DOWN, _("Unable to connect to contact server"));
164 }
165
166 /*msn contact SOAP server connect process*/
167 static gboolean
168 msn_contact_login_connect_cb(MsnSoapConn *soapconn, PurpleSslConnection *gsc)
169 {
170 MsnSession * session;
171 MsnContact *contact;
172
173 contact = soapconn->parent;
174 g_return_val_if_fail(contact != NULL, TRUE);
175
176 session = contact->session;
177 g_return_val_if_fail(session != NULL, FALSE);
178
179 /*login ok!We can retrieve the contact list*/
180 // msn_get_contact_list(contact, MSN_PS_INITIAL, NULL);
181 return TRUE;
182 } 160 }
183 161
184 /*get MSN member role utility*/ 162 /*get MSN member role utility*/
185 static MsnListId 163 static MsnListId
186 msn_get_memberrole(const char *role) 164 msn_get_memberrole(const char *role)
217 195
218 return MSN_USER_TYPE_UNKNOWN; 196 return MSN_USER_TYPE_UNKNOWN;
219 } 197 }
220 198
221 /* Create the AddressBook in the server, if we don't have one */ 199 /* Create the AddressBook in the server, if we don't have one */
222 static gboolean 200 static void
223 msn_create_address_cb(MsnSoapConn *soapconn) 201 msn_create_address_cb(MsnSoapMessage *req, MsnSoapMessage *resp, gpointer data)
224 { 202 {
225 MsnContact *contact; 203 if (resp && msn_soap_xml_get(resp->xml, "Body/Fault") == NULL) {
226 204 purple_debug_info("msnab", "Address Book successfully created!\n");
227 if (soapconn->body == NULL) 205 msn_get_address_book((MsnContact *)data, MSN_PS_INITIAL, NULL, NULL);
228 return TRUE; 206 } else {
229 207 purple_debug_info("msnab", "Address Book creation failed!\n");
230 contact = soapconn->parent; 208 }
231 g_return_val_if_fail(contact != NULL, TRUE);
232
233 purple_debug_info("MSN AddressBook", "Address Book successfully created!\n");
234 msn_get_address_book(contact, MSN_PS_INITIAL, NULL, NULL);
235
236 // msn_soap_free_read_buf(soapconn);
237 return TRUE;
238 }
239
240 static void
241 msn_create_address_written_cb(MsnSoapConn *soapconn)
242 {
243 purple_debug_info("MSN AddressBook","AddressBookAdd written\n");
244 soapconn->read_cb = msn_create_address_cb;
245
246 return;
247 } 209 }
248 210
249 static void 211 static void
250 msn_create_address_book(MsnContact * contact) 212 msn_create_address_book(MsnContact * contact)
251 { 213 {
252 MsnSoapReq *soap_request;
253 gchar *body; 214 gchar *body;
254 215
255 g_return_if_fail(contact != NULL); 216 g_return_if_fail(contact != NULL);
256 g_return_if_fail(contact->session != NULL); 217 g_return_if_fail(contact->session != NULL);
257 g_return_if_fail(contact->session->user != NULL); 218 g_return_if_fail(contact->session->user != NULL);
258 g_return_if_fail(contact->session->user->passport != NULL); 219 g_return_if_fail(contact->session->user->passport != NULL);
259 220
260 purple_debug_info("MSN AddressBook","Creating an Address Book.\n"); 221 purple_debug_info("msnab","Creating an Address Book.\n");
261 222
262 body = g_strdup_printf(MSN_ADD_ADDRESSBOOK_TEMPLATE, contact->session->user->passport); 223 body = g_strdup_printf(MSN_ADD_ADDRESSBOOK_TEMPLATE, contact->session->user->passport);
263 224
264 soap_request = msn_soap_request_new(MSN_CONTACT_SERVER, 225 msn_soap_message_send(contact->session,
265 MSN_ADDRESS_BOOK_POST_URL,MSN_ADD_ADDRESSBOOK_SOAP_ACTION, 226 msn_soap_message_new(MSN_ADD_ADDRESSBOOK_SOAP_ACTION,
266 body, 227 xmlnode_from_str(body, -1)),
267 NULL, 228 MSN_CONTACT_SERVER, MSN_ADDRESS_BOOK_POST_URL, msn_create_address_cb,
268 msn_create_address_cb, 229 contact);
269 msn_create_address_written_cb,
270 msn_contact_connect_init);
271 msn_soap_post(contact->soapconn, soap_request);
272 230
273 g_free(body); 231 g_free(body);
274 232 }
275 return; 233
234 static void
235 msn_parse_each_member(MsnSession *session, xmlnode *member, const char *node,
236 MsnListId list)
237 {
238 char *passport = xmlnode_get_data(xmlnode_get_child(member, node));
239 char *type = xmlnode_get_data(xmlnode_get_child(member, "type"));
240 char *member_id = xmlnode_get_data(xmlnode_get_child(member, "MembershipId"));
241 MsnUser *user = msn_userlist_find_add_user(session->userlist, passport, NULL);
242
243 purple_debug_info("msncl","%s name: %s, Type: %s\n", node, passport, type);
244
245 if (member_id) {
246 user->membership_id[list] = atoi(member_id);
247 }
248
249 msn_got_lst_user(session, user, 1 << list, NULL);
250
251 g_free(passport);
252 g_free(type);
253 g_free(member_id);
254 }
255
256 static void
257 msn_parse_each_service(MsnSession *session, xmlnode *service)
258 {
259 xmlnode *type;
260
261 if ((type = msn_soap_xml_get(service, "Info/Handle/Type"))) {
262 char *type_str = xmlnode_get_data(type);
263
264 if (g_str_equal(type_str, "Profile")) {
265 /* Process Windows Live 'Messenger Roaming Identity' */
266 } else if (g_str_equal(type_str, "Messenger")) {
267 xmlnode *lastchange = xmlnode_get_child(service, "LastChange");
268 char *lastchange_str = xmlnode_get_data(lastchange);
269 xmlnode *membership;
270
271 purple_debug_info("msncl","last change: %s\n", lastchange_str);
272 purple_account_set_string(session->account, "CLLastChange",
273 lastchange_str);
274
275 for (membership = msn_soap_xml_get(service,
276 "Memberships/Membership");
277 membership; membership = xmlnode_get_next_twin(membership)) {
278
279 xmlnode *role = xmlnode_get_child(membership, "MemberRole");
280 char *role_str = xmlnode_get_data(role);
281 MsnListId list = msn_get_memberrole(role_str);
282 xmlnode *member;
283
284 purple_debug_info("msncl", "MemberRole role: %s, list: %d\n",
285 role, list);
286
287 for (member = msn_soap_xml_get(membership, "Members/Member");
288 member; member = xmlnode_get_next_twin(member)) {
289 const char *member_type = xmlnode_get_attrib(member, "type");
290 if (g_str_equal(member_type, "PassportMember")) {
291 msn_parse_each_member(session, member, "PassportName",
292 list);
293 } else if (g_str_equal(member_type, "PhoneMember")) {
294
295 } else if (g_str_equal(member_type, "EmailMember")) {
296 msn_parse_each_member(session, member, "Email", list);
297 }
298 }
299
300 g_free(role_str);
301 }
302
303 g_free(lastchange_str);
304 }
305
306 g_free(type_str);
307 }
276 } 308 }
277 309
278 /*parse contact list*/ 310 /*parse contact list*/
279 static void 311 static void
280 msn_parse_contact_list(MsnContact * contact) 312 msn_parse_contact_list(MsnContact *contact, xmlnode *node)
281 { 313 {
282 MsnSession * session; 314 xmlnode *fault, *faultnode;
283 MsnListOp list_op = 0; 315
284 MsnListId list; 316 /* we may get a response if our cache data is too old:
285 char * passport, *typedata; 317 *
286 xmlnode *fault, *faultstringnode, *faultdetail, *errorcode; 318 * <faultstring>Need to do full sync. Can't sync deltas Client
287 xmlnode *node, *body, *response, *result, *services; 319 * has too old a copy for us to do a delta sync</faultstring>
288 xmlnode *service, *memberships, *info, *handle, *handletype; 320 *
289 xmlnode *membershipnode, *members, *member, *passportNode; 321 * this is not handled yet
290 322 */
291 session = contact->session; 323 if ((fault = msn_soap_xml_get(node, "Body/Fault"))) {
292 node = xmlnode_from_str(contact->soapconn->body, contact->soapconn->body_len); 324 if ((faultnode = xmlnode_get_child(fault, "faultstring"))) {
293 325 char *faultstring = xmlnode_get_data(faultnode);
294 if (node == NULL) { 326 purple_debug_info("msncl", "Retrieving contact list failed: %s\n",
295 purple_debug_error("MSNCL","Unable to parse SOAP data!\n"); 327 faultstring);
296 return;
297 }
298
299 purple_debug_misc("MSNCL","Parsing contact list with size %d\n", contact->soapconn->body_len);
300
301 purple_debug_misc("MSNCL","Root node @ %p: Name: '%s', child: '%s', lastchild: '%s'\n", node,
302 node->name ? node->name : "(null)",
303 (node->child && node->child->name) ? node->child->name : "(null)",
304 (node->lastchild && node->lastchild->name) ? node->lastchild->name : "(null)");
305
306 body = xmlnode_get_child(node, "Body");
307
308 if (body == NULL) {
309 purple_debug_warning("MSNCL", "Failed to parse contact list Body node\n");
310 xmlnode_free(node);
311 return;
312 }
313 purple_debug_info("MSNCL","Body @ %p: Name: '%s'\n",body,body->name);
314
315 /* Did we receive a <Fault> ? */
316 if ( (fault = xmlnode_get_child(body, "Fault")) != NULL) {
317 purple_debug_info("MSNCL","Fault received from SOAP server!\n");
318
319 if ( (faultstringnode = xmlnode_get_child(fault, "faultstring")) != NULL ) {
320 gchar * faultstring = xmlnode_get_data(faultstringnode);
321 purple_debug_info("MSNCL", "Faultstring: %s\n", faultstring ? faultstring : "(null)");
322 g_free(faultstring); 328 g_free(faultstring);
323 } 329 }
324 if ( (faultdetail = xmlnode_get_child(fault, "detail")) != NULL ) { 330 if ((faultnode = msn_soap_xml_get(fault, "detail/errorcode"))) {
325 purple_debug_info("MSNCL","detail @ %p, name: %s\n",faultdetail, faultdetail->name); 331 char *errorcode = xmlnode_get_data(faultnode);
326 332
327 if ( (errorcode = xmlnode_get_child(faultdetail, "errorcode")) != NULL ) { 333 if (g_str_equal(errorcode, "ABDoesNotExist")) {
328 purple_debug_info("MSNCL","errorcode @ %p, name: %s\n", errorcode, errorcode->name); 334 msn_create_address_book(contact);
329 335 g_free(errorcode);
330 if (errorcode->child != NULL) {
331 gchar *errorcodestring = xmlnode_get_data(errorcode);
332 purple_debug_info("MSNCL", "Error Code: %s\n", errorcodestring ? errorcodestring : "(null)");
333
334 if (errorcodestring && !strncmp(errorcodestring, "ABDoesNotExist", 14) ) {
335 xmlnode_free(node);
336 g_free(errorcodestring);
337 msn_create_address_book(contact);
338 return;
339 }
340 g_free(errorcodestring);
341 }
342 }
343 }
344 xmlnode_free(node);
345 msn_get_contact_list(contact, MSN_PS_INITIAL, NULL);
346 return;
347 }
348
349 response = xmlnode_get_child(body,"FindMembershipResponse");
350
351 if (response == NULL) {
352 /* we may get a response if our cache data is too old:
353 *
354 * <faultstring>Need to do full sync. Can't sync deltas Client
355 * has too old a copy for us to do a delta sync</faultstring>
356 */
357 xmlnode_free(node);
358 msn_get_contact_list(contact, MSN_PS_INITIAL, NULL);
359 return;
360 }
361 purple_debug_info("MSNCL","FindMembershipResponse @ %p: Name: '%s'\n",response,response->name);
362
363 result = xmlnode_get_child(response,"FindMembershipResult");
364 if (result == NULL) {
365 purple_debug_warning("MSNCL","Received No Update!\n");
366 xmlnode_free(node);
367 return;
368 }
369 purple_debug_info("MSNCL","Result @ %p: Name: '%s'\n", result, result->name);
370
371 if ( (services = xmlnode_get_child(result,"Services")) == NULL) {
372 purple_debug_misc("MSNCL","No <Services> received.\n");
373 xmlnode_free(node);
374 return;
375 }
376
377 purple_debug_info("MSNCL","Services @ %p\n",services);
378
379 for (service = xmlnode_get_child(services, "Service"); service;
380 service = xmlnode_get_next_twin(service)) {
381 purple_debug_info("MSNCL","Service @ %p\n",service);
382
383 if ( (info = xmlnode_get_child(service,"Info")) == NULL ) {
384 purple_debug_error("MSNCL","Error getting 'Info' child node\n");
385 continue;
386 }
387 if ( (handle = xmlnode_get_child(info,"Handle")) == NULL ) {
388 purple_debug_error("MSNCL","Error getting 'Handle' child node\n");
389 continue;
390 }
391 if ( (handletype = xmlnode_get_child(handle,"Type")) == NULL ) {
392 purple_debug_error("MSNCL","Error getting 'Type' child node\n");
393 continue;
394 }
395
396 if ( (typedata = xmlnode_get_data(handletype)) == NULL) {
397 purple_debug_error("MSNCL","Error retrieving data from 'Type' child node\n");
398 continue;
399 }
400
401 purple_debug_info("MSNCL","processing '%s' Service\n", typedata);
402
403 if ( !g_strcasecmp(typedata, "Profile") ) {
404 /* Process Windows Live 'Messenger Roaming Identity' */
405 g_free(typedata);
406 continue;
407 }
408
409 if ( !g_strcasecmp(typedata, "Messenger") ) {
410 char *LastChangeStr = NULL;
411 xmlnode *LastChangeNode;
412
413 /*Last Change Node*/
414 if ((LastChangeNode = xmlnode_get_child(service, "LastChange")))
415 LastChangeStr = xmlnode_get_data(LastChangeNode);
416 purple_debug_info("MSNCL","LastChangeNode: '%s'\n",LastChangeStr ? LastChangeStr : "(null)");
417 purple_account_set_string(session->account, "CLLastChange", LastChangeStr);
418 g_free(LastChangeStr);
419
420 memberships = xmlnode_get_child(service,"Memberships");
421 if (memberships == NULL) {
422 purple_debug_warning("MSNCL","Memberships = NULL, cleaning up and returning.\n");
423 g_free(typedata);
424 xmlnode_free(node);
425 return; 336 return;
426 } 337 }
427 purple_debug_info("MSNCL","Memberships @ %p: Name: '%s'\n",memberships,memberships->name); 338
428 for (membershipnode = xmlnode_get_child(memberships, "Membership"); membershipnode; 339 g_free(errorcode);
429 membershipnode = xmlnode_get_next_twin(membershipnode)){ 340 }
430 xmlnode *roleNode; 341
431 char *role = NULL; 342 msn_get_contact_list(contact, MSN_PS_INITIAL, NULL);
432 list = 0; 343 } else {
433 344 xmlnode *service;
434 if ((roleNode = xmlnode_get_child(membershipnode,"MemberRole"))) { 345
435 role = xmlnode_get_data(roleNode); 346 for (service = msn_soap_xml_get(node, "Body/FindMembershipResponse/"
436 list = msn_get_memberrole(role); 347 "FindMembershipResult/Services/Service");
437 } 348 service; service = xmlnode_get_next_twin(service)) {
438 list_op = 1 << list; 349 msn_parse_each_service(contact->session, service);
439 350 }
440 purple_debug_info("MSNCL","MemberRole role: %s, list_op: %d\n", role ? role : "(null)", list_op); 351 }
441 352 }
442 g_free(role); 353
443 354 static void
444 members = xmlnode_get_child(membershipnode, "Members"); 355 msn_get_contact_list_cb(MsnSoapMessage *req, MsnSoapMessage *resp,
445 for (member = xmlnode_get_child(members, "Member"); member; 356 gpointer data)
446 member = xmlnode_get_next_twin(member)){ 357 {
447 MsnUser *user = NULL; 358 GetContactListCbData *cb_data = data;
448 xmlnode *typeNode, *membershipIdNode = NULL; 359 MsnContact *contact = cb_data->contact;
449 gchar *type, *membershipId = NULL; 360 MsnSession *session = contact->session;
450 const char *member_type = xmlnode_get_attrib(member, "type"); 361
451 362 g_return_if_fail(session != NULL);
452 if (!member_type) { 363
453 purple_debug_error("msn", "No Member Type specified for Member.\n"); 364 if (resp != NULL) {
454 continue; 365 const char *abLastChange;
455 } 366 const char *dynamicItemLastChange;
456 367
457 if(!g_strcasecmp(member_type, "PassportMember") ) { 368 purple_debug_misc("msncl","Got the contact list!\n");
458 passport = type = NULL; 369
459 if ((passportNode = xmlnode_get_child(member, "PassportName"))) 370 msn_parse_contact_list(cb_data->contact, resp->xml);
460 passport = xmlnode_get_data(passportNode); 371 abLastChange = purple_account_get_string(session->account,
461 if ((typeNode = xmlnode_get_child(member, "Type"))) 372 "ablastChange", NULL);
462 type = xmlnode_get_data(typeNode); 373 dynamicItemLastChange = purple_account_get_string(session->account,
463 purple_debug_info("MSNCL","Passport name: '%s', Type: %s\n", passport ? passport : "(null)", type ? type : "(null)"); 374 "dynamicItemLastChange", NULL);
464 /* Why do we even bother parsing it just to free it??? */ 375
465 g_free(type); 376 if (cb_data->which == MSN_PS_INITIAL) {
466
467 user = msn_userlist_find_add_user(session->userlist,passport,NULL);
468 g_free(passport);
469
470 membershipIdNode = xmlnode_get_child(member,"MembershipId");
471 if (membershipIdNode != NULL) {
472 membershipId = xmlnode_get_data(membershipIdNode);
473 if (membershipId != NULL) {
474 user->membership_id[list] = atoi(membershipId);
475 g_free(membershipId);
476 }
477 }
478
479 msn_got_lst_user(session, user, list_op, NULL);
480 }
481 else if (!g_strcasecmp(member_type, "PhoneMember")) {
482 purple_debug_info("msn", "Recieved Phone Member; ignoring.\n");
483 }
484 else if (!g_strcasecmp(member_type, "EmailMember")) {
485 xmlnode *emailNode;
486 passport = NULL;
487
488 if ((emailNode = xmlnode_get_child(member, "Email")))
489 passport = xmlnode_get_data(emailNode);
490 purple_debug_info("MSNCL","Email Member: Name: '%s', list_op: %d\n", passport ? passport : "(null)", list_op);
491
492 user = msn_userlist_find_add_user(session->userlist, passport, NULL);
493 g_free(passport);
494
495 membershipIdNode = xmlnode_get_child(member,"MembershipId");
496 if (membershipIdNode != NULL) {
497 membershipId = xmlnode_get_data(membershipIdNode);
498 if (membershipId != NULL) {
499 user->membership_id[list] = atoi(membershipId);
500 g_free(membershipId);
501 }
502 }
503
504 msn_got_lst_user(session, user, list_op, NULL);
505 } else {
506 purple_debug_info("msn", "Unknown Member type: %s\n", member_type);
507 }
508 }
509 }
510 }
511 g_free(typedata);
512 }
513
514 xmlnode_free(node); /* Free the whole XML tree */
515 }
516
517 static gboolean
518 msn_get_contact_list_cb(MsnSoapConn *soapconn)
519 {
520 MsnContact *contact;
521 MsnSession *session;
522 const char *abLastChange;
523 const char *dynamicItemLastChange;
524 gchar *partner_scenario;
525
526 if (soapconn->body == NULL)
527 return TRUE;
528
529 purple_debug_misc("MSNCL","Got the contact list!\n");
530
531 contact = soapconn->parent;
532 g_return_val_if_fail(contact != NULL, TRUE);
533 session = soapconn->session;
534 g_return_val_if_fail(session != NULL, FALSE);
535 g_return_val_if_fail(soapconn->data_cb != NULL, TRUE);
536
537 partner_scenario = soapconn->data_cb;
538
539 msn_parse_contact_list(contact);
540 /*free the read buffer*/
541 msn_soap_free_read_buf(soapconn);
542
543 abLastChange = purple_account_get_string(session->account, "ablastChange", NULL);
544 dynamicItemLastChange = purple_account_get_string(session->account, "dynamicItemLastChange", NULL);
545
546 if (!strcmp(partner_scenario, MsnSoapPartnerScenarioText[MSN_PS_INITIAL])) {
547
548 #ifdef MSN_PARTIAL_LISTS 377 #ifdef MSN_PARTIAL_LISTS
549 /* XXX: this should be enabled when we can correctly do partial 378 /* XXX: this should be enabled when we can correctly do partial
550 syncs with the server. Currently we need to retrieve the whole 379 syncs with the server. Currently we need to retrieve the whole
551 list to detect sync issues */ 380 list to detect sync issues */
552 msn_get_address_book(contact, MSN_PS_INITIAL, abLastChange, dynamicItemLastChange); 381 msn_get_address_book(contact, MSN_PS_INITIAL, abLastChange, dynamicItemLastChange);
553 #else 382 #else
554 msn_get_address_book(contact, MSN_PS_INITIAL, NULL, NULL); 383 msn_get_address_book(contact, MSN_PS_INITIAL, NULL, NULL);
555 #endif 384 #endif
556 } else { 385 }
557 msn_soap_free_read_buf(soapconn); 386 }
558 } 387
559 388 g_free(cb_data);
560 return TRUE;
561 }
562
563 static void
564 msn_get_contact_written_cb(MsnSoapConn *soapconn)
565 {
566 purple_debug_misc("MSNCL","Sent SOAP request for the contact list.\n");
567 soapconn->read_cb = msn_get_contact_list_cb;
568 } 389 }
569 390
570 /* SOAP get contact list*/ 391 /* SOAP get contact list*/
571 void 392 void
572 msn_get_contact_list(MsnContact * contact, const MsnSoapPartnerScenario partner_scenario, const char *update_time) 393 msn_get_contact_list(MsnContact * contact,
573 { 394 const MsnSoapPartnerScenario partner_scenario, const char *update_time)
574 MsnSoapReq *soap_request; 395 {
575 gchar *body; 396 gchar *body = NULL;
576 gchar *update_str = NULL; 397 gchar * update_str;
398 GetContactListCbData cb_data = { contact, partner_scenario };
577 const gchar *partner_scenario_str = MsnSoapPartnerScenarioText[partner_scenario]; 399 const gchar *partner_scenario_str = MsnSoapPartnerScenarioText[partner_scenario];
578 400
579 purple_debug_misc("MSNCL","Getting Contact List.\n"); 401 purple_debug_misc("MSNCL","Getting Contact List.\n");
580 402
581 if ( update_time != NULL ) { 403 if ( update_time != NULL ) {
582 purple_debug_info("MSNCL","Last update time: %s\n",update_time); 404 purple_debug_info("MSNCL","Last update time: %s\n",update_time);
583 update_str = g_strdup_printf(MSN_GET_CONTACT_UPDATE_XML,update_time); 405 update_str = g_strdup_printf(MSN_GET_CONTACT_UPDATE_XML,update_time);
584 } 406 } else {
585 407 update_str = g_strdup("");
586 body = g_strdup_printf(MSN_GET_CONTACT_TEMPLATE, partner_scenario_str, update_str ? update_str : ""); 408 }
409
410 body = g_strdup_printf(MSN_GET_CONTACT_TEMPLATE, partner_scenario_str,
411 update_str);
412
413 msn_soap_message_send(contact->session,
414 msn_soap_message_new(MSN_GET_CONTACT_SOAP_ACTION,
415 xmlnode_from_str(body, -1)),
416 MSN_CONTACT_SERVER, MSN_GET_CONTACT_POST_URL,
417 msn_get_contact_list_cb, g_memdup(&cb_data, sizeof(cb_data)));
418
587 g_free(update_str); 419 g_free(update_str);
588
589 soap_request = msn_soap_request_new(MSN_CONTACT_SERVER,
590 MSN_GET_CONTACT_POST_URL,
591 MSN_GET_CONTACT_SOAP_ACTION,
592 body,
593 (gpointer) partner_scenario_str,
594 msn_get_contact_list_cb,
595 msn_get_contact_written_cb,
596 msn_contact_connect_init);
597 msn_soap_post(contact->soapconn,soap_request);
598 g_free(body); 420 g_free(body);
599 } 421 }
600 422
601 static void 423 static void
602 msn_parse_addressbook_groups(MsnContact *contact, xmlnode *node) 424 msn_parse_addressbook_groups(MsnContact *contact, xmlnode *node)
603 { 425 {
604 MsnSession *session = contact->session; 426 MsnSession *session = contact->session;
605 xmlnode *group; 427 xmlnode *group;
606 428
607 purple_debug_info("MsnAb","msn_parse_addressbook_groups()\n"); 429 purple_debug_info("MSNAB","msn_parse_addressbook_groups()\n");
608 430
609 for(group = xmlnode_get_child(node, "Group"); group; 431 for(group = xmlnode_get_child(node, "Group"); group;
610 group = xmlnode_get_next_twin(group)){ 432 group = xmlnode_get_next_twin(group)){
611 xmlnode *groupId, *groupInfo, *groupname; 433 xmlnode *groupId, *groupInfo, *groupname;
612 char *group_id = NULL, *group_name = NULL; 434 char *group_id = NULL, *group_name = NULL;
754 g_free(uid); 576 g_free(uid);
755 g_free(type); 577 g_free(type);
756 } 578 }
757 579
758 static gboolean 580 static gboolean
759 msn_parse_addressbook(MsnContact * contact) 581 msn_parse_addressbook(MsnContact * contact, xmlnode *node)
760 { 582 {
761 MsnSession *session; 583 MsnSession * session;
762 xmlnode * node,*body,*response,*result; 584 xmlnode *result;
763 xmlnode *groups; 585 xmlnode *groups;
764 xmlnode *contacts; 586 xmlnode *contacts;
765 xmlnode *abNode; 587 xmlnode *abNode;
766 xmlnode *fault, *faultstringnode, *faultdetail, *errorcode; 588 xmlnode *fault;
767 589
768 session = contact->session; 590 session = contact->session;
769 591
770 node = xmlnode_from_str(contact->soapconn->body, contact->soapconn->body_len); 592 if ((fault = msn_soap_xml_get(node, "Body/Fault"))) {
771 if ( node == NULL ) { 593 xmlnode *faultnode;
772 purple_debug_error("MSN AddressBook","Error parsing Address Book with size %d\n", contact->soapconn->body_len); 594
595 if ((faultnode = xmlnode_get_child(fault, "faultstring"))) {
596 gchar *faultstring = xmlnode_get_data(faultnode);
597 purple_debug_info("MSNAB","Faultstring: %s\n", faultstring);
598 g_free(faultstring);
599 }
600
601 if ((faultnode = msn_soap_xml_get(fault, "detail/errorcode"))) {
602 gchar *errorcode = xmlnode_get_data(faultnode);
603
604 purple_debug_info("MSNAB", "Error Code: %s\n", errorcode);
605
606 if (g_str_equal(errorcode, "ABDoesNotExist")) {
607 g_free(errorcode);
608 return TRUE;
609 }
610 }
611
773 return FALSE; 612 return FALSE;
774 } 613 }
775 614
776 purple_debug_misc("MSN AddressBook", "Parsing Address Book with size %d\n", contact->soapconn->body_len); 615 result = msn_soap_xml_get(node, "Body/ABFindAllResponse/ABFindAllResult");
777
778 purple_debug_misc("MSN AddressBook","node{%p},name:%s,child:%s,last:%s\n", node,
779 node->name ? node->name : "(null)",
780 (node->child && node->child->name) ? node->child->name : "(null)",
781 (node->lastchild && node->lastchild->name) ? node->lastchild->name : "(null)");
782
783 body = xmlnode_get_child(node,"Body");
784 purple_debug_misc("MSN AddressBook","body{%p},name:%s\n",body,body->name);
785
786 /* TODO: This appears to be used in a number of places and should be de-duplicated */
787 if ( (fault = xmlnode_get_child(body, "Fault")) != NULL) {
788 purple_debug_info("MSN AddressBook","Fault received from SOAP server!\n");
789
790 if ( (faultstringnode = xmlnode_get_child(fault, "faultstring")) != NULL ) {
791 gchar *faultstring = xmlnode_get_data(faultstringnode);
792 purple_debug_info("MSN AddressBook","Faultstring: %s\n", faultstring ? faultstring : "(null)");
793 g_free(faultstring);
794 }
795 if ( (faultdetail = xmlnode_get_child(fault, "detail")) != NULL ) {
796 purple_debug_info("MSN AddressBook","detail @ %p, name: %s\n",faultdetail, faultdetail->name);
797
798 if ( (errorcode = xmlnode_get_child(faultdetail, "errorcode")) != NULL ) {
799 gchar *errorcodestring;
800 purple_debug_info("MSN AddressBook","errorcode @ %p, name: %s\n",errorcode, errorcode->name);
801
802 errorcodestring = xmlnode_get_data(errorcode);
803 purple_debug_info("MSN AddressBook", "Error Code: %s\n", errorcodestring ? errorcodestring : "(null)");
804
805 if (errorcodestring && !strncmp(errorcodestring, "ABDoesNotExist", 14) ) {
806 g_free(errorcodestring);
807 xmlnode_free(node);
808 return TRUE;
809 }
810 g_free(errorcodestring);
811 }
812 }
813 xmlnode_free(node);
814 return FALSE;
815 }
816
817
818 response = xmlnode_get_child(body,"ABFindAllResponse");
819
820 if (response == NULL) {
821 xmlnode_free(node);
822 return FALSE;
823 }
824
825 purple_debug_misc("MSN SOAP","response{%p},name:%s\n",response,response->name);
826 result = xmlnode_get_child(response,"ABFindAllResult");
827 if(result == NULL){ 616 if(result == NULL){
828 purple_debug_misc("MSNAB","receive no address book update\n"); 617 purple_debug_misc("MSNAB","receive no address book update\n");
829 xmlnode_free(node);
830 return TRUE; 618 return TRUE;
831 } 619 }
832 purple_debug_info("MSN SOAP","result{%p},name:%s\n",result,result->name); 620
833 621 /* I don't see this "groups" tag documented on msnpiki, need to find out
622 if they are really there, and update msnpiki */
834 /*Process Group List*/ 623 /*Process Group List*/
835 groups = xmlnode_get_child(result,"groups"); 624 groups = xmlnode_get_child(result,"groups");
836 if (groups != NULL) { 625 if (groups != NULL) {
837 msn_parse_addressbook_groups(contact, groups); 626 msn_parse_addressbook_groups(contact, groups);
838 } 627 }
839 628
840 /*add a default No group to set up the no group Membership*/ 629 /*add a default No group to set up the no group Membership*/
841 msn_group_new(session->userlist, MSN_INDIVIDUALS_GROUP_ID, 630 msn_group_new(session->userlist, MSN_INDIVIDUALS_GROUP_ID,
842 MSN_INDIVIDUALS_GROUP_NAME); 631 MSN_INDIVIDUALS_GROUP_NAME);
843 purple_debug_misc("MsnAB","group_id:%s name:%s\n", 632 purple_debug_misc("MSNAB","group_id:%s name:%s\n",
844 MSN_INDIVIDUALS_GROUP_ID, MSN_INDIVIDUALS_GROUP_NAME); 633 MSN_INDIVIDUALS_GROUP_ID, MSN_INDIVIDUALS_GROUP_NAME);
845 if ((purple_find_group(MSN_INDIVIDUALS_GROUP_NAME)) == NULL){ 634 if ((purple_find_group(MSN_INDIVIDUALS_GROUP_NAME)) == NULL){
846 PurpleGroup *g = purple_group_new(MSN_INDIVIDUALS_GROUP_NAME); 635 PurpleGroup *g = purple_group_new(MSN_INDIVIDUALS_GROUP_NAME);
847 purple_blist_add_group(g, NULL); 636 purple_blist_add_group(g, NULL);
848 } 637 }
849 638
850 /*add a default No group to set up the no group Membership*/ 639 /*add a default No group to set up the no group Membership*/
851 msn_group_new(session->userlist, MSN_NON_IM_GROUP_ID, MSN_NON_IM_GROUP_NAME); 640 msn_group_new(session->userlist, MSN_NON_IM_GROUP_ID, MSN_NON_IM_GROUP_NAME);
852 purple_debug_misc("MsnAB","group_id:%s name:%s\n", MSN_NON_IM_GROUP_ID, MSN_NON_IM_GROUP_NAME); 641 purple_debug_misc("MSNAB","group_id:%s name:%s\n", MSN_NON_IM_GROUP_ID, MSN_NON_IM_GROUP_NAME);
853 if ((purple_find_group(MSN_NON_IM_GROUP_NAME)) == NULL){ 642 if ((purple_find_group(MSN_NON_IM_GROUP_NAME)) == NULL){
854 PurpleGroup *g = purple_group_new(MSN_NON_IM_GROUP_NAME); 643 PurpleGroup *g = purple_group_new(MSN_NON_IM_GROUP_NAME);
855 purple_blist_add_group(g, NULL); 644 purple_blist_add_group(g, NULL);
856 } 645 }
857 646
878 purple_debug_info("MsnAB"," DynamicItemLastChanged :{%s}\n", tmp ? tmp : "(null)"); 667 purple_debug_info("MsnAB"," DynamicItemLastChanged :{%s}\n", tmp ? tmp : "(null)");
879 purple_account_set_string(session->account, "DynamicItemLastChanged", tmp); 668 purple_account_set_string(session->account, "DynamicItemLastChanged", tmp);
880 g_free(tmp); 669 g_free(tmp);
881 } 670 }
882 671
883 xmlnode_free(node);
884 msn_soap_free_read_buf(contact->soapconn);
885 return TRUE; 672 return TRUE;
886 } 673 }
887 674
888 static gboolean 675 static void
889 msn_get_address_cb(MsnSoapConn *soapconn) 676 msn_get_address_cb(MsnSoapMessage *req, MsnSoapMessage *resp, gpointer data)
890 { 677 {
891 MsnContact *contact; 678 MsnContact *contact = data;
892 MsnSession *session; 679 MsnSession *session;
893 680
894 if (soapconn->body == NULL) 681 if (resp == NULL)
895 return TRUE; 682 return;
896 683
897 contact = soapconn->parent; 684 g_return_if_fail(contact != NULL);
898 g_return_val_if_fail(contact != NULL, TRUE); 685 session = contact->session;
899 session = soapconn->session; 686 g_return_if_fail(session != NULL);
900 g_return_val_if_fail(session != NULL, FALSE); 687
901 688 purple_debug_misc("MSNAB", "Got the Address Book!\n");
902 purple_debug_misc("MSN AddressBook", "Got the Address Book!\n"); 689
903 690 if (msn_parse_addressbook(contact, resp->xml)) {
904 if ( msn_parse_addressbook(contact) ) {
905 //msn_soap_free_read_buf(soapconn);
906
907 if (!session->logged_in) { 691 if (!session->logged_in) {
908 msn_send_privacy(session->account->gc); 692 msn_send_privacy(session->account->gc);
909 msn_notification_dump_contact(session); 693 msn_notification_dump_contact(session);
910 } 694 }
911
912 /*free the read buffer*/
913 msn_soap_free_read_buf(soapconn);
914 return TRUE;
915 } else { 695 } else {
916 /* This is making us loop infinitely when we fail to parse the address book, 696 /* This is making us loop infinitely when we fail to parse the
917 disable for now (we should re-enable when we send timestamps) 697 address book, disable for now (we should re-enable when we
698 send timestamps)
918 */ 699 */
919 /* 700 /*
920 msn_get_address_book(contact, NULL, NULL); 701 msn_get_address_book(contact, NULL, NULL);
921 */ 702 */
922 msn_session_disconnect(session); 703 msn_session_disconnect(session);
923 purple_connection_error(session->account->gc, _("Unable to retrieve MSN Address Book")); 704 purple_connection_error(session->account->gc, _("Unable to retrieve MSN Address Book"));
924 return FALSE; 705 }
925 }
926 }
927
928 /**/
929 static void
930 msn_address_written_cb(MsnSoapConn *soapconn)
931 {
932 purple_debug_misc("MSN AddressBook","Sent SOAP request for the Address Book.\n");
933 soapconn->read_cb = msn_get_address_cb;
934 } 706 }
935 707
936 /*get the address book*/ 708 /*get the address book*/
937 void 709 void
938 msn_get_address_book(MsnContact *contact, const MsnSoapPartnerScenario partner_scenario, const char *LastChanged, const char *dynamicItemLastChange) 710 msn_get_address_book(MsnContact *contact,
939 { 711 MsnSoapPartnerScenario partner_scenario, const char *LastChanged,
940 MsnSoapReq *soap_request; 712 const char *dynamicItemLastChange)
941 char *body; 713 {
942 char *update_str = NULL; 714 char *body = NULL;
943 715 char *ab_update_str,*update_str;
944 purple_debug_misc("MSN AddressBook","Getting Address Book\n"); 716
717 purple_debug_misc("MSNAB","Getting Address Book\n");
945 718
946 /*build SOAP and POST it*/ 719 /*build SOAP and POST it*/
947 if (dynamicItemLastChange != NULL) 720 if ( LastChanged != NULL ) {
948 update_str = g_strdup_printf(MSN_GET_ADDRESS_UPDATE_XML, dynamicItemLastChange); 721 ab_update_str = g_strdup_printf(MSN_GET_ADDRESS_UPDATE_XML,LastChanged);
949 else if (LastChanged != NULL) 722 } else {
950 update_str = g_strdup_printf(MSN_GET_ADDRESS_UPDATE_XML, LastChanged); 723 ab_update_str = g_strdup("");
951 724 }
952 725 if ( dynamicItemLastChange != NULL ) {
953 body = g_strdup_printf(MSN_GET_ADDRESS_TEMPLATE, MsnSoapPartnerScenarioText[partner_scenario], update_str ? update_str : ""); 726 update_str = g_strdup_printf(MSN_GET_ADDRESS_UPDATE_XML,
727 dynamicItemLastChange);
728 } else {
729 update_str = g_strdup(ab_update_str);
730 }
731
732 body = g_strdup_printf(MSN_GET_ADDRESS_TEMPLATE, MsnSoapPartnerScenarioText[partner_scenario], update_str);
954 g_free(update_str); 733 g_free(update_str);
955 734
956 soap_request = msn_soap_request_new(MSN_CONTACT_SERVER, 735 msn_soap_message_send(contact->session,
957 MSN_ADDRESS_BOOK_POST_URL,MSN_GET_ADDRESS_SOAP_ACTION, 736 msn_soap_message_new(MSN_GET_ADDRESS_SOAP_ACTION,
958 body, 737 xmlnode_from_str(body, -1)),
959 NULL, 738 MSN_CONTACT_SERVER, MSN_ADDRESS_BOOK_POST_URL, msn_get_address_cb,
960 msn_get_address_cb, 739 contact);
961 msn_address_written_cb, 740
962 msn_contact_connect_init); 741 g_free(ab_update_str);
963 msn_soap_post(contact->soapconn,soap_request);
964 g_free(body); 742 g_free(body);
965 } 743 }
966 744
967 static gboolean 745 static void
968 msn_add_contact_read_cb(MsnSoapConn *soapconn) 746 msn_add_contact_read_cb(MsnSoapMessage *req, MsnSoapMessage *resp,
969 { 747 gpointer data)
970 MsnCallbackState *state = NULL; 748 {
971 MsnUserList *userlist; 749 MsnCallbackState *state = data;
972 MsnUser *user; 750 MsnSession *session = state->session;
973 751
974 g_return_val_if_fail(soapconn->data_cb != NULL, TRUE); 752 g_return_if_fail(session != NULL);
975 g_return_val_if_fail(soapconn->session != NULL, FALSE); 753
976 g_return_val_if_fail(soapconn->session->userlist != NULL, TRUE); 754 if (resp != NULL) {
977 755 MsnUserList *userlist = session->userlist;
978 state = (MsnCallbackState *) soapconn->data_cb; 756 MsnUser *user;
979 757
980 if (soapconn->body == NULL) { 758 purple_debug_info("MSNCL","Contact added successfully\n");
981 msn_callback_state_free(state); 759
982 return TRUE; 760 // the code this block is replacing didn't send ADL for yahoo contacts,
983 } 761 // but i haven't confirmed this is WLM's behaviour wrt yahoo contacts
984 762
985 userlist = soapconn->session->userlist; 763 if ( !msn_user_is_yahoo(session->account, state->who) ) {
986
987 purple_debug_info("MSNCL","Contact added successfully\n");
988
989 // the code this block is replacing didn't send ADL for yahoo contacts,
990 // but i haven't confirmed this is WLM's behaviour wrt yahoo contacts
991
992 if ( !msn_user_is_yahoo(soapconn->session->account, state->who) ) {
993 764
994 msn_userlist_add_buddy_to_list(userlist, state->who, MSN_LIST_AL); 765 msn_userlist_add_buddy_to_list(userlist, state->who, MSN_LIST_AL);
995 msn_userlist_add_buddy_to_list(userlist, state->who, MSN_LIST_FL); 766 msn_userlist_add_buddy_to_list(userlist, state->who, MSN_LIST_FL);
996 } 767 }
997 msn_notification_send_fqy(soapconn->session, state->who); 768 msn_notification_send_fqy(session, state->who);
998 769
999 user = msn_userlist_find_add_user(userlist, state->who, state->who); 770 user = msn_userlist_find_add_user(userlist, state->who, state->who);
1000 msn_user_add_group_id(user, state->guid); 771 msn_user_add_group_id(user, state->guid);
1001 772
1002 msn_soap_free_read_buf(soapconn); 773 if (msn_userlist_user_is_in_list(user, MSN_LIST_PL)) {
774 msn_del_contact_from_list(session->contact, NULL, state->who, MSN_LIST_PL);
775 }
776 }
777
1003 msn_callback_state_free(state); 778 msn_callback_state_free(state);
1004
1005 return TRUE;
1006 }
1007
1008 static void
1009 msn_add_contact_written_cb(MsnSoapConn *soapconn)
1010 {
1011 purple_debug_info("MSNCL","Add contact request written\n");
1012 soapconn->read_cb = msn_add_contact_read_cb;
1013 } 779 }
1014 780
1015 /* add a Contact in MSN_INDIVIDUALS_GROUP */ 781 /* add a Contact in MSN_INDIVIDUALS_GROUP */
1016 void 782 void
1017 msn_add_contact(MsnContact *contact, MsnCallbackState *state, const char *passport) 783 msn_add_contact(MsnContact *contact, MsnCallbackState *state, const char *passport)
1018 { 784 {
1019 MsnSoapReq *soap_request;
1020 gchar *body = NULL; 785 gchar *body = NULL;
1021 gchar *contact_xml = NULL; 786 gchar *contact_xml = NULL;
1022 787
1023 g_return_if_fail(passport != NULL); 788 #if 0
1024 /* gchar *escaped_displayname; 789 gchar *escaped_displayname;
1025 790
1026 791
1027 if (displayname != NULL) { 792 if (displayname != NULL) {
1028 escaped_displayname = g_markup_decode_text(displayname, -1); 793 escaped_displayname = g_markup_decode_text(displayname, -1);
1029 } else { 794 } else {
1030 escaped_displayname = passport; 795 escaped_displayname = passport;
1031 } 796 }
1032 contact_xml = g_strdup_printf(MSN_XML_ADD_CONTACT, escaped_displayname, passport); 797 contact_xml = g_strdup_printf(MSN_XML_ADD_CONTACT, escaped_displayname, passport);
1033 */ 798 #endif
799
1034 purple_debug_info("MSNCL","Adding contact %s to contact list\n", passport); 800 purple_debug_info("MSNCL","Adding contact %s to contact list\n", passport);
1035 801
1036 // if ( !strcmp(state->guid, MSN_INDIVIDUALS_GROUP_ID) ) { 802 contact_xml = g_strdup_printf(MSN_CONTACT_XML, passport);
1037 contact_xml = g_strdup_printf(MSN_CONTACT_XML, passport);
1038 // }
1039 body = g_strdup_printf(MSN_ADD_CONTACT_TEMPLATE, contact_xml); 803 body = g_strdup_printf(MSN_ADD_CONTACT_TEMPLATE, contact_xml);
1040 804
805 msn_soap_message_send(contact->session,
806 msn_soap_message_new(MSN_CONTACT_ADD_SOAP_ACTION,
807 xmlnode_from_str(body, -1)),
808 MSN_CONTACT_SERVER, MSN_ADDRESS_BOOK_POST_URL,
809 msn_add_contact_read_cb, state);
810
1041 g_free(contact_xml); 811 g_free(contact_xml);
1042
1043 /*build SOAP and POST it*/
1044
1045 soap_request = msn_soap_request_new(MSN_CONTACT_SERVER,
1046 MSN_ADDRESS_BOOK_POST_URL,
1047 MSN_CONTACT_ADD_SOAP_ACTION,
1048 body,
1049 state,
1050 msn_add_contact_read_cb,
1051 msn_add_contact_written_cb,
1052 msn_contact_connect_init);
1053 msn_soap_post(contact->soapconn,soap_request);
1054
1055 g_free(body); 812 g_free(body);
1056 } 813 }
1057 814
1058 static gboolean 815 static void
1059 msn_add_contact_to_group_read_cb(MsnSoapConn *soapconn) 816 msn_add_contact_to_group_read_cb(MsnSoapMessage *req, MsnSoapMessage *resp,
1060 { 817 gpointer data)
1061 MsnCallbackState *state; 818 {
819 MsnCallbackState *state = data;
1062 MsnUserList *userlist; 820 MsnUserList *userlist;
1063 821
1064 g_return_val_if_fail(soapconn->data_cb != NULL, TRUE); 822 g_return_if_fail(data != NULL);
1065 g_return_val_if_fail(soapconn->session != NULL, FALSE); 823
1066 g_return_val_if_fail(soapconn->session->userlist != NULL, TRUE); 824 userlist = state->session->userlist;
1067 825
1068 userlist = soapconn->session->userlist; 826 if (resp != NULL) {
1069 827 if (msn_userlist_add_buddy_to_group(userlist, state->who,
1070 state = (MsnCallbackState *) soapconn->data_cb; 828 state->new_group_name)) {
1071 829 purple_debug_info("MSNCL", "Contact %s added to group %s successfully!\n", state->who, state->new_group_name);
1072 if (soapconn->body == NULL) { 830 } else {
1073 msn_callback_state_free(state); 831 purple_debug_info("MSNCL","Contact %s added to group %s successfully on server, but failed in the local list\n", state->who, state->new_group_name);
1074 return TRUE; 832 }
1075 } 833
1076 834 if (state->action & MSN_ADD_BUDDY) {
1077 if (msn_userlist_add_buddy_to_group(userlist, state->who, state->new_group_name) == TRUE) { 835 MsnUser *user = msn_userlist_find_user(userlist, state->who);
1078 purple_debug_info("MSNCL", "Contact %s added to group %s successfully!\n", state->who, state->new_group_name); 836
1079 } else { 837 if ( !msn_user_is_yahoo(state->session->account, state->who) ) {
1080 purple_debug_info("MSNCL","Contact %s added to group %s successfully on server, but failed in the local list\n", state->who, state->new_group_name); 838
1081 } 839 msn_userlist_add_buddy_to_list(userlist, state->who, MSN_LIST_AL);
1082 840 msn_userlist_add_buddy_to_list(userlist, state->who, MSN_LIST_FL);
1083 if (state->action & MSN_ADD_BUDDY) {
1084
1085 if ( !msn_user_is_yahoo(soapconn->session->account, state->who) ) {
1086
1087 msn_userlist_add_buddy_to_list(userlist, state->who, MSN_LIST_AL);
1088 msn_userlist_add_buddy_to_list(userlist, state->who, MSN_LIST_FL);
1089 } 841 }
1090 msn_notification_send_fqy(soapconn->session, state->who); 842 msn_notification_send_fqy(state->session, state->who);
1091 } 843
1092 844 if (msn_userlist_user_is_in_list(user, MSN_LIST_PL)) {
1093 if (state->action & MSN_MOVE_BUDDY) { 845 msn_del_contact_from_list(state->session->contact, NULL, state->who, MSN_LIST_PL);
1094 msn_del_contact_from_group(soapconn->session->contact, state->who, state->old_group_name); 846 msn_callback_state_free(state);
1095 } else { 847 return;
1096 msn_callback_state_free(state); 848 }
1097 msn_soap_free_read_buf(soapconn); 849 }
1098 } 850
1099 return TRUE; 851 if (state->action & MSN_MOVE_BUDDY) {
1100 } 852 msn_del_contact_from_group(state->session->contact, state->who, state->old_group_name);
1101 853 }
1102 static void 854 }
1103 msn_add_contact_to_group_written_cb(MsnSoapConn *soapconn) 855
1104 { 856 msn_callback_state_free(state);
1105 purple_debug_info("MSNCL","Add contact to group request sent!\n");
1106 soapconn->read_cb = msn_add_contact_to_group_read_cb;
1107 } 857 }
1108 858
1109 void 859 void
1110 msn_add_contact_to_group(MsnContact *contact, MsnCallbackState *state, 860 msn_add_contact_to_group(MsnContact *contact, MsnCallbackState *state,
1111 const char *passport, const char *groupId) 861 const char *passport, const char *groupId)
1112 { 862 {
1113 MsnSoapReq *soap_request;
1114 MsnUserList *userlist; 863 MsnUserList *userlist;
1115 MsnUser *user; 864 MsnUser *user;
1116 gchar *body = NULL, *contact_xml; 865 gchar *body = NULL, *contact_xml;
1117 866
1118 g_return_if_fail(passport != NULL); 867 g_return_if_fail(passport != NULL);
1141 } 890 }
1142 891
1143 return; 892 return;
1144 } 893 }
1145 894
1146
1147 purple_debug_info("MSNCL", "Adding user %s to group %s\n", passport, 895 purple_debug_info("MSNCL", "Adding user %s to group %s\n", passport,
1148 msn_userlist_find_group_name(userlist, groupId)); 896 msn_userlist_find_group_name(userlist, groupId));
1149 897
1150 user = msn_userlist_find_user(userlist, passport); 898 user = msn_userlist_find_user(userlist, passport);
1151 if (user == NULL) { 899 if (user == NULL) {
1152 purple_debug_warning("MSN CL", "Unable to retrieve user %s from the userlist!\n", passport); 900 purple_debug_warning("MSNCL", "Unable to retrieve user %s from the userlist!\n", passport);
901 msn_callback_state_free(state);
902 return; /* guess this never happened! */
1153 } 903 }
1154 904
1155 if (user != NULL && user->uid != NULL) { 905 if (user != NULL && user->uid != NULL) {
1156 contact_xml = g_strdup_printf(MSN_CONTACT_ID_XML, user->uid); 906 contact_xml = g_strdup_printf(MSN_CONTACT_ID_XML, user->uid);
1157 } else { 907 } else {
1158 contact_xml = g_strdup_printf(MSN_CONTACT_XML, passport); 908 contact_xml = g_strdup_printf(MSN_CONTACT_XML, passport);
1159 } 909 }
1160 910
1161 body = g_strdup_printf(MSN_ADD_CONTACT_GROUP_TEMPLATE, groupId, contact_xml); 911 body = g_strdup_printf(MSN_ADD_CONTACT_GROUP_TEMPLATE, groupId, contact_xml);
912
913 msn_soap_message_send(state->session,
914 msn_soap_message_new(MSN_ADD_CONTACT_GROUP_SOAP_ACTION,
915 xmlnode_from_str(body, -1)),
916 MSN_CONTACT_SERVER, MSN_ADDRESS_BOOK_POST_URL,
917 msn_add_contact_to_group_read_cb, state);
918
1162 g_free(contact_xml); 919 g_free(contact_xml);
1163
1164 /*build SOAP and POST it*/
1165
1166 soap_request = msn_soap_request_new(MSN_CONTACT_SERVER,
1167 MSN_ADDRESS_BOOK_POST_URL,
1168 MSN_ADD_CONTACT_GROUP_SOAP_ACTION,
1169 body,
1170 state,
1171 msn_add_contact_to_group_read_cb,
1172 msn_add_contact_to_group_written_cb,
1173 msn_contact_connect_init);
1174 msn_soap_post(contact->soapconn,soap_request);
1175
1176 g_free(body); 920 g_free(body);
1177 } 921 }
1178 922
1179 923 static void
1180 924 msn_delete_contact_read_cb(MsnSoapMessage *req, MsnSoapMessage *resp,
1181 static gboolean 925 gpointer data)
1182 msn_delete_contact_read_cb(MsnSoapConn *soapconn) 926 {
1183 { 927 if (resp == NULL)
1184 MsnUser *user; 928 return;
1185 MsnCallbackState *state = (MsnCallbackState *) soapconn->data_cb;
1186 MsnUserList *userlist;
1187
1188 g_return_val_if_fail(soapconn->session != NULL, FALSE);
1189 g_return_val_if_fail(soapconn->session->userlist != NULL, TRUE);
1190
1191 userlist = soapconn->session->userlist;
1192
1193 if (soapconn->body == NULL) {
1194 msn_callback_state_free(state);
1195 return TRUE;
1196 }
1197 929
1198 purple_debug_info("MSNCL","Delete contact successful\n"); 930 purple_debug_info("MSNCL","Delete contact successful\n");
1199 931
1200 user = msn_userlist_find_user_with_id(userlist, state->uid); 932 user = msn_userlist_find_user_with_id(userlist, state->uid);
1201 if (user != NULL) { 933 if (user != NULL) {
1219 void 951 void
1220 msn_delete_contact(MsnContact *contact, const char *contactId) 952 msn_delete_contact(MsnContact *contact, const char *contactId)
1221 { 953 {
1222 gchar *body = NULL; 954 gchar *body = NULL;
1223 gchar *contact_id_xml = NULL ; 955 gchar *contact_id_xml = NULL ;
1224 MsnSoapReq *soap_request;
1225 MsnCallbackState *state;
1226 956
1227 g_return_if_fail(contactId != NULL); 957 g_return_if_fail(contactId != NULL);
1228 contact_id_xml = g_strdup_printf(MSN_CONTACT_ID_XML, contactId); 958 contact_id_xml = g_strdup_printf(MSN_CONTACT_ID_XML, contactId);
1229 959
1230 state = msn_callback_state_new(); 960 state = msn_callback_state_new();
1241 msn_delete_contact_read_cb, 971 msn_delete_contact_read_cb,
1242 msn_delete_contact_written_cb, 972 msn_delete_contact_written_cb,
1243 msn_contact_connect_init); 973 msn_contact_connect_init);
1244 974
1245 g_free(contact_id_xml); 975 g_free(contact_id_xml);
1246
1247 /* POST the SOAP request */
1248 msn_soap_post(contact->soapconn, soap_request);
1249
1250 g_free(body); 976 g_free(body);
1251 } 977 }
1252 978
1253 static gboolean 979 static void
1254 msn_del_contact_from_group_read_cb(MsnSoapConn *soapconn) 980 msn_del_contact_from_group_read_cb(MsnSoapMessage *req, MsnSoapMessage *resp,
1255 { 981 gpointer data)
1256 MsnCallbackState *state = (MsnCallbackState *) soapconn->data_cb; 982 {
1257 983 MsnCallbackState *state = data;
1258 if (soapconn->body == NULL) { 984
1259 msn_callback_state_free(state); 985 if (resp != NULL) {
1260 return TRUE; 986 if (msn_userlist_rem_buddy_from_group(state->session->userlist,
1261 } 987 state->who, state->old_group_name)) {
1262 988 purple_debug_info("MSNCL", "Contact %s deleted successfully from group %s\n", state->who, state->old_group_name);
1263 if (msn_userlist_rem_buddy_from_group(soapconn->session->userlist, state->who, state->old_group_name)) { 989 } else {
1264 purple_debug_info("MSN CL", "Contact %s deleted successfully from group %s\n", state->who, state->old_group_name); 990 purple_debug_info("MSNCL", "Contact %s deleted successfully from group %s in the server, but failed in the local list\n", state->who, state->old_group_name);
1265 } else { 991 }
1266 purple_debug_info("MSN CL", "Contact %s deleted successfully from group %s in the server, but failed in the local list\n", state->who, state->old_group_name);
1267 } 992 }
1268 993
1269 msn_callback_state_free(state); 994 msn_callback_state_free(state);
1270 msn_soap_free_read_buf(soapconn);
1271
1272 return TRUE;
1273 }
1274
1275 static void
1276 msn_del_contact_from_group_written_cb(MsnSoapConn *soapconn)
1277 {
1278 purple_debug_info("MSN CL","Del contact from group request sent!\n");
1279 soapconn->read_cb = msn_del_contact_from_group_read_cb;
1280 } 995 }
1281 996
1282 void 997 void
1283 msn_del_contact_from_group(MsnContact *contact, const char *passport, const char *group_name) 998 msn_del_contact_from_group(MsnContact *contact, const char *passport, const char *group_name)
1284 { 999 {
1285 MsnSoapReq *soap_request;
1286 MsnUserList * userlist; 1000 MsnUserList * userlist;
1287 MsnUser *user; 1001 MsnUser *user;
1288 MsnCallbackState *state; 1002 MsnCallbackState *state;
1289 gchar *body = NULL, *contact_id_xml; 1003 gchar *body, *contact_id_xml;
1290 const gchar *groupId; 1004 const gchar *groupId;
1291 1005
1292 g_return_if_fail(passport != NULL); 1006 g_return_if_fail(passport != NULL);
1293 g_return_if_fail(group_name != NULL); 1007 g_return_if_fail(group_name != NULL);
1294 g_return_if_fail(contact != NULL); 1008 g_return_if_fail(contact != NULL);
1297 1011
1298 userlist = contact->session->userlist; 1012 userlist = contact->session->userlist;
1299 1013
1300 groupId = msn_userlist_find_group_id(userlist, group_name); 1014 groupId = msn_userlist_find_group_id(userlist, group_name);
1301 if (groupId != NULL) { 1015 if (groupId != NULL) {
1302 purple_debug_info("MSN CL", "Deleting user %s from group %s\n", passport, group_name); 1016 purple_debug_info("MSNCL", "Deleting user %s from group %s\n", passport, group_name);
1303 } else { 1017 } else {
1304 purple_debug_warning("MSN CL", "Unable to retrieve group id from group %s !\n", group_name); 1018 purple_debug_warning("MSNCL", "Unable to retrieve group id from group %s !\n", group_name);
1305 return; 1019 return;
1306 } 1020 }
1307 1021
1308 user = msn_userlist_find_user(userlist, passport); 1022 user = msn_userlist_find_user(userlist, passport);
1309 1023
1310 if (user == NULL) { 1024 if (user == NULL) {
1311 purple_debug_warning("MSN CL", "Unable to retrieve user from passport %s!\n", passport); 1025 purple_debug_warning("MSNCL", "Unable to retrieve user from passport %s!\n", passport);
1312 return; 1026 return;
1313 } 1027 }
1314 1028
1315 if ( !strcmp(groupId, MSN_INDIVIDUALS_GROUP_ID) || !strcmp(groupId, MSN_NON_IM_GROUP_ID)) { 1029 if ( !strcmp(groupId, MSN_INDIVIDUALS_GROUP_ID) || !strcmp(groupId, MSN_NON_IM_GROUP_ID)) {
1316 msn_user_remove_group_id(user, groupId); 1030 msn_user_remove_group_id(user, groupId);
1317 return; 1031 return;
1318 } 1032 }
1319 1033
1320 state = msn_callback_state_new(); 1034 state = msn_callback_state_new(contact->session);
1321 msn_callback_state_set_who(state, passport); 1035 msn_callback_state_set_who(state, passport);
1322 msn_callback_state_set_guid(state, groupId); 1036 msn_callback_state_set_guid(state, groupId);
1323 msn_callback_state_set_old_group_name(state, group_name); 1037 msn_callback_state_set_old_group_name(state, group_name);
1324 1038
1325 contact_id_xml = g_strdup_printf(MSN_CONTACT_ID_XML, user->uid); 1039 contact_id_xml = g_strdup_printf(MSN_CONTACT_ID_XML, user->uid);
1326 body = g_strdup_printf(MSN_CONTACT_DEL_GROUP_TEMPLATE, contact_id_xml, groupId); 1040 body = g_strdup_printf(MSN_CONTACT_DEL_GROUP_TEMPLATE, contact_id_xml, groupId);
1041
1042 msn_soap_message_send(contact->session,
1043 msn_soap_message_new(MSN_CONTACT_DEL_GROUP_SOAP_ACTION,
1044 xmlnode_from_str(body, -1)),
1045 MSN_CONTACT_SERVER, MSN_ADDRESS_BOOK_POST_URL,
1046 msn_del_contact_from_group_read_cb, state);
1047
1327 g_free(contact_id_xml); 1048 g_free(contact_id_xml);
1328
1329 /*build SOAP and POST it*/
1330 soap_request = msn_soap_request_new(MSN_CONTACT_SERVER,
1331 MSN_ADDRESS_BOOK_POST_URL,
1332 MSN_CONTACT_DEL_GROUP_SOAP_ACTION,
1333 body,
1334 state,
1335 msn_del_contact_from_group_read_cb,
1336 msn_del_contact_from_group_written_cb,
1337 msn_contact_connect_init);
1338 msn_soap_post(contact->soapconn,soap_request);
1339
1340 g_free(body); 1049 g_free(body);
1341 } 1050 }
1342 1051
1343 1052
1344 static gboolean 1053 static void
1345 msn_update_contact_read_cb(MsnSoapConn *soapconn) 1054 msn_update_contact_read_cb(MsnSoapMessage *req, MsnSoapMessage *resp,
1346 { 1055 gpointer data)
1347 if (soapconn->body == NULL) 1056 {
1348 return TRUE; 1057 if (resp)
1349 1058 purple_debug_info("MSN CL","Contact updated successfully\n");
1350 purple_debug_info("MSN CL","Contact updated successfully\n"); 1059 else
1351 1060 purple_debug_info("MSN CL","Contact updated successfully\n");
1352 return TRUE;
1353 }
1354
1355 static void
1356 msn_update_contact_written_cb(MsnSoapConn *soapconn)
1357 {
1358 purple_debug_info("MSN CL","Update contact information request sent\n");
1359 soapconn->read_cb = msn_update_contact_read_cb;
1360 } 1061 }
1361 1062
1362 /* Update a contact's nickname */ 1063 /* Update a contact's nickname */
1363
1364 void 1064 void
1365 msn_update_contact(MsnContact *contact, const char* nickname) 1065 msn_update_contact(MsnContact *contact, const char* nickname)
1366 { 1066 {
1367 MsnSoapReq *soap_request; 1067 gchar *body = NULL, *escaped_nickname;
1368 gchar *body, *escaped_nickname;
1369
1370 /* I'm not sure this is right, but if it isn't, the rest of this function will need to be fixed */
1371 g_return_if_fail(nickname != NULL);
1372 1068
1373 purple_debug_info("MSN CL","Update contact information with new friendly name: %s\n", nickname); 1069 purple_debug_info("MSN CL","Update contact information with new friendly name: %s\n", nickname);
1374 1070
1375 escaped_nickname = g_markup_escape_text(nickname, -1); 1071 escaped_nickname = g_markup_escape_text(nickname, -1);
1376 1072
1377 body = g_strdup_printf(MSN_CONTACT_UPDATE_TEMPLATE, escaped_nickname); 1073 body = g_strdup_printf(MSN_CONTACT_UPDATE_TEMPLATE, escaped_nickname);
1378 1074
1075 msn_soap_message_send(contact->session,
1076 msn_soap_message_new(MSN_CONTACT_UPDATE_SOAP_ACTION,
1077 xmlnode_from_str(body, -1)),
1078 MSN_CONTACT_SERVER, MSN_ADDRESS_BOOK_POST_URL,
1079 msn_update_contact_read_cb, NULL);
1080
1379 g_free(escaped_nickname); 1081 g_free(escaped_nickname);
1380 /*build SOAP and POST it*/
1381 soap_request = msn_soap_request_new(MSN_CONTACT_SERVER,
1382 MSN_ADDRESS_BOOK_POST_URL,
1383 MSN_CONTACT_UPDATE_SOAP_ACTION,
1384 body,
1385 NULL,
1386 msn_update_contact_read_cb,
1387 msn_update_contact_written_cb,
1388 msn_contact_connect_init);
1389 msn_soap_post(contact->soapconn, soap_request);
1390
1391 g_free(body); 1082 g_free(body);
1392 } 1083 }
1393 1084
1394 1085 static void
1395 static gboolean 1086 msn_del_contact_from_list_read_cb(MsnSoapMessage *req, MsnSoapMessage *resp,
1396 msn_del_contact_from_list_read_cb(MsnSoapConn *soapconn) 1087 gpointer data)
1397 { 1088 {
1398 MsnCallbackState *state = NULL; 1089 MsnCallbackState *state = data;
1399 1090 MsnSession *session = state->session;
1400 g_return_val_if_fail(soapconn->data_cb != NULL, TRUE); 1091
1401 g_return_val_if_fail(soapconn->session != NULL, FALSE); 1092 if (resp != NULL) {
1402 g_return_val_if_fail(soapconn->session->contact != NULL, FALSE); 1093 purple_debug_info("MSN CL", "Contact %s deleted successfully from %s list on server!\n", state->who, MsnMemberRole[state->list_id]);
1403 g_return_val_if_fail(soapconn->session->userlist != NULL, FALSE); 1094
1404 1095 if (state->list_id == MSN_LIST_PL) {
1405 state = (MsnCallbackState *) soapconn->data_cb; 1096 msn_add_contact_to_list(session->contact, state, state->who, MSN_LIST_RL);
1406 1097 } else if (state->list_id == MSN_LIST_AL) {
1407 if (soapconn->body == NULL) { 1098 purple_privacy_permit_remove(session->account, state->who, TRUE);
1408 msn_callback_state_free(state); 1099 msn_add_contact_to_list(session->contact, NULL, state->who, MSN_LIST_BL);
1409 return TRUE; 1100 } else if (state->list_id == MSN_LIST_BL) {
1410 } 1101 purple_privacy_deny_remove(session->account, state->who, TRUE);
1411 1102 msn_add_contact_to_list(session->contact, NULL, state->who, MSN_LIST_AL);
1412 purple_debug_info("MSN CL", "Contact %s deleted successfully from %s list on server!\n", state->who, MsnMemberRole[state->list_id]); 1103 }
1413
1414 if (state->list_id == MSN_LIST_PL) {
1415 MsnUser *user = msn_userlist_find_user(soapconn->session->userlist, state->who);
1416
1417 if (user != NULL)
1418 msn_user_unset_op(user, MSN_LIST_PL_OP);
1419
1420 msn_add_contact_to_list(soapconn->session->contact, state, state->who, MSN_LIST_RL);
1421 return TRUE;
1422 }
1423
1424 if (state->list_id == MSN_LIST_AL) {
1425 purple_privacy_permit_remove(soapconn->session->account, state->who, TRUE);
1426 msn_add_contact_to_list(soapconn->session->contact, NULL, state->who, MSN_LIST_BL);
1427 msn_callback_state_free(state);
1428 return TRUE;
1429 }
1430
1431 if (state->list_id == MSN_LIST_BL) {
1432 purple_privacy_deny_remove(soapconn->session->account, state->who, TRUE);
1433 msn_add_contact_to_list(soapconn->session->contact, NULL, state->who, MSN_LIST_AL);
1434 msn_callback_state_free(state);
1435 return TRUE;
1436 } 1104 }
1437 1105
1438 msn_callback_state_free(state); 1106 msn_callback_state_free(state);
1439 msn_soap_free_read_buf(soapconn);
1440
1441 return TRUE;
1442 }
1443
1444 static void
1445 msn_del_contact_from_list_written_cb(MsnSoapConn *soapconn)
1446 {
1447 purple_debug_info("MSN CL","Delete contact from list SOAP request sent!\n");
1448 soapconn->read_cb = msn_del_contact_from_list_read_cb;
1449 } 1107 }
1450 1108
1451 void 1109 void
1452 msn_del_contact_from_list(MsnContact *contact, MsnCallbackState *state, 1110 msn_del_contact_from_list(MsnContact *contact, MsnCallbackState *state,
1453 const gchar *passport, const MsnListId list) 1111 const gchar *passport, const MsnListId list)
1454 { 1112 {
1455 MsnSoapReq *soap_request;
1456 gchar *body = NULL, *member = NULL; 1113 gchar *body = NULL, *member = NULL;
1457 MsnSoapPartnerScenario partner_scenario; 1114 MsnSoapPartnerScenario partner_scenario;
1458 MsnUser *user; 1115 MsnUser *user;
1459 1116
1460 g_return_if_fail(contact != NULL); 1117 g_return_if_fail(contact != NULL);
1462 g_return_if_fail(list < 5); 1119 g_return_if_fail(list < 5);
1463 1120
1464 purple_debug_info("MSN CL", "Deleting contact %s from %s list\n", passport, MsnMemberRole[list]); 1121 purple_debug_info("MSN CL", "Deleting contact %s from %s list\n", passport, MsnMemberRole[list]);
1465 1122
1466 if (state == NULL) { 1123 if (state == NULL) {
1467 state = msn_callback_state_new(); 1124 state = msn_callback_state_new(contact->session);
1468 } 1125 }
1469 msn_callback_state_set_list_id(state, list); 1126 msn_callback_state_set_list_id(state, list);
1470 msn_callback_state_set_who(state, passport); 1127 msn_callback_state_set_who(state, passport);
1471 1128
1472 if (list == MSN_LIST_PL) { 1129 if (list == MSN_LIST_PL) {
1486 1143
1487 body = g_strdup_printf( MSN_CONTACT_DELECT_FROM_LIST_TEMPLATE, 1144 body = g_strdup_printf( MSN_CONTACT_DELECT_FROM_LIST_TEMPLATE,
1488 MsnSoapPartnerScenarioText[partner_scenario], 1145 MsnSoapPartnerScenarioText[partner_scenario],
1489 MsnMemberRole[list], 1146 MsnMemberRole[list],
1490 member); 1147 member);
1148
1149 msn_soap_message_send(contact->session,
1150 msn_soap_message_new(MSN_DELETE_MEMBER_FROM_LIST_SOAP_ACTION,
1151 xmlnode_from_str(body, -1)),
1152 MSN_CONTACT_SERVER, MSN_SHARE_POST_URL,
1153 msn_del_contact_from_list_read_cb, state);
1154
1491 g_free(member); 1155 g_free(member);
1492
1493 soap_request = msn_soap_request_new( MSN_CONTACT_SERVER,
1494 MSN_SHARE_POST_URL,
1495 MSN_DELETE_MEMBER_FROM_LIST_SOAP_ACTION,
1496 body,
1497 state,
1498 msn_del_contact_from_list_read_cb,
1499 msn_del_contact_from_list_written_cb,
1500 msn_contact_connect_init);
1501
1502 msn_soap_post(contact->soapconn,soap_request);
1503
1504 g_free(body); 1156 g_free(body);
1505 } 1157 }
1506 1158
1507 static gboolean 1159 static void
1508 msn_add_contact_to_list_read_cb(MsnSoapConn *soapconn) 1160 msn_add_contact_to_list_read_cb(MsnSoapMessage *req, MsnSoapMessage *resp,
1509 { 1161 gpointer data)
1510 MsnCallbackState *state = NULL; 1162 {
1511 1163 MsnCallbackState *state = data;
1512 g_return_val_if_fail(soapconn->data_cb != NULL, TRUE); 1164
1513 g_return_val_if_fail(soapconn->session != NULL, FALSE); 1165 g_return_if_fail(state != NULL);
1514 g_return_val_if_fail(soapconn->session->userlist != NULL, FALSE); 1166 g_return_if_fail(state->session != NULL);
1515 1167 g_return_if_fail(state->session->contact != NULL);
1516 state = (MsnCallbackState *) soapconn->data_cb; 1168
1517 1169 if (resp != NULL) {
1518 if (soapconn->body == NULL) { 1170 purple_debug_info("MSN CL", "Contact %s added successfully to %s list on server!\n", state->who, MsnMemberRole[state->list_id]);
1519 msn_callback_state_free(state); 1171
1520 return TRUE; 1172 if (state->list_id == MSN_LIST_RL &&
1521 } 1173 (state->action & MSN_DENIED_BUDDY)) {
1522 1174
1523 purple_debug_info("MSN CL", "Contact %s added successfully to %s list on server!\n", state->who, MsnMemberRole[state->list_id]); 1175 msn_add_contact_to_list(state->session->contact, NULL, state->who, MSN_LIST_BL);
1524 1176 } else if (state->list_id == MSN_LIST_AL) {
1525 if (state->list_id == MSN_LIST_RL) { 1177 purple_privacy_permit_add(state->session->account, state->who, TRUE);
1526 MsnUser *user = msn_userlist_find_user(soapconn->session->userlist, state->who); 1178 } else if (state->list_id == MSN_LIST_BL) {
1527 1179 purple_privacy_deny_add(state->session->account, state->who, TRUE);
1528 if (user != NULL) {
1529 msn_user_set_op(user, MSN_LIST_RL_OP);
1530 }
1531
1532 if (state->action & MSN_DENIED_BUDDY) {
1533 g_return_val_if_fail(soapconn->session->contact != NULL, FALSE);
1534
1535 msn_add_contact_to_list(soapconn->session->contact, NULL, state->who, MSN_LIST_BL);
1536 return TRUE;
1537 } 1180 }
1538 } 1181 }
1539 1182
1540 if (state->list_id == MSN_LIST_AL) { 1183 if (state->list_id == MSN_LIST_AL) {
1541 purple_privacy_permit_add(soapconn->session->account, state->who, TRUE); 1184 purple_privacy_permit_add(soapconn->session->account, state->who, TRUE);
1542 } else if (state->list_id == MSN_LIST_BL) { 1185 } else if (state->list_id == MSN_LIST_BL) {
1543 purple_privacy_deny_add(soapconn->session->account, state->who, TRUE); 1186 purple_privacy_deny_add(soapconn->session->account, state->who, TRUE);
1544 } 1187 }
1545 1188
1546 msn_callback_state_free(state); 1189 msn_callback_state_free(state);
1547 msn_soap_free_read_buf(soapconn);
1548 return TRUE;
1549 }
1550
1551
1552 static void
1553 msn_add_contact_to_list_written_cb(MsnSoapConn *soapconn)
1554 {
1555 purple_debug_info("MSN CL","Add contact to list SOAP request sent!\n");
1556 soapconn->read_cb = msn_add_contact_to_list_read_cb;
1557 } 1190 }
1558 1191
1559 void 1192 void
1560 msn_add_contact_to_list(MsnContact *contact, MsnCallbackState *state, 1193 msn_add_contact_to_list(MsnContact *contact, MsnCallbackState *state,
1561 const gchar *passport, const MsnListId list) 1194 const gchar *passport, const MsnListId list)
1562 { 1195 {
1563 MsnSoapReq *soap_request;
1564 gchar *body = NULL, *member = NULL; 1196 gchar *body = NULL, *member = NULL;
1565 MsnSoapPartnerScenario partner_scenario; 1197 MsnSoapPartnerScenario partner_scenario;
1566 1198
1567 g_return_if_fail(contact != NULL); 1199 g_return_if_fail(contact != NULL);
1568 g_return_if_fail(passport != NULL); 1200 g_return_if_fail(passport != NULL);
1569 g_return_if_fail(list < 5); 1201 g_return_if_fail(list < 5);
1570 1202
1571 purple_debug_info("MSN CL", "Adding contact %s to %s list\n", passport, MsnMemberRole[list]); 1203 purple_debug_info("MSN CL", "Adding contact %s to %s list\n", passport, MsnMemberRole[list]);
1572 1204
1573 if (state == NULL) { 1205 if (state == NULL) {
1574 state = msn_callback_state_new(); 1206 state = msn_callback_state_new(contact->session);
1575 } 1207 }
1576 msn_callback_state_set_list_id(state, list); 1208 msn_callback_state_set_list_id(state, list);
1577 msn_callback_state_set_who(state, passport); 1209 msn_callback_state_set_who(state, passport);
1578 1210
1579 partner_scenario = (list == MSN_LIST_RL) ? MSN_PS_CONTACT_API : MSN_PS_BLOCK_UNBLOCK; 1211 partner_scenario = (list == MSN_LIST_RL) ? MSN_PS_CONTACT_API : MSN_PS_BLOCK_UNBLOCK;
1583 body = g_strdup_printf(MSN_CONTACT_ADD_TO_LIST_TEMPLATE, 1215 body = g_strdup_printf(MSN_CONTACT_ADD_TO_LIST_TEMPLATE,
1584 MsnSoapPartnerScenarioText[partner_scenario], 1216 MsnSoapPartnerScenarioText[partner_scenario],
1585 MsnMemberRole[list], 1217 MsnMemberRole[list],
1586 member); 1218 member);
1587 1219
1220 msn_soap_message_send(contact->session,
1221 msn_soap_message_new(MSN_ADD_MEMBER_TO_LIST_SOAP_ACTION,
1222 xmlnode_from_str(body, -1)),
1223 MSN_CONTACT_SERVER, MSN_SHARE_POST_URL,
1224 msn_add_contact_to_list_read_cb, state);
1225
1588 g_free(member); 1226 g_free(member);
1589
1590 soap_request = msn_soap_request_new( MSN_CONTACT_SERVER,
1591 MSN_SHARE_POST_URL,
1592 MSN_ADD_MEMBER_TO_LIST_SOAP_ACTION,
1593 body,
1594 state,
1595 msn_add_contact_to_list_read_cb,
1596 msn_add_contact_to_list_written_cb,
1597 msn_contact_connect_init);
1598
1599 msn_soap_post(contact->soapconn, soap_request);
1600
1601 g_free(body); 1227 g_free(body);
1602 } 1228 }
1603 1229
1604
1605 #if 0 1230 #if 0
1606 static gboolean 1231 static void
1607 msn_gleams_read_cb(MsnSoapConn * soapconn) 1232 msn_gleams_read_cb(MsnSoapMessage *req, MsnSoapMessage *resp, gpointer data)
1608 { 1233 {
1609 purple_debug_info("MSN CL","Gleams read done\n"); 1234 if (resp != NULL)
1610 return TRUE; 1235 purple_debug_info("MSNP14","Gleams read done\n");
1611 } 1236 else
1612 1237 purple_debug_info("MSNP14","Gleams read failed\n");
1613 static void
1614 msn_gleams_written_cb(MsnSoapConn * soapconn)
1615 {
1616 purple_debug_info("MSNP14","finish Group written\n");
1617 soapconn->read_cb = msn_gleams_read_cb;
1618 // msn_soap_read_cb(data,source,cond);
1619 } 1238 }
1620 1239
1621 /*get the gleams info*/ 1240 /*get the gleams info*/
1622 void 1241 void
1623 msn_get_gleams(MsnContact *contact) 1242 msn_get_gleams(MsnContact *contact)
1624 { 1243 {
1625 MsnSoapReq *soap_request; 1244 MsnSoapReq *soap_request;
1626 1245
1627 purple_debug_info("MSNP14","msn get gleams info...\n"); 1246 purple_debug_info("MSNP14","msn get gleams info...\n");
1628 /*build SOAP and POST it*/ 1247 msn_soap_message_send(contact->session,
1629 soap_request = msn_soap_request_new(MSN_CONTACT_SERVER, 1248 msn_soap_message_new(MSN_GET_GLEAMS_SOAP_ACTION,
1630 MSN_ADDRESS_BOOK_POST_URL, 1249 xmlnode_from_str(MSN_GLEAMS_TEMPLATE, -1)),
1631 MSN_GET_GLEAMS_SOAP_ACTION, 1250 MSN_CONTACT_SERVER, MSN_ADDRESS_BOOK_POST_URL,
1632 MSN_GLEAMS_TEMPLATE, 1251 msn_gleams_read_cb, NULL);
1633 NULL,
1634 msn_gleams_read_cb,
1635 msn_gleams_written_cb,
1636 msn_contact_connect_init);
1637 msn_soap_post(contact->soapconn,soap_request);
1638 } 1252 }
1639 #endif 1253 #endif
1640 1254
1641 1255
1642 /*************************************************************** 1256 /***************************************************************
1643 * Group Operations 1257 * Group Operations
1644 ***************************************************************/ 1258 ***************************************************************/
1645 1259
1646 static gboolean 1260 static void
1647 msn_group_read_cb(MsnSoapConn *soapconn) 1261 msn_group_read_cb(MsnSoapMessage *req, MsnSoapMessage *resp, gpointer data)
1648 { 1262 {
1649 MsnUserList *userlist; 1263 MsnCallbackState *state = data;
1650 MsnCallbackState *state = NULL; 1264
1651 1265 purple_debug_info("MSNCL", "Group request successful.\n");
1652 purple_debug_info("MSN CL", "Group request successful.\n"); 1266
1653 1267 g_return_if_fail(state->session != NULL);
1654 g_return_val_if_fail(soapconn->session != NULL, FALSE); 1268 g_return_if_fail(state->session->userlist != NULL);
1655 g_return_val_if_fail(soapconn->session->userlist != NULL, TRUE); 1269 g_return_if_fail(state->session->contact != NULL);
1656 g_return_val_if_fail(soapconn->session->contact != NULL, FALSE); 1270
1657 1271 if (resp == NULL) {
1658 state = (MsnCallbackState *) soapconn->data_cb;
1659
1660 if (soapconn->body == NULL) {
1661 msn_callback_state_free(state); 1272 msn_callback_state_free(state);
1662 return TRUE; 1273 return;
1663 } 1274 }
1664 1275
1665 if (state) { 1276 if (state) {
1666 userlist = soapconn->session->userlist; 1277 MsnSession *session = state->session;
1278 MsnUserList *userlist = session->userlist;
1667 1279
1668 if (state->action & MSN_RENAME_GROUP) { 1280 if (state->action & MSN_RENAME_GROUP) {
1669 msn_userlist_rename_group_id(soapconn->session->userlist, 1281 msn_userlist_rename_group_id(session->userlist,
1670 state->guid, 1282 state->guid,
1671 state->new_group_name); 1283 state->new_group_name);
1672 } 1284 }
1673 1285
1674 if (state->action & MSN_ADD_GROUP) { 1286 if (state->action & MSN_ADD_GROUP) {
1675 gchar *guid, *endguid; 1287 /* the response is taken from
1676 1288 http://telepathy.freedesktop.org/wiki/Pymsn/MSNP/ContactListActions
1677 guid = g_strstr_len(soapconn->read_buf, soapconn->read_len, "<guid>"); 1289 should copy it to msnpiki some day */
1678 guid += 6; 1290 xmlnode *guid_node = msn_soap_xml_get(resp->xml,
1679 endguid = g_strstr_len(soapconn->read_buf, soapconn->read_len, "</guid>"); 1291 "Body/ABGroupAddResponse/ABGroupAddResult/guid");
1680 *endguid = '\0'; 1292
1681 /* create and add the new group to the userlist */ 1293 if (guid_node) {
1682 purple_debug_info("MSN CL", "Adding group %s with guid = %s to the userlist\n", state->new_group_name, guid); 1294 char *guid = xmlnode_get_data(guid_node);
1683 msn_group_new(soapconn->session->userlist, guid, state->new_group_name); 1295
1684 1296 /* create and add the new group to the userlist */
1685 if (state->action & MSN_ADD_BUDDY) { 1297 purple_debug_info("MSNCL", "Adding group %s with guid = %s to the userlist\n", state->new_group_name, guid);
1686 msn_userlist_add_buddy(soapconn->session->userlist, 1298 msn_group_new(session->userlist, guid, state->new_group_name);
1687 state->who, 1299
1688 state->new_group_name); 1300 if (state->action & MSN_ADD_BUDDY) {
1689 msn_callback_state_free(state); 1301 msn_userlist_add_buddy(session->userlist,
1690 return TRUE; 1302 state->who,
1691 } 1303 state->new_group_name);
1692 1304 msn_callback_state_free(state);
1693 if (state->action & MSN_MOVE_BUDDY) { 1305 } else if (state->action & MSN_MOVE_BUDDY) {
1694 msn_add_contact_to_group(soapconn->session->contact, state, state->who, guid); 1306 msn_add_contact_to_group(session->contact, state, state->who, guid);
1695 return TRUE; 1307 }
1308
1309 g_free(guid);
1310 } else {
1311 purple_debug_info("MSNCL", "Adding group %s failed\n",
1312 state->new_group_name);
1696 } 1313 }
1697 } 1314 }
1698 1315
1699 if (state->action & MSN_DEL_GROUP) { 1316 if (state->action & MSN_DEL_GROUP) {
1700 GList *l; 1317 GList *l;
1701 1318
1702 msn_userlist_remove_group_id(soapconn->session->userlist, state->guid); 1319 msn_userlist_remove_group_id(session->userlist, state->guid);
1703 for (l = userlist->users; l != NULL; l = l->next) { 1320 for (l = userlist->users; l != NULL; l = l->next) {
1704 msn_user_remove_group_id( (MsnUser *)l->data, state->guid); 1321 msn_user_remove_group_id( (MsnUser *)l->data, state->guid);
1705 } 1322 }
1706
1707 } 1323 }
1708 1324
1709 msn_callback_state_free(state); 1325 msn_callback_state_free(state);
1710 } 1326 }
1711
1712 msn_soap_free_read_buf(soapconn);
1713 return TRUE;
1714 }
1715
1716 static void
1717 msn_group_written_cb(MsnSoapConn *soapconn)
1718 {
1719 purple_debug_info("MSN CL","Sent group request.\n");
1720 soapconn->read_cb = msn_group_read_cb;
1721 } 1327 }
1722 1328
1723 /* add group */ 1329 /* add group */
1724 void 1330 void
1725 msn_add_group(MsnSession *session, MsnCallbackState *state, const char* group_name) 1331 msn_add_group(MsnSession *session, MsnCallbackState *state, const char* group_name)
1726 { 1332 {
1727 MsnSoapReq *soap_request;
1728 MsnContact *contact;
1729 char *body = NULL; 1333 char *body = NULL;
1730 gchar *escaped_group_name;
1731 1334
1732 g_return_if_fail(session != NULL); 1335 g_return_if_fail(session != NULL);
1733 g_return_if_fail(group_name != NULL); 1336 g_return_if_fail(group_name != NULL);
1734 1337
1735 contact = session->contact; 1338 purple_debug_info("MSNCL","Adding group %s to contact list.\n", group_name);
1736 purple_debug_info("MSN CL","Adding group %s to contact list.\n", group_name);
1737 1339
1738 if (state == NULL) { 1340 if (state == NULL) {
1739 state = msn_callback_state_new(); 1341 state = msn_callback_state_new(session);
1740 } 1342 }
1741 1343
1742 msn_callback_state_set_action(state, MSN_ADD_GROUP); 1344 msn_callback_state_set_action(state, MSN_ADD_GROUP);
1743 msn_callback_state_set_new_group_name(state, group_name); 1345 msn_callback_state_set_new_group_name(state, group_name);
1744 1346
1745 /* escape group name's html special chars so it can safely be sent 1347 /* escape group name's html special chars so it can safely be sent
1746 * in a XML SOAP request 1348 * in a XML SOAP request
1747 */ 1349 */
1748 escaped_group_name = g_markup_escape_text(group_name, -1); 1350 body = g_markup_printf_escaped(MSN_GROUP_ADD_TEMPLATE, group_name);
1749 body = g_strdup_printf(MSN_GROUP_ADD_TEMPLATE, escaped_group_name); 1351
1750 g_free(escaped_group_name); 1352 msn_soap_message_send(session,
1751 1353 msn_soap_message_new(MSN_GROUP_ADD_SOAP_ACTION,
1752 /*build SOAP and POST it*/ 1354 xmlnode_from_str(body, -1)),
1753 soap_request = msn_soap_request_new(MSN_CONTACT_SERVER, 1355 MSN_CONTACT_SERVER, MSN_ADDRESS_BOOK_POST_URL,
1754 MSN_ADDRESS_BOOK_POST_URL, 1356 msn_group_read_cb, state);
1755 MSN_GROUP_ADD_SOAP_ACTION, 1357
1756 body,
1757 state,
1758 msn_group_read_cb,
1759 msn_group_written_cb,
1760 msn_contact_connect_init);
1761 msn_soap_post(contact->soapconn,soap_request);
1762
1763 g_free(body); 1358 g_free(body);
1764 } 1359 }
1765 1360
1766 /* delete group */ 1361 /* delete group */
1767 void 1362 void
1768 msn_del_group(MsnSession *session, const gchar *group_name) 1363 msn_del_group(MsnSession *session, const gchar *group_name)
1769 { 1364 {
1770 MsnSoapReq *soap_request;
1771 MsnContact *contact;
1772 MsnCallbackState *state; 1365 MsnCallbackState *state;
1773 char *body = NULL; 1366 char *body = NULL;
1774 const gchar *guid; 1367 const gchar *guid;
1775 1368
1776 g_return_if_fail(session != NULL); 1369 g_return_if_fail(session != NULL);
1777 1370
1778 g_return_if_fail(group_name != NULL); 1371 g_return_if_fail(group_name != NULL);
1779 contact = session->contact; 1372 purple_debug_info("MSNCL","Deleting group %s from contact list\n", group_name);
1780 purple_debug_info("MSN CL","Deleting group %s from contact list\n", group_name);
1781 1373
1782 guid = msn_userlist_find_group_id(session->userlist, group_name); 1374 guid = msn_userlist_find_group_id(session->userlist, group_name);
1783 1375
1784 /* if group uid we need to del is NULL, 1376 /* if group uid we need to del is NULL,
1785 * we need to delete nothing 1377 * we need to delete nothing
1786 */ 1378 */
1787 if (guid == NULL) { 1379 if (guid == NULL) {
1788 purple_debug_info("MSN CL", "Group %s guid not found, returning.\n", group_name); 1380 purple_debug_info("MSNCL", "Group %s guid not found, returning.\n", group_name);
1789 return; 1381 return;
1790 } 1382 }
1791 1383
1792 if ( !strcmp(guid, MSN_INDIVIDUALS_GROUP_ID) || !strcmp(guid, MSN_NON_IM_GROUP_ID) ) { 1384 if ( !strcmp(guid, MSN_INDIVIDUALS_GROUP_ID) || !strcmp(guid, MSN_NON_IM_GROUP_ID) ) {
1793 // XXX add back PurpleGroup since it isn't really removed in the server? 1385 // XXX add back PurpleGroup since it isn't really removed in the server?
1794 return; 1386 return;
1795 } 1387 }
1796 1388
1797 state = msn_callback_state_new(); 1389 state = msn_callback_state_new(session);
1798 msn_callback_state_set_action(state, MSN_DEL_GROUP); 1390 msn_callback_state_set_action(state, MSN_DEL_GROUP);
1799 msn_callback_state_set_guid(state, guid); 1391 msn_callback_state_set_guid(state, guid);
1800 1392
1801 body = g_strdup_printf(MSN_GROUP_DEL_TEMPLATE, guid); 1393 body = g_strdup_printf(MSN_GROUP_DEL_TEMPLATE, guid);
1802 /*build SOAP and POST it*/ 1394
1803 soap_request = msn_soap_request_new(MSN_CONTACT_SERVER, 1395 msn_soap_message_send(session,
1804 MSN_ADDRESS_BOOK_POST_URL, 1396 msn_soap_message_new(MSN_GROUP_DEL_SOAP_ACTION,
1805 MSN_GROUP_DEL_SOAP_ACTION, 1397 xmlnode_from_str(body, -1)),
1806 body, 1398 MSN_CONTACT_SERVER, MSN_ADDRESS_BOOK_POST_URL,
1807 state, 1399 msn_group_read_cb, state);
1808 msn_group_read_cb,
1809 msn_group_written_cb,
1810 msn_contact_connect_init);
1811 msn_soap_post(contact->soapconn, soap_request);
1812 1400
1813 g_free(body); 1401 g_free(body);
1814 } 1402 }
1815 1403
1816 /* rename group */ 1404 /* rename group */
1817 void 1405 void
1818 msn_contact_rename_group(MsnSession *session, const char *old_group_name, const char *new_group_name) 1406 msn_contact_rename_group(MsnSession *session, const char *old_group_name, const char *new_group_name)
1819 { 1407 {
1820 MsnSoapReq *soap_request; 1408 gchar *body = NULL;
1821 MsnContact *contact;
1822 gchar * escaped_group_name, *body = NULL;
1823 const gchar * guid; 1409 const gchar * guid;
1824 MsnCallbackState *state = msn_callback_state_new(); 1410 MsnCallbackState *state;
1825 1411
1826 g_return_if_fail(session != NULL); 1412 g_return_if_fail(session != NULL);
1827 g_return_if_fail(session->userlist != NULL); 1413 g_return_if_fail(session->userlist != NULL);
1828 g_return_if_fail(old_group_name != NULL); 1414 g_return_if_fail(old_group_name != NULL);
1829 g_return_if_fail(new_group_name != NULL); 1415 g_return_if_fail(new_group_name != NULL);
1830 1416
1831 contact = session->contact;
1832 purple_debug_info("MSN CL", "Renaming group %s to %s.\n", old_group_name, new_group_name); 1417 purple_debug_info("MSN CL", "Renaming group %s to %s.\n", old_group_name, new_group_name);
1833 1418
1834 guid = msn_userlist_find_group_id(session->userlist, old_group_name); 1419 guid = msn_userlist_find_group_id(session->userlist, old_group_name);
1835 if (guid == NULL) 1420 if (guid == NULL)
1836 return; 1421 return;
1837 1422
1423 state = msn_callback_state_new(session);
1838 msn_callback_state_set_guid(state, guid); 1424 msn_callback_state_set_guid(state, guid);
1839 msn_callback_state_set_new_group_name(state, new_group_name); 1425 msn_callback_state_set_new_group_name(state, new_group_name);
1840 1426
1841 if ( !strcmp(guid, MSN_INDIVIDUALS_GROUP_ID) || !strcmp(guid, MSN_NON_IM_GROUP_ID) ) { 1427 if ( !strcmp(guid, MSN_INDIVIDUALS_GROUP_ID) || !strcmp(guid, MSN_NON_IM_GROUP_ID) ) {
1842 msn_add_group(session, state, new_group_name); 1428 msn_add_group(session, state, new_group_name);
1843 // XXX move every buddy there (we probably need to fix concurrent SOAP reqs first) 1429 // XXX move every buddy there (we probably need to fix concurrent SOAP reqs first)
1844 } 1430 }
1845 1431
1846 msn_callback_state_set_action(state, MSN_RENAME_GROUP); 1432 msn_callback_state_set_action(state, MSN_RENAME_GROUP);
1847 1433
1848 /* escape group name's html special chars so it can safely be sent 1434 body = g_markup_printf_escaped(MSN_GROUP_RENAME_TEMPLATE,
1849 * in a XML SOAP request 1435 guid, new_group_name);
1850 */ 1436
1851 escaped_group_name = g_markup_escape_text(new_group_name, -1); 1437 msn_soap_message_send(session,
1852 1438 msn_soap_message_new(MSN_GROUP_RENAME_SOAP_ACTION,
1853 body = g_strdup_printf(MSN_GROUP_RENAME_TEMPLATE, guid, escaped_group_name); 1439 xmlnode_from_str(body, -1)),
1854 1440 MSN_CONTACT_SERVER, MSN_ADDRESS_BOOK_POST_URL,
1855 soap_request = msn_soap_request_new(MSN_CONTACT_SERVER, 1441 msn_group_read_cb, state);
1856 MSN_ADDRESS_BOOK_POST_URL, 1442
1857 MSN_GROUP_RENAME_SOAP_ACTION,
1858 body,
1859 state,
1860 msn_group_read_cb,
1861 msn_group_written_cb,
1862 msn_contact_connect_init);
1863 msn_soap_post(contact->soapconn, soap_request);
1864
1865 g_free(escaped_group_name);
1866 g_free(body); 1443 g_free(body);
1867 } 1444 }
1868
1869 void
1870 msn_contact_connect_init(MsnSoapConn *soapconn)
1871 {
1872 msn_soap_init(soapconn, MSN_CONTACT_SERVER, TRUE,
1873 msn_contact_login_connect_cb,
1874 msn_contact_login_error_cb);
1875 }