Index: protocols/jabber/conference.c
===================================================================
--- protocols/jabber/conference.c	(revision dce390357114e30a424106c99e49cef1e682e1af)
+++ protocols/jabber/conference.c	(revision 08135dff0e668622fc858d2ad8a7d0bdbdb8cb24)
@@ -24,4 +24,6 @@
 #include "jabber.h"
 
+static xt_status jabber_chat_join_failed( struct im_connection *ic, struct xt_node *node, struct xt_node *orig );
+
 struct groupchat *jabber_chat_join( struct im_connection *ic, char *room, char *nick, char *password )
 {
@@ -35,12 +37,11 @@
 	xt_add_attr( node, "xmlns", XMLNS_MUC );
 	node = jabber_make_packet( "presence", NULL, roomjid, node );
+	jabber_cache_add( ic, node, jabber_chat_join_failed );
 	
 	if( !jabber_write_packet( ic, node ) )
 	{
 		g_free( roomjid );
-		xt_free_node( node );
 		return NULL;
 	}
-	xt_free_node( node );
 	
 	jc = g_new0( struct jabber_chat, 1 );
@@ -63,4 +64,43 @@
 	
 	return c;
+}
+
+static xt_status jabber_chat_join_failed( struct im_connection *ic, struct xt_node *node, struct xt_node *orig )
+{
+	struct jabber_error *err;
+	struct jabber_buddy *bud;
+	char *room;
+	
+	room = xt_find_attr( orig, "to" );
+	if( ( bud = jabber_buddy_by_jid( ic, room, 0 ) ) )
+		jabber_chat_free( jabber_chat_by_jid( ic, bud->bare_jid ) );
+	
+	err = jabber_error_parse( xt_find_node( node->children, "error" ), XMLNS_STANZA_ERROR );
+	if( err )
+	{
+		imcb_error( ic, "Error joining groupchat %s: %s%s%s",
+		            bud->bare_jid, err->code, err->text ? ": " : "",
+		            err->text ? err->text : "" );
+		jabber_error_free( err );
+	}
+	
+	return XT_HANDLED;
+}
+
+struct groupchat *jabber_chat_by_jid( struct im_connection *ic, const char *name )
+{
+	char *normalized = jabber_normalize( name );
+	struct groupchat *ret;
+	struct jabber_chat *jc;
+	
+	for( ret = ic->groupchats; ret; ret = ret->next )
+	{
+		jc = ret->data;
+		if( strcmp( normalized, jc->name ) == 0 )
+			break;
+	}
+	g_free( normalized );
+	
+	return ret;
 }
 
@@ -148,5 +188,5 @@
 	char *s;
 	
-	if( ( chat = jabber_chat_by_name( ic, bud->bare_jid ) ) == NULL )
+	if( ( chat = jabber_chat_by_jid( ic, bud->bare_jid ) ) == NULL )
 	{
 		/* How could this happen?? We could do kill( self, 11 )
@@ -250,5 +290,5 @@
 		return;
 	}
-	else if( ( chat = jabber_chat_by_name( ic, bud->bare_jid ) ) == NULL )
+	else if( ( chat = jabber_chat_by_jid( ic, bud->bare_jid ) ) == NULL )
 	{
 		/* How could this happen?? We could do kill( self, 11 )
Index: protocols/jabber/iq.c
===================================================================
--- protocols/jabber/iq.c	(revision dce390357114e30a424106c99e49cef1e682e1af)
+++ protocols/jabber/iq.c	(revision 08135dff0e668622fc858d2ad8a7d0bdbdb8cb24)
@@ -31,5 +31,4 @@
 {
 	struct im_connection *ic = data;
-	struct jabber_data *jd = ic->proto_data;
 	struct xt_node *c, *reply = NULL;
 	char *type, *s;
@@ -47,21 +46,5 @@
 	if( strcmp( type, "result" ) == 0 || strcmp( type, "error" ) == 0 )
 	{
-		struct jabber_cache_entry *entry;
-		
-		if( ( s = xt_find_attr( node, "id" ) ) == NULL ||
-		    strncmp( s, jd->cached_id_prefix, strlen( jd->cached_id_prefix ) ) != 0 )
-		{
-			/* Silently ignore it, without an ID (or a non-cache
-			   ID) we don't know how to handle the packet and we
-			   probably don't have to. */
-			return XT_HANDLED;
-		}
-		
-		entry = g_hash_table_lookup( jd->node_cache, s );
-		
-		if( entry == NULL )
-			imcb_log( ic, "WARNING: Received IQ-%s packet with unknown/expired ID %s!", type, s );
-		else if( entry->func )
-			return entry->func( ic, node, entry->node );
+		return jabber_cache_handle_packet( ic, node );
 	}
 	else if( strcmp( type, "get" ) == 0 )
Index: protocols/jabber/jabber.c
===================================================================
--- protocols/jabber/jabber.c	(revision dce390357114e30a424106c99e49cef1e682e1af)
+++ protocols/jabber/jabber.c	(revision 08135dff0e668622fc858d2ad8a7d0bdbdb8cb24)
@@ -226,6 +226,4 @@
 	jd->cached_id_prefix = g_strdup_printf( "%s%s", JABBER_CACHED_ID, s );
 	g_free( s );
-	
-	printf( "%s\n", jd->cached_id_prefix );
 }
 
@@ -272,5 +270,5 @@
 		return jabber_write( ic, message, strlen( message ) );
 	
-	if( ( s = strchr( who, '=' ) ) && jabber_chat_by_name( ic, s + 1 ) )
+	if( ( s = strchr( who, '=' ) ) && jabber_chat_by_jid( ic, s + 1 ) )
 		bud = jabber_buddy_by_ext_jid( ic, who, 0 );
 	else
@@ -399,5 +397,5 @@
 	if( strchr( room, '@' ) == NULL )
 		imcb_error( ic, "Invalid room name: %s", room );
-	else if( jabber_chat_by_name( ic, room ) )
+	else if( jabber_chat_by_jid( ic, room ) )
 		imcb_error( ic, "Already present in chat `%s'", room );
 	else
Index: protocols/jabber/jabber.h
===================================================================
--- protocols/jabber/jabber.h	(revision dce390357114e30a424106c99e49cef1e682e1af)
+++ protocols/jabber/jabber.h	(revision 08135dff0e668622fc858d2ad8a7d0bdbdb8cb24)
@@ -227,4 +227,5 @@
 void jabber_cache_entry_free( gpointer entry );
 void jabber_cache_clean( struct im_connection *ic );
+xt_status jabber_cache_handle_packet( struct im_connection *ic, struct xt_node *node );
 const struct jabber_away_state *jabber_away_state_by_code( char *code );
 const struct jabber_away_state *jabber_away_state_by_name( char *name );
@@ -249,5 +250,4 @@
 int jabber_buddy_remove( struct im_connection *ic, char *full_jid );
 int jabber_buddy_remove_bare( struct im_connection *ic, char *bare_jid );
-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 );
@@ -272,4 +272,5 @@
 /* conference.c */
 struct groupchat *jabber_chat_join( struct im_connection *ic, char *room, char *nick, char *password );
+struct groupchat *jabber_chat_by_jid( struct im_connection *ic, const char *name );
 void jabber_chat_free( struct groupchat *c );
 int jabber_chat_msg( struct groupchat *ic, char *message, int flags );
Index: protocols/jabber/jabber_util.c
===================================================================
--- protocols/jabber/jabber_util.c	(revision dce390357114e30a424106c99e49cef1e682e1af)
+++ protocols/jabber/jabber_util.c	(revision 08135dff0e668622fc858d2ad8a7d0bdbdb8cb24)
@@ -183,4 +183,34 @@
 		return FALSE;
 	}
+}
+
+xt_status jabber_cache_handle_packet( struct im_connection *ic, struct xt_node *node )
+{
+	struct jabber_data *jd = ic->proto_data;
+	struct jabber_cache_entry *entry;
+	char *s;
+	
+	if( ( s = xt_find_attr( node, "id" ) ) == NULL ||
+	    strncmp( s, jd->cached_id_prefix, strlen( jd->cached_id_prefix ) ) != 0 )
+	{
+		/* Silently ignore it, without an ID (or a non-cache
+		   ID) we don't know how to handle the packet and we
+		   probably don't have to. */
+		return XT_HANDLED;
+	}
+	
+	entry = g_hash_table_lookup( jd->node_cache, s );
+	
+	if( entry == NULL )
+	{
+		imcb_log( ic, "WARNING: Received %s-%s packet with unknown/expired ID %s!",
+		              node->name, xt_find_attr( node, "type" ) ? : "(no type)", s );
+	}
+	else if( entry->func )
+	{
+		return entry->func( ic, node, entry->node );
+	}
+	
+	return XT_HANDLED;
 }
 
@@ -595,21 +625,4 @@
 }
 
-struct groupchat *jabber_chat_by_name( struct im_connection *ic, const char *name )
-{
-	char *normalized = jabber_normalize( name );
-	struct groupchat *ret;
-	struct jabber_chat *jc;
-	
-	for( ret = ic->groupchats; ret; ret = ret->next )
-	{
-		jc = ret->data;
-		if( strcmp( normalized, jc->name ) == 0 )
-			break;
-	}
-	g_free( normalized );
-	
-	return ret;
-}
-
 time_t jabber_get_timestamp( struct xt_node *xt )
 {
@@ -663,8 +676,12 @@
 struct jabber_error *jabber_error_parse( struct xt_node *node, char *xmlns )
 {
-	struct jabber_error *err = g_new0( struct jabber_error, 1 );
+	struct jabber_error *err;
 	struct xt_node *c;
 	char *s;
 	
+	if( node == NULL )
+		return NULL;
+	
+	err = g_new0( struct jabber_error, 1 );
 	err->type = xt_find_attr( node, "type" );
 	
Index: protocols/jabber/presence.c
===================================================================
--- protocols/jabber/presence.c	(revision dce390357114e30a424106c99e49cef1e682e1af)
+++ protocols/jabber/presence.c	(revision 08135dff0e668622fc858d2ad8a7d0bdbdb8cb24)
@@ -40,5 +40,5 @@
 	{
 		*s = 0;
-		if( jabber_chat_by_name( ic, from ) )
+		if( jabber_chat_by_jid( ic, from ) )
 			is_chat = 1;
 		*s = '/';
@@ -164,6 +164,8 @@
 	else if( strcmp( type, "error" ) == 0 )
 	{
+		return jabber_cache_handle_packet( ic, node );
+		
+		/*
 		struct jabber_error *err;
-		
 		if( ( c = xt_find_node( node->children, "error" ) ) )
 		{
@@ -173,6 +175,5 @@
 			            err->text ? err->text : "" );
 			jabber_error_free( err );
-		}
-		/* What else to do with it? */
+		} */
 	}
 	
