libpurple/protocols/myspace/myspace.c

branch
soc.2007.msimprpl
changeset 17957
bc5874ed7a09
parent 17956
0b3393767f6d
child 17958
9f809365230b
equal deleted inserted replaced
17956:0b3393767f6d 17957:bc5874ed7a09
755 /* TODO: Free copy cloned from msim_preprocess_incoming(). */ 755 /* TODO: Free copy cloned from msim_preprocess_incoming(). */
756 //XXX msim_msg_free(msg); 756 //XXX msim_msg_free(msg);
757 g_hash_table_destroy(body); 757 g_hash_table_destroy(body);
758 } 758 }
759 759
760 /* Lookup a username by userid, from buddy list.
761 *
762 * @param wanted_uid
763 *
764 * @return Username of wanted_uid, if on blist, or NULL. Static string.
765 *
766 * XXX WARNING: UNKNOWN MEMORY CORRUPTION HERE!
767 */
768 static const gchar *msim_uid2username_from_blist(MsimSession *session, guint wanted_uid)
769 {
770 GSList *buddies, *buddies_head;
771
772 for (buddies = buddies_head = purple_find_buddies(session->account, NULL);
773 buddies;
774 buddies = g_slist_next(buddies))
775 {
776 PurpleBuddy *buddy;
777 guint uid;
778 gchar *name;
779
780 buddy = buddies->data;
781
782 uid = purple_blist_node_get_int(&buddy->node, "uid");
783
784 /* name = buddy->name; */ /* crash */
785 /* name = PURPLE_BLIST_NODE_NAME(&buddy->node); */ /* crash */
786
787 /* XXX Is this right? Memory corruption here somehow. Happens only
788 * when return one of these values. */
789 name = purple_buddy_get_name(buddy); /* crash */
790 /* return name; */ /* crash (with above) */
791
792 /* name = NULL; */ /* no crash */
793 /* return NULL; */ /* no crash (with anything) */
794
795 /* crash =
796 *** glibc detected *** pidgin: realloc(): invalid pointer: 0x0000000000d2aec0 ***
797 ======= Backtrace: =========
798 /lib/libc.so.6(__libc_realloc+0x323)[0x2b7bfc012e03]
799 /usr/lib/libglib-2.0.so.0(g_realloc+0x31)[0x2b7bfba79a41]
800 /usr/lib/libgtk-x11-2.0.so.0(gtk_tree_path_append_index+0x3a)[0x2b7bfa110d5a]
801 /usr/lib/libgtk-x11-2.0.so.0[0x2b7bfa1287dc]
802 /usr/lib/libgtk-x11-2.0.so.0[0x2b7bfa128e56]
803 /usr/lib/libgtk-x11-2.0.so.0[0x2b7bfa128efd]
804 /usr/lib/libglib-2.0.so.0(g_main_context_dispatch+0x1b4)[0x2b7bfba72c84]
805 /usr/lib/libglib-2.0.so.0[0x2b7bfba75acd]
806 /usr/lib/libglib-2.0.so.0(g_main_loop_run+0x1ca)[0x2b7bfba75dda]
807 /usr/lib/libgtk-x11-2.0.so.0(gtk_main+0xa3)[0x2b7bfa0475f3]
808 pidgin(main+0x8be)[0x46b45e]
809 /lib/libc.so.6(__libc_start_main+0xf4)[0x2b7bfbfbf0c4]
810 pidgin(gtk_widget_grab_focus+0x39)[0x429ab9]
811
812 or:
813 *** glibc detected *** /usr/local/bin/pidgin: malloc(): memory corruption (fast): 0x0000000000c10076 ***
814 (gdb) bt
815 #0 0x00002b4074ecd47b in raise () from /lib/libc.so.6
816 #1 0x00002b4074eceda0 in abort () from /lib/libc.so.6
817 #2 0x00002b4074f0453b in __fsetlocking () from /lib/libc.so.6
818 #3 0x00002b4074f0c810 in free () from /lib/libc.so.6
819 #4 0x00002b4074f0d6dd in malloc () from /lib/libc.so.6
820 #5 0x00002b4074974b5b in g_malloc () from /usr/lib/libglib-2.0.so.0
821 #6 0x00002b40749868bf in g_strdup () from /usr/lib/libglib-2.0.so.0
822 #7 0x00002b407810969f in msim_parse (
823 raw=0xd2a910 "\\bm\\100\\f\\3656574\\msg\\|s|0|ss|Offline")
824 at message.c:648
825 #8 0x00002b407810889c in msim_input_cb (gc_uncasted=0xcf92c0,
826 source=<value optimized out>, cond=<value optimized out>) at myspace.c:1478
827
828
829 Why is it crashing in msim_parse()'s g_strdup()?
830 */
831
832
833 purple_debug_info("msim", "msim_uid2username_from_blist: %s's uid=%d (want %d)\n",
834 name, uid, wanted_uid);
835
836 if (uid == wanted_uid)
837 {
838 g_slist_free(buddies_head);
839
840 return name;
841 }
842 }
843
844 g_slist_free(buddies_head);
845 return NULL;
846 }
847
760 /** Preprocess incoming messages, resolving as needed, calling msim_process() when ready to process. 848 /** Preprocess incoming messages, resolving as needed, calling msim_process() when ready to process.
761 * 849 *
762 * TODO: if no uid to resolve, process immediately. if uid, check if know username, 850 * TODO: if no uid to resolve, process immediately. if uid, check if know username,
763 * if so, tag and process immediately, if not, queue, send resolve msg, and process 851 * if so, tag and process immediately, if not, queue, send resolve msg, and process
764 * once get username. 852 * once get username.
768 */ 856 */
769 gboolean msim_preprocess_incoming(MsimSession *session, MsimMessage *msg) 857 gboolean msim_preprocess_incoming(MsimSession *session, MsimMessage *msg)
770 { 858 {
771 if (msim_msg_get(msg, "bm") && msim_msg_get(msg, "f")) 859 if (msim_msg_get(msg, "bm") && msim_msg_get(msg, "f"))
772 { 860 {
861 guint uid;
862 const gchar *username;
863
773 /* 'f' = userid message is from, in buddy messages */ 864 /* 'f' = userid message is from, in buddy messages */
774 865 uid = msim_msg_get_integer(msg, "f");
775 /* TODO XXX IMPORTANT TODO: if know uid->username mapping already, process immediately */ 866
776 /* TODO XXX Currently, uid is ALWAYS explicitly resolved, on each message, by sending 867 /* TODO: Make caching work. Currently it is commented out because
777 * a getuserbyuserid message. This is very wasteful. TODO: Be frugal. 868 * it crashes for unknown reasons, memory realloc error. */
778 */ 869 //#define _MSIM_UID2USERNAME_WORKS
779 870 #ifdef _MSIM_UID2USERNAME_WORKS
780 /* Send lookup request. */ 871 username = msim_uid2username_from_blist(session, uid);
781 /* XXX: where is msim_msg_get_string() freed? make _strdup and _nonstrdup. */ 872 #else
782 purple_debug_info("msim", "msim_incoming: sending lookup, setting up callback\n"); 873 username = NULL;
783 msim_lookup_user(session, msim_msg_get_string(msg, "f"), msim_incoming_resolved, msim_msg_clone(msg)); 874 #endif
784 875
785 /* indeterminate */ 876 if (username)
786 return TRUE; 877 {
878 /* Know username already, use it. */
879 purple_debug_info("msim", "msim_preprocess_incoming: tagging with _username=%s\n",
880 username);
881 msg = msim_msg_append(msg, "_username", MSIM_TYPE_STRING, g_strdup(username));
882 return msim_process(session, msg);
883
884 } else {
885 /* Send lookup request. */
886 /* XXX: where is msim_msg_get_string() freed? make _strdup and _nonstrdup. */
887 purple_debug_info("msim", "msim_incoming: sending lookup, setting up callback\n");
888 msim_lookup_user(session, msim_msg_get_string(msg, "f"), msim_incoming_resolved, msim_msg_clone(msg));
889
890 /* indeterminate */
891 return TRUE;
892 }
787 } else { 893 } else {
788 /* Nothing to resolve - send directly to processing. */ 894 /* Nothing to resolve - send directly to processing. */
789 return msim_process(session, msg); 895 return msim_process(session, msg);
790 } 896 }
791 } 897 }
896 1002
897 /* TODO: implement a better hash-like interface, and use it. */ 1003 /* TODO: implement a better hash-like interface, and use it. */
898 username = g_hash_table_lookup(body, "UserName"); 1004 username = g_hash_table_lookup(body, "UserName");
899 if (username) 1005 if (username)
900 { 1006 {
901 /* TODO: permanently associated with blist item, if in buddy in blist, 1007 PurpleBuddy *buddy;
902 * See purple_blist_node_set_int(). */ 1008 gchar *uid;
903 g_hash_table_insert(session->user_lookup_cache, g_strdup(username), body); 1009
1010 uid = g_hash_table_lookup(body, "UserID");
1011 g_assert(uid);
1012
1013 /* Associate uid with user on buddy list. This is saved to blist.xml. */
1014
1015 purple_debug_info("msim", "associating %d with %s\n", uid, username);
1016
1017 buddy = purple_find_buddy(session->account, username);
1018 if (buddy)
1019 {
1020 purple_blist_node_set_int(&buddy->node, "uid", atoi(uid));
1021 }
904 } else { 1022 } else {
905 purple_debug_info("msim", 1023 purple_debug_info("msim",
906 "msim_process_reply: not caching body, no UserName\n"); 1024 "msim_process_reply: not caching body, no UserName\n");
907 } 1025 }
908 1026
1455 1573
1456 session->magic = MSIM_SESSION_STRUCT_MAGIC; 1574 session->magic = MSIM_SESSION_STRUCT_MAGIC;
1457 session->account = acct; 1575 session->account = acct;
1458 session->gc = purple_account_get_connection(acct); 1576 session->gc = purple_account_get_connection(acct);
1459 session->fd = -1; 1577 session->fd = -1;
1578
1579 /* TODO: Remove. */
1460 session->user_lookup_cb = g_hash_table_new_full(g_direct_hash, 1580 session->user_lookup_cb = g_hash_table_new_full(g_direct_hash,
1461 g_direct_equal, NULL, NULL); /* do NOT free function pointers! (values) */ 1581 g_direct_equal, NULL, NULL); /* do NOT free function pointers! (values) */
1462 session->user_lookup_cb_data = g_hash_table_new_full(g_direct_hash, 1582 session->user_lookup_cb_data = g_hash_table_new_full(g_direct_hash,
1463 g_direct_equal, NULL, NULL);/* TODO: we don't know what the values are, 1583 g_direct_equal, NULL, NULL);/* TODO: we don't know what the values are,
1464 they could be integers inside gpointers 1584 they could be integers inside gpointers
1465 or strings, so I don't freed them. 1585 or strings, so I don't freed them.
1466 Figure this out, once free cache. */ 1586 Figure this out, once free cache. */
1467 session->user_lookup_cache = g_hash_table_new_full(g_str_hash, g_str_equal, 1587 session->user_lookup_cache = g_hash_table_new_full(g_str_hash, g_str_equal,
1468 g_free, (GDestroyNotify)g_hash_table_destroy); 1588 g_free, (GDestroyNotify)g_hash_table_destroy);
1589
1469 session->rxoff = 0; 1590 session->rxoff = 0;
1470 session->rxbuf = g_new0(gchar, MSIM_READ_BUF_SIZE); 1591 session->rxbuf = g_new0(gchar, MSIM_READ_BUF_SIZE);
1471 session->next_rid = 1; 1592 session->next_rid = 1;
1472 1593
1473 return session; 1594 return session;
1485 session->magic = -1; 1606 session->magic = -1;
1486 1607
1487 g_free(session->rxbuf); 1608 g_free(session->rxbuf);
1488 g_free(session->userid); 1609 g_free(session->userid);
1489 1610
1611 /* TODO: Remove. */
1612 g_hash_table_destroy(session->user_lookup_cb);
1613 g_hash_table_destroy(session->user_lookup_cb_data);
1614 g_hash_table_destroy(session->user_lookup_cache);
1615
1490 g_free(session); 1616 g_free(session);
1491 } 1617 }
1492 1618
1493 1619
1494 1620

mercurial