aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--protocols/jabber/io.c12
-rw-r--r--protocols/jabber/iq.c34
-rw-r--r--protocols/jabber/jabber.h1
-rw-r--r--protocols/jabber/jabber_util.c32
-rw-r--r--protocols/jabber/xmltree.c36
-rw-r--r--protocols/jabber/xmltree.h1
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