comparison 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
comparison
equal deleted inserted replaced
16392:9da82444eee3 17977:f71bd7e56389
22 * along with this program; if not, write to the Free Software 22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 */ 24 */
25 #include "account.h" 25 #include "account.h"
26 #include "core.h" 26 #include "core.h"
27 #include "connection.c"
28 #include "debug.h"
27 #include "request.h" 29 #include "request.h"
28 30
29 #include "gntconn.h" 31 #include "gntconn.h"
30 #include "finch.h" 32 #include "finch.h"
31 33
34 #define INITIAL_RECON_DELAY_MIN 8000
35 #define INITIAL_RECON_DELAY_MAX 60000
36
37 #define MAX_RECON_DELAY 600000
38
39 typedef struct {
40 int delay;
41 guint timeout;
42 } FinchAutoRecon;
43
44 /**
45 * Contains accounts that are auto-reconnecting.
46 * The key is a pointer to the PurpleAccount and the
47 * value is a pointer to a FinchAutoRecon.
48 */
49 static GHashTable *hash = NULL;
50
51 static void
52 free_auto_recon(gpointer data)
53 {
54 FinchAutoRecon *info = data;
55
56 if (info->timeout != 0)
57 g_source_remove(info->timeout);
58
59 g_free(info);
60 }
61
62
63 static gboolean
64 do_signon(gpointer data)
65 {
66 PurpleAccount *account = data;
67 FinchAutoRecon *info;
68 PurpleStatus *status;
69
70 purple_debug_info("autorecon", "do_signon called\n");
71 g_return_val_if_fail(account != NULL, FALSE);
72 info = g_hash_table_lookup(hash, account);
73
74 if (info)
75 info->timeout = 0;
76
77 status = purple_account_get_active_status(account);
78 if (purple_status_is_online(status))
79 {
80 purple_debug_info("autorecon", "calling purple_account_connect\n");
81 purple_account_connect(account);
82 purple_debug_info("autorecon", "done calling purple_account_connect\n");
83 }
84
85 return FALSE;
86 }
87
32 static void 88 static void
33 finch_connection_report_disconnect(PurpleConnection *gc, const char *text) 89 finch_connection_report_disconnect(PurpleConnection *gc, const char *text)
34 { 90 {
35 char *act, *primary, *secondary; 91 FinchAutoRecon *info;
36 PurpleAccount *account = purple_connection_get_account(gc); 92 PurpleAccount *account = purple_connection_get_account(gc);
37 93
38 act = g_strdup_printf(_("%s (%s)"), purple_account_get_username(account), 94 info = g_hash_table_lookup(hash, account);
39 purple_account_get_protocol_name(account));
40 95
41 primary = g_strdup_printf(_("%s disconnected."), act); 96 if (!gc->wants_to_die) {
42 secondary = g_strdup_printf(_("%s was disconnected due to the following error:\n%s"), 97 if (info == NULL) {
43 act, text); 98 info = g_new0(FinchAutoRecon, 1);
99 g_hash_table_insert(hash, account, info);
100 info->delay = g_random_int_range(INITIAL_RECON_DELAY_MIN, INITIAL_RECON_DELAY_MAX);
101 } else {
102 info->delay = MIN(2 * info->delay, MAX_RECON_DELAY);
103 if (info->timeout != 0)
104 g_source_remove(info->timeout);
105 }
106 info->timeout = g_timeout_add(info->delay, do_signon, account);
107 } else {
108 char *act, *primary, *secondary;
109 act = g_strdup_printf(_("%s (%s)"), purple_account_get_username(account),
110 purple_account_get_protocol_name(account));
44 111
45 purple_request_action(account, _("Connection Error"), primary, secondary, 1, 112 primary = g_strdup_printf(_("%s disconnected."), act);
46 account, 2, 113 secondary = g_strdup_printf(_("%s\n\n"
47 _("OK"), NULL, 114 "Finch will not attempt to reconnect the account until you "
48 _("Connect"), 115 "correct the error and re-enable the account."), text);
49 PURPLE_CALLBACK(purple_account_connect)); 116 purple_notify_error(NULL, NULL, primary, secondary);
50 117
51 g_free(act); 118 g_free(act);
52 g_free(primary); 119 g_free(primary);
53 g_free(secondary); 120 g_free(secondary);
121 purple_account_set_enabled(account, FINCH_UI, FALSE);
122 }
123 }
124
125 static void
126 account_removed_cb(PurpleAccount *account, gpointer user_data)
127 {
128 g_hash_table_remove(hash, account);
129 }
130
131 static void *
132 finch_connection_get_handle(void)
133 {
134 static int handle;
135
136 return &handle;
54 } 137 }
55 138
56 static PurpleConnectionUiOps ops = 139 static PurpleConnectionUiOps ops =
57 { 140 {
58 .connect_progress = NULL, 141 NULL, /* connect_progress */
59 .connected = NULL, 142 NULL, /* connected */
60 .disconnected = NULL, 143 NULL, /* disconnected */
61 .notice = NULL, 144 NULL, /* notice */
62 .report_disconnect = finch_connection_report_disconnect 145 finch_connection_report_disconnect,
146 NULL, /* network_connected */
147 NULL, /* network_disconnected */
148 NULL,
149 NULL,
150 NULL,
151 NULL
63 }; 152 };
64 153
65 PurpleConnectionUiOps *finch_connections_get_ui_ops() 154 PurpleConnectionUiOps *finch_connections_get_ui_ops()
66 { 155 {
67 return &ops; 156 return &ops;
68 } 157 }
69 158
70 void finch_connections_init() 159 void finch_connections_init()
71 {} 160 {
161 hash = g_hash_table_new_full(
162 g_direct_hash, g_direct_equal,
163 NULL, free_auto_recon);
164
165 purple_signal_connect(purple_accounts_get_handle(), "account-removed",
166 finch_connection_get_handle(),
167 PURPLE_CALLBACK(account_removed_cb), NULL);
168 }
72 169
73 void finch_connections_uninit() 170 void finch_connections_uninit()
74 {} 171 {
75 172 purple_signals_disconnect_by_handle(finch_connection_get_handle());
173 g_hash_table_destroy(hash);
174 }