示例#1
0
/*
 * Subtype 0x0006
 *
 * We could probably include this in the normal ICBM parsing 
 * code as channel 0x0003, however, since only the start
 * would be the same, we might as well do it here.
 *
 * General outline of this SNAC:
 *   snac
 *   cookie
 *   channel id
 *   tlvlist
 *     unknown
 *     source user info
 *       name
 *       evility
 *       userinfo tlvs
 *         online time
 *         etc
 *     message metatlv
 *       message tlv
 *         message string
 *       possibly others
 *  
 */
static int incomingim_ch3(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
{
	int ret = 0, i;
	aim_rxcallback_t userfunc;	
	aim_userinfo_t userinfo;
	fu8_t cookie[8];
	fu16_t channel;
	aim_tlvlist_t *otl;
	char *msg = NULL;
	int len = 0;
	char *encoding = NULL, *language = NULL;
	aim_msgcookie_t *ck;

	memset(&userinfo, 0, sizeof(aim_userinfo_t));

	/*
	 * Read ICBM Cookie.
	 */
	for (i = 0; i < 8; i++)
		cookie[i] = aimbs_get8(bs);

	if ((ck = aim_uncachecookie(sess, cookie, AIM_COOKIETYPE_CHAT))) {
		free(ck->data);
		free(ck);
	}

	/*
	 * Channel ID
	 *
	 * Channel 0x0003 is used for chat messages.
	 *
	 */
	channel = aimbs_get16(bs);

	if (channel != 0x0003) {
		faimdprintf(sess, 0, "faim: chat_incoming: unknown channel! (0x%04x)\n", channel);
		return 0;
	}

	/*
	 * Start parsing TLVs right away. 
	 */
	otl = aim_tlvlist_read(bs);

	/*
	 * Type 0x0003: Source User Information
	 */
	if (aim_tlv_gettlv(otl, 0x0003, 1)) {
		aim_tlv_t *userinfotlv;
		aim_bstream_t tbs;

		userinfotlv = aim_tlv_gettlv(otl, 0x0003, 1);

		aim_bstream_init(&tbs, userinfotlv->value, userinfotlv->length);
		aim_info_extract(sess, &tbs, &userinfo);
	}

	/*
	 * Type 0x0001: If present, it means it was a message to the 
	 * room (as opposed to a whisper).
	 */
	if (aim_tlv_gettlv(otl, 0x0001, 1))
		;

	/*
	 * Type 0x0005: Message Block.  Conains more TLVs.
	 */
	if (aim_tlv_gettlv(otl, 0x0005, 1)) {
		aim_tlvlist_t *itl;
		aim_tlv_t *msgblock;
		aim_bstream_t tbs;

		msgblock = aim_tlv_gettlv(otl, 0x0005, 1);
		aim_bstream_init(&tbs, msgblock->value, msgblock->length);
		itl = aim_tlvlist_read(&tbs);

		/* 
		 * Type 0x0001: Message.
		 */	
		if (aim_tlv_gettlv(itl, 0x0001, 1)) {
			msg = aim_tlv_getstr(itl, 0x0001, 1);
			len = aim_tlv_gettlv(itl, 0x0001, 1)->length;
		}

		/*
		 * Type 0x0002: Encoding.
		 */	
		if (aim_tlv_gettlv(itl, 0x0002, 1))
			encoding = aim_tlv_getstr(itl, 0x0002, 1);

		/*
		 * Type 0x0003: Language.
		 */	
		if (aim_tlv_gettlv(itl, 0x0003, 1))
			language = aim_tlv_getstr(itl, 0x0003, 1);

		aim_tlvlist_free(&itl); 
	}

	if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))
		ret = userfunc(sess, rx, &userinfo, len, msg, encoding, language);

	aim_info_free(&userinfo);
	free(msg);
	aim_tlvlist_free(&otl);

	return ret;
}
示例#2
0
文件: chat.c 项目: Doap/transports
/*
 * We could probably include this in the normal ICBM parsing 
 * code as channel 0x0003, however, since only the start
 * would be the same, we might as well do it here.
 *
 * General outline of this SNAC:
 *   snac
 *   cookie
 *   channel id
 *   tlvlist
 *     unknown
 *     source user info
 *       name
 *       evility
 *       userinfo tlvs
 *         online time
 *         etc
 *     message metatlv
 *       message tlv
 *         message string
 *       possibly others
 *  
 */
static int incomingmsg(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
{
	aim_userinfo_t userinfo;
	aim_rxcallback_t userfunc;	
	int ret = 0;
	fu8_t *cookie;
	fu16_t channel;
	aim_tlvlist_t *otl;
	char *msg = NULL;
	aim_msgcookie_t *ck;

	memset(&userinfo, 0, sizeof(aim_userinfo_t));

	/*
	 * ICBM Cookie.  Uncache it.
	 */
	cookie = aimbs_getraw(bs, 8);

	if ((ck = aim_uncachecookie(sess, cookie, AIM_COOKIETYPE_CHAT))) {
		free(ck->data);
		free(ck);
	}

	/*
	 * Channel ID
	 *
	 * Channels 1 and 2 are implemented in the normal ICBM
	 * parser.
	 *
	 * We only do channel 3 here.
	 *
	 */
	channel = aimbs_get16(bs);

	if (channel != 0x0003) {
		faimdprintf(sess, 0, "faim: chat_incoming: unknown channel! (0x%04x)\n", channel);
		return 0;
	}

	/*
	 * Start parsing TLVs right away. 
	 */
	otl = aim_readtlvchain(bs);

	/*
	 * Type 0x0003: Source User Information
	 */
	if (aim_gettlv(otl, 0x0003, 1)) {
		aim_tlv_t *userinfotlv;
		aim_bstream_t tbs;

		userinfotlv = aim_gettlv(otl, 0x0003, 1);

		aim_bstream_init(&tbs, userinfotlv->value, userinfotlv->length);
		aim_extractuserinfo(sess, &tbs, &userinfo);
	}

	/*
	 * Type 0x0001: If present, it means it was a message to the 
	 * room (as opposed to a whisper).
	 */
	if (aim_gettlv(otl, 0x0001, 1))
		;

	/*
	 * Type 0x0005: Message Block.  Conains more TLVs.
	 */
	if (aim_gettlv(otl, 0x0005, 1)) {
		aim_tlvlist_t *itl;
		aim_tlv_t *msgblock;
		aim_bstream_t tbs;

		msgblock = aim_gettlv(otl, 0x0005, 1);
		aim_bstream_init(&tbs, msgblock->value, msgblock->length);
		itl = aim_readtlvchain(&tbs);

		/* 
		 * Type 0x0001: Message.
		 */	
		if (aim_gettlv(itl, 0x0001, 1))
			msg = aim_gettlv_str(itl, 0x0001, 1);

		aim_freetlvchain(&itl); 
	}

	if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))
		ret = userfunc(sess, rx, &userinfo, msg);

	free(cookie);
	free(msg);
	aim_freetlvchain(&otl);

	return ret;
}
示例#3
0
/*
 * Subtype 0x0006
 *
 * We could probably include this in the normal ICBM parsing
 * code as channel 0x0003, however, since only the start
 * would be the same, we might as well do it here.
 *
 * General outline of this SNAC:
 *   snac
 *   cookie
 *   channel id
 *   tlvlist
 *     unknown
 *     source user info
 *       name
 *       evility
 *       userinfo tlvs
 *         online time
 *         etc
 *     message metatlv
 *       message tlv
 *         message string
 *       possibly others
 *
 */
static int
incomingim_ch3(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *frame, aim_modsnac_t *snac, ByteStream *bs)
{
	int ret = 0, i;
	aim_rxcallback_t userfunc;
	aim_userinfo_t userinfo;
	guint8 cookie[8];
	guint16 channel;
	GSList *tlvlist;
	char *msg = NULL;
	int len = 0;
	char *encoding = NULL, *language = NULL;
	IcbmCookie *ck;
	aim_tlv_t *tlv;
	ByteStream tbs;

	memset(&userinfo, 0, sizeof(aim_userinfo_t));

	/*
	 * Read ICBM Cookie.
	 */
	for (i = 0; i < 8; i++)
		cookie[i] = byte_stream_get8(bs);

	if ((ck = aim_uncachecookie(od, cookie, AIM_COOKIETYPE_CHAT))) {
		g_free(ck->data);
		g_free(ck);
	}

	/*
	 * Channel ID
	 *
	 * Channel 0x0003 is used for chat messages.
	 *
	 */
	channel = byte_stream_get16(bs);

	if (channel != 0x0003) {
		purple_debug_misc("oscar", "faim: chat_incoming: unknown channel! (0x%04x)\n", channel);
		return 0;
	}

	/*
	 * Start parsing TLVs right away.
	 */
	tlvlist = aim_tlvlist_read(bs);

	/*
	 * Type 0x0003: Source User Information
	 */
	tlv = aim_tlv_gettlv(tlvlist, 0x0003, 1);
	if (tlv != NULL)
	{
		byte_stream_init(&tbs, tlv->value, tlv->length);
		aim_info_extract(od, &tbs, &userinfo);
	}

	/*
	 * Type 0x0005: Message Block.  Conains more TLVs.
	 */
	tlv = aim_tlv_gettlv(tlvlist, 0x0005, 1);
	if (tlv != NULL)
	{
		GSList *inner_tlvlist;
		aim_tlv_t *inner_tlv;

		byte_stream_init(&tbs, tlv->value, tlv->length);
		inner_tlvlist = aim_tlvlist_read(&tbs);

		/*
		 * Type 0x0001: Message.
		 */
		inner_tlv = aim_tlv_gettlv(inner_tlvlist, 0x0001, 1);
		if (inner_tlv != NULL)
		{
			len = inner_tlv->length;
			msg = aim_tlv_getvalue_as_string(inner_tlv);
		}

		/*
		 * Type 0x0002: Encoding.
		 */
		encoding = aim_tlv_getstr(inner_tlvlist, 0x0002, 1);

		/*
		 * Type 0x0003: Language.
		 */
		language = aim_tlv_getstr(inner_tlvlist, 0x0003, 1);

		aim_tlvlist_free(inner_tlvlist);
	}

	if ((userfunc = aim_callhandler(od, snac->family, snac->subtype)))
		ret = userfunc(od, conn, frame, &userinfo, len, msg, encoding, language);

	aim_info_free(&userinfo);
	g_free(msg);
	g_free(encoding);
	g_free(language);
	aim_tlvlist_free(tlvlist);

	return ret;
}