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