aboutsummaryrefslogtreecommitdiffstats
path: root/protocols/jabber/io.c
diff options
context:
space:
mode:
authorWilmer van der Gaast <wilmer@gaast.net>2006-10-11 20:29:56 +0200
committerWilmer van der Gaast <wilmer@gaast.net>2006-10-11 20:29:56 +0200
commitb56b220e4280a75577f79b9dbcaf6eb2d7336873 (patch)
tree6d38607399347025d280c5eb7873fb972325201b /protocols/jabber/io.c
parent58b5f622cd003433dc78b4f510c667baf537424a (diff)
Fixed issues in end-of-connection detection and added basic "handling" of
stream errors. (They can't really be handled, but at least the user can be informed.)
Diffstat (limited to 'protocols/jabber/io.c')
-rw-r--r--protocols/jabber/io.c51
1 files changed, 50 insertions, 1 deletions
diff --git a/protocols/jabber/io.c b/protocols/jabber/io.c
index 783d6d2c..aa43d04e 100644
--- a/protocols/jabber/io.c
+++ b/protocols/jabber/io.c
@@ -161,7 +161,7 @@ static gboolean jabber_read_callback( gpointer data, gint fd, b_input_condition
if( st > 0 )
{
/* Parse. */
- if( !xt_feed( jd->xt, buf, st ) )
+ if( xt_feed( jd->xt, buf, st ) < 0 )
{
hide_login_progress_error( gc, "XML stream error" );
signoff( gc );
@@ -278,6 +278,7 @@ gboolean jabber_connected_ssl( gpointer data, void *source, b_input_condition co
static xt_status jabber_end_of_stream( struct xt_node *node, gpointer data )
{
+ signoff( data );
return XT_ABORT;
}
@@ -426,6 +427,53 @@ static xt_status jabber_pkt_proceed_tls( struct xt_node *node, gpointer data )
return XT_HANDLED;
}
+static xt_status jabber_pkt_stream_error( struct xt_node *node, gpointer data )
+{
+ struct gaim_connection *gc = data;
+ struct xt_node *c;
+ char *s, *type = NULL, *text = NULL;
+
+ for( c = node->children; c; c = c->next )
+ {
+ if( !( s = xt_find_attr( c, "xmlns" ) ) ||
+ strcmp( s, "urn:ietf:params:xml:ns:xmpp-streams" ) != 0 )
+ continue;
+
+ if( strcmp( c->name, "text" ) != 0 )
+ {
+ type = c->name;
+ }
+ /* Only use the text if it doesn't have an xml:lang attribute,
+ if it's empty or if it's set to something English. */
+ else if( !( s = xt_find_attr( c, "xml:lang" ) ) ||
+ !*s || strncmp( s, "en", 2 ) == 0 )
+ {
+ text = c->text;
+ }
+ }
+
+ /* Tssk... */
+ if( type == NULL )
+ {
+ hide_login_progress_error( gc, "Unknown stream error reported by server" );
+ signoff( gc );
+ return XT_ABORT;
+ }
+
+ /* We know that this is a fatal error. If it's a "conflict" error, we
+ should turn off auto-reconnect to make sure we won't get some nasty
+ infinite loop! */
+ if( strcmp( type, "conflict" ) == 0 )
+ gc->wants_to_die = TRUE;
+
+ 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;
+}
+
static xt_status jabber_pkt_misc( struct xt_node *node, gpointer data )
{
printf( "Received unknown packet:\n" );
@@ -440,6 +488,7 @@ static const struct xt_handler_entry jabber_handlers[] = {
{ "presence", "stream:stream", jabber_pkt_presence },
{ "iq", "stream:stream", jabber_pkt_iq },
{ "stream:features", "stream:stream", jabber_pkt_features },
+ { "stream:error", "stream:stream", jabber_pkt_stream_error },
{ "proceed", "stream:stream", jabber_pkt_proceed_tls },
{ "challenge", "stream:stream", sasl_pkt_challenge },
{ "success", "stream:stream", sasl_pkt_result },