comparison libpurple/protocols/msn/user.c @ 31292:47b6eda87723

propagate from branch 'im.pidgin.pidgin' (head 07d0765c444a097af45c2650f54323afb900a07b) to branch 'im.pidgin.soc.2010.msn-tlc' (head f3998422a4724ab424e4e2328f58fc0504856557)
author masca@cpw.pidgin.im
date Mon, 19 Jul 2010 21:11:32 +0000
parents 56ef12440d52
children 4445ae4215b8
comparison
equal deleted inserted replaced
30698:e874875a74a7 31292:47b6eda87723
19 * 19 *
20 * You should have received a copy of the GNU General Public License 20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software 21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA 22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
23 */ 23 */
24 #include "msn.h" 24
25 #include "internal.h"
26 #include "debug.h"
27 #include "util.h"
28
25 #include "user.h" 29 #include "user.h"
26 #include "slp.h" 30 #include "slp.h"
31
32 static void free_user_endpoint(MsnUserEndpoint *data)
33 {
34 g_free(data->id);
35 g_free(data->name);
36 g_free(data);
37 }
27 38
28 /*new a user object*/ 39 /*new a user object*/
29 MsnUser * 40 MsnUser *
30 msn_user_new(MsnUserList *userlist, const char *passport, 41 msn_user_new(MsnUserList *userlist, const char *passport,
31 const char *friendly_name) 42 const char *friendly_name)
37 user->userlist = userlist; 48 user->userlist = userlist;
38 49
39 msn_user_set_passport(user, passport); 50 msn_user_set_passport(user, passport);
40 msn_user_set_friendly_name(user, friendly_name); 51 msn_user_set_friendly_name(user, friendly_name);
41 52
42 return user; 53 return msn_user_ref(user);
43 } 54 }
44 55
45 /*destroy a user object*/ 56 /*destroy a user object*/
46 void 57 static void
47 msn_user_destroy(MsnUser *user) 58 msn_user_destroy(MsnUser *user)
48 { 59 {
49 g_return_if_fail(user != NULL); 60 g_return_if_fail(user != NULL);
61
62 if (user->refcount > 1) {
63 msn_user_unref(user);
64 return;
65 }
66
67 while (user->endpoints != NULL) {
68 free_user_endpoint(user->endpoints->data);
69 user->endpoints = g_slist_delete_link(user->endpoints, user->endpoints);
70 }
50 71
51 if (user->clientcaps != NULL) 72 if (user->clientcaps != NULL)
52 g_hash_table_destroy(user->clientcaps); 73 g_hash_table_destroy(user->clientcaps);
53 74
54 if (user->group_ids != NULL) 75 if (user->group_ids != NULL)
78 } 99 }
79 g_free(user->statusline); 100 g_free(user->statusline);
80 g_free(user->invite_message); 101 g_free(user->invite_message);
81 102
82 g_free(user); 103 g_free(user);
104 }
105
106 MsnUser *
107 msn_user_ref(MsnUser *user)
108 {
109 g_return_val_if_fail(user != NULL, NULL);
110
111 user->refcount++;
112
113 return user;
114 }
115
116 void
117 msn_user_unref(MsnUser *user)
118 {
119 g_return_if_fail(user != NULL);
120
121 user->refcount--;
122
123 if(user->refcount == 0)
124 msn_user_destroy(user);
83 } 125 }
84 126
85 void 127 void
86 msn_user_update(MsnUser *user) 128 msn_user_update(MsnUser *user)
87 { 129 {
184 gboolean 226 gboolean
185 msn_user_set_friendly_name(MsnUser *user, const char *name) 227 msn_user_set_friendly_name(MsnUser *user, const char *name)
186 { 228 {
187 g_return_val_if_fail(user != NULL, FALSE); 229 g_return_val_if_fail(user != NULL, FALSE);
188 230
231 if (user == user->userlist->session->user)
232 return FALSE;
233
189 if (user->friendly_name && name && (!strcmp(user->friendly_name, name) || 234 if (user->friendly_name && name && (!strcmp(user->friendly_name, name) ||
190 !strcmp(user->passport, name))) 235 !strcmp(user->passport, name)))
191 return FALSE; 236 return FALSE;
192 237
193 g_free(user->friendly_name); 238 g_free(user->friendly_name);
212 { 257 {
213 g_return_if_fail(user != NULL); 258 g_return_if_fail(user != NULL);
214 259
215 g_free(user->uid); 260 g_free(user->uid);
216 user->uid = g_strdup(uid); 261 user->uid = g_strdup(uid);
262 }
263
264 void
265 msn_user_set_endpoint_data(MsnUser *user, const char *input, MsnUserEndpoint *newep)
266 {
267 MsnUserEndpoint *ep;
268 char *endpoint;
269 GSList *l;
270
271 g_return_if_fail(user != NULL);
272 g_return_if_fail(input != NULL);
273
274 endpoint = g_ascii_strdown(input, -1);
275
276 for (l = user->endpoints; l; l = l->next) {
277 ep = l->data;
278 if (g_str_equal(ep->id, endpoint)) {
279 /* We have info about this endpoint! */
280
281 g_free(endpoint);
282
283 if (newep == NULL) {
284 /* Delete it and exit */
285 user->endpoints = g_slist_delete_link(user->endpoints, l);
286 free_user_endpoint(ep);
287 return;
288 }
289
290 /* Break out of our loop and update it */
291 break;
292 }
293 }
294 if (l == NULL) {
295 /* Need to add a new endpoint */
296 ep = g_new0(MsnUserEndpoint, 1);
297 ep->id = endpoint;
298 user->endpoints = g_slist_prepend(user->endpoints, ep);
299 }
300
301 ep->clientid = newep->clientid;
302 ep->extcaps = newep->extcaps;
217 } 303 }
218 304
219 void 305 void
220 msn_user_set_op(MsnUser *user, MsnListOp list_op) 306 msn_user_set_op(MsnUser *user, MsnListOp list_op)
221 { 307 {
404 490
405 user->clientid = clientid; 491 user->clientid = clientid;
406 } 492 }
407 493
408 void 494 void
495 msn_user_set_extcaps(MsnUser *user, guint extcaps)
496 {
497 g_return_if_fail(user != NULL);
498
499 user->extcaps = extcaps;
500 }
501
502 void
409 msn_user_set_network(MsnUser *user, MsnNetwork network) 503 msn_user_set_network(MsnUser *user, MsnNetwork network)
410 { 504 {
411 g_return_if_fail(user != NULL); 505 g_return_if_fail(user != NULL);
412 506
413 user->networkid = network; 507 user->networkid = network;
508 }
509
510 static gboolean
511 buddy_icon_cached(PurpleConnection *gc, MsnObject *obj)
512 {
513 PurpleAccount *account;
514 PurpleBuddy *buddy;
515 const char *old;
516 const char *new;
517
518 g_return_val_if_fail(obj != NULL, FALSE);
519
520 account = purple_connection_get_account(gc);
521
522 buddy = purple_find_buddy(account, msn_object_get_creator(obj));
523 if (buddy == NULL)
524 return FALSE;
525
526 old = purple_buddy_icons_get_checksum_for_user(buddy);
527 new = msn_object_get_sha1(obj);
528
529 if (new == NULL)
530 return FALSE;
531
532 /* If the old and new checksums are the same, and the file actually exists,
533 * then return TRUE */
534 if (old != NULL && !strcmp(old, new))
535 return TRUE;
536
537 return FALSE;
538 }
539
540 static void
541 queue_buddy_icon_request(MsnUser *user)
542 {
543 PurpleAccount *account;
544 MsnObject *obj;
545 GQueue *queue;
546
547 g_return_if_fail(user != NULL);
548
549 account = user->userlist->session->account;
550
551 obj = msn_user_get_object(user);
552
553 if (obj == NULL) {
554 purple_buddy_icons_set_for_user(account, user->passport, NULL, 0, NULL);
555 return;
556 }
557
558 if (!buddy_icon_cached(account->gc, obj)) {
559 MsnUserList *userlist;
560
561 userlist = user->userlist;
562 queue = userlist->buddy_icon_requests;
563
564 if (purple_debug_is_verbose())
565 purple_debug_info("msn", "Queueing buddy icon request for %s (buddy_icon_window = %i)\n",
566 user->passport, userlist->buddy_icon_window);
567
568 g_queue_push_tail(queue, user);
569
570 if (userlist->buddy_icon_window > 0)
571 msn_release_buddy_icon_request(userlist);
572 }
414 } 573 }
415 574
416 void 575 void
417 msn_user_set_object(MsnUser *user, MsnObject *obj) 576 msn_user_set_object(MsnUser *user, MsnObject *obj)
418 { 577 {
421 if (user->msnobj != NULL) 580 if (user->msnobj != NULL)
422 msn_object_destroy(user->msnobj); 581 msn_object_destroy(user->msnobj);
423 582
424 user->msnobj = obj; 583 user->msnobj = obj;
425 584
426 if (user->list_op & MSN_LIST_FL_OP) 585 if (user != user->userlist->session->user && user->list_op & MSN_LIST_FL_OP)
427 msn_queue_buddy_icon_request(user); 586 queue_buddy_icon_request(user);
428 } 587 }
429 588
430 void 589 void
431 msn_user_set_client_caps(MsnUser *user, GHashTable *info) 590 msn_user_set_client_caps(MsnUser *user, GHashTable *info)
432 { 591 {
494 g_return_val_if_fail(user != NULL, 0); 653 g_return_val_if_fail(user != NULL, 0);
495 654
496 return user->clientid; 655 return user->clientid;
497 } 656 }
498 657
658 guint
659 msn_user_get_extcaps(const MsnUser *user)
660 {
661 g_return_val_if_fail(user != NULL, 0);
662
663 return user->extcaps;
664 }
665
666 MsnUserEndpoint *
667 msn_user_get_endpoint_data(MsnUser *user, const char *input)
668 {
669 char *endpoint;
670 GSList *l;
671 MsnUserEndpoint *ep;
672
673 g_return_val_if_fail(user != NULL, NULL);
674 g_return_val_if_fail(input != NULL, NULL);
675
676 endpoint = g_ascii_strdown(input, -1);
677
678 for (l = user->endpoints; l; l = l->next) {
679 ep = l->data;
680 if (g_str_equal(ep->id, endpoint)) {
681 g_free(endpoint);
682 return ep;
683 }
684 }
685
686 g_free(endpoint);
687
688 return NULL;
689 }
690
499 MsnObject * 691 MsnObject *
500 msn_user_get_object(const MsnUser *user) 692 msn_user_get_object(const MsnUser *user)
501 { 693 {
502 g_return_val_if_fail(user != NULL, NULL); 694 g_return_val_if_fail(user != NULL, NULL);
503 695
518 g_return_val_if_fail(user != NULL, NULL); 710 g_return_val_if_fail(user != NULL, NULL);
519 711
520 return user->invite_message; 712 return user->invite_message;
521 } 713 }
522 714
715 gboolean
716 msn_user_is_capable(MsnUser *user, char *endpoint, guint capability, guint extcap)
717 {
718 g_return_val_if_fail(user != NULL, FALSE);
719
720 if (endpoint != NULL) {
721 MsnUserEndpoint *ep = msn_user_get_endpoint_data(user, endpoint);
722 if (ep != NULL)
723 return (ep->clientid & capability) && (ep->extcaps & extcap);
724 else
725 return FALSE;
726 }
727
728 return (user->clientid & capability) && (user->extcaps & extcap);
729 }
730
731 /**************************************************************************
732 * Utility functions
733 **************************************************************************/
734
735 int
736 msn_user_passport_cmp(MsnUser *user, const char *passport)
737 {
738 const char *pass;
739
740 pass = msn_user_get_passport(user);
741
742 return strcmp(pass, purple_normalize_nocase(NULL, passport));
743 }
744
745 gboolean
746 msn_user_is_in_group(MsnUser *user, const char * group_id)
747 {
748 if (user == NULL)
749 return FALSE;
750
751 if (group_id == NULL)
752 return FALSE;
753
754 return (g_list_find_custom(user->group_ids, group_id, (GCompareFunc)strcmp)) != NULL;
755 }
756
757 gboolean
758 msn_user_is_in_list(MsnUser *user, MsnListId list_id)
759 {
760 if (user == NULL)
761 return FALSE;
762
763 return (user->list_op & (1 << list_id));
764 }
765