Index: protocols/jabber/io.c
===================================================================
--- protocols/jabber/io.c	(revision 85023c65b697d2dab932acbda31258ae5270dbe6)
+++ protocols/jabber/io.c	(revision 1baaef858136cd3a4799b3ccf1d9961534e0017c)
@@ -436,32 +436,15 @@
 {
 	struct im_connection *ic = data;
-	struct xt_node *c;
-	char *s, *type = NULL, *text = NULL;
 	int allow_reconnect = TRUE;
-	
-	for( c = node->children; c; c = c->next )
-	{
-		if( !( s = xt_find_attr( c, "xmlns" ) ) ||
-		    strcmp( s, XMLNS_STREAM_ERROR ) != 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;
-		}
-	}
+	struct jabber_error *err;
+	
+	err = jabber_error_parse( node, XMLNS_STREAM_ERROR );
 	
 	/* Tssk... */
-	if( type == NULL )
+	if( err->code == NULL )
 	{
 		imcb_error( ic, "Unknown stream error reported by server" );
 		imc_logout( ic, allow_reconnect );
+		jabber_error_free( err );
 		return XT_ABORT;
 	}
@@ -470,5 +453,5 @@
 	   should turn off auto-reconnect to make sure we won't get some nasty
 	   infinite loop! */
-	if( strcmp( type, "conflict" ) == 0 )
+	if( strcmp( err->code, "conflict" ) == 0 )
 	{
 		imcb_error( ic, "Account and resource used from a different location" );
@@ -477,7 +460,9 @@
 	else
 	{
-		imcb_error( ic, "Stream error: %s%s%s", type, text ? ": " : "", text ? text : "" );
-	}
-	
+		imcb_error( ic, "Stream error: %s%s%s", err->code, err->text ? ": " : "",
+		            err->text ? err->text : "" );
+	}
+	
+	jabber_error_free( err );
 	imc_logout( ic, allow_reconnect );
 	
Index: protocols/jabber/jabber.h
===================================================================
--- protocols/jabber/jabber.h	(revision 85023c65b697d2dab932acbda31258ae5270dbe6)
+++ protocols/jabber/jabber.h	(revision 1baaef858136cd3a4799b3ccf1d9961534e0017c)
@@ -194,4 +194,9 @@
 } get_buddy_flags_t;
 
+struct jabber_error
+{
+	char *code, *text, *type;
+};
+
 struct jabber_buddy *jabber_buddy_add( struct im_connection *ic, char *full_jid );
 struct jabber_buddy *jabber_buddy_by_jid( struct im_connection *ic, char *jid, get_buddy_flags_t flags );
@@ -201,4 +206,6 @@
 struct groupchat *jabber_chat_by_name( struct im_connection *ic, const char *name );
 time_t jabber_get_timestamp( struct xt_node *xt );
+struct jabber_error *jabber_error_parse( struct xt_node *node, char *xmlns );
+void jabber_error_free( struct jabber_error *err );
 
 extern const struct jabber_away_state jabber_away_state_list[];
Index: protocols/jabber/jabber_util.c
===================================================================
--- protocols/jabber/jabber_util.c	(revision 85023c65b697d2dab932acbda31258ae5270dbe6)
+++ protocols/jabber/jabber_util.c	(revision 1baaef858136cd3a4799b3ccf1d9961534e0017c)
@@ -648,2 +648,37 @@
 	return res;
 }
+
+struct jabber_error *jabber_error_parse( struct xt_node *node, char *xmlns )
+{
+	struct jabber_error *err = g_new0( struct jabber_error, 1 );
+	struct xt_node *c;
+	char *s;
+	
+	err->type = xt_find_attr( node, "type" );
+	
+	for( c = node->children; c; c = c->next )
+	{
+		if( !( s = xt_find_attr( c, "xmlns" ) ) ||
+		    strcmp( s, xmlns ) != 0 )
+			continue;
+		
+		if( strcmp( c->name, "text" ) != 0 )
+		{
+			err->code = 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 )
+		{
+			err->text = c->text;
+		}
+	}
+	
+	return err;
+}
+
+void jabber_error_free( struct jabber_error *err )
+{
+	g_free( err );
+}
Index: protocols/jabber/presence.c
===================================================================
--- protocols/jabber/presence.c	(revision 85023c65b697d2dab932acbda31258ae5270dbe6)
+++ protocols/jabber/presence.c	(revision 1baaef858136cd3a4799b3ccf1d9961534e0017c)
@@ -158,5 +158,15 @@
 	else if( strcmp( type, "error" ) == 0 )
 	{
-		/* What to do with it? */
+		struct jabber_error *err;
+		
+		if( ( c = xt_find_node( node->children, "error" ) ) )
+		{
+			err = jabber_error_parse( c, XMLNS_STANZA_ERROR );
+			imcb_error( ic, "Stanza (%s) error: %s%s%s", node->name,
+			            err->code, err->text ? ": " : "",
+			            err->text ? err->text : "" );
+			jabber_error_free( err );
+		}
+		/* What else to do with it? */
 	}
 	else
