📄 buddy.c
字号:
if(child2->type != XMLNODE_TYPE_TAG) continue; text2 = xmlnode_get_data(child2); if(text2 && !strcmp(child2->name, "ORGNAME")) { g_string_append_printf(info_text, "<b>%s:</b> %s<br/>", _("Organization Name"), text2); } else if(text2 && !strcmp(child2->name, "ORGUNIT")) { g_string_append_printf(info_text, "<b>%s:</b> %s<br/>", _("Organization Unit"), text2); } g_free(text2); } } else if(text && !strcmp(child->name, "TITLE")) { g_string_append_printf(info_text, "<b>%s:</b> %s<br/>", _("Title"), text); } else if(text && !strcmp(child->name, "ROLE")) { g_string_append_printf(info_text, "<b>%s:</b> %s<br/>", _("Role"), text); } else if(text && !strcmp(child->name, "DESC")) { g_string_append_printf(info_text, "<b>%s:</b> %s<br/>", _("Description"), text); } else if(!strcmp(child->name, "PHOTO") || !strcmp(child->name, "LOGO")) { char *bintext = NULL; xmlnode *binval; if( ((binval = xmlnode_get_child(child, "BINVAL")) && (bintext = xmlnode_get_data(binval))) || (bintext = xmlnode_get_data(child))) { gsize size; guchar *data; int i; unsigned char hashval[20]; char *p, hash[41]; gboolean photo = (strcmp(child->name, "PHOTO") == 0); data = purple_base64_decode(bintext, &size); if (data) { jbi->vcard_imgids = g_slist_prepend(jbi->vcard_imgids, GINT_TO_POINTER(purple_imgstore_add_with_id(g_memdup(data, size), size, "logo.png"))); g_string_append_printf(info_text, "<b>%s:</b> <img id='%d'><br/>", photo ? _("Photo") : _("Logo"), GPOINTER_TO_INT(jbi->vcard_imgids->data)); purple_cipher_digest_region("sha1", (guchar *)data, size, sizeof(hashval), hashval, NULL); p = hash; for(i=0; i<20; i++, p+=2) snprintf(p, 3, "%02x", hashval[i]); purple_buddy_icons_set_for_user(js->gc->account, bare_jid, data, size, hash); g_free(bintext); } } } g_free(text); } } jbi->vcard_text = purple_strdup_withhtml(info_text->str); g_string_free(info_text, TRUE); g_free(bare_jid); jabber_buddy_info_show_if_ready(jbi);}static void jabber_buddy_info_resource_free(gpointer data){ JabberBuddyInfoResource *jbri = data; g_free(jbri);}static void jabber_version_parse(JabberStream *js, xmlnode *packet, gpointer data){ JabberBuddyInfo *jbi = data; const char *type, *id, *from; xmlnode *query; char *resource_name; g_return_if_fail(jbi != NULL); type = xmlnode_get_attrib(packet, "type"); id = xmlnode_get_attrib(packet, "id"); from = xmlnode_get_attrib(packet, "from"); jabber_buddy_info_remove_id(jbi, id); if(!from) return; resource_name = jabber_get_resource(from); if(resource_name) { if(type && !strcmp(type, "result")) { if((query = xmlnode_get_child(packet, "query"))) { JabberBuddyResource *jbr = jabber_buddy_find_resource(jbi->jb, resource_name); if(jbr) { xmlnode *node; if((node = xmlnode_get_child(query, "name"))) { jbr->client.name = xmlnode_get_data(node); } if((node = xmlnode_get_child(query, "version"))) { jbr->client.version = xmlnode_get_data(node); } if((node = xmlnode_get_child(query, "os"))) { jbr->client.os = xmlnode_get_data(node); } } } } g_free(resource_name); } jabber_buddy_info_show_if_ready(jbi);}static void jabber_last_parse(JabberStream *js, xmlnode *packet, gpointer data){ JabberBuddyInfo *jbi = data; xmlnode *query; char *resource_name; const char *type, *id, *from, *seconds; g_return_if_fail(jbi != NULL); type = xmlnode_get_attrib(packet, "type"); id = xmlnode_get_attrib(packet, "id"); from = xmlnode_get_attrib(packet, "from"); jabber_buddy_info_remove_id(jbi, id); if(!from) return; resource_name = jabber_get_resource(from); if(resource_name) { if(type && !strcmp(type, "result")) { if((query = xmlnode_get_child(packet, "query"))) { seconds = xmlnode_get_attrib(query, "seconds"); if(seconds) { char *end = NULL; long sec = strtol(seconds, &end, 10); if(end != seconds) { JabberBuddyInfoResource *jbir = g_hash_table_lookup(jbi->resources, resource_name); if(jbir) { jbir->idle_seconds = sec; } } } } } g_free(resource_name); } jabber_buddy_info_show_if_ready(jbi);}void jabber_buddy_remove_all_pending_buddy_info_requests(JabberStream *js){ if (js->pending_buddy_info_requests) { JabberBuddyInfo *jbi; GSList *l = js->pending_buddy_info_requests; while (l) { jbi = l->data; g_slist_free(jbi->ids); jabber_buddy_info_destroy(jbi); l = l->next; } g_slist_free(js->pending_buddy_info_requests); js->pending_buddy_info_requests = NULL; }}static gboolean jabber_buddy_get_info_timeout(gpointer data){ JabberBuddyInfo *jbi = data; /* remove the pending callbacks */ while(jbi->ids) { char *id = jbi->ids->data; jabber_iq_remove_callback_by_id(jbi->js, id); jbi->ids = g_slist_remove(jbi->ids, id); g_free(id); } jbi->js->pending_buddy_info_requests = g_slist_remove(jbi->js->pending_buddy_info_requests, jbi); jbi->timeout_handle = 0; jabber_buddy_info_show_if_ready(jbi); return FALSE;}static gboolean _client_is_blacklisted(JabberBuddyResource *jbr, const char *ns){ /* can't be blacklisted if we don't know what you're running yet */ if(!jbr->client.name) return FALSE; if(!strcmp(ns, "jabber:iq:last")) { if(!strcmp(jbr->client.name, "Trillian")) { if(!strcmp(jbr->client.version, "3.1.0.121")) { /* verified by nwalp 2007/05/09 */ return TRUE; } } } return FALSE;}static void jabber_buddy_get_info_for_jid(JabberStream *js, const char *jid){ JabberIq *iq; xmlnode *vcard; GList *resources; JabberBuddy *jb; JabberBuddyInfo *jbi; jb = jabber_buddy_find(js, jid, TRUE); /* invalid JID */ if(!jb) return; jbi = g_new0(JabberBuddyInfo, 1); jbi->jid = g_strdup(jid); jbi->js = js; jbi->jb = jb; jbi->resources = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, jabber_buddy_info_resource_free); iq = jabber_iq_new(js, JABBER_IQ_GET); xmlnode_set_attrib(iq->node, "to", jid); vcard = xmlnode_new_child(iq->node, "vCard"); xmlnode_set_namespace(vcard, "vcard-temp"); jabber_iq_set_callback(iq, jabber_vcard_parse, jbi); jbi->ids = g_slist_prepend(jbi->ids, g_strdup(iq->id)); jabber_iq_send(iq); for(resources = jb->resources; resources; resources = resources->next) { JabberBuddyResource *jbr = resources->data; JabberBuddyInfoResource *jbir; char *full_jid; if ((strchr(jid, '/') == NULL) && (jbr->name != NULL)) { full_jid = g_strdup_printf("%s/%s", jid, jbr->name); } else { full_jid = g_strdup(jid); } if (jbr->name != NULL) { jbir = g_new0(JabberBuddyInfoResource, 1); g_hash_table_insert(jbi->resources, g_strdup(jbr->name), jbir); } if(!jbr->client.name) { iq = jabber_iq_new_query(js, JABBER_IQ_GET, "jabber:iq:version"); xmlnode_set_attrib(iq->node, "to", full_jid); jabber_iq_set_callback(iq, jabber_version_parse, jbi); jbi->ids = g_slist_prepend(jbi->ids, g_strdup(iq->id)); jabber_iq_send(iq); } /* this is to fix the feeling of irritation I get when trying * to get info on a friend running Trillian, which doesn't * respond (with an error or otherwise) to jabber:iq:last * requests. There are a number of Trillian users in my * office. */ if(!_client_is_blacklisted(jbr, "jabber:iq:last")) { iq = jabber_iq_new_query(js, JABBER_IQ_GET, "jabber:iq:last"); xmlnode_set_attrib(iq->node, "to", full_jid); jabber_iq_set_callback(iq, jabber_last_parse, jbi); jbi->ids = g_slist_prepend(jbi->ids, g_strdup(iq->id)); jabber_iq_send(iq); } g_free(full_jid); } js->pending_buddy_info_requests = g_slist_prepend(js->pending_buddy_info_requests, jbi); jbi->timeout_handle = purple_timeout_add(30000, jabber_buddy_get_info_timeout, jbi);}void jabber_buddy_get_info(PurpleConnection *gc, const char *who){ JabberStream *js = gc->proto_data; char *bare_jid = jabber_get_bare_jid(who); if(bare_jid) { jabber_buddy_get_info_for_jid(js, bare_jid); g_free(bare_jid); }}void jabber_buddy_get_info_chat(PurpleConnection *gc, int id, const char *resource){ JabberStream *js = gc->proto_data; JabberChat *chat = jabber_chat_find_by_id(js, id); char *full_jid; if(!chat) return; full_jid = g_strdup_printf("%s@%s/%s", chat->room, chat->server, resource); jabber_buddy_get_info_for_jid(js, full_jid); g_free(full_jid);}static void jabber_buddy_set_invisibility(JabberStream *js, const char *who, gboolean invisible){ PurplePresence *gpresence; PurpleAccount *account; PurpleStatus *status; JabberBuddy *jb = jabber_buddy_find(js, who, TRUE); xmlnode *presence; JabberBuddyState state; char *msg; int priority; account = purple_connection_get_account(js->gc); gpresence = purple_account_get_presence(account); status = purple_presence_get_active_status(gpresence); purple_status_to_jabber(status, &state, &msg, &priority); presence = jabber_presence_create(state, msg, priority); g_free(msg); xmlnode_set_attrib(presence, "to", who); if(invisible) { xmlnode_set_attrib(presence, "type", "invisible"); jb->invisible |= JABBER_INVIS_BUDDY; } else { jb->invisible &= ~JABBER_INVIS_BUDDY; } jabber_send(js, presence); xmlnode_free(presence);}static void jabber_buddy_make_invisible(PurpleBlistNode *node, gpointer data){ PurpleBuddy *buddy; PurpleConnection *gc; JabberStream *js; g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node)); buddy = (PurpleBuddy *) node; gc = purple_account_get_connection(buddy->account); js = gc->proto_data; jabber_buddy_set_invisibility(js, buddy->name, TRUE);}static void jabber_buddy_make_visible(PurpleBlistNode *node, gpointer data){ PurpleBuddy *buddy; PurpleConnection *gc; JabberStream *js; g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node)); buddy = (PurpleBuddy *) node; gc = purple_account_get_connection(buddy->account); js = gc->proto_data; jabber_buddy_set_invisibility(js, buddy->name, FALSE);}static void jabber_buddy_cancel_presence_notification(PurpleBlistNode *node, gpointer data){ PurpleBuddy *buddy; PurpleConnection *gc; JabberStream *js; g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node)); buddy = (PurpleBuddy *) node; gc = purple_account_get_connection(buddy->account); js = gc->proto_data; /* I wonder if we should prompt the user before doing this */ jabber_presence_subscription_set(js, buddy->name, "unsubscribed");}static void jabber_buddy_rerequest_auth(PurpleBlistNode *node, gpointer data){ PurpleBuddy *buddy; PurpleConnection *gc; JabberStream *js; g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node)); buddy = (PurpleBuddy *) node; gc = purple_account_get_connection(buddy->account); js = gc->proto_data; jabber_presence_subscription_set(js, buddy->name, "subscribe");}static void jabber_buddy_unsubscribe(PurpleBlistNode *node, gpointer data){ PurpleBuddy *buddy; PurpleConnection *gc; JabberStream *js; g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node)); buddy = (PurpleBuddy *) node; gc = purple_account_get_connection(buddy->account); js = gc->proto_data; jabber_presence_subscription_set(js, buddy->name, "unsubscribe");}static GList *jabber_buddy_menu(PurpleBuddy *buddy){ PurpleConnection *gc = purple_account_get_connection(buddy->account); JabberStream *js = gc->proto_data; JabberBuddy *jb = jabber_buddy_find(js, buddy->name, TRUE); GList *m = NULL; PurpleMenuAction *act; if(!jb) return m; /* XXX: fix the NOT ME below */ if(js->protocol_version == JABBER_PROTO_0_9 /* && NOT ME */) { if(jb->invisible & JABBER_INVIS_BUDDY) { act = purple_menu_action_new(_("Un-hide From"), PURPLE_CALLBACK(jabber_buddy_make_visible), NULL, NULL); } else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -