Mercurial > pidgin
changeset 20107:d3bd5414eb0f
propagate from branch 'im.pidgin.pidgin' (head 41389df89a4a6a007d41cec33e33043cd41ea159)
to branch 'im.pidgin.cpw.resiak.disconnectreason' (head 04389226a6288dedc7867ed0ecabdd64350099b0)
author | Will Thompson <will.thompson@collabora.co.uk> |
---|---|
date | Mon, 17 Sep 2007 17:51:22 +0000 |
parents | 2d38b90bee15 (diff) bacfbe346b47 (current diff) |
children | 88b97e07f35f |
files | libpurple/connection.c libpurple/connection.h pidgin/gtkconn.c |
diffstat | 3 files changed, 154 insertions(+), 10 deletions(-) [+] |
line wrap: on
line diff
--- a/libpurple/connection.c Mon Sep 17 16:24:24 2007 +0000 +++ b/libpurple/connection.c Mon Sep 17 17:51:22 2007 +0000 @@ -488,28 +488,69 @@ void purple_connection_error(PurpleConnection *gc, const char *text) { + purple_connection_error_reason (gc, PURPLE_REASON_OTHER_ERROR, text); +} + +void +purple_connection_error_reason (PurpleConnection *gc, + PurpleDisconnectReason reason, + const char *description) +{ PurpleConnectionUiOps *ops; g_return_if_fail(gc != NULL); - if (text == NULL) { - purple_debug_error("connection", "purple_connection_error: check `text != NULL' failed\n"); - text = _("Unknown error"); + if (description == NULL) { + purple_debug_error("connection", "purple_connection_error_reason: check `description != NULL' failed\n"); + description = _("Unknown error"); } + g_assert (reason < PURPLE_NUM_REASONS); + /* If we've already got one error, we don't need any more */ if (gc->disconnect_timeout) return; ops = purple_connections_get_ui_ops(); - if (ops != NULL && ops->report_disconnect != NULL) - ops->report_disconnect(gc, text); + if (ops != NULL) + { + if (ops->report_disconnect_reason != NULL) + ops->report_disconnect_reason (gc, reason, description); + if (ops->report_disconnect != NULL) + ops->report_disconnect (gc, description); + } gc->disconnect_timeout = purple_timeout_add(0, purple_connection_disconnect_cb, purple_connection_get_account(gc)); } +gboolean +purple_connection_reason_is_fatal (PurpleDisconnectReason reason) +{ + switch (reason) + { + case PURPLE_REASON_NETWORK_ERROR: + return FALSE; + case PURPLE_REASON_AUTHENTICATION_FAILED: + case PURPLE_REASON_ENCRYPTION_ERROR: + case PURPLE_REASON_NAME_IN_USE: + case PURPLE_REASON_CERT_NOT_PROVIDED: + case PURPLE_REASON_CERT_UNTRUSTED: + case PURPLE_REASON_CERT_EXPIRED: + case PURPLE_REASON_CERT_NOT_ACTIVATED: + case PURPLE_REASON_CERT_HOSTNAME_MISMATCH: + case PURPLE_REASON_CERT_FINGERPRINT_MISMATCH: + case PURPLE_REASON_CERT_SELF_SIGNED: + case PURPLE_REASON_CERT_OTHER_ERROR: + case PURPLE_REASON_OTHER_ERROR: + return TRUE; + default: + g_assert_not_reached (); + return TRUE; + } +} + void purple_connections_disconnect_all(void) {
--- a/libpurple/connection.h Mon Sep 17 16:24:24 2007 +0000 +++ b/libpurple/connection.h Mon Sep 17 17:51:22 2007 +0000 @@ -55,6 +55,52 @@ } PurpleConnectionState; +/** Possible errors that can cause a connection to be closed. */ +typedef enum +{ + /** There was an error sending or receiving on the network socket. */ + PURPLE_REASON_NETWORK_ERROR = 0, + /** The username or password was invalid. */ + PURPLE_REASON_AUTHENTICATION_FAILED, + /** There was an error negotiating SSL on this connection, or encryption + * was unavailable and an account option was set to require it. + */ + PURPLE_REASON_ENCRYPTION_ERROR, + /** Someone is already connected to the server using the name you are + * trying to connect with. + */ + PURPLE_REASON_NAME_IN_USE, + + /** The server did not provide a SSL certificate. */ + PURPLE_REASON_CERT_NOT_PROVIDED, + /** The server's SSL certificate could not be trusted. */ + PURPLE_REASON_CERT_UNTRUSTED, + /** The server's SSL certificate has expired. */ + PURPLE_REASON_CERT_EXPIRED, + /** The server's SSL certificate is not yet valid. */ + PURPLE_REASON_CERT_NOT_ACTIVATED, + /** The server's SSL certificate did not match its hostname. */ + PURPLE_REASON_CERT_HOSTNAME_MISMATCH, + /** The server's SSL certificate does not have the expected + * fingerprint. + */ + PURPLE_REASON_CERT_FINGERPRINT_MISMATCH, + /** The server's SSL certificate is self-signed. */ + PURPLE_REASON_CERT_SELF_SIGNED, + /** There was some other error validating the server's SSL certificate. + */ + PURPLE_REASON_CERT_OTHER_ERROR, + + /** Some other error occured which fits into none of the other + * categories. + */ + PURPLE_REASON_OTHER_ERROR, + + /** The number of PurpleDisconnectReason elements; not a valid reason. + */ + PURPLE_NUM_REASONS +} PurpleDisconnectReason; + #include <time.h> #include "account.h" @@ -74,11 +120,13 @@ * the UI of what is happening, as well as which @a step out of @a * step_count has been reached (which might be displayed as a progress * bar). + * @see #purple_connection_update_progress */ void (*connect_progress)(PurpleConnection *gc, const char *text, size_t step, size_t step_count); + /** Called when a connection is established (just before the * @ref signed-on signal). */ @@ -87,17 +135,23 @@ * and @ref signed-off signals). */ void (*disconnected)(PurpleConnection *gc); + /** Used to display connection-specific notices. (Pidgin's Gtk user * interface implements this as a no-op; #purple_connection_notice(), * which uses this operation, is not used by any of the protocols * shipped with libpurple.) */ void (*notice)(PurpleConnection *gc, const char *text); + /** Called when an error causes a connection to be disconnected. * Called before #disconnected. * @param text a localized error message. + * @see #purple_connection_error + * @deprecated in favour of + * #PurpleConnectionUiOps.report_disconnect_reason. */ void (*report_disconnect)(PurpleConnection *gc, const char *text); + /** Called when libpurple discovers that the computer's network * connection is active. On Linux, this uses Network Manager if * available; on Windows, it uses Win32's network change notification @@ -109,10 +163,21 @@ */ void (*network_disconnected)(); + /** Called when a connection is disconnected, whether due to an + * error or to user request. Called before #disconnected. + * @param reason why the connection ended, if known, or + * PURPLE_REASON_OTHER_ERROR, if not. + * @param text a localized message describing the disconnection + * in more detail to the user. + * @see #purple_connection_error_reason + */ + void (*report_disconnect_reason)(PurpleConnection *gc, + PurpleDisconnectReason reason, + const char *text); + void (*_purple_reserved1)(void); void (*_purple_reserved2)(void); void (*_purple_reserved3)(void); - void (*_purple_reserved4)(void); } PurpleConnectionUiOps; struct _PurpleConnection @@ -290,9 +355,44 @@ * * @param gc The connection. * @param reason The error text. + * @deprecated in favour of #purple_connection_error_reason. Calling + * @c purple_connection_error(gc, text) is equivalent to calling + * @c purple_connection_error_reason(gc, PURPLE_REASON_OTHER_ERROR, text). */ void purple_connection_error(PurpleConnection *gc, const char *reason); +/** + * Closes a connection with an error and an optional description of the + * error. + * + * @param reason why the connection is closing. + * @param description a localized description of the error. + */ +void +purple_connection_error_reason (PurpleConnection *gc, + PurpleDisconnectReason reason, + const char *description); + +/** + * Reports whether a disconnection reason is fatal (in which case the account + * should probably not be automatically reconnected) or transient (so + * auto-reconnection is a good idea. + * For instance, #PURPLE_REASON_NETWORK_ERROR is a temporary + * error, which might be caused by losing the network connection, so + * @a purple_connection_reason_is_fatal(PURPLE_REASON_NETWORK_ERROR) is + * @a FALSE. On the other hand, #PURPLE_REASON_AUTHENTICATION_FAILED probably + * indicates a misconfiguration of the account which needs the user to go fix + * it up, so @a + * purple_connection_reason_is_fatal(PURPLE_REASON_AUTHENTICATION_FAILED) + * is @a TRUE. + * + * (This function is meant to replace checking PurpleConnection.wants_to_die.) + * + * @return @a TRUE iff automatic reconnection is a bad idea. + */ +gboolean +purple_connection_reason_is_fatal (PurpleDisconnectReason reason); + /*@}*/ /**************************************************************************/
--- a/pidgin/gtkconn.c Mon Sep 17 16:24:24 2007 +0000 +++ b/pidgin/gtkconn.c Mon Sep 17 17:51:22 2007 +0000 @@ -42,6 +42,7 @@ #define INITIAL_RECON_DELAY_MAX 60000 #define MAX_RECON_DELAY 600000 +#define MAX_RACCOON_DELAY "shorter in urban areas" typedef struct { int delay; @@ -137,7 +138,9 @@ } static void -pidgin_connection_report_disconnect(PurpleConnection *gc, const char *text) +pidgin_connection_report_disconnect_reason (PurpleConnection *gc, + PurpleDisconnectReason reason, + const char *text) { PurpleAccount *account = NULL; PidginAutoRecon *info; @@ -146,7 +149,7 @@ info = g_hash_table_lookup(auto_reconns, account); pidgin_blist_update_account_error_state(account, text); - if (!gc->wants_to_die) { + if (!purple_connection_reason_is_fatal (reason)) { if (info == NULL) { info = g_new0(PidginAutoRecon, 1); g_hash_table_insert(auto_reconns, account, info); @@ -247,10 +250,10 @@ pidgin_connection_connected, pidgin_connection_disconnected, pidgin_connection_notice, - pidgin_connection_report_disconnect, + NULL, /* report_disconnect */ pidgin_connection_network_connected, pidgin_connection_network_disconnected, - NULL, + pidgin_connection_report_disconnect_reason, NULL, NULL, NULL