コード例 #1
0
ファイル: msnslp.c プロジェクト: BackupTheBerlios/irssi-icq
void
msn_slp_session_send_msg(MsnSlpSession *slpsession, MsnMessage *msg)
{
	g_return_if_fail(slpsession != NULL);
	g_return_if_fail(msg != NULL);
	g_return_if_fail(msg->msnslp_message);
	g_return_if_fail(slpsession->outgoing_msg == NULL);

	msg->msnslp_header.session_id = slpsession->session_id;

	slpsession->outgoing_msg = msn_message_ref(msg);

	if (slpsession->base_id == 0)
	{
		slpsession->base_id = rand() % 0x0FFFFFF0 + 4;
		slpsession->prev_msg_id = slpsession->base_id;
	}
	else if (slpsession->offset == 0)
		slpsession->prev_msg_id = ++slpsession->base_id;

	msg->msnslp_header.id = slpsession->prev_msg_id;
//	msg->msnslp_header.ack_session_id = rand() % 0xFFFFFF00;
	msg->msnslp_header.ack_session_id = 0x1407C7DE;

	msn_message_set_charset(msg, NULL);

	if (msg->msnslp_header.session_id != 0)
		msg->msnslp_footer.app_id = 1;

	if (msg->bin_content)
	{
		const void *temp;

		temp = msn_message_get_bin_data(msg, &slpsession->orig_len);

		slpsession->orig_body = g_memdup(temp, slpsession->orig_len);
	}
	else
	{
		slpsession->orig_body = g_strdup(msn_message_get_body(msg));
		slpsession->orig_len  = strlen(slpsession->orig_body);
	}

	msg->msnslp_header.total_size_1 = slpsession->orig_len;

	send_msg_part(slpsession, msg);
}
コード例 #2
0
ファイル: msg.c プロジェクト: bf4/pidgin-mac
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 "/" DISPLAY_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;
}
コード例 #3
0
ファイル: msg.c プロジェクト: Distrotech/pidgin
MsnMessage *
msn_message_new_plain(const char *message)
{
	MsnMessage *msg;
	char *message_cr;

	msg = msn_message_new(MSN_MSG_TEXT);
	msg->retries = 1;
	msn_message_set_header(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_header(msg, "X-MMS-IM-Format",
						 "FN=Segoe%20UI; EF=; CO=0; CS=1;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;
}
コード例 #4
0
ファイル: msg.c プロジェクト: allanfreitas/msn-pecan
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", "msn-pecan/" 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");

#ifdef HAVE_LIBPURPLE
    message_cr = purple_str_add_cr(message);
    msn_message_set_bin_data(msg, message_cr, strlen(message_cr));
#endif /* HAVE_LIBPURPLE */
    g_free(message_cr);

    return msg;
}
コード例 #5
0
ファイル: msg.c プロジェクト: Distrotech/pidgin
void
msn_message_parse_payload(MsnMessage *msg,
						  const char *payload, size_t payload_len,
						  const char *line_dem,const char *body_dem)
{
	char *tmp_base, *tmp;
	const char *content_type;
	char *end;
	char **elems, **cur, **tokens;

	g_return_if_fail(payload != NULL);
	tmp_base = tmp = g_malloc(payload_len + 1);
	memcpy(tmp_base, payload, payload_len);
	tmp_base[payload_len] = '\0';

	/* Find the end of the headers */
	end = strstr(tmp, body_dem);
	/* 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();
	}

	/* NUL-terminate the end of the headers - it'll get skipped over below */
	*end = '\0';

	/* Split the headers and parse each one */
	elems = g_strsplit(tmp, line_dem, 0);
	for (cur = elems; *cur != NULL; cur++)
	{
		const char *key, *value;

		/* If this line starts with whitespace, it's been folded from the
		   previous line and won't have ':'. */
		if ((**cur == ' ') || (**cur == '\t')) {
			tokens = g_strsplit(g_strchug(*cur), "=\"", 2);
			key = tokens[0];
			value = tokens[1];

			/* The only one I care about is 'boundary' (which is folded from
			   the key 'Content-Type'), so only process that. */
			if (!strcmp(key, "boundary") && value) {
				char *end = strchr(value, '\"');
				if (end) {
					*end = '\0';
					msn_message_set_header(msg, key, value);
				}
			}

			g_strfreev(tokens);
			continue;
		}

		tokens = g_strsplit(*cur, ": ", 2);

		key = tokens[0];
		value = tokens[1];

		if (!strcmp(key, "MIME-Version"))
		{
			/* Ignore MIME-Version header */
		}
		else if (!strcmp(key, "Content-Type"))
		{
			char *charset, *c;

			if (value && (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_header(msg, key, value);
		}

		g_strfreev(tokens);
	}
	g_strfreev(elems);

	/* Proceed to the end of the "\r\n\r\n" */
	tmp = end + strlen(body_dem);

	/* Now we *should* be at the body. */
	content_type = msn_message_get_content_type(msg);

	if (payload_len - (tmp - tmp_base) > 0) {
		msg->body_len = payload_len - (tmp - tmp_base);
		g_free(msg->body);
		msg->body = g_malloc(msg->body_len + 1);
		memcpy(msg->body, tmp, msg->body_len);
		msg->body[msg->body_len] = '\0';
	}

	if (msg->body && content_type && purple_str_has_prefix(content_type, "text/")) {
		char *body = NULL;

		if (msg->charset == NULL || g_str_equal(msg->charset, "UTF-8")) {
			/* Charset is UTF-8 */
			if (!g_utf8_validate(msg->body, msg->body_len, NULL)) {
				purple_debug_warning("msn", "Message contains invalid "
						"UTF-8. Attempting to salvage.\n");
				body = purple_utf8_salvage(msg->body);
				payload_len = strlen(body);
			}
		} else {
			/* Charset is something other than UTF-8 */
			GError *err = NULL;
			body = g_convert(msg->body, msg->body_len, "UTF-8",
					msg->charset, NULL, &payload_len, &err);
			if (!body || err) {
				purple_debug_warning("msn", "Unable to convert message from "
						"%s to UTF-8: %s\n", msg->charset,
						err ? err->message : "Unknown error");
				if (err)
					g_error_free(err);

				/* Fallback to ISO-8859-1 */
				g_free(body);
				body = g_convert(msg->body, msg->body_len, "UTF-8",
						"ISO-8859-1", NULL, &payload_len, NULL);
				if (!body) {
					g_free(msg->body);
					msg->body = NULL;
					msg->body_len = 0;
				}
			}
		}

		if (body) {
			g_free(msg->body);
			msg->body = body;
			msg->body_len = payload_len;
			msn_message_set_charset(msg, "UTF-8");
		}
	}

	g_free(tmp_base);
}
コード例 #6
0
ファイル: msg.c プロジェクト: Distrotech/pidgin
void
msn_invite_msg(MsnCmdProc *cmdproc, MsnMessage *msg)
{
	GHashTable *body;
	const gchar *command;
	const gchar *cookie;
	gboolean accepted = FALSE;

	g_return_if_fail(cmdproc != NULL);
	g_return_if_fail(msg != NULL);

	body = msn_message_get_hashtable_from_body(msg);

	if (body == NULL) {
		purple_debug_warning("msn",
				"Unable to parse invite msg body.\n");
		return;
	}

	/*
	 * GUID is NOT always present but Invitation-Command and Invitation-Cookie
	 * are mandatory.
	 */
	command = g_hash_table_lookup(body, "Invitation-Command");
	cookie = g_hash_table_lookup(body, "Invitation-Cookie");

	if (command == NULL || cookie == NULL) {
		purple_debug_warning("msn",
			"Invalid invitation message: either Invitation-Command "
			"or Invitation-Cookie is missing or invalid.\n"
		);
		return;

	} else if (!strcmp(command, "INVITE")) {
		const gchar	*guid = g_hash_table_lookup(body, "Application-GUID");

		if (guid == NULL) {
			purple_debug_warning("msn",
			                     "Invite msg missing Application-GUID.\n");

			accepted = TRUE;

		} else if (!strcmp(guid, MSN_FT_GUID)) {

		} else if (!strcmp(guid, "{02D3C01F-BF30-4825-A83A-DE7AF41648AA}")) {
			purple_debug_info("msn", "Computer call\n");

			if (cmdproc->session) {
				PurpleIMConversation *im = NULL;
				gchar *from = msg->remote_user;
				gchar *buf = NULL;

				if (from)
					im = purple_conversations_find_im_with_account(
							from, cmdproc->session->account);
				if (im)
					buf = g_strdup_printf(
							_("%s sent you a voice chat "
							"invite, which is not yet "
							"supported."), from);
				if (buf) {
					purple_conversation_write(PURPLE_CONVERSATION(im), NULL, buf,
							PURPLE_MESSAGE_SYSTEM |
							PURPLE_MESSAGE_NOTIFY,
							time(NULL));
					g_free(buf);
				}
			}
		} else {
			const gchar *application = g_hash_table_lookup(body, "Application-Name");
			purple_debug_warning("msn", "Unhandled invite msg with GUID %s: %s.\n",
			                     guid, application ? application : "(null)");
		}

		if (!accepted) {
			MsnSwitchBoard *swboard = cmdproc->data;
			char *text;
			MsnMessage *cancel;

			cancel = msn_message_new(MSN_MSG_TEXT);
			msn_message_set_content_type(cancel, "text/x-msmsgsinvite");
			msn_message_set_charset(cancel, "UTF-8");
			msn_message_set_flag(cancel, 'U');

			text = g_strdup_printf("Invitation-Command: CANCEL\r\n"
			                       "Invitation-Cookie: %s\r\n"
			                       "Cancel-Code: REJECT_NOT_INSTALLED\r\n",
			                       cookie);
			msn_message_set_bin_data(cancel, text, strlen(text));
			g_free(text);

			msn_switchboard_send_msg(swboard, cancel, TRUE);
			msn_message_unref(cancel);
		}

	} else if (!strcmp(command, "CANCEL")) {
		const gchar *code = g_hash_table_lookup(body, "Cancel-Code");
		purple_debug_info("msn", "MSMSGS invitation cancelled: %s.\n",
		                  code ? code : "no reason given");

	} else {
		/*
		 * Some other already established invitation session.
		 * Can be retrieved by Invitation-Cookie.
		 */
	}

	g_hash_table_destroy(body);
}
コード例 #7
0
ファイル: msg.c プロジェクト: bf4/pidgin-mac
void
msn_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);
}