--- a/libpurple/account.c Sat Aug 29 01:11:36 2009 +0000 +++ b/libpurple/account.c Sun Oct 30 21:53:14 2011 +0000 @@ -43,14 +43,6 @@ #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 { @@ -315,6 +307,7 @@ proxy_type == PURPLE_PROXY_HTTP ? "http" : proxy_type == PURPLE_PROXY_SOCKS4 ? "socks4" : proxy_type == PURPLE_PROXY_SOCKS5 ? "socks5" : + proxy_type == PURPLE_PROXY_TOR ? "tor" : proxy_type == PURPLE_PROXY_USE_ENVVAR ? "envvar" : "unknown"), -1); if ((value = purple_proxy_info_get_host(proxy_info)) != NULL) @@ -381,8 +374,6 @@ static xmlnode * account_to_xmlnode(PurpleAccount *account) { - PurpleAccountPrivate *priv = PURPLE_ACCOUNT_GET_PRIVATE(account); - xmlnode *node, *child; const char *tmp; const char *keyring_id; @@ -467,7 +458,7 @@ xmlnode_insert_child(node, child); } - child = current_error_to_xmlnode(priv->current_error); + child = current_error_to_xmlnode(account->current_error); xmlnode_insert_child(node, child); return node; @@ -559,8 +550,46 @@ purple_account_remove_setting(account, "xferjp_host"); } - - return; +} + +static void +migrate_icq_server(PurpleAccount *account) +{ + /* Migrate the login server setting for ICQ accounts. See + * 'mtn log --last 1 --no-graph --from b6d7712e90b68610df3bd2d8cbaf46d94c8b3794' + * for details on the change. */ + + if(purple_strequal(purple_account_get_protocol_id(account), "prpl-icq")) { + const char *tmp = purple_account_get_string(account, "server", NULL); + + /* Non-secure server */ + if(purple_strequal(tmp, "login.messaging.aol.com") || + purple_strequal(tmp, "login.oscar.aol.com")) + purple_account_set_string(account, "server", "login.icq.com"); + + /* Secure server */ + if(purple_strequal(tmp, "slogin.oscar.aol.com")) + purple_account_set_string(account, "server", "slogin.icq.com"); + } +} + +static void +migrate_xmpp_encryption(PurpleAccount *account) +{ + /* When this is removed, nuke the "old_ssl" and "require_tls" settings */ + if (g_str_equal(purple_account_get_protocol_id(account), "prpl-jabber")) { + const char *sec = purple_account_get_string(account, "connection_security", ""); + + if (g_str_equal("", sec)) { + const char *val = "require_tls"; + if (purple_account_get_bool(account, "old_ssl", FALSE)) + val = "old_ssl"; + else if (!purple_account_get_bool(account, "require_tls", TRUE)) + val = "opportunistic_tls"; + + purple_account_set_string(account, "connection_security", val); + } + } } static void @@ -630,6 +659,12 @@ /* we do this here because we need access to account settings to determine * if we can/should migrate an old Yahoo! JAPAN account */ migrate_yahoo_japan(account); + /* we do this here because we need access to account settings to determine + * if we can/should migrate an ICQ account's server setting */ + migrate_icq_server(account); + /* we do this here because we need to do it before the user views the + * Edit Account dialog. */ + migrate_xmpp_encryption(account); } static GList * @@ -753,6 +788,8 @@ purple_proxy_info_set_type(proxy_info, PURPLE_PROXY_SOCKS4); else if (purple_strequal(data, "socks5")) purple_proxy_info_set_type(proxy_info, PURPLE_PROXY_SOCKS5); + else if (purple_strequal(data, "tor")) + purple_proxy_info_set_type(proxy_info, PURPLE_PROXY_TOR); else if (purple_strequal(data, "envvar")) purple_proxy_info_set_type(proxy_info, PURPLE_PROXY_USE_ENVVAR); else @@ -882,7 +919,7 @@ return NULL; } - ret = purple_account_new(name, _purple_oscar_convert(name, protocol_id)); /* XXX: */ + ret = purple_account_new(name, protocol_id); g_free(name); g_free(protocol_id); @@ -923,15 +960,6 @@ { purple_buddy_icons_set_account_icon(ret, (guchar *)contents, len); } - else - { - /* Try to see if the icon got left behind in the old cache. */ - g_free(filename); - filename = g_build_filename(g_get_home_dir(), ".gaim", "icons", data, NULL); - if (g_file_get_contents(filename, &contents, &len, NULL)) { - purple_buddy_icons_set_account_icon(ret, (guchar*)contents, len); - } - } g_free(filename); g_free(data); @@ -1024,7 +1052,6 @@ 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; @@ -1039,8 +1066,6 @@ 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); @@ -1083,7 +1108,6 @@ void purple_account_destroy(PurpleAccount *account) { - PurpleAccountPrivate *priv = NULL; GList *l; g_return_if_fail(account != NULL); @@ -1109,17 +1133,32 @@ g_hash_table_destroy(account->settings); g_hash_table_destroy(account->ui_settings); + if (account->proxy_info) + purple_proxy_info_destroy(account->proxy_info); + purple_account_set_status_types(account, NULL); - purple_presence_destroy(account->presence); + if (account->presence) + purple_presence_destroy(account->presence); if(account->system_log) purple_log_free(account->system_log); - priv = PURPLE_ACCOUNT_GET_PRIVATE(account); - PURPLE_DBUS_UNREGISTER_POINTER(priv->current_error); - g_free(priv->current_error); - g_free(priv); + while (account->deny) { + g_free(account->deny->data); + account->deny = g_slist_delete_link(account->deny, account->deny); + } + + while (account->permit) { + g_free(account->permit->data); + account->permit = g_slist_delete_link(account->permit, account->permit); + } + + PURPLE_DBUS_UNREGISTER_POINTER(account->current_error); + if (account->current_error) { + g_free(account->current_error->description); + g_free(account->current_error); + } PURPLE_DBUS_UNREGISTER_POINTER(account); g_free(account); @@ -1224,7 +1263,7 @@ static void request_password_cancel_cb(PurpleAccount *account, PurpleRequestFields *fields) { - /* Disable the account as the user has canceled connecting */ + /* Disable the account as the user has cancelled connecting */ purple_account_set_enabled(account, purple_core_get_ui(), FALSE); } @@ -1447,7 +1486,8 @@ handles = g_list_remove(handles, info); - info->auth_cb(info->userdata); + if (info->auth_cb != NULL) + info->auth_cb(info->userdata); purple_signal_emit(purple_accounts_get_handle(), "account-authorization-granted", info->account, info->user); @@ -1462,7 +1502,8 @@ handles = g_list_remove(handles, info); - info->deny_cb(info->userdata); + if (info->deny_cb != NULL) + info->deny_cb(info->userdata); purple_signal_emit(purple_accounts_get_handle(), "account-authorization-denied", info->account, info->user); @@ -1489,13 +1530,36 @@ "account-authorization-requested", account, remote_user)); if (plugin_return > 0) { - auth_cb(user_data); + if (auth_cb != NULL) + auth_cb(user_data); return NULL; } else if (plugin_return < 0) { - deny_cb(user_data); + if (deny_cb != NULL) + deny_cb(user_data); return NULL; } + plugin_return = GPOINTER_TO_INT( + purple_signal_emit_return_1( + purple_accounts_get_handle(), + "account-authorization-requested-with-message", + account, remote_user, message + )); + + switch (plugin_return) + { + case PURPLE_ACCOUNT_RESPONSE_IGNORE: + return NULL; + case PURPLE_ACCOUNT_RESPONSE_ACCEPT: + if (auth_cb != NULL) + auth_cb(user_data); + return NULL; + case PURPLE_ACCOUNT_RESPONSE_DENY: + if (deny_cb != NULL) + 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; @@ -1646,7 +1710,7 @@ purple_request_input(gc, _("Set User Info"), primary, NULL, purple_account_get_user_info(account), TRUE, FALSE, ((gc != NULL) && - (gc->flags & PURPLE_CONNECTION_HTML) ? "html" : NULL), + (purple_connection_get_flags(gc) & PURPLE_CONNECTION_HTML) ? "html" : NULL), _("Save"), G_CALLBACK(set_user_info_cb), _("Cancel"), NULL, account, NULL, NULL, @@ -1849,6 +1913,14 @@ } void +purple_account_set_privacy_type(PurpleAccount *account, PurplePrivacyType privacy_type) +{ + g_return_if_fail(account != NULL); + + account->perm_deny = privacy_type; +} + +void purple_account_set_status_types(PurpleAccount *account, GList *status_types) { g_return_if_fail(account != NULL); @@ -1914,6 +1986,106 @@ schedule_accounts_save(); } +struct public_alias_closure +{ + PurpleAccount *account; + gpointer failure_cb; +}; + +static gboolean +set_public_alias_unsupported(gpointer data) +{ + struct public_alias_closure *closure = data; + PurpleSetPublicAliasFailureCallback failure_cb = closure->failure_cb; + + failure_cb(closure->account, + _("This protocol does not support setting a public alias.")); + g_free(closure); + + return FALSE; +} + +void +purple_account_set_public_alias(PurpleAccount *account, + const char *alias, PurpleSetPublicAliasSuccessCallback success_cb, + PurpleSetPublicAliasFailureCallback failure_cb) +{ + PurpleConnection *gc; + PurplePlugin *prpl = NULL; + PurplePluginProtocolInfo *prpl_info = NULL; + + g_return_if_fail(account != NULL); + g_return_if_fail(purple_account_is_connected(account)); + + gc = purple_account_get_connection(account); + prpl = purple_connection_get_prpl(gc); + prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl); + + if (PURPLE_PROTOCOL_PLUGIN_HAS_FUNC(prpl_info, set_public_alias)) + prpl_info->set_public_alias(gc, alias, success_cb, failure_cb); + else if (failure_cb) { + struct public_alias_closure *closure = + g_new0(struct public_alias_closure, 1); + closure->account = account; + closure->failure_cb = failure_cb; + purple_timeout_add(0, set_public_alias_unsupported, closure); + } +} + +static gboolean +get_public_alias_unsupported(gpointer data) +{ + struct public_alias_closure *closure = data; + PurpleGetPublicAliasFailureCallback failure_cb = closure->failure_cb; + + failure_cb(closure->account, + _("This protocol does not support fetching the public alias.")); + g_free(closure); + + return FALSE; +} + +void +purple_account_get_public_alias(PurpleAccount *account, + PurpleGetPublicAliasSuccessCallback success_cb, + PurpleGetPublicAliasFailureCallback failure_cb) +{ + PurpleConnection *gc; + PurplePlugin *prpl = NULL; + PurplePluginProtocolInfo *prpl_info = NULL; + + g_return_if_fail(account != NULL); + g_return_if_fail(purple_account_is_connected(account)); + + gc = purple_account_get_connection(account); + prpl = purple_connection_get_prpl(gc); + prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl); + + if (PURPLE_PROTOCOL_PLUGIN_HAS_FUNC(prpl_info, get_public_alias)) + prpl_info->get_public_alias(gc, success_cb, failure_cb); + else if (failure_cb) { + struct public_alias_closure *closure = + g_new0(struct public_alias_closure, 1); + closure->account = account; + closure->failure_cb = failure_cb; + purple_timeout_add(0, get_public_alias_unsupported, closure); + } +} + +gboolean +purple_account_get_silence_suppression(const PurpleAccount *account) +{ + return purple_account_get_bool(account, "silence-suppression", FALSE); +} + +void +purple_account_set_silence_suppression(PurpleAccount *account, gboolean value) +{ + g_return_if_fail(account != NULL); + + purple_account_set_bool(account, "silence-suppression", value); +} + void purple_account_clear_settings(PurpleAccount *account) { @@ -2255,6 +2427,42 @@ return account->gc; } +const gchar * +purple_account_get_name_for_display(const PurpleAccount *account) +{ + PurpleBuddy *self = NULL; + PurpleConnection *gc = NULL; + const gchar *name = NULL, *username = NULL, *displayname = NULL; + + name = purple_account_get_alias(account); + + if (name) { + return name; + } + + username = purple_account_get_username(account); + self = purple_find_buddy((PurpleAccount *)account, username); + + if (self) { + const gchar *calias= purple_buddy_get_contact_alias(self); + + /* We don't want to return the buddy name if the buddy/contact + * doesn't have an alias set. */ + if (!purple_strequal(username, calias)) { + return calias; + } + } + + gc = purple_account_get_connection(account); + displayname = purple_connection_get_display_name(gc); + + if (displayname) { + return displayname; + } + + return username; +} + gboolean purple_account_get_remember_password(const PurpleAccount *account) { @@ -2288,6 +2496,14 @@ return account->proxy_info; } +PurplePrivacyType +purple_account_get_privacy_type(const PurpleAccount *account) +{ + g_return_val_if_fail(account != NULL, PURPLE_PRIVACY_ALLOW_ALL); + + return account->perm_deny; +} + PurpleStatus * purple_account_get_active_status(const PurpleAccount *account) { @@ -2491,6 +2707,24 @@ return setting->value.boolean; } +gpointer +purple_account_get_ui_data(const PurpleAccount *account) +{ + g_return_val_if_fail(account != NULL, NULL); + + return account->ui_data; +} + +void +purple_account_set_ui_data(PurpleAccount *account, + gpointer ui_data) +{ + g_return_if_fail(account != NULL); + + account->ui_data = ui_data; +} + + PurpleLog * purple_account_get_log(PurpleAccount *account, gboolean create) { @@ -2523,31 +2757,37 @@ } void -purple_account_add_buddy(PurpleAccount *account, PurpleBuddy *buddy) +purple_account_add_buddy(PurpleAccount *account, PurpleBuddy *buddy, const char *message) +{ + PurplePluginProtocolInfo *prpl_info = NULL; + PurpleConnection *gc; + PurplePlugin *prpl = NULL; + + g_return_if_fail(account != NULL); + g_return_if_fail(buddy != NULL); + + gc = purple_account_get_connection(account); + if (gc != NULL) + prpl = purple_connection_get_prpl(gc); + + if (prpl != NULL) + prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl); + + if (prpl_info != NULL) { + if (PURPLE_PROTOCOL_PLUGIN_HAS_FUNC(prpl_info, add_buddy)) + prpl_info->add_buddy(gc, buddy, purple_buddy_get_group(buddy), message); + } +} + +void +purple_account_add_buddies(PurpleAccount *account, GList *buddies, const char *message) { PurplePluginProtocolInfo *prpl_info = NULL; PurpleConnection *gc = purple_account_get_connection(account); PurplePlugin *prpl = NULL; if (gc != NULL) - prpl = purple_connection_get_prpl(gc); - - if (prpl != NULL) - prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl); - - if (prpl_info != NULL && prpl_info->add_buddy != NULL) - prpl_info->add_buddy(gc, buddy, purple_buddy_get_group(buddy)); -} - -void -purple_account_add_buddies(PurpleAccount *account, GList *buddies) -{ - PurplePluginProtocolInfo *prpl_info = NULL; - PurpleConnection *gc = purple_account_get_connection(account); - PurplePlugin *prpl = NULL; - - if (gc != NULL) - prpl = purple_connection_get_prpl(gc); + prpl = purple_connection_get_prpl(gc); if (prpl != NULL) prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl); @@ -2561,13 +2801,13 @@ groups = g_list_append(groups, purple_buddy_get_group(buddy)); } - if (prpl_info->add_buddies != NULL) - prpl_info->add_buddies(gc, buddies, groups); - else if (prpl_info->add_buddy != NULL) { + if (PURPLE_PROTOCOL_PLUGIN_HAS_FUNC(prpl_info, add_buddies)) + prpl_info->add_buddies(gc, buddies, groups, message); + else if (PURPLE_PROTOCOL_PLUGIN_HAS_FUNC(prpl_info, add_buddy)) { GList *curb = buddies, *curg = groups; while ((curb != NULL) && (curg != NULL)) { - prpl_info->add_buddy(gc, curb->data, curg->data); + prpl_info->add_buddy(gc, curb->data, curg->data, message); curb = curb->next; curg = curg->next; } @@ -2586,7 +2826,7 @@ PurplePlugin *prpl = NULL; if (gc != NULL) - prpl = purple_connection_get_prpl(gc); + prpl = purple_connection_get_prpl(gc); if (prpl != NULL) prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl); @@ -2603,7 +2843,7 @@ PurplePlugin *prpl = NULL; if (gc != NULL) - prpl = purple_connection_get_prpl(gc); + prpl = purple_connection_get_prpl(gc); if (prpl != NULL) prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl); @@ -2631,7 +2871,7 @@ PurplePlugin *prpl = NULL; if (gc != NULL) - prpl = purple_connection_get_prpl(gc); + prpl = purple_connection_get_prpl(gc); if (prpl != NULL) prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl); @@ -2651,7 +2891,7 @@ purple_account_set_password_async(account, g_strdup(new_pw), g_free, NULL, NULL); if (gc != NULL) - prpl = purple_connection_get_prpl(gc); + prpl = purple_connection_get_prpl(gc); if (prpl != NULL) prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl); @@ -2689,23 +2929,34 @@ { PurpleAccount *account = purple_connection_get_account(gc); purple_account_clear_current_error(account); + + purple_signal_emit(purple_accounts_get_handle(), "account-signed-on", + account); +} + +static void +signed_off_cb(PurpleConnection *gc, + gpointer unused) +{ + PurpleAccount *account = purple_connection_get_account(gc); + + purple_signal_emit(purple_accounts_get_handle(), "account-signed-off", + account); } static void set_current_error(PurpleAccount *account, PurpleConnectionErrorInfo *new_err) { - PurpleAccountPrivate *priv; PurpleConnectionErrorInfo *old_err; g_return_if_fail(account != NULL); - priv = PURPLE_ACCOUNT_GET_PRIVATE(account); - old_err = priv->current_error; + old_err = account->current_error; if(new_err == old_err) return; - priv->current_error = new_err; + account->current_error = new_err; purple_signal_emit(purple_accounts_get_handle(), "account-error-changed", @@ -2739,13 +2990,15 @@ err->description = g_strdup(description); set_current_error(account, err); + + purple_signal_emit(purple_accounts_get_handle(), "account-connection-error", + account, type, description); } const PurpleConnectionErrorInfo * purple_account_get_current_error(PurpleAccount *account) { - PurpleAccountPrivate *priv = PURPLE_ACCOUNT_GET_PRIVATE(account); - return priv->current_error; + return account->current_error; } void @@ -2934,11 +3187,12 @@ char *who; g_return_val_if_fail(name != NULL, NULL); + g_return_val_if_fail(protocol_id != NULL, NULL); for (l = purple_accounts_get_all(); l != NULL; l = l->next) { account = (PurpleAccount *)l->data; - if (protocol_id && !purple_strequal(account->protocol_id, protocol_id)) - continue; + if (!purple_strequal(account->protocol_id, protocol_id)) + continue; who = g_strdup(purple_normalize(account, name)); if (purple_strequal(purple_normalize(account, purple_account_get_username(account)), who)) { @@ -3070,6 +3324,13 @@ PURPLE_SUBTYPE_ACCOUNT), purple_value_new(PURPLE_TYPE_STRING)); + purple_signal_register(handle, "account-authorization-requested-with-message", + purple_marshal_INT__POINTER_POINTER_POINTER, + purple_value_new(PURPLE_TYPE_INT), 3, + purple_value_new(PURPLE_TYPE_SUBTYPE, + PURPLE_SUBTYPE_ACCOUNT), + purple_value_new(PURPLE_TYPE_STRING), + 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, @@ -3090,8 +3351,27 @@ purple_value_new(PURPLE_TYPE_POINTER), purple_value_new(PURPLE_TYPE_POINTER)); + purple_signal_register(handle, "account-signed-on", + purple_marshal_VOID__POINTER, NULL, 1, + purple_value_new(PURPLE_TYPE_SUBTYPE, + PURPLE_SUBTYPE_ACCOUNT)); + + purple_signal_register(handle, "account-signed-off", + purple_marshal_VOID__POINTER, NULL, 1, + purple_value_new(PURPLE_TYPE_SUBTYPE, + PURPLE_SUBTYPE_ACCOUNT)); + + purple_signal_register(handle, "account-connection-error", + purple_marshal_VOID__POINTER_INT_POINTER, NULL, 3, + purple_value_new(PURPLE_TYPE_SUBTYPE, + PURPLE_SUBTYPE_ACCOUNT), + purple_value_new(PURPLE_TYPE_ENUM), + purple_value_new(PURPLE_TYPE_STRING)); + purple_signal_connect(conn_handle, "signed-on", handle, PURPLE_CALLBACK(signed_on_cb), NULL); + purple_signal_connect(conn_handle, "signed-off", handle, + PURPLE_CALLBACK(signed_off_cb), NULL); purple_signal_connect(conn_handle, "connection-error", handle, PURPLE_CALLBACK(connection_error_cb), NULL);