comparison libpurple/protocols/msn/contact.c @ 20666:0e1bc5c51030

A few leak plugs, some unnecessary allocation prevention, null pointer deref fixes and general robustness fixes. I'm sure there is more to do here, I got tired... Fixes #3308
author Daniel Atallah <daniel.atallah@gmail.com>
date Thu, 27 Sep 2007 04:41:04 +0000
parents 2c8c6d77f12c
children 4dd60add6a7c
comparison
equal deleted inserted replaced
20665:601083413e36 20666:0e1bc5c51030
29 #include "xmlnode.h" 29 #include "xmlnode.h"
30 #include "group.h" 30 #include "group.h"
31 31
32 const char *MsnSoapPartnerScenarioText[] = 32 const char *MsnSoapPartnerScenarioText[] =
33 { 33 {
34 "Initial", 34 "Initial",
35 "ContactSave", 35 "ContactSave",
36 "MessengerPendingList", 36 "MessengerPendingList",
37 "ContactMsgrAPI", 37 "ContactMsgrAPI",
38 "BlockUnblock" 38 "BlockUnblock"
39 }; 39 };
40 40
70 70
71 MsnCallbackState * 71 MsnCallbackState *
72 msn_callback_state_new(void) 72 msn_callback_state_new(void)
73 { 73 {
74 return g_new0(MsnCallbackState, 1); 74 return g_new0(MsnCallbackState, 1);
75 } 75 }
76 76
77 void 77 void
78 msn_callback_state_free(MsnCallbackState *state) 78 msn_callback_state_free(MsnCallbackState *state)
79 { 79 {
80 if (state == NULL) 80 if (state == NULL)
81 return; 81 return;
82 82
83 if (state->who != NULL) 83 g_free(state->who);
84 g_free(state->who); 84 g_free(state->uid);
85 85 g_free(state->old_group_name);
86 if (state->uid != NULL) 86 g_free(state->new_group_name);
87 g_free(state->uid); 87 g_free(state->guid);
88
89 if (state->old_group_name != NULL)
90 g_free(state->old_group_name);
91
92 if (state->new_group_name != NULL)
93 g_free(state->new_group_name);
94
95 if (state->guid != NULL)
96 g_free(state->guid);
97 88
98 g_free(state); 89 g_free(state);
99 } 90 }
100 91
101 void 92 void
102 msn_callback_state_set_who(MsnCallbackState *state, const gchar *who) 93 msn_callback_state_set_who(MsnCallbackState *state, const gchar *who)
103 { 94 {
104 gchar *new_str = NULL; 95 gchar *new_str = NULL;
105 96
106 g_return_if_fail(state != NULL); 97 g_return_if_fail(state != NULL);
107 98
108 if (who != NULL) 99 if (who != NULL)
109 new_str = g_strdup(who); 100 new_str = g_strdup(who);
110 101
111 if (state->who != NULL) 102 g_free(state->who);
112 g_free(state->who);
113
114 state->who = new_str; 103 state->who = new_str;
115 } 104 }
116 105
117 void 106 void
118 msn_callback_state_set_uid(MsnCallbackState *state, const gchar *uid) 107 msn_callback_state_set_uid(MsnCallbackState *state, const gchar *uid)
119 { 108 {
120 gchar *new_str = NULL; 109 gchar *new_str = NULL;
121 110
122 g_return_if_fail(state != NULL); 111 g_return_if_fail(state != NULL);
123 112
124 if (uid != NULL) 113 if (uid != NULL)
125 new_str = g_strdup(uid); 114 new_str = g_strdup(uid);
126 115
127 if (state->uid != NULL) 116 g_free(state->uid);
128 g_free(state->uid); 117 state->uid = new_str;
129
130 state->uid = new_str;
131 } 118 }
132 119
133 void 120 void
134 msn_callback_state_set_old_group_name(MsnCallbackState *state, const gchar *old_group_name) 121 msn_callback_state_set_old_group_name(MsnCallbackState *state, const gchar *old_group_name)
135 { 122 {
138 g_return_if_fail(state != NULL); 125 g_return_if_fail(state != NULL);
139 126
140 if (old_group_name != NULL) 127 if (old_group_name != NULL)
141 new_str = g_strdup(old_group_name); 128 new_str = g_strdup(old_group_name);
142 129
143 if (state->old_group_name != NULL) 130 g_free(state->old_group_name);
144 g_free(state->old_group_name);
145
146 state->old_group_name = new_str; 131 state->old_group_name = new_str;
147 } 132 }
148 133
149 void 134 void
150 msn_callback_state_set_new_group_name(MsnCallbackState *state, const gchar *new_group_name) 135 msn_callback_state_set_new_group_name(MsnCallbackState *state, const gchar *new_group_name)
154 g_return_if_fail(state != NULL); 139 g_return_if_fail(state != NULL);
155 140
156 if (new_group_name != NULL) 141 if (new_group_name != NULL)
157 new_str = g_strdup(new_group_name); 142 new_str = g_strdup(new_group_name);
158 143
159 if (state->new_group_name != NULL) 144 g_free(state->new_group_name);
160 g_free(state->new_group_name);
161
162 state->new_group_name = new_str; 145 state->new_group_name = new_str;
163 } 146 }
164 147
165 void 148 void
166 msn_callback_state_set_guid(MsnCallbackState *state, const gchar *guid) 149 msn_callback_state_set_guid(MsnCallbackState *state, const gchar *guid)
169 152
170 g_return_if_fail(state != NULL); 153 g_return_if_fail(state != NULL);
171 154
172 if (guid != NULL) 155 if (guid != NULL)
173 new_str = g_strdup(guid); 156 new_str = g_strdup(guid);
174 157
175 if (state->guid != NULL) 158 g_free(state->guid);
176 g_free(state->guid);
177
178 state->guid = new_str; 159 state->guid = new_str;
179 } 160 }
180 161
181 162
182 void 163 void
183 msn_callback_state_set_list_id(MsnCallbackState *state, MsnListId list_id) 164 msn_callback_state_set_list_id(MsnCallbackState *state, MsnListId list_id)
184 { 165 {
185 g_return_if_fail(state != NULL); 166 g_return_if_fail(state != NULL);
186 167
187 state->list_id = list_id; 168 state->list_id = list_id;
188 } 169 }
189 170
190 void 171 void
191 msn_callback_state_set_action(MsnCallbackState *state, MsnCallbackAction action) 172 msn_callback_state_set_action(MsnCallbackState *state, MsnCallbackAction action)
192 { 173 {
193 g_return_if_fail(state != NULL); 174 g_return_if_fail(state != NULL);
194 175
195 state->action |= action; 176 state->action |= action;
196 } 177 }
197 178
198 /*contact SOAP server login error*/ 179 /*contact SOAP server login error*/
199 static void 180 static void
200 msn_contact_login_error_cb(MsnSoapConn *soapconn, PurpleSslConnection *gsc, PurpleSslErrorType error) 181 msn_contact_login_error_cb(MsnSoapConn *soapconn, PurpleSslConnection *gsc, PurpleSslErrorType error)
201 { 182 {
202 MsnSession *session; 183 MsnSession *session;
225 return TRUE; 206 return TRUE;
226 } 207 }
227 208
228 /*get MSN member role utility*/ 209 /*get MSN member role utility*/
229 static MsnListId 210 static MsnListId
230 msn_get_memberrole(char * role) 211 msn_get_memberrole(char *role)
231 { 212 {
232 213 g_return_val_if_fail(role != NULL, 0);
214
233 if (!strcmp(role,"Allow")) { 215 if (!strcmp(role,"Allow")) {
234 return MSN_LIST_AL; 216 return MSN_LIST_AL;
235 } else if (!strcmp(role,"Block")) { 217 } else if (!strcmp(role,"Block")) {
236 return MSN_LIST_BL; 218 return MSN_LIST_BL;
237 } else if (!strcmp(role,"Reverse")) { 219 } else if (!strcmp(role,"Reverse")) {
241 } 223 }
242 return 0; 224 return 0;
243 } 225 }
244 226
245 /*get User Type*/ 227 /*get User Type*/
246 static int 228 static int
247 msn_get_user_type(char * type) 229 msn_get_user_type(char *type)
248 { 230 {
231 g_return_val_if_fail(type != NULL, 0);
232
249 if (!strcmp(type,"Regular")) { 233 if (!strcmp(type,"Regular")) {
250 return MSN_USER_TYPE_PASSPORT; 234 return MSN_USER_TYPE_PASSPORT;
251 } 235 }
252 if (!strcmp(type,"Live")) { 236 if (!strcmp(type,"Live")) {
253 return MSN_USER_TYPE_PASSPORT; 237 return MSN_USER_TYPE_PASSPORT;
325 MsnListId list; 309 MsnListId list;
326 char * passport, *typedata; 310 char * passport, *typedata;
327 xmlnode *fault, *faultstringnode, *faultdetail, *errorcode; 311 xmlnode *fault, *faultstringnode, *faultdetail, *errorcode;
328 xmlnode *node, *body, *response, *result, *services; 312 xmlnode *node, *body, *response, *result, *services;
329 xmlnode *service, *memberships, *info, *handle, *handletype; 313 xmlnode *service, *memberships, *info, *handle, *handletype;
330 xmlnode *LastChangeNode;
331 xmlnode *membershipnode, *members, *member, *passportNode; 314 xmlnode *membershipnode, *members, *member, *passportNode;
332 char *LastChangeStr;
333 315
334 session = contact->session; 316 session = contact->session;
335 node = xmlnode_from_str(contact->soapconn->body, contact->soapconn->body_len); 317 node = xmlnode_from_str(contact->soapconn->body, contact->soapconn->body_len);
336 318
337 if (node == NULL) { 319 if (node == NULL) {
339 return; 321 return;
340 } 322 }
341 323
342 purple_debug_misc("MSNCL","Parsing contact list with size %d\n", contact->soapconn->body_len); 324 purple_debug_misc("MSNCL","Parsing contact list with size %d\n", contact->soapconn->body_len);
343 325
344 purple_debug_misc("MSNCL","Root node @ %p: Name: '%s', child: '%s', lastchild: '%s'\n",node,node->name,node->child->name,node->lastchild->name); 326 purple_debug_misc("MSNCL","Root node @ %p: Name: '%s', child: '%s', lastchild: '%s'\n", node,
345 body = xmlnode_get_child(node,"Body"); 327 node->name ? node->name : "(null)",
328 (node->child && node->child->name) ? node->child->name : "(null)",
329 (node->lastchild && node->lastchild->name) ? node->lastchild->name : "(null)");
330
331 body = xmlnode_get_child(node, "Body");
346 332
347 if (body == NULL) { 333 if (body == NULL) {
348 purple_debug_warning("MSNCL", "Failed to parse contact list Body node\n"); 334 purple_debug_warning("MSNCL", "Failed to parse contact list Body node\n");
349 xmlnode_free(node); 335 xmlnode_free(node);
350 return; 336 return;
355 if ( (fault = xmlnode_get_child(body, "Fault")) != NULL) { 341 if ( (fault = xmlnode_get_child(body, "Fault")) != NULL) {
356 purple_debug_info("MSNCL","Fault received from SOAP server!\n"); 342 purple_debug_info("MSNCL","Fault received from SOAP server!\n");
357 343
358 if ( (faultstringnode = xmlnode_get_child(fault, "faultstring")) != NULL ) { 344 if ( (faultstringnode = xmlnode_get_child(fault, "faultstring")) != NULL ) {
359 gchar * faultstring = xmlnode_get_data(faultstringnode); 345 gchar * faultstring = xmlnode_get_data(faultstringnode);
360 purple_debug_info("MSNCL","Faultstring: %s\n", faultstring); 346 purple_debug_info("MSNCL", "Faultstring: %s\n", faultstring ? faultstring : "(null)");
361 g_free(faultstring); 347 g_free(faultstring);
362 } 348 }
363 if ( (faultdetail = xmlnode_get_child(fault, "detail")) != NULL ) { 349 if ( (faultdetail = xmlnode_get_child(fault, "detail")) != NULL ) {
364 purple_debug_info("MSNCL","detail @ %p, name: %s\n",faultdetail, faultdetail->name); 350 purple_debug_info("MSNCL","detail @ %p, name: %s\n",faultdetail, faultdetail->name);
365 351
366 if ( (errorcode = xmlnode_get_child(faultdetail, "errorcode")) != NULL ) { 352 if ( (errorcode = xmlnode_get_child(faultdetail, "errorcode")) != NULL ) {
367 purple_debug_info("MSNCL","errorcode @ %p, name: %s\n",errorcode, errorcode->name); 353 purple_debug_info("MSNCL","errorcode @ %p, name: %s\n", errorcode, errorcode->name);
368 354
369 if (errorcode->child != NULL) { 355 if (errorcode->child != NULL) {
370 gchar *errorcodestring = xmlnode_get_data(errorcode); 356 gchar *errorcodestring = xmlnode_get_data(errorcode);
371 purple_debug_info("MSNCL", "Error Code: %s\n", errorcodestring); 357 purple_debug_info("MSNCL", "Error Code: %s\n", errorcodestring ? errorcodestring : "(null)");
372 358
373 if ( !strncmp(errorcodestring, "ABDoesNotExist", 14) ) { 359 if (errorcodestring && !strncmp(errorcodestring, "ABDoesNotExist", 14) ) {
374 xmlnode_free(node); 360 xmlnode_free(node);
375 g_free(errorcodestring); 361 g_free(errorcodestring);
376 msn_create_address_book(contact); 362 msn_create_address_book(contact);
377 return; 363 return;
378 } 364 }
416 purple_debug_info("MSNCL","Services @ %p\n",services); 402 purple_debug_info("MSNCL","Services @ %p\n",services);
417 403
418 for (service = xmlnode_get_child(services, "Service"); service; 404 for (service = xmlnode_get_child(services, "Service"); service;
419 service = xmlnode_get_next_twin(service)) { 405 service = xmlnode_get_next_twin(service)) {
420 purple_debug_info("MSNCL","Service @ %p\n",service); 406 purple_debug_info("MSNCL","Service @ %p\n",service);
421 407
422 if ( (info = xmlnode_get_child(service,"Info")) == NULL ) { 408 if ( (info = xmlnode_get_child(service,"Info")) == NULL ) {
423 purple_debug_error("MSNCL","Error getting 'Info' child node\n"); 409 purple_debug_error("MSNCL","Error getting 'Info' child node\n");
424 continue; 410 continue;
425 } 411 }
426 if ( (handle = xmlnode_get_child(info,"Handle")) == NULL ) { 412 if ( (handle = xmlnode_get_child(info,"Handle")) == NULL ) {
432 continue; 418 continue;
433 } 419 }
434 420
435 if ( (typedata = xmlnode_get_data(handletype)) == NULL) { 421 if ( (typedata = xmlnode_get_data(handletype)) == NULL) {
436 purple_debug_error("MSNCL","Error retrieving data from 'Type' child node\n"); 422 purple_debug_error("MSNCL","Error retrieving data from 'Type' child node\n");
437 g_free(typedata);
438 continue; 423 continue;
439 } 424 }
440 425
441 purple_debug_info("MSNCL","processing '%s' Service\n", typedata); 426 purple_debug_info("MSNCL","processing '%s' Service\n", typedata);
442 427
445 g_free(typedata); 430 g_free(typedata);
446 continue; 431 continue;
447 } 432 }
448 433
449 if ( !g_strcasecmp(typedata, "Messenger") ) { 434 if ( !g_strcasecmp(typedata, "Messenger") ) {
435 char *LastChangeStr = NULL;
436 xmlnode *LastChangeNode;
450 437
451 /*Last Change Node*/ 438 /*Last Change Node*/
452 LastChangeNode = xmlnode_get_child(service, "LastChange"); 439 if ((LastChangeNode = xmlnode_get_child(service, "LastChange")))
453 LastChangeStr = xmlnode_get_data(LastChangeNode); 440 LastChangeStr = xmlnode_get_data(LastChangeNode);
454 purple_debug_info("MSNCL","LastChangeNode: '%s'\n",LastChangeStr); 441 purple_debug_info("MSNCL","LastChangeNode: '%s'\n",LastChangeStr ? LastChangeStr : "(null)");
455 purple_account_set_string(session->account, "CLLastChange", LastChangeStr); 442 purple_account_set_string(session->account, "CLLastChange", LastChangeStr);
456 g_free(LastChangeStr); 443 g_free(LastChangeStr);
457 444
458 memberships = xmlnode_get_child(service,"Memberships"); 445 memberships = xmlnode_get_child(service,"Memberships");
459 if (memberships == NULL) { 446 if (memberships == NULL) {
464 } 451 }
465 purple_debug_info("MSNCL","Memberships @ %p: Name: '%s'\n",memberships,memberships->name); 452 purple_debug_info("MSNCL","Memberships @ %p: Name: '%s'\n",memberships,memberships->name);
466 for (membershipnode = xmlnode_get_child(memberships, "Membership"); membershipnode; 453 for (membershipnode = xmlnode_get_child(memberships, "Membership"); membershipnode;
467 membershipnode = xmlnode_get_next_twin(membershipnode)){ 454 membershipnode = xmlnode_get_next_twin(membershipnode)){
468 xmlnode *roleNode; 455 xmlnode *roleNode;
469 char *role; 456 char *role = NULL;
470 457 list = 0;
471 roleNode = xmlnode_get_child(membershipnode,"MemberRole"); 458
472 role = xmlnode_get_data(roleNode); 459 if ((roleNode = xmlnode_get_child(membershipnode,"MemberRole"))) {
473 list = msn_get_memberrole(role); 460 role = xmlnode_get_data(roleNode);
461 list = msn_get_memberrole(role);
462 }
474 list_op = 1 << list; 463 list_op = 1 << list;
475 464
476 purple_debug_info("MSNCL","MemberRole role: %s, list_op: %d\n",role,list_op); 465 purple_debug_info("MSNCL","MemberRole role: %s, list_op: %d\n", role ? role : "(null)", list_op);
477 466
478 g_free(role); 467 g_free(role);
479 468
480 members = xmlnode_get_child(membershipnode,"Members"); 469 members = xmlnode_get_child(membershipnode, "Members");
481 for (member = xmlnode_get_child(members, "Member"); member; 470 for (member = xmlnode_get_child(members, "Member"); member;
482 member = xmlnode_get_next_twin(member)){ 471 member = xmlnode_get_next_twin(member)){
483 MsnUser *user = NULL; 472 MsnUser *user = NULL;
484 xmlnode *typeNode, *membershipIdNode=NULL; 473 xmlnode *typeNode, *membershipIdNode = NULL;
485 gchar *type, *membershipId = NULL; 474 gchar *type, *membershipId = NULL;
486 475 const char *member_type = xmlnode_get_attrib(member, "type");
487 purple_debug_info("MSNCL","Member type: %s\n", xmlnode_get_attrib(member,"type")); 476
488 477 purple_debug_info("MSNCL","Member type: %s\n", member_type ? member_type : "(null)");
489 if( !g_strcasecmp(xmlnode_get_attrib(member,"type"), "PassportMember") ) { 478
490 passportNode = xmlnode_get_child(member,"PassportName"); 479 if (!member_type)
491 passport = xmlnode_get_data(passportNode); 480 continue;
492 typeNode = xmlnode_get_child(member,"Type"); 481
493 type = xmlnode_get_data(typeNode); 482 if(!g_strcasecmp(member_type, "PassportMember") ) {
494 purple_debug_info("MSNCL","Passport name: '%s', Type: %s\n",passport,type); 483 passport = type = NULL;
484 if ((passportNode = xmlnode_get_child(member, "PassportName")))
485 passport = xmlnode_get_data(passportNode);
486 if ((typeNode = xmlnode_get_child(member, "Type")))
487 type = xmlnode_get_data(typeNode);
488 purple_debug_info("MSNCL","Passport name: '%s', Type: %s\n", passport ? passport : "(null)", type ? type : "(null)");
489 /* Why do we even bother parsing it just to free it??? */
495 g_free(type); 490 g_free(type);
496 491
497 user = msn_userlist_find_add_user(session->userlist,passport,NULL); 492 user = msn_userlist_find_add_user(session->userlist,passport,NULL);
493 g_free(passport);
498 494
499 membershipIdNode = xmlnode_get_child(member,"MembershipId"); 495 membershipIdNode = xmlnode_get_child(member,"MembershipId");
500 if (membershipIdNode != NULL) { 496 if (membershipIdNode != NULL) {
501 membershipId = xmlnode_get_data(membershipIdNode); 497 membershipId = xmlnode_get_data(membershipIdNode);
502 if (membershipId != NULL) { 498 if (membershipId != NULL) {
503 user->membership_id[list] = atoi(membershipId); 499 user->membership_id[list] = atoi(membershipId);
504 g_free(membershipId); 500 g_free(membershipId);
505 } 501 }
506 } 502 }
507 503
508 msn_got_lst_user(session, user, list_op, NULL); 504 msn_got_lst_user(session, user, list_op, NULL);
509 505 }
506 else if (!g_strcasecmp(member_type, "PhoneMember")) {
507 }
508 else if (!g_strcasecmp(member_type, "EmailMember")) {
509 xmlnode *emailNode;
510 passport = NULL;
511
512 if ((emailNode = xmlnode_get_child(member, "Email")))
513 passport = xmlnode_get_data(emailNode);
514 purple_debug_info("MSNCL","Email Member: Name: '%s', list_op: %d\n", passport ? passport : "(null)", list_op);
515
516 user = msn_userlist_find_add_user(session->userlist, passport, NULL);
510 g_free(passport); 517 g_free(passport);
511 } 518
512
513 if (!g_strcasecmp(xmlnode_get_attrib(member,"type"),"PhoneMember")) {
514 }
515
516 if (!g_strcasecmp(xmlnode_get_attrib(member,"type"),"EmailMember")) {
517 xmlnode *emailNode;
518
519 emailNode = xmlnode_get_child(member,"Email");
520 passport = xmlnode_get_data(emailNode);
521 purple_debug_info("MSNCL","Email Member: Name: '%s', list_op: %d\n", passport, list_op);
522 user = msn_userlist_find_add_user(session->userlist, passport, NULL);
523
524 membershipIdNode = xmlnode_get_child(member,"MembershipId"); 519 membershipIdNode = xmlnode_get_child(member,"MembershipId");
525 if (membershipIdNode != NULL) { 520 if (membershipIdNode != NULL) {
526 membershipId = xmlnode_get_data(membershipIdNode); 521 membershipId = xmlnode_get_data(membershipIdNode);
527 if (membershipId != NULL) { 522 if (membershipId != NULL) {
528 user->membership_id[list] = atoi(membershipId); 523 user->membership_id[list] = atoi(membershipId);
529 g_free(membershipId); 524 g_free(membershipId);
530 } 525 }
531 } 526 }
532 527
533 msn_got_lst_user(session, user, list_op, NULL); 528 msn_got_lst_user(session, user, list_op, NULL);
534 g_free(passport);
535 } 529 }
536 } 530 }
537 } 531 }
538 g_free(typedata); /* Free 'Type' node data after processing 'Messenger' Service */ 532 g_free(typedata); /* Free 'Type' node data after processing 'Messenger' Service */
539 } 533 }
668 static void 662 static void
669 msn_parse_addressbook_contacts(MsnContact *contact, xmlnode *node) 663 msn_parse_addressbook_contacts(MsnContact *contact, xmlnode *node)
670 { 664 {
671 MsnSession *session = contact->session; 665 MsnSession *session = contact->session;
672 xmlnode *contactNode; 666 xmlnode *contactNode;
667 char *passport = NULL, *Name = NULL, *uid = NULL, *type = NULL;
673 668
674 for(contactNode = xmlnode_get_child(node, "Contact"); contactNode; 669 for(contactNode = xmlnode_get_child(node, "Contact"); contactNode;
675 contactNode = xmlnode_get_next_twin(contactNode)){ 670 contactNode = xmlnode_get_next_twin(contactNode)) {
676 xmlnode *contactId,*contactInfo,*contactType,*passportName,*displayName,*guid; 671 xmlnode *contactId, *contactInfo, *contactType, *passportName, *displayName, *guid, *groupIds;
677 xmlnode *groupIds;
678 MsnUser *user; 672 MsnUser *user;
679 MsnUserType usertype; 673 MsnUserType usertype;
680 char *passport = NULL, *Name = NULL, *uid = NULL, *type = NULL; 674
681 675 if (!(contactId = xmlnode_get_child(contactNode,"contactId"))
682 contactId= xmlnode_get_child(contactNode,"contactId"); 676 || !(contactInfo = xmlnode_get_child(contactNode, "contactInfo"))
677 || !(contactType = xmlnode_get_child(contactInfo, "contactType")))
678 continue;
679
680 g_free(passport);
681 g_free(Name);
682 g_free(uid);
683 g_free(type);
684 passport = Name = uid = type = NULL;
685
683 uid = xmlnode_get_data(contactId); 686 uid = xmlnode_get_data(contactId);
684
685 contactInfo = xmlnode_get_child(contactNode,"contactInfo");
686 contactType = xmlnode_get_child(contactInfo,"contactType");
687 type = xmlnode_get_data(contactType); 687 type = xmlnode_get_data(contactType);
688 688
689 /*setup the Display Name*/ 689 /*setup the Display Name*/
690 if (!strcmp(type, "Me")){ 690 if (type && !strcmp(type, "Me")){
691 char *friendly; 691 char *friendly = NULL;
692 friendly = xmlnode_get_data(xmlnode_get_child(contactInfo, "displayName")); 692 if ((displayName = xmlnode_get_child(contactInfo, "displayName")))
693 purple_connection_set_display_name(session->account->gc, purple_url_decode(friendly)); 693 friendly = xmlnode_get_data(displayName);
694 purple_connection_set_display_name(session->account->gc, friendly ? purple_url_decode(friendly) : NULL);
694 g_free(friendly); 695 g_free(friendly);
695 g_free(uid);
696 g_free(type);
697 continue; /* Not adding own account as buddy to buddylist */ 696 continue; /* Not adding own account as buddy to buddylist */
698 } 697 }
698
699 usertype = msn_get_user_type(type); 699 usertype = msn_get_user_type(type);
700 passportName = xmlnode_get_child(contactInfo,"passportName"); 700 passportName = xmlnode_get_child(contactInfo, "passportName");
701 if (passportName == NULL) { 701 if (passportName == NULL) {
702 xmlnode *emailsNode, *contactEmailNode, *emailNode; 702 xmlnode *emailsNode, *contactEmailNode, *emailNode;
703 xmlnode *messengerEnabledNode; 703 xmlnode *messengerEnabledNode;
704 char *msnEnabled; 704 char *msnEnabled;
705 705
706 /*TODO: add it to the none-instant Messenger group and recognize as email Membership*/ 706 /*TODO: add it to the none-instant Messenger group and recognize as email Membership*/
707 /*Yahoo User?*/ 707 /*Yahoo User?*/
708 emailsNode = xmlnode_get_child(contactInfo,"emails"); 708 emailsNode = xmlnode_get_child(contactInfo, "emails");
709 if (emailsNode == NULL) { 709 if (emailsNode == NULL) {
710 /*TODO: need to support the Mobile type*/ 710 /*TODO: need to support the Mobile type*/
711 g_free(uid);
712 g_free(type);
713 continue; 711 continue;
714 } 712 }
715 for(contactEmailNode = xmlnode_get_child(emailsNode,"ContactEmail");contactEmailNode; 713 for(contactEmailNode = xmlnode_get_child(emailsNode, "ContactEmail"); contactEmailNode;
716 contactEmailNode = xmlnode_get_next_twin(contactEmailNode) ){ 714 contactEmailNode = xmlnode_get_next_twin(contactEmailNode) ){
717 messengerEnabledNode = xmlnode_get_child(contactEmailNode,"isMessengerEnabled"); 715 if (!(messengerEnabledNode = xmlnode_get_child(contactEmailNode, "isMessengerEnabled"))) {
718 if(messengerEnabledNode == NULL){ 716 /* XXX: Should this be a continue instead of a break? It seems like it'd cause unpredictable results otherwise. */
719 g_free(uid);
720 g_free(type);
721 break; 717 break;
722 } 718 }
719
723 msnEnabled = xmlnode_get_data(messengerEnabledNode); 720 msnEnabled = xmlnode_get_data(messengerEnabledNode);
724 if(!strcmp(msnEnabled,"true")){ 721
722 if ((emailNode = xmlnode_get_child(contactEmailNode, "email"))) {
723 g_free(passport);
724 passport = xmlnode_get_data(emailNode);
725 }
726
727 if(msnEnabled && !strcmp(msnEnabled, "true")) {
725 /*Messenger enabled, Get the Passport*/ 728 /*Messenger enabled, Get the Passport*/
726 emailNode = xmlnode_get_child(contactEmailNode,"email"); 729 purple_debug_info("MsnAB", "Yahoo User %s\n", passport ? passport : "(null)");
727 passport = xmlnode_get_data(emailNode);
728 purple_debug_info("MsnAB","Yahoo User %s\n",passport);
729 usertype = MSN_USER_TYPE_YAHOO; 730 usertype = MSN_USER_TYPE_YAHOO;
730 g_free(uid);
731 g_free(type);
732 g_free(passport);
733 g_free(msnEnabled); 731 g_free(msnEnabled);
734 break; 732 break;
735 }else{ 733 } else {
736 /*TODO maybe we can just ignore it in Purple?*/ 734 /*TODO maybe we can just ignore it in Purple?*/
737 emailNode = xmlnode_get_child(contactEmailNode,"email"); 735 purple_debug_info("MSNAB", "Other type user\n");
738 passport = xmlnode_get_data(emailNode);
739 purple_debug_info("MSNAB","Other type user\n");
740 } 736 }
737
741 g_free(msnEnabled); 738 g_free(msnEnabled);
742 } 739 }
743 } else { 740 } else {
744 passport = xmlnode_get_data(passportName); 741 passport = xmlnode_get_data(passportName);
745 } 742 }
746 743
747 if (passport == NULL) { 744 if (passport == NULL)
748 g_free(uid);
749 g_free(type);
750 continue; 745 continue;
751 } 746
752 747 if ((displayName = xmlnode_get_child(contactInfo, "displayName")))
753 displayName = xmlnode_get_child(contactInfo,"displayName"); 748 Name = xmlnode_get_data(displayName);
754 if (displayName == NULL) { 749 else
755 Name = g_strdup(passport); 750 Name = g_strdup(passport);
756 } else {
757 Name = xmlnode_get_data(displayName);
758 }
759 751
760 purple_debug_misc("MsnAB","passport:{%s} uid:{%s} display:{%s}\n", 752 purple_debug_misc("MsnAB","passport:{%s} uid:{%s} display:{%s}\n",
761 passport,uid,Name); 753 passport, uid ? uid : "(null)", Name ? Name : "(null)");
762 754
763 user = msn_userlist_find_add_user(session->userlist, passport,Name); 755 user = msn_userlist_find_add_user(session->userlist, passport, Name);
764 msn_user_set_uid(user,uid); 756 msn_user_set_uid(user, uid);
765 msn_user_set_type(user, usertype); 757 msn_user_set_type(user, usertype);
766 g_free(Name);
767 g_free(passport);
768 g_free(uid);
769 g_free(type);
770 758
771 purple_debug_misc("MsnAB","parse guid...\n"); 759 purple_debug_misc("MsnAB","parse guid...\n");
772 groupIds = xmlnode_get_child(contactInfo,"groupIds"); 760 groupIds = xmlnode_get_child(contactInfo, "groupIds");
773 if (groupIds) { 761 if (groupIds) {
774 for (guid = xmlnode_get_child(groupIds, "guid");guid; 762 for (guid = xmlnode_get_child(groupIds, "guid"); guid;
775 guid = xmlnode_get_next_twin(guid)){ 763 guid = xmlnode_get_next_twin(guid)){
776 char *group_id; 764 char *group_id = xmlnode_get_data(guid);
777 group_id = xmlnode_get_data(guid); 765 msn_user_add_group_id(user, group_id);
778 msn_user_add_group_id(user,group_id); 766 purple_debug_misc("MsnAB", "guid:%s\n", group_id ? group_id : "(null)");
779 purple_debug_misc("MsnAB","guid:%s\n",group_id);
780 g_free(group_id); 767 g_free(group_id);
781 } 768 }
782 } else { 769 } else {
783 /*not in any group,Then set default group*/ 770 /*not in any group,Then set default group*/
784 msn_user_add_group_id(user, MSN_INDIVIDUALS_GROUP_ID); 771 msn_user_add_group_id(user, MSN_INDIVIDUALS_GROUP_ID);
785 } 772 }
786 773
787 msn_got_lst_user(session, user, MSN_LIST_FL_OP, NULL); 774 msn_got_lst_user(session, user, MSN_LIST_FL_OP, NULL);
788 } 775 }
776
777 g_free(passport);
778 g_free(Name);
779 g_free(uid);
780 g_free(type);
789 } 781 }
790 782
791 static gboolean 783 static gboolean
792 msn_parse_addressbook(MsnContact * contact) 784 msn_parse_addressbook(MsnContact * contact)
793 { 785 {
812 804
813 purple_debug_misc("MSN AddressBook","node{%p},name:%s,child:%s,last:%s\n",node,node->name,node->child->name,node->lastchild->name); 805 purple_debug_misc("MSN AddressBook","node{%p},name:%s,child:%s,last:%s\n",node,node->name,node->child->name,node->lastchild->name);
814 806
815 body = xmlnode_get_child(node,"Body"); 807 body = xmlnode_get_child(node,"Body");
816 purple_debug_misc("MSN AddressBook","body{%p},name:%s\n",body,body->name); 808 purple_debug_misc("MSN AddressBook","body{%p},name:%s\n",body,body->name);
817 809
810 /* TODO: This appears to be used in a number of places and should be de-duplicated */
818 if ( (fault = xmlnode_get_child(body, "Fault")) != NULL) { 811 if ( (fault = xmlnode_get_child(body, "Fault")) != NULL) {
819 purple_debug_info("MSN AddressBook","Fault received from SOAP server!\n"); 812 purple_debug_info("MSN AddressBook","Fault received from SOAP server!\n");
820 813
821 if ( (faultstringnode = xmlnode_get_child(fault, "faultstring")) != NULL ) { 814 if ( (faultstringnode = xmlnode_get_child(fault, "faultstring")) != NULL ) {
822 gchar *faultstring = xmlnode_get_data(faultstringnode); 815 gchar *faultstring = xmlnode_get_data(faultstringnode);
823 purple_debug_info("MSN AddressBook","Faultstring: %s\n", faultstring); 816 purple_debug_info("MSN AddressBook","Faultstring: %s\n", faultstring ? faultstring : "(null)");
824 g_free(faultstring); 817 g_free(faultstring);
825 } 818 }
826 if ( (faultdetail = xmlnode_get_child(fault, "detail")) != NULL ) { 819 if ( (faultdetail = xmlnode_get_child(fault, "detail")) != NULL ) {
827 purple_debug_info("MSN AddressBook","detail @ %p, name: %s\n",faultdetail, faultdetail->name); 820 purple_debug_info("MSN AddressBook","detail @ %p, name: %s\n",faultdetail, faultdetail->name);
828 821
829 if ( (errorcode = xmlnode_get_child(faultdetail, "errorcode")) != NULL ) { 822 if ( (errorcode = xmlnode_get_child(faultdetail, "errorcode")) != NULL ) {
830 gchar *errorcodestring; 823 gchar *errorcodestring;
831 purple_debug_info("MSN AddressBook","errorcode @ %p, name: %s\n",errorcode, errorcode->name); 824 purple_debug_info("MSN AddressBook","errorcode @ %p, name: %s\n",errorcode, errorcode->name);
832 825
833 errorcodestring = xmlnode_get_data(errorcode); 826 errorcodestring = xmlnode_get_data(errorcode);
834 purple_debug_info("MSN AddressBook", "Error Code: %s\n", errorcodestring); 827 purple_debug_info("MSN AddressBook", "Error Code: %s\n", errorcodestring ? errorcodestring : "(null)");
835 828
836 if ( !strncmp(errorcodestring, "ABDoesNotExist", 14) ) { 829 if (errorcodestring && !strncmp(errorcodestring, "ABDoesNotExist", 14) ) {
837 g_free(errorcodestring); 830 g_free(errorcodestring);
838 xmlnode_free(node); 831 xmlnode_free(node);
839 return TRUE; 832 return TRUE;
840 } 833 }
841 g_free(errorcodestring); 834 g_free(errorcodestring);
893 msn_parse_addressbook_contacts(contact, contacts); 886 msn_parse_addressbook_contacts(contact, contacts);
894 } 887 }
895 888
896 abNode =xmlnode_get_child(result,"ab"); 889 abNode =xmlnode_get_child(result,"ab");
897 if(abNode != NULL){ 890 if(abNode != NULL){
898 xmlnode *LastChangeNode, *DynamicItemLastChangedNode; 891 xmlnode *node2;
899 char *lastchange, *dynamicChange; 892 char *tmp = NULL;
900 893
901 LastChangeNode = xmlnode_get_child(abNode,"lastChange"); 894 if ((node2 = xmlnode_get_child(abNode, "lastChange")))
902 lastchange = xmlnode_get_data(LastChangeNode); 895 tmp = xmlnode_get_data(node2);
903 purple_debug_info("MsnAB"," lastchanged Time:{%s}\n",lastchange); 896 purple_debug_info("MsnAB"," lastchanged Time:{%s}\n", tmp ? tmp : "(null)");
904 purple_account_set_string(session->account, "ablastChange", lastchange); 897 purple_account_set_string(session->account, "ablastChange", tmp);
905 898
906 DynamicItemLastChangedNode = xmlnode_get_child(abNode,"DynamicItemLastChanged"); 899 g_free(tmp); tmp = NULL;
907 dynamicChange = xmlnode_get_data(DynamicItemLastChangedNode); 900 if ((node2 = xmlnode_get_child(abNode, "DynamicItemLastChanged")))
908 purple_debug_info("MsnAB"," DynamicItemLastChanged :{%s}\n",dynamicChange); 901 tmp = xmlnode_get_data(node2);
909 purple_account_set_string(session->account, "DynamicItemLastChanged", lastchange); 902 purple_debug_info("MsnAB"," DynamicItemLastChanged :{%s}\n", tmp ? tmp : "(null)");
910 g_free(dynamicChange); 903 purple_account_set_string(session->account, "DynamicItemLastChanged", tmp);
911 g_free(lastchange); 904 g_free(tmp);
912 } 905 }
913 906
914 xmlnode_free(node); 907 xmlnode_free(node);
915 msn_soap_free_read_buf(contact->soapconn); 908 msn_soap_free_read_buf(contact->soapconn);
916 return TRUE; 909 return TRUE;
967 /*get the address book*/ 960 /*get the address book*/
968 void 961 void
969 msn_get_address_book(MsnContact *contact, const MsnSoapPartnerScenario partner_scenario, const char *LastChanged, const char *dynamicItemLastChange) 962 msn_get_address_book(MsnContact *contact, const MsnSoapPartnerScenario partner_scenario, const char *LastChanged, const char *dynamicItemLastChange)
970 { 963 {
971 MsnSoapReq *soap_request; 964 MsnSoapReq *soap_request;
972 char *body = NULL; 965 char *body;
973 char *ab_update_str,*update_str; 966 char *update_str = NULL;
974 967
975 purple_debug_misc("MSN AddressBook","Getting Address Book\n"); 968 purple_debug_misc("MSN AddressBook","Getting Address Book\n");
976 969
977 /*build SOAP and POST it*/ 970 /*build SOAP and POST it*/
978 if ( LastChanged != NULL ) { 971 if (dynamicItemLastChange != NULL)
979 ab_update_str = g_strdup_printf(MSN_GET_ADDRESS_UPDATE_XML,LastChanged); 972 update_str = g_strdup_printf(MSN_GET_ADDRESS_UPDATE_XML, dynamicItemLastChange);
980 } else { 973 else if (LastChanged != NULL)
981 ab_update_str = g_strdup(""); 974 update_str = g_strdup_printf(MSN_GET_ADDRESS_UPDATE_XML, LastChanged);
982 } 975
983 if ( dynamicItemLastChange != NULL ) { 976
984 update_str = g_strdup_printf(MSN_GET_ADDRESS_UPDATE_XML, 977 body = g_strdup_printf(MSN_GET_ADDRESS_TEMPLATE, MsnSoapPartnerScenarioText[partner_scenario], update_str ? update_str : "");
985 dynamicItemLastChange);
986 } else {
987 update_str = g_strdup(ab_update_str);
988 }
989 g_free(ab_update_str);
990
991
992 body = g_strdup_printf(MSN_GET_ADDRESS_TEMPLATE, MsnSoapPartnerScenarioText[partner_scenario], update_str);
993 g_free(update_str); 978 g_free(update_str);
994 979
995 soap_request = msn_soap_request_new(MSN_CONTACT_SERVER, 980 soap_request = msn_soap_request_new(MSN_CONTACT_SERVER,
996 MSN_ADDRESS_BOOK_POST_URL,MSN_GET_ADDRESS_SOAP_ACTION, 981 MSN_ADDRESS_BOOK_POST_URL,MSN_GET_ADDRESS_SOAP_ACTION,
997 body, 982 body,
1061 msn_add_contact(MsnContact *contact, MsnCallbackState *state, const char *passport) 1046 msn_add_contact(MsnContact *contact, MsnCallbackState *state, const char *passport)
1062 { 1047 {
1063 MsnSoapReq *soap_request; 1048 MsnSoapReq *soap_request;
1064 gchar *body = NULL; 1049 gchar *body = NULL;
1065 gchar *contact_xml = NULL; 1050 gchar *contact_xml = NULL;
1066 gchar *soap_action; 1051
1052 g_return_if_fail(passport != NULL);
1067 /* gchar *escaped_displayname; 1053 /* gchar *escaped_displayname;
1068 1054
1069 1055
1070 if (displayname != NULL) { 1056 if (displayname != NULL) {
1071 escaped_displayname = g_markup_decode_text(displayname, -1); 1057 escaped_displayname = g_markup_decode_text(displayname, -1);
1082 body = g_strdup_printf(MSN_ADD_CONTACT_TEMPLATE, contact_xml); 1068 body = g_strdup_printf(MSN_ADD_CONTACT_TEMPLATE, contact_xml);
1083 1069
1084 g_free(contact_xml); 1070 g_free(contact_xml);
1085 1071
1086 /*build SOAP and POST it*/ 1072 /*build SOAP and POST it*/
1087 soap_action = g_strdup(MSN_CONTACT_ADD_SOAP_ACTION);
1088 1073
1089 soap_request = msn_soap_request_new(MSN_CONTACT_SERVER, 1074 soap_request = msn_soap_request_new(MSN_CONTACT_SERVER,
1090 MSN_ADDRESS_BOOK_POST_URL, 1075 MSN_ADDRESS_BOOK_POST_URL,
1091 soap_action, 1076 MSN_CONTACT_ADD_SOAP_ACTION,
1092 body, 1077 body,
1093 state, 1078 state,
1094 msn_add_contact_read_cb, 1079 msn_add_contact_read_cb,
1095 msn_add_contact_written_cb, 1080 msn_add_contact_written_cb,
1096 msn_contact_connect_init); 1081 msn_contact_connect_init);
1097 msn_soap_post(contact->soapconn,soap_request); 1082 msn_soap_post(contact->soapconn,soap_request);
1098 1083
1099 g_free(soap_action);
1100 g_free(body); 1084 g_free(body);
1101 } 1085 }
1102 1086
1103 static gboolean 1087 static gboolean
1104 msn_add_contact_to_group_read_cb(MsnSoapConn *soapconn) 1088 msn_add_contact_to_group_read_cb(MsnSoapConn *soapconn)
1163 const char *passport, const char *groupId) 1147 const char *passport, const char *groupId)
1164 { 1148 {
1165 MsnSoapReq *soap_request; 1149 MsnSoapReq *soap_request;
1166 MsnUserList *userlist; 1150 MsnUserList *userlist;
1167 MsnUser *user; 1151 MsnUser *user;
1168 gchar *body = NULL, *soap_action, *contact_xml; 1152 gchar *body = NULL, *contact_xml;
1169 1153
1170 g_return_if_fail(passport != NULL); 1154 g_return_if_fail(passport != NULL);
1171 g_return_if_fail(groupId != NULL); 1155 g_return_if_fail(groupId != NULL);
1172 1156
1173 g_return_if_fail(contact != NULL); 1157 g_return_if_fail(contact != NULL);
1212 1196
1213 body = g_strdup_printf(MSN_ADD_CONTACT_GROUP_TEMPLATE, groupId, contact_xml); 1197 body = g_strdup_printf(MSN_ADD_CONTACT_GROUP_TEMPLATE, groupId, contact_xml);
1214 g_free(contact_xml); 1198 g_free(contact_xml);
1215 1199
1216 /*build SOAP and POST it*/ 1200 /*build SOAP and POST it*/
1217 soap_action = g_strdup(MSN_ADD_CONTACT_GROUP_SOAP_ACTION);
1218 1201
1219 soap_request = msn_soap_request_new(MSN_CONTACT_SERVER, 1202 soap_request = msn_soap_request_new(MSN_CONTACT_SERVER,
1220 MSN_ADDRESS_BOOK_POST_URL, 1203 MSN_ADDRESS_BOOK_POST_URL,
1221 soap_action, 1204 MSN_ADD_CONTACT_GROUP_SOAP_ACTION,
1222 body, 1205 body,
1223 state, 1206 state,
1224 msn_add_contact_to_group_read_cb, 1207 msn_add_contact_to_group_read_cb,
1225 msn_add_contact_to_group_written_cb, 1208 msn_add_contact_to_group_written_cb,
1226 msn_contact_connect_init); 1209 msn_contact_connect_init);
1227 msn_soap_post(contact->soapconn,soap_request); 1210 msn_soap_post(contact->soapconn,soap_request);
1228 1211
1229 g_free(soap_action);
1230 g_free(body); 1212 g_free(body);
1231 } 1213 }
1232 1214
1233 1215
1234 1216
1338 { 1320 {
1339 MsnSoapReq *soap_request; 1321 MsnSoapReq *soap_request;
1340 MsnUserList * userlist; 1322 MsnUserList * userlist;
1341 MsnUser *user; 1323 MsnUser *user;
1342 MsnCallbackState *state; 1324 MsnCallbackState *state;
1343 gchar *body = NULL, *soap_action, *contact_id_xml; 1325 gchar *body = NULL, *contact_id_xml;
1344 const gchar *groupId; 1326 const gchar *groupId;
1345 1327
1346 g_return_if_fail(passport != NULL); 1328 g_return_if_fail(passport != NULL);
1347 g_return_if_fail(group_name != NULL); 1329 g_return_if_fail(group_name != NULL);
1348 g_return_if_fail(contact != NULL); 1330 g_return_if_fail(contact != NULL);
1373 1355
1374 state = msn_callback_state_new(); 1356 state = msn_callback_state_new();
1375 msn_callback_state_set_who(state, passport); 1357 msn_callback_state_set_who(state, passport);
1376 msn_callback_state_set_guid(state, groupId); 1358 msn_callback_state_set_guid(state, groupId);
1377 msn_callback_state_set_old_group_name(state, group_name); 1359 msn_callback_state_set_old_group_name(state, group_name);
1378 1360
1379 contact_id_xml = g_strdup_printf(MSN_CONTACT_ID_XML, user->uid); 1361 contact_id_xml = g_strdup_printf(MSN_CONTACT_ID_XML, user->uid);
1380 body = g_strdup_printf(MSN_CONTACT_DEL_GROUP_TEMPLATE, contact_id_xml, groupId); 1362 body = g_strdup_printf(MSN_CONTACT_DEL_GROUP_TEMPLATE, contact_id_xml, groupId);
1381 g_free(contact_id_xml); 1363 g_free(contact_id_xml);
1382 1364
1383 /*build SOAP and POST it*/ 1365 /*build SOAP and POST it*/
1384 soap_action = g_strdup(MSN_CONTACT_DEL_GROUP_SOAP_ACTION);
1385
1386 soap_request = msn_soap_request_new(MSN_CONTACT_SERVER, 1366 soap_request = msn_soap_request_new(MSN_CONTACT_SERVER,
1387 MSN_ADDRESS_BOOK_POST_URL, 1367 MSN_ADDRESS_BOOK_POST_URL,
1388 soap_action, 1368 MSN_CONTACT_DEL_GROUP_SOAP_ACTION,
1389 body, 1369 body,
1390 state, 1370 state,
1391 msn_del_contact_from_group_read_cb, 1371 msn_del_contact_from_group_read_cb,
1392 msn_del_contact_from_group_written_cb, 1372 msn_del_contact_from_group_written_cb,
1393 msn_contact_connect_init); 1373 msn_contact_connect_init);
1394 msn_soap_post(contact->soapconn,soap_request); 1374 msn_soap_post(contact->soapconn,soap_request);
1395 1375
1396 g_free(soap_action);
1397 g_free(body); 1376 g_free(body);
1398 } 1377 }
1399 1378
1400 1379
1401 static gboolean 1380 static gboolean