/src/pidgin/libpurple/protocols/jabber/pep.c
Line | Count | Source |
1 | | /* |
2 | | * purple - Jabber Protocol Plugin |
3 | | * |
4 | | * Purple is the legal property of its developers, whose names are too numerous |
5 | | * to list here. Please refer to the COPYRIGHT file distributed with this |
6 | | * source distribution. |
7 | | * |
8 | | * This program is free software; you can redistribute it and/or modify |
9 | | * it under the terms of the GNU General Public License as published by |
10 | | * the Free Software Foundation; either version 2 of the License, or |
11 | | * (at your option) any later version. |
12 | | * |
13 | | * This program is distributed in the hope that it will be useful, |
14 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 | | * GNU General Public License for more details. |
17 | | * |
18 | | * You should have received a copy of the GNU General Public License |
19 | | * along with this program; if not, write to the Free Software |
20 | | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA |
21 | | * |
22 | | */ |
23 | | |
24 | | #include "internal.h" |
25 | | |
26 | | #include "pep.h" |
27 | | #include "iq.h" |
28 | | #include <string.h> |
29 | | #include "useravatar.h" |
30 | | #include "usermood.h" |
31 | | #include "usernick.h" |
32 | | #include "usertune.h" |
33 | | |
34 | | static GHashTable *pep_handlers = NULL; |
35 | | |
36 | 0 | void jabber_pep_init(void) { |
37 | 0 | if(!pep_handlers) { |
38 | 0 | pep_handlers = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); |
39 | | |
40 | | /* register PEP handlers */ |
41 | 0 | jabber_avatar_init(); |
42 | 0 | jabber_mood_init(); |
43 | 0 | jabber_tune_init(); |
44 | 0 | jabber_nick_init(); |
45 | 0 | } |
46 | 0 | } |
47 | | |
48 | 0 | void jabber_pep_uninit(void) { |
49 | | /* any PEP handlers that need to clean things up go here. The standard |
50 | | * cleanup of removing the handler and feature are handled here and by |
51 | | * jabber_features_destroy() in jabber.c |
52 | | */ |
53 | 0 | g_hash_table_destroy(pep_handlers); |
54 | 0 | pep_handlers = NULL; |
55 | 0 | } |
56 | | |
57 | 0 | void jabber_pep_init_actions(GList **m) { |
58 | | /* register the PEP-specific actions */ |
59 | 0 | jabber_nick_init_action(m); |
60 | 0 | } |
61 | | |
62 | 0 | void jabber_pep_register_handler(const char *xmlns, JabberPEPHandler handlerfunc) { |
63 | 0 | gchar *notifyns = g_strdup_printf("%s+notify", xmlns); |
64 | 0 | jabber_add_feature(notifyns, NULL); /* receiving PEPs is always supported */ |
65 | 0 | g_free(notifyns); |
66 | 0 | g_hash_table_replace(pep_handlers, g_strdup(xmlns), handlerfunc); |
67 | 0 | } |
68 | | |
69 | | static void |
70 | | do_pep_iq_request_item_callback(JabberStream *js, const char *from, |
71 | | JabberIqType type, const char *id, |
72 | | xmlnode *packet, gpointer data) |
73 | 0 | { |
74 | 0 | xmlnode *pubsub; |
75 | 0 | xmlnode *items = NULL; |
76 | 0 | JabberPEPHandler *cb = data; |
77 | |
|
78 | 0 | if (type == JABBER_IQ_RESULT) { |
79 | 0 | pubsub = xmlnode_get_child_with_namespace(packet, "pubsub", "http://jabber.org/protocol/pubsub"); |
80 | 0 | if(pubsub) |
81 | 0 | items = xmlnode_get_child(pubsub, "items"); |
82 | 0 | } |
83 | |
|
84 | 0 | cb(js, from, items); |
85 | 0 | } |
86 | | |
87 | 0 | void jabber_pep_request_item(JabberStream *js, const char *to, const char *node, const char *id, JabberPEPHandler cb) { |
88 | 0 | JabberIq *iq = jabber_iq_new(js, JABBER_IQ_GET); |
89 | 0 | xmlnode *pubsub, *items; |
90 | |
|
91 | 0 | if (to) |
92 | 0 | xmlnode_set_attrib(iq->node, "to", to); |
93 | |
|
94 | 0 | pubsub = xmlnode_new_child(iq->node,"pubsub"); |
95 | 0 | xmlnode_set_namespace(pubsub, "http://jabber.org/protocol/pubsub"); |
96 | |
|
97 | 0 | items = xmlnode_new_child(pubsub, "items"); |
98 | 0 | xmlnode_set_attrib(items,"node",node); |
99 | |
|
100 | 0 | if (id) { |
101 | 0 | xmlnode *item = xmlnode_new_child(items, "item"); |
102 | 0 | xmlnode_set_attrib(item, "id", id); |
103 | 0 | } else |
104 | | /* Most recent item */ |
105 | 0 | xmlnode_set_attrib(items, "max_items", "1"); |
106 | |
|
107 | 0 | jabber_iq_set_callback(iq,do_pep_iq_request_item_callback,(gpointer)cb); |
108 | |
|
109 | 0 | jabber_iq_send(iq); |
110 | 0 | } |
111 | | |
112 | 0 | gboolean jabber_pep_namespace_only_when_pep_enabled_cb(JabberStream *js, const gchar *namespace) { |
113 | 0 | return js->pep; |
114 | 0 | } |
115 | | |
116 | 0 | void jabber_handle_event(JabberMessage *jm) { |
117 | | /* this may be called even when the own server doesn't support pep! */ |
118 | 0 | JabberPEPHandler *jph; |
119 | 0 | GList *itemslist; |
120 | 0 | char *jid; |
121 | |
|
122 | 0 | if (jm->type != JABBER_MESSAGE_EVENT) |
123 | 0 | return; |
124 | | |
125 | 0 | jid = jabber_get_bare_jid(jm->from); |
126 | |
|
127 | 0 | for(itemslist = jm->eventitems; itemslist; itemslist = itemslist->next) { |
128 | 0 | xmlnode *items = (xmlnode*)itemslist->data; |
129 | 0 | const char *nodename = xmlnode_get_attrib(items,"node"); |
130 | |
|
131 | 0 | if(nodename && (jph = g_hash_table_lookup(pep_handlers, nodename))) |
132 | 0 | jph(jm->js, jid, items); |
133 | 0 | } |
134 | | |
135 | | /* discard items we don't have a handler for */ |
136 | 0 | g_free(jid); |
137 | 0 | } |
138 | | |
139 | | void jabber_pep_delete_node(JabberStream *js, const gchar *node) |
140 | 0 | { |
141 | 0 | JabberIq *iq; |
142 | 0 | xmlnode *pubsub, *del; |
143 | |
|
144 | 0 | g_return_if_fail(node != NULL); |
145 | 0 | g_return_if_fail(js->pep); |
146 | | |
147 | 0 | iq = jabber_iq_new(js, JABBER_IQ_SET); |
148 | |
|
149 | 0 | pubsub = xmlnode_new_child(iq->node, "pubsub"); |
150 | 0 | xmlnode_set_namespace(pubsub, "http://jabber.org/protocol/pubsub#owner"); |
151 | |
|
152 | 0 | del = xmlnode_new_child(pubsub, "delete"); |
153 | 0 | xmlnode_set_attrib(del, "node", node); |
154 | |
|
155 | 0 | jabber_iq_send(iq); |
156 | 0 | } |
157 | | |
158 | 0 | void jabber_pep_publish(JabberStream *js, xmlnode *publish) { |
159 | 0 | JabberIq *iq; |
160 | 0 | xmlnode *pubsub; |
161 | |
|
162 | 0 | if(js->pep != TRUE) { |
163 | | /* ignore when there's no PEP support on the server */ |
164 | 0 | xmlnode_free(publish); |
165 | 0 | return; |
166 | 0 | } |
167 | | |
168 | 0 | iq = jabber_iq_new(js, JABBER_IQ_SET); |
169 | |
|
170 | 0 | pubsub = xmlnode_new("pubsub"); |
171 | 0 | xmlnode_set_namespace(pubsub, "http://jabber.org/protocol/pubsub"); |
172 | |
|
173 | 0 | xmlnode_insert_child(pubsub, publish); |
174 | |
|
175 | 0 | xmlnode_insert_child(iq->node, pubsub); |
176 | |
|
177 | 0 | jabber_iq_send(iq); |
178 | 0 | } |