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

📄 notification.c

📁 Linux下的多协议即时通讯程序源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/** * @file notification.c Notification server 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 "notification.h"#include "state.h"#include "error.h"#include "msn-utils.h"#include "page.h"#include "userlist.h"#include "sync.h"#include "slplink.h"static MsnTable *cbs_table;/************************************************************************** * Main **************************************************************************/static voiddestroy_cb(MsnServConn *servconn){	MsnNotification *notification;	notification = servconn->cmdproc->data;	g_return_if_fail(notification != NULL);	msn_notification_destroy(notification);}MsnNotification *msn_notification_new(MsnSession *session){	MsnNotification *notification;	MsnServConn *servconn;	g_return_val_if_fail(session != NULL, NULL);	notification = g_new0(MsnNotification, 1);	notification->session = session;	notification->servconn = servconn = msn_servconn_new(session, MSN_SERVCONN_NS);	msn_servconn_set_destroy_cb(servconn, destroy_cb);	notification->cmdproc = servconn->cmdproc;	notification->cmdproc->data = notification;	notification->cmdproc->cbs_table = cbs_table;	return notification;}voidmsn_notification_destroy(MsnNotification *notification){	notification->cmdproc->data = NULL;	msn_servconn_set_destroy_cb(notification->servconn, NULL);	msn_servconn_destroy(notification->servconn);	g_free(notification);}/************************************************************************** * Connect **************************************************************************/static voidconnect_cb(MsnServConn *servconn){	MsnCmdProc *cmdproc;	MsnSession *session;	PurpleAccount *account;	char **a, **c, *vers;	int i;	g_return_if_fail(servconn != NULL);	cmdproc = servconn->cmdproc;	session = servconn->session;	account = session->account;	/* Allocate an array for CVR0, NULL, and all the versions */	a = c = g_new0(char *, session->protocol_ver - 8 + 3);	for (i = session->protocol_ver; i >= 8; i--)		*c++ = g_strdup_printf("MSNP%d", i);	*c++ = g_strdup("CVR0");	vers = g_strjoinv(" ", a);	if (session->login_step == MSN_LOGIN_STEP_START)		msn_session_set_login_step(session, MSN_LOGIN_STEP_HANDSHAKE);	else		msn_session_set_login_step(session, MSN_LOGIN_STEP_HANDSHAKE2);	msn_cmdproc_send(cmdproc, "VER", "%s", vers);	g_strfreev(a);	g_free(vers);}gbooleanmsn_notification_connect(MsnNotification *notification, const char *host, int port){	MsnServConn *servconn;	g_return_val_if_fail(notification != NULL, FALSE);	servconn = notification->servconn;	msn_servconn_set_connect_cb(servconn, connect_cb);	notification->in_use = msn_servconn_connect(servconn, host, port);	return notification->in_use;}voidmsn_notification_disconnect(MsnNotification *notification){	g_return_if_fail(notification != NULL);	g_return_if_fail(notification->in_use);	msn_servconn_disconnect(notification->servconn);	notification->in_use = FALSE;}/************************************************************************** * Util **************************************************************************/static voidgroup_error_helper(MsnSession *session, const char *msg, int group_id, int error){	PurpleAccount *account;	PurpleConnection *gc;	char *reason = NULL;	char *title = NULL;	account = session->account;	gc = purple_account_get_connection(account);	if (error == 224)	{		if (group_id == 0)		{			return;		}		else		{			const char *group_name;			group_name =				msn_userlist_find_group_name(session->userlist,											 group_id);			reason = g_strdup_printf(_("%s is not a valid group."),									 group_name);		}	}	else	{		reason = g_strdup(_("Unknown error."));	}	title = g_strdup_printf(_("%s on %s (%s)"), msg,						  purple_account_get_username(account),						  purple_account_get_protocol_name(account));	purple_notify_error(gc, NULL, title, reason);	g_free(title);	g_free(reason);}/************************************************************************** * Login **************************************************************************/voidmsn_got_login_params(MsnSession *session, const char *login_params){	MsnCmdProc *cmdproc;	cmdproc = session->notification->cmdproc;	msn_session_set_login_step(session, MSN_LOGIN_STEP_AUTH_END);	msn_cmdproc_send(cmdproc, "USR", "TWN S %s", login_params);}static voidcvr_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd){	PurpleAccount *account;	account = cmdproc->session->account;	msn_cmdproc_send(cmdproc, "USR", "TWN I %s",					 purple_account_get_username(account));}static voidusr_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd){	MsnSession *session;	PurpleAccount *account;	PurpleConnection *gc;	session = cmdproc->session;	account = session->account;	gc = purple_account_get_connection(account);	if (!g_ascii_strcasecmp(cmd->params[1], "OK"))	{		/* OK */		const char *friendly = purple_url_decode(cmd->params[3]);		purple_connection_set_display_name(gc, friendly);		msn_session_set_login_step(session, MSN_LOGIN_STEP_SYN);		msn_cmdproc_send(cmdproc, "SYN", "%s", "0");	}	else if (!g_ascii_strcasecmp(cmd->params[1], "TWN"))	{		/* Passport authentication */		char **elems, **cur, **tokens;		session->nexus = msn_nexus_new(session);		/* Parse the challenge data. */		elems = g_strsplit(cmd->params[3], ",", 0);		for (cur = elems; *cur != NULL; cur++)		{				tokens = g_strsplit(*cur, "=", 2);				g_hash_table_insert(session->nexus->challenge_data, tokens[0], tokens[1]);				/* Don't free each of the tokens, only the array. */				g_free(tokens);		}		g_strfreev(elems);		msn_session_set_login_step(session, MSN_LOGIN_STEP_AUTH_START);		msn_nexus_connect(session->nexus);	}}static voidusr_error(MsnCmdProc *cmdproc, MsnTransaction *trans, int error){	MsnErrorType msnerr = 0;	switch (error)	{		case 500:		case 601:		case 910:		case 921:			msnerr = MSN_ERROR_SERV_UNAVAILABLE;			break;		case 911:			msnerr = MSN_ERROR_AUTH;			break;		default:			return;			break;	}	msn_session_set_error(cmdproc->session, msnerr, NULL);}static voidver_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd){	MsnSession *session;	PurpleAccount *account;	gboolean protocol_supported = FALSE;	char proto_str[8];	size_t i;	session = cmdproc->session;	account = session->account;	g_snprintf(proto_str, sizeof(proto_str), "MSNP%d", session->protocol_ver);	for (i = 1; i < cmd->param_count; i++)	{		if (!strcmp(cmd->params[i], proto_str))		{			protocol_supported = TRUE;			break;		}	}	if (!protocol_supported)	{		msn_session_set_error(session, MSN_ERROR_UNSUPPORTED_PROTOCOL,							  NULL);		return;	}	msn_cmdproc_send(cmdproc, "CVR",					 "0x0409 winnt 5.1 i386 MSNMSGR 6.0.0602 MSMSGS %s",					 purple_account_get_username(account));}/************************************************************************** * Log out **************************************************************************/static voidout_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd){	if (!g_ascii_strcasecmp(cmd->params[0], "OTH"))		msn_session_set_error(cmdproc->session, MSN_ERROR_SIGN_OTHER,							  NULL);	else if (!g_ascii_strcasecmp(cmd->params[0], "SSD"))		msn_session_set_error(cmdproc->session, MSN_ERROR_SERV_DOWN, NULL);}voidmsn_notification_close(MsnNotification *notification){	g_return_if_fail(notification != NULL);	if (!notification->in_use)		return;	msn_cmdproc_send_quick(notification->cmdproc, "OUT", NULL, NULL);	msn_notification_disconnect(notification);}/************************************************************************** * Messages **************************************************************************/static voidmsg_cmd_post(MsnCmdProc *cmdproc, MsnCommand *cmd, char *payload,			 size_t len){	MsnMessage *msg;	msg = msn_message_new_from_cmd(cmdproc->session, cmd);	msn_message_parse_payload(msg, payload, len);#ifdef MSN_DEBUG_NS	msn_message_show_readable(msg, "Notification", TRUE);#endif	msn_cmdproc_process_msg(cmdproc, msg);	msn_message_destroy(msg);}static voidmsg_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd){	/* NOTE: cmd is not always cmdproc->last_cmd, sometimes cmd is a queued	 * command and we are processing it */	if (cmd->payload == NULL)	{		cmdproc->last_cmd->payload_cb  = msg_cmd_post;		cmdproc->servconn->payload_len = atoi(cmd->params[2]);	}	else	{		g_return_if_fail(cmd->payload_cb != NULL);		cmd->payload_cb(cmdproc, cmd, cmd->payload, cmd->payload_len);	}}/************************************************************************** * Challenges **************************************************************************/static voidchl_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd){	MsnTransaction *trans;	char buf[33];	const char *challenge_resp;	PurpleCipher *cipher;	PurpleCipherContext *context;	guchar digest[16];	int i;	cipher = purple_ciphers_find_cipher("md5");	context = purple_cipher_context_new(cipher, NULL);	purple_cipher_context_append(context, (const guchar *)cmd->params[1],							   strlen(cmd->params[1]));	challenge_resp = "VT6PX?UQTM4WM%YR";	purple_cipher_context_append(context, (const guchar *)challenge_resp,							   strlen(challenge_resp));	purple_cipher_context_digest(context, sizeof(digest), digest, NULL);	purple_cipher_context_destroy(context);	for (i = 0; i < 16; i++)		g_snprintf(buf + (i*2), 3, "%02x", digest[i]);	trans = msn_transaction_new(cmdproc, "QRY", "%s 32", "PROD0038W!61ZTF9");	msn_transaction_set_payload(trans, buf, 32);	msn_cmdproc_send_trans(cmdproc, trans);}/************************************************************************** * Buddy Lists **************************************************************************/static voidadd_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd){	MsnSession *session;	MsnUser *user;	const char *list;	const char *passport;	const char *friendly;	MsnListId list_id;	int group_id;	list     = cmd->params[1];	passport = cmd->params[3];	friendly = purple_url_decode(cmd->params[4]);	session = cmdproc->session;	user = msn_userlist_find_user(session->userlist, passport);	if (user == NULL)	{		user = msn_user_new(session->userlist, passport, friendly);		msn_userlist_add_user(session->userlist, user);	}	else		msn_user_set_friendly_name(user, friendly);	list_id = msn_get_list_id(list);	if (cmd->param_count >= 6)		group_id = atoi(cmd->params[5]);	else		group_id = -1;	msn_got_add_user(session, user, list_id, group_id);	msn_user_update(user);}static voidadd_error(MsnCmdProc *cmdproc, MsnTransaction *trans, int error){	MsnSession *session;	PurpleAccount *account;	PurpleConnection *gc;	const char *list, *passport;	char *reason = NULL;	char *msg = NULL;	char **params;	session = cmdproc->session;

⌨️ 快捷键说明

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