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 }