diff options
Diffstat (limited to 'protocols')
| -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 | 
