diff options
author | Wilmer van der Gaast <wilmer@gaast.net> | 2006-10-11 10:45:45 +0200 |
---|---|---|
committer | Wilmer van der Gaast <wilmer@gaast.net> | 2006-10-11 10:45:45 +0200 |
commit | 58b5f622cd003433dc78b4f510c667baf537424a (patch) | |
tree | 7408c6f44f1c29aa87da8f2e826d86a8a6c3aecb /protocols/jabber/iq.c | |
parent | 8eb10c9dbdf1497a5e154e3d32734f79f42e8213 (diff) |
Handling of some basic IQ-get packets.
Diffstat (limited to 'protocols/jabber/iq.c')
-rw-r--r-- | protocols/jabber/iq.c | 73 |
1 files changed, 70 insertions, 3 deletions
diff --git a/protocols/jabber/iq.c b/protocols/jabber/iq.c index 1b968739..e39f3064 100644 --- a/protocols/jabber/iq.c +++ b/protocols/jabber/iq.c @@ -27,22 +27,31 @@ xt_status jabber_pkt_iq( struct xt_node *node, gpointer data ) { struct gaim_connection *gc = data; struct jabber_data *jd = gc->proto_data; + struct xt_node *c, *reply = NULL; char *type, *s; + int st; type = xt_find_attr( node, "type" ); if( !type ) { - hide_login_progress_error( gc, "Received IQ packet without type!" ); + hide_login_progress_error( gc, "Received IQ packet without type." ); signoff( gc ); return XT_ABORT; } - if( ( s = xt_find_attr( node, "id" ) ) && - ( strcmp( type, "result" ) == 0 || strcmp( type, "error" ) == 0 ) ) + if( strcmp( type, "result" ) == 0 || strcmp( type, "error" ) == 0 ) { struct jabber_cache_entry *entry; + if( ( s = xt_find_attr( node, "id" ) ) == NULL ) + { + /* Silently ignore it, without an ID we don't know + how to handle the packet, but it doesn't have + to be a serious problem. */ + return XT_HANDLED; + } + entry = g_hash_table_lookup( jd->node_cache, s ); if( entry == NULL ) @@ -50,6 +59,64 @@ xt_status jabber_pkt_iq( struct xt_node *node, gpointer data ) else if( entry->func ) return entry->func( gc, node, entry->node ); } + else if( strcmp( type, "get" ) == 0 ) + { + if( !( c = xt_find_node( node->children, "query" ) ) || + !( s = xt_find_attr( c, "xmlns" ) ) ) + { + serv_got_crap( gc, "WARNING: Received incomplete IQ-get packet" ); + return XT_HANDLED; + } + + reply = xt_new_node( "query", NULL, NULL ); + xt_add_attr( reply, "xmlns", s ); + + /* Of course this is a very essential query to support. ;-) */ + if( strcmp( s, "jabber:iq:version" ) == 0 ) + { + xt_add_child( reply, xt_new_node( "name", "BitlBee", NULL ) ); + xt_add_child( reply, xt_new_node( "version", BITLBEE_VERSION, NULL ) ); + xt_add_child( reply, xt_new_node( "os", ARCH, NULL ) ); + } + else if( strcmp( s, "http://jabber.org/protocol/disco#info" ) == 0 ) + { + c = xt_new_node( "identity", NULL, NULL ); + xt_add_attr( c, "category", "client" ); + xt_add_attr( c, "type", "pc" ); + xt_add_attr( c, "name", "BitlBee" ); + xt_add_child( reply, c ); + + c = xt_new_node( "feature", NULL, NULL ); + xt_add_attr( c, "var", "jabber:iq:version" ); + xt_add_child( reply, c ); + + c = xt_new_node( "feature", NULL, NULL ); + xt_add_attr( c, "var", "http://jabber.org/protocol/chatstates" ); + xt_add_child( reply, c ); + + /* Later this can be useful to announce things like + MUC support. */ + } + else + { + xt_free_node( reply ); + reply = NULL; + } + + /* If we recognized the xmlns and managed to generate a reply, + finish and send it. */ + if( reply ) + { + reply = jabber_make_packet( "iq", "result", xt_find_attr( node, "from" ), reply ); + if( ( s = xt_find_attr( node, "id" ) ) ) + xt_add_attr( reply, "id", s ); + + st = jabber_write_packet( gc, reply ); + xt_free_node( reply ); + if( !st ) + return XT_ABORT; + } + } return XT_HANDLED; } |