Mercurial > pidgin
comparison libpurple/protocols/jabber/iq.c @ 26870:92565c8e1e3a
Add jabber signals for IQ, Message, and Presence stanzas. Lightly tested (it doesn't crash [Prove me wrong!]) and as you'll note, I refer to documentation that doesn't yet exist.
author | Paul Aurich <paul@darkrain42.org> |
---|---|
date | Tue, 12 May 2009 05:49:34 +0000 |
parents | 457dca546b23 |
children | 10c91922bc1e |
comparison
equal
deleted
inserted
replaced
26869:329f5a43b68a | 26870:92565c8e1e3a |
---|---|
40 #ifdef _WIN32 | 40 #ifdef _WIN32 |
41 #include "utsname.h" | 41 #include "utsname.h" |
42 #endif | 42 #endif |
43 | 43 |
44 GHashTable *iq_handlers = NULL; | 44 GHashTable *iq_handlers = NULL; |
45 | 45 GHashTable *signal_iq_handlers = NULL; |
46 | 46 |
47 JabberIq *jabber_iq_new(JabberStream *js, JabberIqType type) | 47 JabberIq *jabber_iq_new(JabberStream *js, JabberIqType type) |
48 { | 48 { |
49 JabberIq *iq; | 49 JabberIq *iq; |
50 | 50 |
287 JabberCallbackData *jcd; | 287 JabberCallbackData *jcd; |
288 xmlnode *child, *error, *x; | 288 xmlnode *child, *error, *x; |
289 const char *xmlns; | 289 const char *xmlns; |
290 const char *iq_type, *id, *from; | 290 const char *iq_type, *id, *from; |
291 JabberIqType type = JABBER_IQ_NONE; | 291 JabberIqType type = JABBER_IQ_NONE; |
292 gboolean signal_return; | |
293 | |
294 from = xmlnode_get_attrib(packet, "from"); | |
295 id = xmlnode_get_attrib(packet, "id"); | |
296 iq_type = xmlnode_get_attrib(packet, "type"); | |
297 | |
298 signal_return = GPOINTER_TO_INT(purple_signal_emit_return_1(jabber_plugin, | |
299 "jabber-receiving-iq", js->gc, iq_type, id, from, packet)); | |
300 if (signal_return) | |
301 return; | |
292 | 302 |
293 /* | 303 /* |
294 * child will be either the first tag child or NULL if there is no child. | 304 * child will be either the first tag child or NULL if there is no child. |
295 * Historically, we used just the 'query' subchild, but newer XEPs use | 305 * Historically, we used just the 'query' subchild, but newer XEPs use |
296 * differently named children. Grabbing the first child is (for the time | 306 * differently named children. Grabbing the first child is (for the time |
299 for (child = packet->child; child; child = child->next) { | 309 for (child = packet->child; child; child = child->next) { |
300 if (child->type == XMLNODE_TYPE_TAG) | 310 if (child->type == XMLNODE_TYPE_TAG) |
301 break; | 311 break; |
302 } | 312 } |
303 | 313 |
304 iq_type = xmlnode_get_attrib(packet, "type"); | |
305 from = xmlnode_get_attrib(packet, "from"); | |
306 id = xmlnode_get_attrib(packet, "id"); | |
307 | |
308 if (iq_type) { | 314 if (iq_type) { |
309 if (!strcmp(iq_type, "get")) | 315 if (!strcmp(iq_type, "get")) |
310 type = JABBER_IQ_GET; | 316 type = JABBER_IQ_GET; |
311 else if (!strcmp(iq_type, "set")) | 317 else if (!strcmp(iq_type, "set")) |
312 type = JABBER_IQ_SET; | 318 type = JABBER_IQ_SET; |
359 jabber_iq_remove_callback_by_id(js, id); | 365 jabber_iq_remove_callback_by_id(js, id); |
360 return; | 366 return; |
361 } | 367 } |
362 } | 368 } |
363 | 369 |
364 /* Apparently not, so lets see if we have a pre-defined handler */ | 370 /* |
371 * Apparently not, so let's see if we have a pre-defined handler | |
372 * or if an outside plugin is interested. | |
373 */ | |
365 if(child && (xmlns = xmlnode_get_namespace(child))) { | 374 if(child && (xmlns = xmlnode_get_namespace(child))) { |
366 char *key = g_strdup_printf("%s %s", child->name, xmlns); | 375 char *key = g_strdup_printf("%s %s", child->name, xmlns); |
367 JabberIqHandler *jih = g_hash_table_lookup(iq_handlers, key); | 376 JabberIqHandler *jih = g_hash_table_lookup(iq_handlers, key); |
377 int signal_ref = GPOINTER_TO_INT(g_hash_table_lookup(signal_iq_handlers, key)); | |
368 g_free(key); | 378 g_free(key); |
379 | |
380 if (signal_ref > 0) { | |
381 signal_return = GPOINTER_TO_INT(purple_signal_emit_return_1(jabber_plugin, "jabber-watched-iq", | |
382 js->gc, iq_type, id, from, child)); | |
383 if (signal_return) | |
384 return; | |
385 } | |
369 | 386 |
370 if(jih) { | 387 if(jih) { |
371 jih(js, from, type, id, child); | 388 jih(js, from, type, id, child); |
372 return; | 389 return; |
373 } | 390 } |
406 */ | 423 */ |
407 char *key = g_strdup_printf("%s %s", node, xmlns); | 424 char *key = g_strdup_printf("%s %s", node, xmlns); |
408 g_hash_table_replace(iq_handlers, key, handlerfunc); | 425 g_hash_table_replace(iq_handlers, key, handlerfunc); |
409 } | 426 } |
410 | 427 |
428 void jabber_iq_signal_register(const gchar *node, const gchar *xmlns) | |
429 { | |
430 gchar *key; | |
431 int ref; | |
432 | |
433 g_return_if_fail(node != NULL && *node != '\0'); | |
434 g_return_if_fail(xmlns != NULL && *xmlns != '\0'); | |
435 | |
436 key = g_strdup_printf("%s %s", node, xmlns); | |
437 ref = GPOINTER_TO_INT(g_hash_table_lookup(signal_iq_handlers, key)); | |
438 if (ref == 0) { | |
439 g_hash_table_insert(signal_iq_handlers, key, GINT_TO_POINTER(1)); | |
440 } else { | |
441 g_hash_table_insert(signal_iq_handlers, key, GINT_TO_POINTER(ref + 1)); | |
442 g_free(key); | |
443 } | |
444 } | |
445 | |
446 void jabber_iq_signal_unregister(const gchar *node, const gchar *xmlns) | |
447 { | |
448 gchar *key; | |
449 int ref; | |
450 | |
451 g_return_if_fail(node != NULL && *node != '\0'); | |
452 g_return_if_fail(xmlns != NULL && *xmlns != '\0'); | |
453 | |
454 key = g_strdup_printf("%s %s", node, xmlns); | |
455 ref = GPOINTER_TO_INT(g_hash_table_lookup(signal_iq_handlers, key)); | |
456 | |
457 if (ref == 1) { | |
458 g_hash_table_remove(signal_iq_handlers, key); | |
459 } else if (ref > 1) { | |
460 g_hash_table_insert(signal_iq_handlers, key, GINT_TO_POINTER(ref - 1)); | |
461 } | |
462 | |
463 g_free(key); | |
464 } | |
465 | |
411 void jabber_iq_init(void) | 466 void jabber_iq_init(void) |
412 { | 467 { |
413 iq_handlers = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); | 468 iq_handlers = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); |
469 signal_iq_handlers = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); | |
414 | 470 |
415 jabber_iq_register_handler("jingle", JINGLE, jingle_parse); | 471 jabber_iq_register_handler("jingle", JINGLE, jingle_parse); |
416 jabber_iq_register_handler("mailbox", "google:mail:notify", | 472 jabber_iq_register_handler("mailbox", "google:mail:notify", |
417 jabber_gmail_poke); | 473 jabber_gmail_poke); |
418 jabber_iq_register_handler("new-mail", "google:mail:notify", | 474 jabber_iq_register_handler("new-mail", "google:mail:notify", |
444 } | 500 } |
445 | 501 |
446 void jabber_iq_uninit(void) | 502 void jabber_iq_uninit(void) |
447 { | 503 { |
448 g_hash_table_destroy(iq_handlers); | 504 g_hash_table_destroy(iq_handlers); |
449 iq_handlers = NULL; | 505 g_hash_table_destroy(signal_iq_handlers); |
450 } | 506 iq_handlers = signal_iq_handlers = NULL; |
507 } |