* Purple is the legal property of its developers, whose names are too numerous * to list here. Please refer to the COPYRIGHT file distributed with this * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA * Structure representing an account. char *username; /* The username. */ char *alias; /* How you appear to yourself. */ char *password; /* The account password. */ char *user_info; /* User information. */ char *buddy_icon_path; /* The buddy icon's non-cached path. */ gboolean remember_pass; /* Remember the password. */ * TODO: After a GObject representing a protocol is ready, use it * here instead of the protocol ID. char *protocol_id; /* The ID of the protocol. */ PurpleConnection *gc; /* The connection handle. */ gboolean disconnecting; /* The account is currently disconnecting */ GHashTable *settings; /* Protocol-specific settings. */ GHashTable *ui_settings; /* UI-specific settings. */ PurpleProxyInfo *proxy_info; /* Proxy information. This will be set */ /* to NULL when the account inherits */ /* proxy settings from global prefs. */ * TODO: Instead of linked lists for permit and deny, use a data * structure that allows fast lookups AND decent performance when * iterating through all items. Fast lookups should help performance * for protocols like MSN, where all your buddies exist in your permit * list therefore the permit list is large. Possibly GTree or GSList *permit; /* Permit list. */ GSList *deny; /* Deny list. */ PurpleAccountPrivacyType privacy_type; /* The permit/deny setting. */ GList *status_types; /* Status types. */ PurplePresence *presence; /* Presence. */ PurpleLog *system_log; /* The system log */ PurpleAccountRegistrationCb registration_cb; void *registration_cb_user_data; PurpleConnectionErrorInfo *current_error; /* Errors */ PurpleAccountRequestType type; PurpleAccountRequestAuthorizationCb auth_cb; PurpleAccountRequestAuthorizationCb deny_cb; } PurpleAccountRequestInfo; /* GObject Property enums */ static GParamSpec *properties[PROP_LAST]; static GList *handles = NULL; G_DEFINE_TYPE_WITH_PRIVATE(PurpleAccount, purple_account, G_TYPE_OBJECT); /****************************************************************************** *****************************************************************************/ purple_account_register_got_password_cb(PurpleAccount *account, const gchar *password, GError *error, gpointer data) g_return_if_fail(PURPLE_IS_ACCOUNT(account)); _purple_connection_new(account, TRUE, password); purple_account_register(PurpleAccount *account) g_return_if_fail(PURPLE_IS_ACCOUNT(account)); purple_debug_info("account", "Registering account %s\n", purple_account_get_username(account)); purple_keyring_get_password(account, purple_account_register_got_password_cb, NULL); purple_account_unregister_got_password_cb(PurpleAccount *account, const gchar *password, GError *error, gpointer data) PurpleCallbackBundle *cbb = data; PurpleAccountUnregistrationCb cb; cb = (PurpleAccountUnregistrationCb)cbb->cb; _purple_connection_new_unregister(account, password, cb, cbb->data); struct register_completed_closure purple_account_register_completed_cb(gpointer data) struct register_completed_closure *closure = data; PurpleAccountPrivate *priv; priv = purple_account_get_instance_private(closure->account); if (priv->registration_cb) (priv->registration_cb)(closure->account, closure->succeeded, priv->registration_cb_user_data); g_object_unref(closure->account); request_password_ok_cb(PurpleAccount *account, PurpleRequestFields *fields) entry = purple_request_fields_get_string(fields, "password"); remember = purple_request_fields_get_bool(fields, "remember"); purple_notify_error(account, NULL, _("Password is required to sign on."), NULL, purple_request_cpar_from_account(account)); purple_account_set_remember_password(account, remember); purple_account_set_password(account, entry, NULL, NULL); _purple_connection_new(account, FALSE, entry); request_password_cancel_cb(PurpleAccount *account, PurpleRequestFields *fields) /* Disable the account as the user has cancelled connecting */ purple_account_set_enabled(account, purple_core_get_ui(), FALSE); purple_account_connect_got_password_cb(PurpleAccount *account, const gchar *password, GError *error, gpointer data) PurpleProtocol *protocol = data; if ((password == NULL || *password == '\0') && !(purple_protocol_get_options(protocol) & OPT_PROTO_NO_PASSWORD) && !(purple_protocol_get_options(protocol) & OPT_PROTO_PASSWORD_OPTIONAL)) purple_account_request_password(account, G_CALLBACK(request_password_ok_cb), G_CALLBACK(request_password_cancel_cb), account); _purple_connection_new(account, FALSE, password); static PurpleAccountRequestInfo * purple_account_request_info_unref(PurpleAccountRequestInfo *info) /* TODO: This will leak info->user_data, but there is no callback to just clean that up */ purple_account_request_close_info(PurpleAccountRequestInfo *info) ops = purple_accounts_get_ui_ops(); if (ops != NULL && ops->close_account_request != NULL) ops->close_account_request(info->ui_handle); purple_account_request_info_unref(info); request_auth_cb(const char *message, void *data) PurpleAccountRequestInfo *info = data; handles = g_list_remove(handles, info); if (info->auth_cb != NULL) info->auth_cb(message, info->userdata); purple_signal_emit(purple_accounts_get_handle(), "account-authorization-granted", info->account, info->user, message); purple_account_request_info_unref(info); request_deny_cb(const char *message, void *data) PurpleAccountRequestInfo *info = data; handles = g_list_remove(handles, info); if (info->deny_cb != NULL) info->deny_cb(message, info->userdata); purple_signal_emit(purple_accounts_get_handle(), "account-authorization-denied", info->account, info->user, message); purple_account_request_info_unref(info); change_password_cb(PurpleAccount *account, PurpleRequestFields *fields) const char *orig_pass, *new_pass_1, *new_pass_2; orig_pass = purple_request_fields_get_string(fields, "password"); new_pass_1 = purple_request_fields_get_string(fields, "new_password_1"); new_pass_2 = purple_request_fields_get_string(fields, "new_password_2"); if (g_utf8_collate(new_pass_1, new_pass_2)) purple_notify_error(account, NULL, _("New passwords do not match."), NULL, purple_request_cpar_from_account(account)); if ((purple_request_fields_is_field_required(fields, "password") && (orig_pass == NULL || *orig_pass == '\0')) || (purple_request_fields_is_field_required(fields, "new_password_1") && (new_pass_1 == NULL || *new_pass_1 == '\0')) || (purple_request_fields_is_field_required(fields, "new_password_2") && (new_pass_2 == NULL || *new_pass_2 == '\0'))) purple_notify_error(account, NULL, _("Fill out all fields completely."), NULL, purple_request_cpar_from_account(account)); purple_account_change_password(account, orig_pass, new_pass_1); set_user_info_cb(PurpleAccount *account, const char *user_info) purple_account_set_user_info(account, user_info); gc = purple_account_get_connection(account); purple_serv_set_info(gc, user_info); struct public_alias_closure 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_object_unref(closure->account); 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_object_unref(closure->account); delete_setting(void *data) PurpleAccountSetting *setting = (PurpleAccountSetting *)data; g_value_unset(&setting->value); get_ui_settings_table(PurpleAccount *account, const char *ui) PurpleAccountPrivate *priv = purple_account_get_instance_private(account); table = g_hash_table_lookup(priv->ui_settings, ui); table = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_hash_table_insert(priv->ui_settings, g_strdup(ui), table); static PurpleConnectionState purple_account_get_state(PurpleAccount *account) g_return_val_if_fail(PURPLE_IS_ACCOUNT(account), PURPLE_CONNECTION_DISCONNECTED); gc = purple_account_get_connection(account); return PURPLE_CONNECTION_DISCONNECTED; return purple_connection_get_state(gc); purple_account_get_password_got(PurpleAccount *account, const gchar *password, GError *error, gpointer data) PurpleCallbackBundle *cbb = data; PurpleKeyringReadCallback cb; PurpleAccountPrivate *priv = purple_account_get_instance_private(account); purple_debug_info("account", "Read password for account %s from async keyring.\n", purple_account_get_username(account)); purple_str_wipe(priv->password); priv->password = g_strdup(password); cb = (PurpleKeyringReadCallback)cbb->cb; cb(account, password, error, cbb->data); * This makes sure your permit list contains all buddies from your * buddy list and ONLY buddies from your buddy list. add_all_buddies_to_permit_list(PurpleAccount *account, gboolean local) PurpleAccountPrivate *priv = purple_account_get_instance_private(account); /* Remove anyone in the permit list who is not in the buddylist */ for (list = priv->permit; list != NULL; ) { char *person = list->data; if (!purple_blist_find_buddy(account, person)) purple_account_privacy_permit_remove(account, person, local); /* Now make sure everyone in the buddylist is in the permit list */ list = purple_blist_find_buddies(account, NULL); PurpleBuddy *buddy = list->data; const gchar *name = purple_buddy_get_name(buddy); if (!g_slist_find_custom(priv->permit, name, (GCompareFunc)g_utf8_collate)) purple_account_privacy_permit_add(account, name, local); list = g_slist_delete_link(list, list); _purple_account_set_current_error(PurpleAccount *account, PurpleConnectionErrorInfo *new_err) PurpleConnectionErrorInfo *old_err; PurpleAccountPrivate *priv; g_return_if_fail(PURPLE_IS_ACCOUNT(account)); priv = purple_account_get_instance_private(account); old_err = priv->current_error; priv->current_error = new_err; purple_signal_emit(purple_accounts_get_handle(), account, old_err, new_err); purple_accounts_schedule_save(); g_free(old_err->description); /****************************************************************************** *****************************************************************************/ status_attribute_to_xmlnode(PurpleStatus *status, PurpleStatusType *type, PurpleStatusAttribute *attr) PurpleStatusAttribute *default_attr; id = purple_status_attribute_get_id(attr); g_return_val_if_fail(id, NULL); attr_value = purple_status_get_attr_value(status, id); g_return_val_if_fail(attr_value, NULL); attr_type = G_VALUE_TYPE(attr_value); * If attr_value is a different type than it should be * then don't write it to the file. default_attr = purple_status_type_get_attr(type, id); default_value = purple_status_attribute_get_value(default_attr); if (attr_type != G_VALUE_TYPE(default_value)) * If attr_value is the same as the default for this status * then there is no need to write it to the file. if (attr_type == G_TYPE_STRING) const char *string_value = g_value_get_string(attr_value); const char *default_string_value = g_value_get_string(default_value); if (purple_strequal(string_value, default_string_value)) value = g_value_dup_string(attr_value); else if (attr_type == G_TYPE_INT) int int_value = g_value_get_int(attr_value); if (int_value == g_value_get_int(default_value)) value = g_strdup_printf("%d", int_value); else if (attr_type == G_TYPE_BOOLEAN) gboolean boolean_value = g_value_get_boolean(attr_value); if (boolean_value == g_value_get_boolean(default_value)) value = g_strdup(boolean_value ? g_return_val_if_fail(value, NULL); node = purple_xmlnode_new("attribute"); purple_xmlnode_set_attrib(node, "id", id); purple_xmlnode_set_attrib(node, "value", value); status_attrs_to_xmlnode(PurpleStatus *status) PurpleStatusType *type = purple_status_get_status_type(status); PurpleXmlNode *node, *child; node = purple_xmlnode_new("attributes"); attrs = purple_status_type_get_attrs(type); for (attr = attrs; attr != NULL; attr = attr->next) child = status_attribute_to_xmlnode(status, type, (PurpleStatusAttribute *)attr->data); purple_xmlnode_insert_child(node, child); status_to_xmlnode(PurpleStatus *status) PurpleXmlNode *node, *child; node = purple_xmlnode_new("status"); purple_xmlnode_set_attrib(node, "type", purple_status_get_id(status)); if (purple_status_get_name(status) != NULL) purple_xmlnode_set_attrib(node, "name", purple_status_get_name(status)); purple_xmlnode_set_attrib(node, "active", purple_status_is_active(status) ? "true" : "false"); child = status_attrs_to_xmlnode(status); purple_xmlnode_insert_child(node, child); statuses_to_xmlnode(PurplePresence *presence) PurpleXmlNode *node, *child; node = purple_xmlnode_new("statuses"); statuses = purple_presence_get_statuses(presence); for (; statuses != NULL; statuses = statuses->next) if (purple_status_type_is_saveable(purple_status_get_status_type(status))) child = status_to_xmlnode(status); purple_xmlnode_insert_child(node, child); proxy_settings_to_xmlnode(const PurpleProxyInfo *proxy_info) PurpleXmlNode *node, *child; PurpleProxyType proxy_type; proxy_type = purple_proxy_info_get_proxy_type(proxy_info); node = purple_xmlnode_new("proxy"); child = purple_xmlnode_new_child(node, "type"); purple_xmlnode_insert_data(child, (proxy_type == PURPLE_PROXY_USE_GLOBAL ? "global" : proxy_type == PURPLE_PROXY_NONE ? "none" : 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) child = purple_xmlnode_new_child(node, "host"); purple_xmlnode_insert_data(child, value, -1); if ((int_value = purple_proxy_info_get_port(proxy_info)) != 0) g_snprintf(buf, sizeof(buf), "%d", int_value); child = purple_xmlnode_new_child(node, "port"); purple_xmlnode_insert_data(child, buf, -1); if ((value = purple_proxy_info_get_username(proxy_info)) != NULL) child = purple_xmlnode_new_child(node, "username"); purple_xmlnode_insert_data(child, value, -1); if ((value = purple_proxy_info_get_password(proxy_info)) != NULL) child = purple_xmlnode_new_child(node, "password"); purple_xmlnode_insert_data(child, value, -1); current_error_to_xmlnode(PurpleConnectionErrorInfo *err) PurpleXmlNode *node, *child; node = purple_xmlnode_new("current_error"); /* It doesn't make sense to have transient errors persist across a if(!purple_connection_error_is_fatal (err->type)) child = purple_xmlnode_new_child(node, "type"); g_snprintf(type_str, sizeof(type_str), "%u", err->type); purple_xmlnode_insert_data(child, type_str, -1); child = purple_xmlnode_new_child(node, "description"); char *utf8ized = purple_utf8_try_convert(err->description); utf8ized = purple_utf8_salvage(err->description); purple_xmlnode_insert_data(child, utf8ized, -1); setting_to_xmlnode(gpointer key, gpointer value, gpointer user_data) PurpleAccountSetting *setting; PurpleXmlNode *node, *child; name = (const char *)key; setting = (PurpleAccountSetting *)value; node = (PurpleXmlNode *)user_data; child = purple_xmlnode_new_child(node, "setting"); purple_xmlnode_set_attrib(child, "name", name); if (G_VALUE_HOLDS_INT(&setting->value)) { purple_xmlnode_set_attrib(child, "type", "int"); g_snprintf(buf, sizeof(buf), "%d", g_value_get_int(&setting->value)); purple_xmlnode_insert_data(child, buf, -1); else if (G_VALUE_HOLDS_STRING(&setting->value) && g_value_get_string(&setting->value) != NULL) { purple_xmlnode_set_attrib(child, "type", "string"); purple_xmlnode_insert_data(child, g_value_get_string(&setting->value), -1); else if (G_VALUE_HOLDS_BOOLEAN(&setting->value)) { purple_xmlnode_set_attrib(child, "type", "bool"); g_snprintf(buf, sizeof(buf), "%d", g_value_get_boolean(&setting->value)); purple_xmlnode_insert_data(child, buf, -1); ui_setting_to_xmlnode(gpointer key, gpointer value, gpointer user_data) PurpleXmlNode *node, *child; table = (GHashTable *)value; node = (PurpleXmlNode *)user_data; if (g_hash_table_size(table) > 0) child = purple_xmlnode_new_child(node, "settings"); purple_xmlnode_set_attrib(child, "ui", ui); g_hash_table_foreach(table, setting_to_xmlnode, child); _purple_account_to_xmlnode(PurpleAccount *account) PurpleXmlNode *node, *child; PurplePresence *presence; const PurpleProxyInfo *proxy_info; PurpleAccountPrivate *priv = purple_account_get_instance_private(account); node = purple_xmlnode_new("account"); child = purple_xmlnode_new_child(node, "protocol"); purple_xmlnode_insert_data(child, purple_account_get_protocol_id(account), -1); child = purple_xmlnode_new_child(node, "name"); purple_xmlnode_insert_data(child, purple_account_get_username(account), -1); if (purple_account_get_remember_password(account)) const char *keyring_id = NULL; GDestroyNotify destroy = NULL; gboolean exported = purple_keyring_export_password(account, &keyring_id, &mode, &data, &error, &destroy); purple_debug_error("account", "Failed to export password for account %s: %s.\n", purple_account_get_username(account), child = purple_xmlnode_new_child(node, "password"); purple_xmlnode_set_attrib(child, "keyring_id", keyring_id); purple_xmlnode_set_attrib(child, "mode", mode); purple_xmlnode_insert_data(child, data, -1); if ((tmp = purple_account_get_private_alias(account)) != NULL) child = purple_xmlnode_new_child(node, "alias"); purple_xmlnode_insert_data(child, tmp, -1); if ((presence = purple_account_get_presence(account)) != NULL) child = statuses_to_xmlnode(presence); purple_xmlnode_insert_child(node, child); if ((tmp = purple_account_get_user_info(account)) != NULL) /* TODO: Do we need to call purple_str_strip_char(tmp, '\r') here? */ child = purple_xmlnode_new_child(node, "user-info"); purple_xmlnode_insert_data(child, tmp, -1); if (g_hash_table_size(priv->settings) > 0) child = purple_xmlnode_new_child(node, "settings"); g_hash_table_foreach(priv->settings, setting_to_xmlnode, child); if (g_hash_table_size(priv->ui_settings) > 0) g_hash_table_foreach(priv->ui_settings, ui_setting_to_xmlnode, node); if ((proxy_info = purple_account_get_proxy_info(account)) != NULL) child = proxy_settings_to_xmlnode(proxy_info); purple_xmlnode_insert_child(node, child); child = current_error_to_xmlnode(priv->current_error); purple_xmlnode_insert_child(node, child); /****************************************************************************** *****************************************************************************/ purple_account_set_property(GObject *obj, guint param_id, const GValue *value, PurpleAccount *account = PURPLE_ACCOUNT(obj); purple_account_set_username(account, g_value_get_string(value)); purple_account_set_private_alias(account, g_value_get_string(value)); purple_account_set_enabled(account, purple_core_get_ui(), g_value_get_boolean(value)); purple_account_set_connection(account, g_value_get_object(value)); purple_account_set_protocol_id(account, g_value_get_string(value)); purple_account_set_user_info(account, g_value_get_string(value)); case PROP_BUDDY_ICON_PATH: purple_account_set_buddy_icon_path(account, g_value_get_string(value)); case PROP_REMEMBER_PASSWORD: purple_account_set_remember_password(account, g_value_get_boolean(value)); purple_account_set_check_mail(account, g_value_get_boolean(value)); G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec); purple_account_get_property(GObject *obj, guint param_id, GValue *value, PurpleAccount *account = PURPLE_ACCOUNT(obj); g_value_set_string(value, purple_account_get_username(account)); g_value_set_string(value, purple_account_get_private_alias(account)); g_value_set_boolean(value, purple_account_get_enabled(account, g_value_set_object(value, purple_account_get_connection(account)); g_value_set_string(value, purple_account_get_protocol_id(account)); g_value_set_string(value, purple_account_get_user_info(account)); case PROP_BUDDY_ICON_PATH: g_value_set_string(value, purple_account_get_buddy_icon_path(account)); case PROP_REMEMBER_PASSWORD: g_value_set_boolean(value, purple_account_get_remember_password(account)); g_value_set_boolean(value, purple_account_get_check_mail(account)); G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec); purple_account_init(PurpleAccount *account) PurpleAccountPrivate *priv = purple_account_get_instance_private(account); priv->settings = g_hash_table_new_full(g_str_hash, g_str_equal, priv->ui_settings = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, (GDestroyNotify)g_hash_table_destroy); priv->privacy_type = PURPLE_ACCOUNT_PRIVACY_ALLOW_ALL; purple_account_constructed(GObject *object) PurpleAccount *account = PURPLE_ACCOUNT(object); PurpleAccountPrivate *priv = purple_account_get_instance_private(account); gchar *username, *protocol_id; PurpleProtocol *protocol = NULL; PurpleStatusType *status_type; G_OBJECT_CLASS(purple_account_parent_class)->constructed(object); "protocol-id", &protocol_id, purple_signal_emit(purple_accounts_get_handle(), "account-created", protocol = purple_protocols_find(protocol_id); purple_account_set_status_types(account, purple_protocol_class_status_types(protocol, account)); priv->presence = PURPLE_PRESENCE(purple_account_presence_new(account)); status_type = purple_account_get_status_type_with_primitive(account, PURPLE_STATUS_AVAILABLE); purple_presence_set_status_active(priv->presence, purple_status_type_get_id(status_type), purple_presence_set_status_active(priv->presence, purple_account_dispose(GObject *object) PurpleAccount *account = PURPLE_ACCOUNT(object); PurpleAccountPrivate *priv = purple_account_get_instance_private(account); if (!purple_account_is_disconnected(account)) purple_account_disconnect(account); g_object_unref(priv->presence); G_OBJECT_CLASS(purple_account_parent_class)->dispose(object); purple_account_finalize(GObject *object) PurpleAccount *account = PURPLE_ACCOUNT(object); PurpleAccountPrivate *priv = purple_account_get_instance_private(account); purple_debug_info("account", "Destroying account %p\n", account); purple_signal_emit(purple_accounts_get_handle(), "account-destroying", for (l = purple_conversations_get_all(); l != NULL; l = l->next) PurpleConversation *conv = (PurpleConversation *)l->data; if (purple_conversation_get_account(conv) == account) purple_conversation_set_account(conv, NULL); purple_account_set_status_types(account, NULL); purple_proxy_info_destroy(priv->proxy_info); purple_log_free(priv->system_log); if (priv->current_error) { g_free(priv->current_error->description); g_free(priv->current_error); purple_str_wipe(priv->password); g_free(priv->buddy_icon_path); g_free(priv->protocol_id); g_hash_table_destroy(priv->settings); g_hash_table_destroy(priv->ui_settings); g_slist_free_full(priv->deny, g_free); g_slist_free_full(priv->permit, g_free); G_OBJECT_CLASS(purple_account_parent_class)->finalize(object); purple_account_class_init(PurpleAccountClass *klass) GObjectClass *obj_class = G_OBJECT_CLASS(klass); obj_class->dispose = purple_account_dispose; obj_class->finalize = purple_account_finalize; obj_class->constructed = purple_account_constructed; obj_class->get_property = purple_account_get_property; obj_class->set_property = purple_account_set_property; properties[PROP_USERNAME] = g_param_spec_string("username", "Username", "The username for the account.", NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS); properties[PROP_PRIVATE_ALIAS] = g_param_spec_string("private-alias", "The private alias for the account.", NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); properties[PROP_USER_INFO] = g_param_spec_string("user-info", "Detailed user information for the account.", NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); properties[PROP_BUDDY_ICON_PATH] = g_param_spec_string("buddy-icon-path", "Path to the buddyicon for the account.", NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); properties[PROP_ENABLED] = g_param_spec_boolean("enabled", "Enabled", "Whether the account is enabled or not.", FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); properties[PROP_REMEMBER_PASSWORD] = g_param_spec_boolean( "remember-password", "Remember password", "Whether to remember and store the password for this account.", FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); properties[PROP_CHECK_MAIL] = g_param_spec_boolean("check-mail", "Whether to check mails for this account.", FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); properties[PROP_CONNECTION] = g_param_spec_object("connection", "The connection for the account.", PURPLE_TYPE_CONNECTION, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); properties[PROP_PROTOCOL_ID] = g_param_spec_string("protocol-id", "ID of the protocol that is responsible for the account.", NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | g_object_class_install_properties(obj_class, PROP_LAST, properties); /****************************************************************************** *****************************************************************************/ purple_account_new(const char *username, const char *protocol_id) g_return_val_if_fail(username != NULL, NULL); g_return_val_if_fail(protocol_id != NULL, NULL); account = purple_accounts_find(username, protocol_id); account = g_object_new(PURPLE_TYPE_ACCOUNT, "protocol-id", protocol_id, purple_account_connect(PurpleAccount *account) PurpleProtocol *protocol; PurpleAccountPrivate *priv; g_return_if_fail(PURPLE_IS_ACCOUNT(account)); username = purple_account_get_username(account); if (!purple_account_get_enabled(account, purple_core_get_ui())) { purple_debug_info("account", "Account %s not enabled, not connecting.\n", protocol = purple_protocols_find(purple_account_get_protocol_id(account)); message = g_strdup_printf(_("Missing protocol for %s"), username); purple_notify_error(account, _("Connection Error"), message, NULL, purple_request_cpar_from_account(account)); priv = purple_account_get_instance_private(account); purple_debug_info("account", "Connecting to account %s.\n", username); if (priv->password != NULL) { purple_account_connect_got_password_cb(account, priv->password, NULL, protocol); purple_keyring_get_password(account, purple_account_connect_got_password_cb, protocol); purple_account_set_register_callback(PurpleAccount *account, PurpleAccountRegistrationCb cb, void *user_data) PurpleAccountPrivate *priv; g_return_if_fail(PURPLE_IS_ACCOUNT(account)); priv = purple_account_get_instance_private(account); priv->registration_cb = cb; priv->registration_cb_user_data = user_data; purple_account_register_completed(PurpleAccount *account, gboolean succeeded) struct register_completed_closure *closure; g_return_if_fail(PURPLE_IS_ACCOUNT(account)); closure = g_new0(struct register_completed_closure, 1); closure->account = g_object_ref(account); closure->succeeded = succeeded; g_timeout_add(0, purple_account_register_completed_cb, closure); purple_account_unregister(PurpleAccount *account, PurpleAccountUnregistrationCb cb, void *user_data) PurpleCallbackBundle *cbb; g_return_if_fail(PURPLE_IS_ACCOUNT(account)); purple_debug_info("account", "Unregistering account %s\n", purple_account_get_username(account)); cbb = g_new0(PurpleCallbackBundle, 1); cbb->cb = PURPLE_CALLBACK(cb); purple_keyring_get_password(account, purple_account_unregister_got_password_cb, cbb); purple_account_disconnect(PurpleAccount *account) PurpleAccountPrivate *priv; g_return_if_fail(PURPLE_IS_ACCOUNT(account)); g_return_if_fail(!purple_account_is_disconnecting(account)); g_return_if_fail(!purple_account_is_disconnected(account)); priv = purple_account_get_instance_private(account); username = purple_account_get_username(account); purple_debug_info("account", "Disconnecting account %s (%p)\n", username ? username : "(null)", account); priv->disconnecting = TRUE; gc = purple_account_get_connection(account); purple_account_set_connection(account, NULL); priv->disconnecting = FALSE; purple_account_is_disconnecting(PurpleAccount *account) PurpleAccountPrivate *priv; g_return_val_if_fail(PURPLE_IS_ACCOUNT(account), TRUE); priv = purple_account_get_instance_private(account); return priv->disconnecting; purple_account_notify_added(PurpleAccount *account, const char *remote_user, const char *id, const char *alias, PurpleAccountUiOps *ui_ops; g_return_if_fail(PURPLE_IS_ACCOUNT(account)); g_return_if_fail(remote_user != NULL); ui_ops = purple_accounts_get_ui_ops(); if (ui_ops != NULL && ui_ops->notify_added != NULL) ui_ops->notify_added(account, remote_user, id, alias, message); purple_account_request_add(PurpleAccount *account, const char *remote_user, const char *id, const char *alias, PurpleAccountUiOps *ui_ops; g_return_if_fail(PURPLE_IS_ACCOUNT(account)); g_return_if_fail(remote_user != NULL); ui_ops = purple_accounts_get_ui_ops(); if (ui_ops != NULL && ui_ops->request_add != NULL) ui_ops->request_add(account, remote_user, id, alias, message); purple_account_request_authorization(PurpleAccount *account, const char *remote_user, const char *id, const char *alias, const char *message, gboolean on_list, PurpleAccountRequestAuthorizationCb auth_cb, PurpleAccountRequestAuthorizationCb deny_cb, void *user_data) PurpleAccountUiOps *ui_ops; PurpleAccountRequestInfo *info; g_return_val_if_fail(PURPLE_IS_ACCOUNT(account), 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, message, &response case PURPLE_ACCOUNT_RESPONSE_IGNORE: case PURPLE_ACCOUNT_RESPONSE_ACCEPT: auth_cb(response, user_data); case PURPLE_ACCOUNT_RESPONSE_DENY: deny_cb(response, user_data); if (ui_ops != NULL && ui_ops->request_authorize != NULL) { info = g_new0(PurpleAccountRequestInfo, 1); info->type = PURPLE_ACCOUNT_REQUEST_AUTHORIZATION; info->userdata = user_data; info->user = g_strdup(remote_user); info->ref = 2; /* We hold an extra ref to make sure info remains valid if any of the callbacks are called synchronously. We unref it after the function call */ info->ui_handle = ui_ops->request_authorize(account, remote_user, id, alias, message, on_list, request_auth_cb, request_deny_cb, info); info = purple_account_request_info_unref(info); handles = g_list_append(handles, info); purple_account_request_close_with_account(PurpleAccount *account) g_return_if_fail(PURPLE_IS_ACCOUNT(account)); for (l = handles; l != NULL; l = l_next) { PurpleAccountRequestInfo *info = l->data; if (info->account == account) { handles = g_list_delete_link(handles, l); purple_account_request_close_info(info); purple_account_request_close(void *ui_handle) g_return_if_fail(ui_handle != NULL); for (l = handles; l != NULL; l = l_next) { PurpleAccountRequestInfo *info = l->data; if (info->ui_handle == ui_handle) { handles = g_list_delete_link(handles, l); purple_account_request_close_info(info); purple_account_request_password(PurpleAccount *account, GCallback ok_cb, GCallback cancel_cb, void *user_data) PurpleRequestFieldGroup *group; PurpleRequestField *field; PurpleRequestFields *fields; /* Close any previous password request windows */ purple_request_close_with_handle(account); username = purple_account_get_username(account); primary = g_strdup_printf(_("Enter password for %s (%s)"), username, purple_account_get_protocol_name(account)); fields = purple_request_fields_new(); group = purple_request_field_group_new(NULL); purple_request_fields_add_group(fields, group); field = purple_request_field_string_new("password", _("Enter Password"), NULL, FALSE); purple_request_field_string_set_masked(field, TRUE); purple_request_field_set_required(field, TRUE); purple_request_field_group_add_field(group, field); field = purple_request_field_bool_new("remember", _("Save password"), FALSE); purple_request_field_group_add_field(group, field); purple_request_fields(account, NULL, primary, NULL, fields, _("OK"), ok_cb, _("Cancel"), cancel_cb, purple_request_cpar_from_account(account), user_data); purple_account_request_change_password(PurpleAccount *account) PurpleRequestFields *fields; PurpleRequestFieldGroup *group; PurpleRequestField *field; PurpleProtocol *protocol = NULL; g_return_if_fail(PURPLE_IS_ACCOUNT(account)); g_return_if_fail(purple_account_is_connected(account)); gc = purple_account_get_connection(account); protocol = purple_connection_get_protocol(gc); fields = purple_request_fields_new(); group = purple_request_field_group_new(NULL); purple_request_fields_add_group(fields, group); field = purple_request_field_string_new("password", _("Original password"), purple_request_field_string_set_masked(field, TRUE); if (!protocol || !(purple_protocol_get_options(protocol) & OPT_PROTO_PASSWORD_OPTIONAL)) purple_request_field_set_required(field, TRUE); purple_request_field_group_add_field(group, field); field = purple_request_field_string_new("new_password_1", purple_request_field_string_set_masked(field, TRUE); if (!protocol || !(purple_protocol_get_options(protocol) & OPT_PROTO_PASSWORD_OPTIONAL)) purple_request_field_set_required(field, TRUE); purple_request_field_group_add_field(group, field); field = purple_request_field_string_new("new_password_2", _("New password (again)"), purple_request_field_string_set_masked(field, TRUE); if (!protocol || !(purple_protocol_get_options(protocol) & OPT_PROTO_PASSWORD_OPTIONAL)) purple_request_field_set_required(field, TRUE); purple_request_field_group_add_field(group, field); g_snprintf(primary, sizeof(primary), _("Change password for %s"), purple_account_get_username(account)); /* I'm sticking this somewhere in the code: bologna */ purple_request_fields(purple_account_get_connection(account), NULL, primary, _("Please enter your current password and your new " "password."), fields, _("OK"), G_CALLBACK(change_password_cb), _("Cancel"), NULL, purple_request_cpar_from_account(account), purple_account_request_change_user_info(PurpleAccount *account) g_return_if_fail(PURPLE_IS_ACCOUNT(account)); g_return_if_fail(purple_account_is_connected(account)); gc = purple_account_get_connection(account); g_snprintf(primary, sizeof(primary), _("Change user information for %s"), purple_account_get_username(account)); purple_request_input(gc, _("Set User Info"), primary, NULL, purple_account_get_user_info(account), TRUE, FALSE, ((gc != NULL) && (purple_connection_get_flags(gc) & PURPLE_CONNECTION_FLAG_HTML) ? "html" : NULL), _("Save"), G_CALLBACK(set_user_info_cb), purple_request_cpar_from_account(account), purple_account_set_username(PurpleAccount *account, const char *username) PurpleAccountPrivate *priv; g_return_if_fail(PURPLE_IS_ACCOUNT(account)); priv = purple_account_get_instance_private(account); priv->username = g_strdup(username); g_object_notify_by_pspec(G_OBJECT(account), properties[PROP_USERNAME]); purple_accounts_schedule_save(); /* if the name changes, we should re-write the buddy list * to disk with the new name */ purple_blist_save_account(purple_blist_get_default(), account); purple_account_set_password(PurpleAccount *account, const gchar *password, PurpleKeyringSaveCallback cb, gpointer data) PurpleAccountPrivate *priv; g_return_if_fail(PURPLE_IS_ACCOUNT(account)); priv = purple_account_get_instance_private(account); purple_str_wipe(priv->password); priv->password = g_strdup(password); purple_accounts_schedule_save(); if (!purple_account_get_remember_password(account)) { purple_debug_info("account", "Password for %s set, not sent to keyring.\n", purple_account_get_username(account)); purple_keyring_set_password(account, password, cb, data); purple_account_set_private_alias(PurpleAccount *account, const char *alias) PurpleAccountPrivate *priv; g_return_if_fail(PURPLE_IS_ACCOUNT(account)); priv = purple_account_get_instance_private(account); * Do nothing if alias and priv->alias are both NULL. Or if * they're the exact same string. if (alias == priv->alias) if ((!alias && priv->alias) || (alias && !priv->alias) || g_utf8_collate(priv->alias, alias)) priv->alias = g_strdup(alias); g_object_notify_by_pspec(G_OBJECT(account), properties[PROP_PRIVATE_ALIAS]); purple_signal_emit(purple_accounts_get_handle(), "account-alias-changed", purple_accounts_schedule_save(); purple_account_set_user_info(PurpleAccount *account, const char *user_info) PurpleAccountPrivate *priv; g_return_if_fail(PURPLE_IS_ACCOUNT(account)); priv = purple_account_get_instance_private(account); priv->user_info = g_strdup(user_info); g_object_notify_by_pspec(G_OBJECT(account), properties[PROP_USER_INFO]); purple_accounts_schedule_save(); void purple_account_set_buddy_icon_path(PurpleAccount *account, const char *path) PurpleAccountPrivate *priv; g_return_if_fail(PURPLE_IS_ACCOUNT(account)); priv = purple_account_get_instance_private(account); g_free(priv->buddy_icon_path); priv->buddy_icon_path = g_strdup(path); g_object_notify_by_pspec(G_OBJECT(account), properties[PROP_BUDDY_ICON_PATH]); purple_accounts_schedule_save(); purple_account_set_protocol_id(PurpleAccount *account, const char *protocol_id) PurpleAccountPrivate *priv; g_return_if_fail(PURPLE_IS_ACCOUNT(account)); g_return_if_fail(protocol_id != NULL); priv = purple_account_get_instance_private(account); g_free(priv->protocol_id); priv->protocol_id = g_strdup(protocol_id); g_object_notify_by_pspec(G_OBJECT(account), properties[PROP_PROTOCOL_ID]); purple_accounts_schedule_save(); purple_account_set_connection(PurpleAccount *account, PurpleConnection *gc) PurpleAccountPrivate *priv; g_return_if_fail(PURPLE_IS_ACCOUNT(account)); priv = purple_account_get_instance_private(account); g_object_notify_by_pspec(G_OBJECT(account), properties[PROP_CONNECTION]); purple_account_set_remember_password(PurpleAccount *account, gboolean value) PurpleAccountPrivate *priv; g_return_if_fail(PURPLE_IS_ACCOUNT(account)); priv = purple_account_get_instance_private(account); priv->remember_pass = value; g_object_notify_by_pspec(G_OBJECT(account), properties[PROP_REMEMBER_PASSWORD]); purple_accounts_schedule_save(); purple_account_set_check_mail(PurpleAccount *account, gboolean value) g_return_if_fail(PURPLE_IS_ACCOUNT(account)); purple_account_set_bool(account, "check-mail", value); g_object_notify_by_pspec(G_OBJECT(account), properties[PROP_CHECK_MAIL]); purple_account_set_enabled(PurpleAccount *account, const char *ui, PurpleAccountPrivate *priv; gboolean was_enabled = FALSE; g_return_if_fail(PURPLE_IS_ACCOUNT(account)); g_return_if_fail(ui != NULL); was_enabled = purple_account_get_enabled(account, ui); purple_account_set_ui_bool(account, ui, "auto-login", value); gc = purple_account_get_connection(account); if(was_enabled && !value) purple_signal_emit(purple_accounts_get_handle(), "account-disabled", account); else if(!was_enabled && value) purple_signal_emit(purple_accounts_get_handle(), "account-enabled", account); g_object_notify_by_pspec(G_OBJECT(account), properties[PROP_ENABLED]); if ((gc != NULL) && (_purple_connection_wants_to_die(gc))) priv = purple_account_get_instance_private(account); if (value && purple_presence_is_online(priv->presence)) purple_account_connect(account); else if (!value && !purple_account_is_disconnected(account)) purple_account_disconnect(account); purple_account_set_proxy_info(PurpleAccount *account, PurpleProxyInfo *info) PurpleAccountPrivate *priv; g_return_if_fail(PURPLE_IS_ACCOUNT(account)); priv = purple_account_get_instance_private(account); if (priv->proxy_info != NULL) purple_proxy_info_destroy(priv->proxy_info); purple_accounts_schedule_save(); purple_account_set_privacy_type(PurpleAccount *account, PurpleAccountPrivacyType privacy_type) PurpleAccountPrivate *priv; g_return_if_fail(PURPLE_IS_ACCOUNT(account)); priv = purple_account_get_instance_private(account); priv->privacy_type = privacy_type; purple_account_set_status_types(PurpleAccount *account, GList *status_types) PurpleAccountPrivate *priv; g_return_if_fail(PURPLE_IS_ACCOUNT(account)); priv = purple_account_get_instance_private(account); /* Out with the old... */ g_list_free_full(priv->status_types, (GDestroyNotify)purple_status_type_destroy); priv->status_types = status_types; purple_account_set_status(PurpleAccount *account, const char *status_id, while ((id = va_arg(args, const char *)) != NULL) attrs = g_list_append(attrs, (char *)id); data = va_arg(args, void *); attrs = g_list_append(attrs, data); purple_account_set_status_list(account, status_id, active, attrs); purple_account_set_status_list(PurpleAccount *account, const char *status_id, gboolean active, GList *attrs) g_return_if_fail(PURPLE_IS_ACCOUNT(account)); g_return_if_fail(status_id != NULL); status = purple_account_get_status(account, status_id); purple_debug_error("account", "Invalid status ID '%s' for account %s (%s)\n", status_id, purple_account_get_username(account), purple_account_get_protocol_id(account)); if (active || purple_status_is_independent(status)) purple_status_set_active_with_attrs_list(status, active, attrs); * Our current statuses are saved to accounts.xml (so that when we * reconnect, we go back to the previous status). purple_accounts_schedule_save(); purple_account_set_public_alias(PurpleAccount *account, const char *alias, PurpleSetPublicAliasSuccessCallback success_cb, PurpleSetPublicAliasFailureCallback failure_cb) PurpleProtocol *protocol = NULL; g_return_if_fail(PURPLE_IS_ACCOUNT(account)); g_return_if_fail(purple_account_is_connected(account)); gc = purple_account_get_connection(account); protocol = purple_connection_get_protocol(gc); if (PURPLE_PROTOCOL_IMPLEMENTS(protocol, SERVER, set_public_alias)) purple_protocol_server_iface_set_public_alias(protocol, gc, alias, success_cb, failure_cb); struct public_alias_closure *closure = g_new0(struct public_alias_closure, 1); closure->account = g_object_ref(account); closure->failure_cb = failure_cb; g_timeout_add(0, set_public_alias_unsupported, closure); purple_account_get_public_alias(PurpleAccount *account, PurpleGetPublicAliasSuccessCallback success_cb, PurpleGetPublicAliasFailureCallback failure_cb) PurpleProtocol *protocol = NULL; g_return_if_fail(PURPLE_IS_ACCOUNT(account)); g_return_if_fail(purple_account_is_connected(account)); gc = purple_account_get_connection(account); protocol = purple_connection_get_protocol(gc); if (PURPLE_PROTOCOL_IMPLEMENTS(protocol, SERVER, get_public_alias)) purple_protocol_server_iface_get_public_alias(protocol, gc, success_cb, failure_cb); struct public_alias_closure *closure = g_new0(struct public_alias_closure, 1); closure->account = g_object_ref(account); closure->failure_cb = failure_cb; g_timeout_add(0, get_public_alias_unsupported, closure); purple_account_get_silence_suppression(PurpleAccount *account) return purple_account_get_bool(account, "silence-suppression", FALSE); purple_account_set_silence_suppression(PurpleAccount *account, gboolean value) g_return_if_fail(PURPLE_IS_ACCOUNT(account)); purple_account_set_bool(account, "silence-suppression", value); purple_account_clear_settings(PurpleAccount *account) PurpleAccountPrivate *priv; g_return_if_fail(PURPLE_IS_ACCOUNT(account)); priv = purple_account_get_instance_private(account); g_hash_table_destroy(priv->settings); priv->settings = g_hash_table_new_full(g_str_hash, g_str_equal, purple_account_remove_setting(PurpleAccount *account, const char *setting) PurpleAccountPrivate *priv; g_return_if_fail(PURPLE_IS_ACCOUNT(account)); g_return_if_fail(setting != NULL); priv = purple_account_get_instance_private(account); g_hash_table_remove(priv->settings, setting); purple_account_set_int(PurpleAccount *account, const char *name, int value) PurpleAccountSetting *setting; PurpleAccountPrivate *priv; g_return_if_fail(PURPLE_IS_ACCOUNT(account)); g_return_if_fail(name != NULL); priv = purple_account_get_instance_private(account); setting = g_new0(PurpleAccountSetting, 1); g_value_init(&setting->value, G_TYPE_INT); g_value_set_int(&setting->value, value); g_hash_table_insert(priv->settings, g_strdup(name), setting); purple_accounts_schedule_save(); purple_account_set_string(PurpleAccount *account, const char *name, PurpleAccountSetting *setting; PurpleAccountPrivate *priv; g_return_if_fail(PURPLE_IS_ACCOUNT(account)); g_return_if_fail(name != NULL); priv = purple_account_get_instance_private(account); setting = g_new0(PurpleAccountSetting, 1); g_value_init(&setting->value, G_TYPE_STRING); g_value_set_string(&setting->value, value); g_hash_table_insert(priv->settings, g_strdup(name), setting); purple_accounts_schedule_save(); purple_account_set_bool(PurpleAccount *account, const char *name, gboolean value) PurpleAccountSetting *setting; PurpleAccountPrivate *priv; g_return_if_fail(PURPLE_IS_ACCOUNT(account)); g_return_if_fail(name != NULL); priv = purple_account_get_instance_private(account); setting = g_new0(PurpleAccountSetting, 1); g_value_init(&setting->value, G_TYPE_BOOLEAN); g_value_set_boolean(&setting->value, value); g_hash_table_insert(priv->settings, g_strdup(name), setting); purple_accounts_schedule_save(); purple_account_set_ui_int(PurpleAccount *account, const char *ui, const char *name, int value) PurpleAccountSetting *setting; g_return_if_fail(PURPLE_IS_ACCOUNT(account)); g_return_if_fail(ui != NULL); g_return_if_fail(name != NULL); setting = g_new0(PurpleAccountSetting, 1); setting->ui = g_strdup(ui); g_value_init(&setting->value, G_TYPE_INT); g_value_set_int(&setting->value, value); table = get_ui_settings_table(account, ui); g_hash_table_insert(table, g_strdup(name), setting); purple_accounts_schedule_save(); purple_account_set_ui_string(PurpleAccount *account, const char *ui, const char *name, const char *value) PurpleAccountSetting *setting; g_return_if_fail(PURPLE_IS_ACCOUNT(account)); g_return_if_fail(ui != NULL); g_return_if_fail(name != NULL); setting = g_new0(PurpleAccountSetting, 1); setting->ui = g_strdup(ui); g_value_init(&setting->value, G_TYPE_STRING); g_value_set_string(&setting->value, value); table = get_ui_settings_table(account, ui); g_hash_table_insert(table, g_strdup(name), setting); purple_accounts_schedule_save(); purple_account_set_ui_bool(PurpleAccount *account, const char *ui, const char *name, gboolean value) PurpleAccountSetting *setting; g_return_if_fail(PURPLE_IS_ACCOUNT(account)); g_return_if_fail(ui != NULL); g_return_if_fail(name != NULL); setting = g_new0(PurpleAccountSetting, 1); setting->ui = g_strdup(ui); g_value_init(&setting->value, G_TYPE_BOOLEAN); g_value_set_boolean(&setting->value, value); table = get_ui_settings_table(account, ui); g_hash_table_insert(table, g_strdup(name), setting); purple_accounts_schedule_save(); purple_account_is_connected(PurpleAccount *account) return (purple_account_get_state(account) == PURPLE_CONNECTION_CONNECTED); purple_account_is_connecting(PurpleAccount *account) return (purple_account_get_state(account) == PURPLE_CONNECTION_CONNECTING); purple_account_is_disconnected(PurpleAccount *account) return (purple_account_get_state(account) == PURPLE_CONNECTION_DISCONNECTED); purple_account_get_username(PurpleAccount *account) PurpleAccountPrivate *priv; g_return_val_if_fail(PURPLE_IS_ACCOUNT(account), NULL); priv = purple_account_get_instance_private(account); purple_account_get_password(PurpleAccount *account, PurpleKeyringReadCallback cb, gpointer data) PurpleAccountPrivate *priv; cb(NULL, NULL, NULL, data); priv = purple_account_get_instance_private(account); if (priv->password != NULL) { purple_debug_info("account", "Reading password for account %s from cache.\n", purple_account_get_username(account)); cb(account, priv->password, NULL, data); PurpleCallbackBundle *cbb = g_new0(PurpleCallbackBundle, 1); cbb->cb = PURPLE_CALLBACK(cb); purple_debug_info("account", "Reading password for account %s from async keyring.\n", purple_account_get_username(account)); purple_keyring_get_password(account, purple_account_get_password_got, cbb); purple_account_get_private_alias(PurpleAccount *account) PurpleAccountPrivate *priv; g_return_val_if_fail(PURPLE_IS_ACCOUNT(account), NULL); priv = purple_account_get_instance_private(account); purple_account_get_user_info(PurpleAccount *account) PurpleAccountPrivate *priv; g_return_val_if_fail(PURPLE_IS_ACCOUNT(account), NULL); priv = purple_account_get_instance_private(account); purple_account_get_buddy_icon_path(PurpleAccount *account) PurpleAccountPrivate *priv; g_return_val_if_fail(PURPLE_IS_ACCOUNT(account), NULL); priv = purple_account_get_instance_private(account); return priv->buddy_icon_path; purple_account_get_protocol_id(PurpleAccount *account) PurpleAccountPrivate *priv; g_return_val_if_fail(PURPLE_IS_ACCOUNT(account), NULL); priv = purple_account_get_instance_private(account); return priv->protocol_id; purple_account_get_protocol_name(PurpleAccount *account) g_return_val_if_fail(PURPLE_IS_ACCOUNT(account), NULL); p = purple_protocols_find(purple_account_get_protocol_id(account)); return (p && purple_protocol_get_name(p) ? _(purple_protocol_get_name(p)) : _("Unknown")); purple_account_get_connection(PurpleAccount *account) PurpleAccountPrivate *priv; g_return_val_if_fail(PURPLE_IS_ACCOUNT(account), NULL); priv = purple_account_get_instance_private(account); purple_account_get_name_for_display(PurpleAccount *account) PurpleBuddy *self = NULL; PurpleConnection *gc = NULL; const gchar *name = NULL, *username = NULL, *displayname = NULL; name = purple_account_get_private_alias(account); username = purple_account_get_username(account); self = purple_blist_find_buddy((PurpleAccount *)account, username); 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)) { gc = purple_account_get_connection(account); displayname = purple_connection_get_display_name(gc); purple_account_get_remember_password(PurpleAccount *account) PurpleAccountPrivate *priv; g_return_val_if_fail(PURPLE_IS_ACCOUNT(account), FALSE); priv = purple_account_get_instance_private(account); return priv->remember_pass; purple_account_get_check_mail(PurpleAccount *account) g_return_val_if_fail(PURPLE_IS_ACCOUNT(account), FALSE); return purple_account_get_bool(account, "check-mail", FALSE); purple_account_get_enabled(PurpleAccount *account, const char *ui) g_return_val_if_fail(PURPLE_IS_ACCOUNT(account), FALSE); g_return_val_if_fail(ui != NULL, FALSE); return purple_account_get_ui_bool(account, ui, "auto-login", FALSE); purple_account_get_proxy_info(PurpleAccount *account) PurpleAccountPrivate *priv; g_return_val_if_fail(PURPLE_IS_ACCOUNT(account), NULL); priv = purple_account_get_instance_private(account); purple_account_get_privacy_type(PurpleAccount *account) PurpleAccountPrivate *priv; g_return_val_if_fail(PURPLE_IS_ACCOUNT(account), PURPLE_ACCOUNT_PRIVACY_ALLOW_ALL); priv = purple_account_get_instance_private(account); return priv->privacy_type; purple_account_privacy_permit_add(PurpleAccount *account, const char *who, PurpleAccountPrivate *priv; PurpleAccountUiOps *ui_ops = purple_accounts_get_ui_ops(); g_return_val_if_fail(PURPLE_IS_ACCOUNT(account), FALSE); g_return_val_if_fail(who != NULL, FALSE); priv = purple_account_get_instance_private(account); name = g_strdup(purple_normalize(account, who)); if (g_slist_find_custom(priv->permit, name, (GCompareFunc)g_strcmp0) != NULL) { /* This buddy already exists, so bail out */ priv->permit = g_slist_append(priv->permit, name); if (!local_only && purple_account_is_connected(account)) purple_serv_add_permit(purple_account_get_connection(account), who); if (ui_ops != NULL && ui_ops->permit_added != NULL) ui_ops->permit_added(account, who); purple_blist_save_account(purple_blist_get_default(), account); /* This lets the UI know a buddy has had its privacy setting changed */ buddy = purple_blist_find_buddy(account, name); purple_signal_emit(purple_blist_get_handle(), "buddy-privacy-changed", buddy); purple_account_privacy_permit_remove(PurpleAccount *account, const char *who, PurpleAccountPrivate *priv; PurpleAccountUiOps *ui_ops = purple_accounts_get_ui_ops(); g_return_val_if_fail(PURPLE_IS_ACCOUNT(account), FALSE); g_return_val_if_fail(who != NULL, FALSE); priv = purple_account_get_instance_private(account); name = purple_normalize(account, who); l = g_slist_find_custom(priv->permit, name, (GCompareFunc)g_strcmp0); /* We didn't find the buddy we were looking for, so bail out */ /* We should not free l->data just yet. There can be occasions where * l->data == who. In such cases, freeing l->data here can cause crashes * later when who is used. */ priv->permit = g_slist_delete_link(priv->permit, l); if (!local_only && purple_account_is_connected(account)) purple_serv_rem_permit(purple_account_get_connection(account), who); if (ui_ops != NULL && ui_ops->permit_removed != NULL) ui_ops->permit_removed(account, who); purple_blist_save_account(purple_blist_get_default(), account); buddy = purple_blist_find_buddy(account, name); purple_signal_emit(purple_blist_get_handle(), "buddy-privacy-changed", buddy); purple_account_privacy_deny_add(PurpleAccount *account, const char *who, PurpleAccountPrivate *priv; PurpleAccountUiOps *ui_ops = purple_accounts_get_ui_ops(); g_return_val_if_fail(PURPLE_IS_ACCOUNT(account), FALSE); g_return_val_if_fail(who != NULL, FALSE); priv = purple_account_get_instance_private(account); name = g_strdup(purple_normalize(account, who)); if (g_slist_find_custom(priv->deny, name, (GCompareFunc)g_strcmp0) != NULL) { /* This buddy already exists, so bail out */ priv->deny = g_slist_append(priv->deny, name); if (!local_only && purple_account_is_connected(account)) purple_serv_add_deny(purple_account_get_connection(account), who); if (ui_ops != NULL && ui_ops->deny_added != NULL) ui_ops->deny_added(account, who); purple_blist_save_account(purple_blist_get_default(), account); buddy = purple_blist_find_buddy(account, name); purple_signal_emit(purple_blist_get_handle(), "buddy-privacy-changed", buddy); purple_account_privacy_deny_remove(PurpleAccount *account, const char *who, PurpleAccountPrivate *priv; PurpleAccountUiOps *ui_ops = purple_accounts_get_ui_ops(); g_return_val_if_fail(PURPLE_IS_ACCOUNT(account), FALSE); g_return_val_if_fail(who != NULL, FALSE); priv = purple_account_get_instance_private(account); normalized = purple_normalize(account, who); l = g_slist_find_custom(priv->deny, normalized, (GCompareFunc)g_strcmp0); /* We didn't find the buddy we were looking for, so bail out */ buddy = purple_blist_find_buddy(account, normalized); priv->deny = g_slist_delete_link(priv->deny, l); if (!local_only && purple_account_is_connected(account)) purple_serv_rem_deny(purple_account_get_connection(account), name); if (ui_ops != NULL && ui_ops->deny_removed != NULL) ui_ops->deny_removed(account, who); purple_signal_emit(purple_blist_get_handle(), "buddy-privacy-changed", buddy); purple_blist_save_account(purple_blist_get_default(), account); purple_account_privacy_allow(PurpleAccount *account, const char *who) PurpleAccountPrivacyType type = purple_account_get_privacy_type(account); PurpleAccountPrivate *priv = purple_account_get_instance_private(account); case PURPLE_ACCOUNT_PRIVACY_ALLOW_ALL: case PURPLE_ACCOUNT_PRIVACY_ALLOW_USERS: purple_account_privacy_permit_add(account, who, FALSE); case PURPLE_ACCOUNT_PRIVACY_DENY_USERS: purple_account_privacy_deny_remove(account, who, FALSE); case PURPLE_ACCOUNT_PRIVACY_DENY_ALL: /* Empty the allow-list. */ const char *norm = purple_normalize(account, who); for (list = priv->permit; list != NULL;) { char *person = list->data; if (!purple_strequal(norm, person)) purple_account_privacy_permit_remove(account, person, FALSE); purple_account_privacy_permit_add(account, who, FALSE); purple_account_set_privacy_type(account, PURPLE_ACCOUNT_PRIVACY_ALLOW_USERS); case PURPLE_ACCOUNT_PRIVACY_ALLOW_BUDDYLIST: if (!purple_blist_find_buddy(account, who)) { add_all_buddies_to_permit_list(account, FALSE); purple_account_privacy_permit_add(account, who, FALSE); purple_account_set_privacy_type(account, PURPLE_ACCOUNT_PRIVACY_ALLOW_USERS); /* Notify the server if the privacy setting was changed */ if (type != purple_account_get_privacy_type(account) && purple_account_is_connected(account)) purple_serv_set_permit_deny(purple_account_get_connection(account)); purple_account_privacy_deny(PurpleAccount *account, const char *who) PurpleAccountPrivacyType type = purple_account_get_privacy_type(account); PurpleAccountPrivate *priv = purple_account_get_instance_private(account); case PURPLE_ACCOUNT_PRIVACY_ALLOW_ALL: /* Empty the deny-list. */ const char *norm = purple_normalize(account, who); for (list = priv->deny; list != NULL; ) { char *person = list->data; if (!purple_strequal(norm, person)) purple_account_privacy_deny_remove(account, person, FALSE); purple_account_privacy_deny_add(account, who, FALSE); purple_account_set_privacy_type(account, PURPLE_ACCOUNT_PRIVACY_DENY_USERS); case PURPLE_ACCOUNT_PRIVACY_ALLOW_USERS: purple_account_privacy_permit_remove(account, who, FALSE); case PURPLE_ACCOUNT_PRIVACY_DENY_USERS: purple_account_privacy_deny_add(account, who, FALSE); case PURPLE_ACCOUNT_PRIVACY_DENY_ALL: case PURPLE_ACCOUNT_PRIVACY_ALLOW_BUDDYLIST: if (purple_blist_find_buddy(account, who)) { add_all_buddies_to_permit_list(account, FALSE); purple_account_privacy_permit_remove(account, who, FALSE); purple_account_set_privacy_type(account, PURPLE_ACCOUNT_PRIVACY_ALLOW_USERS); /* Notify the server if the privacy setting was changed */ if (type != purple_account_get_privacy_type(account) && purple_account_is_connected(account)) purple_serv_set_permit_deny(purple_account_get_connection(account)); purple_account_privacy_get_permitted(PurpleAccount *account) PurpleAccountPrivate *priv = NULL; g_return_val_if_fail(PURPLE_IS_ACCOUNT(account), NULL); priv = purple_account_get_instance_private(account); purple_account_privacy_get_denied(PurpleAccount *account) PurpleAccountPrivate *priv = NULL; g_return_val_if_fail(PURPLE_IS_ACCOUNT(account), NULL); priv = purple_account_get_instance_private(account); purple_account_privacy_check(PurpleAccount *account, const char *who) PurpleAccountPrivate *priv = purple_account_get_instance_private(account); switch (purple_account_get_privacy_type(account)) { case PURPLE_ACCOUNT_PRIVACY_ALLOW_ALL: case PURPLE_ACCOUNT_PRIVACY_DENY_ALL: case PURPLE_ACCOUNT_PRIVACY_ALLOW_USERS: who = purple_normalize(account, who); return (g_slist_find_custom(priv->permit, who, (GCompareFunc)g_strcmp0) != NULL); case PURPLE_ACCOUNT_PRIVACY_DENY_USERS: who = purple_normalize(account, who); return (g_slist_find_custom(priv->deny, who, (GCompareFunc)g_strcmp0) == NULL); case PURPLE_ACCOUNT_PRIVACY_ALLOW_BUDDYLIST: return (purple_blist_find_buddy(account, who) != NULL); g_return_val_if_reached(TRUE); purple_account_get_active_status(PurpleAccount *account) PurpleAccountPrivate *priv; g_return_val_if_fail(PURPLE_IS_ACCOUNT(account), NULL); priv = purple_account_get_instance_private(account); return purple_presence_get_active_status(priv->presence); purple_account_get_status(PurpleAccount *account, const char *status_id) PurpleAccountPrivate *priv; g_return_val_if_fail(PURPLE_IS_ACCOUNT(account), NULL); g_return_val_if_fail(status_id != NULL, NULL); priv = purple_account_get_instance_private(account); return purple_presence_get_status(priv->presence, status_id); purple_account_get_status_type(PurpleAccount *account, const char *id) g_return_val_if_fail(PURPLE_IS_ACCOUNT(account), NULL); g_return_val_if_fail(id != NULL, NULL); for (l = purple_account_get_status_types(account); l != NULL; l = l->next) PurpleStatusType *status_type = (PurpleStatusType *)l->data; if (purple_strequal(purple_status_type_get_id(status_type), id)) purple_account_get_status_type_with_primitive(PurpleAccount *account, PurpleStatusPrimitive primitive) g_return_val_if_fail(PURPLE_IS_ACCOUNT(account), NULL); for (l = purple_account_get_status_types(account); l != NULL; l = l->next) PurpleStatusType *status_type = (PurpleStatusType *)l->data; if (purple_status_type_get_primitive(status_type) == primitive) purple_account_get_presence(PurpleAccount *account) PurpleAccountPrivate *priv; g_return_val_if_fail(PURPLE_IS_ACCOUNT(account), NULL); priv = purple_account_get_instance_private(account); purple_account_is_status_active(PurpleAccount *account, PurpleAccountPrivate *priv; g_return_val_if_fail(PURPLE_IS_ACCOUNT(account), FALSE); g_return_val_if_fail(status_id != NULL, FALSE); priv = purple_account_get_instance_private(account); return purple_presence_is_status_active(priv->presence, status_id); purple_account_get_status_types(PurpleAccount *account) PurpleAccountPrivate *priv; g_return_val_if_fail(PURPLE_IS_ACCOUNT(account), NULL); priv = purple_account_get_instance_private(account); return priv->status_types; purple_account_get_int(PurpleAccount *account, const char *name, PurpleAccountSetting *setting; PurpleAccountPrivate *priv; g_return_val_if_fail(PURPLE_IS_ACCOUNT(account), default_value); g_return_val_if_fail(name != NULL, default_value); priv = purple_account_get_instance_private(account); setting = g_hash_table_lookup(priv->settings, name); g_return_val_if_fail(G_VALUE_HOLDS_INT(&setting->value), default_value); return g_value_get_int(&setting->value); purple_account_get_string(PurpleAccount *account, const char *name, const char *default_value) PurpleAccountSetting *setting; PurpleAccountPrivate *priv; g_return_val_if_fail(PURPLE_IS_ACCOUNT(account), default_value); g_return_val_if_fail(name != NULL, default_value); priv = purple_account_get_instance_private(account); setting = g_hash_table_lookup(priv->settings, name); g_return_val_if_fail(G_VALUE_HOLDS_STRING(&setting->value), default_value); return g_value_get_string(&setting->value); purple_account_get_bool(PurpleAccount *account, const char *name, PurpleAccountSetting *setting; PurpleAccountPrivate *priv; g_return_val_if_fail(PURPLE_IS_ACCOUNT(account), default_value); g_return_val_if_fail(name != NULL, default_value); priv = purple_account_get_instance_private(account); setting = g_hash_table_lookup(priv->settings, name); g_return_val_if_fail(G_VALUE_HOLDS_BOOLEAN(&setting->value), default_value); return g_value_get_boolean(&setting->value); purple_account_get_ui_int(PurpleAccount *account, const char *ui, const char *name, int default_value) PurpleAccountSetting *setting; PurpleAccountPrivate *priv; g_return_val_if_fail(PURPLE_IS_ACCOUNT(account), default_value); g_return_val_if_fail(ui != NULL, default_value); g_return_val_if_fail(name != NULL, default_value); priv = purple_account_get_instance_private(account); if ((table = g_hash_table_lookup(priv->ui_settings, ui)) == NULL) if ((setting = g_hash_table_lookup(table, name)) == NULL) g_return_val_if_fail(G_VALUE_HOLDS_INT(&setting->value), default_value); return g_value_get_int(&setting->value); purple_account_get_ui_string(PurpleAccount *account, const char *ui, const char *name, const char *default_value) PurpleAccountSetting *setting; PurpleAccountPrivate *priv; g_return_val_if_fail(PURPLE_IS_ACCOUNT(account), default_value); g_return_val_if_fail(ui != NULL, default_value); g_return_val_if_fail(name != NULL, default_value); priv = purple_account_get_instance_private(account); if ((table = g_hash_table_lookup(priv->ui_settings, ui)) == NULL) if ((setting = g_hash_table_lookup(table, name)) == NULL) g_return_val_if_fail(G_VALUE_HOLDS_STRING(&setting->value), default_value); return g_value_get_string(&setting->value); purple_account_get_ui_bool(PurpleAccount *account, const char *ui, const char *name, gboolean default_value) PurpleAccountSetting *setting; PurpleAccountPrivate *priv; g_return_val_if_fail(PURPLE_IS_ACCOUNT(account), default_value); g_return_val_if_fail(ui != NULL, default_value); g_return_val_if_fail(name != NULL, default_value); priv = purple_account_get_instance_private(account); if ((table = g_hash_table_lookup(priv->ui_settings, ui)) == NULL) if ((setting = g_hash_table_lookup(table, name)) == NULL) g_return_val_if_fail(G_VALUE_HOLDS_BOOLEAN(&setting->value), default_value); return g_value_get_boolean(&setting->value); purple_account_get_log(PurpleAccount *account, gboolean create) PurpleAccountPrivate *priv; g_return_val_if_fail(PURPLE_IS_ACCOUNT(account), NULL); priv = purple_account_get_instance_private(account); if(!priv->system_log && create){ PurplePresence *presence; presence = purple_account_get_presence(account); login_time = purple_presence_get_login_time(presence); dt = g_date_time_new_from_unix_local(login_time); dt = g_date_time_new_now_local(); priv->system_log = purple_log_new(PURPLE_LOG_SYSTEM, purple_account_get_username(account), purple_account_destroy_log(PurpleAccount *account) PurpleAccountPrivate *priv; g_return_if_fail(PURPLE_IS_ACCOUNT(account)); priv = purple_account_get_instance_private(account); purple_log_free(priv->system_log); purple_account_add_buddy(PurpleAccount *account, PurpleBuddy *buddy, const char *message) PurpleProtocol *protocol = NULL; g_return_if_fail(PURPLE_IS_ACCOUNT(account)); g_return_if_fail(PURPLE_IS_BUDDY(buddy)); gc = purple_account_get_connection(account); protocol = purple_connection_get_protocol(gc); purple_protocol_server_iface_add_buddy(protocol, gc, buddy, purple_buddy_get_group(buddy), message); purple_account_add_buddies(PurpleAccount *account, GList *buddies, const char *message) PurpleProtocol *protocol = NULL; PurpleConnection *gc = purple_account_get_connection(account); protocol = purple_connection_get_protocol(gc); GList *cur, *groups = NULL; /* Make a list of what group each buddy is in */ for (cur = buddies; cur != NULL; cur = cur->next) { PurpleBuddy *buddy = cur->data; groups = g_list_append(groups, purple_buddy_get_group(buddy)); if (PURPLE_PROTOCOL_IMPLEMENTS(protocol, SERVER, add_buddies)) purple_protocol_server_iface_add_buddies(protocol, gc, buddies, groups, message); else if (PURPLE_PROTOCOL_IMPLEMENTS(protocol, SERVER, add_buddy)) { GList *curb = buddies, *curg = groups; while ((curb != NULL) && (curg != NULL)) { purple_protocol_server_iface_add_buddy(protocol, gc, curb->data, curg->data, message); purple_account_remove_buddy(PurpleAccount *account, PurpleBuddy *buddy, PurpleProtocol *protocol = NULL; PurpleConnection *gc = purple_account_get_connection(account); protocol = purple_connection_get_protocol(gc); purple_protocol_server_iface_remove_buddy(protocol, gc, buddy, group); purple_account_remove_buddies(PurpleAccount *account, GList *buddies, GList *groups) PurpleProtocol *protocol = NULL; PurpleConnection *gc = purple_account_get_connection(account); protocol = purple_connection_get_protocol(gc); if (PURPLE_PROTOCOL_IMPLEMENTS(protocol, SERVER, remove_buddies)) purple_protocol_server_iface_remove_buddies(protocol, gc, buddies, groups); while ((curb != NULL) && (curg != NULL)) { purple_account_remove_buddy(account, curb->data, curg->data); purple_account_remove_group(PurpleAccount *account, PurpleGroup *group) PurpleProtocol *protocol = NULL; PurpleConnection *gc = purple_account_get_connection(account); protocol = purple_connection_get_protocol(gc); purple_protocol_server_iface_remove_group(protocol, gc, group); purple_account_change_password(PurpleAccount *account, const char *orig_pw, PurpleProtocol *protocol = NULL; PurpleConnection *gc = purple_account_get_connection(account); purple_account_set_password(account, new_pw, NULL, NULL); protocol = purple_connection_get_protocol(gc); purple_protocol_server_iface_change_passwd(protocol, gc, orig_pw, new_pw); gboolean purple_account_supports_offline_message(PurpleAccount *account, PurpleBuddy *buddy) PurpleProtocol *protocol = NULL; g_return_val_if_fail(PURPLE_IS_ACCOUNT(account), FALSE); g_return_val_if_fail(PURPLE_IS_BUDDY(buddy), FALSE); gc = purple_account_get_connection(account); protocol = purple_connection_get_protocol(gc); return purple_protocol_client_iface_offline_message(protocol, buddy); const PurpleConnectionErrorInfo * purple_account_get_current_error(PurpleAccount *account) PurpleAccountPrivate *priv = purple_account_get_instance_private(account); return priv->current_error; purple_account_clear_current_error(PurpleAccount *account) _purple_account_set_current_error(account, NULL);