Mercurial > pidgin
diff libpurple/account.c @ 21563:1b174854bb80
merge of '30fcf2f336afb635b62a5c3ed3adb3e1fa1dd2d1'
and 'bb60447c0a8c79afca320f4dc689096f4788e7fa'
author | Sadrul Habib Chowdhury <imadil@gmail.com> |
---|---|
date | Sat, 17 Nov 2007 01:55:21 +0000 |
parents | 665e04562de0 |
children | 14afe5a92fc2 975336b01aa9 |
line wrap: on
line diff
--- a/libpurple/account.c Wed Nov 14 03:15:32 2007 +0000 +++ b/libpurple/account.c Sat Nov 17 01:55:21 2007 +0000 @@ -41,6 +41,14 @@ #include "util.h" #include "xmlnode.h" +typedef struct +{ + PurpleConnectionErrorInfo *current_error; +} PurpleAccountPrivate; + +#define PURPLE_ACCOUNT_GET_PRIVATE(account) \ + ((PurpleAccountPrivate *) (account->priv)) + /* TODO: Should use PurpleValue instead of this? What about "ui"? */ typedef struct { @@ -52,7 +60,7 @@ { int integer; char *string; - gboolean bool; + gboolean boolean; } value; @@ -63,7 +71,10 @@ PurpleAccountRequestType type; PurpleAccount *account; void *ui_handle; - + char *user; + gpointer userdata; + PurpleAccountRequestAuthorizationCb auth_cb; + PurpleAccountRequestAuthorizationCb deny_cb; } PurpleAccountRequestInfo; static PurpleAccountUiOps *account_ui_ops = NULL; @@ -74,6 +85,9 @@ static GList *handles = NULL; +static void set_current_error(PurpleAccount *account, + PurpleConnectionErrorInfo *new_err); + /********************************************************************* * Writing to disk * *********************************************************************/ @@ -104,7 +118,7 @@ } else if (setting->type == PURPLE_PREF_BOOLEAN) { xmlnode_set_attrib(child, "type", "bool"); - snprintf(buf, sizeof(buf), "%d", setting->value.bool); + snprintf(buf, sizeof(buf), "%d", setting->value.boolean); xmlnode_insert_data(child, buf, -1); } } @@ -307,8 +321,32 @@ } static xmlnode * +current_error_to_xmlnode(PurpleConnectionErrorInfo *err) +{ + xmlnode *node, *child; + char type_str[3]; + + node = xmlnode_new("current_error"); + + if(err == NULL) + return node; + + child = xmlnode_new_child(node, "type"); + snprintf(type_str, sizeof(type_str), "%u", err->type); + xmlnode_insert_data(child, type_str, -1); + + child = xmlnode_new_child(node, "description"); + if(err->description) + xmlnode_insert_data(child, err->description, -1); + + return node; +} + +static xmlnode * account_to_xmlnode(PurpleAccount *account) { + PurpleAccountPrivate *priv = PURPLE_ACCOUNT_GET_PRIVATE(account); + xmlnode *node, *child; const char *tmp; PurplePresence *presence; @@ -365,6 +403,9 @@ xmlnode_insert_child(node, child); } + child = current_error_to_xmlnode(priv->current_error); + xmlnode_insert_child(node, child); + return node; } @@ -669,6 +710,42 @@ purple_account_set_proxy_info(account, proxy_info); } +static void +parse_current_error(xmlnode *node, PurpleAccount *account) +{ + guint type; + char *type_str = NULL, *description = NULL; + xmlnode *child; + PurpleConnectionErrorInfo *current_error = NULL; + + child = xmlnode_get_child(node, "type"); + if (child == NULL || (type_str = xmlnode_get_data(child)) == NULL) + return; + type = atoi(type_str); + g_free(type_str); + + if (type > PURPLE_CONNECTION_ERROR_OTHER_ERROR) + { + purple_debug_error("account", + "Invalid PurpleConnectionError value %d found when " + "loading account information for %s\n", + type, purple_account_get_username(account)); + type = PURPLE_CONNECTION_ERROR_OTHER_ERROR; + } + + child = xmlnode_get_child(node, "description"); + if (child) + description = xmlnode_get_data(child); + if (description == NULL) + description = g_strdup(""); + + current_error = g_new0(PurpleConnectionErrorInfo, 1); + current_error->type = type; + current_error->description = description; + + set_current_error(account, current_error); +} + static PurpleAccount * parse_account(xmlnode *node) { @@ -778,6 +855,13 @@ parse_proxy_info(child, ret); } + /* Read current error */ + child = xmlnode_get_child(node, "current_error"); + if (child != NULL) + { + parse_current_error(child, ret); + } + return ret; } @@ -824,6 +908,7 @@ purple_account_new(const char *username, const char *protocol_id) { PurpleAccount *account = NULL; + PurpleAccountPrivate *priv = NULL; PurplePlugin *prpl = NULL; PurplePluginProtocolInfo *prpl_info = NULL; PurpleStatusType *status_type; @@ -838,6 +923,8 @@ account = g_new0(PurpleAccount, 1); PURPLE_DBUS_REGISTER_POINTER(account, PurpleAccount); + priv = g_new0(PurpleAccountPrivate, 1); + account->priv = priv; purple_account_set_username(account, username); @@ -878,6 +965,7 @@ void purple_account_destroy(PurpleAccount *account) { + PurpleAccountPrivate *priv = NULL; GList *l; g_return_if_fail(account != NULL); @@ -909,6 +997,10 @@ if(account->system_log) purple_log_free(account->system_log); + priv = PURPLE_ACCOUNT_GET_PRIVATE(account); + g_free(priv->current_error); + g_free(priv); + PURPLE_DBUS_UNREGISTER_POINTER(account); g_free(account); } @@ -1157,6 +1249,28 @@ } } +static void +request_auth_cb(void *data) +{ + PurpleAccountRequestInfo *info = data; + info->auth_cb(info->userdata); + purple_signal_emit(purple_accounts_get_handle(), + "account-authorization-granted", info->account, info->user); + g_free(info->user); + g_free(info); +} + +static void +request_deny_cb(void *data) +{ + PurpleAccountRequestInfo *info = data; + info->deny_cb(info->userdata); + purple_signal_emit(purple_accounts_get_handle(), + "account-authorization-denied", info->account, info->user); + g_free(info->user); + g_free(info); +} + void * purple_account_request_authorization(PurpleAccount *account, const char *remote_user, const char *id, const char *alias, const char *message, gboolean on_list, @@ -1164,18 +1278,35 @@ { PurpleAccountUiOps *ui_ops; PurpleAccountRequestInfo *info; + int plugin_return; g_return_val_if_fail(account != NULL, NULL); g_return_val_if_fail(remote_user != NULL, NULL); ui_ops = purple_accounts_get_ui_ops(); + plugin_return = GPOINTER_TO_INT( + purple_signal_emit_return_1(purple_accounts_get_handle(), + "account-authorization-requested", account, remote_user)); + + if (plugin_return > 0) { + auth_cb(user_data); + return NULL; + } else if (plugin_return < 0) { + deny_cb(user_data); + return NULL; + } + if (ui_ops != NULL && ui_ops->request_authorize != NULL) { info = g_new0(PurpleAccountRequestInfo, 1); info->type = PURPLE_ACCOUNT_REQUEST_AUTHORIZATION; info->account = account; + info->auth_cb = auth_cb; + info->deny_cb = deny_cb; + info->userdata = user_data; + info->user = g_strdup(remote_user); info->ui_handle = ui_ops->request_authorize(account, remote_user, id, alias, message, - on_list, auth_cb, deny_cb, user_data); + on_list, request_auth_cb, request_deny_cb, info); handles = g_list_append(handles, info); return info->ui_handle; @@ -1578,7 +1709,7 @@ setting = g_new0(PurpleAccountSetting, 1); setting->type = PURPLE_PREF_BOOLEAN; - setting->value.bool = value; + setting->value.boolean = value; g_hash_table_insert(account->settings, g_strdup(name), setting); @@ -1664,7 +1795,7 @@ setting->type = PURPLE_PREF_BOOLEAN; setting->ui = g_strdup(ui); - setting->value.bool = value; + setting->value.boolean = value; table = get_ui_settings_table(account, ui); @@ -1939,7 +2070,7 @@ g_return_val_if_fail(setting->type == PURPLE_PREF_BOOLEAN, default_value); - return setting->value.bool; + return setting->value.boolean; } int @@ -2005,7 +2136,7 @@ g_return_val_if_fail(setting->type == PURPLE_PREF_BOOLEAN, default_value); - return setting->value.bool; + return setting->value.boolean; } PurpleLog * @@ -2172,6 +2303,65 @@ return prpl_info->offline_message(buddy); } +static void +signed_on_cb(PurpleConnection *gc, + gpointer unused) +{ + PurpleAccount *account = purple_connection_get_account(gc); + purple_account_clear_current_error(account); +} + +static void +set_current_error(PurpleAccount *account, + PurpleConnectionErrorInfo *new_err) +{ + PurpleAccountPrivate *priv = PURPLE_ACCOUNT_GET_PRIVATE(account); + PurpleConnectionErrorInfo *old_err = priv->current_error; + + if(new_err == old_err) + return; + + priv->current_error = new_err; + + purple_signal_emit(purple_accounts_get_handle(), + "account-error-changed", + account, old_err, new_err); + schedule_accounts_save(); + + if(old_err) + g_free(old_err->description); + + g_free(old_err); +} + +static void +connection_error_cb(PurpleConnection *gc, + PurpleConnectionError type, + const gchar *description, + gpointer unused) +{ + PurpleAccount *account = purple_connection_get_account(gc); + PurpleConnectionErrorInfo *err = g_new0(PurpleConnectionErrorInfo, 1); + + err->type = type; + err->description = g_strdup(description); + + set_current_error(account, err); +} + +const PurpleConnectionErrorInfo * +purple_account_get_current_error(PurpleAccount *account) +{ + PurpleAccountPrivate *priv = PURPLE_ACCOUNT_GET_PRIVATE(account); + return priv->current_error; +} + +void +purple_account_clear_current_error(PurpleAccount *account) +{ + set_current_error(account, NULL); +} + void purple_accounts_add(PurpleAccount *account) { @@ -2196,6 +2386,11 @@ schedule_accounts_save(); + /* Clearing the error ensures that account-error-changed is emitted, + * which is the end of the guarantee that the the error's pointer is + * valid. + */ + purple_account_clear_current_error(account); purple_signal_emit(purple_accounts_get_handle(), "account-removed", account); } @@ -2401,6 +2596,7 @@ purple_accounts_init(void) { void *handle = purple_accounts_get_handle(); + void *conn_handle = purple_connections_get_handle(); purple_signal_register(handle, "account-connecting", purple_marshal_VOID__POINTER, NULL, 1, @@ -2452,6 +2648,38 @@ PURPLE_SUBTYPE_ACCOUNT), purple_value_new(PURPLE_TYPE_STRING)); + purple_signal_register(handle, "account-authorization-requested", + purple_marshal_INT__POINTER_POINTER, + purple_value_new(PURPLE_TYPE_INT), 2, + purple_value_new(PURPLE_TYPE_SUBTYPE, + PURPLE_SUBTYPE_ACCOUNT), + purple_value_new(PURPLE_TYPE_STRING)); + + purple_signal_register(handle, "account-authorization-denied", + purple_marshal_VOID__POINTER_POINTER, NULL, 2, + purple_value_new(PURPLE_TYPE_SUBTYPE, + PURPLE_SUBTYPE_ACCOUNT), + purple_value_new(PURPLE_TYPE_STRING)); + + purple_signal_register(handle, "account-authorization-granted", + purple_marshal_VOID__POINTER_POINTER, NULL, 2, + purple_value_new(PURPLE_TYPE_SUBTYPE, + PURPLE_SUBTYPE_ACCOUNT), + purple_value_new(PURPLE_TYPE_STRING)); + + purple_signal_register(handle, "account-error-changed", + purple_marshal_VOID__POINTER_POINTER_POINTER, + NULL, 3, + purple_value_new(PURPLE_TYPE_SUBTYPE, + PURPLE_SUBTYPE_ACCOUNT), + purple_value_new(PURPLE_TYPE_POINTER), + purple_value_new(PURPLE_TYPE_POINTER)); + + purple_signal_connect(conn_handle, "signed-on", handle, + PURPLE_CALLBACK(signed_on_cb), NULL); + purple_signal_connect(conn_handle, "connection-error", handle, + PURPLE_CALLBACK(connection_error_cb), NULL); + load_accounts(); } @@ -2459,6 +2687,7 @@ void purple_accounts_uninit(void) { + gpointer handle = purple_accounts_get_handle(); if (save_timer != 0) { purple_timeout_remove(save_timer); @@ -2466,5 +2695,6 @@ sync_accounts(); } - purple_signals_unregister_by_instance(purple_accounts_get_handle()); + purple_signals_disconnect_by_handle(handle); + purple_signals_unregister_by_instance(handle); }