Mercurial > pidgin
view src/protocols/msn/switchboard.c @ 5539:de09863bd4b5
[gaim-migrate @ 5939]
Split Show URLs as Links into Show URLs as Links and Send URLs as Links,
and converted them to the new prefs system.
Also, added a function in gtkprefs.c called prefs_checkbox(), which works
with the new prefs.
committer: Tailor Script <tailor@pidgin.im>
author | Christian Hammond <chipx86@chipx86.com> |
---|---|
date | Tue, 27 May 2003 20:10:21 +0000 |
parents | 4f72b611f0ee |
children | 187c740f2a4e |
line wrap: on
line source
/** * @file switchboard.c MSN switchboard functions * * gaim * * Copyright (C) 2003, Christian Hammond <chipx86@gnupdate.org> * * 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 */ #include "msn.h" #include "switchboard.h" #include "utils.h" static GHashTable *switchboard_commands = NULL; static GHashTable *switchboard_msg_types = NULL; /************************************************************************** * Utility functions **************************************************************************/ static gboolean __send_clientcaps(MsnSwitchBoard *swboard) { MsnMessage *msg; if (swboard->buddy_icon_xfer != NULL) return TRUE; msg = msn_message_new(); msn_message_set_content_type(msg, "text/x-clientcaps"); msn_message_set_charset(msg, NULL); msn_message_set_attr(msg, "User-Agent", NULL); msn_message_set_body(msg, MSN_CLIENTINFO); if (!msn_switchboard_send_msg(swboard, msg)) { msn_switchboard_destroy(swboard); msn_message_destroy(msg); return FALSE; } msn_message_destroy(msg); return TRUE; } /************************************************************************** * Catch-all commands **************************************************************************/ static gboolean __blank_cmd(MsnServConn *servconn, const char *command, const char **params, size_t param_count) { return TRUE; } static gboolean __unknown_cmd(MsnServConn *servconn, const char *command, const char **params, size_t param_count) { gaim_debug(GAIM_DEBUG_ERROR, "msg", "Handled switchboard message: %s\n", command); return FALSE; } /************************************************************************** * Switchboard Commands **************************************************************************/ static gboolean __ans_cmd(MsnServConn *servconn, const char *command, const char **params, size_t param_count) { struct gaim_connection *gc = servconn->session->account->gc; MsnSwitchBoard *swboard = servconn->data; if (swboard->chat != NULL) gaim_chat_add_user(GAIM_CHAT(swboard->chat), gc->username, NULL); return __send_clientcaps(swboard); } static gboolean __bye_cmd(MsnServConn *servconn, const char *command, const char **params, size_t param_count) { struct gaim_connection *gc = servconn->session->account->gc; MsnSwitchBoard *swboard = servconn->data; const char *user = params[0]; if (swboard->hidden) return TRUE; if (swboard->chat != NULL) gaim_chat_remove_user(GAIM_CHAT(swboard->chat), user, NULL); else { const char *username; struct gaim_conversation *conv; struct buddy *b; char buf[MSN_BUF_LEN]; if ((b = gaim_find_buddy(gc->account, user)) != NULL) username = gaim_get_buddy_alias(b); else username = user; if (param_count == 2 && atoi(params[1]) == 1) g_snprintf(buf, sizeof(buf), _("The conversation has become inactive " "and timed out.")); else g_snprintf(buf, sizeof(buf), _("%s has closed the conversation window."), username); if ((conv = gaim_find_conversation(user)) != NULL) gaim_conversation_write(conv, NULL, buf, -1, WFLAG_SYSTEM, time(NULL)); msn_switchboard_destroy(swboard); return FALSE; } return TRUE; } static gboolean __iro_cmd(MsnServConn *servconn, const char *command, const char **params, size_t param_count) { struct gaim_connection *gc = servconn->session->account->gc; MsnSwitchBoard *swboard = servconn->data; swboard->total_users = atoi(params[2]); if (swboard->total_users > 1) { if (swboard->chat == NULL) swboard->chat = serv_got_joined_chat(gc, ++swboard->chat_id, "MSN Chat"); gaim_chat_add_user(GAIM_CHAT(swboard->chat), params[3], NULL); } if (swboard->chat != NULL) gaim_chat_add_user(GAIM_CHAT(swboard->chat), gc->username, NULL); return TRUE; } static gboolean __joi_cmd(MsnServConn *servconn, const char *command, const char **params, size_t param_count) { struct gaim_connection *gc = servconn->session->account->gc; MsnSwitchBoard *swboard = servconn->data; const char *passport; passport = params[0]; if (swboard->total_users == 1) { swboard->chat = serv_got_joined_chat(gc, ++swboard->chat_id, "MSN Chat"); gaim_chat_add_user(GAIM_CHAT(swboard->chat), msn_user_get_passport(swboard->user), NULL); gaim_chat_add_user(GAIM_CHAT(swboard->chat), gc->username, NULL); msn_user_unref(swboard->user); } if (swboard->chat != NULL) gaim_chat_add_user(GAIM_CHAT(swboard->chat), passport, NULL); swboard->total_users++; while (servconn->txqueue) { char *buf = servconn->txqueue->data; servconn->txqueue = g_slist_remove(servconn->txqueue, buf); if (msn_servconn_write(swboard->servconn, buf, strlen(buf)) < 0) { msn_switchboard_destroy(swboard); return FALSE; } } return __send_clientcaps(swboard); } static gboolean __msg_cmd(MsnServConn *servconn, const char *command, const char **params, size_t param_count) { gaim_debug(GAIM_DEBUG_INFO, "msn", "Found message. Parsing.\n"); servconn->parsing_msg = TRUE; servconn->msg_passport = g_strdup(params[0]); servconn->msg_friendly = g_strdup(params[1]); servconn->msg_len = atoi(params[2]); return TRUE; } static gboolean __nak_cmd(MsnServConn *servconn, const char *command, const char **params, size_t param_count) { /* * TODO: Investigate this, as it seems to occur frequently with * the old prpl. */ gaim_notify_error(servconn->session->account->gc, NULL, _("An MSN message may not have been received."), NULL); return TRUE; } static gboolean __out_cmd(MsnServConn *servconn, const char *command, const char **params, size_t param_count) { struct gaim_connection *gc = servconn->session->account->gc; MsnSwitchBoard *swboard = servconn->data; if (swboard->chat != NULL) serv_got_chat_left(gc, gaim_chat_get_id(GAIM_CHAT(swboard->chat))); msn_switchboard_destroy(swboard); return FALSE; } static gboolean __usr_cmd(MsnServConn *servconn, const char *command, const char **params, size_t param_count) { MsnSwitchBoard *swboard = servconn->data; if (!msn_switchboard_send_command(swboard, "CAL", msn_user_get_passport(swboard->user))) { msn_switchboard_destroy(swboard); return FALSE; } return TRUE; } /************************************************************************** * Message Types **************************************************************************/ static gboolean __plain_msg(MsnServConn *servconn, MsnMessage *msg) { struct gaim_connection *gc = servconn->session->account->gc; MsnSwitchBoard *swboard = servconn->data; char *body; const char *value; char *format; int flags = 0; body = g_strdup(msn_message_get_body(msg)); gaim_debug(GAIM_DEBUG_INFO, "msn", "Checking User-Agent...\n"); if ((value = msn_message_get_attr(msg, "User-Agent")) != NULL) { gaim_debug(GAIM_DEBUG_MISC, "msn", "value = '%s'\n", value); if (!g_ascii_strncasecmp(value, "Gaim", 4)) { gaim_debug(GAIM_DEBUG_INFO, "msn", "Setting GAIMUSER flag.\n"); flags |= IM_FLAG_GAIMUSER; } } if ((value = msn_message_get_attr(msg, "X-MMS-IM-Format")) != NULL) { format = msn_parse_format(value); body = g_strdup_printf("%s%s", format, body); } if (swboard->chat != NULL) serv_got_chat_in(gc, gaim_chat_get_id(GAIM_CHAT(swboard->chat)), servconn->msg_passport, flags, body, time(NULL)); else serv_got_im(gc, servconn->msg_passport, body, flags, time(NULL), -1); g_free(body); return TRUE; } static gboolean __control_msg(MsnServConn *servconn, MsnMessage *msg) { struct gaim_connection *gc = servconn->session->account->gc; MsnSwitchBoard *swboard = servconn->data; const char *value; if (swboard->chat == NULL && (value = msn_message_get_attr(msg, "TypingUser")) != NULL) { serv_got_typing(gc, servconn->msg_passport, MSN_TYPING_RECV_TIMEOUT, TYPING); } return TRUE; } static gboolean __clientcaps_msg(MsnServConn *servconn, MsnMessage *msg) { MsnSession *session = servconn->session; MsnSwitchBoard *swboard = servconn->data; MsnUser *user; GHashTable *clientcaps; const char *value; user = msn_user_new(session, servconn->msg_passport, NULL); clientcaps = msn_message_get_hashtable_from_body(msg); if ((value = g_hash_table_lookup(clientcaps, "Buddy-Icons")) != NULL) msn_buddy_icon_invite(swboard); return TRUE; } /************************************************************************** * Connect stuff **************************************************************************/ static gboolean __connect_cb(gpointer data, gint source, GaimInputCondition cond) { MsnServConn *servconn = data; MsnSwitchBoard *swboard = servconn->data; char outparams[MSN_BUF_LEN]; if (servconn->fd != source) servconn->fd = source; swboard->in_use = TRUE; gaim_debug(GAIM_DEBUG_INFO, "msn", "Connecting to switchboard...\n"); if (msn_switchboard_is_invited(swboard)) { g_snprintf(outparams, sizeof(outparams), "%s %s %s", servconn->session->account->gc->username, swboard->auth_key, swboard->session_id); if (!msn_switchboard_send_command(swboard, "ANS", outparams)) { msn_switchboard_destroy(swboard); return FALSE; } } else { g_snprintf(outparams, sizeof(outparams), "%s %s", servconn->session->account->gc->username, swboard->auth_key); if (!msn_switchboard_send_command(swboard, "USR", outparams)) { msn_switchboard_destroy(swboard); return FALSE; } } return TRUE; } static void __failed_read_cb(gpointer data, gint source, GaimInputCondition cond) { MsnServConn *servconn = data; msn_switchboard_destroy(servconn->data); } MsnSwitchBoard * msn_switchboard_new(MsnSession *session) { MsnSwitchBoard *swboard; MsnServConn *servconn; g_return_val_if_fail(session != NULL, NULL); swboard = g_new0(MsnSwitchBoard, 1); swboard->servconn = servconn = msn_servconn_new(session); msn_servconn_set_connect_cb(servconn, __connect_cb); msn_servconn_set_failed_read_cb(servconn, __failed_read_cb); servconn->data = swboard; session->switches = g_list_append(session->switches, swboard); if (switchboard_commands == NULL) { /* Register the command callbacks. */ msn_servconn_register_command(servconn, "ACK", __blank_cmd); msn_servconn_register_command(servconn, "ANS", __ans_cmd); msn_servconn_register_command(servconn, "BYE", __bye_cmd); msn_servconn_register_command(servconn, "CAL", __blank_cmd); msn_servconn_register_command(servconn, "IRO", __iro_cmd); msn_servconn_register_command(servconn, "JOI", __joi_cmd); msn_servconn_register_command(servconn, "MSG", __msg_cmd); msn_servconn_register_command(servconn, "NAK", __nak_cmd); msn_servconn_register_command(servconn, "NLN", __blank_cmd); msn_servconn_register_command(servconn, "OUT", __out_cmd); msn_servconn_register_command(servconn, "USR", __usr_cmd); msn_servconn_register_command(servconn, "_unknown_", __unknown_cmd); /* Register the message type callbacks. */ msn_servconn_register_msg_type(servconn, "text/plain", __plain_msg); msn_servconn_register_msg_type(servconn, "text/x-msmsgscontrol", __control_msg); msn_servconn_register_msg_type(servconn, "text/x-clientcaps", __clientcaps_msg); msn_servconn_register_msg_type(servconn, "text/x-clientinfo", __clientcaps_msg); msn_servconn_register_msg_type(servconn, "application/x-buddyicon", msn_buddy_icon_msg); /* Save these for future use. */ switchboard_commands = servconn->commands; switchboard_msg_types = servconn->msg_types; } else { g_hash_table_destroy(servconn->commands); g_hash_table_destroy(servconn->msg_types); servconn->commands = switchboard_commands; servconn->msg_types = switchboard_msg_types; } return swboard; } void msn_switchboard_destroy(MsnSwitchBoard *swboard) { MsnSession *session; g_return_if_fail(swboard != NULL); session = swboard->servconn->session; if (swboard->servconn->connected) msn_switchboard_disconnect(swboard); if (swboard->user != NULL) msn_user_unref(swboard->user); if (swboard->auth_key != NULL) g_free(swboard->auth_key); if (swboard->session_id != NULL) g_free(swboard->session_id); session->switches = g_list_remove(session->switches, swboard); msn_servconn_destroy(swboard->servconn); g_free(swboard); } void msn_switchboard_set_user(MsnSwitchBoard *swboard, MsnUser *user) { g_return_if_fail(swboard != NULL); swboard->user = user; msn_user_ref(user); } MsnUser * msn_switchboard_get_user(const MsnSwitchBoard *swboard) { g_return_val_if_fail(swboard != NULL, NULL); return swboard->user; } void msn_switchboard_set_auth_key(MsnSwitchBoard *swboard, const char *key) { g_return_if_fail(swboard != NULL); g_return_if_fail(key != NULL); swboard->auth_key = g_strdup(key); } const char * msn_switchboard_get_auth_key(const MsnSwitchBoard *swboard) { g_return_val_if_fail(swboard != NULL, NULL); return swboard->auth_key; } void msn_switchboard_set_session_id(MsnSwitchBoard *swboard, const char *id) { g_return_if_fail(swboard != NULL); g_return_if_fail(id != NULL); if (swboard->session_id != NULL) g_free(swboard->session_id); swboard->session_id = g_strdup(id); } const char * msn_switchboard_get_session_id(const MsnSwitchBoard *swboard) { g_return_val_if_fail(swboard != NULL, NULL); return swboard->session_id; } void msn_switchboard_set_invited(MsnSwitchBoard *swboard, gboolean invited) { g_return_if_fail(swboard != NULL); swboard->invited = invited; } gboolean msn_switchboard_is_invited(const MsnSwitchBoard *swboard) { g_return_val_if_fail(swboard != NULL, FALSE); return swboard->invited; } gboolean msn_switchboard_connect(MsnSwitchBoard *swboard, const char *server, int port) { g_return_val_if_fail(swboard != NULL, FALSE); msn_servconn_set_server(swboard->servconn, server, port); if (msn_servconn_connect(swboard->servconn)) swboard->in_use = TRUE; return swboard->in_use; } void msn_switchboard_disconnect(MsnSwitchBoard *swboard) { g_return_if_fail(swboard != NULL); g_return_if_fail(swboard->servconn->connected); msn_servconn_disconnect(swboard->servconn); swboard->in_use = FALSE; } gboolean msn_switchboard_send_msg(MsnSwitchBoard *swboard, MsnMessage *msg) { char *buf; int ret; g_return_val_if_fail(swboard != NULL, FALSE); g_return_val_if_fail(msg != NULL, FALSE); msn_message_set_transaction_id(msg, ++swboard->trId); buf = msn_message_build_string(msg); if (swboard->servconn->txqueue != NULL || !swboard->in_use) { gaim_debug(GAIM_DEBUG_INFO, "msn", "Appending message to queue.\n"); swboard->servconn->txqueue = g_slist_append(swboard->servconn->txqueue, buf); return TRUE; } ret = msn_servconn_write(swboard->servconn, buf, strlen(buf)); g_free(buf); return (ret > 0); } gboolean msn_switchboard_send_command(MsnSwitchBoard *swboard, const char *command, const char *params) { char buf[MSN_BUF_LEN]; g_return_val_if_fail(swboard != NULL, FALSE); g_return_val_if_fail(command != NULL, FALSE); if (params == NULL) g_snprintf(buf, sizeof(buf), "%s %u\r\n", command, ++swboard->trId); else g_snprintf(buf, sizeof(buf), "%s %u %s\r\n", command, ++swboard->trId, params); return (msn_servconn_write(swboard->servconn, buf, strlen(buf)) > 0); }