Index: protocols/jabber/iq.c
===================================================================
--- protocols/jabber/iq.c	(revision 501b4e06244dbd333ee207ceade37592482e0fe7)
+++ protocols/jabber/iq.c	(revision 995913b4be70be6e07b8aa7661ac639e5fc0d6e7)
@@ -148,4 +148,5 @@
 	{
 		struct xt_node *c;
+		
 		if( !( jd->flags & JFLAG_AUTHENTICATED ) &&
 		    ( c = xt_find_node( orig->children, "query" ) ) &&
@@ -199,4 +200,5 @@
 	{
 		if( !( jd->flags & JFLAG_AUTHENTICATED ) &&
+		      orig &&
 		    ( c = xt_find_node( orig->children, "query" ) ) &&
 		    ( c = xt_find_node( c->children, "username" ) ) &&
@@ -207,9 +209,30 @@
 			return XT_ABORT;
 		}
-		else if( orig &&
-		         ( c = xt_find_node( orig->children, "query" ) ) &&
-		         ( c = xt_find_node( c->children, "active" ) ) )
-		{
-			serv_got_crap( gc, "Error while activating privacy list, maybe it doesn't exist" );
+		else if( ( xmlns && strcmp( xmlns, "jabber:iq:privacy" ) == 0 ) ||
+		         ( orig &&
+		           ( c = xt_find_node( orig->children, "query" ) ) &&
+		           ( s = xt_find_attr( c, "xmlns" ) ) &&
+		           strcmp( s, "jabber:iq:privacy" ) == 0 ) )
+		{
+			/* All errors related to privacy lists. */
+			if( ( c = xt_find_node( node->children, "error" ) ) == NULL )
+			{
+				hide_login_progress_error( gc, "Received malformed error packet" );
+				signoff( gc );
+				return XT_ABORT;
+			}
+			
+			if( xt_find_node( c->children, "item-not-found" ) )
+			{
+				serv_got_crap( gc, "Error while activating privacy list, maybe it doesn't exist" );
+				/* Should I do anything else here? */
+			}
+			else if( xt_find_node( c->children, "feature-not-implemented" ) )
+			{
+				jd->flags |= JFLAG_PRIVACY_BROKEN;
+				/* Probably there's no need to inform the user.
+				   We can do that if the user ever tries to use
+				   the block/allow commands. */
+			}
 		}
 	}
@@ -327,7 +350,7 @@
 	node = jabber_make_packet( "iq", "get", NULL, node );
 	
-	st = jabber_write_packet( gc, node );
-	
-	xt_free_node( node );
+	jabber_cache_packet( gc, node );
+	st = jabber_write_packet( gc, node );
+	
 	return st;
 }
@@ -347,2 +370,22 @@
 	return jabber_write_packet( gc, node );
 }
+
+char *set_eval_privacy_list( set_t *set, char *value )
+{
+	account_t *acc = set->data;
+	struct jabber_data *jd = acc->gc->proto_data;
+	
+	if( jd->flags & JFLAG_PRIVACY_BROKEN )
+	{
+		serv_got_crap( acc->gc, "Privacy lists not supported by this server" );
+		return NULL;
+	}
+	
+	/* If we're on-line, return NULL and let the server decide if the
+	   chosen list is valid. If we're off-line, just accept it and we'll
+	   see later (when we connect). */
+	if( acc->gc )
+		jabber_set_privacy( acc->gc, value );
+	
+	return acc->gc ? NULL : value;
+}
Index: protocols/jabber/jabber.c
===================================================================
--- protocols/jabber/jabber.c	(revision 501b4e06244dbd333ee207ceade37592482e0fe7)
+++ protocols/jabber/jabber.c	(revision 995913b4be70be6e07b8aa7661ac639e5fc0d6e7)
@@ -42,6 +42,5 @@
 	s = set_add( &acc->set, "priority", "0", set_eval_priority, acc );
 	
-	s = set_add( &acc->set, "privacy_list", NULL, NULL, acc );
-	/* TODO: Add evaluator. */
+	s = set_add( &acc->set, "privacy_list", NULL, set_eval_privacy_list, acc );
 	
 	s = set_add( &acc->set, "resource", "BitlBee", NULL, acc );
@@ -232,10 +231,22 @@
 static void jabber_add_permit( struct gaim_connection *gc, char *who )
 {
-	presence_send_request( gc, who, "subscribed" );
+	struct jabber_data *jd = gc->proto_data;
+	
+	if( jd->flags & JFLAG_PRIVACY_BROKEN )
+	{
+		serv_got_crap( gc, "Privacy lists not supported by this server" );
+		return;
+	}
 }
 
 static void jabber_rem_permit( struct gaim_connection *gc, char *who )
 {
-	presence_send_request( gc, who, "unsubscribed" );
+	struct jabber_data *jd = gc->proto_data;
+	
+	if( jd->flags & JFLAG_PRIVACY_BROKEN )
+	{
+		serv_got_crap( gc, "Privacy lists not supported by this server" );
+		return;
+	}
 }
 
Index: protocols/jabber/jabber.h
===================================================================
--- protocols/jabber/jabber.h	(revision 501b4e06244dbd333ee207ceade37592482e0fe7)
+++ protocols/jabber/jabber.h	(revision 995913b4be70be6e07b8aa7661ac639e5fc0d6e7)
@@ -37,4 +37,5 @@
 	JFLAG_WAIT_SESSION = 8,		/* Set if we sent a <session> tag and need a reply before we continue. */
 	JFLAG_WAIT_BIND = 16,		/* ... for <bind> tag. */
+	JFLAG_PRIVACY_BROKEN = 32,	/* Or just not supported, actually. */
 } jabber_flags_t;
 
@@ -83,4 +84,5 @@
 int jabber_get_privacy( struct gaim_connection *gc );
 int jabber_set_privacy( struct gaim_connection *gc, char *name );
+char *set_eval_privacy_list( set_t *set, char *value );
 
 /* message.c */
