comparison libpurple/protocols/msn/contact.c @ 21111:c5df2bf2bf8e

merge_into_workspace of 3380c786d272dcd9ab1360f49c3e4e51227af663
author Ka-Hing Cheung <khc@hxbc.us>
date Tue, 30 Oct 2007 06:40:14 +0000
parents c8f99cb61dc9 dead11aac1bc
children 13279824fe64
comparison
equal deleted inserted replaced
21102:f387e8c671a4 21111:c5df2bf2bf8e
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
440 purple_debug_info("MSNCL","MemberRole role: %s, list_op: %d\n", role ? role : "(null)", list_op);
441
442 g_free(role);
443
444 members = xmlnode_get_child(membershipnode, "Members");
445 for (member = xmlnode_get_child(members, "Member"); member;
446 member = xmlnode_get_next_twin(member)){
447 MsnUser *user = NULL;
448 xmlnode *typeNode, *membershipIdNode = NULL;
449 gchar *type, *membershipId = NULL;
450 const char *member_type = xmlnode_get_attrib(member, "type");
451
452 if (!member_type) {
453 purple_debug_error("msn", "No Member Type specified for Member.\n");
454 continue;
455 }
456
457 if(!g_strcasecmp(member_type, "PassportMember") ) {
458 passport = type = NULL;
459 if ((passportNode = xmlnode_get_child(member, "PassportName")))
460 passport = xmlnode_get_data(passportNode);
461 if ((typeNode = xmlnode_get_child(member, "Type")))
462 type = xmlnode_get_data(typeNode);
463 purple_debug_info("MSNCL","Passport name: '%s', Type: %s\n", passport ? passport : "(null)", type ? type : "(null)");
464 /* Why do we even bother parsing it just to free it??? */
465 g_free(type);
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 } 350 }
511 g_free(typedata); 351 g_free(typedata);
512 } 352 }
513 353 }
514 xmlnode_free(node); /* Free the whole XML tree */ 354
515 } 355 static void
516 356 msn_get_contact_list_cb(MsnSoapMessage *req, MsnSoapMessage *resp,
517 static gboolean 357 gpointer data)
518 msn_get_contact_list_cb(MsnSoapConn *soapconn) 358 {
519 { 359 GetContactListCbData *cb_data = data;
520 MsnContact *contact; 360 MsnContact *contact = cb_data->contact;
521 MsnSession *session; 361 MsnSession *session = contact->session;
522 const char *abLastChange; 362
523 const char *dynamicItemLastChange; 363 g_return_if_fail(session != NULL);
524 gchar *partner_scenario; 364
525 365 if (resp != NULL) {
526 if (soapconn->body == NULL) 366 const char *abLastChange;
527 return TRUE; 367 const char *dynamicItemLastChange;
528 368
529 purple_debug_misc("MSNCL","Got the contact list!\n"); 369 purple_debug_misc("msncl","Got the contact list!\n");
530 370
531 contact = soapconn->parent; 371 msn_parse_contact_list(cb_data->contact, resp->xml);
532 g_return_val_if_fail(contact != NULL, TRUE); 372 abLastChange = purple_account_get_string(session->account,
533 session = soapconn->session; 373 "ablastChange", NULL);
534 g_return_val_if_fail(session != NULL, FALSE); 374 dynamicItemLastChange = purple_account_get_string(session->account,
535 g_return_val_if_fail(soapconn->data_cb != NULL, TRUE); 375 "dynamicItemLastChange", NULL);
536 376
537 partner_scenario = soapconn->data_cb; 377 if (cb_data->which == MSN_PS_INITIAL) {
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 378 #ifdef MSN_PARTIAL_LISTS
549 /* XXX: this should be enabled when we can correctly do partial 379 /* XXX: this should be enabled when we can correctly do partial
550 syncs with the server. Currently we need to retrieve the whole 380 syncs with the server. Currently we need to retrieve the whole
551 list to detect sync issues */ 381 list to detect sync issues */
552 msn_get_address_book(contact, MSN_PS_INITIAL, abLastChange, dynamicItemLastChange); 382 msn_get_address_book(contact, MSN_PS_INITIAL, abLastChange, dynamicItemLastChange);
553 #else 383 #else
554 msn_get_address_book(contact, MSN_PS_INITIAL, NULL, NULL); 384 msn_get_address_book(contact, MSN_PS_INITIAL, NULL, NULL);
555 #endif 385 #endif
556 } else { 386 }
557 msn_soap_free_read_buf(soapconn); 387 }
558 } 388
559 389 g_free(cb_data);
560 return TRUE; 390 }
561 } 391
562 392 /*SOAP get contact list*/
563 static void 393 void
564 msn_get_contact_written_cb(MsnSoapConn *soapconn) 394 msn_get_contact_list(MsnContact * contact,
565 { 395 const MsnSoapPartnerScenario partner_scenario, const char *update_time)
566 purple_debug_misc("MSNCL","Sent SOAP request for the contact list.\n"); 396 {
567 soapconn->read_cb = msn_get_contact_list_cb; 397 gchar *body = NULL;
568 }
569
570 /* SOAP get contact list*/
571 void
572 msn_get_contact_list(MsnContact * contact, const MsnSoapPartnerScenario partner_scenario, const char *update_time)
573 {
574 MsnSoapReq *soap_request;
575 gchar *body;
576 gchar *update_str = NULL; 398 gchar *update_str = NULL;
399 GetContactListCbData cb_data = { contact, partner_scenario };
577 const gchar *partner_scenario_str = MsnSoapPartnerScenarioText[partner_scenario]; 400 const gchar *partner_scenario_str = MsnSoapPartnerScenarioText[partner_scenario];
578 401
579 purple_debug_misc("MSNCL","Getting Contact List.\n"); 402 purple_debug_misc("MSNCL","Getting Contact List.\n");
580 403
581 if ( update_time != NULL ) { 404 if ( update_time != NULL ) {
582 purple_debug_info("MSNCL","Last update time: %s\n",update_time); 405 purple_debug_info("MSNCL","Last update time: %s\n",update_time);
583 update_str = g_strdup_printf(MSN_GET_CONTACT_UPDATE_XML,update_time); 406 update_str = g_strdup_printf(MSN_GET_CONTACT_UPDATE_XML,update_time);
584 } 407 }
585 408
586 body = g_strdup_printf(MSN_GET_CONTACT_TEMPLATE, partner_scenario_str, update_str ? update_str : ""); 409 body = g_strdup_printf(MSN_GET_CONTACT_TEMPLATE, partner_scenario_str, update_str ? update_str : "");
410
411 msn_soap_message_send(contact->session,
412 msn_soap_message_new(MSN_GET_CONTACT_SOAP_ACTION,
413 xmlnode_from_str(body, -1)),
414 MSN_CONTACT_SERVER, MSN_GET_CONTACT_POST_URL,
415 msn_get_contact_list_cb, g_memdup(&cb_data, sizeof(cb_data)));
416
587 g_free(update_str); 417 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); 418 g_free(body);
599 } 419 }
600 420
601 static void 421 static void
602 msn_parse_addressbook_groups(MsnContact *contact, xmlnode *node) 422 msn_parse_addressbook_groups(MsnContact *contact, xmlnode *node)
603 { 423 {
604 MsnSession *session = contact->session; 424 MsnSession *session = contact->session;
605 xmlnode *group; 425 xmlnode *group;
606 426
607 purple_debug_info("MsnAb","msn_parse_addressbook_groups()\n"); 427 purple_debug_info("MSNAB","msn_parse_addressbook_groups()\n");
608 428
609 for(group = xmlnode_get_child(node, "Group"); group; 429 for(group = xmlnode_get_child(node, "Group"); group;
610 group = xmlnode_get_next_twin(group)){ 430 group = xmlnode_get_next_twin(group)){
611 xmlnode *groupId, *groupInfo, *groupname; 431 xmlnode *groupId, *groupInfo, *groupname;
612 char *group_id = NULL, *group_name = NULL; 432 char *group_id = NULL, *group_name = NULL;
754 g_free(uid); 574 g_free(uid);
755 g_free(type); 575 g_free(type);
756 } 576 }
757 577
758 static gboolean 578 static gboolean
759 msn_parse_addressbook(MsnContact * contact) 579 msn_parse_addressbook(MsnContact * contact, xmlnode *node)
760 { 580 {
761 MsnSession *session; 581 MsnSession * session;
762 xmlnode * node,*body,*response,*result; 582 xmlnode *result;
763 xmlnode *groups; 583 xmlnode *groups;
764 xmlnode *contacts; 584 xmlnode *contacts;
765 xmlnode *abNode; 585 xmlnode *abNode;
766 xmlnode *fault, *faultstringnode, *faultdetail, *errorcode; 586 xmlnode *fault;
767 587
768 session = contact->session; 588 session = contact->session;
769 589
770 node = xmlnode_from_str(contact->soapconn->body, contact->soapconn->body_len); 590 if ((fault = msn_soap_xml_get(node, "Body/Fault"))) {
771 if ( node == NULL ) { 591 xmlnode *faultnode;
772 purple_debug_error("MSN AddressBook","Error parsing Address Book with size %d\n", contact->soapconn->body_len); 592
593 if ((faultnode = xmlnode_get_child(fault, "faultstring"))) {
594 gchar *faultstring = xmlnode_get_data(faultnode);
595 purple_debug_info("MSNAB","Faultstring: %s\n", faultstring);
596 g_free(faultstring);
597 }
598
599 if ((faultnode = msn_soap_xml_get(fault, "detail/errorcode"))) {
600 gchar *errorcode = xmlnode_get_data(faultnode);
601
602 purple_debug_info("MSNAB", "Error Code: %s\n", errorcode);
603
604 if (g_str_equal(errorcode, "ABDoesNotExist")) {
605 g_free(errorcode);
606 return TRUE;
607 }
608 }
609
773 return FALSE; 610 return FALSE;
774 } 611 }
775 612
776 purple_debug_misc("MSN AddressBook", "Parsing Address Book with size %d\n", contact->soapconn->body_len); 613 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){ 614 if(result == NULL){
828 purple_debug_misc("MSNAB","receive no address book update\n"); 615 purple_debug_misc("MSNAB","receive no address book update\n");
829 xmlnode_free(node);
830 return TRUE; 616 return TRUE;
831 } 617 }
832 purple_debug_info("MSN SOAP","result{%p},name:%s\n",result,result->name); 618
833 619 /* I don't see this "groups" tag documented on msnpiki, need to find out
620 if they are really there, and update msnpiki */
834 /*Process Group List*/ 621 /*Process Group List*/
835 groups = xmlnode_get_child(result,"groups"); 622 groups = xmlnode_get_child(result,"groups");
836 if (groups != NULL) { 623 if (groups != NULL) {
837 msn_parse_addressbook_groups(contact, groups); 624 msn_parse_addressbook_groups(contact, groups);
838 } 625 }
839 626
840 /*add a default No group to set up the no group Membership*/ 627 /*add a default No group to set up the no group Membership*/
841 msn_group_new(session->userlist, MSN_INDIVIDUALS_GROUP_ID, 628 msn_group_new(session->userlist, MSN_INDIVIDUALS_GROUP_ID,
842 MSN_INDIVIDUALS_GROUP_NAME); 629 MSN_INDIVIDUALS_GROUP_NAME);
843 purple_debug_misc("MsnAB","group_id:%s name:%s\n", 630 purple_debug_misc("MSNAB","group_id:%s name:%s\n",
844 MSN_INDIVIDUALS_GROUP_ID, MSN_INDIVIDUALS_GROUP_NAME); 631 MSN_INDIVIDUALS_GROUP_ID, MSN_INDIVIDUALS_GROUP_NAME);
845 if ((purple_find_group(MSN_INDIVIDUALS_GROUP_NAME)) == NULL){ 632 if ((purple_find_group(MSN_INDIVIDUALS_GROUP_NAME)) == NULL){
846 PurpleGroup *g = purple_group_new(MSN_INDIVIDUALS_GROUP_NAME); 633 PurpleGroup *g = purple_group_new(MSN_INDIVIDUALS_GROUP_NAME);
847 purple_blist_add_group(g, NULL); 634 purple_blist_add_group(g, NULL);
848 } 635 }
849 636
850 /*add a default No group to set up the no group Membership*/ 637 /*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); 638 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); 639 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){ 640 if ((purple_find_group(MSN_NON_IM_GROUP_NAME)) == NULL){
854 PurpleGroup *g = purple_group_new(MSN_NON_IM_GROUP_NAME); 641 PurpleGroup *g = purple_group_new(MSN_NON_IM_GROUP_NAME);
855 purple_blist_add_group(g, NULL); 642 purple_blist_add_group(g, NULL);
856 } 643 }
857 644
867 xmlnode *node2; 654 xmlnode *node2;
868 char *tmp = NULL; 655 char *tmp = NULL;
869 656
870 if ((node2 = xmlnode_get_child(abNode, "lastChange"))) 657 if ((node2 = xmlnode_get_child(abNode, "lastChange")))
871 tmp = xmlnode_get_data(node2); 658 tmp = xmlnode_get_data(node2);
872 purple_debug_info("MsnAB"," lastchanged Time:{%s}\n", tmp ? tmp : "(null)"); 659 purple_debug_info("MSNAB"," lastchanged Time:{%s}\n", tmp ? tmp : "(null)");
873 purple_account_set_string(session->account, "ablastChange", tmp); 660 purple_account_set_string(session->account, "ablastChange", tmp);
874 661
875 g_free(tmp); tmp = NULL; 662 g_free(tmp); tmp = NULL;
876 if ((node2 = xmlnode_get_child(abNode, "DynamicItemLastChanged"))) 663 if ((node2 = xmlnode_get_child(abNode, "DynamicItemLastChanged")))
877 tmp = xmlnode_get_data(node2); 664 tmp = xmlnode_get_data(node2);
878 purple_debug_info("MsnAB"," DynamicItemLastChanged :{%s}\n", tmp ? tmp : "(null)"); 665 purple_debug_info("MsnAB"," DynamicItemLastChanged :{%s}\n", tmp ? tmp : "(null)");
879 purple_account_set_string(session->account, "DynamicItemLastChanged", tmp); 666 purple_account_set_string(session->account, "DynamicItemLastChanged", tmp);
880 g_free(tmp); 667 g_free(tmp);
881 } 668 }
882 669
883 xmlnode_free(node);
884 msn_soap_free_read_buf(contact->soapconn);
885 return TRUE; 670 return TRUE;
886 } 671 }
887 672
888 static gboolean 673 static void
889 msn_get_address_cb(MsnSoapConn *soapconn) 674 msn_get_address_cb(MsnSoapMessage *req, MsnSoapMessage *resp, gpointer data)
890 { 675 {
891 MsnContact *contact; 676 MsnContact *contact = data;
892 MsnSession *session; 677 MsnSession *session;
893 678
894 if (soapconn->body == NULL) 679 if (resp == NULL)
895 return TRUE; 680 return;
896 681
897 contact = soapconn->parent; 682 g_return_if_fail(contact != NULL);
898 g_return_val_if_fail(contact != NULL, TRUE); 683 session = contact->session;
899 session = soapconn->session; 684 g_return_if_fail(session != NULL);
900 g_return_val_if_fail(session != NULL, FALSE); 685
901 686 purple_debug_misc("MSNAB", "Got the Address Book!\n");
902 purple_debug_misc("MSN AddressBook", "Got the Address Book!\n"); 687
903 688 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) { 689 if (!session->logged_in) {
908 msn_send_privacy(session->account->gc); 690 msn_send_privacy(session->account->gc);
909 msn_notification_dump_contact(session); 691 msn_notification_dump_contact(session);
910 } 692 }
911
912 /*free the read buffer*/
913 msn_soap_free_read_buf(soapconn);
914 return TRUE;
915 } else { 693 } else {
916 /* This is making us loop infinitely when we fail to parse the address book, 694 /* This is making us loop infinitely when we fail to parse the
917 disable for now (we should re-enable when we send timestamps) 695 address book, disable for now (we should re-enable when we
696 send timestamps)
918 */ 697 */
919 /* 698 /*
920 msn_get_address_book(contact, NULL, NULL); 699 msn_get_address_book(contact, NULL, NULL);
921 */ 700 */
922 msn_session_disconnect(session); 701 msn_session_disconnect(session);
923 purple_connection_error(session->account->gc, _("Unable to retrieve MSN Address Book")); 702 purple_connection_error(session->account->gc, _("Unable to retrieve MSN Address Book"));
924 return FALSE; 703 }
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 } 704 }
935 705
936 /*get the address book*/ 706 /*get the address book*/
937 void 707 void
938 msn_get_address_book(MsnContact *contact, const MsnSoapPartnerScenario partner_scenario, const char *LastChanged, const char *dynamicItemLastChange) 708 msn_get_address_book(MsnContact *contact,
939 { 709 MsnSoapPartnerScenario partner_scenario, const char *LastChanged,
940 MsnSoapReq *soap_request; 710 const char *dynamicItemLastChange)
941 char *body; 711 {
942 char *update_str = NULL; 712 char *body, *update_str = NULL;
943 713
944 purple_debug_misc("MSN AddressBook","Getting Address Book\n"); 714 purple_debug_misc("MSNAB","Getting Address Book\n");
945 715
946 /*build SOAP and POST it*/ 716 /*build SOAP and POST it*/
947 if (dynamicItemLastChange != NULL) 717 if (dynamicItemLastChange != NULL)
948 update_str = g_strdup_printf(MSN_GET_ADDRESS_UPDATE_XML, dynamicItemLastChange); 718 update_str = g_strdup_printf(MSN_GET_ADDRESS_UPDATE_XML, dynamicItemLastChange);
949 else if (LastChanged != NULL) 719 else if (LastChanged != NULL)
950 update_str = g_strdup_printf(MSN_GET_ADDRESS_UPDATE_XML, LastChanged); 720 update_str = g_strdup_printf(MSN_GET_ADDRESS_UPDATE_XML, LastChanged);
951 721
952
953 body = g_strdup_printf(MSN_GET_ADDRESS_TEMPLATE, MsnSoapPartnerScenarioText[partner_scenario], update_str ? update_str : ""); 722 body = g_strdup_printf(MSN_GET_ADDRESS_TEMPLATE, MsnSoapPartnerScenarioText[partner_scenario], update_str ? update_str : "");
723
724 msn_soap_message_send(contact->session,
725 msn_soap_message_new(MSN_GET_ADDRESS_SOAP_ACTION,
726 xmlnode_from_str(body, -1)),
727 MSN_CONTACT_SERVER, MSN_ADDRESS_BOOK_POST_URL, msn_get_address_cb,
728 contact);
729
954 g_free(update_str); 730 g_free(update_str);
955
956 soap_request = msn_soap_request_new(MSN_CONTACT_SERVER,
957 MSN_ADDRESS_BOOK_POST_URL,MSN_GET_ADDRESS_SOAP_ACTION,
958 body,
959 NULL,
960 msn_get_address_cb,
961 msn_address_written_cb,
962 msn_contact_connect_init);
963 msn_soap_post(contact->soapconn,soap_request);
964 g_free(body); 731 g_free(body);
965 } 732 }
966 733
967 static gboolean 734 static void
968 msn_add_contact_read_cb(MsnSoapConn *soapconn) 735 msn_add_contact_read_cb(MsnSoapMessage *req, MsnSoapMessage *resp,
969 { 736 gpointer data)
970 MsnCallbackState *state = NULL; 737 {
971 MsnUserList *userlist; 738 MsnCallbackState *state = data;
972 MsnUser *user; 739 MsnSession *session = state->session;
973 740
974 g_return_val_if_fail(soapconn->data_cb != NULL, TRUE); 741 g_return_if_fail(session != NULL);
975 g_return_val_if_fail(soapconn->session != NULL, FALSE); 742
976 g_return_val_if_fail(soapconn->session->userlist != NULL, TRUE); 743 if (resp != NULL) {
977 744 MsnUserList *userlist = session->userlist;
978 state = (MsnCallbackState *) soapconn->data_cb; 745 MsnUser *user;
979 746
980 if (soapconn->body == NULL) { 747 purple_debug_info("MSNCL","Contact added successfully\n");
981 msn_callback_state_free(state); 748
982 return TRUE; 749 // the code this block is replacing didn't send ADL for yahoo contacts,
983 } 750 // but i haven't confirmed this is WLM's behaviour wrt yahoo contacts
984 751 if ( !msn_user_is_yahoo(session->account, state->who) ) {
985 userlist = soapconn->session->userlist; 752 msn_userlist_add_buddy_to_list(userlist, state->who, MSN_LIST_AL);
986 753 msn_userlist_add_buddy_to_list(userlist, state->who, MSN_LIST_FL);
987 purple_debug_info("MSNCL","Contact added successfully\n"); 754 }
988 755
989 // the code this block is replacing didn't send ADL for yahoo contacts, 756 msn_notification_send_fqy(session, state->who);
990 // but i haven't confirmed this is WLM's behaviour wrt yahoo contacts 757
991 758 user = msn_userlist_find_add_user(userlist, state->who, state->who);
992 if ( !msn_user_is_yahoo(soapconn->session->account, state->who) ) { 759 msn_user_add_group_id(user, state->guid);
993 760 }
994 msn_userlist_add_buddy_to_list(userlist, state->who, MSN_LIST_AL); 761
995 msn_userlist_add_buddy_to_list(userlist, state->who, MSN_LIST_FL);
996 }
997 msn_notification_send_fqy(soapconn->session, state->who);
998
999 user = msn_userlist_find_add_user(userlist, state->who, state->who);
1000 msn_user_add_group_id(user, state->guid);
1001
1002 msn_soap_free_read_buf(soapconn);
1003 msn_callback_state_free(state); 762 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 } 763 }
1014 764
1015 /* add a Contact in MSN_INDIVIDUALS_GROUP */ 765 /* add a Contact in MSN_INDIVIDUALS_GROUP */
1016 void 766 void
1017 msn_add_contact(MsnContact *contact, MsnCallbackState *state, const char *passport) 767 msn_add_contact(MsnContact *contact, MsnCallbackState *state, const char *passport)
1018 { 768 {
1019 MsnSoapReq *soap_request;
1020 gchar *body = NULL; 769 gchar *body = NULL;
1021 gchar *contact_xml = NULL; 770 gchar *contact_xml = NULL;
1022 771
1023 g_return_if_fail(passport != NULL); 772 #if 0
1024 /* gchar *escaped_displayname; 773 gchar *escaped_displayname;
1025 774
1026 775
1027 if (displayname != NULL) { 776 if (displayname != NULL) {
1028 escaped_displayname = g_markup_decode_text(displayname, -1); 777 escaped_displayname = g_markup_decode_text(displayname, -1);
1029 } else { 778 } else {
1030 escaped_displayname = passport; 779 escaped_displayname = passport;
1031 } 780 }
1032 contact_xml = g_strdup_printf(MSN_XML_ADD_CONTACT, escaped_displayname, passport); 781 contact_xml = g_strdup_printf(MSN_XML_ADD_CONTACT, escaped_displayname, passport);
1033 */ 782 #endif
783
1034 purple_debug_info("MSNCL","Adding contact %s to contact list\n", passport); 784 purple_debug_info("MSNCL","Adding contact %s to contact list\n", passport);
1035 785
1036 // if ( !strcmp(state->guid, MSN_INDIVIDUALS_GROUP_ID) ) { 786 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); 787 body = g_strdup_printf(MSN_ADD_CONTACT_TEMPLATE, contact_xml);
1040 788
789 msn_soap_message_send(contact->session,
790 msn_soap_message_new(MSN_CONTACT_ADD_SOAP_ACTION,
791 xmlnode_from_str(body, -1)),
792 MSN_CONTACT_SERVER, MSN_ADDRESS_BOOK_POST_URL,
793 msn_add_contact_read_cb, state);
794
1041 g_free(contact_xml); 795 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); 796 g_free(body);
1056 } 797 }
1057 798
1058 static gboolean 799 static void
1059 msn_add_contact_to_group_read_cb(MsnSoapConn *soapconn) 800 msn_add_contact_to_group_read_cb(MsnSoapMessage *req, MsnSoapMessage *resp,
1060 { 801 gpointer data)
1061 MsnCallbackState *state; 802 {
803 MsnCallbackState *state = data;
1062 MsnUserList *userlist; 804 MsnUserList *userlist;
1063 805
1064 g_return_val_if_fail(soapconn->data_cb != NULL, TRUE); 806 g_return_if_fail(data != NULL);
1065 g_return_val_if_fail(soapconn->session != NULL, FALSE); 807
1066 g_return_val_if_fail(soapconn->session->userlist != NULL, TRUE); 808 userlist = state->session->userlist;
1067 809
1068 userlist = soapconn->session->userlist; 810 if (resp != NULL) {
1069 811 if (msn_userlist_add_buddy_to_group(userlist, state->who,
1070 state = (MsnCallbackState *) soapconn->data_cb; 812 state->new_group_name)) {
1071 813 purple_debug_info("MSNCL", "Contact %s added to group %s successfully!\n", state->who, state->new_group_name);
1072 if (soapconn->body == NULL) { 814 } else {
1073 msn_callback_state_free(state); 815 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; 816 }
1075 } 817
1076 818 if (state->action & MSN_ADD_BUDDY) {
1077 if (msn_userlist_add_buddy_to_group(userlist, state->who, state->new_group_name) == TRUE) { 819 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); 820
1079 } else { 821 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); 822
1081 } 823 msn_userlist_add_buddy_to_list(userlist, state->who, MSN_LIST_AL);
1082 824 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 } 825 }
1090 msn_notification_send_fqy(soapconn->session, state->who); 826 msn_notification_send_fqy(state->session, state->who);
1091 } 827
1092 828 if (msn_userlist_user_is_in_list(user, MSN_LIST_PL)) {
1093 if (state->action & MSN_MOVE_BUDDY) { 829 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); 830 msn_callback_state_free(state);
1095 } else { 831 return;
1096 msn_callback_state_free(state); 832 }
1097 msn_soap_free_read_buf(soapconn); 833 }
1098 } 834
1099 return TRUE; 835 if (state->action & MSN_MOVE_BUDDY) {
1100 } 836 msn_del_contact_from_group(state->session->contact, state->who, state->old_group_name);
1101 837 }
1102 static void 838 }
1103 msn_add_contact_to_group_written_cb(MsnSoapConn *soapconn) 839
1104 { 840 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 } 841 }
1108 842
1109 void 843 void
1110 msn_add_contact_to_group(MsnContact *contact, MsnCallbackState *state, 844 msn_add_contact_to_group(MsnContact *contact, MsnCallbackState *state,
1111 const char *passport, const char *groupId) 845 const char *passport, const char *groupId)
1112 { 846 {
1113 MsnSoapReq *soap_request;
1114 MsnUserList *userlist; 847 MsnUserList *userlist;
1115 MsnUser *user; 848 MsnUser *user;
1116 gchar *body = NULL, *contact_xml; 849 gchar *body = NULL, *contact_xml;
1117 850
1118 g_return_if_fail(passport != NULL); 851 g_return_if_fail(passport != NULL);
1141 } 874 }
1142 875
1143 return; 876 return;
1144 } 877 }
1145 878
1146
1147 purple_debug_info("MSNCL", "Adding user %s to group %s\n", passport, 879 purple_debug_info("MSNCL", "Adding user %s to group %s\n", passport,
1148 msn_userlist_find_group_name(userlist, groupId)); 880 msn_userlist_find_group_name(userlist, groupId));
1149 881
1150 user = msn_userlist_find_user(userlist, passport); 882 user = msn_userlist_find_user(userlist, passport);
1151 if (user == NULL) { 883 if (user == NULL) {
1152 purple_debug_warning("MSN CL", "Unable to retrieve user %s from the userlist!\n", passport); 884 purple_debug_warning("MSNCL", "Unable to retrieve user %s from the userlist!\n", passport);
885 msn_callback_state_free(state);
886 return; /* guess this never happened! */
1153 } 887 }
1154 888
1155 if (user != NULL && user->uid != NULL) { 889 if (user != NULL && user->uid != NULL) {
1156 contact_xml = g_strdup_printf(MSN_CONTACT_ID_XML, user->uid); 890 contact_xml = g_strdup_printf(MSN_CONTACT_ID_XML, user->uid);
1157 } else { 891 } else {
1158 contact_xml = g_strdup_printf(MSN_CONTACT_XML, passport); 892 contact_xml = g_strdup_printf(MSN_CONTACT_XML, passport);
1159 } 893 }
1160 894
1161 body = g_strdup_printf(MSN_ADD_CONTACT_GROUP_TEMPLATE, groupId, contact_xml); 895 body = g_strdup_printf(MSN_ADD_CONTACT_GROUP_TEMPLATE, groupId, contact_xml);
896
897 msn_soap_message_send(state->session,
898 msn_soap_message_new(MSN_ADD_CONTACT_GROUP_SOAP_ACTION,
899 xmlnode_from_str(body, -1)),
900 MSN_CONTACT_SERVER, MSN_ADDRESS_BOOK_POST_URL,
901 msn_add_contact_to_group_read_cb, state);
902
1162 g_free(contact_xml); 903 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); 904 g_free(body);
1177 } 905 }
1178 906
1179 907 static void
1180 908 msn_delete_contact_read_cb(MsnSoapMessage *req, MsnSoapMessage *resp,
1181 static gboolean 909 gpointer data)
1182 msn_delete_contact_read_cb(MsnSoapConn *soapconn) 910 {
1183 { 911 MsnCallbackState *state = data;
1184 MsnUser *user; 912
1185 MsnCallbackState *state = (MsnCallbackState *) soapconn->data_cb; 913 if (resp != NULL) {
1186 MsnUserList *userlist; 914 MsnUserList *userlist = state->session->userlist;
1187 915 MsnUser *user = msn_userlist_find_user_with_id(userlist, state->uid);
1188 g_return_val_if_fail(soapconn->session != NULL, FALSE); 916
1189 g_return_val_if_fail(soapconn->session->userlist != NULL, TRUE); 917 purple_debug_info("MSNCL","Delete contact successful\n");
1190 918
1191 userlist = soapconn->session->userlist; 919 if (user != NULL) {
1192 920 msn_userlist_remove_user(userlist, user);
1193 if (soapconn->body == NULL) { 921 }
1194 msn_callback_state_free(state);
1195 return TRUE;
1196 }
1197
1198 purple_debug_info("MSNCL","Delete contact successful\n");
1199
1200 user = msn_userlist_find_user_with_id(userlist, state->uid);
1201 if (user != NULL) {
1202 msn_userlist_remove_user(userlist, user);
1203 } 922 }
1204 923
1205 msn_callback_state_free(state); 924 msn_callback_state_free(state);
1206 msn_soap_free_read_buf(soapconn);
1207
1208 return TRUE;
1209 }
1210
1211 static void
1212 msn_delete_contact_written_cb(MsnSoapConn *soapconn)
1213 {
1214 purple_debug_info("MSNCL","Delete contact request written\n");
1215 soapconn->read_cb = msn_delete_contact_read_cb;
1216 } 925 }
1217 926
1218 /*delete a Contact*/ 927 /*delete a Contact*/
1219 void 928 void
1220 msn_delete_contact(MsnContact *contact, const char *contactId) 929 msn_delete_contact(MsnContact *contact, const char *contactId)
1221 { 930 {
1222 gchar *body = NULL; 931 gchar *body = NULL;
1223 gchar *contact_id_xml = NULL ; 932 gchar *contact_id_xml = NULL ;
1224 MsnSoapReq *soap_request;
1225 MsnCallbackState *state; 933 MsnCallbackState *state;
1226 934
1227 g_return_if_fail(contactId != NULL); 935 g_return_if_fail(contactId != NULL);
1228 contact_id_xml = g_strdup_printf(MSN_CONTACT_ID_XML, contactId); 936 contact_id_xml = g_strdup_printf(MSN_CONTACT_ID_XML, contactId);
1229 937
1230 state = msn_callback_state_new(); 938 state = msn_callback_state_new(contact->session);
1231 msn_callback_state_set_uid(state, contactId); 939 msn_callback_state_set_uid(state, contactId);
1232 940
1233 /* build SOAP request */ 941 /* build SOAP request */
1234 purple_debug_info("MSNCL","Deleting contact with contactId: %s\n", contactId); 942 purple_debug_info("MSNCL","Deleting contact with contactId: %s\n", contactId);
1235 body = g_strdup_printf(MSN_DEL_CONTACT_TEMPLATE, contact_id_xml); 943 body = g_strdup_printf(MSN_DEL_CONTACT_TEMPLATE, contact_id_xml);
1236 soap_request = msn_soap_request_new(MSN_CONTACT_SERVER, 944 msn_soap_message_send(contact->session,
1237 MSN_ADDRESS_BOOK_POST_URL, 945 msn_soap_message_new(MSN_CONTACT_DEL_SOAP_ACTION,
1238 MSN_CONTACT_DEL_SOAP_ACTION, 946 xmlnode_from_str(body, -1)),
1239 body, 947 MSN_CONTACT_SERVER, MSN_ADDRESS_BOOK_POST_URL,
1240 state, 948 msn_delete_contact_read_cb, state);
1241 msn_delete_contact_read_cb,
1242 msn_delete_contact_written_cb,
1243 msn_contact_connect_init);
1244 949
1245 g_free(contact_id_xml); 950 g_free(contact_id_xml);
1246
1247 /* POST the SOAP request */
1248 msn_soap_post(contact->soapconn, soap_request);
1249
1250 g_free(body); 951 g_free(body);
1251 } 952 }
1252 953
1253 static gboolean 954 static void
1254 msn_del_contact_from_group_read_cb(MsnSoapConn *soapconn) 955 msn_del_contact_from_group_read_cb(MsnSoapMessage *req, MsnSoapMessage *resp,
1255 { 956 gpointer data)
1256 MsnCallbackState *state = (MsnCallbackState *) soapconn->data_cb; 957 {
1257 958 MsnCallbackState *state = data;
1258 if (soapconn->body == NULL) { 959
1259 msn_callback_state_free(state); 960 if (resp != NULL) {
1260 return TRUE; 961 if (msn_userlist_rem_buddy_from_group(state->session->userlist,
1261 } 962 state->who, state->old_group_name)) {
1262 963 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)) { 964 } else {
1264 purple_debug_info("MSN CL", "Contact %s deleted successfully from group %s\n", state->who, state->old_group_name); 965 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 { 966 }
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 } 967 }
1268 968
1269 msn_callback_state_free(state); 969 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 } 970 }
1281 971
1282 void 972 void
1283 msn_del_contact_from_group(MsnContact *contact, const char *passport, const char *group_name) 973 msn_del_contact_from_group(MsnContact *contact, const char *passport, const char *group_name)
1284 { 974 {
1285 MsnSoapReq *soap_request;
1286 MsnUserList * userlist; 975 MsnUserList * userlist;
1287 MsnUser *user; 976 MsnUser *user;
1288 MsnCallbackState *state; 977 MsnCallbackState *state;
1289 gchar *body = NULL, *contact_id_xml; 978 gchar *body, *contact_id_xml;
1290 const gchar *groupId; 979 const gchar *groupId;
1291 980
1292 g_return_if_fail(passport != NULL); 981 g_return_if_fail(passport != NULL);
1293 g_return_if_fail(group_name != NULL); 982 g_return_if_fail(group_name != NULL);
1294 g_return_if_fail(contact != NULL); 983 g_return_if_fail(contact != NULL);
1297 986
1298 userlist = contact->session->userlist; 987 userlist = contact->session->userlist;
1299 988
1300 groupId = msn_userlist_find_group_id(userlist, group_name); 989 groupId = msn_userlist_find_group_id(userlist, group_name);
1301 if (groupId != NULL) { 990 if (groupId != NULL) {
1302 purple_debug_info("MSN CL", "Deleting user %s from group %s\n", passport, group_name); 991 purple_debug_info("MSNCL", "Deleting user %s from group %s\n", passport, group_name);
1303 } else { 992 } else {
1304 purple_debug_warning("MSN CL", "Unable to retrieve group id from group %s !\n", group_name); 993 purple_debug_warning("MSNCL", "Unable to retrieve group id from group %s !\n", group_name);
1305 return; 994 return;
1306 } 995 }
1307 996
1308 user = msn_userlist_find_user(userlist, passport); 997 user = msn_userlist_find_user(userlist, passport);
1309 998
1310 if (user == NULL) { 999 if (user == NULL) {
1311 purple_debug_warning("MSN CL", "Unable to retrieve user from passport %s!\n", passport); 1000 purple_debug_warning("MSNCL", "Unable to retrieve user from passport %s!\n", passport);
1312 return; 1001 return;
1313 } 1002 }
1314 1003
1315 if ( !strcmp(groupId, MSN_INDIVIDUALS_GROUP_ID) || !strcmp(groupId, MSN_NON_IM_GROUP_ID)) { 1004 if ( !strcmp(groupId, MSN_INDIVIDUALS_GROUP_ID) || !strcmp(groupId, MSN_NON_IM_GROUP_ID)) {
1316 msn_user_remove_group_id(user, groupId); 1005 msn_user_remove_group_id(user, groupId);
1317 return; 1006 return;
1318 } 1007 }
1319 1008
1320 state = msn_callback_state_new(); 1009 state = msn_callback_state_new(contact->session);
1321 msn_callback_state_set_who(state, passport); 1010 msn_callback_state_set_who(state, passport);
1322 msn_callback_state_set_guid(state, groupId); 1011 msn_callback_state_set_guid(state, groupId);
1323 msn_callback_state_set_old_group_name(state, group_name); 1012 msn_callback_state_set_old_group_name(state, group_name);
1324 1013
1325 contact_id_xml = g_strdup_printf(MSN_CONTACT_ID_XML, user->uid); 1014 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); 1015 body = g_strdup_printf(MSN_CONTACT_DEL_GROUP_TEMPLATE, contact_id_xml, groupId);
1016
1017 msn_soap_message_send(contact->session,
1018 msn_soap_message_new(MSN_CONTACT_DEL_GROUP_SOAP_ACTION,
1019 xmlnode_from_str(body, -1)),
1020 MSN_CONTACT_SERVER, MSN_ADDRESS_BOOK_POST_URL,
1021 msn_del_contact_from_group_read_cb, state);
1022
1327 g_free(contact_id_xml); 1023 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); 1024 g_free(body);
1341 } 1025 }
1342 1026
1343 1027
1344 static gboolean 1028 static void
1345 msn_update_contact_read_cb(MsnSoapConn *soapconn) 1029 msn_update_contact_read_cb(MsnSoapMessage *req, MsnSoapMessage *resp,
1346 { 1030 gpointer data)
1347 if (soapconn->body == NULL) 1031 {
1348 return TRUE; 1032 if (resp)
1349 1033 purple_debug_info("MSN CL","Contact updated successfully\n");
1350 purple_debug_info("MSN CL","Contact updated successfully\n"); 1034 else
1351 1035 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 } 1036 }
1361 1037
1362 /* Update a contact's nickname */ 1038 /* Update a contact's nickname */
1363
1364 void 1039 void
1365 msn_update_contact(MsnContact *contact, const char* nickname) 1040 msn_update_contact(MsnContact *contact, const char* nickname)
1366 { 1041 {
1367 MsnSoapReq *soap_request; 1042 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 1043
1373 purple_debug_info("MSN CL","Update contact information with new friendly name: %s\n", nickname); 1044 purple_debug_info("MSN CL","Update contact information with new friendly name: %s\n", nickname);
1374 1045
1375 escaped_nickname = g_markup_escape_text(nickname, -1); 1046 escaped_nickname = g_markup_escape_text(nickname, -1);
1376 1047
1377 body = g_strdup_printf(MSN_CONTACT_UPDATE_TEMPLATE, escaped_nickname); 1048 body = g_strdup_printf(MSN_CONTACT_UPDATE_TEMPLATE, escaped_nickname);
1378 1049
1050 msn_soap_message_send(contact->session,
1051 msn_soap_message_new(MSN_CONTACT_UPDATE_SOAP_ACTION,
1052 xmlnode_from_str(body, -1)),
1053 MSN_CONTACT_SERVER, MSN_ADDRESS_BOOK_POST_URL,
1054 msn_update_contact_read_cb, NULL);
1055
1379 g_free(escaped_nickname); 1056 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); 1057 g_free(body);
1392 } 1058 }
1393 1059
1394 1060 static void
1395 static gboolean 1061 msn_del_contact_from_list_read_cb(MsnSoapMessage *req, MsnSoapMessage *resp,
1396 msn_del_contact_from_list_read_cb(MsnSoapConn *soapconn) 1062 gpointer data)
1397 { 1063 {
1398 MsnCallbackState *state = NULL; 1064 MsnCallbackState *state = data;
1399 1065 MsnSession *session = state->session;
1400 g_return_val_if_fail(soapconn->data_cb != NULL, TRUE); 1066
1401 g_return_val_if_fail(soapconn->session != NULL, FALSE); 1067 if (resp != NULL) {
1402 g_return_val_if_fail(soapconn->session->contact != NULL, FALSE); 1068 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); 1069
1404 1070 if (state->list_id == MSN_LIST_PL) {
1405 state = (MsnCallbackState *) soapconn->data_cb; 1071 MsnUser *user = msn_userlist_find_user(session->userlist, state->who);
1406 1072
1407 if (soapconn->body == NULL) { 1073 if (user != NULL)
1408 msn_callback_state_free(state); 1074 msn_user_unset_op(user, MSN_LIST_PL_OP);
1409 return TRUE; 1075
1410 } 1076 msn_add_contact_to_list(session->contact, state, state->who, MSN_LIST_RL);
1411 1077 } else if (state->list_id == 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]); 1078 purple_privacy_permit_remove(session->account, state->who, TRUE);
1413 1079 msn_add_contact_to_list(session->contact, NULL, state->who, MSN_LIST_BL);
1414 if (state->list_id == MSN_LIST_PL) { 1080 } else if (state->list_id == MSN_LIST_BL) {
1415 MsnUser *user = msn_userlist_find_user(soapconn->session->userlist, state->who); 1081 purple_privacy_deny_remove(session->account, state->who, TRUE);
1416 1082 msn_add_contact_to_list(session->contact, NULL, state->who, MSN_LIST_AL);
1417 if (user != NULL) 1083 }
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 } 1084 }
1437 1085
1438 msn_callback_state_free(state); 1086 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 } 1087 }
1450 1088
1451 void 1089 void
1452 msn_del_contact_from_list(MsnContact *contact, MsnCallbackState *state, 1090 msn_del_contact_from_list(MsnContact *contact, MsnCallbackState *state,
1453 const gchar *passport, const MsnListId list) 1091 const gchar *passport, const MsnListId list)
1454 { 1092 {
1455 MsnSoapReq *soap_request;
1456 gchar *body = NULL, *member = NULL; 1093 gchar *body = NULL, *member = NULL;
1457 MsnSoapPartnerScenario partner_scenario; 1094 MsnSoapPartnerScenario partner_scenario;
1458 MsnUser *user; 1095 MsnUser *user;
1459 1096
1460 g_return_if_fail(contact != NULL); 1097 g_return_if_fail(contact != NULL);
1462 g_return_if_fail(list < 5); 1099 g_return_if_fail(list < 5);
1463 1100
1464 purple_debug_info("MSN CL", "Deleting contact %s from %s list\n", passport, MsnMemberRole[list]); 1101 purple_debug_info("MSN CL", "Deleting contact %s from %s list\n", passport, MsnMemberRole[list]);
1465 1102
1466 if (state == NULL) { 1103 if (state == NULL) {
1467 state = msn_callback_state_new(); 1104 state = msn_callback_state_new(contact->session);
1468 } 1105 }
1469 msn_callback_state_set_list_id(state, list); 1106 msn_callback_state_set_list_id(state, list);
1470 msn_callback_state_set_who(state, passport); 1107 msn_callback_state_set_who(state, passport);
1471 1108
1472 if (list == MSN_LIST_PL) { 1109 if (list == MSN_LIST_PL) {
1486 1123
1487 body = g_strdup_printf( MSN_CONTACT_DELECT_FROM_LIST_TEMPLATE, 1124 body = g_strdup_printf( MSN_CONTACT_DELECT_FROM_LIST_TEMPLATE,
1488 MsnSoapPartnerScenarioText[partner_scenario], 1125 MsnSoapPartnerScenarioText[partner_scenario],
1489 MsnMemberRole[list], 1126 MsnMemberRole[list],
1490 member); 1127 member);
1128
1129 msn_soap_message_send(contact->session,
1130 msn_soap_message_new(MSN_DELETE_MEMBER_FROM_LIST_SOAP_ACTION,
1131 xmlnode_from_str(body, -1)),
1132 MSN_CONTACT_SERVER, MSN_SHARE_POST_URL,
1133 msn_del_contact_from_list_read_cb, state);
1134
1491 g_free(member); 1135 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); 1136 g_free(body);
1505 } 1137 }
1506 1138
1507 static gboolean 1139 static void
1508 msn_add_contact_to_list_read_cb(MsnSoapConn *soapconn) 1140 msn_add_contact_to_list_read_cb(MsnSoapMessage *req, MsnSoapMessage *resp,
1509 { 1141 gpointer data)
1510 MsnCallbackState *state = NULL; 1142 {
1511 1143 MsnCallbackState *state = data;
1512 g_return_val_if_fail(soapconn->data_cb != NULL, TRUE); 1144
1513 g_return_val_if_fail(soapconn->session != NULL, FALSE); 1145 g_return_if_fail(state != NULL);
1514 g_return_val_if_fail(soapconn->session->userlist != NULL, FALSE); 1146 g_return_if_fail(state->session != NULL);
1515 1147 g_return_if_fail(state->session->contact != NULL);
1516 state = (MsnCallbackState *) soapconn->data_cb; 1148
1517 1149 if (resp != NULL) {
1518 if (soapconn->body == NULL) { 1150 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); 1151
1520 return TRUE; 1152 if (state->list_id == MSN_LIST_RL) {
1521 } 1153 MsnUser *user = msn_userlist_find_user(state->session->userlist, state->who);
1522
1523 purple_debug_info("MSN CL", "Contact %s added successfully to %s list on server!\n", state->who, MsnMemberRole[state->list_id]);
1524
1525 if (state->list_id == MSN_LIST_RL) {
1526 MsnUser *user = msn_userlist_find_user(soapconn->session->userlist, state->who);
1527 1154
1528 if (user != NULL) { 1155 if (user != NULL) {
1529 msn_user_set_op(user, MSN_LIST_RL_OP); 1156 msn_user_set_op(user, MSN_LIST_RL_OP);
1530 } 1157 }
1531 1158
1532 if (state->action & MSN_DENIED_BUDDY) { 1159 if (state->action & MSN_DENIED_BUDDY) {
1533 g_return_val_if_fail(soapconn->session->contact != NULL, FALSE); 1160
1534 1161 msn_add_contact_to_list(state->session->contact, NULL, state->who, MSN_LIST_BL);
1535 msn_add_contact_to_list(soapconn->session->contact, NULL, state->who, MSN_LIST_BL); 1162 } else if (state->list_id == MSN_LIST_AL) {
1536 return TRUE; 1163 purple_privacy_permit_add(state->session->account, state->who, TRUE);
1537 } 1164 } else if (state->list_id == MSN_LIST_BL) {
1538 } 1165 purple_privacy_deny_add(state->session->account, state->who, TRUE);
1539 1166 }
1540 if (state->list_id == MSN_LIST_AL) { 1167 }
1541 purple_privacy_permit_add(soapconn->session->account, state->who, TRUE);
1542 } else if (state->list_id == MSN_LIST_BL) {
1543 purple_privacy_deny_add(soapconn->session->account, state->who, TRUE);
1544 } 1168 }
1545 1169
1546 msn_callback_state_free(state); 1170 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 } 1171 }
1558 1172
1559 void 1173 void
1560 msn_add_contact_to_list(MsnContact *contact, MsnCallbackState *state, 1174 msn_add_contact_to_list(MsnContact *contact, MsnCallbackState *state,
1561 const gchar *passport, const MsnListId list) 1175 const gchar *passport, const MsnListId list)
1562 { 1176 {
1563 MsnSoapReq *soap_request;
1564 gchar *body = NULL, *member = NULL; 1177 gchar *body = NULL, *member = NULL;
1565 MsnSoapPartnerScenario partner_scenario; 1178 MsnSoapPartnerScenario partner_scenario;
1566 1179
1567 g_return_if_fail(contact != NULL); 1180 g_return_if_fail(contact != NULL);
1568 g_return_if_fail(passport != NULL); 1181 g_return_if_fail(passport != NULL);
1569 g_return_if_fail(list < 5); 1182 g_return_if_fail(list < 5);
1570 1183
1571 purple_debug_info("MSN CL", "Adding contact %s to %s list\n", passport, MsnMemberRole[list]); 1184 purple_debug_info("MSN CL", "Adding contact %s to %s list\n", passport, MsnMemberRole[list]);
1572 1185
1573 if (state == NULL) { 1186 if (state == NULL) {
1574 state = msn_callback_state_new(); 1187 state = msn_callback_state_new(contact->session);
1575 } 1188 }
1576 msn_callback_state_set_list_id(state, list); 1189 msn_callback_state_set_list_id(state, list);
1577 msn_callback_state_set_who(state, passport); 1190 msn_callback_state_set_who(state, passport);
1578 1191
1579 partner_scenario = (list == MSN_LIST_RL) ? MSN_PS_CONTACT_API : MSN_PS_BLOCK_UNBLOCK; 1192 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, 1196 body = g_strdup_printf(MSN_CONTACT_ADD_TO_LIST_TEMPLATE,
1584 MsnSoapPartnerScenarioText[partner_scenario], 1197 MsnSoapPartnerScenarioText[partner_scenario],
1585 MsnMemberRole[list], 1198 MsnMemberRole[list],
1586 member); 1199 member);
1587 1200
1201 msn_soap_message_send(contact->session,
1202 msn_soap_message_new(MSN_ADD_MEMBER_TO_LIST_SOAP_ACTION,
1203 xmlnode_from_str(body, -1)),
1204 MSN_CONTACT_SERVER, MSN_SHARE_POST_URL,
1205 msn_add_contact_to_list_read_cb, state);
1206
1588 g_free(member); 1207 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); 1208 g_free(body);
1602 } 1209 }
1603 1210
1604
1605 #if 0 1211 #if 0
1606 static gboolean 1212 static void
1607 msn_gleams_read_cb(MsnSoapConn * soapconn) 1213 msn_gleams_read_cb(MsnSoapMessage *req, MsnSoapMessage *resp, gpointer data)
1608 { 1214 {
1609 purple_debug_info("MSN CL","Gleams read done\n"); 1215 if (resp != NULL)
1610 return TRUE; 1216 purple_debug_info("MSNP14","Gleams read done\n");
1611 } 1217 else
1612 1218 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 } 1219 }
1620 1220
1621 /*get the gleams info*/ 1221 /*get the gleams info*/
1622 void 1222 void
1623 msn_get_gleams(MsnContact *contact) 1223 msn_get_gleams(MsnContact *contact)
1624 { 1224 {
1625 MsnSoapReq *soap_request; 1225 MsnSoapReq *soap_request;
1626 1226
1627 purple_debug_info("MSNP14","msn get gleams info...\n"); 1227 purple_debug_info("MSNP14","msn get gleams info...\n");
1628 /*build SOAP and POST it*/ 1228 msn_soap_message_send(contact->session,
1629 soap_request = msn_soap_request_new(MSN_CONTACT_SERVER, 1229 msn_soap_message_new(MSN_GET_GLEAMS_SOAP_ACTION,
1630 MSN_ADDRESS_BOOK_POST_URL, 1230 xmlnode_from_str(MSN_GLEAMS_TEMPLATE, -1)),
1631 MSN_GET_GLEAMS_SOAP_ACTION, 1231 MSN_CONTACT_SERVER, MSN_ADDRESS_BOOK_POST_URL,
1632 MSN_GLEAMS_TEMPLATE, 1232 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 } 1233 }
1639 #endif 1234 #endif
1640 1235
1641 1236
1642 /*************************************************************** 1237 /***************************************************************
1643 * Group Operations 1238 * Group Operations
1644 ***************************************************************/ 1239 ***************************************************************/
1645 1240
1646 static gboolean 1241 static void
1647 msn_group_read_cb(MsnSoapConn *soapconn) 1242 msn_group_read_cb(MsnSoapMessage *req, MsnSoapMessage *resp, gpointer data)
1648 { 1243 {
1649 MsnUserList *userlist; 1244 MsnCallbackState *state = data;
1650 MsnCallbackState *state = NULL; 1245
1651 1246 purple_debug_info("MSNCL", "Group request successful.\n");
1652 purple_debug_info("MSN CL", "Group request successful.\n"); 1247
1653 1248 g_return_if_fail(state->session != NULL);
1654 g_return_val_if_fail(soapconn->session != NULL, FALSE); 1249 g_return_if_fail(state->session->userlist != NULL);
1655 g_return_val_if_fail(soapconn->session->userlist != NULL, TRUE); 1250 g_return_if_fail(state->session->contact != NULL);
1656 g_return_val_if_fail(soapconn->session->contact != NULL, FALSE); 1251
1657 1252 if (resp == NULL) {
1658 state = (MsnCallbackState *) soapconn->data_cb;
1659
1660 if (soapconn->body == NULL) {
1661 msn_callback_state_free(state); 1253 msn_callback_state_free(state);
1662 return TRUE; 1254 return;
1663 } 1255 }
1664 1256
1665 if (state) { 1257 if (state) {
1666 userlist = soapconn->session->userlist; 1258 MsnSession *session = state->session;
1259 MsnUserList *userlist = session->userlist;
1667 1260
1668 if (state->action & MSN_RENAME_GROUP) { 1261 if (state->action & MSN_RENAME_GROUP) {
1669 msn_userlist_rename_group_id(soapconn->session->userlist, 1262 msn_userlist_rename_group_id(session->userlist,
1670 state->guid, 1263 state->guid,
1671 state->new_group_name); 1264 state->new_group_name);
1672 } 1265 }
1673 1266
1674 if (state->action & MSN_ADD_GROUP) { 1267 if (state->action & MSN_ADD_GROUP) {
1675 gchar *guid, *endguid; 1268 /* the response is taken from
1676 1269 http://telepathy.freedesktop.org/wiki/Pymsn/MSNP/ContactListActions
1677 guid = g_strstr_len(soapconn->read_buf, soapconn->read_len, "<guid>"); 1270 should copy it to msnpiki some day */
1678 guid += 6; 1271 xmlnode *guid_node = msn_soap_xml_get(resp->xml,
1679 endguid = g_strstr_len(soapconn->read_buf, soapconn->read_len, "</guid>"); 1272 "Body/ABGroupAddResponse/ABGroupAddResult/guid");
1680 *endguid = '\0'; 1273
1681 /* create and add the new group to the userlist */ 1274 if (guid_node) {
1682 purple_debug_info("MSN CL", "Adding group %s with guid = %s to the userlist\n", state->new_group_name, guid); 1275 char *guid = xmlnode_get_data(guid_node);
1683 msn_group_new(soapconn->session->userlist, guid, state->new_group_name); 1276
1684 1277 /* create and add the new group to the userlist */
1685 if (state->action & MSN_ADD_BUDDY) { 1278 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, 1279 msn_group_new(session->userlist, guid, state->new_group_name);
1687 state->who, 1280
1688 state->new_group_name); 1281 if (state->action & MSN_ADD_BUDDY) {
1689 msn_callback_state_free(state); 1282 msn_userlist_add_buddy(session->userlist,
1690 return TRUE; 1283 state->who,
1691 } 1284 state->new_group_name);
1692 1285 msn_callback_state_free(state);
1693 if (state->action & MSN_MOVE_BUDDY) { 1286 } else if (state->action & MSN_MOVE_BUDDY) {
1694 msn_add_contact_to_group(soapconn->session->contact, state, state->who, guid); 1287 msn_add_contact_to_group(session->contact, state, state->who, guid);
1695 return TRUE; 1288 }
1289
1290 g_free(guid);
1291 } else {
1292 purple_debug_info("MSNCL", "Adding group %s failed\n",
1293 state->new_group_name);
1696 } 1294 }
1697 } 1295 }
1698 1296
1699 if (state->action & MSN_DEL_GROUP) { 1297 if (state->action & MSN_DEL_GROUP) {
1700 GList *l; 1298 GList *l;
1701 1299
1702 msn_userlist_remove_group_id(soapconn->session->userlist, state->guid); 1300 msn_userlist_remove_group_id(session->userlist, state->guid);
1703 for (l = userlist->users; l != NULL; l = l->next) { 1301 for (l = userlist->users; l != NULL; l = l->next) {
1704 msn_user_remove_group_id( (MsnUser *)l->data, state->guid); 1302 msn_user_remove_group_id( (MsnUser *)l->data, state->guid);
1705 } 1303 }
1706
1707 } 1304 }
1708 1305
1709 msn_callback_state_free(state); 1306 msn_callback_state_free(state);
1710 } 1307 }
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 } 1308 }
1722 1309
1723 /* add group */ 1310 /* add group */
1724 void 1311 void
1725 msn_add_group(MsnSession *session, MsnCallbackState *state, const char* group_name) 1312 msn_add_group(MsnSession *session, MsnCallbackState *state, const char* group_name)
1726 { 1313 {
1727 MsnSoapReq *soap_request;
1728 MsnContact *contact;
1729 char *body = NULL; 1314 char *body = NULL;
1730 gchar *escaped_group_name;
1731 1315
1732 g_return_if_fail(session != NULL); 1316 g_return_if_fail(session != NULL);
1733 g_return_if_fail(group_name != NULL); 1317 g_return_if_fail(group_name != NULL);
1734 1318
1735 contact = session->contact; 1319 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 1320
1738 if (state == NULL) { 1321 if (state == NULL) {
1739 state = msn_callback_state_new(); 1322 state = msn_callback_state_new(session);
1740 } 1323 }
1741 1324
1742 msn_callback_state_set_action(state, MSN_ADD_GROUP); 1325 msn_callback_state_set_action(state, MSN_ADD_GROUP);
1743 msn_callback_state_set_new_group_name(state, group_name); 1326 msn_callback_state_set_new_group_name(state, group_name);
1744 1327
1745 /* escape group name's html special chars so it can safely be sent 1328 /* escape group name's html special chars so it can safely be sent
1746 * in a XML SOAP request 1329 * in a XML SOAP request
1747 */ 1330 */
1748 escaped_group_name = g_markup_escape_text(group_name, -1); 1331 body = g_markup_printf_escaped(MSN_GROUP_ADD_TEMPLATE, group_name);
1749 body = g_strdup_printf(MSN_GROUP_ADD_TEMPLATE, escaped_group_name); 1332
1750 g_free(escaped_group_name); 1333 msn_soap_message_send(session,
1751 1334 msn_soap_message_new(MSN_GROUP_ADD_SOAP_ACTION,
1752 /*build SOAP and POST it*/ 1335 xmlnode_from_str(body, -1)),
1753 soap_request = msn_soap_request_new(MSN_CONTACT_SERVER, 1336 MSN_CONTACT_SERVER, MSN_ADDRESS_BOOK_POST_URL,
1754 MSN_ADDRESS_BOOK_POST_URL, 1337 msn_group_read_cb, state);
1755 MSN_GROUP_ADD_SOAP_ACTION, 1338
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); 1339 g_free(body);
1764 } 1340 }
1765 1341
1766 /* delete group */ 1342 /* delete group */
1767 void 1343 void
1768 msn_del_group(MsnSession *session, const gchar *group_name) 1344 msn_del_group(MsnSession *session, const gchar *group_name)
1769 { 1345 {
1770 MsnSoapReq *soap_request;
1771 MsnContact *contact;
1772 MsnCallbackState *state; 1346 MsnCallbackState *state;
1773 char *body = NULL; 1347 char *body = NULL;
1774 const gchar *guid; 1348 const gchar *guid;
1775 1349
1776 g_return_if_fail(session != NULL); 1350 g_return_if_fail(session != NULL);
1777 1351
1778 g_return_if_fail(group_name != NULL); 1352 g_return_if_fail(group_name != NULL);
1779 contact = session->contact; 1353 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 1354
1782 guid = msn_userlist_find_group_id(session->userlist, group_name); 1355 guid = msn_userlist_find_group_id(session->userlist, group_name);
1783 1356
1784 /* if group uid we need to del is NULL, 1357 /* if group uid we need to del is NULL,
1785 * we need to delete nothing 1358 * we need to delete nothing
1786 */ 1359 */
1787 if (guid == NULL) { 1360 if (guid == NULL) {
1788 purple_debug_info("MSN CL", "Group %s guid not found, returning.\n", group_name); 1361 purple_debug_info("MSNCL", "Group %s guid not found, returning.\n", group_name);
1789 return; 1362 return;
1790 } 1363 }
1791 1364
1792 if ( !strcmp(guid, MSN_INDIVIDUALS_GROUP_ID) || !strcmp(guid, MSN_NON_IM_GROUP_ID) ) { 1365 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? 1366 // XXX add back PurpleGroup since it isn't really removed in the server?
1794 return; 1367 return;
1795 } 1368 }
1796 1369
1797 state = msn_callback_state_new(); 1370 state = msn_callback_state_new(session);
1798 msn_callback_state_set_action(state, MSN_DEL_GROUP); 1371 msn_callback_state_set_action(state, MSN_DEL_GROUP);
1799 msn_callback_state_set_guid(state, guid); 1372 msn_callback_state_set_guid(state, guid);
1800 1373
1801 body = g_strdup_printf(MSN_GROUP_DEL_TEMPLATE, guid); 1374 body = g_strdup_printf(MSN_GROUP_DEL_TEMPLATE, guid);
1802 /*build SOAP and POST it*/ 1375
1803 soap_request = msn_soap_request_new(MSN_CONTACT_SERVER, 1376 msn_soap_message_send(session,
1804 MSN_ADDRESS_BOOK_POST_URL, 1377 msn_soap_message_new(MSN_GROUP_DEL_SOAP_ACTION,
1805 MSN_GROUP_DEL_SOAP_ACTION, 1378 xmlnode_from_str(body, -1)),
1806 body, 1379 MSN_CONTACT_SERVER, MSN_ADDRESS_BOOK_POST_URL,
1807 state, 1380 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 1381
1813 g_free(body); 1382 g_free(body);
1814 } 1383 }
1815 1384
1816 /* rename group */ 1385 /* rename group */
1817 void 1386 void
1818 msn_contact_rename_group(MsnSession *session, const char *old_group_name, const char *new_group_name) 1387 msn_contact_rename_group(MsnSession *session, const char *old_group_name, const char *new_group_name)
1819 { 1388 {
1820 MsnSoapReq *soap_request; 1389 gchar *body = NULL;
1821 MsnContact *contact;
1822 gchar * escaped_group_name, *body = NULL;
1823 const gchar * guid; 1390 const gchar * guid;
1824 MsnCallbackState *state = msn_callback_state_new(); 1391 MsnCallbackState *state;
1825 1392
1826 g_return_if_fail(session != NULL); 1393 g_return_if_fail(session != NULL);
1827 g_return_if_fail(session->userlist != NULL); 1394 g_return_if_fail(session->userlist != NULL);
1828 g_return_if_fail(old_group_name != NULL); 1395 g_return_if_fail(old_group_name != NULL);
1829 g_return_if_fail(new_group_name != NULL); 1396 g_return_if_fail(new_group_name != NULL);
1830 1397
1831 contact = session->contact;
1832 purple_debug_info("MSN CL", "Renaming group %s to %s.\n", old_group_name, new_group_name); 1398 purple_debug_info("MSN CL", "Renaming group %s to %s.\n", old_group_name, new_group_name);
1833 1399
1834 guid = msn_userlist_find_group_id(session->userlist, old_group_name); 1400 guid = msn_userlist_find_group_id(session->userlist, old_group_name);
1835 if (guid == NULL) 1401 if (guid == NULL)
1836 return; 1402 return;
1837 1403
1404 state = msn_callback_state_new(session);
1838 msn_callback_state_set_guid(state, guid); 1405 msn_callback_state_set_guid(state, guid);
1839 msn_callback_state_set_new_group_name(state, new_group_name); 1406 msn_callback_state_set_new_group_name(state, new_group_name);
1840 1407
1841 if ( !strcmp(guid, MSN_INDIVIDUALS_GROUP_ID) || !strcmp(guid, MSN_NON_IM_GROUP_ID) ) { 1408 if ( !strcmp(guid, MSN_INDIVIDUALS_GROUP_ID) || !strcmp(guid, MSN_NON_IM_GROUP_ID) ) {
1842 msn_add_group(session, state, new_group_name); 1409 msn_add_group(session, state, new_group_name);
1843 // XXX move every buddy there (we probably need to fix concurrent SOAP reqs first) 1410 // XXX move every buddy there (we probably need to fix concurrent SOAP reqs first)
1844 } 1411 }
1845 1412
1846 msn_callback_state_set_action(state, MSN_RENAME_GROUP); 1413 msn_callback_state_set_action(state, MSN_RENAME_GROUP);
1847 1414
1848 /* escape group name's html special chars so it can safely be sent 1415 body = g_markup_printf_escaped(MSN_GROUP_RENAME_TEMPLATE,
1849 * in a XML SOAP request 1416 guid, new_group_name);
1850 */ 1417
1851 escaped_group_name = g_markup_escape_text(new_group_name, -1); 1418 msn_soap_message_send(session,
1852 1419 msn_soap_message_new(MSN_GROUP_RENAME_SOAP_ACTION,
1853 body = g_strdup_printf(MSN_GROUP_RENAME_TEMPLATE, guid, escaped_group_name); 1420 xmlnode_from_str(body, -1)),
1854 1421 MSN_CONTACT_SERVER, MSN_ADDRESS_BOOK_POST_URL,
1855 soap_request = msn_soap_request_new(MSN_CONTACT_SERVER, 1422 msn_group_read_cb, state);
1856 MSN_ADDRESS_BOOK_POST_URL, 1423
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); 1424 g_free(body);
1867 } 1425 }
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 }