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

📄 family_icbm.c

📁 Linux下的多协议即时通讯程序源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	aim_tlvlist_free(inner_tlvlist);	aim_tlvlist_free(outer_tlvlist);	flap_connection_send(conn, frame);}/** * Subtype 0x0006 - Send an "I want to send you this file" message * */voidaim_im_sendch2_sendfile_requestdirect(OscarData *od, guchar *cookie, const char *sn, const guint8 *ip, guint16 port, guint16 requestnumber, const gchar *filename, guint32 size, guint16 numfiles){	FlapConnection *conn;	FlapFrame *frame;	aim_snacid_t snacid;	GSList *outer_tlvlist = NULL, *inner_tlvlist = NULL;	ByteStream hdrbs;	conn = flap_connection_findbygroup(od, 0x0004);	if (conn == NULL)		return;	frame = flap_frame_new(od, 0x02, 1024);	snacid = aim_cachesnac(od, 0x0004, 0x0006, 0x0000, NULL, 0);	aim_putsnac(&frame->data, 0x0004, 0x0006, 0x0000, snacid);	/* ICBM header */	aim_im_puticbm(&frame->data, cookie, 0x0002, sn);	aim_tlvlist_add_noval(&outer_tlvlist, 0x0003);	byte_stream_new(&hdrbs, 512);	byte_stream_put16(&hdrbs, AIM_RENDEZVOUS_PROPOSE);	byte_stream_putraw(&hdrbs, cookie, 8);	byte_stream_putcaps(&hdrbs, OSCAR_CAPABILITY_SENDFILE);	aim_tlvlist_add_raw(&inner_tlvlist, 0x0002, 4, ip);	aim_tlvlist_add_raw(&inner_tlvlist, 0x0003, 4, ip);	aim_tlvlist_add_16(&inner_tlvlist, 0x0005, port);	aim_tlvlist_add_16(&inner_tlvlist, 0x000a, requestnumber);	aim_tlvlist_add_noval(&inner_tlvlist, 0x000f);	/* TODO: Send 0x0016 and 0x0017 */#if 0	/* TODO: If the following is ever enabled, ensure that it is	 *       not sent with a receive redirect or stage 3 proxy	 *       redirect for a file receive (same conditions for	 *       sending 0x000f above)	 */	aim_tlvlist_add_raw(&inner_tlvlist, 0x000e, 2, "en");	aim_tlvlist_add_raw(&inner_tlvlist, 0x000d, 8, "us-ascii");	aim_tlvlist_add_raw(&inner_tlvlist, 0x000c, 24, "Please accept this file.");#endif	if (filename != NULL)	{		ByteStream bs;		/* Begin TLV t(2711) */		byte_stream_new(&bs, 2+2+4+strlen(filename)+1);		byte_stream_put16(&bs, (numfiles > 1) ? 0x0002 : 0x0001);		byte_stream_put16(&bs, numfiles);		byte_stream_put32(&bs, size);		/* Filename - NULL terminated, for some odd reason */		byte_stream_putstr(&bs, filename);		byte_stream_put8(&bs, 0x00);		aim_tlvlist_add_raw(&inner_tlvlist, 0x2711, bs.len, bs.data);		g_free(bs.data);		/* End TLV t(2711) */	}	aim_tlvlist_write(&hdrbs, &inner_tlvlist);	aim_tlvlist_add_raw(&outer_tlvlist, 0x0005, byte_stream_curpos(&hdrbs), hdrbs.data);	g_free(hdrbs.data);	aim_tlvlist_write(&frame->data, &outer_tlvlist);	aim_tlvlist_free(inner_tlvlist);	aim_tlvlist_free(outer_tlvlist);	flap_connection_send(conn, frame);}/** * Subtype 0x0006 - Send a sendfile connect rendezvous ICBM asking the * remote user to connect to us via a proxy server. */voidaim_im_sendch2_sendfile_requestproxy(OscarData *od, guchar *cookie, const char *sn, const guint8 *ip, guint16 pin, guint16 requestnumber, const gchar *filename, guint32 size, guint16 numfiles){	FlapConnection *conn;	FlapFrame *frame;	aim_snacid_t snacid;	GSList *outer_tlvlist = NULL, *inner_tlvlist = NULL;	ByteStream hdrbs;	guint8 ip_comp[4];	conn = flap_connection_findbygroup(od, 0x0004);	if (conn == NULL)		return;	frame = flap_frame_new(od, 0x02, 1024);	snacid = aim_cachesnac(od, 0x0004, 0x0006, 0x0000, NULL, 0);	aim_putsnac(&frame->data, 0x0004, 0x0006, 0x0000, snacid);	/* ICBM header */	aim_im_puticbm(&frame->data, cookie, 0x0002, sn);	aim_tlvlist_add_noval(&outer_tlvlist, 0x0003);	byte_stream_new(&hdrbs, 512);	byte_stream_put16(&hdrbs, AIM_RENDEZVOUS_PROPOSE);	byte_stream_putraw(&hdrbs, cookie, 8);	byte_stream_putcaps(&hdrbs, OSCAR_CAPABILITY_SENDFILE);	aim_tlvlist_add_raw(&inner_tlvlist, 0x0002, 4, ip);	aim_tlvlist_add_raw(&inner_tlvlist, 0x0003, 4, ip);	aim_tlvlist_add_16(&inner_tlvlist, 0x0005, pin);	aim_tlvlist_add_16(&inner_tlvlist, 0x000a, requestnumber);	aim_tlvlist_add_noval(&inner_tlvlist, 0x000f);	aim_tlvlist_add_noval(&inner_tlvlist, 0x0010);	/* Send the bitwise complement of the port and ip.  As a check? */	ip_comp[0] = ~ip[0];	ip_comp[1] = ~ip[1];	ip_comp[2] = ~ip[2];	ip_comp[3] = ~ip[3];	aim_tlvlist_add_raw(&inner_tlvlist, 0x0016, 4, ip_comp);	aim_tlvlist_add_16(&inner_tlvlist, 0x0017, ~pin);#if 0	/* TODO: If the following is ever enabled, ensure that it is	 *       not sent with a receive redirect or stage 3 proxy	 *       redirect for a file receive (same conditions for	 *       sending 0x000f above)	 */	aim_tlvlist_add_raw(&inner_tlvlist, 0x000e, 2, "en");	aim_tlvlist_add_raw(&inner_tlvlist, 0x000d, 8, "us-ascii");	aim_tlvlist_add_raw(&inner_tlvlist, 0x000c, 24, "Please accept this file.");#endif	if (filename != NULL)	{		ByteStream bs;		/* Begin TLV t(2711) */		byte_stream_new(&bs, 2+2+4+strlen(filename)+1);		byte_stream_put16(&bs, (numfiles > 1) ? 0x0002 : 0x0001);		byte_stream_put16(&bs, numfiles);		byte_stream_put32(&bs, size);		/* Filename - NULL terminated, for some odd reason */		byte_stream_putstr(&bs, filename);		byte_stream_put8(&bs, 0x00);		aim_tlvlist_add_raw(&inner_tlvlist, 0x2711, bs.len, bs.data);		g_free(bs.data);		/* End TLV t(2711) */	}	aim_tlvlist_write(&hdrbs, &inner_tlvlist);	aim_tlvlist_add_raw(&outer_tlvlist, 0x0005, byte_stream_curpos(&hdrbs), hdrbs.data);	g_free(hdrbs.data);	aim_tlvlist_write(&frame->data, &outer_tlvlist);	aim_tlvlist_free(inner_tlvlist);	aim_tlvlist_free(outer_tlvlist);	flap_connection_send(conn, frame);}/** * Subtype 0x0006 - Request the status message of the given ICQ user. * * @param od 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. */int aim_im_sendch2_geticqaway(OscarData *od, const char *sn, int type){	FlapConnection *conn;	FlapFrame *frame;	aim_snacid_t snacid;	guchar cookie[8];	if (!od || !(conn = flap_connection_findbygroup(od, 0x0004)) || !sn)		return -EINVAL;	aim_icbm_makecookie(cookie);	frame = flap_frame_new(od, 0x02, 10+8+2+1+strlen(sn) + 4+0x5e + 4);	snacid = aim_cachesnac(od, 0x0004, 0x0006, 0x0000, NULL, 0);	aim_putsnac(&frame->data, 0x0004, 0x0006, 0x0000, snacid);	/* ICBM header */	aim_im_puticbm(&frame->data, cookie, 0x0002, sn);	/* TLV t(0005) - Encompasses almost everything below. */	byte_stream_put16(&frame->data, 0x0005); /* T */	byte_stream_put16(&frame->data, 0x005e); /* L */	{ /* V */		byte_stream_put16(&frame->data, 0x0000);		/* Cookie */		byte_stream_putraw(&frame->data, cookie, 8);		/* Put the 16 byte server relay capability */		byte_stream_putcaps(&frame->data, OSCAR_CAPABILITY_ICQSERVERRELAY);		/* TLV t(000a) */		byte_stream_put16(&frame->data, 0x000a);		byte_stream_put16(&frame->data, 0x0002);		byte_stream_put16(&frame->data, 0x0001);		/* TLV t(000f) */		byte_stream_put16(&frame->data, 0x000f);		byte_stream_put16(&frame->data, 0x0000);		/* TLV t(2711) */		byte_stream_put16(&frame->data, 0x2711);		byte_stream_put16(&frame->data, 0x0036);		{ /* V */			byte_stream_putle16(&frame->data, 0x001b); /* L */			byte_stream_putle16(&frame->data, 0x0009); /* Protocol version */			byte_stream_putcaps(&frame->data, OSCAR_CAPABILITY_EMPTY);			byte_stream_putle16(&frame->data, 0x0000); /* Unknown */			byte_stream_putle16(&frame->data, 0x0001); /* Client features? */			byte_stream_putle16(&frame->data, 0x0000); /* Unknown */			byte_stream_putle8(&frame->data, 0x00); /* Unkizown */			byte_stream_putle16(&frame->data, 0xffff); /* Sequence number?  XXX - This should decrement by 1 with each request */			byte_stream_putle16(&frame->data, 0x000e); /* L */			byte_stream_putle16(&frame->data, 0xffff); /* Sequence number?  XXX - This should decrement by 1 with each request */			byte_stream_putle32(&frame->data, 0x00000000); /* Unknown */			byte_stream_putle32(&frame->data, 0x00000000); /* Unknown */			byte_stream_putle32(&frame->data, 0x00000000); /* Unknown */			/* The type of status message being requested */			if (type & AIM_ICQ_STATE_CHAT)				byte_stream_putle16(&frame->data, 0x03ec);			else if(type & AIM_ICQ_STATE_DND)				byte_stream_putle16(&frame->data, 0x03eb);			else if(type & AIM_ICQ_STATE_OUT)				byte_stream_putle16(&frame->data, 0x03ea);			else if(type & AIM_ICQ_STATE_BUSY)				byte_stream_putle16(&frame->data, 0x03e9);			else if(type & AIM_ICQ_STATE_AWAY)				byte_stream_putle16(&frame->data, 0x03e8);			byte_stream_putle16(&frame->data, 0x0001); /* Status? */			byte_stream_putle16(&frame->data, 0x0001); /* Priority of this message? */			byte_stream_putle16(&frame->data, 0x0001); /* L */			byte_stream_putle8(&frame->data, 0x00); /* String of length L */		} /* End TLV t(2711) */	} /* End TLV t(0005) */	/* TLV t(0003) */	byte_stream_put16(&frame->data, 0x0003);	byte_stream_put16(&frame->data, 0x0000);	flap_connection_send(conn, frame);	return 0;}/** * Subtype 0x0006 - Send an ICQ-esque ICBM. * * This can be used to send an ICQ authorization reply (deny or grant).  It is the "old way." * The new way is to use SSI.  I like the new way a lot better.  This seems like such a hack, * mostly because it's in network byte order.  Figuring this stuff out sometimes takes a while, * but thats ok, because it gives me time to try to figure out what kind of drugs the AOL people * were taking when they merged the two protocols. * * @param sn The destination screen name. * @param type The type of message.  0x0007 for authorization denied.  0x0008 for authorization granted. * @param message The message you want to send, it should be null terminated. * @return Return 0 if no errors, otherwise return the error number. */int aim_im_sendch4(OscarData *od, const char *sn, guint16 type, const char *message){	FlapConnection *conn;	FlapFrame *frame;	aim_snacid_t snacid;	guchar cookie[8];	if (!od || !(conn = flap_connection_findbygroup(od, 0x0002)))		return -EINVAL;	if (!sn || !type || !message)		return -EINVAL;	frame = flap_frame_new(od, 0x02, 10+8+3+strlen(sn)+12+strlen(message)+1+4);	snacid = aim_cachesnac(od, 0x0004, 0x0006, 0x0000, NULL, 0);	aim_putsnac(&frame->data, 0x0004, 0x0006, 0x0000, snacid);	aim_icbm_makecookie(cookie);	/* ICBM header */	aim_im_puticbm(&frame->data, cookie, 0x0004, sn);	/*	 * TLV t(0005)	 *	 * ICQ data (the UIN and the message).	 */	byte_stream_put16(&frame->data, 0x0005);	byte_stream_put16(&frame->data, 4 + 2+2+strlen(message)+1);	/*	 * Your UIN	 */	byte_stream_putle32(&frame->data, atoi(od->sn));	/*	 * TLV t(type) l(strlen(message)+1) v(message+NULL)	 */	byte_stream_putle16(&frame->data, type);	byte_stream_putle16(&frame->data, strlen(message)+1);	byte_stream_putraw(&frame->data, (const guint8 *)message, strlen(message)+1);	/*	 * TLV t(0006) l(0000) v()	 */	byte_stream_put16(&frame->data, 0x0006);	byte_stream_put16(&frame->data, 0x0000);	flap_connection_send(conn, frame);	return 0;}/* * XXX - I don't see when this would ever get called... */static int outgoingim(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *frame, aim_modsnac_t *snac, ByteStream *bs){	int ret = 0;	aim_rxcallback_t userfunc;	guchar cookie[8];	guint16 channel;	GSList *tlvlist;	char *sn;	int snlen;	guint16 icbmflags = 0;	guint8 flag1 = 0, flag2 = 0;	gchar *msg = NULL;	aim_tlv_t *msgblock;	/* ICBM Cookie. */	aim_icbm_makecookie(cookie);	/* Channel ID */	channel = byte_stream_get16(bs);	if (channel != 0x01) {		purple_debug_misc("oscar", "icbm: ICBM recieved on unsupported channel.  Ignoring. (chan = %04x)\n", channel);		return 0;	}	snlen = byte_stream_get8(bs);	sn = byte_stream_getstr(bs, snlen);	tlvlist = aim_tlvlist_read(bs);	if (aim_tlv_gettlv(tlvlist, 0x0003, 1))		icbmflags |= AIM_IMFLAGS_ACK;	if (aim_tlv_gettlv(tlvlist, 0x0004, 1))		icbmflags |= AIM_IMFLAGS_AWAY;	if ((msgblock = aim_tlv_gettlv(tlvlist, 0x0002, 1))) {		ByteStream mbs;		int featurelen, msglen;		byte_stream_init(&mbs, msgblock->value, msgblock->length);		byte_stream_get8(&mbs);		byte_stream_get8(&mbs);		for (featurelen = byte_stream_get16(&mbs); featurelen; featurelen--)			byte_stream_get8(&mbs);		byte_stream_get8(&mbs);		byte_stream_get8(&mbs);		msglen = byte_stream_get16(&mbs) - 4; /* final block length */		flag1 = byte_stream_get16(&mbs);		flag2 = byte_stream_get16(&mbs);		msg = byte_stream_getstr(&mbs, msglen);	}	if ((userfunc = aim_callhandler(od, snac->family, snac->subtype)))		ret = userfunc(od, conn, frame, channel, sn, msg, icbmflags, flag1, flag2);	g_free(sn);	g_free(msg);	aim_tlvlist_free(tlvlist);	return ret;}/* * Ahh, the joys of nearly ridiculous over-engineering. * * Not only do AIM ICBM's support multiple channels.  Not only do they * support multiple character sets.  But they support multiple character * sets / encodings within the same ICBM. * * These multipart messages allow for complex space savings techniques, which * seem utterly unnecessary by today's standards.  In fact, there is only * one client still in popular use that still uses this method: AOL for the * Macintosh, Version 5.0.  Obscure, yes, I know. * * In modern (non-"legacy") clients, if the user tries to send a character * that is not ISO-8859-1 or ASCII, the client will send the entire message * as UNICODE, meaning that every character in the message will occupy the * full 16 bit UNICODE field, even if the high order byte would be zero. * Multipart messages prevent this wasted space by allowing the client to * only send the characters in UNICODE that need to be sent that way, and * the rest of the message can be sent in whatever the native character * set is (probably ASCII). * * An important note is that sections will be displayed in the order that * they appear in the ICBM.  There is no facility for merging or rearranging

⌨️ 快捷键说明

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