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

📄 im.c

📁 oscar message protocol stack
💻 C
📖 第 1 页 / 共 5 页
字号:
	aimbs_put16(&fr->data, 0x0002); /* Channel */	aimbs_put8(&fr->data, strlen(sn)); /* Screename length */	aimbs_putraw(&fr->data, sn, strlen(sn)); /* Screenname */	/*	 * 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, ck, sizeof(ck)); /* I think... */	aim_putcap(&hdrbs, AIM_CAPS_CHAT);	aim_tlvlist_add_16(&itl, 0x000a, 0x0001);	aim_tlvlist_add_noval(&itl, 0x000f);	aim_tlvlist_add_raw(&itl, 0x000c, strlen(msg), msg);	aim_tlvlist_add_chatroom(&itl, 0x2711, exchange, roomname, instance);	aim_tlvlist_write(&hdrbs, &itl);		aim_tlvlist_add_raw(&otl, 0x0005, aim_bstream_curpos(&hdrbs), hdr);	aim_tlvlist_write(&fr->data, &otl);	free(hdr);	aim_tlvlist_free(&itl);	aim_tlvlist_free(&otl);		aim_tx_enqueue(sess, fr);	return 0;}/** * Subtype 0x0006 - Send your icon to a given user. * * This is also performance sensitive. (If you can believe it...) * */faim_export int aim_im_sendch2_icon(aim_session_t *sess, const char *sn, const fu8_t *icon, int iconlen, time_t stamp, fu16_t iconsum){	aim_conn_t *conn;	aim_frame_t *fr;	aim_snacid_t snacid;	fu8_t ck[8];	int i;	if (!sess || !(conn = aim_conn_findbygroup(sess, 0x0004)))		return -EINVAL;	if (!sn || !icon || (iconlen <= 0) || (iconlen >= MAXICONLEN))		return -EINVAL;	for (i = 0; i < 8; i++)		ck[i] = (fu8_t)rand();	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+8+2+1+strlen(sn)+2+2+2+8+16+2+2+2+2+2+2+2+4+4+4+iconlen+strlen(AIM_ICONIDENT)+2+2)))		return -ENOMEM;	snacid = aim_cachesnac(sess, 0x0004, 0x0006, 0x0000, NULL, 0);	aim_putsnac(&fr->data, 0x0004, 0x0006, 0x0000, snacid);	/* ICBM header */	aim_im_puticbm(&fr->data, ck, 0x0002, sn);	/*	 * TLV t(0005)	 *	 * Encompasses everything below.	 */	aimbs_put16(&fr->data, 0x0005);	aimbs_put16(&fr->data, 2+8+16+6+4+4+iconlen+4+4+4+strlen(AIM_ICONIDENT));	aimbs_put16(&fr->data, 0x0000);	aimbs_putraw(&fr->data, ck, 8);	aim_putcap(&fr->data, AIM_CAPS_BUDDYICON);	/* TLV t(000a) */	aimbs_put16(&fr->data, 0x000a);	aimbs_put16(&fr->data, 0x0002);	aimbs_put16(&fr->data, 0x0001);	/* TLV t(000f) */	aimbs_put16(&fr->data, 0x000f);	aimbs_put16(&fr->data, 0x0000);	/* TLV t(2711) */	aimbs_put16(&fr->data, 0x2711);	aimbs_put16(&fr->data, 4+4+4+iconlen+strlen(AIM_ICONIDENT));	aimbs_put16(&fr->data, 0x0000);	aimbs_put16(&fr->data, iconsum);	aimbs_put32(&fr->data, iconlen);	aimbs_put32(&fr->data, stamp);	aimbs_putraw(&fr->data, icon, iconlen);	aimbs_putraw(&fr->data, AIM_ICONIDENT, strlen(AIM_ICONIDENT));	/* TLV t(0003) */	aimbs_put16(&fr->data, 0x0003);	aimbs_put16(&fr->data, 0x0000);	aim_tx_enqueue(sess, fr);	return 0;}/* * Subtype 0x0006 - Send a rich text message. * * This only works for ICQ 2001b (thats 2001 not 2000).  Better, only * send it to clients advertising the RTF capability.  In fact, if you send * it to a client that doesn't support that capability, the server will gladly * bounce it back to you. * * You'd think this would be in icq.c, but, well, I'm trying to stick with * the one-group-per-file scheme as much as possible.  This could easily * be an exception, since Rendezvous IMs are external of the Oscar core, * and therefore are undefined.  Really I just need to think of a good way to * make an interface similar to what AOL actually uses.  But I'm not using COM. * */faim_export int aim_im_sendch2_rtfmsg(aim_session_t *sess, struct aim_sendrtfmsg_args *args){	aim_conn_t *conn;	aim_frame_t *fr;	aim_snacid_t snacid;	fu8_t ck[8];	const char rtfcap[] = {"{97B12751-243C-4334-AD22-D6ABF73F1492}"}; /* AIM_CAPS_ICQRTF capability in string form */	int i, servdatalen;	if (!sess || !(conn = aim_conn_findbygroup(sess, 0x0004)))		return -EINVAL;	if (!args || !args->destsn || !args->rtfmsg)		return -EINVAL;	servdatalen = 2+2+16+2+4+1+2  +  2+2+4+4+4  +  2+4+2+strlen(args->rtfmsg)+1  +  4+4+4+strlen(rtfcap)+1;	for (i = 0; i < 8; i++)		ck[i] = (fu8_t)rand();	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+128+servdatalen)))		return -ENOMEM;	snacid = aim_cachesnac(sess, 0x0004, 0x0006, 0x0000, NULL, 0);	aim_putsnac(&fr->data, 0x0004, 0x0006, 0x0000, snacid);	/* ICBM header */	aim_im_puticbm(&fr->data, ck, 0x0002, args->destsn);	/* TLV t(0005) - Encompasses everything below. */	aimbs_put16(&fr->data, 0x0005);	aimbs_put16(&fr->data, 2+8+16  +  2+2+2  +  2+2  +  2+2+servdatalen);	aimbs_put16(&fr->data, 0x0000);	aimbs_putraw(&fr->data, ck, 8);	aim_putcap(&fr->data, AIM_CAPS_ICQSERVERRELAY);	/* t(000a) l(0002) v(0001) */	aimbs_put16(&fr->data, 0x000a);	aimbs_put16(&fr->data, 0x0002);	aimbs_put16(&fr->data, 0x0001);	/* t(000f) l(0000) v() */	aimbs_put16(&fr->data, 0x000f);	aimbs_put16(&fr->data, 0x0000);	/* Service Data TLV */	aimbs_put16(&fr->data, 0x2711);	aimbs_put16(&fr->data, servdatalen);	aimbs_putle16(&fr->data, 11 + 16 /* 11 + (sizeof CLSID) */);	aimbs_putle16(&fr->data, 9);	aim_putcap(&fr->data, AIM_CAPS_EMPTY);	aimbs_putle16(&fr->data, 0);	aimbs_putle32(&fr->data, 0);	aimbs_putle8(&fr->data, 0);	aimbs_putle16(&fr->data, 0x03ea); /* trid1 */	aimbs_putle16(&fr->data, 14);	aimbs_putle16(&fr->data, 0x03eb); /* trid2 */	aimbs_putle32(&fr->data, 0);	aimbs_putle32(&fr->data, 0);	aimbs_putle32(&fr->data, 0);	aimbs_putle16(&fr->data, 0x0001);	aimbs_putle32(&fr->data, 0);	aimbs_putle16(&fr->data, strlen(args->rtfmsg)+1);	aimbs_putraw(&fr->data, args->rtfmsg, strlen(args->rtfmsg)+1);	aimbs_putle32(&fr->data, args->fgcolor);	aimbs_putle32(&fr->data, args->bgcolor);	aimbs_putle32(&fr->data, strlen(rtfcap)+1);	aimbs_putraw(&fr->data, rtfcap, strlen(rtfcap)+1);	aim_tx_enqueue(sess, fr);	return 0;}/** * Subtype 0x0006 - Send an "I want to directly connect to you" message * */faim_export int aim_im_sendch2_odcrequest(aim_session_t *sess, fu8_t *cookie, bool usecookie, const char *sn, const fu8_t *ip, fu16_t port){	aim_conn_t *conn;	aim_frame_t *fr;	aim_snacid_t snacid;	fu8_t ck[8];	aim_tlvlist_t *tl = NULL, *itl = NULL;	int hdrlen, i;	fu8_t *hdr;	aim_bstream_t hdrbs;	if (!sess || !(conn = aim_conn_findbygroup(sess, 0x0004)))		return -EINVAL;	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 256+strlen(sn))))		return -ENOMEM;	snacid = aim_cachesnac(sess, 0x0004, 0x0006, 0x0000, NULL, 0);	aim_putsnac(&fr->data, 0x0004, 0x0006, 0x0000, snacid);	/*	 * Generate a random message cookie	 *	 * This cookie needs to be alphanumeric and NULL-terminated to be	 * TOC-compatible.	 *	 * XXX - have I mentioned these should be generated in msgcookie.c?	 *	 */	if (cookie && usecookie) /* allow user-specified cookie */		memcpy(ck, cookie, 8);	else		for (i = 0; i < 7; i++)			ck[i] = 0x30 + ((fu8_t) rand() % 10);	ck[7] = '\0';	if (cookie && !usecookie)		memcpy(cookie, ck, 8);	/* ICBM header */	aim_im_puticbm(&fr->data, ck, 0x0002, sn);	aim_tlvlist_add_noval(&tl, 0x0003);	hdrlen = 2+8+16+6+8+6+4;	hdr = malloc(hdrlen);	aim_bstream_init(&hdrbs, hdr, hdrlen);	aimbs_put16(&hdrbs, 0x0000);	aimbs_putraw(&hdrbs, ck, 8);	aim_putcap(&hdrbs, AIM_CAPS_DIRECTIM);	aim_tlvlist_add_16(&itl, 0x000a, 0x0001);	aim_tlvlist_add_raw(&itl, 0x0003, 4, ip);	aim_tlvlist_add_16(&itl, 0x0005, port);	aim_tlvlist_add_noval(&itl, 0x000f);		aim_tlvlist_write(&hdrbs, &itl);	aim_tlvlist_add_raw(&tl, 0x0005, aim_bstream_curpos(&hdrbs), hdr);	aim_tlvlist_write(&fr->data, &tl);	free(hdr);	aim_tlvlist_free(&itl);	aim_tlvlist_free(&tl);	aim_tx_enqueue(sess, fr);	return 0;}/** * Subtype 0x0006 - Send an "I want to send you this file" message * */faim_export int aim_im_sendch2_sendfile_ask(aim_session_t *sess, struct aim_oft_info *oft_info){	aim_conn_t *conn;	aim_frame_t *fr;	aim_snacid_t snacid;	aim_tlvlist_t *tl=NULL, *subtl=NULL;	int i;	if (!sess || !(conn = aim_conn_findbygroup(sess, 0x0004)) || !oft_info)		return -EINVAL;	/* XXX - Should be like "21CBF95" and null terminated */	for (i = 0; i < 7; i++)		oft_info->cookie[i] = 0x30 + ((fu8_t)rand() % 10);	oft_info->cookie[7] = '\0';	{ /* Create the subTLV chain */		fu8_t *buf;		int buflen;		aim_bstream_t bs;		aim_tlvlist_add_16(&subtl, 0x000a, 0x0001);		aim_tlvlist_add_noval(&subtl, 0x000f);/*		aim_tlvlist_add_raw(&subtl, 0x000e, 2, "en");		aim_tlvlist_add_raw(&subtl, 0x000d, 8, "us-ascii");		aim_tlvlist_add_raw(&subtl, 0x000c, 24, "Please accept this file."); */		/* XXX - Change oft_info->clientip to an array of 4 bytes */		if (oft_info->clientip) {			fu8_t ip[4];			char *nexttoken;			int i = 0;			nexttoken = strtok(oft_info->clientip, ".");			while (nexttoken && i<4) {				ip[i] = atoi(nexttoken);				nexttoken = strtok(NULL, ".");				i++;			}			aim_tlvlist_add_raw(&subtl, 0x0003, 4, ip);		}		aim_tlvlist_add_16(&subtl, 0x0005, oft_info->port);		/* TLV t(2711) */		buflen = 2+2+4+strlen(oft_info->fh.name)+1;		buf = malloc(buflen);		aim_bstream_init(&bs, buf, buflen);		aimbs_put16(&bs, (oft_info->fh.totfiles > 1) ? 0x0002 : 0x0001);		aimbs_put16(&bs, oft_info->fh.totfiles);		aimbs_put32(&bs, oft_info->fh.totsize);		/* Filename - NULL terminated, for some odd reason */		aimbs_putraw(&bs, oft_info->fh.name, strlen(oft_info->fh.name));		aimbs_put8(&bs, 0x00);		aim_tlvlist_add_raw(&subtl, 0x2711, bs.len, bs.data);		free(buf);	}	{ /* Create the main TLV chain */		fu8_t *buf;		int buflen;		aim_bstream_t bs;		/* TLV t(0005) - Encompasses everything from above. Gee. */		buflen = 2+8+16+aim_tlvlist_size(&subtl);		buf = malloc(buflen);		aim_bstream_init(&bs, buf, buflen);		aimbs_put16(&bs, AIM_RENDEZVOUS_PROPOSE);		aimbs_putraw(&bs, oft_info->cookie, 8);		aim_putcap(&bs, AIM_CAPS_SENDFILE);		aim_tlvlist_write(&bs, &subtl);		aim_tlvlist_free(&subtl);		aim_tlvlist_add_raw(&tl, 0x0005, bs.len, bs.data);		free(buf);		/* TLV t(0003) - Request an ack */		aim_tlvlist_add_noval(&tl, 0x0003);	}	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10 + 11+strlen(oft_info->sn) + aim_tlvlist_size(&tl))))		return -ENOMEM;	snacid = aim_cachesnac(sess, 0x0004, 0x0006, AIM_SNACFLAGS_DESTRUCTOR, oft_info->cookie, sizeof(oft_info->cookie));	aim_putsnac(&fr->data, 0x0004, 0x0006, 0x0000, snacid);	/* ICBM header */	aim_im_puticbm(&fr->data, oft_info->cookie, 0x0002, oft_info->sn);	/* All that crap from above (the 0x0005 TLV and the 0x0003 TLV) */	aim_tlvlist_write(&fr->data, &tl);	aim_tlvlist_free(&tl);	aim_tx_enqueue(sess, fr);	return 0;}/** * Subtype 0x0006 - Send an "I will accept this file" message? * * @param rendid Capability type (AIM_CAPS_GETFILE or AIM_CAPS_SENDFILE) */faim_export int aim_im_sendch2_sendfile_accept(aim_session_t *sess, struct aim_oft_info *oft_info){	aim_conn_t *conn;	aim_frame_t *fr;	aim_snacid_t snacid;	if (!sess || !(conn = aim_conn_findbygroup(sess, 0x0004)) || !oft_info)		return -EINVAL;	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10 + 11+strlen(oft_info->sn) + 4+2+8+16)))		return -ENOMEM;	snacid = aim_cachesnac(sess, 0x0004, 0x0006, 0x0000, NULL, 0);	aim_putsnac(&fr->data, 0x0004, 0x0006, 0x0000, snacid);	/* ICBM header */	aim_im_puticbm(&fr->data, oft_info->cookie, 0x0002, oft_info->sn);	aimbs_put16(&fr->data, 0x0005);	aimbs_put16(&fr->data, 0x001a);	aimbs_put16(&fr->data, AIM_RENDEZVOUS_ACCEPT);	aimbs_putraw(&fr->data, oft_info->cookie, 8);	aim_putcap(&fr->data, AIM_CAPS_SENDFILE);	aim_tx_enqueue(sess, fr);	return 0;}/** * Subtype 0x0006 - Send a "cancel this file transfer" message? * */faim_export int aim_im_sendch2_sendfile_cancel(aim_session_t *sess, struct aim_oft_info *oft_info){	aim_conn_t *conn;	aim_frame_t *fr;	aim_snacid_t snacid;	if (!sess || !(conn = aim_conn_findbygroup(sess, 0x0004)) || !oft_info)		return -EINVAL;	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10 + 11+strlen(oft_info->sn) + 4+2+8+16)))		return -ENOMEM;	snacid = aim_cachesnac(sess, 0x0004, 0x0006, 0x0000, NULL, 0);	aim_putsnac(&fr->data, 0x0004, 0x0006, 0x0000, snacid);	/* ICBM header */	aim_im_puticbm(&fr->data, oft_info->cookie, 0x0002, oft_info->sn);	aimbs_put16(&fr->data, 0x0005);	aimbs_put16(&fr->data, 0x001a);	aimbs_put16(&fr->data, AIM_RENDEZVOUS_CANCEL);	aimbs_putraw(&fr->data, oft_info->cookie, 8);	aim_putcap(&fr->data, AIM_CAPS_SENDFILE);	aim_tx_enqueue(sess, fr);	return 0;}/** * Subtype 0x0006 - Request the status message of the given ICQ user. * * @param sess The oscar session. * @param sn The UIN of the user of whom you wish to request info. * @param type The type of info you wish to request.  This should be the current  *        state of the user, as one of the AIM_ICQ_STATE_* defines. * @return Return 0 if no errors, otherwise return the error number. */faim_export int aim_im_sendch2_geticqaway(aim_session_t *sess, const char *sn, int type){	aim_conn_t *conn;	aim_frame_t *fr;	aim_snacid_t snacid;

⌨️ 快捷键说明

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