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

📄 family_oservice.c

📁 Linux下的多协议即时通讯程序源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * Purple's oscar protocol plugin * This file is the legal property of its developers. * Please see the AUTHORS file distributed alongside this file. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA*//* * Family 0x0001 - This is a very special group.  All connections support * this group, as it does some particularly good things (like rate limiting). */#include "oscar.h"#include "cipher.h"/* Subtype 0x0002 - Client Online */voidaim_clientready(OscarData *od, FlapConnection *conn){	FlapFrame *frame;	aim_snacid_t snacid;	GSList *cur;	frame = flap_frame_new(od, 0x02, 1152);	snacid = aim_cachesnac(od, 0x0001, 0x0002, 0x0000, NULL, 0);	aim_putsnac(&frame->data, 0x0001, 0x0002, 0x0000, snacid);	/*	 * Send only the tool versions that the server cares about (that it	 * marked as supporting in the server ready SNAC).	 */	for (cur = conn->groups; cur != NULL; cur = cur->next)	{		aim_module_t *mod;		if ((mod = aim__findmodulebygroup(od, GPOINTER_TO_UINT(cur->data))))		{			byte_stream_put16(&frame->data, mod->family);			byte_stream_put16(&frame->data, mod->version);			byte_stream_put16(&frame->data, mod->toolid);			byte_stream_put16(&frame->data, mod->toolversion);		}	}	flap_connection_send(conn, frame);}/* * Subtype 0x0003 - Host Online * * See comments in conn.c about how the group associations are supposed * to work, and how they really work. * * This info probably doesn't even need to make it to the client. * * We don't actually call the client here.  This starts off the connection * initialization routine required by all AIM connections.  The next time * the client is called is the CONNINITDONE callback, which should be * shortly after the rate information is acknowledged. * */static inthostonline(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *frame, aim_modsnac_t *snac, ByteStream *bs){	int group;	while (byte_stream_empty(bs))	{		group = byte_stream_get16(bs);		conn->groups = g_slist_prepend(conn->groups, GUINT_TO_POINTER(group));	}	/*	 * Next step is in the Host Versions handler.	 *	 * Note that we must send this before we request rates, since	 * the format of the rate information depends on the versions we	 * give it.	 *	 */	aim_srv_setversions(od, conn);	return 1;}/* Subtype 0x0004 - Service request */voidaim_srv_requestnew(OscarData *od, guint16 serviceid){	FlapConnection *conn;	conn = flap_connection_findbygroup(od, SNAC_FAMILY_BOS);	if(!conn)		return;	aim_genericreq_s(od, conn, 0x0001, 0x0004, &serviceid);}/* * 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. */intaim_chat_join(OscarData *od, guint16 exchange, const char *roomname, guint16 instance){	FlapConnection *conn;	FlapFrame *frame;	aim_snacid_t snacid;	GSList *tlvlist = NULL;	struct chatsnacinfo csi;	conn = flap_connection_findbygroup(od, SNAC_FAMILY_BOS);	if (!conn || !roomname || !strlen(roomname))		return -EINVAL;	frame = flap_frame_new(od, 0x02, 512);	memset(&csi, 0, sizeof(csi));	csi.exchange = exchange;	strncpy(csi.name, roomname, sizeof(csi.name));	csi.instance = instance;	snacid = aim_cachesnac(od, 0x0001, 0x0004, 0x0000, &csi, sizeof(csi));	aim_putsnac(&frame->data, 0x0001, 0x0004, 0x0000, snacid);	/*	 * Requesting service chat (0x000e)	 */	byte_stream_put16(&frame->data, 0x000e);	aim_tlvlist_add_chatroom(&tlvlist, 0x0001, exchange, roomname, instance);	aim_tlvlist_write(&frame->data, &tlvlist);	aim_tlvlist_free(tlvlist);	flap_connection_send(conn, frame);	return 0;}/* Subtype 0x0005 - Redirect */static intredirect(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *frame, aim_modsnac_t *snac, ByteStream *bs){	struct aim_redirect_data redir;	aim_rxcallback_t userfunc;	GSList *tlvlist;	aim_snac_t *origsnac = NULL;	int ret = 0;	memset(&redir, 0, sizeof(redir));	tlvlist = aim_tlvlist_read(bs);	if (!aim_tlv_gettlv(tlvlist, 0x000d, 1) ||			!aim_tlv_gettlv(tlvlist, 0x0005, 1) ||			!aim_tlv_gettlv(tlvlist, 0x0006, 1)) {		aim_tlvlist_free(tlvlist);		return 0;	}	redir.group = aim_tlv_get16(tlvlist, 0x000d, 1);	redir.ip = aim_tlv_getstr(tlvlist, 0x0005, 1);	redir.cookielen = aim_tlv_gettlv(tlvlist, 0x0006, 1)->length;	redir.cookie = (guchar *)aim_tlv_getstr(tlvlist, 0x0006, 1);	/* Fetch original SNAC so we can get csi if needed */	origsnac = aim_remsnac(od, snac->id);	if ((redir.group == SNAC_FAMILY_CHAT) && origsnac) {		struct chatsnacinfo *csi = (struct chatsnacinfo *)origsnac->data;		redir.chat.exchange = csi->exchange;		redir.chat.room = csi->name;		redir.chat.instance = csi->instance;	}	if ((userfunc = aim_callhandler(od, snac->family, snac->subtype)))		ret = userfunc(od, conn, frame, &redir);	g_free((void *)redir.ip);	g_free((void *)redir.cookie);	if (origsnac)		g_free(origsnac->data);	g_free(origsnac);	aim_tlvlist_free(tlvlist);	return ret;}/* Subtype 0x0006 - Request Rate Information. */voidaim_srv_reqrates(OscarData *od, FlapConnection *conn){	aim_genericreq_n_snacid(od, conn, 0x0001, 0x0006);}/* * OSCAR defines several 'rate classes'.  Each class has separate * rate limiting properties (limit level, alert level, disconnect * level, etc), and a set of SNAC family/type pairs associated with * it.  The rate classes, their limiting properties, and the definitions * of which SNACs belong to which class are defined in the * Rate Response packet at login to each host. * * Logically, all rate offenses within one class count against further * offenses for other SNACs in the same class (ie, sending messages * too fast will limit the number of user info requests you can send, * since those two SNACs are in the same rate class). * * Since the rate classes are defined dynamically at login, the values * below may change. But they seem to be fairly constant. * * Currently, BOS defines five rate classes, with the commonly used * members as follows... * *  Rate class 0x0001: *	- Everything thats not in any of the other classes * *  Rate class 0x0002: *	- Buddy list add/remove *	- Permit list add/remove *	- Deny list add/remove * *  Rate class 0x0003: *	- User information requests *	- Outgoing ICBMs * *  Rate class 0x0004: *	- A few unknowns: 2/9, 2/b, and f/2 * *  Rate class 0x0005: *	- Chat room create *	- Outgoing chat ICBMs * * The only other thing of note is that class 5 (chat) has slightly looser * limiting properties than class 3 (normal messages).  But thats just a * small bit of trivia for you. * * The last thing that needs to be learned about the rate limiting * system is how the actual numbers relate to the passing of time.  This * seems to be a big mystery. * * See joscar's javadoc for the RateClassInfo class for a great * explanation.  You might be able to find it at * http://dscoder.com/RateClassInfo.html */static struct rateclass *rateclass_find(GSList *rateclasses, guint16 id){	GSList *tmp;	for (tmp = rateclasses; tmp != NULL; tmp = tmp->next)	{		struct rateclass *rateclass;		rateclass = tmp->data;		if (rateclass->classid == id)			return rateclass;	}	return NULL;}/* Subtype 0x0007 - Rate Parameters */static intrateresp(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *frame, aim_modsnac_t *snac, ByteStream *bs){	guint16 numclasses, i;	aim_rxcallback_t userfunc;	/*	 * First are the parameters for each rate class.	 */	numclasses = byte_stream_get16(bs);	for (i = 0; i < numclasses; i++)	{		struct rateclass *rateclass;		rateclass = g_new0(struct rateclass, 1);		rateclass->classid = byte_stream_get16(bs);		rateclass->windowsize = byte_stream_get32(bs);		rateclass->clear = byte_stream_get32(bs);		rateclass->alert = byte_stream_get32(bs);		rateclass->limit = byte_stream_get32(bs);		rateclass->disconnect = byte_stream_get32(bs);		rateclass->current = byte_stream_get32(bs);		rateclass->max = byte_stream_get32(bs);		/*		 * The server will send an extra five bytes of parameters		 * depending on the version we advertised in 1/17.  If we		 * didn't send 1/17 (evil!), then this will crash and you		 * die, as it will default to the old version but we have		 * the new version hardcoded here.		 */		if (mod->version >= 3)			byte_stream_getrawbuf(bs, rateclass->unknown, sizeof(rateclass->unknown));		rateclass->members = g_hash_table_new(g_direct_hash, g_direct_equal);		rateclass->last.tv_sec = 0;		rateclass->last.tv_usec = 0;		conn->rateclasses = g_slist_prepend(conn->rateclasses, rateclass);	}	conn->rateclasses = g_slist_reverse(conn->rateclasses);	/*	 * Then the members of each class.	 */	for (i = 0; i < numclasses; i++)	{		guint16 classid, count;		struct rateclass *rateclass;		int j;		classid = byte_stream_get16(bs);		count = byte_stream_get16(bs);		rateclass = rateclass_find(conn->rateclasses, classid);		for (j = 0; j < count; j++)		{			guint16 group, subtype;			group = byte_stream_get16(bs);			subtype = byte_stream_get16(bs);			if (rateclass != NULL)				g_hash_table_insert(rateclass->members,						GUINT_TO_POINTER((group << 16) + subtype),						GUINT_TO_POINTER(TRUE));		}	}	/*	 * We don't pass the rate information up to the client, as it really	 * doesn't care.  The information is stored in the connection, however	 * so that we can do rate limiting management when sending SNACs.	 */	/*	 * Last step in the conn init procedure is to acknowledge that we	 * agree to these draconian limitations.	 */	aim_srv_rates_addparam(od, conn);	/*	 * Finally, tell the client it's ready to go...	 */	if ((userfunc = aim_callhandler(od, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNINITDONE)))		userfunc(od, conn, frame);

⌨️ 快捷键说明

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