diff options
-rw-r--r-- | protocols/jabber/io.c | 12 | ||||
-rw-r--r-- | protocols/jabber/iq.c | 34 | ||||
-rw-r--r-- | protocols/jabber/jabber.h | 1 | ||||
-rw-r--r-- | protocols/jabber/jabber_util.c | 32 | ||||
-rw-r--r-- | protocols/jabber/xmltree.c | 36 | ||||
-rw-r--r-- | protocols/jabber/xmltree.h | 1 |
6 files changed, 101 insertions, 15 deletions
diff --git a/protocols/jabber/io.c b/protocols/jabber/io.c index aa43d04e..665f5322 100644 --- a/protocols/jabber/io.c +++ b/protocols/jabber/io.c @@ -464,11 +464,17 @@ static xt_status jabber_pkt_stream_error( struct xt_node *node, gpointer data ) should turn off auto-reconnect to make sure we won't get some nasty infinite loop! */ if( strcmp( type, "conflict" ) == 0 ) + { + hide_login_progress( gc, "Account and resource used from a different location" ); gc->wants_to_die = TRUE; + } + else + { + s = g_strdup_printf( "Stream error: %s%s%s", type, text ? ": " : "", text ? text : "" ); + hide_login_progress_error( gc, s ); + g_free( s ); + } - s = g_strdup_printf( "Stream error: %s%s%s", type, text ? ": " : "", text ? text : "" ); - hide_login_progress_error( gc, s ); - g_free( s ); signoff( gc ); return XT_ABORT; diff --git a/protocols/jabber/iq.c b/protocols/jabber/iq.c index e39f3064..265fae53 100644 --- a/protocols/jabber/iq.c +++ b/protocols/jabber/iq.c @@ -29,7 +29,7 @@ xt_status jabber_pkt_iq( struct xt_node *node, gpointer data ) struct jabber_data *jd = gc->proto_data; struct xt_node *c, *reply = NULL; char *type, *s; - int st; + int st, pack = 1; type = xt_find_attr( node, "type" ); @@ -100,22 +100,34 @@ xt_status jabber_pkt_iq( struct xt_node *node, gpointer data ) else { xt_free_node( reply ); - reply = NULL; + reply = jabber_make_error_packet( node, "feature-not-implemented", "cancel" ); + pack = 0; } - - /* If we recognized the xmlns and managed to generate a reply, - finish and send it. */ - if( reply ) + } + else if( strcmp( type, "set" ) == 0 ) + { + xt_free_node( reply ); + reply = jabber_make_error_packet( node, "feature-not-implemented", "cancel" ); + pack = 0; + } + + /* If we recognized the xmlns and managed to generate a reply, + finish and send it. */ + if( reply ) + { + /* Normally we still have to pack it into an iq-result + packet, but for errors, for example, we don't. */ + if( pack ) { 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; } + + st = jabber_write_packet( gc, reply ); + xt_free_node( reply ); + if( !st ) + return XT_ABORT; } return XT_HANDLED; diff --git a/protocols/jabber/jabber.h b/protocols/jabber/jabber.h index 3535ecc5..e5b85f39 100644 --- a/protocols/jabber/jabber.h +++ b/protocols/jabber/jabber.h @@ -126,6 +126,7 @@ int presence_send_request( struct gaim_connection *gc, char *handle, char *reque char *set_eval_priority( set_t *set, char *value ); char *set_eval_tls( set_t *set, char *value ); struct xt_node *jabber_make_packet( char *name, char *type, char *to, struct xt_node *children ); +struct xt_node *jabber_make_error_packet( struct xt_node *orig, char *err_cond, char *err_type ); void jabber_cache_add( struct gaim_connection *gc, struct xt_node *node, jabber_cache_event func ); struct xt_node *jabber_cache_get( struct gaim_connection *gc, char *id ); void jabber_cache_entry_free( gpointer entry ); diff --git a/protocols/jabber/jabber_util.c b/protocols/jabber/jabber_util.c index 357743d3..d9a89951 100644 --- a/protocols/jabber/jabber_util.c +++ b/protocols/jabber/jabber_util.c @@ -78,7 +78,37 @@ struct xt_node *jabber_make_packet( char *name, char *type, char *to, struct xt_ return node; } -/* Cache a node/packet for later use. Mainly useful for IQ packets if you need +struct xt_node *jabber_make_error_packet( struct xt_node *orig, char *err_cond, char *err_type ) +{ + struct xt_node *node, *c; + char *to; + + /* Create the "defined-condition" tag. */ + c = xt_new_node( err_cond, NULL, NULL ); + xt_add_attr( c, "xmlns", "urn:ietf:params:xml:ns:xmpp-stanzas" ); + + /* Put it in an <error> tag. */ + c = xt_new_node( "error", NULL, c ); + xt_add_attr( c, "type", err_type ); + + /* To make the actual error packet, we copy the original packet and + add our <error>/type="error" tag. Including the original packet + is recommended, so let's just do it. */ + node = xt_dup( orig ); + xt_add_child( node, c ); + xt_add_attr( node, "type", "error" ); + + /* Return to sender. */ + if( ( to = xt_find_attr( node, "from" ) ) ) + { + xt_add_attr( node, "to", to ); + xt_remove_attr( node, "from" ); + } + + return node; +} + +/* Cache a node/epacket for later use. Mainly useful for IQ packets if you need them when you receive the response. Use this BEFORE sending the packet so it'll get an id= tag, and do NOT free() the packet after writing it! */ void jabber_cache_add( struct gaim_connection *gc, struct xt_node *node, jabber_cache_event func ) diff --git a/protocols/jabber/xmltree.c b/protocols/jabber/xmltree.c index af0c5832..7a165a1e 100644 --- a/protocols/jabber/xmltree.c +++ b/protocols/jabber/xmltree.c @@ -549,3 +549,39 @@ void xt_add_attr( struct xt_node *node, char *key, char *value ) node->attr[i].value = g_strdup( value ); } + +int xt_remove_attr( struct xt_node *node, char *key ) +{ + int i, last; + + for( i = 0; node->attr[i].key; i ++ ) + if( strcmp( node->attr[i].key, key ) == 0 ) + break; + + /* If we didn't find the attribute... */ + if( node->attr[i].key == NULL ) + return 0; + + g_free( node->attr[i].key ); + g_free( node->attr[i].value ); + + /* If it's the last, this is easy: */ + if( node->attr[i+1].key == NULL ) + { + node->attr[i].key = node->attr[i].value = NULL; + } + else /* It's also pretty easy, actually. */ + { + /* Find the last item. */ + for( last = i + 1; node->attr[last+1].key; last ++ ); + + node->attr[i] = node->attr[last]; + node->attr[last].key = NULL; + node->attr[last].value = NULL; + } + + /* Let's not bother with reallocating memory here. It takes time and + most packets don't stay in memory for long anyway. */ + + return 1; +} diff --git a/protocols/jabber/xmltree.h b/protocols/jabber/xmltree.h index 4abb094f..70850c1d 100644 --- a/protocols/jabber/xmltree.h +++ b/protocols/jabber/xmltree.h @@ -92,5 +92,6 @@ char *xt_find_attr( struct xt_node *node, char *key ); struct xt_node *xt_new_node( char *name, char *text, struct xt_node *children ); void xt_add_child( struct xt_node *parent, struct xt_node *child ); void xt_add_attr( struct xt_node *node, char *key, char *value ); +int xt_remove_attr( struct xt_node *node, char *key ); #endif |