comparison libpurple/protocols/msn/contact.c @ 21109:e64e6fbd1351

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