⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 switchboard.c

📁 Linux下的多协议即时通讯程序源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/** * @file switchboard.c MSN switchboard functions * * purple * * 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 * source distribution. * * 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 "prefs.h"#include "switchboard.h"#include "notification.h"#include "msn-utils.h"#include "error.h"static MsnTable *cbs_table;static void msg_error_helper(MsnCmdProc *cmdproc, MsnMessage *msg,							 MsnMsgErrorType error);/************************************************************************** * Main **************************************************************************/MsnSwitchBoard *msn_switchboard_new(MsnSession *session){	MsnSwitchBoard *swboard;	MsnServConn *servconn;	g_return_val_if_fail(session != NULL, NULL);	swboard = g_new0(MsnSwitchBoard, 1);	swboard->session = session;	swboard->servconn = servconn = msn_servconn_new(session, MSN_SERVCONN_SB);	swboard->cmdproc = servconn->cmdproc;	swboard->msg_queue = g_queue_new();	swboard->empty = TRUE;	swboard->cmdproc->data = swboard;	swboard->cmdproc->cbs_table = cbs_table;	session->switches = g_list_append(session->switches, swboard);	return swboard;}voidmsn_switchboard_destroy(MsnSwitchBoard *swboard){	MsnSession *session;	MsnMessage *msg;	GList *l;#ifdef MSN_DEBUG_SB	purple_debug_info("msn", "switchboard_destroy: swboard(%p)\n", swboard);#endif	g_return_if_fail(swboard != NULL);	if (swboard->destroying)		return;	swboard->destroying = TRUE;	/* If it linked us is because its looking for trouble */	while (swboard->slplinks != NULL)		msn_slplink_destroy(swboard->slplinks->data);	/* Destroy the message queue */	while ((msg = g_queue_pop_head(swboard->msg_queue)) != NULL)	{		if (swboard->error != MSN_SB_ERROR_NONE)		{			/* The messages could not be sent due to a switchboard error */			msg_error_helper(swboard->cmdproc, msg,							 MSN_MSG_ERROR_SB);		}		msn_message_unref(msg);	}	g_queue_free(swboard->msg_queue);	/* msg_error_helper will both remove the msg from ack_list and	   unref it, so we don't need to do either here */	while ((l = swboard->ack_list) != NULL)		msg_error_helper(swboard->cmdproc, l->data, MSN_MSG_ERROR_SB);	g_free(swboard->im_user);	g_free(swboard->auth_key);	g_free(swboard->session_id);	for (l = swboard->users; l != NULL; l = l->next)		g_free(l->data);	session = swboard->session;	session->switches = g_list_remove(session->switches, swboard);#if 0	/* This should never happen or we are in trouble. */	if (swboard->servconn != NULL)		msn_servconn_destroy(swboard->servconn);#endif	swboard->cmdproc->data = NULL;	msn_servconn_set_disconnect_cb(swboard->servconn, NULL);	msn_servconn_destroy(swboard->servconn);	g_free(swboard);}voidmsn_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(MsnSwitchBoard *swboard){	g_return_val_if_fail(swboard != NULL, NULL);	return swboard->auth_key;}voidmsn_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(MsnSwitchBoard *swboard){	g_return_val_if_fail(swboard != NULL, NULL);	return swboard->session_id;}voidmsn_switchboard_set_invited(MsnSwitchBoard *swboard, gboolean invited){	g_return_if_fail(swboard != NULL);	swboard->invited = invited;}gbooleanmsn_switchboard_is_invited(MsnSwitchBoard *swboard){	g_return_val_if_fail(swboard != NULL, FALSE);	return swboard->invited;}/************************************************************************** * Utility **************************************************************************/static voidsend_clientcaps(MsnSwitchBoard *swboard){	MsnMessage *msg;	msg = msn_message_new(MSN_MSG_CAPS);	msn_message_set_content_type(msg, "text/x-clientcaps");	msn_message_set_flag(msg, 'U');	msn_message_set_bin_data(msg, MSN_CLIENTINFO, strlen(MSN_CLIENTINFO));	msn_switchboard_send_msg(swboard, msg, TRUE);	msn_message_destroy(msg);}static voidmsn_switchboard_add_user(MsnSwitchBoard *swboard, const char *user){	MsnCmdProc *cmdproc;	PurpleAccount *account;	g_return_if_fail(swboard != NULL);	cmdproc = swboard->cmdproc;	account = cmdproc->session->account;	swboard->users = g_list_prepend(swboard->users, g_strdup(user));	swboard->current_users++;	swboard->empty = FALSE;#ifdef MSN_DEBUG_CHAT	purple_debug_info("msn", "user=[%s], total=%d\n", user,					swboard->current_users);#endif	if (!(swboard->flag & MSN_SB_FLAG_IM) && (swboard->conv != NULL))	{		/* This is a helper switchboard. */		purple_debug_error("msn", "switchboard_add_user: conv != NULL\n");		return;	}	if ((swboard->conv != NULL) &&		(purple_conversation_get_type(swboard->conv) == PURPLE_CONV_TYPE_CHAT))	{		purple_conv_chat_add_user(PURPLE_CONV_CHAT(swboard->conv), user, NULL,								PURPLE_CBFLAGS_NONE, TRUE);	}	else if (swboard->current_users > 1 || swboard->total_users > 1)	{		if (swboard->conv == NULL ||			purple_conversation_get_type(swboard->conv) != PURPLE_CONV_TYPE_CHAT)		{			GList *l;#ifdef MSN_DEBUG_CHAT			purple_debug_info("msn", "[chat] Switching to chat.\n");#endif#if 0			/* this is bad - it causes msn_switchboard_close to be called on the			 * switchboard we're in the middle of using :( */			if (swboard->conv != NULL)				purple_conversation_destroy(swboard->conv);#endif			swboard->chat_id = cmdproc->session->conv_seq++;			swboard->flag |= MSN_SB_FLAG_IM;			swboard->conv = serv_got_joined_chat(account->gc,												 swboard->chat_id,												 "MSN Chat");			for (l = swboard->users; l != NULL; l = l->next)			{				const char *tmp_user;				tmp_user = l->data;#ifdef MSN_DEBUG_CHAT				purple_debug_info("msn", "[chat] Adding [%s].\n", tmp_user);#endif				purple_conv_chat_add_user(PURPLE_CONV_CHAT(swboard->conv),										tmp_user, NULL, PURPLE_CBFLAGS_NONE, TRUE);			}#ifdef MSN_DEBUG_CHAT			purple_debug_info("msn", "[chat] We add ourselves.\n");#endif			purple_conv_chat_add_user(PURPLE_CONV_CHAT(swboard->conv),									purple_account_get_username(account),									NULL, PURPLE_CBFLAGS_NONE, TRUE);			g_free(swboard->im_user);			swboard->im_user = NULL;		}	}	else if (swboard->conv == NULL)	{		swboard->conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM,															user, account);	}	else	{		purple_debug_warning("msn", "switchboard_add_user: This should not happen!\n");	}}static PurpleConversation *msn_switchboard_get_conv(MsnSwitchBoard *swboard){	PurpleAccount *account;	g_return_val_if_fail(swboard != NULL, NULL);	if (swboard->conv != NULL)		return swboard->conv;	purple_debug_error("msn", "Switchboard with unassigned conversation\n");	account = swboard->session->account;	return (swboard->conv = purple_conversation_new(PURPLE_CONV_TYPE_IM,												  account, swboard->im_user));}static voidmsn_switchboard_report_user(MsnSwitchBoard *swboard, PurpleMessageFlags flags, const char *msg){	PurpleConversation *conv;	g_return_if_fail(swboard != NULL);	g_return_if_fail(msg != NULL);	if ((conv = msn_switchboard_get_conv(swboard)) != NULL)	{		purple_conversation_write(conv, NULL, msg, flags, time(NULL));	}}static voidswboard_error_helper(MsnSwitchBoard *swboard, int reason, const char *passport){	g_return_if_fail(swboard != NULL);	purple_debug_warning("msg", "Error: Unable to call the user %s for reason %i\n",					   passport ? passport : "(null)", reason);	/* TODO: if current_users > 0, this is probably a chat and an invite failed,	 * we should report that in the chat or something */	if (swboard->current_users == 0)	{		swboard->error = reason;		msn_switchboard_close(swboard);	}}static voidcal_error_helper(MsnTransaction *trans, int reason){	MsnSwitchBoard *swboard;	const char *passport;	char **params;	params = g_strsplit(trans->params, " ", 0);	passport = params[0];	swboard = trans->data;	purple_debug_warning("msn", "cal_error_helper: command %s failed for reason %i\n",trans->command,reason);	swboard_error_helper(swboard, reason, passport);	g_strfreev(params);}static voidmsg_error_helper(MsnCmdProc *cmdproc, MsnMessage *msg, MsnMsgErrorType error){	MsnSwitchBoard *swboard;	g_return_if_fail(cmdproc != NULL);	g_return_if_fail(msg     != NULL);	if ((error != MSN_MSG_ERROR_SB) && (msg->nak_cb != NULL))		msg->nak_cb(msg, msg->ack_data);	swboard = cmdproc->data;	/* This is not good, and should be fixed somewhere else. */	g_return_if_fail(swboard != NULL);	if (msg->type == MSN_MSG_TEXT)	{		const char *format, *str_reason;		char *body_str, *body_enc, *pre, *post;#if 0		if (swboard->conv == NULL)		{			if (msg->ack_ref)				msn_message_unref(msg);			return;		}#endif		if (error == MSN_MSG_ERROR_TIMEOUT)		{			str_reason = _("Message may have not been sent "						   "because a timeout occurred:");		}		else if (error == MSN_MSG_ERROR_SB)		{			switch (swboard->error)			{				case MSN_SB_ERROR_OFFLINE:					str_reason = _("Message could not be sent, "								   "not allowed while invisible:");					break;				case MSN_SB_ERROR_USER_OFFLINE:					str_reason = _("Message could not be sent "								   "because the user is offline:");					break;				case MSN_SB_ERROR_CONNECTION:					str_reason = _("Message could not be sent "								   "because a connection error occurred:");					break;				case MSN_SB_ERROR_TOO_FAST:					str_reason = _("Message could not be sent "								   "because we are sending too quickly:");					break;				case MSN_SB_ERROR_AUTHFAILED:					str_reason = _("Message could not be sent "								   "because we wer unable to establish a "								   "session with the server. This is "								   "likely a server problem, try again in "								   "a few minutes:");					break;				default:					str_reason = _("Message could not be sent "								   "because an error with "								   "the switchboard occurred:");					break;			}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -