* @file connection.c Connection API * Gaim 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA static GList *connections = NULL; static GList *connections_connecting = NULL; static GaimConnectionUiOps *connection_ui_ops = NULL; static int connections_handle; send_keepalive(gpointer data) GaimConnection *gc = data; GaimPluginProtocolInfo *prpl_info = NULL; if (gc != NULL && gc->prpl != NULL) prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl); if (prpl_info && prpl_info->keepalive) prpl_info->keepalive(gc); update_keepalive(GaimConnection *gc, gboolean on) if (on && !gc->keepalive) gaim_debug_info("connection", "Activating keepalive.\n"); gc->keepalive = gaim_timeout_add(30000, send_keepalive, gc); else if (!on && gc->keepalive > 0) gaim_debug_info("connection", "Deactivating keepalive.\n"); gaim_timeout_remove(gc->keepalive); gaim_connection_new(GaimAccount *account, gboolean regist, const char *password) GaimPluginProtocolInfo *prpl_info; g_return_if_fail(account != NULL); if (!gaim_account_is_disconnected(account)) prpl = gaim_find_prpl(gaim_account_get_protocol_id(account)); prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(prpl); message = g_strdup_printf(_("Missing protocol plugin for %s"), gaim_account_get_username(account)); gaim_notify_error(NULL, regist ? _("Registration Error") : _("Connection Error"), message, NULL); if (prpl_info->register_user == NULL) if (((password == NULL) || (*password == '\0')) && !(prpl_info->options & OPT_PROTO_NO_PASSWORD) && !(prpl_info->options & OPT_PROTO_PASSWORD_OPTIONAL)) gaim_debug_error("connection", "Can not connect to account %s without " "a password.\n", gaim_account_get_username(account)); gc = g_new0(GaimConnection, 1); GAIM_DBUS_REGISTER_POINTER(gc, GaimConnection); if ((password != NULL) && (*password != '\0')) gc->password = g_strdup(password); gaim_connection_set_account(gc, account); gaim_connection_set_state(gc, GAIM_CONNECTING); connections = g_list_append(connections, gc); gaim_account_set_connection(account, gc); gaim_signal_emit(gaim_connections_get_handle(), "signing-on", gc); gaim_debug_info("connection", "Registering. gc = %p\n", gc); /* set this so we don't auto-reconnect after registering */ prpl_info->register_user(account); gaim_debug_info("connection", "Connecting. gc = %p\n", gc); gaim_signal_emit(gaim_accounts_get_handle(), "account-connecting", account); prpl_info->login(account); gaim_connection_destroy(GaimConnection *gc) GaimPluginProtocolInfo *prpl_info = NULL; g_return_if_fail(gc != NULL); account = gaim_connection_get_account(gc); gaim_debug_info("connection", "Disconnecting connection %p\n", gc); if (gaim_connection_get_state(gc) != GAIM_CONNECTING) gaim_signal_emit(gaim_connections_get_handle(), "signing-off", gc); GaimConversation *b = gc->buddy_chats->data; gc->buddy_chats = g_slist_remove(gc->buddy_chats, b); gaim_conv_chat_left(GAIM_CONV_CHAT(b)); update_keepalive(gc, FALSE); prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl); connections = g_list_remove(connections, gc); gaim_connection_set_state(gc, GAIM_DISCONNECTED); gaim_blist_remove_account(account); gaim_signal_emit(gaim_connections_get_handle(), "signed-off", gc); /* see comment later in file on if 0'd same code */ * XXX This is a hack! Remove this and replace it with a better event for (wins = gaim_get_windows(); wins != NULL; wins = wins->next) { GaimConvWindow *win = (GaimConvWindow *)wins->data; gaim_conversation_update(gaim_conv_window_get_conversation_at(win, 0), GAIM_CONV_ACCOUNT_OFFLINE); gaim_request_close_with_handle(gc); gaim_notify_close_with_handle(gc); gaim_debug_info("connection", "Destroying connection %p\n", gc); gaim_account_set_connection(account, NULL); if (gc->password != NULL) if (gc->display_name != NULL) g_free(gc->display_name); if (gc->disconnect_timeout) gaim_timeout_remove(gc->disconnect_timeout); GAIM_DBUS_UNREGISTER_POINTER(gc); gaim_connection_set_state(GaimConnection *gc, GaimConnectionState state) GaimConnectionUiOps *ops; g_return_if_fail(gc != NULL); ops = gaim_connections_get_ui_ops(); if (gc->state == GAIM_CONNECTING) { connections_connecting = g_list_append(connections_connecting, gc); connections_connecting = g_list_remove(connections_connecting, gc); if (gc->state == GAIM_CONNECTED) { account = gaim_connection_get_account(gc); presence = gaim_account_get_presence(account); /* Set the time the account came online */ gaim_presence_set_login_time(presence, time(NULL)); if (gaim_prefs_get_bool("/core/logging/log_system")) GaimLog *log = gaim_account_get_log(account, TRUE); char *msg = g_strdup_printf(_("+++ %s signed on"), gaim_account_get_username(account)); gaim_log_write(log, GAIM_MESSAGE_SYSTEM, gaim_account_get_username(account), gaim_presence_get_login_time(presence), if (ops != NULL && ops->connected != NULL) gaim_blist_add_account(account); gaim_signal_emit(gaim_connections_get_handle(), "signed-on", gc); serv_set_permit_deny(gc); update_keepalive(gc, TRUE); if (gaim_account_get_user_info(account) != NULL) serv_set_info(gc, gaim_account_get_user_info(account)); else if (gc->state == GAIM_DISCONNECTED) { GaimAccount *account = gaim_connection_get_account(gc); if (gaim_prefs_get_bool("/core/logging/log_system")) GaimLog *log = gaim_account_get_log(account, FALSE); char *msg = g_strdup_printf(_("+++ %s signed off"), gaim_account_get_username(account)); gaim_log_write(log, GAIM_MESSAGE_SYSTEM, gaim_account_get_username(account), time(NULL), gaim_account_destroy_log(account); if (ops != NULL && ops->disconnected != NULL) gaim_connection_set_account(GaimConnection *gc, GaimAccount *account) g_return_if_fail(gc != NULL); g_return_if_fail(account != NULL); gaim_connection_set_display_name(GaimConnection *gc, const char *name) g_return_if_fail(gc != NULL); if (gc->display_name != NULL) g_free(gc->display_name); gc->display_name = (name == NULL ? NULL : g_strdup(name)); gaim_connection_get_state(const GaimConnection *gc) g_return_val_if_fail(gc != NULL, GAIM_DISCONNECTED); gaim_connection_get_account(const GaimConnection *gc) g_return_val_if_fail(gc != NULL, NULL); gaim_connection_get_password(const GaimConnection *gc) g_return_val_if_fail(gc != NULL, NULL); gaim_connection_get_display_name(const GaimConnection *gc) g_return_val_if_fail(gc != NULL, NULL); gaim_connection_update_progress(GaimConnection *gc, const char *text, size_t step, size_t count) GaimConnectionUiOps *ops; g_return_if_fail(gc != NULL); g_return_if_fail(text != NULL); g_return_if_fail(step < count); g_return_if_fail(count > 1); ops = gaim_connections_get_ui_ops(); if (ops != NULL && ops->connect_progress != NULL) ops->connect_progress(gc, text, step, count); gaim_connection_notice(GaimConnection *gc, const char *text) GaimConnectionUiOps *ops; g_return_if_fail(gc != NULL); g_return_if_fail(text != NULL); ops = gaim_connections_get_ui_ops(); if (ops != NULL && ops->notice != NULL) gaim_connection_disconnect_cb(gpointer data) GaimAccount *account = data; char *password = g_strdup(gaim_account_get_password(account)); gaim_account_disconnect(account); gaim_account_set_password(account, password); gaim_connection_error(GaimConnection *gc, const char *text) GaimConnectionUiOps *ops; g_return_if_fail(gc != NULL); g_return_if_fail(text != NULL); /* If we've already got one error, we don't need any more */ if (gc->disconnect_timeout) ops = gaim_connections_get_ui_ops(); if (ops->report_disconnect != NULL) ops->report_disconnect(gc, text); gc->disconnect_timeout = gaim_timeout_add(0, gaim_connection_disconnect_cb, gaim_connection_get_account(gc)); gaim_connections_disconnect_all(void) while ((l = gaim_connections_get_all()) != NULL) { gaim_account_disconnect(gc->account); gaim_connections_get_all(void) gaim_connections_get_connecting(void) return connections_connecting; gaim_connections_set_ui_ops(GaimConnectionUiOps *ops) gaim_connections_get_ui_ops(void) return connection_ui_ops; gaim_connections_init(void) void *handle = gaim_connections_get_handle(); gaim_signal_register(handle, "signing-on", gaim_marshal_VOID__POINTER, NULL, 1, gaim_value_new(GAIM_TYPE_SUBTYPE, GAIM_SUBTYPE_CONNECTION)); gaim_signal_register(handle, "signed-on", gaim_marshal_VOID__POINTER, NULL, 1, gaim_value_new(GAIM_TYPE_SUBTYPE, GAIM_SUBTYPE_CONNECTION)); gaim_signal_register(handle, "signing-off", gaim_marshal_VOID__POINTER, NULL, 1, gaim_value_new(GAIM_TYPE_SUBTYPE, GAIM_SUBTYPE_CONNECTION)); gaim_signal_register(handle, "signed-off", gaim_marshal_VOID__POINTER, NULL, 1, gaim_value_new(GAIM_TYPE_SUBTYPE, GAIM_SUBTYPE_CONNECTION)); gaim_connections_uninit(void) gaim_signals_unregister_by_instance(gaim_connections_get_handle()); gaim_connections_get_handle(void) return &connections_handle;