# HG changeset patch
# Node ID 532cac028b9c58d369a0b86bb36bfae78cc8dc48
# Parent  006b071042ed1841c83c1ed943672ff0482f8aad
diff --git a/libpurple/accounts.c b/libpurple/accounts.c
--- a/libpurple/accounts.c
+++ b/libpurple/accounts.c
@@ -521,32 +521,9 @@
 	return &handle;
 }
 
-static void
-connection_error_cb(PurpleConnection *gc,
-                    PurpleConnectionError type,
-                    const gchar *description,
-                    G_GNUC_UNUSED gpointer unused)
-{
-	PurpleAccount *account;
-	PurpleConnectionErrorInfo *err;
-
-	account = purple_connection_get_account(gc);
-
-	g_return_if_fail(account != NULL);
-
-	err = purple_connection_error_info_new(type, description);
-	purple_account_set_error(account, err);
-}
-
 void
 purple_accounts_init(void)
 {
-	void *handle = purple_accounts_get_handle();
-	void *conn_handle = purple_connections_get_handle();
-
-	purple_signal_connect(conn_handle, "connection-error", handle,
-	                      G_CALLBACK(connection_error_cb), NULL);
-
 	load_accounts();
 
 	g_signal_connect(G_OBJECT(g_network_monitor_get_default()),
diff --git a/libpurple/connection.c b/libpurple/connection.c
--- a/libpurple/connection.c
+++ b/libpurple/connection.c
@@ -46,20 +46,6 @@
 
 	PurpleAccount *account;       /* The account being connected to.   */
 	char *password;               /* The password used.                */
-
-	/* Wants to Die state.  This is set when the user chooses to log out, or
-	 * when the protocol is disconnected and should not be automatically
-	 * reconnected (incorrect password, etc.).  Protocols should rely on
-	 * purple_connection_error() to set this for them rather than
-	 * setting it themselves.
-	 * See purple_connection_error_is_fatal()
-	 */
-	gboolean wants_to_die;
-
-	/* The connection error and its description if an error occurred. */
-	PurpleConnectionErrorInfo *error_info;
-
-	guint disconnect_timeout;  /* Timer used for nasty stack tricks. */
 } PurpleConnectionPrivate;
 
 enum {
@@ -75,8 +61,6 @@
 
 static GParamSpec *properties[N_PROPERTIES] = {NULL, };
 
-static int connections_handle;
-
 G_DEFINE_TYPE_WITH_PRIVATE(PurpleConnection, purple_connection, G_TYPE_OBJECT)
 
 /**************************************************************************
@@ -197,165 +181,6 @@
 }
 
 gboolean
-_purple_connection_wants_to_die(PurpleConnection *connection) {
-	PurpleConnectionPrivate *priv = NULL;
-
-	g_return_val_if_fail(PURPLE_IS_CONNECTION(connection), FALSE);
-
-	priv = purple_connection_get_instance_private(connection);
-
-	return priv->wants_to_die;
-}
-
-static gboolean
-purple_connection_disconnect_cb(gpointer data) {
-	PurpleAccount *account = data;
-	PurpleConnection *connection;
-
-	connection = purple_account_get_connection(account);
-
-	if(PURPLE_IS_CONNECTION(connection)) {
-		PurpleConnectionPrivate *priv = NULL;
-
-		priv = purple_connection_get_instance_private(connection);
-
-		priv->disconnect_timeout = 0;
-
-		if(priv->state != PURPLE_CONNECTION_STATE_DISCONNECTED) {
-			/* If the connection is not disconnected, disconnect it. */
-			purple_account_disconnect(account);
-		} else {
-			/* Otherwise assume the connection was already disconnected or in
-			 * the process of being disconnected and we just need to finish our
-			 * cleanup.
-			 */
-			GError *error = NULL;
-
-			if(!purple_connection_disconnect(connection, &error)) {
-				const char *message = "unknown error";
-
-				if(error != NULL) {
-					message = error->message;
-				}
-
-				purple_debug_warning("connections",
-				                     "failed to disconnect %p : %s",
-				                     connection, message);
-			}
-
-			g_clear_error(&error);
-
-			purple_account_set_connection(account, NULL);
-		}
-	}
-
-	return G_SOURCE_REMOVE;
-}
-
-void
-purple_connection_error(PurpleConnection *connection,
-                        PurpleConnectionError reason,
-                        const char *description)
-{
-	PurpleConnectionPrivate *priv = NULL;
-
-	g_return_if_fail(PURPLE_IS_CONNECTION(connection));
-
-	priv = purple_connection_get_instance_private(connection);
-
-	/* This sanity check relies on PURPLE_CONNECTION_ERROR_OTHER_ERROR
-	 * being the last member of the PurpleConnectionError enum in
-	 * connection.h; if other reasons are added after it, this check should
-	 * be updated.
-	 */
-	if(reason > PURPLE_CONNECTION_ERROR_OTHER_ERROR) {
-		purple_debug_error("connection",
-			"purple_connection_error: reason %u isn't a "
-			"valid reason\n", reason);
-		reason = PURPLE_CONNECTION_ERROR_OTHER_ERROR;
-	}
-
-	if(description == NULL) {
-		purple_debug_error("connection", "purple_connection_error called with NULL description\n");
-		description = _("Unknown error");
-	}
-
-	/* If we've already got one error, we don't need any more */
-	if(priv->error_info != NULL) {
-		return;
-	}
-
-	priv->wants_to_die = purple_connection_error_is_fatal(reason);
-
-	purple_debug_info("connection",
-	                  "Connection error on %p (reason: %u description: %s)\n",
-	                  connection, reason, description);
-
-	priv->error_info = purple_connection_error_info_new(reason, description);
-
-	purple_signal_emit(purple_connections_get_handle(), "connection-error",
-	                   connection, reason, description);
-
-	priv->disconnect_timeout = g_timeout_add(0, purple_connection_disconnect_cb,
-	                                         priv->account);
-}
-
-PurpleConnectionErrorInfo *
-purple_connection_get_error_info(PurpleConnection *connection) {
-	PurpleConnectionPrivate *priv = NULL;
-
-	g_return_val_if_fail(PURPLE_IS_CONNECTION(connection), NULL);
-
-	priv = purple_connection_get_instance_private(connection);
-
-	return priv->error_info;
-}
-
-void
-purple_connection_g_error(PurpleConnection *connection, const GError *error) {
-	PurpleConnectionError reason;
-
-	if(g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
-		/* Not a connection error. Ignore. */
-		return;
-	}
-
-	if(error->domain == G_TLS_ERROR) {
-		switch (error->code) {
-		case G_TLS_ERROR_UNAVAILABLE:
-			reason = PURPLE_CONNECTION_ERROR_NO_SSL_SUPPORT;
-			break;
-		case G_TLS_ERROR_NOT_TLS:
-		case G_TLS_ERROR_HANDSHAKE:
-			reason = PURPLE_CONNECTION_ERROR_ENCRYPTION_ERROR;
-			break;
-		case G_TLS_ERROR_BAD_CERTIFICATE:
-		case G_TLS_ERROR_CERTIFICATE_REQUIRED:
-			reason = PURPLE_CONNECTION_ERROR_CERT_OTHER_ERROR;
-			break;
-		case G_TLS_ERROR_EOF:
-		case G_TLS_ERROR_MISC:
-		default:
-			reason = PURPLE_CONNECTION_ERROR_NETWORK_ERROR;
-		}
-	} else if (error->domain == G_IO_ERROR) {
-		reason = PURPLE_CONNECTION_ERROR_NETWORK_ERROR;
-	} else if (error->domain == PURPLE_CONNECTION_ERROR) {
-		reason = error->code;
-	} else {
-		reason = PURPLE_CONNECTION_ERROR_OTHER_ERROR;
-	}
-
-	purple_connection_error(connection, reason, error->message);
-}
-
-void
-purple_connection_take_error(PurpleConnection *connection, GError *error) {
-	purple_connection_g_error(connection, error);
-	g_error_free(error);
-}
-
-gboolean
 purple_connection_error_is_fatal(PurpleConnectionError reason) {
 	switch (reason) {
 	case PURPLE_CONNECTION_ERROR_NETWORK_ERROR:
@@ -516,8 +341,6 @@
 
 	g_clear_object(&priv->account);
 
-	g_clear_handle_id(&priv->disconnect_timeout, g_source_remove);
-
 	G_OBJECT_CLASS(purple_connection_parent_class)->dispose(obj);
 }
 
@@ -528,8 +351,6 @@
 
 	priv = purple_connection_get_instance_private(connection);
 
-	g_clear_pointer(&priv->error_info, purple_connection_error_info_free);
-
 	purple_str_wipe(priv->password);
 	g_free(priv->id);
 
@@ -716,26 +537,3 @@
 
 	return priv->cancellable;
 }
-
-/**************************************************************************
- * Connections API
- **************************************************************************/
-void
-purple_connections_init(void) {
-	void *handle = purple_connections_get_handle();
-
-	purple_signal_register(handle, "connection-error",
-	                       purple_marshal_VOID__POINTER_INT_POINTER,
-	                       G_TYPE_NONE, 3, PURPLE_TYPE_CONNECTION,
-	                       PURPLE_TYPE_CONNECTION_ERROR, G_TYPE_STRING);
-}
-
-void
-purple_connections_uninit(void) {
-	purple_signals_unregister_by_instance(purple_connections_get_handle());
-}
-
-void *
-purple_connections_get_handle(void) {
-	return &connections_handle;
-}
diff --git a/libpurple/connection.h b/libpurple/connection.h
--- a/libpurple/connection.h
+++ b/libpurple/connection.h
@@ -254,70 +254,6 @@
 GCancellable *purple_connection_get_cancellable(PurpleConnection *connection);
 
 /**
- * purple_connection_error:
- * @connection: The connection which is closing.
- * @reason: Why the connection is closing.
- * @description: A localized description of the error.
- *
- * Closes a connection with an error and a human-readable description of the
- * error.
- *
- * Since: 2.0
- */
-PURPLE_AVAILABLE_IN_ALL
-void purple_connection_error(PurpleConnection *connection, PurpleConnectionError reason, const char *description);
-
-/**
- * purple_connection_get_error_info:
- * @connection: The connection.
- *
- * Returns the #PurpleConnectionErrorInfo instance of a connection if an
- * error exists.
- *
- * Returns: The #PurpleConnectionErrorInfo instance of the connection if an
- *          error exists, %NULL otherwise.
- *
- * Since: 3.0
- */
-PURPLE_AVAILABLE_IN_3_0
-PurpleConnectionErrorInfo *purple_connection_get_error_info(PurpleConnection *connection);
-
-/**
- * purple_connection_g_error:
- * @connection: Connection the error is associated with
- * @error: Error information
- *
- * Closes a connection similar to [method@Purple.Connection.error], but takes a
- * [type@GLib.Error] which is then converted to purple error codes.
- *
- * This function ignores G_IO_ERROR_CANCELLED, returning without
- * closing the connection. This can be used as a shortcut when
- * cancelling connections, as this is commonly done when shutting
- * down a connection. If G_IO_ERROR_CANCELLED needs to be caught,
- * do so with [method@GLib.Error.matches] prior to calling this function.
- *
- * Since: 3.0
- */
-PURPLE_AVAILABLE_IN_3_0
-void purple_connection_g_error(PurpleConnection *connection, const GError *error);
-
-/**
- * purple_connection_take_error:
- * @connection: Connection the error is associated with
- * @error: Return address for a #GError, or %NULL.
- *
- * Closes a connection similar to [method@Purple.Connection.error], but takes a
- * [type@GLib.Error] which is then converted to purple error codes.
- *
- * This function is equivalent to [method@Purple.Connection.g_error], expect
- * that it takes ownership of the GError.
- *
- * Since: 3.0
- */
-PURPLE_AVAILABLE_IN_3_0
-void purple_connection_take_error(PurpleConnection *connection, GError *error);
-
-/**
  * purple_connection_error_is_fatal:
  * @reason: The connection error to check.
  *
@@ -344,42 +280,6 @@
 PURPLE_AVAILABLE_IN_ALL
 gboolean purple_connection_error_is_fatal(PurpleConnectionError reason);
 
-/**************************************************************************/
-/* Connections Subsystem                                                  */
-/**************************************************************************/
-
-/**
- * purple_connections_init:
- *
- * Initializes the connections subsystem.
- *
- * Since: 2.0
- */
-PURPLE_AVAILABLE_IN_ALL
-void purple_connections_init(void);
-
-/**
- * purple_connections_uninit:
- *
- * Uninitializes the connections subsystem.
- *
- * Since: 2.0
- */
-PURPLE_AVAILABLE_IN_ALL
-void purple_connections_uninit(void);
-
-/**
- * purple_connections_get_handle:
- *
- * Returns the handle to the connections subsystem.
- *
- * Returns: The connections subsystem handle.
- *
- * Since: 2.0
- */
-PURPLE_AVAILABLE_IN_ALL
-void *purple_connections_get_handle(void);
-
 G_END_DECLS
 
 #endif /* PURPLE_CONNECTION_H */
diff --git a/libpurple/core.c b/libpurple/core.c
--- a/libpurple/core.c
+++ b/libpurple/core.c
@@ -26,7 +26,6 @@
 #define G_SETTINGS_ENABLE_BACKEND
 #include <gio/gsettingsbackend.h>
 
-#include "connection.h"
 #include "core.h"
 #include "debug.h"
 #include "network.h"
@@ -134,8 +133,6 @@
 	 */
 	purple_plugins_init();
 
-	purple_connections_init();
-
 	purple_account_manager_startup();
 	purple_accounts_init();
 	purple_contact_manager_startup();
@@ -208,7 +205,6 @@
 	purple_idle_manager_shutdown();
 	purple_whiteboard_manager_shutdown();
 	purple_conversation_manager_shutdown();
-	purple_connections_uninit();
 	purple_presence_manager_shutdown();
 	purple_accounts_uninit();
 	purple_proxy_uninit();
diff --git a/libpurple/purpleaccount.c b/libpurple/purpleaccount.c
--- a/libpurple/purpleaccount.c
+++ b/libpurple/purpleaccount.c
@@ -184,17 +184,18 @@
 
 	purple_account_set_connection(account, connection);
 	if(!purple_connection_connect(connection, &error)) {
+		PurpleConnectionErrorInfo *error_info = NULL;
 		const char *message = "unknown error";
 
 		if(error != NULL && error->message != NULL) {
 			message = error->message;
 		}
 
-		purple_connection_error(connection,
-		                        PURPLE_CONNECTION_ERROR_OTHER_ERROR,
-		                        message);
+		error_info = purple_connection_error_info_new(PURPLE_CONNECTION_ERROR_OTHER_ERROR,
+		                                              message);
+		g_clear_error(&error);
 
-		g_clear_error(&error);
+		purple_account_set_error(account, error_info);
 	}
 
 	/* Finally remove our reference to the connection. */
@@ -1304,7 +1305,6 @@
 
 void
 purple_account_set_enabled(PurpleAccount *account, gboolean value) {
-	PurpleConnection *gc;
 	gboolean was_enabled = FALSE;
 
 	g_return_if_fail(PURPLE_IS_ACCOUNT(account));
@@ -1315,11 +1315,6 @@
 		g_object_notify_by_pspec(G_OBJECT(account), properties[PROP_ENABLED]);
 	}
 
-	gc = purple_account_get_connection(account);
-	if(gc != NULL && _purple_connection_wants_to_die(gc)) {
-		return;
-	}
-
 	if(value && purple_presence_is_online(account->presence)) {
 		purple_account_connect(account);
 	} else if (!value && !purple_account_is_disconnected(account)) {
diff --git a/libpurple/purpleprivate.h b/libpurple/purpleprivate.h
--- a/libpurple/purpleprivate.h
+++ b/libpurple/purpleprivate.h
@@ -32,7 +32,6 @@
 
 #include "core.h"
 #include "accounts.h"
-#include "connection.h"
 #include "purplecredentialprovider.h"
 #include "purplehistoryadapter.h"
 #include "purpleversion.h"
@@ -52,18 +51,6 @@
 PurpleXmlNode *_purple_account_to_xmlnode(PurpleAccount *account);
 
 /**
- * _purple_connection_wants_to_die:
- * @gc:  The connection to check
- *
- * Checks if a connection is disconnecting, and should not attempt to reconnect.
- *
- * Note: This function should only be called by purple_account_set_enabled()
- *       in account.c.
- */
-G_GNUC_INTERNAL
-gboolean _purple_connection_wants_to_die(PurpleConnection *gc);
-
-/**
  * purple_account_manager_startup:
  *
  * Starts up the account manager by creating the default instance.
diff --git a/libpurple/reference/libpurple.toml.in b/libpurple/reference/libpurple.toml.in
--- a/libpurple/reference/libpurple.toml.in
+++ b/libpurple/reference/libpurple.toml.in
@@ -38,7 +38,6 @@
 # The same order will be used when generating the index
 content_files = [
 	"contributing.md",
-	"signals_connection.md",
 	"tut_c_plugins.md",
 ]
 content_images = [
diff --git a/libpurple/reference/meson.build b/libpurple/reference/meson.build
--- a/libpurple/reference/meson.build
+++ b/libpurple/reference/meson.build
@@ -1,6 +1,5 @@
 libpurple_doc_content_files = [
 	'contributing.md',
-	'signals_connection.md',
 	'tut_c_plugins.md',
 ]
 
diff --git a/libpurple/reference/signals_connection.md b/libpurple/reference/signals_connection.md
deleted file mode 100644
--- a/libpurple/reference/signals_connection.md
+++ /dev/null
@@ -1,35 +0,0 @@
-Title: Connection Signals
-Slug: connection-signals
-
-## Connection Signals
-
-### Signal List
-
-* [connection-error](#connection-error)
-
-### Signal Details
-
-#### connection-error
-
-```c
-void user_function(PurpleConnection *gc,
-                   PurpleConnectionError err,
-                   const gchar *desc,
-                   gpointer user_data);
-```
-
-Emitted when a connection error occurs, before `"signed"`-off.
-
-**Parameters:**
-
-**gc**
-: The connection on which the error has occurred.
-
-**err**
-: The error that occurred.
-
-**desc**
-: A description of the error, giving more information.
-
-**user_data**
-: user data set when the signal handler was connected.
diff --git a/protocols/demo/purpledemoprotocolactions.c b/protocols/demo/purpledemoprotocolactions.c
--- a/protocols/demo/purpledemoprotocolactions.c
+++ b/protocols/demo/purpledemoprotocolactions.c
@@ -42,6 +42,7 @@
                                   const char *disconnect_str)
 {
 	PurpleConnection *connection = PURPLE_CONNECTION(data);
+	PurpleConnectionErrorInfo *error_info = NULL;
 	PurpleAccount *account = purple_connection_get_account(connection);
 	char *message = NULL;
 	int timeout = 0;
@@ -74,9 +75,12 @@
 	}
 
 	message = g_strdup_printf(_(disconnect_str), REAPER_BUDDY_NAME);
-	purple_connection_error(connection, error_code, message);
+	error_info = purple_connection_error_info_new(error_code, message);
 	g_free(message);
 
+	purple_account_set_error(account, error_info);
+	purple_account_disconnect(account);
+
 	return G_SOURCE_REMOVE;
 }
 
diff --git a/protocols/ircv3/purpleircv3connection.c b/protocols/ircv3/purpleircv3connection.c
--- a/protocols/ircv3/purpleircv3connection.c
+++ b/protocols/ircv3/purpleircv3connection.c
@@ -551,7 +551,13 @@
 
 	error = ibis_client_get_error(client);
 	if(error != NULL) {
-		purple_connection_g_error(connection, error);
+		PurpleAccount *account = purple_connection_get_account(connection);
+		PurpleConnectionErrorInfo *error_info = NULL;
+
+		error_info = purple_connection_error_info_new(PURPLE_CONNECTION_ERROR_OTHER_ERROR,
+		                                              error->message);
+		purple_account_set_error(account, error_info);
+		purple_account_disconnect(account);
 	}
 }
 
diff --git a/protocols/xmpp/purplexmppconnection.c b/protocols/xmpp/purplexmppconnection.c
--- a/protocols/xmpp/purplexmppconnection.c
+++ b/protocols/xmpp/purplexmppconnection.c
@@ -49,7 +49,14 @@
 	output = xeme_connection_connect_finish(XEME_CONNECTION(source), result,
 	                                        &error);
 	if(error != NULL) {
-		purple_connection_take_error(PURPLE_CONNECTION(connection), error);
+		PurpleAccount *account = NULL;
+		PurpleConnectionErrorInfo *error_info = NULL;
+
+		account = purple_connection_get_account(PURPLE_CONNECTION(connection));
+		error_info = purple_connection_error_info_new(PURPLE_CONNECTION_ERROR_OTHER_ERROR,
+		                                              error->message);
+		purple_account_set_error(account, error_info);
+		purple_account_disconnect(account);
 
 		return;
 	}
