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

📄 msg.c

📁 Linux下的多协议即时通讯程序源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/** * @file msg.c Message 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 "msg.h"MsnMessage *msn_message_new(MsnMsgType type){	MsnMessage *msg;	msg = g_new0(MsnMessage, 1);	msg->type = type;#ifdef MSN_DEBUG_MSG	purple_debug_info("msn", "message new (%p)(%d)\n", msg, type);#endif	msg->attr_table = g_hash_table_new_full(g_str_hash, g_str_equal,											g_free, g_free);	msn_message_ref(msg);	return msg;}voidmsn_message_destroy(MsnMessage *msg){	g_return_if_fail(msg != NULL);	if (msg->ref_count > 0)	{		msn_message_unref(msg);		return;	}#ifdef MSN_DEBUG_MSG	purple_debug_info("msn", "message destroy (%p)\n", msg);#endif	if (msg->remote_user != NULL)		g_free(msg->remote_user);	if (msg->body != NULL)		g_free(msg->body);	if (msg->content_type != NULL)		g_free(msg->content_type);	if (msg->charset != NULL)		g_free(msg->charset);	g_hash_table_destroy(msg->attr_table);	g_list_free(msg->attr_list);	g_free(msg);}MsnMessage *msn_message_ref(MsnMessage *msg){	g_return_val_if_fail(msg != NULL, NULL);	msg->ref_count++;#ifdef MSN_DEBUG_MSG	purple_debug_info("msn", "message ref (%p)[%d]\n", msg, msg->ref_count);#endif	return msg;}MsnMessage *msn_message_unref(MsnMessage *msg){	g_return_val_if_fail(msg != NULL, NULL);	g_return_val_if_fail(msg->ref_count > 0, NULL);	msg->ref_count--;#ifdef MSN_DEBUG_MSG	purple_debug_info("msn", "message unref (%p)[%d]\n", msg, msg->ref_count);#endif	if (msg->ref_count == 0)	{		msn_message_destroy(msg);		return NULL;	}	return msg;}MsnMessage *msn_message_new_plain(const char *message){	MsnMessage *msg;	char *message_cr;	msg = msn_message_new(MSN_MSG_TEXT);	msn_message_set_attr(msg, "User-Agent", PACKAGE_NAME "/" VERSION);	msn_message_set_content_type(msg, "text/plain");	msn_message_set_charset(msg, "UTF-8");	msn_message_set_flag(msg, 'A');	msn_message_set_attr(msg, "X-MMS-IM-Format",						 "FN=MS%20Sans%20Serif; EF=; CO=0; PF=0");	message_cr = purple_str_add_cr(message);	msn_message_set_bin_data(msg, message_cr, strlen(message_cr));	g_free(message_cr);	return msg;}MsnMessage *msn_message_new_msnslp(void){	MsnMessage *msg;	msg = msn_message_new(MSN_MSG_SLP);	msn_message_set_attr(msg, "User-Agent", NULL);	msg->msnslp_message = TRUE;	msn_message_set_flag(msg, 'D');	msn_message_set_content_type(msg, "application/x-msnmsgrp2p");	return msg;}MsnMessage *msn_message_new_nudge(void){	MsnMessage *msg;	msg = msn_message_new(MSN_MSG_NUDGE);	msn_message_set_content_type(msg, "text/x-msnmsgr-datacast\r\n");	msn_message_set_flag(msg, 'N');	msn_message_set_attr(msg,"ID","1\r\n");	return msg;}voidmsn_message_parse_slp_body(MsnMessage *msg, const char *body, size_t len){	MsnSlpHeader header;	const char *tmp;	int body_len;	tmp = body;	if (len < sizeof(header)) {		g_return_if_reached();	}	/* Import the header. */	memcpy(&header, tmp, sizeof(header));	tmp += sizeof(header);	msg->msnslp_header.session_id = GUINT32_FROM_LE(header.session_id);	msg->msnslp_header.id         = GUINT32_FROM_LE(header.id);	msg->msnslp_header.offset     = GUINT64_FROM_LE(header.offset);	msg->msnslp_header.total_size = GUINT64_FROM_LE(header.total_size);	msg->msnslp_header.length     = GUINT32_FROM_LE(header.length);	msg->msnslp_header.flags      = GUINT32_FROM_LE(header.flags);	msg->msnslp_header.ack_id     = GUINT32_FROM_LE(header.ack_id);	msg->msnslp_header.ack_sub_id = GUINT32_FROM_LE(header.ack_sub_id);	msg->msnslp_header.ack_size   = GUINT64_FROM_LE(header.ack_size);	/* Import the body. */	body_len = len - (tmp - body);	/* msg->body_len = msg->msnslp_header.length; */	if (body_len > 0) {		msg->body_len = len - (tmp - body);		msg->body = g_malloc0(msg->body_len + 1);		memcpy(msg->body, tmp, msg->body_len);		tmp += body_len;	}}voidmsn_message_parse_payload(MsnMessage *msg,						  const char *payload, size_t payload_len){	char *tmp_base, *tmp;	const char *content_type;	char *end;	char **elems, **cur, **tokens;	g_return_if_fail(payload != NULL);	tmp_base = tmp = g_malloc0(payload_len + 1);	memcpy(tmp_base, payload, payload_len);	/* Parse the attributes. */	end = strstr(tmp, "\r\n\r\n");	/* TODO? some clients use \r delimiters instead of \r\n, the official client	 * doesn't send such messages, but does handle receiving them. We'll just	 * avoid crashing for now */	if (end == NULL) {		g_free(tmp_base);		g_return_if_reached();	}	*end = '\0';	elems = g_strsplit(tmp, "\r\n", 0);	for (cur = elems; *cur != NULL; cur++)	{		const char *key, *value;		tokens = g_strsplit(*cur, ": ", 2);		key = tokens[0];		value = tokens[1];		if (!strcmp(key, "MIME-Version"))		{			g_strfreev(tokens);			continue;		}		if (!strcmp(key, "Content-Type"))		{			char *charset, *c;			if ((c = strchr(value, ';')) != NULL)			{				if ((charset = strchr(c, '=')) != NULL)				{					charset++;					msn_message_set_charset(msg, charset);				}				*c = '\0';			}			msn_message_set_content_type(msg, value);		}		else		{			msn_message_set_attr(msg, key, value);		}		g_strfreev(tokens);	}	g_strfreev(elems);	/* Proceed to the end of the "\r\n\r\n" */	tmp = end + 4;	/* Now we *should* be at the body. */	content_type = msn_message_get_content_type(msg);	if (content_type != NULL &&		!strcmp(content_type, "application/x-msnmsgrp2p"))	{		MsnSlpHeader header;		MsnSlpFooter footer;		int body_len;		if (payload_len - (tmp - tmp_base) < sizeof(header)) {			g_free(tmp_base);			g_return_if_reached();		}		msg->msnslp_message = TRUE;		/* Import the header. */		memcpy(&header, tmp, sizeof(header));		tmp += sizeof(header);		msg->msnslp_header.session_id = GUINT32_FROM_LE(header.session_id);		msg->msnslp_header.id         = GUINT32_FROM_LE(header.id);		msg->msnslp_header.offset     = GUINT64_FROM_LE(header.offset);		msg->msnslp_header.total_size = GUINT64_FROM_LE(header.total_size);		msg->msnslp_header.length     = GUINT32_FROM_LE(header.length);		msg->msnslp_header.flags      = GUINT32_FROM_LE(header.flags);		msg->msnslp_header.ack_id     = GUINT32_FROM_LE(header.ack_id);		msg->msnslp_header.ack_sub_id = GUINT32_FROM_LE(header.ack_sub_id);		msg->msnslp_header.ack_size   = GUINT64_FROM_LE(header.ack_size);		body_len = payload_len - (tmp - tmp_base) - sizeof(footer);		/* Import the body. */		if (body_len > 0) {			msg->body_len = body_len;			msg->body = g_malloc0(msg->body_len + 1);			memcpy(msg->body, tmp, msg->body_len);			tmp += body_len;		}		/* Import the footer. */		if (body_len >= 0) {			memcpy(&footer, tmp, sizeof(footer));			tmp += sizeof(footer);			msg->msnslp_footer.value = GUINT32_FROM_BE(footer.value);		}	}	else	{		if (payload_len - (tmp - tmp_base) > 0) {			msg->body_len = payload_len - (tmp - tmp_base);			msg->body = g_malloc0(msg->body_len + 1);			memcpy(msg->body, tmp, msg->body_len);		}	}	g_free(tmp_base);}MsnMessage *msn_message_new_from_cmd(MsnSession *session, MsnCommand *cmd){	MsnMessage *msg;	g_return_val_if_fail(cmd != NULL, NULL);	msg = msn_message_new(MSN_MSG_UNKNOWN);	msg->remote_user = g_strdup(cmd->params[0]);	/* msg->size = atoi(cmd->params[2]); */	msg->cmd = cmd;	return msg;}char *msn_message_gen_slp_body(MsnMessage *msg, size_t *ret_size){	MsnSlpHeader header;	char *tmp, *base;	const void *body;	size_t len, body_len;	g_return_val_if_fail(msg != NULL, NULL);	len = MSN_BUF_LEN;	base = tmp = g_malloc(len + 1);	body = msn_message_get_bin_data(msg, &body_len);	header.session_id = GUINT32_TO_LE(msg->msnslp_header.session_id);	header.id         = GUINT32_TO_LE(msg->msnslp_header.id);	header.offset     = GUINT64_TO_LE(msg->msnslp_header.offset);	header.total_size = GUINT64_TO_LE(msg->msnslp_header.total_size);	header.length     = GUINT32_TO_LE(msg->msnslp_header.length);	header.flags      = GUINT32_TO_LE(msg->msnslp_header.flags);	header.ack_id     = GUINT32_TO_LE(msg->msnslp_header.ack_id);	header.ack_sub_id = GUINT32_TO_LE(msg->msnslp_header.ack_sub_id);	header.ack_size   = GUINT64_TO_LE(msg->msnslp_header.ack_size);	memcpy(tmp, &header, 48);	tmp += 48;	if (body != NULL)	{		memcpy(tmp, body, body_len);		tmp += body_len;	}	if (ret_size != NULL)		*ret_size = tmp - base;	return base;

⌨️ 快捷键说明

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