# HG changeset patch # User Mark Doliner # Date 1229932266 0 # Node ID 0700833f0c5d18bc718d951f789e3f14be27b11a # Parent 95c9c306d5820b4100c20827a04cda848b011be1 Commit patch #7670: Implement xep-0191 (simple blocking) for jabber protocols from Vijay Raghunathan (a co-worker of mine). We're testing this at Meebo and it seems to work ok. Closes #7670. diff -r 95c9c306d582 -r 0700833f0c5d ChangeLog --- a/ChangeLog Sun Dec 21 18:01:37 2008 +0000 +++ b/ChangeLog Mon Dec 22 07:51:06 2008 +0000 @@ -7,6 +7,9 @@ * Don't ignore namespace information when parsing XMPP data. (Michal Witkowski) + XMPP: + * Support for XEP-0191 blocking. (Vijay Raghunathan) + version 2.5.3 (12/20/2008): libpurple: * The Buddy State Notification plugin no longer prints duplicate diff -r 95c9c306d582 -r 0700833f0c5d libpurple/protocols/jabber/disco.c --- a/libpurple/protocols/jabber/disco.c Sun Dec 21 18:01:37 2008 +0000 +++ b/libpurple/protocols/jabber/disco.c Mon Dec 22 07:51:06 2008 +0000 @@ -355,6 +355,11 @@ jabber_adhoc_server_get_list(js); } + /* If the server supports blocking, request the block list */ + if (js->server_caps & JABBER_CAP_BLOCKING) { + jabber_request_block_list(js); + } + /* If there are manually specified bytestream proxies, query them */ ft_proxies = purple_account_get_string(js->gc->account, "ft_proxies", NULL); if (ft_proxies) { @@ -454,6 +459,8 @@ jabber_google_roster_init(js); } else if (!strcmp("http://jabber.org/protocol/commands", var)) { js->server_caps |= JABBER_CAP_ADHOC; + } else if (!strcmp("urn:xmpp:blocking", var)) { + js->server_caps |= JABBER_CAP_BLOCKING; } } diff -r 95c9c306d582 -r 0700833f0c5d libpurple/protocols/jabber/jabber.c --- a/libpurple/protocols/jabber/jabber.c Sun Dec 21 18:01:37 2008 +0000 +++ b/libpurple/protocols/jabber/jabber.c Mon Dec 22 07:51:06 2008 +0000 @@ -31,6 +31,7 @@ #include "message.h" #include "notify.h" #include "pluginpref.h" +#include "privacy.h" #include "proxy.h" #include "prpl.h" #include "request.h" @@ -1454,6 +1455,106 @@ js->idle = idle ? time(NULL) - idle : idle; } +static void jabber_blocklist_parse(JabberStream *js, xmlnode *packet, gpointer data) +{ + xmlnode *blocklist, *item; + PurpleAccount *account; + + blocklist = xmlnode_get_child_with_namespace(packet, + "blocklist", "urn:xmpp:blocking"); + account = purple_connection_get_account(js->gc); + + if (blocklist == NULL) + return; + + item = xmlnode_get_child(blocklist, "item"); + while (item != NULL) { + const char *jid = xmlnode_get_attrib(item, "jid"); + + purple_privacy_deny_add(account, jid, TRUE); + item = xmlnode_get_next_twin(item); + } +} + +void jabber_request_block_list(JabberStream *js) +{ + JabberIq *iq; + xmlnode *blocklist; + + iq = jabber_iq_new(js, JABBER_IQ_GET); + + blocklist = xmlnode_new_child(iq->node, "blocklist"); + xmlnode_set_namespace(blocklist, "urn:xmpp:blocking"); + + jabber_iq_set_callback(iq, jabber_blocklist_parse, NULL); + + jabber_iq_send(iq); +} + +void jabber_add_deny(PurpleConnection *gc, const char *who) +{ + JabberStream *js; + JabberIq *iq; + xmlnode *block, *item; + + js = gc->proto_data; + if (js == NULL) + return; + + if (js->server_caps & JABBER_CAP_GOOGLE_ROSTER) + { + jabber_google_roster_add_deny(gc, who); + return; + } + + if (!(js->server_caps & JABBER_CAP_BLOCKING)) + { + purple_notify_error(NULL, _("Server doesn't support blocking"), + _("Server doesn't support blocking"), NULL); + return; + } + + iq = jabber_iq_new(js, JABBER_IQ_SET); + + block = xmlnode_new_child(iq->node, "block"); + xmlnode_set_namespace(block, "urn:xmpp:blocking"); + + item = xmlnode_new_child(block, "item"); + xmlnode_set_attrib(item, "jid", who); + + jabber_iq_send(iq); +} + +void jabber_rem_deny(PurpleConnection *gc, const char *who) +{ + JabberStream *js; + JabberIq *iq; + xmlnode *unblock, *item; + + js = gc->proto_data; + if (js == NULL) + return; + + if (js->server_caps & JABBER_CAP_GOOGLE_ROSTER) + { + jabber_google_roster_rem_deny(gc, who); + return; + } + + if (!(js->server_caps & JABBER_CAP_BLOCKING)) + return; + + iq = jabber_iq_new(js, JABBER_IQ_SET); + + unblock = xmlnode_new_child(iq->node, "unblock"); + xmlnode_set_namespace(unblock, "urn:xmpp:blocking"); + + item = xmlnode_new_child(unblock, "item"); + xmlnode_set_attrib(item, "jid", who); + + jabber_iq_send(iq); +} + void jabber_add_feature(const char *shortname, const char *namespace, JabberFeatureEnabled cb) { JabberFeature *feat; diff -r 95c9c306d582 -r 0700833f0c5d libpurple/protocols/jabber/jabber.h --- a/libpurple/protocols/jabber/jabber.h Sun Dec 21 18:01:37 2008 +0000 +++ b/libpurple/protocols/jabber/jabber.h Mon Dec 22 07:51:06 2008 +0000 @@ -42,7 +42,8 @@ JABBER_CAP_PING = 1 << 11, JABBER_CAP_ADHOC = 1 << 12, - + JABBER_CAP_BLOCKING = 1 << 13, + JABBER_CAP_RETRIEVED = 1 << 31 } JabberCapabilities; @@ -294,6 +295,9 @@ void jabber_login(PurpleAccount *account); void jabber_close(PurpleConnection *gc); void jabber_idle_set(PurpleConnection *gc, int idle); +void jabber_request_block_list(JabberStream *js); +void jabber_add_deny(PurpleConnection *gc, const char *who); +void jabber_rem_deny(PurpleConnection *gc, const char *who); void jabber_keepalive(PurpleConnection *gc); void jabber_register_gateway(JabberStream *js, const char *gateway); void jabber_register_account(PurpleAccount *account); diff -r 95c9c306d582 -r 0700833f0c5d libpurple/protocols/jabber/libxmpp.c --- a/libpurple/protocols/jabber/libxmpp.c Sun Dec 21 18:01:37 2008 +0000 +++ b/libpurple/protocols/jabber/libxmpp.c Mon Dec 22 07:51:06 2008 +0000 @@ -77,9 +77,9 @@ jabber_roster_remove_buddy, /* remove_buddy */ NULL, /* remove_buddies */ NULL, /* add_permit */ - jabber_google_roster_add_deny, /* add_deny */ + jabber_add_deny, /* add_deny */ NULL, /* rem_permit */ - jabber_google_roster_rem_deny, /* rem_deny */ + jabber_rem_deny, /* rem_deny */ NULL, /* set_permit_deny */ jabber_chat_join, /* join_chat */ NULL, /* reject_chat */