Mercurial > pidgin.yaz
diff finch/gntconn.c @ 17977:f71bd7e56389
propagate from branch 'im.pidgin.pidgin' (head b438ea0760758dc547f95d62892455f50ee4c4f1)
to branch 'im.pidgin.soc.2007.remotelogging' (head 7e683fd40634aa3eb22dcf25cbd25c8959d76662)
author | Michael Shkutkov <mshkutkov@soc.pidgin.im> |
---|---|
date | Sat, 09 Jun 2007 12:01:29 +0000 |
parents | 8c3a3407af58 |
children | 392889212240 |
line wrap: on
line diff
--- a/finch/gntconn.c Sun Apr 22 11:11:49 2007 +0000 +++ b/finch/gntconn.c Sat Jun 09 12:01:29 2007 +0000 @@ -24,42 +24,131 @@ */ #include "account.h" #include "core.h" +#include "connection.c" +#include "debug.h" #include "request.h" #include "gntconn.h" #include "finch.h" +#define INITIAL_RECON_DELAY_MIN 8000 +#define INITIAL_RECON_DELAY_MAX 60000 + +#define MAX_RECON_DELAY 600000 + +typedef struct { + int delay; + guint timeout; +} FinchAutoRecon; + +/** + * Contains accounts that are auto-reconnecting. + * The key is a pointer to the PurpleAccount and the + * value is a pointer to a FinchAutoRecon. + */ +static GHashTable *hash = NULL; + +static void +free_auto_recon(gpointer data) +{ + FinchAutoRecon *info = data; + + if (info->timeout != 0) + g_source_remove(info->timeout); + + g_free(info); +} + + +static gboolean +do_signon(gpointer data) +{ + PurpleAccount *account = data; + FinchAutoRecon *info; + PurpleStatus *status; + + purple_debug_info("autorecon", "do_signon called\n"); + g_return_val_if_fail(account != NULL, FALSE); + info = g_hash_table_lookup(hash, account); + + if (info) + info->timeout = 0; + + status = purple_account_get_active_status(account); + if (purple_status_is_online(status)) + { + purple_debug_info("autorecon", "calling purple_account_connect\n"); + purple_account_connect(account); + purple_debug_info("autorecon", "done calling purple_account_connect\n"); + } + + return FALSE; +} + static void finch_connection_report_disconnect(PurpleConnection *gc, const char *text) { - char *act, *primary, *secondary; + FinchAutoRecon *info; PurpleAccount *account = purple_connection_get_account(gc); - act = g_strdup_printf(_("%s (%s)"), purple_account_get_username(account), - purple_account_get_protocol_name(account)); + info = g_hash_table_lookup(hash, account); - primary = g_strdup_printf(_("%s disconnected."), act); - secondary = g_strdup_printf(_("%s was disconnected due to the following error:\n%s"), - act, text); + if (!gc->wants_to_die) { + if (info == NULL) { + info = g_new0(FinchAutoRecon, 1); + g_hash_table_insert(hash, account, info); + info->delay = g_random_int_range(INITIAL_RECON_DELAY_MIN, INITIAL_RECON_DELAY_MAX); + } else { + info->delay = MIN(2 * info->delay, MAX_RECON_DELAY); + if (info->timeout != 0) + g_source_remove(info->timeout); + } + info->timeout = g_timeout_add(info->delay, do_signon, account); + } else { + char *act, *primary, *secondary; + act = g_strdup_printf(_("%s (%s)"), purple_account_get_username(account), + purple_account_get_protocol_name(account)); - purple_request_action(account, _("Connection Error"), primary, secondary, 1, - account, 2, - _("OK"), NULL, - _("Connect"), - PURPLE_CALLBACK(purple_account_connect)); + primary = g_strdup_printf(_("%s disconnected."), act); + secondary = g_strdup_printf(_("%s\n\n" + "Finch will not attempt to reconnect the account until you " + "correct the error and re-enable the account."), text); + purple_notify_error(NULL, NULL, primary, secondary); + + g_free(act); + g_free(primary); + g_free(secondary); + purple_account_set_enabled(account, FINCH_UI, FALSE); + } +} - g_free(act); - g_free(primary); - g_free(secondary); +static void +account_removed_cb(PurpleAccount *account, gpointer user_data) +{ + g_hash_table_remove(hash, account); +} + +static void * +finch_connection_get_handle(void) +{ + static int handle; + + return &handle; } static PurpleConnectionUiOps ops = { - .connect_progress = NULL, - .connected = NULL, - .disconnected = NULL, - .notice = NULL, - .report_disconnect = finch_connection_report_disconnect + NULL, /* connect_progress */ + NULL, /* connected */ + NULL, /* disconnected */ + NULL, /* notice */ + finch_connection_report_disconnect, + NULL, /* network_connected */ + NULL, /* network_disconnected */ + NULL, + NULL, + NULL, + NULL }; PurpleConnectionUiOps *finch_connections_get_ui_ops() @@ -68,8 +157,18 @@ } void finch_connections_init() -{} +{ + hash = g_hash_table_new_full( + g_direct_hash, g_direct_equal, + NULL, free_auto_recon); + + purple_signal_connect(purple_accounts_get_handle(), "account-removed", + finch_connection_get_handle(), + PURPLE_CALLBACK(account_removed_cb), NULL); +} void finch_connections_uninit() -{} - +{ + purple_signals_disconnect_by_handle(finch_connection_get_handle()); + g_hash_table_destroy(hash); +}