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

📄 service.c

📁 oscar message protocol stack
💻 C
📖 第 1 页 / 共 3 页
字号:
	/*	 * Finally, tell the client it's ready to go...	 */	if ((userfunc = aim_callhandler(sess, rx->conn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNINITDONE)))		userfunc(sess, rx);	return 1;}/* Subtype 0x0008 - Add Rate Parameter */faim_internal int aim_rates_addparam(aim_session_t *sess, aim_conn_t *conn){	aim_conn_inside_t *ins = (aim_conn_inside_t *)conn->inside;	aim_frame_t *fr;		aim_snacid_t snacid;	struct rateclass *rc;	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 512)))		return -ENOMEM; 	snacid = aim_cachesnac(sess, 0x0001, 0x0008, 0x0000, NULL, 0);	aim_putsnac(&fr->data, 0x0001, 0x0008, 0x0000, snacid);	for (rc = ins->rates; rc; rc = rc->next)		aimbs_put16(&fr->data, rc->classid);	aim_tx_enqueue(sess, fr);	return 0;}/* Subtype 0x0009 - Delete Rate Parameter */faim_internal int aim_rates_delparam(aim_session_t *sess, aim_conn_t *conn){	aim_conn_inside_t *ins = (aim_conn_inside_t *)conn->inside;	aim_frame_t *fr;		aim_snacid_t snacid;	struct rateclass *rc;	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 512)))		return -ENOMEM; 	snacid = aim_cachesnac(sess, 0x0001, 0x0009, 0x0000, NULL, 0);	aim_putsnac(&fr->data, 0x0001, 0x0009, 0x0000, snacid);	for (rc = ins->rates; rc; rc = rc->next)		aimbs_put16(&fr->data, rc->classid);	aim_tx_enqueue(sess, fr);	return 0;}/* Subtype 0x000a - Rate Change */static int ratechange(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs){	int ret = 0;	aim_rxcallback_t userfunc;	fu16_t code, rateclass;	fu32_t currentavg, maxavg, windowsize, clear, alert, limit, disconnect;	code = aimbs_get16(bs);	rateclass = aimbs_get16(bs);		windowsize = aimbs_get32(bs);	clear = aimbs_get32(bs);	alert = aimbs_get32(bs);	limit = aimbs_get32(bs);	disconnect = aimbs_get32(bs);	currentavg = aimbs_get32(bs);	maxavg = aimbs_get32(bs);	if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))		ret = userfunc(sess, rx, code, rateclass, windowsize, clear, alert, limit, disconnect, currentavg, maxavg);	return ret;}/* * How Migrations work. * * The server sends a Server Pause message, which the client should respond to  * with a Server Pause Ack, which contains the families it needs on this  * connection. The server will send a Migration Notice with an IP address, and  * then disconnect. Next the client should open the connection and send the  * cookie.  Repeat the normal login process and pretend this never happened. * * The Server Pause contains no data. * *//* Subtype 0x000b - Service Pause */static int serverpause(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs){	int ret = 0;	aim_rxcallback_t userfunc;	if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))		ret = userfunc(sess, rx);	return ret;}/* * Subtype 0x000c - Service Pause Acknowledgement * * It is rather important that aim_sendpauseack() gets called for the exact * same connection that the Server Pause callback was called for, since * libfaim extracts the data for the SNAC from the connection structure. * * Of course, if you don't do that, more bad things happen than just what * libfaim can cause. * */faim_export int aim_sendpauseack(aim_session_t *sess, aim_conn_t *conn){	aim_frame_t *fr;	aim_snacid_t snacid;	aim_conn_inside_t *ins = (aim_conn_inside_t *)conn->inside;	struct snacgroup *sg;	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 1024)))		return -ENOMEM;	snacid = aim_cachesnac(sess, 0x0001, 0x000c, 0x0000, NULL, 0);	aim_putsnac(&fr->data, 0x0001, 0x000c, 0x0000, snacid);	/*	 * This list should have all the groups that the original 	 * Host Online / Server Ready said this host supports.  And 	 * we want them all back after the migration.	 */	for (sg = ins->groups; sg; sg = sg->next)		aimbs_put16(&fr->data, sg->group);	aim_tx_enqueue(sess, fr);	return 0;}/* Subtype 0x000d - Service Resume */static int serverresume(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs){	int ret = 0;	aim_rxcallback_t userfunc;	if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))		ret = userfunc(sess, rx);	return ret;}/* Subtype 0x000e - Request self-info */faim_export int aim_reqpersonalinfo(aim_session_t *sess, aim_conn_t *conn){	return aim_genericreq_n_snacid(sess, conn, 0x0001, 0x000e);}/* Subtype 0x000f - Self User Info */static int selfinfo(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs){	int ret = 0;	aim_rxcallback_t userfunc;	aim_userinfo_t userinfo;	aim_info_extract(sess, bs, &userinfo);	if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))		ret = userfunc(sess, rx, &userinfo);	aim_info_free(&userinfo);	return ret;}/* Subtype 0x0010 - Evil Notification */static int evilnotify(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs){	int ret = 0;	aim_rxcallback_t userfunc;	fu16_t newevil;	aim_userinfo_t userinfo;	memset(&userinfo, 0, sizeof(aim_userinfo_t));		newevil = aimbs_get16(bs);	if (aim_bstream_empty(bs))		aim_info_extract(sess, bs, &userinfo);	if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))		ret = userfunc(sess, rx, newevil, &userinfo);	aim_info_free(&userinfo);	return ret;}/* * Subtype 0x0011 - Idle Notification * * Should set your current idle time in seconds.  Note that this should * never be called consecutively with a non-zero idle time.  That makes * OSCAR do funny things.  Instead, just set it once you go idle, and then * call it again with zero when you're back. * */faim_export int aim_srv_setidle(aim_session_t *sess, fu32_t idletime){	aim_conn_t *conn;	if (!sess || !(conn = aim_conn_findbygroup(sess, AIM_CB_FAM_BOS)))		return -EINVAL;	return aim_genericreq_l(sess, conn, 0x0001, 0x0011, &idletime);}/* * Subtype 0x0012 - Service Migrate * * This is the final SNAC sent on the original connection during a migration. * It contains the IP and cookie used to connect to the new server, and  * optionally a list of the SNAC groups being migrated. * */static int migrate(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs){	aim_rxcallback_t userfunc;	int ret = 0;	fu16_t groupcount, i;	aim_tlvlist_t *tl;	char *ip = NULL;	aim_tlv_t *cktlv;	/*	 * Apparently there's some fun stuff that can happen right here. The	 * migration can actually be quite selective about what groups it	 * moves to the new server.  When not all the groups for a connection	 * are migrated, or they are all migrated but some groups are moved	 * to a different server than others, it is called a bifurcated 	 * migration.	 *	 * Let's play dumb and not support that.	 *	 */	groupcount = aimbs_get16(bs);	for (i = 0; i < groupcount; i++) {		fu16_t group;		group = aimbs_get16(bs);		faimdprintf(sess, 0, "bifurcated migration unsupported -- group 0x%04x\n", group);	}	tl = aim_tlvlist_read(bs);	if (aim_tlv_gettlv(tl, 0x0005, 1))		ip = aim_tlv_getstr(tl, 0x0005, 1);	cktlv = aim_tlv_gettlv(tl, 0x0006, 1);	if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))		ret = userfunc(sess, rx, ip, cktlv ? cktlv->value : NULL);	aim_tlvlist_free(&tl);	free(ip);	return ret;}/* Subtype 0x0013 - Message of the Day */static int motd(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs){	aim_rxcallback_t userfunc;	char *msg = NULL;	int ret = 0;	aim_tlvlist_t *tlvlist;	fu16_t id;	/*	 * Code.	 *	 * Valid values:	 *   1 Mandatory upgrade	 *   2 Advisory upgrade	 *   3 System bulletin	 *   4 Nothing's wrong ("top o the world" -- normal)	 *   5 Lets-break-something. 	 *	 */	id = aimbs_get16(bs);	/* 	 * TLVs follow 	 */	tlvlist = aim_tlvlist_read(bs);	msg = aim_tlv_getstr(tlvlist, 0x000b, 1);	if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))		ret = userfunc(sess, rx, id, msg);	free(msg);	aim_tlvlist_free(&tlvlist);	return ret;}/*  * Subtype 0x0014 - Set privacy flags * * Normally 0x03. * *  Bit 1:  Allows other AIM users to see how long you've been idle. *  Bit 2:  Allows other AIM users to see how long you've been a member. * */faim_export int aim_bos_setprivacyflags(aim_session_t *sess, aim_conn_t *conn, fu32_t flags){	return aim_genericreq_l(sess, conn, 0x0001, 0x0014, &flags);}/* * Subtype 0x0016 - No-op * * WinAIM sends these every 4min or so to keep the connection alive.  Its not  * really necessary. * * Wha?  No?  Since when?  I think WinAIM sends an empty channel 3  * SNAC as a no-op... */faim_export int aim_nop(aim_session_t *sess, aim_conn_t *conn){	return aim_genericreq_n(sess, conn, 0x0001, 0x0016);}/*  * Subtype 0x0017 - Set client versions * * If you've seen the clientonline/clientready SNAC you're probably  * wondering what the point of this one is.  And that point seems to be * that the versions in the client online SNAC are sent too late for the * server to be able to use them to change the protocol for the earlier * login packets (client versions are sent right after Host Online is  * received, but client online versions aren't sent until quite a bit later). * We can see them already making use of this by changing the format of * the rate information based on what version of group 1 we advertise here. * */faim_internal int aim_setversions(aim_session_t *sess, aim_conn_t *conn){	aim_conn_inside_t *ins = (aim_conn_inside_t *)conn->inside;	struct snacgroup *sg;	aim_frame_t *fr;	aim_snacid_t snacid;	if (!ins)		return -EINVAL;	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 1152)))		return -ENOMEM;	snacid = aim_cachesnac(sess, 0x0001, 0x0017, 0x0000, NULL, 0);	aim_putsnac(&fr->data, 0x0001, 0x0017, 0x0000, snacid);	/*	 * Send only the versions that the server cares about (that it	 * marked as supporting in the server ready SNAC).  	 */	for (sg = ins->groups; sg; sg = sg->next) {		aim_module_t *mod;		if ((mod = aim__findmodulebygroup(sess, sg->group))) {			aimbs_put16(&fr->data, mod->family);

⌨️ 快捷键说明

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