# HG changeset patch
# Node ID 03d4e908c0fd
# Parent  17fd3bcecaeb
diff --git a/ChangeLog.API b/ChangeLog.API
--- a/ChangeLog.API
+++ b/ChangeLog.API
@@ -357,12 +357,10 @@
 		* network-configuration-changed signal
 		* PurpleAccount->ui_data
 		* PurpleAccountPrefsUiOps
+		* PurpleAccountPrivacyType
 		* PurpleAccountRequestAuthorizationCb
 		* PurpleAccountRequestType
-		* PurpleAccountUiOps:close_account_request
-		* PurpleAccountUiOps:request_add
-		* PurpleAccountUiOps:request_authorization
-		* PurpleAccountUiOps:status_changed
+		* PurpleAccountUiOps
 		* purple_account_add_buddies_with_invite
 		* purple_account_add_buddy_with_invite
 		* purple_account_destroy_log
@@ -371,11 +369,21 @@
 		* purple_account_get_password.  Use
 		  purple_credential_manager_read_password_async instead.
 		* purple_account_get_public_alias
+		* purple_account_get_privacy_type
 		* purple_account_get_silence_suppression
 		* purple_account_get_ui_int
 		* purple_account_get_ui_string
 		* purple_account_get_ui_bool
 		* purple_account_notify_added
+		* purple_account_privacy_allow
+		* purple_account_privacy_check
+		* purple_account_privacy_deny
+		* purple_account_privacy_deny_add
+		* purple_account_privacy_deny_remove
+		* purple_account_privacy_get_denied
+		* purple_account_privacy_get_permitted
+		* purple_account_privacy_permit_add
+		* purple_account_privacy_permit_remove
 		* purple_account_remove_setting
 		* purple_account_request_add. Use purple_add_contact_request_new
 		  instead.
@@ -385,6 +393,7 @@
 		* purple_account_set_current_error
 		* purple_account_set_password.  Use
 		  purple_credential_manager_write_password_async instead.
+		* purple_account_set_privacy_type
 		* purple_account_set_public_alias
 		* purple_account_set_silence_suppression
 		* purple_account_set_ui_int
@@ -394,8 +403,10 @@
 		* purple_accounts_find
 		* purple_accounts_get_all
 		* purple_accounts_get_all_active
+		* purple_accounts_get_ui_ops
 		* purple_accounts_remove
 		* purple_accounts_reorder
+		* purple_accounts_set_ui_ops
 		* PurpleAttentionType
 		* purple_attention_type_set_name
 		* purple_attention_type_set_incoming_desc
@@ -915,6 +926,7 @@
 		* gtk_imhtml_image_scale
 		* pidgin_account_dialog_show
 		* pidgin_accounts_get_handle
+		* pidgin_accounts_get_ui_ops
 		* pidgin_accounts_window_hide
 		* pidgin_accounts_window_show, use pidgin_account_manager_new instead.
 		* pidgin_append_blist_node_extended_menu
@@ -1109,7 +1121,12 @@
 		* pidgin_pounces_manager_show
 		* pidgin_prefs_labeled_entry
 		* pidgin_prefs_labeled_password
+		* pidgin_privacy_dialog_hide
+		* pidgin_privacy_dialog_show
+		* pidgin_privacy_init
 		* pidgin_protocol_option_menu_get_selected
+		* pidgin_request_add_permit
+		* pidgin_request_add_block
 		* pidgin_save_accels
 		* pidgin_save_accels_cb
 		* PidginScrollBook
diff --git a/finch/finchui.c b/finch/finchui.c
--- a/finch/finchui.c
+++ b/finch/finchui.c
@@ -169,7 +169,6 @@
 
 static void
 finch_ui_stop(G_GNUC_UNUSED PurpleUi *ui) {
-	purple_accounts_set_ui_ops(NULL);
 	finch_accounts_uninit();
 
 	purple_connections_set_ui_ops(NULL);
diff --git a/finch/gntblist.c b/finch/gntblist.c
--- a/finch/gntblist.c
+++ b/finch/gntblist.c
@@ -1139,17 +1139,6 @@
 }
 
 static void
-toggle_block_buddy(GntMenuItem *item, gpointer buddy)
-{
-	gboolean block = gnt_menuitem_check_get_checked(GNT_MENU_ITEM_CHECK(item));
-	PurpleAccount *account = purple_buddy_get_account(buddy);
-	const char *name = purple_buddy_get_name(buddy);
-
-	block ? purple_account_privacy_deny(account, name) :
-		purple_account_privacy_allow(account, name);
-}
-
-static void
 toggle_show_offline(GntMenuItem *item, gpointer buddy)
 {
 	purple_blist_node_set_bool(buddy, "show_offline",
@@ -1163,8 +1152,6 @@
 static void
 create_buddy_menu(GntMenu *menu, PurpleBuddy *buddy)
 {
-	PurpleAccount *account;
-	gboolean permitted;
 	GntMenuItem *item;
 	PurpleProtocol *protocol;
 	PurpleConnection *gc = purple_account_get_connection(purple_buddy_get_account(buddy));
@@ -1188,14 +1175,6 @@
 		}
 	}
 
-	account = purple_buddy_get_account(buddy);
-	permitted = purple_account_privacy_check(account, purple_buddy_get_name(buddy));
-
-	item = gnt_menuitem_check_new(_("Blocked"));
-	gnt_menuitem_check_set_checked(GNT_MENU_ITEM_CHECK(item), !permitted);
-	gnt_menuitem_set_callback(item, toggle_block_buddy, buddy);
-	gnt_menu_add_item(menu, item);
-
 	item = gnt_menuitem_check_new(_("Show when offline"));
 	gnt_menuitem_check_set_checked(GNT_MENU_ITEM_CHECK(item), purple_blist_node_get_bool((PurpleBlistNode*)buddy, "show_offline"));
 	gnt_menuitem_set_callback(item, toggle_show_offline, buddy);
@@ -2502,58 +2481,6 @@
 	purple_prefs_set_string(PREF_ROOT "/sort_type", n);
 }
 
-static void
-block_select_cb(gpointer data, PurpleRequestFields *fields)
-{
-	PurpleAccount *account = purple_request_fields_get_account(fields, "account");
-	const char *name = purple_request_fields_get_string(fields,  "screenname");
-	if (account && name && *name != '\0') {
-		if (GPOINTER_TO_INT(purple_request_fields_get_choice(fields, "block")) == 1) {
-			purple_account_privacy_deny(account, name);
-		} else {
-			purple_account_privacy_allow(account, name);
-		}
-	}
-}
-
-static void
-block_select(GntMenuItem *item, gpointer n)
-{
-	PurpleRequestFields *fields;
-	PurpleRequestFieldGroup *group;
-	PurpleRequestField *field;
-
-	fields = purple_request_fields_new();
-
-	group = purple_request_field_group_new(NULL);
-	purple_request_fields_add_group(fields, group);
-
-	field = purple_request_field_string_new("screenname", _("Name"), NULL, FALSE);
-	purple_request_field_set_type_hint(field, "screenname");
-	purple_request_field_set_required(field, TRUE);
-	purple_request_field_group_add_field(group, field);
-
-	field = purple_request_field_account_new("account", _("Account"), NULL);
-	purple_request_field_set_type_hint(field, "account");
-	purple_request_field_set_visible(field,
-		(purple_connections_get_all() != NULL &&
-		 purple_connections_get_all()->next != NULL));
-	purple_request_field_set_required(field, TRUE);
-	purple_request_field_group_add_field(group, field);
-
-	field = purple_request_field_choice_new("block", _("Block/Unblock"), GINT_TO_POINTER(1));
-	purple_request_field_choice_add(field, _("Block"), GINT_TO_POINTER(1));
-	purple_request_field_choice_add(field, _("Unblock"), GINT_TO_POINTER(2));
-	purple_request_field_group_add_field(group, field);
-
-	purple_request_fields(
-	        purple_blist_get_default(), _("Block/Unblock"), NULL,
-	        _("Please enter the username or alias of the person "
-	          "you would like to Block/Unblock."),
-	        fields, _("OK"), G_CALLBACK(block_select_cb), _("Cancel"), NULL,
-	        NULL, NULL);
-}
-
 /* send_im_select* -- Xerox */
 static void
 send_im_select_cb(gpointer data, PurpleRequestFields *fields)
@@ -2726,11 +2653,6 @@
 	gnt_menu_add_item(GNT_MENU(sub), item);
 	gnt_menuitem_set_callback(GNT_MENU_ITEM(item), send_im_select, NULL);
 
-	item = gnt_menuitem_new(_("Block/Unblock..."));
-	gnt_menuitem_set_id(GNT_MENU_ITEM(item), "block-unblock");
-	gnt_menu_add_item(GNT_MENU(sub), item);
-	gnt_menuitem_set_callback(GNT_MENU_ITEM(item), block_select, NULL);
-
 	item = gnt_menuitem_new(_("Join Chat..."));
 	gnt_menuitem_set_id(GNT_MENU_ITEM(item), "join-chat");
 	gnt_menu_add_item(GNT_MENU(sub), item);
diff --git a/libpurple/account.h b/libpurple/account.h
--- a/libpurple/account.h
+++ b/libpurple/account.h
@@ -63,26 +63,6 @@
 	PURPLE_ACCOUNT_RESPONSE_ACCEPT = 1
 } PurpleAccountRequestResponse;
 
-/**
- * PurpleAccountPrivacyType:
- * @PURPLE_ACCOUNT_PRIVACY_ALLOW_ALL: Allow everything.
- * @PURPLE_ACCOUNT_PRIVACY_DENY_ALL: Deny everything.
- * @PURPLE_ACCOUNT_PRIVACY_ALLOW_USERS: Allow specific users.
- * @PURPLE_ACCOUNT_PRIVACY_DENY_USERS: Deny specific users.
- * @PURPLE_ACCOUNT_PRIVACY_ALLOW_BUDDYLIST: Allow users found in the buddy
- *                                          list.
- *
- * Privacy data types.
- */
-typedef enum
-{
-	PURPLE_ACCOUNT_PRIVACY_ALLOW_ALL = 1,
-	PURPLE_ACCOUNT_PRIVACY_DENY_ALL,
-	PURPLE_ACCOUNT_PRIVACY_ALLOW_USERS,
-	PURPLE_ACCOUNT_PRIVACY_DENY_USERS,
-	PURPLE_ACCOUNT_PRIVACY_ALLOW_BUDDYLIST
-} PurpleAccountPrivacyType;
-
 G_BEGIN_DECLS
 
 /**************************************************************************/
@@ -284,15 +264,6 @@
 void purple_account_set_proxy_info(PurpleAccount *account, PurpleProxyInfo *info);
 
 /**
- * purple_account_set_privacy_type:
- * @account:      The account.
- * @privacy_type: The privacy type.
- *
- * Sets the account's privacy type.
- */
-void purple_account_set_privacy_type(PurpleAccount *account, PurpleAccountPrivacyType privacy_type);
-
-/**
  * purple_account_set_status_types:
  * @account:      The account.
  * @status_types: (element-type PurpleStatusType): The list of status types.
@@ -549,159 +520,6 @@
 PurpleProxyInfo *purple_account_get_proxy_info(PurpleAccount *account);
 
 /**
- * purple_account_get_privacy_type:
- * @account:   The account.
- *
- * Returns the account's privacy type.
- *
- * Returns: The privacy type.
- */
-PurpleAccountPrivacyType purple_account_get_privacy_type(PurpleAccount *account);
-
-/**
- * purple_account_privacy_permit_add:
- * @account:    The account.
- * @name:       The name of the user to add to the list.
- * @local_only: If TRUE, only the local list is updated, and not
- *                   the server.
- *
- * Adds a user to the account's permit list.
- *
- * Returns: TRUE if the user was added successfully, or %FALSE otherwise.
- */
-gboolean purple_account_privacy_permit_add(PurpleAccount *account,
-								const char *name, gboolean local_only);
-
-/**
- * purple_account_privacy_permit_remove:
- * @account:    The account.
- * @name:       The name of the user to add to the list.
- * @local_only: If TRUE, only the local list is updated, and not
- *                   the server.
- *
- * Removes a user from the account's permit list.
- *
- * Returns: TRUE if the user was removed successfully, or %FALSE otherwise.
- */
-gboolean purple_account_privacy_permit_remove(PurpleAccount *account,
-									const char *name, gboolean local_only);
-
-/**
- * purple_account_privacy_deny_add:
- * @account:    The account.
- * @name:       The name of the user to add to the list.
- * @local_only: If TRUE, only the local list is updated, and not
- *                   the server.
- *
- * Adds a user to the account's deny list.
- *
- * Returns: TRUE if the user was added successfully, or %FALSE otherwise.
- */
-gboolean purple_account_privacy_deny_add(PurpleAccount *account,
-									const char *name, gboolean local_only);
-
-/**
- * purple_account_privacy_deny_remove:
- * @account:    The account.
- * @name:       The name of the user to add to the list.
- * @local_only: If TRUE, only the local list is updated, and not
- *                   the server.
- *
- * Removes a user from the account's deny list.
- *
- * Returns: TRUE if the user was removed successfully, or %FALSE otherwise.
- */
-gboolean purple_account_privacy_deny_remove(PurpleAccount *account,
-									const char *name, gboolean local_only);
-
-/**
- * purple_account_privacy_allow:
- * @account:	The account.
- * @who:		The name of the user.
- *
- * Allow a user to send messages. If current privacy setting for the account is:
- *		PURPLE_ACCOUNT_PRIVACY_ALLOW_USERS:	The user is added to the allow-list.
- *		PURPLE_ACCOUNT_PRIVACY_DENY_USERS	:	The user is removed from the
- *		                                        deny-list.
- *		PURPLE_ACCOUNT_PRIVACY_ALLOW_ALL	:	No changes made.
- *		PURPLE_ACCOUNT_PRIVACY_DENY_ALL	:	The privacy setting is changed to
- *									PURPLE_ACCOUNT_PRIVACY_ALLOW_USERS and the
- *									user is added to the allow-list.
- *		PURPLE_ACCOUNT_PRIVACY_ALLOW_BUDDYLIST: No changes made if the user is
- *									already in the buddy-list. Otherwise the
- *									setting is changed to
- *		PURPLE_ACCOUNT_PRIVACY_ALLOW_USERS, all the buddies are added to the
- *									allow-list, and the user is also added to
- *									the allow-list.
- *
- * The changes are reflected on the server. The previous allow/deny list is not
- * restored if the privacy setting is changed.
- */
-void purple_account_privacy_allow(PurpleAccount *account, const char *who);
-
-/**
- * purple_account_privacy_deny:
- * @account:	The account.
- * @who:		The name of the user.
- *
- * Block messages from a user. If current privacy setting for the account is:
- *		PURPLE_ACCOUNT_PRIVACY_ALLOW_USERS:	The user is removed from the
- *											allow-list.
- *		PURPLE_ACCOUNT_PRIVACY_DENY_USERS:	The user is added to the deny-list.
- *		PURPLE_ACCOUNT_PRIVACY_DENY_ALL:	No changes made.
- *		PURPLE_ACCOUNT_PRIVACY_ALLOW_ALL:	The privacy setting is changed to
- *									PURPLE_ACCOUNT_PRIVACY_DENY_USERS and the
- *									user is added to the deny-list.
- *		PURPLE_ACCOUNT_PRIVACY_ALLOW_BUDDYLIST: If the user is not in the
- *									buddy-list, then no changes made. Otherwise,
- *									the setting is changed to
- *									PURPLE_ACCOUNT_PRIVACY_ALLOW_USERS, all
- *									the buddies are added to the allow-list, and
- *									this user is removed from the list.
- *
- * The changes are reflected on the server. The previous allow/deny list is not
- * restored if the privacy setting is changed.
- */
-void purple_account_privacy_deny(PurpleAccount *account, const char *who);
-
-/**
- * purple_account_privacy_get_permitted:
- * @account:	The account.
- *
- * Returns the account's permit list.
- *
- * Returns: (transfer none) (element-type utf8): A list of the permitted users
- *
- * Since: 3.0.0
- */
-GSList *purple_account_privacy_get_permitted(PurpleAccount *account);
-
-/**
- * purple_account_privacy_get_denied:
- * @account:	The account.
- *
- * Returns the account's deny list.
- *
- * Returns: (transfer none) (element-type utf8): A list of the denied users
- *
- * Since: 3.0.0
- */
-GSList *purple_account_privacy_get_denied(PurpleAccount *account);
-
-/**
- * purple_account_privacy_check:
- * @account:	The account.
- * @who:		The name of the user.
- *
- * Check the privacy-setting for a user.
- *
- * Returns: %FALSE if the specified account's privacy settings block the user
- *		or %TRUE otherwise. The meaning of "block" is protocol-dependent and
- *				generally relates to status and/or sending of messages.
- */
-gboolean purple_account_privacy_check(PurpleAccount *account, const char *who);
-
-/**
  * purple_account_get_active_status:
  * @account:   The account.
  *
diff --git a/libpurple/account.c b/libpurple/account.c
--- a/libpurple/account.c
+++ b/libpurple/account.c
@@ -37,7 +37,6 @@
 #include "purpleprivate.h"
 #include "purpleprotocolclient.h"
 #include "purpleprotocolmanager.h"
-#include "purpleprotocolprivacy.h"
 #include "purpleprotocolserver.h"
 #include "request.h"
 #include "server.h"
@@ -83,18 +82,6 @@
 								/*   to NULL when the account inherits      */
 								/*   proxy settings from global prefs.      */
 
-	/*
-	 * TODO: Instead of linked lists for permit and deny, use a data
-	 * structure that allows fast lookups AND decent performance when
-	 * iterating through all items. Fast lookups should help performance
-	 * for protocols like MSN, where all your buddies exist in your permit
-	 * list therefore the permit list is large. Possibly GTree or
-	 * GHashTable.
-	 */
-	GSList *permit;             /* Permit list.                           */
-	GSList *deny;               /* Deny list.                             */
-	PurpleAccountPrivacyType privacy_type;  /* The permit/deny setting.   */
-
 	GList *status_types;        /* Status types.                          */
 
 	PurplePresence *presence;     /* Presence.                            */
@@ -417,40 +404,6 @@
 	return purple_connection_get_state(gc);
 }
 
-/*
- * This makes sure your permit list contains all buddies from your
- * buddy list and ONLY buddies from your buddy list.
- */
-static void
-add_all_buddies_to_permit_list(PurpleAccount *account, gboolean local)
-{
-	GSList *list;
-
-	/* Remove anyone in the permit list who is not in the buddylist */
-	for (list = account->permit; list != NULL; ) {
-		char *person = list->data;
-		list = list->next;
-		if (!purple_blist_find_buddy(account, person))
-			purple_account_privacy_permit_remove(account, person, local);
-	}
-
-	/* Now make sure everyone in the buddylist is in the permit list */
-	list = purple_blist_find_buddies(account, NULL);
-	while (list != NULL)
-	{
-		PurpleBuddy *buddy = list->data;
-		const gchar *name = purple_buddy_get_name(buddy);
-
-		if (!g_slist_find_custom(account->permit, name,
-		                         (GCompareFunc)g_utf8_collate))
-		{
-			purple_account_privacy_permit_add(account, name, local);
-		}
-
-		list = g_slist_delete_link(list, list);
-	}
-}
-
 void
 _purple_account_set_current_error(PurpleAccount *account,
 		PurpleConnectionErrorInfo *new_err)
@@ -785,8 +738,6 @@
 {
 	account->settings = g_hash_table_new_full(g_str_hash, g_str_equal, g_free,
 	                                          delete_setting);
-
-	account->privacy_type = PURPLE_ACCOUNT_PRIVACY_ALLOW_ALL;
 }
 
 static void
@@ -915,9 +866,6 @@
 
 	g_hash_table_destroy(account->settings);
 
-	g_slist_free_full(account->deny, g_free);
-	g_slist_free_full(account->permit, g_free);
-
 	G_OBJECT_CLASS(purple_account_parent_class)->finalize(object);
 }
 
@@ -1469,14 +1417,6 @@
 }
 
 void
-purple_account_set_privacy_type(PurpleAccount *account, PurpleAccountPrivacyType privacy_type)
-{
-	g_return_if_fail(PURPLE_IS_ACCOUNT(account));
-
-	account->privacy_type = privacy_type;
-}
-
-void
 purple_account_set_status_types(PurpleAccount *account, GList *status_types)
 {
 	g_return_if_fail(PURPLE_IS_ACCOUNT(account));
@@ -1754,353 +1694,6 @@
 	return account->proxy_info;
 }
 
-PurpleAccountPrivacyType
-purple_account_get_privacy_type(PurpleAccount *account)
-{
-	g_return_val_if_fail(PURPLE_IS_ACCOUNT(account), PURPLE_ACCOUNT_PRIVACY_ALLOW_ALL);
-
-	return account->privacy_type;
-}
-
-gboolean
-purple_account_privacy_permit_add(PurpleAccount *account, const char *who,
-						gboolean local_only)
-{
-	char *name;
-	PurpleBuddy *buddy;
-	PurpleAccountUiOps *ui_ops = purple_accounts_get_ui_ops();
-
-	g_return_val_if_fail(PURPLE_IS_ACCOUNT(account), FALSE);
-	g_return_val_if_fail(who     != NULL, FALSE);
-
-	name = g_strdup(purple_normalize(account, who));
-
-	if (g_slist_find_custom(account->permit, name, (GCompareFunc)g_strcmp0) != NULL) {
-		/* This buddy already exists, so bail out */
-		g_free(name);
-		return FALSE;
-	}
-
-	account->permit = g_slist_append(account->permit, name);
-
-	if (!local_only && purple_account_is_connected(account)) {
-		PurpleConnection *connection = purple_account_get_connection(account);
-		PurpleProtocol *protocol = purple_connection_get_protocol(connection);
-		PurpleProtocolPrivacy *privacy = PURPLE_PROTOCOL_PRIVACY(protocol);
-
-		purple_protocol_privacy_add_permit(privacy, connection, who);
-	}
-
-	if (ui_ops != NULL && ui_ops->permit_added != NULL)
-		ui_ops->permit_added(account, who);
-
-	purple_blist_save_account(purple_blist_get_default(), account);
-
-	/* This lets the UI know a buddy has had its privacy setting changed */
-	buddy = purple_blist_find_buddy(account, name);
-	if (buddy != NULL) {
-		purple_signal_emit(purple_blist_get_handle(),
-                "buddy-privacy-changed", buddy);
-	}
-	return TRUE;
-}
-
-gboolean
-purple_account_privacy_permit_remove(PurpleAccount *account, const char *who,
-						   gboolean local_only)
-{
-	GSList *l;
-	const char *name;
-	PurpleBuddy *buddy;
-	char *del;
-	PurpleAccountUiOps *ui_ops = purple_accounts_get_ui_ops();
-
-	g_return_val_if_fail(PURPLE_IS_ACCOUNT(account), FALSE);
-	g_return_val_if_fail(who     != NULL, FALSE);
-
-	name = purple_normalize(account, who);
-
-	l = g_slist_find_custom(account->permit, name, (GCompareFunc)g_strcmp0);
-	if (l == NULL) {
-		/* We didn't find the buddy we were looking for, so bail out */
-		return FALSE;
-	}
-
-	/* We should not free l->data just yet. There can be occasions where
-	 * l->data == who. In such cases, freeing l->data here can cause crashes
-	 * later when who is used. */
-	del = l->data;
-	account->permit = g_slist_delete_link(account->permit, l);
-
-	if (!local_only && purple_account_is_connected(account)) {
-		PurpleConnection *connection = purple_account_get_connection(account);
-		PurpleProtocol *protocol = purple_connection_get_protocol(connection);
-		PurpleProtocolPrivacy *privacy = PURPLE_PROTOCOL_PRIVACY(protocol);
-
-		purple_protocol_privacy_remove_permit(privacy, connection, who);
-	}
-
-	if (ui_ops != NULL && ui_ops->permit_removed != NULL) {
-		ui_ops->permit_removed(account, who);
-	}
-
-	purple_blist_save_account(purple_blist_get_default(), account);
-
-	buddy = purple_blist_find_buddy(account, name);
-	if (buddy != NULL) {
-		purple_signal_emit(purple_blist_get_handle(),
-                "buddy-privacy-changed", buddy);
-	}
-	g_free(del);
-	return TRUE;
-}
-
-gboolean
-purple_account_privacy_deny_add(PurpleAccount *account, const char *who,
-					  gboolean local_only)
-{
-	char *name;
-	PurpleBuddy *buddy;
-	PurpleAccountUiOps *ui_ops = purple_accounts_get_ui_ops();
-
-	g_return_val_if_fail(PURPLE_IS_ACCOUNT(account), FALSE);
-	g_return_val_if_fail(who     != NULL, FALSE);
-
-	name = g_strdup(purple_normalize(account, who));
-
-	if (g_slist_find_custom(account->deny, name,
-	                        (GCompareFunc)g_strcmp0) != NULL)
-	{
-		/* This buddy already exists, so bail out */
-		g_free(name);
-		return FALSE;
-	}
-
-	account->deny = g_slist_append(account->deny, name);
-
-	if (!local_only && purple_account_is_connected(account)) {
-		PurpleConnection *connection = purple_account_get_connection(account);
-		PurpleProtocol *protocol = purple_connection_get_protocol(connection);
-		PurpleProtocolPrivacy *privacy = PURPLE_PROTOCOL_PRIVACY(protocol);
-
-		purple_protocol_privacy_add_deny(privacy, connection, who);
-	}
-
-	if (ui_ops != NULL && ui_ops->deny_added != NULL)
-		ui_ops->deny_added(account, who);
-
-	purple_blist_save_account(purple_blist_get_default(), account);
-
-	buddy = purple_blist_find_buddy(account, name);
-	if (buddy != NULL) {
-		purple_signal_emit(purple_blist_get_handle(),
-                "buddy-privacy-changed", buddy);
-	}
-	return TRUE;
-}
-
-gboolean
-purple_account_privacy_deny_remove(PurpleAccount *account, const char *who,
-						 gboolean local_only)
-{
-	GSList *l;
-	const char *normalized;
-	char *name;
-	PurpleBuddy *buddy;
-	PurpleAccountUiOps *ui_ops = purple_accounts_get_ui_ops();
-
-	g_return_val_if_fail(PURPLE_IS_ACCOUNT(account), FALSE);
-	g_return_val_if_fail(who     != NULL, FALSE);
-
-	normalized = purple_normalize(account, who);
-
-	l = g_slist_find_custom(account->deny, normalized, (GCompareFunc)g_strcmp0);
-	if (l == NULL) {
-		/* We didn't find the buddy we were looking for, so bail out */
-		return FALSE;
-	}
-
-	buddy = purple_blist_find_buddy(account, normalized);
-
-	name = l->data;
-	account->deny = g_slist_delete_link(account->deny, l);
-
-	if (!local_only && purple_account_is_connected(account)) {
-		PurpleConnection *connection = purple_account_get_connection(account);
-		PurpleProtocol *protocol = purple_connection_get_protocol(connection);
-		PurpleProtocolPrivacy *privacy = PURPLE_PROTOCOL_PRIVACY(protocol);
-
-		purple_protocol_privacy_remove_deny(privacy, connection, name);
-	}
-
-	if (ui_ops != NULL && ui_ops->deny_removed != NULL) {
-		ui_ops->deny_removed(account, who);
-	}
-
-	if (buddy != NULL) {
-		purple_signal_emit(purple_blist_get_handle(),
-                "buddy-privacy-changed", buddy);
-	}
-
-	g_free(name);
-
-	purple_blist_save_account(purple_blist_get_default(), account);
-
-	return TRUE;
-}
-
-void
-purple_account_privacy_allow(PurpleAccount *account, const char *who)
-{
-	GSList *list;
-	PurpleAccountPrivacyType type = purple_account_get_privacy_type(account);
-
-	switch (type) {
-		case PURPLE_ACCOUNT_PRIVACY_ALLOW_ALL:
-			return;
-		case PURPLE_ACCOUNT_PRIVACY_ALLOW_USERS:
-			purple_account_privacy_permit_add(account, who, FALSE);
-			break;
-		case PURPLE_ACCOUNT_PRIVACY_DENY_USERS:
-			purple_account_privacy_deny_remove(account, who, FALSE);
-			break;
-		case PURPLE_ACCOUNT_PRIVACY_DENY_ALL:
-			{
-				/* Empty the allow-list. */
-				const char *norm = purple_normalize(account, who);
-				for (list = account->permit; list != NULL;) {
-					char *person = list->data;
-					list = list->next;
-					if (!purple_strequal(norm, person))
-						purple_account_privacy_permit_remove(account, person, FALSE);
-				}
-				purple_account_privacy_permit_add(account, who, FALSE);
-				purple_account_set_privacy_type(account, PURPLE_ACCOUNT_PRIVACY_ALLOW_USERS);
-			}
-			break;
-		case PURPLE_ACCOUNT_PRIVACY_ALLOW_BUDDYLIST:
-			if (!purple_blist_find_buddy(account, who)) {
-				add_all_buddies_to_permit_list(account, FALSE);
-				purple_account_privacy_permit_add(account, who, FALSE);
-				purple_account_set_privacy_type(account, PURPLE_ACCOUNT_PRIVACY_ALLOW_USERS);
-			}
-			break;
-		default:
-			g_return_if_reached();
-	}
-
-	/* Notify the server if the privacy setting was changed */
-	if(type != purple_account_get_privacy_type(account) &&
-	   purple_account_is_connected(account))
-	{
-		PurpleProtocol *protocol = purple_account_get_protocol(account);
-
-		if(PURPLE_IS_PROTOCOL_PRIVACY(protocol)) {
-			PurpleConnection *connection = purple_account_get_connection(account);
-
-			purple_protocol_privacy_set_permit_deny(PURPLE_PROTOCOL_PRIVACY(protocol),
-			                                        connection);
-		}
-	}
-}
-
-void
-purple_account_privacy_deny(PurpleAccount *account, const char *who)
-{
-	GSList *list;
-	PurpleAccountPrivacyType type = purple_account_get_privacy_type(account);
-
-	switch (type) {
-		case PURPLE_ACCOUNT_PRIVACY_ALLOW_ALL:
-			{
-				/* Empty the deny-list. */
-				const char *norm = purple_normalize(account, who);
-				for (list = account->deny; list != NULL; ) {
-					char *person = list->data;
-					list = list->next;
-					if (!purple_strequal(norm, person))
-						purple_account_privacy_deny_remove(account, person, FALSE);
-				}
-				purple_account_privacy_deny_add(account, who, FALSE);
-				purple_account_set_privacy_type(account, PURPLE_ACCOUNT_PRIVACY_DENY_USERS);
-			}
-			break;
-		case PURPLE_ACCOUNT_PRIVACY_ALLOW_USERS:
-			purple_account_privacy_permit_remove(account, who, FALSE);
-			break;
-		case PURPLE_ACCOUNT_PRIVACY_DENY_USERS:
-			purple_account_privacy_deny_add(account, who, FALSE);
-			break;
-		case PURPLE_ACCOUNT_PRIVACY_DENY_ALL:
-			break;
-		case PURPLE_ACCOUNT_PRIVACY_ALLOW_BUDDYLIST:
-			if (purple_blist_find_buddy(account, who)) {
-				add_all_buddies_to_permit_list(account, FALSE);
-				purple_account_privacy_permit_remove(account, who, FALSE);
-				purple_account_set_privacy_type(account, PURPLE_ACCOUNT_PRIVACY_ALLOW_USERS);
-			}
-			break;
-		default:
-			g_return_if_reached();
-	}
-
-	/* Notify the server if the privacy setting was changed */
-	if(type != purple_account_get_privacy_type(account) &&
-	   purple_account_is_connected(account))
-	{
-		PurpleProtocol *protocol = purple_account_get_protocol(account);
-
-		if(PURPLE_IS_PROTOCOL_PRIVACY(protocol)) {
-			PurpleConnection *connection = purple_account_get_connection(account);
-
-			purple_protocol_privacy_set_permit_deny(PURPLE_PROTOCOL_PRIVACY(protocol),
-			                                        connection);
-		}
-	}
-}
-
-GSList *
-purple_account_privacy_get_permitted(PurpleAccount *account)
-{
-	g_return_val_if_fail(PURPLE_IS_ACCOUNT(account), NULL);
-
-	return account->permit;
-}
-
-GSList *
-purple_account_privacy_get_denied(PurpleAccount *account)
-{
-	g_return_val_if_fail(PURPLE_IS_ACCOUNT(account), NULL);
-
-	return account->deny;
-}
-
-gboolean
-purple_account_privacy_check(PurpleAccount *account, const char *who)
-{
-	switch (purple_account_get_privacy_type(account)) {
-		case PURPLE_ACCOUNT_PRIVACY_ALLOW_ALL:
-			return TRUE;
-
-		case PURPLE_ACCOUNT_PRIVACY_DENY_ALL:
-			return FALSE;
-
-		case PURPLE_ACCOUNT_PRIVACY_ALLOW_USERS:
-			who = purple_normalize(account, who);
-			return (g_slist_find_custom(account->permit, who, (GCompareFunc)g_strcmp0) != NULL);
-
-		case PURPLE_ACCOUNT_PRIVACY_DENY_USERS:
-			who = purple_normalize(account, who);
-			return (g_slist_find_custom(account->deny, who, (GCompareFunc)g_strcmp0) == NULL);
-
-		case PURPLE_ACCOUNT_PRIVACY_ALLOW_BUDDYLIST:
-			return (purple_blist_find_buddy(account, who) != NULL);
-
-		default:
-			g_return_val_if_reached(TRUE);
-	}
-}
-
 PurpleStatus *
 purple_account_get_active_status(PurpleAccount *account)
 {
diff --git a/libpurple/accounts.h b/libpurple/accounts.h
--- a/libpurple/accounts.h
+++ b/libpurple/accounts.h
@@ -29,34 +29,6 @@
 #include "account.h"
 #include "status.h"
 
-#define PURPLE_TYPE_ACCOUNT_UI_OPS (purple_account_ui_ops_get_type())
-
-typedef struct _PurpleAccountUiOps  PurpleAccountUiOps;
-
-/**
- * PurpleAccountUiOps:
- * @status_changed:        This account's status changed.
- * @permit_added: Called during a call to purple_account_privacy_permit_add().
- * @permit_removed: Called during a call to
- *                  purple_account_privacy_permit_removed().
- * @deny_added: Called during a call to purple_account_privacy_deny_add().
- * @deny_removed: Called during a call to
- *                purple_account_privacy_deny_removed().
- *
- * Account UI operations, used to notify the user of status changes and when
- * buddies add this account to their buddy lists.
- */
-struct _PurpleAccountUiOps
-{
-	void (*permit_added)(PurpleAccount *account, const char *name);
-	void (*permit_removed)(PurpleAccount *account, const char *name);
-	void (*deny_added)(PurpleAccount *account, const char *name);
-	void (*deny_removed)(PurpleAccount *account, const char *name);
-
-	/*< private >*/
-	gpointer reserved[4];
-};
-
 G_BEGIN_DECLS
 
 /**************************************************************************/
@@ -88,36 +60,6 @@
  */
 void purple_accounts_restore_current_statuses(void);
 
-
-/**************************************************************************/
-/* UI Registration Functions                                              */
-/**************************************************************************/
-
-/**
- * purple_account_ui_ops_get_type:
- *
- * Returns: The #GType for the #PurpleAccountUiOps boxed structure.
- */
-GType purple_account_ui_ops_get_type(void);
-
-/**
- * purple_accounts_set_ui_ops:
- * @ops: The UI operations structure.
- *
- * Sets the UI operations structure to be used for accounts.
- */
-void purple_accounts_set_ui_ops(PurpleAccountUiOps *ops);
-
-/**
- * purple_accounts_get_ui_ops:
- *
- * Returns the UI operations structure used for accounts.
- *
- * Returns: The UI operations structure in use.
- */
-PurpleAccountUiOps *purple_accounts_get_ui_ops(void);
-
-
 /**************************************************************************/
 /* Accounts Subsystem                                                     */
 /**************************************************************************/
diff --git a/libpurple/accounts.c b/libpurple/accounts.c
--- a/libpurple/accounts.c
+++ b/libpurple/accounts.c
@@ -31,8 +31,6 @@
 #include "purpleenums.h"
 #include "purpleprivate.h"
 
-static PurpleAccountUiOps *account_ui_ops = NULL;
-
 static guint    save_timer = 0;
 static gboolean accounts_loaded = FALSE;
 
@@ -590,45 +588,6 @@
 	                               NULL);
 }
 
-static PurpleAccountUiOps *
-purple_account_ui_ops_copy(PurpleAccountUiOps *ops)
-{
-	PurpleAccountUiOps *ops_new;
-
-	g_return_val_if_fail(ops != NULL, NULL);
-
-	ops_new = g_new(PurpleAccountUiOps, 1);
-	*ops_new = *ops;
-
-	return ops_new;
-}
-
-GType
-purple_account_ui_ops_get_type(void)
-{
-	static GType type = 0;
-
-	if (type == 0) {
-		type = g_boxed_type_register_static("PurpleAccountUiOps",
-				(GBoxedCopyFunc)purple_account_ui_ops_copy,
-				(GBoxedFreeFunc)g_free);
-	}
-
-	return type;
-}
-
-void
-purple_accounts_set_ui_ops(PurpleAccountUiOps *ops)
-{
-	account_ui_ops = ops;
-}
-
-PurpleAccountUiOps *
-purple_accounts_get_ui_ops(void)
-{
-	return account_ui_ops;
-}
-
 void *
 purple_accounts_get_handle(void)
 {
diff --git a/libpurple/buddylist.c b/libpurple/buddylist.c
--- a/libpurple/buddylist.c
+++ b/libpurple/buddylist.c
@@ -348,37 +348,7 @@
 }
 
 static PurpleXmlNode *
-accountprivacy_to_xmlnode(PurpleAccount *account)
-{
-	PurpleXmlNode *node, *child;
-	GSList *cur;
-	char buf[10];
-
-	node = purple_xmlnode_new("account");
-	purple_xmlnode_set_attrib(node, "proto", purple_account_get_protocol_id(account));
-	purple_xmlnode_set_attrib(node, "name", purple_account_get_username(account));
-	g_snprintf(buf, sizeof(buf), "%d", purple_account_get_privacy_type(account));
-	purple_xmlnode_set_attrib(node, "mode", buf);
-
-	for (cur = purple_account_privacy_get_permitted(account); cur; cur = cur->next)
-	{
-		child = purple_xmlnode_new_child(node, "permit");
-		purple_xmlnode_insert_data(child, cur->data, -1);
-	}
-
-	for (cur = purple_account_privacy_get_denied(account); cur; cur = cur->next)
-	{
-		child = purple_xmlnode_new_child(node, "block");
-		purple_xmlnode_insert_data(child, cur->data, -1);
-	}
-
-	return node;
-}
-
-static PurpleXmlNode *
 blist_to_xmlnode(void) {
-	GListModel *manager_model = NULL;
-	guint n_items = 0;
 	PurpleXmlNode *node, *child, *grandchild;
 	PurpleBlistNode *gnode;
 	const gchar *localized_default;
@@ -408,17 +378,6 @@
 		}
 	}
 
-	/* Write privacy settings */
-	child = purple_xmlnode_new_child(node, "privacy");
-	manager_model = purple_account_manager_get_default_as_model();
-	n_items = g_list_model_get_n_items(manager_model);
-	for(guint index = 0; index < n_items; index++) {
-		PurpleAccount *account = g_list_model_get_item(manager_model, index);
-		grandchild = accountprivacy_to_xmlnode(account);
-		purple_xmlnode_insert_child(child, grandchild);
-		g_object_unref(account);
-	}
-
 	return node;
 }
 
@@ -667,8 +626,7 @@
 static void
 load_blist(void)
 {
-	PurpleAccountManager *manager = NULL;
-	PurpleXmlNode *purple, *blist, *privacy;
+	PurpleXmlNode *purple, *blist;
 
 	blist_loaded = TRUE;
 
@@ -678,8 +636,6 @@
 		return;
 	}
 
-	manager = purple_account_manager_get_default();
-
 	blist = purple_xmlnode_get_child(purple, "blist");
 	if(blist) {
 		PurpleXmlNode *groupnode;
@@ -697,51 +653,6 @@
 		localized_default_group_name = NULL;
 	}
 
-	privacy = purple_xmlnode_get_child(purple, "privacy");
-	if(privacy) {
-		PurpleXmlNode *anode;
-		for(anode = privacy->child; anode; anode = anode->next) {
-			PurpleAccount *account;
-			PurpleXmlNode *x;
-			int imode;
-			const char *acct_name, *proto, *mode;
-
-			acct_name = purple_xmlnode_get_attrib(anode, "name");
-			proto = purple_xmlnode_get_attrib(anode, "proto");
-			mode = purple_xmlnode_get_attrib(anode, "mode");
-
-			if(!acct_name || !proto || !mode) {
-				continue;
-			}
-
-			account = purple_account_manager_find(manager, acct_name, proto);
-
-			if(!account) {
-				continue;
-			}
-
-			imode = atoi(mode);
-			purple_account_set_privacy_type(account, (imode != 0 ? imode : PURPLE_ACCOUNT_PRIVACY_ALLOW_ALL));
-
-			for(x = anode->child; x; x = x->next) {
-				char *name;
-				if(x->type != PURPLE_XMLNODE_TYPE_TAG) {
-					continue;
-				}
-
-				if(purple_strequal(x->name, "permit")) {
-					name = purple_xmlnode_get_data(x);
-					purple_account_privacy_permit_add(account, name, TRUE);
-					g_free(name);
-				} else if(purple_strequal(x->name, "block")) {
-					name = purple_xmlnode_get_data(x);
-					purple_account_privacy_deny_add(account, name, TRUE);
-					g_free(name);
-				}
-			}
-		}
-	}
-
 	purple_xmlnode_free(purple);
 
 	/* This tells the buddy icon code to do its thing. */
diff --git a/libpurple/connection.c b/libpurple/connection.c
--- a/libpurple/connection.c
+++ b/libpurple/connection.c
@@ -30,7 +30,6 @@
 #include "proxy.h"
 #include "purpleenums.h"
 #include "purpleprivate.h"
-#include "purpleprotocolprivacy.h"
 #include "purpleprotocolserver.h"
 #include "request.h"
 #include "server.h"
@@ -197,13 +196,6 @@
 		purple_signal_emit(handle, "signed-on", connection);
 		purple_signal_emit_return_1(handle, "autojoin", connection);
 
-		if(PURPLE_IS_PROTOCOL_PRIVACY(priv->protocol)) {
-			PurpleProtocolPrivacy *privacy = NULL;
-
-			privacy = PURPLE_PROTOCOL_PRIVACY(priv->protocol);
-			purple_protocol_privacy_set_permit_deny(privacy, connection);
-		}
-
 		update_keepalive(connection, TRUE);
 
 		/* check if connections_connected is NULL, if so we need to emit the
diff --git a/libpurple/meson.build b/libpurple/meson.build
--- a/libpurple/meson.build
+++ b/libpurple/meson.build
@@ -79,7 +79,6 @@
 	'purpleprotocolim.c',
 	'purpleprotocolmanager.c',
 	'purpleprotocolmedia.c',
-	'purpleprotocolprivacy.c',
 	'purpleprotocolroomlist.c',
 	'purpleprotocolserver.c',
 	'purpleprotocolwhiteboard.c',
@@ -185,7 +184,6 @@
 	'purpleprotocolim.h',
 	'purpleprotocolmedia.h',
 	'purpleprotocolmanager.h',
-	'purpleprotocolprivacy.h',
 	'purpleprotocolroomlist.h',
 	'purpleprotocolserver.h',
 	'purpleprotocolwhiteboard.h',
diff --git a/libpurple/plugins/psychic/psychic.c b/libpurple/plugins/psychic/psychic.c
--- a/libpurple/plugins/psychic/psychic.c
+++ b/libpurple/plugins/psychic/psychic.c
@@ -61,12 +61,6 @@
 		return;
 	}
 
-	if(!purple_account_privacy_check(acct, name)) {
-		purple_debug_info("psychic", "user %s is blocked", name);
-		g_object_unref(settings);
-		return;
-	}
-
 	manager = purple_conversation_manager_get_default();
 	im = purple_conversation_manager_find_im(manager, acct, name);
 	if(im == NULL) {
diff --git a/libpurple/protocols/bonjour/xmpp.c b/libpurple/protocols/bonjour/xmpp.c
--- a/libpurple/protocols/bonjour/xmpp.c
+++ b/libpurple/protocols/bonjour/xmpp.c
@@ -1300,38 +1300,12 @@
 	return iq;
 }
 
-static gboolean
-check_if_blocked(PurpleBuddy *pb)
-{
-	gboolean blocked = FALSE;
-	GSList *l = NULL;
-	PurpleAccount *acc = purple_buddy_get_account(pb);
-	const gchar *name;
-
-	if(acc == NULL)
-		return FALSE;
-
-	l = purple_account_privacy_get_denied(acc);
-	name = purple_buddy_get_name(pb);
-
-	if(g_slist_find_custom(l, name, (GCompareFunc)purple_utf8_strcasecmp) != NULL) {
-		const gchar *username = bonjour_get_jid(acc);
-
-		purple_debug_info("bonjour", "%s has been blocked by %s.\n", name, username);
-		blocked = TRUE;
-	}
-	return blocked;
-}
-
 static void
 xep_iq_parse(PurpleXmlNode *packet, PurpleBuddy *pb)
 {
 	PurpleAccount *account;
 	PurpleConnection *gc;
 
-	if(check_if_blocked(pb))
-		return;
-
 	account = purple_buddy_get_account(pb);
 	gc = purple_account_get_connection(account);
 
diff --git a/libpurple/protocols/gg/gg.c b/libpurple/protocols/gg/gg.c
--- a/libpurple/protocols/gg/gg.c
+++ b/libpurple/protocols/gg/gg.c
@@ -227,6 +227,7 @@
 
 /* ----- BLOCK BUDDIES -------------------------------------------------- */
 
+#if 0
 static void ggp_add_deny(PurpleProtocolPrivacy *privacy, PurpleConnection *gc,
                          const char *who)
 {
@@ -250,6 +251,7 @@
 	gg_remove_notify_ex(info->session, uin, GG_USER_BLOCKED);
 	gg_add_notify_ex(info->session, uin, GG_USER_NORMAL);
 }
+#endif
 
 /* ---------------------------------------------------------------------- */
 /* ----- INTERNAL CALLBACKS --------------------------------------------- */
@@ -1330,13 +1332,6 @@
 }
 
 static void
-ggp_protocol_privacy_iface_init(PurpleProtocolPrivacyInterface *privacy_iface)
-{
-	privacy_iface->add_deny = ggp_add_deny;
-	privacy_iface->remove_deny = ggp_remove_deny;
-}
-
-static void
 ggp_protocol_xfer_iface_init(PurpleProtocolXferInterface *xfer_iface)
 {
 	xfer_iface->can_receive = ggp_edisc_xfer_can_receive_file;
@@ -1361,8 +1356,6 @@
 	                              ggp_protocol_chat_iface_init)
 	G_IMPLEMENT_INTERFACE_DYNAMIC(PURPLE_TYPE_PROTOCOL_ROOMLIST,
 	                              ggp_protocol_roomlist_iface_init)
-	G_IMPLEMENT_INTERFACE_DYNAMIC(PURPLE_TYPE_PROTOCOL_PRIVACY,
-	                              ggp_protocol_privacy_iface_init)
 	G_IMPLEMENT_INTERFACE_DYNAMIC(PURPLE_TYPE_PROTOCOL_XFER,
 	                              ggp_protocol_xfer_iface_init))
 
diff --git a/libpurple/protocols/jabber/jabber.c b/libpurple/protocols/jabber/jabber.c
--- a/libpurple/protocols/jabber/jabber.c
+++ b/libpurple/protocols/jabber/jabber.c
@@ -1181,6 +1181,7 @@
                                  JabberIqType type, const char *id,
                                  PurpleXmlNode *child)
 {
+#if 0
 	JabberIq *result;
 	PurpleXmlNode *item;
 	PurpleAccount *account;
@@ -1243,8 +1244,10 @@
 	result = jabber_iq_new(js, JABBER_IQ_RESULT);
 	purple_xmlnode_set_attrib(result->node, "id", id);
 	jabber_iq_send(result);
+#endif
 }
 
+#if 0
 static void jabber_blocklist_parse(JabberStream *js, const char *from,
                                    JabberIqType type, const char *id,
                                    PurpleXmlNode *packet, gpointer data)
@@ -1277,9 +1280,11 @@
 		item = purple_xmlnode_get_next_twin(item);
 	}
 }
+#endif
 
 void jabber_request_block_list(JabberStream *js)
 {
+#if 0
 	JabberIq *iq;
 	PurpleXmlNode *blocklist;
 
@@ -1291,8 +1296,10 @@
 	jabber_iq_set_callback(iq, jabber_blocklist_parse, NULL);
 
 	jabber_iq_send(iq);
+#endif
 }
 
+#if 0
 static void
 jabber_add_deny(PurpleProtocolPrivacy *privacy, PurpleConnection *gc,
                 const char *who)
@@ -1353,6 +1360,7 @@
 
 	jabber_iq_send(iq);
 }
+#endif
 
 void jabber_add_feature(const char *namespace, JabberFeatureEnabled cb) {
 	JabberFeature *feat;
@@ -3536,13 +3544,6 @@
 }
 
 static void
-jabber_protocol_privacy_iface_init(PurpleProtocolPrivacyInterface *privacy_iface)
-{
-	privacy_iface->add_deny = jabber_add_deny;
-	privacy_iface->remove_deny = jabber_remove_deny;
-}
-
-static void
 jabber_protocol_roomlist_iface_init(PurpleProtocolRoomlistInterface *roomlist_iface)
 {
 	roomlist_iface->get_list       = jabber_roomlist_get_list;
@@ -3580,8 +3581,6 @@
 	                              jabber_protocol_im_iface_init)
 	G_IMPLEMENT_INTERFACE_DYNAMIC(PURPLE_TYPE_PROTOCOL_CHAT,
 	                              jabber_protocol_chat_iface_init)
-	G_IMPLEMENT_INTERFACE_DYNAMIC(PURPLE_TYPE_PROTOCOL_PRIVACY,
-	                              jabber_protocol_privacy_iface_init)
 	G_IMPLEMENT_INTERFACE_DYNAMIC(PURPLE_TYPE_PROTOCOL_ROOMLIST,
 	                              jabber_protocol_roomlist_iface_init)
 	G_IMPLEMENT_INTERFACE_DYNAMIC(PURPLE_TYPE_PROTOCOL_MEDIA,
diff --git a/libpurple/purpleprotocolprivacy.h b/libpurple/purpleprotocolprivacy.h
deleted file mode 100644
--- a/libpurple/purpleprotocolprivacy.h
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Purple - Internet Messaging Library
- * Copyright (C) Pidgin Developers <devel@pidgin.im>
- *
- * Purple is the legal property of its developers, whose names are too numerous
- * to list here.  Please refer to the COPYRIGHT file distributed with this
- * source distribution.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <https://www.gnu.org/licenses/>.
- */
-
-#if !defined(PURPLE_GLOBAL_HEADER_INSIDE) && !defined(PURPLE_COMPILATION)
-# error "only <purple.h> may be included directly"
-#endif
-
-#ifndef PURPLE_PROTOCOL_PRIVACY_H
-#define PURPLE_PROTOCOL_PRIVACY_H
-
-#include <glib.h>
-#include <glib-object.h>
-
-#include <libpurple/connection.h>
-#include <libpurple/purpleprotocol.h>
-
-#define PURPLE_TYPE_PROTOCOL_PRIVACY (purple_protocol_privacy_get_type())
-
-/**
- * PurpleProtocolPrivacy:
- *
- * #PurpleProtocolPrivacy describes the privacy API available to protocols.
- */
-G_DECLARE_INTERFACE(PurpleProtocolPrivacy, purple_protocol_privacy, PURPLE,
-                    PROTOCOL_PRIVACY, PurpleProtocol)
-
-/**
- * PurpleProtocolPrivacyInterface:
- * @add_permit: Add the buddy on the required authorized list.
- * @add_deny: Add the buddy on the required blocked list.
- * @remove_permit: Remove the buddy from the required authorized list.
- * @remove_deny: Remove the buddy from the required blocked list.
- * @set_permit_deny: Update the server with the privacy information on the
- *                   permit and deny lists.
- *
- * The protocol privacy interface.
- *
- * This interface provides privacy callbacks such as to permit/deny users.
- */
-struct _PurpleProtocolPrivacyInterface {
-	/*< private >*/
-	GTypeInterface parent;
-
-	/*< public >*/
-	void (*add_permit)(PurpleProtocolPrivacy *privacy, PurpleConnection *connection, const gchar *name);
-
-	void (*add_deny)(PurpleProtocolPrivacy *privacy, PurpleConnection *connection, const gchar *name);
-
-	void (*remove_permit)(PurpleProtocolPrivacy *privacy, PurpleConnection *connection, const gchar *name);
-
-	void (*remove_deny)(PurpleProtocolPrivacy *privacy, PurpleConnection *connection, const gchar *name);
-
-	void (*set_permit_deny)(PurpleProtocolPrivacy *privacy, PurpleConnection *connection);
-
-	/*< private >*/
-	gpointer reserved[4];
-};
-
-G_BEGIN_DECLS
-
-/**
- * purple_protocol_privacy_add_permit:
- * @privacy: The #PurpleProtocolPrivacy instance.
- * @connection: The #PurpleConnection instance.
- * @name: The username to permit.
- *
- * Adds a permit to the privacy settings for @connection to allow @name to
- * contact the user.
- *
- * Since: 3.0.0
- */
-void purple_protocol_privacy_add_permit(PurpleProtocolPrivacy *privacy, PurpleConnection *connection, const gchar *name);
-
-/**
- * purple_protocol_privacy_add_deny:
- * @privacy: The #PurpleProtocolPrivacy instance.
- * @connection: The #PurpleConnection instance.
- * @name: The username to deny.
- *
- * Adds a deny to the privacy settings for @connection to deny @name from
- * contacting the user.
- *
- * Since: 3.0.0
- */
-void purple_protocol_privacy_add_deny(PurpleProtocolPrivacy *privacy, PurpleConnection *connection, const gchar *name);
-
-/**
- * purple_protocol_privacy_remove_permit:
- * @privacy: The #PurpleProtocolPrivacy instance.
- * @connection: The #PurpleConnection instance.
- * @name: The username to remove from the permit privacy settings.
- *
- * Removes an existing permit for @name.
- *
- * Since: 3.0.0
- */
-void purple_protocol_privacy_remove_permit(PurpleProtocolPrivacy *privacy, PurpleConnection *connection, const gchar *name);
-
-/**
- * purple_protocol_privacy_remove_deny:
- * @privacy: The #PurpleProtocolPrivacy instance.
- * @connection: The #PurpleConnection instance.
- * @name: The username to remove from the deny privacy settings.
- *
- * Removes an existing deny for @name.
- *
- * Since: 3.0.0
- */
-void purple_protocol_privacy_remove_deny(PurpleProtocolPrivacy *privacy, PurpleConnection *connection, const gchar *name);
-
-/**
- * purple_protocol_privacy_set_permit_deny:
- * @privacy: The #PurpleProtocolPrivacy instance.
- * @connection: The #PurpleConnection instance.
- *
- * Forces a sync of the privacy settings with server.
- *
- * Since: 3.0.0
- */
-void purple_protocol_privacy_set_permit_deny(PurpleProtocolPrivacy *privacy, PurpleConnection *connection);
-
-G_END_DECLS
-
-#endif /* PURPLE_PROTOCOL_PRIVACY_H */
\ No newline at end of file
diff --git a/libpurple/purpleprotocolprivacy.c b/libpurple/purpleprotocolprivacy.c
deleted file mode 100644
--- a/libpurple/purpleprotocolprivacy.c
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * purple
- *
- * Purple is the legal property of its developers, whose names are too numerous
- * to list here.  Please refer to the COPYRIGHT file distributed with this
- * source distribution.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <https://www.gnu.org/licenses/>.
- */
-
-#include "purpleprotocolprivacy.h"
-
-/******************************************************************************
- * GObject Implementation
- *****************************************************************************/
-G_DEFINE_INTERFACE(PurpleProtocolPrivacy, purple_protocol_privacy,
-                   PURPLE_TYPE_PROTOCOL)
-
-static void
-purple_protocol_privacy_default_init(PurpleProtocolPrivacyInterface *iface) {
-}
-
-/******************************************************************************
- * Public API
- *****************************************************************************/
-void
-purple_protocol_privacy_add_permit(PurpleProtocolPrivacy *privacy,
-                                   PurpleConnection *connection,
-                                   const gchar *name)
-{
-	PurpleProtocolPrivacyInterface *iface = NULL;
-
-	g_return_if_fail(PURPLE_IS_PROTOCOL_PRIVACY(privacy));
-	g_return_if_fail(PURPLE_IS_CONNECTION(connection));
-
-	iface = PURPLE_PROTOCOL_PRIVACY_GET_IFACE(privacy);
-	if(iface && iface->add_permit) {
-		iface->add_permit(privacy, connection, name);
-	}
-}
-
-void
-purple_protocol_privacy_add_deny(PurpleProtocolPrivacy *privacy,
-                                 PurpleConnection *connection,
-                                 const gchar *name)
-{
-	PurpleProtocolPrivacyInterface *iface = NULL;
-
-	g_return_if_fail(PURPLE_IS_PROTOCOL_PRIVACY(privacy));
-	g_return_if_fail(PURPLE_IS_CONNECTION(connection));
-
-	iface = PURPLE_PROTOCOL_PRIVACY_GET_IFACE(privacy);
-	if(iface && iface->add_deny) {
-		iface->add_deny(privacy, connection, name);
-	}
-}
-
-void
-purple_protocol_privacy_remove_permit(PurpleProtocolPrivacy *privacy,
-                                      PurpleConnection *connection,
-                                      const gchar *name)
-{
-	PurpleProtocolPrivacyInterface *iface = NULL;
-
-	g_return_if_fail(PURPLE_IS_PROTOCOL_PRIVACY(privacy));
-	g_return_if_fail(PURPLE_IS_CONNECTION(connection));
-
-	iface = PURPLE_PROTOCOL_PRIVACY_GET_IFACE(privacy);
-	if(iface && iface->remove_permit) {
-		iface->remove_permit(privacy, connection, name);
-	}
-}
-
-void
-purple_protocol_privacy_remove_deny(PurpleProtocolPrivacy *privacy,
-                                    PurpleConnection *connection,
-                                    const gchar *name)
-{
-	PurpleProtocolPrivacyInterface *iface = NULL;
-
-	g_return_if_fail(PURPLE_IS_PROTOCOL_PRIVACY(privacy));
-	g_return_if_fail(PURPLE_IS_CONNECTION(connection));
-
-	iface = PURPLE_PROTOCOL_PRIVACY_GET_IFACE(privacy);
-	if(iface && iface->remove_deny) {
-		iface->remove_deny(privacy, connection, name);
-	}
-}
-
-void
-purple_protocol_privacy_set_permit_deny(PurpleProtocolPrivacy *privacy,
-                                        PurpleConnection *connection)
-{
-	PurpleProtocolPrivacyInterface *iface = NULL;
-
-	g_return_if_fail(PURPLE_IS_PROTOCOL_PRIVACY(privacy));
-	g_return_if_fail(PURPLE_IS_CONNECTION(connection));
-
-	iface = PURPLE_PROTOCOL_PRIVACY_GET_IFACE(privacy);
-	if(iface && iface->set_permit_deny) {
-		iface->set_permit_deny(privacy, connection);
-	}
-}
diff --git a/libpurple/server.c b/libpurple/server.c
--- a/libpurple/server.c
+++ b/libpurple/server.c
@@ -35,7 +35,6 @@
 #include "purpleprotocol.h"
 #include "purpleprotocolchat.h"
 #include "purpleprotocolim.h"
-#include "purpleprotocolprivacy.h"
 #include "purpleprotocolserver.h"
 #include "request.h"
 #include "signals.h"
@@ -337,12 +336,6 @@
 	 */
 	flags |= PURPLE_MESSAGE_RECV;
 
-	if (!purple_account_privacy_check(account, who)) {
-		purple_signal_emit(purple_conversations_get_handle(), "blocked-im-msg",
-				account, who, msg, flags, (unsigned int)mtime);
-		return;
-	}
-
 	manager = purple_conversation_manager_get_default();
 
 	/*
@@ -496,12 +489,6 @@
 	g_return_if_fail(who != NULL);
 
 	account = purple_connection_get_account(gc);
-	if (!purple_account_privacy_check(account, who)) {
-		purple_signal_emit(purple_conversations_get_handle(), "chat-invite-blocked",
-				account, who, name, message, data);
-		return;
-	}
-
 	cid = g_new0(struct chat_invite_data, 1);
 
 	plugin_return = GPOINTER_TO_INT(purple_signal_emit_return_1(
diff --git a/pidgin/gtkaccount.h b/pidgin/gtkaccount.h
--- a/pidgin/gtkaccount.h
+++ b/pidgin/gtkaccount.h
@@ -31,15 +31,6 @@
 G_BEGIN_DECLS
 
 /**
- * pidgin_accounts_get_ui_ops:
- *
- * Returns the GTK account UI ops
- *
- * Returns: The UI operations structure.
- */
-PurpleAccountUiOps *pidgin_accounts_get_ui_ops(void);
-
-/**
  * pidgin_accounts_init:
  *
  * Initializes the GTK account system
diff --git a/pidgin/gtkaccount.c b/pidgin/gtkaccount.c
--- a/pidgin/gtkaccount.c
+++ b/pidgin/gtkaccount.c
@@ -24,15 +24,6 @@
 #include "gtkaccount.h"
 #include "pidgincore.h"
 
-/* This still exists because gtkprivacy calls it to add the privacy ui ops */
-static PurpleAccountUiOps ui_ops = {};
-
-PurpleAccountUiOps *
-pidgin_accounts_get_ui_ops(void)
-{
-	return &ui_ops;
-}
-
 void
 pidgin_accounts_init(void)
 {
diff --git a/pidgin/gtkblist.c b/pidgin/gtkblist.c
--- a/pidgin/gtkblist.c
+++ b/pidgin/gtkblist.c
@@ -32,7 +32,6 @@
 #include "gtkconv.h"
 #include "gtkdialogs.h"
 #include "gtkxfer.h"
-#include "gtkprivacy.h"
 #include "gtkroomlist.h"
 #include "gtkutils.h"
 #include "pidgin/pidginaccountchooser.h"
@@ -355,38 +354,6 @@
 }
 
 static void
-pidgin_blist_menu_block_cb(GSimpleAction *action, GVariant *state,
-                           gpointer data)
-{
-	PidginBuddyList *blist = data;
-	PurpleBuddy *buddy;
-	PurpleAccount *account;
-	gboolean permitted;
-	const char *name;
-
-	buddy = pidgin_blist_get_selected_buddy(blist);
-
-	if (!PURPLE_IS_BUDDY(buddy))
-		return;
-
-	account = purple_buddy_get_account(buddy);
-	name = purple_buddy_get_name(buddy);
-
-	permitted = purple_account_privacy_check(account, name);
-
-	/* XXX: Perhaps ask whether to restore the previous lists where appropirate? */
-
-	if (permitted)
-		purple_account_privacy_deny(account, name);
-	else
-		purple_account_privacy_allow(account, name);
-
-	pidgin_blist_update(PURPLE_BUDDY_LIST(blist), PURPLE_BLIST_NODE(buddy));
-
-	g_simple_action_set_state(action, state);
-}
-
-static void
 pidgin_blist_menu_chat_settings_cb(G_GNUC_UNUSED GSimpleAction *action,
                                    G_GNUC_UNUSED GVariant *parameter,
                                    gpointer data)
@@ -595,11 +562,6 @@
 		.name = "buddy-audio-call",
 		.activate = pidgin_blist_menu_audio_call_cb,
 	}, {
-		.name = "buddy-block",
-		.activate = pidgin_blist_toggle_action,
-		.state = "false",
-		.change_state = pidgin_blist_menu_block_cb,
-	}, {
 		.name = "buddy-get-info",
 		.activate = pidgin_blist_menu_info_cb,
 	}, {
@@ -1542,7 +1504,6 @@
 		PurpleBuddy *buddy = NULL;
 		PurpleConnection *connection = NULL;
 		PurpleProtocol *protocol = NULL;
-		GVariant *variant = NULL;
 		const gchar *buddy_name = NULL;
 
 		menu = gtk_application_get_menu_by_id(gtk_application, "buddy");
@@ -1594,12 +1555,6 @@
 			          (caps & PURPLE_MEDIA_CAPS_VIDEO);
 			g_simple_action_set_enabled(G_SIMPLE_ACTION(action), enabled);
 		}
-
-		/* Set the proper state of the block action. */
-		action = g_action_map_lookup_action(action_map, "buddy-block");
-		enabled = !purple_account_privacy_check(account, buddy_name);
-		variant = g_variant_new_boolean(enabled);
-		g_simple_action_set_state(G_SIMPLE_ACTION(action), variant);
 	}
 
 	action = g_action_map_lookup_action(action_map,
@@ -2554,12 +2509,6 @@
 	g_return_val_if_fail(buddy != NULL, NULL);
 
 	account = purple_buddy_get_account(buddy);
-	if (!purple_account_privacy_check(account, purple_buddy_get_name(buddy))) {
-		path = g_build_filename(PURPLE_DATADIR, "pidgin", "icons",
-			"hicolor", "16x16", "emblems", "emblem-blocked.png",
-			NULL);
-		return _pidgin_blist_get_cached_emblem(path);
-	}
 
 	/* If we came through the contact code flow above, we didn't need
 	 * to get the presence until now. */
diff --git a/pidgin/gtkconv.c b/pidgin/gtkconv.c
--- a/pidgin/gtkconv.c
+++ b/pidgin/gtkconv.c
@@ -42,7 +42,6 @@
 #include "gtkblist.h"
 #include "gtkconv.h"
 #include "gtkdialogs.h"
-#include "gtkprivacy.h"
 #include "gtkutils.h"
 #include "pidginavatar.h"
 #include "pidgincolor.h"
diff --git a/pidgin/gtkprivacy.h b/pidgin/gtkprivacy.h
deleted file mode 100644
--- a/pidgin/gtkprivacy.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/* pidgin
- *
- * Pidgin is the legal property of its developers, whose names are too numerous
- * to list here.  Please refer to the COPYRIGHT file distributed with this
- * source distribution.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
- */
-
-#if !defined(PIDGIN_GLOBAL_HEADER_INSIDE) && !defined(PIDGIN_COMPILATION)
-# error "only <pidgin.h> may be included directly"
-#endif
-
-#ifndef _PIDGINPRIVACY_H_
-#define _PIDGINPRIVACY_H_
-
-#include <purple.h>
-
-G_BEGIN_DECLS
-
-/**
- * pidgin_privacy_init:
- *
- * Initializes the GTK privacy subsystem.
- */
-void pidgin_privacy_init(void);
-
-/**
- * pidgin_privacy_dialog_show:
- *
- * Shows the privacy dialog.
- */
-void pidgin_privacy_dialog_show(void);
-
-/**
- * pidgin_privacy_dialog_hide:
- *
- * Hides the privacy dialog.
- */
-void pidgin_privacy_dialog_hide(void);
-
-/**
- * pidgin_request_add_permit:
- * @account: The account.
- * @name:    The name of the user to add.
- *
- * Requests confirmation to add a user to the allow list for an account,
- * and then adds it.
- *
- * If @name is not specified, an input dialog will be presented.
- */
-void pidgin_request_add_permit(PurpleAccount *account, const char *name);
-
-/**
- * pidgin_request_add_block:
- * @account: The account.
- * @name:    The name of the user to add.
- *
- * Requests confirmation to add a user to the block list for an account,
- * and then adds it.
- *
- * If @name is not specified, an input dialog will be presented.
- */
-void pidgin_request_add_block(PurpleAccount *account, const char *name);
-
-G_END_DECLS
-
-#endif /* _PIDGINPRIVACY_H_ */
diff --git a/pidgin/gtkprivacy.c b/pidgin/gtkprivacy.c
deleted file mode 100644
--- a/pidgin/gtkprivacy.c
+++ /dev/null
@@ -1,496 +0,0 @@
-/* pidgin
- *
- * Pidgin is the legal property of its developers, whose names are too numerous
- * to list here.  Please refer to the COPYRIGHT file distributed with this
- * source distribution.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
- */
-
-#include <glib/gi18n-lib.h>
-
-#include <purple.h>
-
-#include "gtkaccount.h"
-#include "gtkblist.h"
-#include "gtkprivacy.h"
-#include "gtkutils.h"
-#include "pidginaccountchooser.h"
-
-#define PIDGIN_TYPE_PRIVACY_DIALOG (pidgin_privacy_dialog_get_type())
-G_DECLARE_FINAL_TYPE(PidginPrivacyDialog, pidgin_privacy_dialog, PIDGIN,
-                     PRIVACY_DIALOG, GtkDialog)
-
-struct _PidginPrivacyDialog {
-	GtkDialog parent;
-
-	GtkWidget *type_menu;
-
-	GtkWidget *add_button;
-	GtkWidget *remove_button;
-	GtkWidget *removeall_button;
-	GtkWidget *close_button;
-
-	GtkWidget *allow_widget;
-	GtkWidget *block_widget;
-
-	GtkListStore *allow_store;
-	GtkListStore *block_store;
-
-	GtkWidget *allow_list;
-	GtkWidget *block_list;
-
-	gboolean in_allow_list;
-
-	GtkWidget *account_chooser;
-	PurpleAccount *account;
-};
-
-typedef struct
-{
-	PurpleAccount *account;
-	char *name;
-	gboolean block;
-
-} PidginPrivacyRequestData;
-
-static struct
-{
-	const char *text;
-	PurpleAccountPrivacyType type;
-
-} const menu_entries[] =
-{
-	{ N_("Allow all users to contact me"),         PURPLE_ACCOUNT_PRIVACY_ALLOW_ALL },
-	{ N_("Allow only the users on my buddy list"), PURPLE_ACCOUNT_PRIVACY_ALLOW_BUDDYLIST },
-	{ N_("Allow only the users below"),            PURPLE_ACCOUNT_PRIVACY_ALLOW_USERS },
-	{ N_("Block all users"),                       PURPLE_ACCOUNT_PRIVACY_DENY_ALL },
-	{ N_("Block only the users below"),            PURPLE_ACCOUNT_PRIVACY_DENY_USERS }
-};
-
-static const size_t menu_entry_count = sizeof(menu_entries) / sizeof(*menu_entries);
-
-static PidginPrivacyDialog *privacy_dialog = NULL;
-
-static void
-rebuild_allow_list(PidginPrivacyDialog *dialog)
-{
-	GSList *l;
-	GtkTreeIter iter;
-
-	gtk_list_store_clear(dialog->allow_store);
-
-	for (l = purple_account_privacy_get_permitted(dialog->account); l != NULL; l = l->next) {
-		gtk_list_store_append(dialog->allow_store, &iter);
-		gtk_list_store_set(dialog->allow_store, &iter, 0, l->data, -1);
-	}
-}
-
-static void
-rebuild_block_list(PidginPrivacyDialog *dialog)
-{
-	GSList *l;
-	GtkTreeIter iter;
-
-	gtk_list_store_clear(dialog->block_store);
-
-	for (l = purple_account_privacy_get_denied(dialog->account); l != NULL; l = l->next) {
-		gtk_list_store_append(dialog->block_store, &iter);
-		gtk_list_store_set(dialog->block_store, &iter, 0, l->data, -1);
-	}
-}
-
-static void
-user_selected_cb(G_GNUC_UNUSED GtkTreeSelection *sel,
-                 PidginPrivacyDialog *dialog)
-{
-	gtk_widget_set_sensitive(dialog->remove_button, TRUE);
-}
-
-static void
-select_account_cb(GObject *obj, G_GNUC_UNUSED GParamSpec *pspec, gpointer data)
-{
-	PidginPrivacyDialog *dialog = data;
-	PidginAccountChooser *chooser = PIDGIN_ACCOUNT_CHOOSER(obj);
-	PurpleAccount *account = pidgin_account_chooser_get_selected(chooser);
-	gsize i;
-
-	dialog->account = account;
-
-	if (account) {
-		gtk_widget_set_sensitive(dialog->type_menu, TRUE);
-		gtk_widget_set_sensitive(dialog->add_button, TRUE);
-		/* dialog->remove_button is enabled when a user is selected. */
-		gtk_widget_set_sensitive(dialog->removeall_button, TRUE);
-	} else {
-		gtk_widget_set_sensitive(dialog->type_menu, FALSE);
-		gtk_widget_set_sensitive(dialog->add_button, FALSE);
-		gtk_widget_set_sensitive(dialog->remove_button, FALSE);
-		gtk_widget_set_sensitive(dialog->removeall_button, FALSE);
-		gtk_list_store_clear(dialog->allow_store);
-		gtk_list_store_clear(dialog->block_store);
-		return;
-	}
-
-	for (i = 0; i < menu_entry_count; i++) {
-		if (menu_entries[i].type == purple_account_get_privacy_type(account)) {
-			gtk_drop_down_set_selected(GTK_DROP_DOWN(dialog->type_menu), i);
-			break;
-		}
-	}
-
-	rebuild_allow_list(dialog);
-	rebuild_block_list(dialog);
-}
-
-/*
- * TODO: Setting the permit/deny setting needs to go through privacy.c
- *       Even better: the privacy API needs to not suck.
- */
-static void
-type_changed_cb(GObject *obj, G_GNUC_UNUSED GParamSpec *pspec, gpointer data) {
-	PidginPrivacyDialog *dialog = data;
-	PurpleAccountPrivacyType new_type =
-		menu_entries[gtk_drop_down_get_selected(GTK_DROP_DOWN(obj))].type;
-	PurpleProtocol *protocol = NULL;
-	gboolean buttons_sensitive;
-
-	purple_account_set_privacy_type(dialog->account, new_type);
-
-	protocol = purple_account_get_protocol(dialog->account);
-	if(PURPLE_IS_PROTOCOL_PRIVACY(protocol)) {
-		PurpleConnection *connection = NULL;
-
-		connection = purple_account_get_connection(dialog->account);
-		if(PURPLE_IS_CONNECTION(connection)) {
-			PurpleProtocolPrivacy *privacy = NULL;
-
-			privacy = PURPLE_PROTOCOL_PRIVACY(protocol);
-			purple_protocol_privacy_set_permit_deny(privacy, connection);
-		}
-	}
-
-	gtk_widget_hide(dialog->allow_widget);
-	gtk_widget_hide(dialog->block_widget);
-	buttons_sensitive = FALSE;
-
-	if (new_type == PURPLE_ACCOUNT_PRIVACY_ALLOW_USERS) {
-		gtk_widget_show(dialog->allow_widget);
-		buttons_sensitive = TRUE;
-		dialog->in_allow_list = TRUE;
-	}
-	else if (new_type == PURPLE_ACCOUNT_PRIVACY_DENY_USERS) {
-		gtk_widget_show(dialog->block_widget);
-		buttons_sensitive = TRUE;
-		dialog->in_allow_list = FALSE;
-	}
-
-	gtk_widget_set_sensitive(dialog->add_button, buttons_sensitive);
-	/* dialog->remove_button is enabled when a user is selected. */
-	gtk_widget_set_sensitive(dialog->remove_button, FALSE);
-	gtk_widget_set_sensitive(dialog->removeall_button, buttons_sensitive);
-
-	purple_blist_schedule_save();
-	pidgin_blist_refresh(purple_blist_get_default());
-}
-
-static void
-add_cb(G_GNUC_UNUSED GtkWidget *button, PidginPrivacyDialog *dialog)
-{
-	if (dialog->in_allow_list)
-		pidgin_request_add_permit(dialog->account, NULL);
-	else
-		pidgin_request_add_block(dialog->account, NULL);
-}
-
-static void
-remove_cb(G_GNUC_UNUSED GtkWidget *button, PidginPrivacyDialog *dialog)
-{
-	GtkTreeIter iter;
-	GtkTreeModel *model;
-	GtkTreeSelection *sel;
-	char *name;
-
-	if (dialog->in_allow_list && dialog->allow_store == NULL)
-		return;
-
-	if (!dialog->in_allow_list && dialog->block_store == NULL)
-		return;
-
-	if (dialog->in_allow_list) {
-		model = GTK_TREE_MODEL(dialog->allow_store);
-		sel   = gtk_tree_view_get_selection(GTK_TREE_VIEW(dialog->allow_list));
-	}
-	else {
-		model = GTK_TREE_MODEL(dialog->block_store);
-		sel   = gtk_tree_view_get_selection(GTK_TREE_VIEW(dialog->block_list));
-	}
-
-	if (gtk_tree_selection_get_selected(sel, NULL, &iter))
-		gtk_tree_model_get(model, &iter, 0, &name, -1);
-	else
-		return;
-
-	if (dialog->in_allow_list)
-		purple_account_privacy_permit_remove(dialog->account, name, FALSE);
-	else
-		purple_account_privacy_deny_remove(dialog->account, name, FALSE);
-
-	g_free(name);
-}
-
-static void
-removeall_cb(G_GNUC_UNUSED GtkWidget *button, PidginPrivacyDialog *dialog)
-{
-	GSList *l;
-	if (dialog->in_allow_list)
-		l = purple_account_privacy_get_permitted(dialog->account);
-	else
-		l = purple_account_privacy_get_denied(dialog->account);
-	while (l) {
-		char *user;
-		user = l->data;
-		l = l->next;
-		if (dialog->in_allow_list)
-			purple_account_privacy_permit_remove(dialog->account, user, FALSE);
-		else
-			purple_account_privacy_deny_remove(dialog->account, user, FALSE);
-	}
-}
-
-G_DEFINE_TYPE(PidginPrivacyDialog, pidgin_privacy_dialog, GTK_TYPE_DIALOG)
-
-static void
-pidgin_privacy_dialog_class_init(PidginPrivacyDialogClass *klass)
-{
-	GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
-
-	gtk_widget_class_set_template_from_resource(
-	        widget_class, "/im/pidgin/Pidgin3/Privacy/dialog.ui");
-
-	gtk_widget_class_bind_template_child(widget_class, PidginPrivacyDialog,
-	                                     account_chooser);
-	gtk_widget_class_bind_template_child(widget_class, PidginPrivacyDialog,
-	                                     add_button);
-	gtk_widget_class_bind_template_child(widget_class, PidginPrivacyDialog,
-	                                     allow_list);
-	gtk_widget_class_bind_template_child(widget_class, PidginPrivacyDialog,
-	                                     allow_store);
-	gtk_widget_class_bind_template_child(widget_class, PidginPrivacyDialog,
-	                                     allow_widget);
-	gtk_widget_class_bind_template_child(widget_class, PidginPrivacyDialog,
-	                                     block_list);
-	gtk_widget_class_bind_template_child(widget_class, PidginPrivacyDialog,
-	                                     block_store);
-	gtk_widget_class_bind_template_child(widget_class, PidginPrivacyDialog,
-	                                     block_widget);
-	gtk_widget_class_bind_template_child(widget_class, PidginPrivacyDialog,
-	                                     close_button);
-	gtk_widget_class_bind_template_child(widget_class, PidginPrivacyDialog,
-	                                     remove_button);
-	gtk_widget_class_bind_template_child(widget_class, PidginPrivacyDialog,
-	                                     removeall_button);
-	gtk_widget_class_bind_template_child(widget_class, PidginPrivacyDialog,
-	                                     type_menu);
-
-	gtk_widget_class_bind_template_callback(widget_class, add_cb);
-	gtk_widget_class_bind_template_callback(widget_class, remove_cb);
-	gtk_widget_class_bind_template_callback(widget_class, removeall_cb);
-	gtk_widget_class_bind_template_callback(widget_class, select_account_cb);
-	gtk_widget_class_bind_template_callback(widget_class, type_changed_cb);
-	gtk_widget_class_bind_template_callback(widget_class, user_selected_cb);
-}
-
-static void
-pidgin_privacy_dialog_init(PidginPrivacyDialog *dialog) {
-	PidginAccountChooser *chooser = NULL;
-	GtkStringList *model = NULL;
-	guint selected = GTK_INVALID_LIST_POSITION;
-
-	gtk_widget_init_template(GTK_WIDGET(dialog));
-
-	chooser = PIDGIN_ACCOUNT_CHOOSER(dialog->account_chooser);
-	dialog->account = pidgin_account_chooser_get_selected(chooser);
-
-	/* Add the drop-down list with the allow/block types. */
-	model = GTK_STRING_LIST(gtk_drop_down_get_model(GTK_DROP_DOWN(dialog->type_menu)));
-	for (guint i = 0; i < menu_entry_count; i++) {
-		gtk_string_list_append(model, _(menu_entries[i].text));
-
-		if (menu_entries[i].type == purple_account_get_privacy_type(dialog->account)) {
-			selected = i;
-		}
-	}
-	gtk_drop_down_set_selected(GTK_DROP_DOWN(dialog->type_menu), selected);
-
-	/* Rebuild the allow and block lists views. */
-	rebuild_allow_list(dialog);
-	rebuild_block_list(dialog);
-
-	type_changed_cb(G_OBJECT(dialog->type_menu), NULL, dialog);
-}
-
-void
-pidgin_privacy_dialog_show(void)
-{
-	g_return_if_fail(purple_connections_get_all() != NULL);
-
-	if (privacy_dialog == NULL) {
-		privacy_dialog = g_object_new(PIDGIN_TYPE_PRIVACY_DIALOG, NULL);
-		g_object_add_weak_pointer(G_OBJECT(privacy_dialog),
-		                          (gpointer)&privacy_dialog);
-	}
-
-	gtk_widget_show(GTK_WIDGET(privacy_dialog));
-}
-
-void
-pidgin_privacy_dialog_hide(void)
-{
-	if(GTK_IS_WIDGET(privacy_dialog)) {
-		gtk_window_destroy(GTK_WINDOW(privacy_dialog));
-	}
-}
-
-static void
-destroy_request_data(PidginPrivacyRequestData *data)
-{
-	g_free(data->name);
-	g_free(data);
-}
-
-static void
-confirm_permit_block_cb(PidginPrivacyRequestData *data,
-                        G_GNUC_UNUSED int option)
-{
-	if (data->block)
-		purple_account_privacy_deny(data->account, data->name);
-	else
-		purple_account_privacy_allow(data->account, data->name);
-
-	destroy_request_data(data);
-}
-
-static void
-add_permit_block_cb(PidginPrivacyRequestData *data, const char *name)
-{
-	data->name = g_strdup(name);
-
-	confirm_permit_block_cb(data, 0);
-}
-
-void
-pidgin_request_add_permit(PurpleAccount *account, const char *name)
-{
-	PidginPrivacyRequestData *data;
-
-	g_return_if_fail(account != NULL);
-
-	data = g_new0(PidginPrivacyRequestData, 1);
-	data->account = account;
-	data->name    = g_strdup(name);
-	data->block   = FALSE;
-
-	if (name == NULL) {
-		purple_request_input(account, _("Permit User"),
-			_("Type a user you permit to contact you."),
-			_("Please enter the name of the user you wish to be "
-			  "able to contact you."),
-			NULL, FALSE, FALSE, NULL,
-			_("_Permit"), G_CALLBACK(add_permit_block_cb),
-			_("Cancel"), G_CALLBACK(destroy_request_data),
-			purple_request_cpar_from_account(account),
-			data);
-	}
-	else {
-		char *primary = g_strdup_printf(_("Allow %s to contact you?"), name);
-		char *secondary =
-			g_strdup_printf(_("Are you sure you wish to allow "
-							  "%s to contact you?"), name);
-
-
-		purple_request_action(account, _("Permit User"), primary,
-			secondary, 0, purple_request_cpar_from_account(account),
-			data, 2,
-			_("_Permit"), G_CALLBACK(confirm_permit_block_cb),
-			_("Cancel"), G_CALLBACK(destroy_request_data));
-
-		g_free(primary);
-		g_free(secondary);
-	}
-}
-
-void
-pidgin_request_add_block(PurpleAccount *account, const char *name)
-{
-	PidginPrivacyRequestData *data;
-
-	g_return_if_fail(account != NULL);
-
-	data = g_new0(PidginPrivacyRequestData, 1);
-	data->account = account;
-	data->name    = g_strdup(name);
-	data->block   = TRUE;
-
-	if (name == NULL) {
-		purple_request_input(account, _("Block User"),
-			_("Type a user to block."),
-			_("Please enter the name of the user you wish to block."),
-			NULL, FALSE, FALSE, NULL,
-			_("_Block"), G_CALLBACK(add_permit_block_cb),
-			_("Cancel"), G_CALLBACK(destroy_request_data),
-			purple_request_cpar_from_account(account),
-			data);
-	}
-	else {
-		char *primary = g_strdup_printf(_("Block %s?"), name);
-		char *secondary =
-			g_strdup_printf(_("Are you sure you want to block %s?"), name);
-
-		purple_request_action(account, _("Block User"), primary,
-			secondary, 0, purple_request_cpar_from_account(account),
-			data, 2,
-			_("_Block"), G_CALLBACK(confirm_permit_block_cb),
-			_("Cancel"), G_CALLBACK(destroy_request_data));
-
-		g_free(primary);
-		g_free(secondary);
-	}
-}
-
-static void
-pidgin_permit_added_removed(G_GNUC_UNUSED PurpleAccount *account,
-                            G_GNUC_UNUSED const char *name)
-{
-	if (privacy_dialog != NULL)
-		rebuild_allow_list(privacy_dialog);
-}
-
-static void
-pidgin_deny_added_removed(G_GNUC_UNUSED PurpleAccount *account,
-                          G_GNUC_UNUSED const char *name)
-{
-	if (privacy_dialog != NULL)
-		rebuild_block_list(privacy_dialog);
-}
-
-void
-pidgin_privacy_init(void)
-{
-	PurpleAccountUiOps *ops = pidgin_accounts_get_ui_ops();
-
-	ops->permit_added = ops->permit_removed = pidgin_permit_added_removed;
-	ops->deny_added = ops->deny_removed = pidgin_deny_added_removed;
-}
diff --git a/pidgin/meson.build b/pidgin/meson.build
--- a/pidgin/meson.build
+++ b/pidgin/meson.build
@@ -11,7 +11,6 @@
 	'gtkmedia.c',
 	'gtknotify.c',
 	'gtkpluginpref.c',
-	'gtkprivacy.c',
 	'gtkrequest.c',
 	'gtkroomlist.c',
 	'gtksavedstatuses.c',
@@ -78,7 +77,6 @@
 	'gtkmedia.h',
 	'gtknotify.h',
 	'gtkpluginpref.h',
-	'gtkprivacy.h',
 	'gtkrequest.h',
 	'gtkroomlist.h',
 	'gtksavedstatuses.h',
diff --git a/pidgin/pidginapplication.c b/pidgin/pidginapplication.c
--- a/pidgin/pidginapplication.c
+++ b/pidgin/pidginapplication.c
@@ -37,7 +37,6 @@
 
 #include "gtkblist.h"
 #include "gtkdialogs.h"
-#include "gtkprivacy.h"
 #include "gtkroomlist.h"
 #include "gtksavedstatuses.h"
 #include "gtkxfer.h"
@@ -201,7 +200,6 @@
 	"add-group",
 	"get-user-info",
 	"new-message",
-	"privacy",
 	"set-mood",
 };
 
@@ -487,14 +485,6 @@
 }
 
 static void
-pidgin_application_privacy(G_GNUC_UNUSED GSimpleAction *simple,
-                           G_GNUC_UNUSED GVariant *parameter,
-                           G_GNUC_UNUSED gpointer data)
-{
-	pidgin_privacy_dialog_show();
-}
-
-static void
 pidgin_application_quit(G_GNUC_UNUSED GSimpleAction *simple,
                         G_GNUC_UNUSED GVariant *parameter,
                         G_GNUC_UNUSED gpointer data)
@@ -608,9 +598,6 @@
 		.name = "preferences",
 		.activate = pidgin_application_preferences,
 	}, {
-		.name = "privacy",
-		.activate = pidgin_application_privacy,
-	}, {
 		.name = "quit",
 		.activate = pidgin_application_quit,
 	}, {
diff --git a/pidgin/pidginui.c b/pidgin/pidginui.c
--- a/pidgin/pidginui.c
+++ b/pidgin/pidginui.c
@@ -38,7 +38,6 @@
 #include "gtkidle.h"
 #include "gtkmedia.h"
 #include "gtknotify.h"
-#include "gtkprivacy.h"
 #include "gtkroomlist.h"
 #include "gtkrequest.h"
 #include "gtkwhiteboard.h"
@@ -191,7 +190,6 @@
 	pidgin_blist_init();
 	pidgin_conversations_init();
 	pidgin_commands_init();
-	pidgin_privacy_init();
 	pidgin_xfers_init();
 	pidgin_roomlist_init();
 	pidgin_medias_init();
diff --git a/pidgin/resources/gtk/menus.ui b/pidgin/resources/gtk/menus.ui
--- a/pidgin/resources/gtk/menus.ui
+++ b/pidgin/resources/gtk/menus.ui
@@ -183,10 +183,6 @@
           <attribute name="accel">&lt;Primary&gt;P</attribute>
         </item>
         <item>
-          <attribute name="label" translatable="yes">Pr_ivacy</attribute>
-          <attribute name="action">app.privacy</attribute>
-        </item>
-        <item>
           <attribute name="label" translatable="yes">Set _Mood</attribute>
           <attribute name="action">app.set-mood</attribute>
           <attribute name="accel">&lt;Primary&gt;D</attribute>
diff --git a/po/POTFILES.in b/po/POTFILES.in
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -199,7 +199,6 @@
 libpurple/purpleprotocolim.c
 libpurple/purpleprotocolmanager.c
 libpurple/purpleprotocolmedia.c
-libpurple/purpleprotocolprivacy.c
 libpurple/purpleprotocolroomlist.c
 libpurple/purpleprotocolserver.c
 libpurple/purpleprotocolwhiteboard.c
@@ -250,7 +249,6 @@
 pidgin/gtkmedia.c
 pidgin/gtknotify.c
 pidgin/gtkpluginpref.c
-pidgin/gtkprivacy.c
 pidgin/gtkrequest.c
 pidgin/gtkroomlist.c
 pidgin/gtksavedstatuses.c
