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

📄 chat.c

📁 AnyQ服务端源代码(2004/10/28)源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * aim_chat.c * * Routines for the Chat service. * */#define FAIM_INTERNAL#include <aim.h> /* Stored in the ->priv of chat connections */struct chatconnpriv {	fu16_t exchange;	char *name;	fu16_t instance;};faim_internal void aim_conn_kill_chat(aim_session_t *sess, aim_conn_t *conn){	struct chatconnpriv *ccp = (struct chatconnpriv *)conn->priv;	if (ccp)		free(ccp->name);	free(ccp);	return;}faim_export char *aim_chat_getname(aim_conn_t *conn){	struct chatconnpriv *ccp;	if (!conn)		return NULL;	if (conn->type != AIM_CONN_TYPE_CHAT)		return NULL;	ccp = (struct chatconnpriv *)conn->priv;	return ccp->name;}/* XXX get this into conn.c -- evil!! */faim_export aim_conn_t *aim_chat_getconn(aim_session_t *sess, const char *name){	aim_conn_t *cur;	for (cur = sess->connlist; cur; cur = cur->next) {		struct chatconnpriv *ccp = (struct chatconnpriv *)cur->priv;		if (cur->type != AIM_CONN_TYPE_CHAT)			continue;		if (!cur->priv) {			faimdprintf(sess, 0, "faim: chat: chat connection with no name! (fd = %d)\n", cur->fd);			continue;		}		if (strcmp(ccp->name, name) == 0)			break;	}	return cur;}faim_export int aim_chat_attachname(aim_conn_t *conn, fu16_t exchange, const char *roomname, fu16_t instance){	struct chatconnpriv *ccp;	if (!conn || !roomname)		return -EINVAL;	if (conn->priv)		free(conn->priv);	if (!(ccp = malloc(sizeof(struct chatconnpriv))))		return -ENOMEM;	ccp->exchange = exchange;	ccp->name = strdup(roomname);	ccp->instance = instance;	conn->priv = (void *)ccp;	return 0;}/* * Send a Chat Message. * * Possible flags: *   AIM_CHATFLAGS_NOREFLECT   --  Unset the flag that requests messages *                                 should be sent to their sender. *   AIM_CHATFLAGS_AWAY        --  Mark the message as an autoresponse *                                 (Note that WinAIM does not honor this, *                                 and displays the message as normal.) * * XXX convert this to use tlvchains  */faim_export int aim_chat_send_im(aim_session_t *sess, aim_conn_t *conn, fu16_t flags, const char *msg, int msglen){   	int i;	aim_frame_t *fr;	aim_msgcookie_t *cookie;	aim_snacid_t snacid;	fu8_t ckstr[8];	aim_tlvlist_t *otl = NULL, *itl = NULL;	if (!sess || !conn || !msg || (msglen <= 0))		return 0;	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 1152)))		return -ENOMEM;	snacid = aim_cachesnac(sess, 0x000e, 0x0005, 0x0000, NULL, 0);	aim_putsnac(&fr->data, 0x000e, 0x0005, 0x0000, snacid);	/* 	 * Generate a random message cookie.	 *	 * XXX mkcookie should generate the cookie and cache it in one	 * operation to preserve uniqueness.	 *	 */	for (i = 0; i < sizeof(ckstr); i++)		aimutil_put8(ckstr+i, (fu8_t) rand());	cookie = aim_mkcookie(ckstr, AIM_COOKIETYPE_CHAT, NULL);	cookie->data = NULL; /* XXX store something useful here */	aim_cachecookie(sess, cookie);	for (i = 0; i < sizeof(ckstr); i++)		aimbs_put8(&fr->data, ckstr[i]);	/*	 * Channel ID. 	 */	aimbs_put16(&fr->data, 0x0003);	/*	 * Type 1: Flag meaning this message is destined to the room.	 */	aim_addtlvtochain_noval(&otl, 0x0001);	/*	 * Type 6: Reflect	 */	if (!(flags & AIM_CHATFLAGS_NOREFLECT))		aim_addtlvtochain_noval(&otl, 0x0006);	/*	 * Type 7: Autoresponse	 */	if (flags & AIM_CHATFLAGS_AWAY)		aim_addtlvtochain_noval(&otl, 0x0007);	/*	 * SubTLV: Type 1: Message	 */	aim_addtlvtochain_raw(&itl, 0x0001, strlen(msg), msg);	/*	 * Type 5: Message block.  Contains more TLVs.	 *	 * This could include other information... We just	 * put in a message TLV however.  	 * 	 */	aim_addtlvtochain_frozentlvlist(&otl, 0x0005, &itl);	aim_writetlvchain(&fr->data, &otl);		aim_freetlvchain(&itl);	aim_freetlvchain(&otl);		aim_tx_enqueue(sess, fr);	return 0;}static int aim_addtlvtochain_chatroom(aim_tlvlist_t **list, fu16_t type, fu16_t exchange, const char *roomname, fu16_t instance){	fu8_t *buf;	int buflen;	aim_bstream_t bs;	buflen = 2 + 1 + strlen(roomname) + 2;		if (!(buf = malloc(buflen)))		return 0;	aim_bstream_init(&bs, buf, buflen);	aimbs_put16(&bs, exchange);	aimbs_put8(&bs, strlen(roomname));	aimbs_putraw(&bs, roomname, strlen(roomname));	aimbs_put16(&bs, instance);	aim_addtlvtochain_raw(list, type, aim_bstream_curpos(&bs), buf);	free(buf);	return 0;}/* * Join a room of name roomname.  This is the first step to joining an  * already created room.  It's basically a Service Request for  * family 0x000e, with a little added on to specify the exchange and room  * name. */faim_export int aim_chat_join(aim_session_t *sess, aim_conn_t *conn, fu16_t exchange, const char *roomname, fu16_t instance){	aim_frame_t *fr;	aim_snacid_t snacid;	aim_tlvlist_t *tl = NULL;	struct chatsnacinfo csi;		if (!sess || !conn || !roomname || !strlen(roomname))		return -EINVAL;	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 512)))		return -ENOMEM;	memset(&csi, 0, sizeof(csi));	csi.exchange = exchange;	strncpy(csi.name, roomname, sizeof(csi.name));	csi.instance = instance;	snacid = aim_cachesnac(sess, 0x0001, 0x0004, 0x0000, &csi, sizeof(csi));	aim_putsnac(&fr->data, 0x0001, 0x0004, 0x0000, snacid);	/*	 * Requesting service chat (0x000e)	 */	aimbs_put16(&fr->data, 0x000e);	aim_addtlvtochain_chatroom(&tl, 0x0001, exchange, roomname, instance);	aim_writetlvchain(&fr->data, &tl);	aim_freetlvchain(&tl);	aim_tx_enqueue(sess, fr);	return 0; }faim_internal int aim_chat_readroominfo(aim_bstream_t *bs, struct aim_chat_roominfo *outinfo){	int namelen;	if (!bs || !outinfo)		return 0;	outinfo->exchange = aimbs_get16(bs);	namelen = aimbs_get8(bs);	outinfo->name = aimbs_getstr(bs, namelen);	outinfo->instance = aimbs_get16(bs);	return 0;}faim_export int aim_chat_leaveroom(aim_session_t *sess, const char *name){	aim_conn_t *conn;	if (!(conn = aim_chat_getconn(sess, name)))		return -ENOENT;	aim_conn_close(conn);	return 0;}/* * conn must be a BOS connection! */faim_export int aim_chat_invite(aim_session_t *sess, aim_conn_t *conn, const char *sn, const char *msg, fu16_t exchange, const char *roomname, fu16_t instance){	int i;	aim_frame_t *fr;	aim_msgcookie_t *cookie;	struct aim_invite_priv *priv;	fu8_t ckstr[8];	aim_snacid_t snacid;	aim_tlvlist_t *otl = NULL, *itl = NULL;	fu8_t *hdr;	int hdrlen;	aim_bstream_t hdrbs;		if (!sess || !conn || !sn || !msg || !roomname)		return -EINVAL;	if (conn->type != AIM_CONN_TYPE_BOS)		return -EINVAL;	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 1152+strlen(sn)+strlen(roomname)+strlen(msg))))		return -ENOMEM;	snacid = aim_cachesnac(sess, 0x0004, 0x0006, 0x0000, sn, strlen(sn)+1);	aim_putsnac(&fr->data, 0x0004, 0x0006, 0x0000, snacid);	/*	 * Cookie	 */	for (i = 0; i < sizeof(ckstr); i++)		aimutil_put8(ckstr, (fu8_t) rand());	/* XXX should be uncached by an unwritten 'invite accept' handler */	if ((priv = malloc(sizeof(struct aim_invite_priv)))) {		priv->sn = strdup(sn);		priv->roomname = strdup(roomname);		priv->exchange = exchange;		priv->instance = instance;	}	if ((cookie = aim_mkcookie(ckstr, AIM_COOKIETYPE_INVITE, priv)))		aim_cachecookie(sess, cookie);	else		free(priv);	for (i = 0; i < sizeof(ckstr); i++)		aimbs_put8(&fr->data, ckstr[i]);	/*	 * Channel (2)	 */	aimbs_put16(&fr->data, 0x0002);	/*	 * Dest sn	 */	aimbs_put8(&fr->data, strlen(sn));	aimbs_putraw(&fr->data, sn, strlen(sn));	/*	 * TLV t(0005)	 *	 * Everything else is inside this TLV.	 *	 * Sigh.  AOL was rather inconsistent right here.  So we have	 * to play some minor tricks.  Right inside the type 5 is some	 * raw data, followed by a series of TLVs.  	 *	 */	hdrlen = 2+8+16+6+4+4+strlen(msg)+4+2+1+strlen(roomname)+2;	hdr = malloc(hdrlen);	aim_bstream_init(&hdrbs, hdr, hdrlen);		aimbs_put16(&hdrbs, 0x0000); /* Unknown! */	aimbs_putraw(&hdrbs, ckstr, sizeof(ckstr)); /* I think... */	aim_putcap(&hdrbs, AIM_CAPS_CHAT);

⌨️ 快捷键说明

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