comparison libpurple/protocols/msn/contact.c @ 21103:aa875e77e5ce

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