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

📄 family_icbm.c

📁 Linux下的多协议即时通讯程序源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	args.flags &= ~(AIM_IMFLAGS_CUSTOMFEATURES | AIM_IMFLAGS_HASICON | AIM_IMFLAGS_MULTIPART);	return aim_im_sendch1_ext(od, &args);}/* * Subtype 0x0006 - Send a chat invitation. */int aim_im_sendch2_chatinvite(OscarData *od, const char *sn, const char *msg, guint16 exchange, const char *roomname, guint16 instance){	FlapConnection *conn;	FlapFrame *frame;	aim_snacid_t snacid;	IcbmCookie *msgcookie;	struct aim_invite_priv *priv;	guchar cookie[8];	GSList *outer_tlvlist = NULL, *inner_tlvlist = NULL;	ByteStream hdrbs;	if (!od || !(conn = flap_connection_findbygroup(od, 0x0004)))		return -EINVAL;	if (!sn || !msg || !roomname)		return -EINVAL;	aim_icbm_makecookie(cookie);	frame = flap_frame_new(od, 0x02, 1152+strlen(sn)+strlen(roomname)+strlen(msg));	snacid = aim_cachesnac(od, 0x0004, 0x0006, 0x0000, sn, strlen(sn)+1);	aim_putsnac(&frame->data, 0x0004, 0x0006, 0x0000, snacid);	/* XXX should be uncached by an unwritten 'invite accept' handler */	priv = g_malloc(sizeof(struct aim_invite_priv));	priv->sn = g_strdup(sn);	priv->roomname = g_strdup(roomname);	priv->exchange = exchange;	priv->instance = instance;	if ((msgcookie = aim_mkcookie(cookie, AIM_COOKIETYPE_INVITE, priv)))		aim_cachecookie(od, msgcookie);	else		g_free(priv);	/* ICBM Header */	aim_im_puticbm(&frame->data, cookie, 0x0002, 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.	 *	 */	byte_stream_new(&hdrbs, 2+8+16+6+4+4+strlen(msg)+4+2+1+strlen(roomname)+2);	byte_stream_put16(&hdrbs, 0x0000); /* Unknown! */	byte_stream_putraw(&hdrbs, cookie, sizeof(cookie)); /* I think... */	byte_stream_putcaps(&hdrbs, OSCAR_CAPABILITY_CHAT);	aim_tlvlist_add_16(&inner_tlvlist, 0x000a, 0x0001);	aim_tlvlist_add_noval(&inner_tlvlist, 0x000f);	aim_tlvlist_add_str(&inner_tlvlist, 0x000c, msg);	aim_tlvlist_add_chatroom(&inner_tlvlist, 0x2711, exchange, roomname, instance);	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);	return 0;}/** * Subtype 0x0006 - Send your icon to a given user. * * This is also performance sensitive. (If you can believe it...) * */int aim_im_sendch2_icon(OscarData *od, const char *sn, const guint8 *icon, int iconlen, time_t stamp, guint16 iconsum){	FlapConnection *conn;	FlapFrame *frame;	aim_snacid_t snacid;	guchar cookie[8];	if (!od || !(conn = flap_connection_findbygroup(od, 0x0004)))		return -EINVAL;	if (!sn || !icon || (iconlen <= 0) || (iconlen >= MAXICONLEN))		return -EINVAL;	aim_icbm_makecookie(cookie);	frame = flap_frame_new(od, 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);	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 everything below.	 */	byte_stream_put16(&frame->data, 0x0005);	byte_stream_put16(&frame->data, 2+8+16+6+4+4+iconlen+4+4+4+strlen(AIM_ICONIDENT));	byte_stream_put16(&frame->data, 0x0000);	byte_stream_putraw(&frame->data, cookie, 8);	byte_stream_putcaps(&frame->data, OSCAR_CAPABILITY_BUDDYICON);	/* 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, 4+4+4+iconlen+strlen(AIM_ICONIDENT));	byte_stream_put16(&frame->data, 0x0000);	byte_stream_put16(&frame->data, iconsum);	byte_stream_put32(&frame->data, iconlen);	byte_stream_put32(&frame->data, stamp);	byte_stream_putraw(&frame->data, icon, iconlen);	byte_stream_putstr(&frame->data, AIM_ICONIDENT);	/* 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 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. * */int aim_im_sendch2_rtfmsg(OscarData *od, struct aim_sendrtfmsg_args *args){	FlapConnection *conn;	FlapFrame *frame;	aim_snacid_t snacid;	guchar cookie[8];	const char rtfcap[] = {"{97B12751-243C-4334-AD22-D6ABF73F1492}"}; /* OSCAR_CAPABILITY_ICQRTF capability in string form */	int servdatalen;	if (!od || !(conn = flap_connection_findbygroup(od, 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;	aim_icbm_makecookie(cookie);	frame = flap_frame_new(od, 0x02, 10+128+servdatalen);	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, args->destsn);	/* TLV t(0005) - Encompasses everything below. */	byte_stream_put16(&frame->data, 0x0005);	byte_stream_put16(&frame->data, 2+8+16  +  2+2+2  +  2+2  +  2+2+servdatalen);	byte_stream_put16(&frame->data, 0x0000);	byte_stream_putraw(&frame->data, cookie, 8);	byte_stream_putcaps(&frame->data, OSCAR_CAPABILITY_ICQSERVERRELAY);	/* t(000a) l(0002) v(0001) */	byte_stream_put16(&frame->data, 0x000a);	byte_stream_put16(&frame->data, 0x0002);	byte_stream_put16(&frame->data, 0x0001);	/* t(000f) l(0000) v() */	byte_stream_put16(&frame->data, 0x000f);	byte_stream_put16(&frame->data, 0x0000);	/* Service Data TLV */	byte_stream_put16(&frame->data, 0x2711);	byte_stream_put16(&frame->data, servdatalen);	byte_stream_putle16(&frame->data, 11 + 16 /* 11 + (sizeof CLSID) */);	byte_stream_putle16(&frame->data, 9);	byte_stream_putcaps(&frame->data, OSCAR_CAPABILITY_EMPTY);	byte_stream_putle16(&frame->data, 0);	byte_stream_putle32(&frame->data, 0);	byte_stream_putle8(&frame->data, 0);	byte_stream_putle16(&frame->data, 0x03ea); /* trid1 */	byte_stream_putle16(&frame->data, 14);	byte_stream_putle16(&frame->data, 0x03eb); /* trid2 */	byte_stream_putle32(&frame->data, 0);	byte_stream_putle32(&frame->data, 0);	byte_stream_putle32(&frame->data, 0);	byte_stream_putle16(&frame->data, 0x0001);	byte_stream_putle32(&frame->data, 0);	byte_stream_putle16(&frame->data, strlen(args->rtfmsg)+1);	byte_stream_putraw(&frame->data, (const guint8 *)args->rtfmsg, strlen(args->rtfmsg)+1);	byte_stream_putle32(&frame->data, args->fgcolor);	byte_stream_putle32(&frame->data, args->bgcolor);	byte_stream_putle32(&frame->data, strlen(rtfcap)+1);	byte_stream_putraw(&frame->data, (const guint8 *)rtfcap, strlen(rtfcap)+1);	flap_connection_send(conn, frame);	return 0;}/** * Cancel a rendezvous invitation.  It could be an invitation to * establish a direct connection, or a file-send, or a chat invite. */voidaim_im_sendch2_cancel(PeerConnection *peer_conn){	OscarData *od;	FlapConnection *conn;	FlapFrame *frame;	aim_snacid_t snacid;	GSList *outer_tlvlist = NULL, *inner_tlvlist = NULL;	ByteStream hdrbs;	od = peer_conn->od;	conn = flap_connection_findbygroup(od, 0x0004);	if (conn == NULL)		return;	frame = flap_frame_new(od, 0x02, 128+strlen(peer_conn->sn));	snacid = aim_cachesnac(od, 0x0004, 0x0006, 0x0000, NULL, 0);	aim_putsnac(&frame->data, 0x0004, 0x0006, 0x0000, snacid);	/* ICBM header */	aim_im_puticbm(&frame->data, peer_conn->cookie, 0x0002, peer_conn->sn);	aim_tlvlist_add_noval(&outer_tlvlist, 0x0003);	byte_stream_new(&hdrbs, 64);	byte_stream_put16(&hdrbs, AIM_RENDEZVOUS_CANCEL);	byte_stream_putraw(&hdrbs, peer_conn->cookie, 8);	byte_stream_putcaps(&hdrbs, peer_conn->type);	/* This TLV means "cancel!" */	aim_tlvlist_add_16(&inner_tlvlist, 0x000b, 0x0001);	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 an "I accept and I've connected to * you" message. */voidaim_im_sendch2_connected(PeerConnection *peer_conn){	OscarData *od;	FlapConnection *conn;	FlapFrame *frame;	aim_snacid_t snacid;	od = peer_conn->od;	conn = flap_connection_findbygroup(od, 0x0004);	if (conn == NULL)		return;	frame = flap_frame_new(od, 0x02, 10 + 11+strlen(peer_conn->sn) + 4+2+8+16);	snacid = aim_cachesnac(od, 0x0004, 0x0006, 0x0000, NULL, 0);	aim_putsnac(&frame->data, 0x0004, 0x0006, 0x0000, snacid);	/* ICBM header */	aim_im_puticbm(&frame->data, peer_conn->cookie, 0x0002, peer_conn->sn);	byte_stream_put16(&frame->data, 0x0005);	byte_stream_put16(&frame->data, 0x001a);	byte_stream_put16(&frame->data, AIM_RENDEZVOUS_CONNECTED);	byte_stream_putraw(&frame->data, peer_conn->cookie, 8);	byte_stream_putcaps(&frame->data, peer_conn->type);	flap_connection_send(conn, frame);}/** * Subtype 0x0006 - Send a direct connect rendezvous ICBM.  This * could have a number of meanings, depending on the content: * "I want you to connect to me" * "I want to connect to you" * "I want to connect through a proxy server" */voidaim_im_sendch2_odc_requestdirect(OscarData *od, guchar *cookie, const char *sn, const guint8 *ip, guint16 port, guint16 requestnumber){	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, 256+strlen(sn));	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, 128);	byte_stream_put16(&hdrbs, AIM_RENDEZVOUS_PROPOSE);	byte_stream_putraw(&hdrbs, cookie, 8);	byte_stream_putcaps(&hdrbs, OSCAR_CAPABILITY_DIRECTIM);	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);	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 direct connect rendezvous ICBM asking the * remote user to connect to us via a proxy server. */voidaim_im_sendch2_odc_requestproxy(OscarData *od, guchar *cookie, const char *sn, const guint8 *ip, guint16 pin, guint16 requestnumber){	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, 256+strlen(sn));	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, 128);	byte_stream_put16(&hdrbs, AIM_RENDEZVOUS_PROPOSE);	byte_stream_putraw(&hdrbs, cookie, 8);	byte_stream_putcaps(&hdrbs, OSCAR_CAPABILITY_DIRECTIM);	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);	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);

⌨️ 快捷键说明

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