comparison src/protocols/jabber/iq.c @ 7395:b250288fa948

[gaim-migrate @ 7990] this would be the non-working start of file transfer (the real way) for jabber also approximately eleventy billion jabber tweaks committer: Tailor Script <tailor@pidgin.im>
author Nathan Walp <nwalp@pidgin.im>
date Fri, 31 Oct 2003 02:43:58 +0000
parents 1cf80749f2f0
children aaf91a891cd9
comparison
equal deleted inserted replaced
7394:c6ff3c1fb1b3 7395:b250288fa948
20 */ 20 */
21 #include "internal.h" 21 #include "internal.h"
22 #include "debug.h" 22 #include "debug.h"
23 #include "prefs.h" 23 #include "prefs.h"
24 24
25 #include "buddy.h"
25 #include "iq.h" 26 #include "iq.h"
26 #include "oob.h" 27 #include "oob.h"
27 #include "roster.h" 28 #include "roster.h"
29 #include "si.h"
28 30
29 #ifdef _WIN32 31 #ifdef _WIN32
30 #include "utsname.h" 32 #include "utsname.h"
31 #endif 33 #endif
32 34
77 xmlnode_set_attrib(query, "xmlns", xmlns); 79 xmlnode_set_attrib(query, "xmlns", xmlns);
78 80
79 return iq; 81 return iq;
80 } 82 }
81 83
82 void jabber_iq_set_callback(JabberIq *iq, JabberCallback *callback) 84 typedef struct _JabberCallbackData {
85 JabberIqCallback *callback;
86 gpointer data;
87 } JabberCallbackData;
88
89 void
90 jabber_iq_set_callback(JabberIq *iq, JabberIqCallback *callback, gpointer data)
83 { 91 {
84 iq->callback = callback; 92 iq->callback = callback;
93 iq->callback_data = data;
85 } 94 }
86 95
87 void jabber_iq_set_id(JabberIq *iq, const char *id) 96 void jabber_iq_set_id(JabberIq *iq, const char *id)
88 { 97 {
89 if(iq->id) 98 if(iq->id)
98 } 107 }
99 } 108 }
100 109
101 void jabber_iq_send(JabberIq *iq) 110 void jabber_iq_send(JabberIq *iq)
102 { 111 {
112 JabberCallbackData *jcd;
103 g_return_if_fail(iq != NULL); 113 g_return_if_fail(iq != NULL);
104 114
105 jabber_send(iq->js, iq->node); 115 jabber_send(iq->js, iq->node);
106 116
107 if(iq->id && iq->callback) 117 if(iq->id && iq->callback) {
108 g_hash_table_insert(iq->js->callbacks, g_strdup(iq->id), iq->callback); 118 jcd = g_new0(JabberCallbackData, 1);
119 jcd->callback = iq->callback;
120 jcd->data = iq->callback_data;
121 g_hash_table_insert(iq->js->callbacks, g_strdup(iq->id), jcd);
122 }
109 123
110 jabber_iq_free(iq); 124 jabber_iq_free(iq);
111 } 125 }
112 126
113 void jabber_iq_free(JabberIq *iq) 127 void jabber_iq_free(JabberIq *iq)
203 } 217 }
204 218
205 jabber_iq_send(iq); 219 jabber_iq_send(iq);
206 } 220 }
207 221
222 #define SUPPORT_FEATURE(x) \
223 feature = xmlnode_new_child(query, "feature"); \
224 xmlnode_set_attrib(feature, "var", x);
225
226
227 void jabber_disco_info_parse(JabberStream *js, xmlnode *packet) {
228 const char *from = xmlnode_get_attrib(packet, "from");
229 const char *type = xmlnode_get_attrib(packet, "type");
230
231 if(!from || !type)
232 return;
233
234 if(!strcmp(type, "get")) {
235 xmlnode *query, *identity, *feature;
236 JabberIq *iq = jabber_iq_new_query(js, JABBER_IQ_RESULT,
237 "http://jabber.org/protocol/disco#info");
238
239 jabber_iq_set_id(iq, xmlnode_get_attrib(packet, "id"));
240
241 xmlnode_set_attrib(iq->node, "to", from);
242 query = xmlnode_get_child(iq->node, "query");
243
244 identity = xmlnode_new_child(query, "identity");
245 xmlnode_set_attrib(identity, "category", "client");
246 xmlnode_set_attrib(identity, "type", "pc"); /* XXX: bot, console,
247 * handheld, pc, phone,
248 * web */
249
250 SUPPORT_FEATURE("jabber:iq:last")
251 SUPPORT_FEATURE("jabber:iq:oob")
252 SUPPORT_FEATURE("jabber:iq:time")
253 SUPPORT_FEATURE("jabber:iq:version")
254 SUPPORT_FEATURE("jabber:x:conference")
255 SUPPORT_FEATURE("http://jabber.org/protocol/bytestreams")
256 SUPPORT_FEATURE("http://jabber.org/protocol/disco#info")
257 SUPPORT_FEATURE("http://jabber.org/protocol/disco#items")
258 SUPPORT_FEATURE("http://jabber.org/protocol/muc")
259 SUPPORT_FEATURE("http://jabber.org/protocol/muc#user")
260 SUPPORT_FEATURE("http://jabber.org/protocol/si")
261 SUPPORT_FEATURE("http://jabber.org/protocol/si/profile/file-transfer")
262
263 jabber_iq_send(iq);
264 }else if(!strcmp(type, "result")) {
265 xmlnode *query = xmlnode_get_child(packet, "query");
266 xmlnode *child;
267 JabberID *jid;
268 JabberBuddy *jb;
269 JabberBuddyResource *jbr = NULL;
270
271 if(!(jid = jabber_id_new(from)))
272 return;
273
274 if(jid->resource && (jb = jabber_buddy_find(js, from, TRUE)))
275 jbr = jabber_buddy_find_resource(jb, jid->resource);
276
277 if(!jbr) {
278 jabber_id_free(jid);
279 return;
280 }
281
282 for(child = query->child; child; child = child->next) {
283 if(child->type != NODE_TYPE_TAG)
284 continue;
285
286 if(!strcmp(child->name, "feature")) {
287 const char *var = xmlnode_get_attrib(child, "var");
288 if(!var)
289 continue;
290
291 if(!strcmp(var, "http://jabber.org/protocol/si"))
292 jbr->capabilities |= JABBER_CAP_SI;
293 else if(!strcmp(var,
294 "http://jabber.org/protocol/si/profile/file-transfer"))
295 jbr->capabilities |= JABBER_CAP_SI_FILE_XFER;
296 else if(!strcmp(var, "http://jabber.org/protocol/bytestreams"))
297 jbr->capabilities |= JABBER_CAP_BYTESTREAMS;
298 }
299 }
300 jabber_id_free(jid);
301 }
302 }
303
304 void jabber_disco_items_parse(JabberStream *js, xmlnode *packet) {
305 const char *from = xmlnode_get_attrib(packet, "from");
306 const char *type = xmlnode_get_attrib(packet, "type");
307
308 if(!strcmp(type, "get")) {
309 JabberIq *iq = jabber_iq_new_query(js, JABBER_IQ_RESULT,
310 "http://jabber.org/protocol/disco#items");
311
312 jabber_iq_set_id(iq, xmlnode_get_attrib(packet, "id"));
313
314 xmlnode_set_attrib(iq->node, "to", from);
315 jabber_iq_send(iq);
316 }
317 }
318
208 void jabber_iq_parse(JabberStream *js, xmlnode *packet) 319 void jabber_iq_parse(JabberStream *js, xmlnode *packet)
209 { 320 {
321 JabberCallbackData *jcd;
210 xmlnode *query; 322 xmlnode *query;
211 const char *xmlns; 323 const char *xmlns;
324 const char *type, *id;
212 325
213 query = xmlnode_get_child(packet, "query"); 326 query = xmlnode_get_child(packet, "query");
214 327
215 if(!query) 328 if(query) {
329
330 xmlns = xmlnode_get_attrib(query, "xmlns");
331
332 if(!xmlns)
333 return;
334
335 if(!strcmp(xmlns, "jabber:iq:roster")) {
336 jabber_roster_parse(js, packet);
337 return;
338 } else if(!strcmp(xmlns, "jabber:iq:last")) {
339 jabber_iq_handle_last(js, packet);
340 return;
341 } else if(!strcmp(xmlns, "jabber:iq:time")) {
342 jabber_iq_handle_time(js, packet);
343 return;
344 } else if(!strcmp(xmlns, "jabber:iq:version")) {
345 jabber_iq_handle_version(js, packet);
346 return;
347 } else if(!strcmp(xmlns, "jabber:iq:register")) {
348 jabber_register_parse(js, packet);
349 return;
350 } else if(!strcmp(xmlns, "jabber:iq:oob")) {
351 jabber_oob_parse(js, packet);
352 return;
353 } else if(!strcmp(xmlns, "http://jabber.org/protocol/disco#info")) {
354 jabber_disco_info_parse(js, packet);
355 return;
356 } else if(!strcmp(xmlns, "http://jabber.org/protocol/disco#items")) {
357 jabber_disco_items_parse(js, packet);
358 return;
359 }
360 } else if(xmlnode_get_child(packet, "si")) {
361 jabber_si_parse(js, packet);
216 return; 362 return;
217 363 }
218 xmlns = xmlnode_get_attrib(query, "xmlns"); 364
219 365 /* If we got here, no pre-defined handlers got it, lets see if a special
220 if(!xmlns) 366 * callback got registered */
221 return; 367
222 368 type = xmlnode_get_attrib(packet, "type");
223 if(!strcmp(xmlns, "jabber:iq:roster")) { 369 id = xmlnode_get_attrib(packet, "id");
224 jabber_roster_parse(js, packet); 370
225 } else if(!strcmp(xmlns, "jabber:iq:last")) { 371 if(type && (!strcmp(type, "result") || !strcmp(type, "error")) && id
226 jabber_iq_handle_last(js, packet); 372 && *id && (jcd = g_hash_table_lookup(js->callbacks, id))) {
227 } else if(!strcmp(xmlns, "jabber:iq:time")) { 373 jcd->callback(js, packet, jcd->data);
228 jabber_iq_handle_time(js, packet); 374 g_free(jcd);
229 } else if(!strcmp(xmlns, "jabber:iq:version")) { 375 }
230 jabber_iq_handle_version(js, packet); 376 }
231 } else if(!strcmp(xmlns, "jabber:iq:register")) { 377
232 jabber_register_parse(js, packet);
233 } else if(!strcmp(xmlns, "jabber:iq:oob")) {
234 jabber_oob_parse(js, packet);
235 } else {
236 gaim_debug(GAIM_DEBUG_WARNING, "jabber", "Unknown query: %s\n", xmlns);
237 }
238 }
239