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

📄 locate.c

📁 oscar message protocol stack
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * Family 0x0002 - Locate. * * The functions here are responsible for requesting and parsing information- * gathering SNACs.  Or something like that.  This family contains the SNACs  * for getting and setting info, away messages, directory profile thingy, etc. */#define FAIM_INTERNAL#include <aim.h>#ifdef _WIN32#include "win32dep.h"#endif/* * Capability blocks.  * * These are CLSIDs. They should actually be of the form: * * {0x0946134b, 0x4c7f, 0x11d1, *  {0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}}, * * But, eh. */static const struct {	fu32_t flag;	fu8_t data[16];} aim_caps[] = {	/*	 * These are in ascending numerical order.	 */	/*	 * Perhaps better called AIM_CAPS_SHORTCAPS	 */	{AIM_CAPS_ICHAT,	 {0x09, 0x46, 0x00, 0x00, 0x4c, 0x7f, 0x11, 0xd1, 	  0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}},	{AIM_CAPS_SECUREIM,	 {0x09, 0x46, 0x00, 0x01, 0x4c, 0x7f, 0x11, 0xd1, 	  0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}},	{AIM_CAPS_VIDEO,	 {0x09, 0x46, 0x01, 0x00, 0x4c, 0x7f, 0x11, 0xd1, 	  0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}},	/* "Live Video" support in Windows AIM 5.5.3501 and newer */	{AIM_CAPS_LIVEVIDEO,	 {0x09, 0x46, 0x01, 0x01, 0x4c, 0x7f, 0x11, 0xd1, 	  0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}},	/* "Camera" support in Windows AIM 5.5.3501 and newer */	{AIM_CAPS_CAMERA,	 {0x09, 0x46, 0x01, 0x02, 0x4c, 0x7f, 0x11, 0xd1, 	  0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}},	/* In Windows AIM 5.5.3501 and newer */	{AIM_CAPS_GENERICUNKNOWN,	 {0x09, 0x46, 0x01, 0x03, 0x4c, 0x7f, 0x11, 0xd1, 	  0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}},	/* In iChatAV (version numbers...?) */	{AIM_CAPS_ICHATAV,	 {0x09, 0x46, 0x01, 0x05, 0x4c, 0x7f, 0x11, 0xd1, 	  0x82, 0x22, 0x44, 0x45, 0x45, 0x53, 0x54, 0x00}},	/*	 * Not really sure about this one.  In an email from 	 * 26 Sep 2003, Matthew Sachs suggested that, "this 	 * is probably the capability for the SMS features."	 */	{AIM_CAPS_SMS,	 {0x09, 0x46, 0x01, 0xff, 0x4c, 0x7f, 0x11, 0xd1, 	  0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}},	{AIM_CAPS_GENERICUNKNOWN,	 {0x09, 0x46, 0xf0, 0x03, 0x4c, 0x7f, 0x11, 0xd1, 	  0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}},	{AIM_CAPS_GENERICUNKNOWN,	 {0x09, 0x46, 0xf0, 0x04, 0x4c, 0x7f, 0x11, 0xd1, 	  0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}},	{AIM_CAPS_GENERICUNKNOWN,	 {0x09, 0x46, 0xf0, 0x05, 0x4c, 0x7f, 0x11, 0xd1, 	  0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}},	{AIM_CAPS_HIPTOP,	 {0x09, 0x46, 0x13, 0x23, 0x4c, 0x7f, 0x11, 0xd1, 	  0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}},	{AIM_CAPS_TALK,	 {0x09, 0x46, 0x13, 0x41, 0x4c, 0x7f, 0x11, 0xd1, 	  0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}},	{AIM_CAPS_SENDFILE,	 {0x09, 0x46, 0x13, 0x43, 0x4c, 0x7f, 0x11, 0xd1, 	  0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}},	{AIM_CAPS_ICQ_DIRECT,	 {0x09, 0x46, 0x13, 0x44, 0x4c, 0x7f, 0x11, 0xd1, 	  0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}},	{AIM_CAPS_DIRECTIM,	 {0x09, 0x46, 0x13, 0x45, 0x4c, 0x7f, 0x11, 0xd1, 	  0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}},	{AIM_CAPS_BUDDYICON,	 {0x09, 0x46, 0x13, 0x46, 0x4c, 0x7f, 0x11, 0xd1, 	  0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}},	{AIM_CAPS_ADDINS,	 {0x09, 0x46, 0x13, 0x47, 0x4c, 0x7f, 0x11, 0xd1,	  0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}},	{AIM_CAPS_GETFILE,	 {0x09, 0x46, 0x13, 0x48, 0x4c, 0x7f, 0x11, 0xd1,	  0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}},	{AIM_CAPS_ICQSERVERRELAY,	 {0x09, 0x46, 0x13, 0x49, 0x4c, 0x7f, 0x11, 0xd1,	  0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}},	/*	 * Indeed, there are two of these.  The former appears to be correct, 	 * but in some versions of winaim, the second one is set.  Either they 	 * forgot to fix endianness, or they made a typo. It really doesn't 	 * matter which.	 */	{AIM_CAPS_GAMES,	 {0x09, 0x46, 0x13, 0x4a, 0x4c, 0x7f, 0x11, 0xd1,	  0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}},	{AIM_CAPS_GAMES2,	 {0x09, 0x46, 0x13, 0x4a, 0x4c, 0x7f, 0x11, 0xd1,	  0x22, 0x82, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}},	{AIM_CAPS_SENDBUDDYLIST,	 {0x09, 0x46, 0x13, 0x4b, 0x4c, 0x7f, 0x11, 0xd1,	  0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}},	/*	 * Setting this lets AIM users receive messages from ICQ users, and ICQ 	 * users receive messages from AIM users.  It also lets ICQ users show 	 * up in buddy lists for AIM users, and AIM users show up in buddy lists 	 * for ICQ users.  And ICQ privacy/invisibility acts like AIM privacy, 	 * in that if you add a user to your deny list, you will not be able to 	 * see them as online (previous you could still see them, but they 	 * couldn't see you.	 */	{AIM_CAPS_INTEROPERATE,	 {0x09, 0x46, 0x13, 0x4d, 0x4c, 0x7f, 0x11, 0xd1,	  0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}},	{AIM_CAPS_ICQUTF8,	 {0x09, 0x46, 0x13, 0x4e, 0x4c, 0x7f, 0x11, 0xd1,	  0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}},	{AIM_CAPS_ICQUTF8OLD,	 {0x2e, 0x7a, 0x64, 0x75, 0xfa, 0xdf, 0x4d, 0xc8,	  0x88, 0x6f, 0xea, 0x35, 0x95, 0xfd, 0xb6, 0xdf}},	/*	 * Chat is oddball.	 */	{AIM_CAPS_CHAT,	 {0x74, 0x8f, 0x24, 0x20, 0x62, 0x87, 0x11, 0xd1, 	  0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}},	/*	{AIM_CAPS_ICQ2GO,	 {0x56, 0x3f, 0xc8, 0x09, 0x0b, 0x6f, 0x41, 0xbd,	  0x9f, 0x79, 0x42, 0x26, 0x09, 0xdf, 0xa2, 0xf3}},	*/	{AIM_CAPS_ICQRTF,	 {0x97, 0xb1, 0x27, 0x51, 0x24, 0x3c, 0x43, 0x34,	  0xad, 0x22, 0xd6, 0xab, 0xf7, 0x3f, 0x14, 0x92}},	/* This is added by the servers and it only shows up for ourselves... */	{AIM_CAPS_GENERICUNKNOWN,	 {0x97, 0xb1, 0x27, 0x51, 0x24, 0x3c, 0x43, 0x34, 	  0xad, 0x22, 0xd6, 0xab, 0xf7, 0x3f, 0x14, 0x09}},	{AIM_CAPS_APINFO, 	 {0xaa, 0x4a, 0x32, 0xb5, 0xf8, 0x84, 0x48, 0xc6,	  0xa3, 0xd7, 0x8c, 0x50, 0x97, 0x19, 0xfd, 0x5b}},	{AIM_CAPS_TRILLIANCRYPT,	 {0xf2, 0xe7, 0xc7, 0xf4, 0xfe, 0xad, 0x4d, 0xfb,	  0xb2, 0x35, 0x36, 0x79, 0x8b, 0xdf, 0x00, 0x00}},	{AIM_CAPS_EMPTY,	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},	{AIM_CAPS_LAST}};/* * Add the userinfo to our linked list.  If we already have userinfo  * for this buddy, then just overwrite parts of the old data. * @param userinfo Contains the new information for the buddy. */static void aim_locate_adduserinfo(aim_session_t *sess, aim_userinfo_t *userinfo) {	aim_userinfo_t *cur;	cur = aim_locate_finduserinfo(sess, userinfo->sn);	if (cur == NULL) {		cur = (aim_userinfo_t *)calloc(1, sizeof(aim_userinfo_t));		cur->sn = strdup(userinfo->sn);		cur->next = sess->locate.userinfo;		sess->locate.userinfo = cur;	}	cur->warnlevel = userinfo->warnlevel;	cur->idletime = userinfo->idletime;	if (userinfo->flags != 0)		cur->flags = userinfo->flags;	if (userinfo->createtime != 0)		cur->createtime = userinfo->createtime;	if (userinfo->membersince != 0)		cur->membersince = userinfo->membersince;	if (userinfo->onlinesince != 0)		cur->onlinesince = userinfo->onlinesince;	if (userinfo->sessionlen != 0)		cur->sessionlen = userinfo->sessionlen;	if (userinfo->capabilities != 0)		cur->capabilities = userinfo->capabilities;	cur->present |= userinfo->present;	if (userinfo->iconcsumlen > 0) {		free(cur->iconcsum);		cur->iconcsum = (fu8_t *)malloc(userinfo->iconcsumlen);		memcpy(cur->iconcsum, userinfo->iconcsum, userinfo->iconcsumlen);		cur->iconcsumlen = userinfo->iconcsumlen;	}	if (userinfo->info != NULL) {		free(cur->info);		free(cur->info_encoding);		if (userinfo->info_len > 0) {			cur->info = (char *)malloc(userinfo->info_len);			memcpy(cur->info, userinfo->info, userinfo->info_len);		} else			cur->info = NULL;		cur->info_encoding = strdup(userinfo->info_encoding);		cur->info_len = userinfo->info_len;	}	if (userinfo->away != NULL) {		free(cur->away);		free(cur->away_encoding);		if (userinfo->away_len > 0) {			cur->away = (char *)malloc(userinfo->away_len);			memcpy(cur->away, userinfo->away, userinfo->away_len);		} else			cur->away = NULL;		cur->away_encoding = strdup(userinfo->away_encoding);		cur->away_len = userinfo->away_len;	}}faim_export void aim_locate_dorequest(aim_session_t *sess) {	struct userinfo_node *cur = sess->locate.torequest;	if (cur == NULL)		return;	if (sess->locate.waiting_for_response == TRUE)		return;	sess->locate.waiting_for_response = TRUE;	aim_locate_getinfoshort(sess, cur->sn, 0x00000003);	/* Move this node to the "requested" queue */	sess->locate.torequest = cur->next;	cur->next = sess->locate.requested;	sess->locate.requested = cur;}/** * Remove this screen name from our queue.  If this info was requested  * by our info request queue, then pop the next element off of the queue. * * @param sess The aim session. * @param sn Screen name of the info we just received. * @return True if the request was explicit (client requested the info),  *         false if the request was implicit (libfaim request the info). */static int aim_locate_gotuserinfo(aim_session_t *sess, const char *sn) {	struct userinfo_node *cur, *del;	int was_explicit = TRUE;	while ((sess->locate.requested != NULL) && (aim_sncmp(sn, sess->locate.requested->sn) == 0)) {		del = sess->locate.requested;		sess->locate.requested = del->next;		was_explicit = FALSE;		free(del->sn);		free(del);	}	cur = sess->locate.requested;	while ((cur != NULL) && (cur->next != NULL)) {		if (aim_sncmp(sn, cur->next->sn) == 0) {			del = cur->next;			cur->next = del->next;			was_explicit = FALSE;			free(del->sn);			free(del);		} else			cur = cur->next;	}	if (!was_explicit) {		aim_conn_t *conn = aim_conn_findbygroup(sess, AIM_CB_FAM_LOC);		aim_rxcallback_t userfunc;		sess->locate.waiting_for_response = FALSE;		if ((userfunc = aim_callhandler(sess, conn, AIM_CB_FAM_LOC, AIM_CB_LOC_REQUESTINFOTIMEOUT)))			userfunc(sess, NULL);		else			aim_locate_dorequest(sess);	}	return was_explicit;}faim_internal void aim_locate_requestuserinfo(aim_session_t *sess, const char *sn) {	struct userinfo_node *cur;	/* Make sure we aren't already requesting info for this buddy */	cur = sess->locate.torequest;	while (cur != NULL) {		if (aim_sncmp(sn, cur->sn) == 0)			return;		cur = cur->next;	}	/* Add a new node to our request queue */	cur = (struct userinfo_node *)malloc(sizeof(struct userinfo_node));	cur->sn = strdup(sn);	cur->next = sess->locate.torequest;	sess->locate.torequest = cur;	/* Actually request some info up in this piece */	aim_locate_dorequest(sess);}faim_export aim_userinfo_t *aim_locate_finduserinfo(aim_session_t *sess, const char *sn) {	aim_userinfo_t *cur = NULL;	if ( sn == NULL )		return NULL;		cur = sess->locate.userinfo;	while (cur != NULL) {		if (aim_sncmp(cur->sn, sn) == 0)			return cur;		cur = cur->next;	}	return NULL;}faim_internal fu32_t aim_locate_getcaps(aim_session_t *sess, aim_bstream_t *bs, int len){	fu32_t flags = 0;	int offset;	for (offset = 0; aim_bstream_empty(bs) && (offset < len); offset += 0x10) {		fu8_t *cap;		int i, identified;		cap = aimbs_getraw(bs, 0x10);		for (i = 0, identified = 0; !(aim_caps[i].flag & AIM_CAPS_LAST); i++) {			if (memcmp(&aim_caps[i].data, cap, 0x10) == 0) {				flags |= aim_caps[i].flag;				identified++;				break; /* should only match once... */			}		}		if (!identified)			faimdprintf(sess, 0, "unknown capability: {%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x}\n",					cap[0], cap[1], cap[2], cap[3],					cap[4], cap[5],					cap[6], cap[7],					cap[8], cap[9],					cap[10], cap[11], cap[12], cap[13],					cap[14], cap[15]);		free(cap);	}	return flags;}faim_internal fu32_t aim_locate_getcaps_short(aim_session_t *sess, aim_bstream_t *bs, int len){	fu32_t flags = 0;	int offset;	for (offset = 0; aim_bstream_empty(bs) && (offset < len); offset += 0x02) {		fu8_t *cap;		int i, identified;		cap = aimbs_getraw(bs, 0x02);		for (i = 0, identified = 0; !(aim_caps[i].flag & AIM_CAPS_LAST); i++) {			if (memcmp(&aim_caps[i].data[2], cap, 0x02) == 0) {				flags |= aim_caps[i].flag;				identified++;				break; /* should only match once... */			}		}		if (!identified)			faimdprintf(sess, 0, "unknown short capability: {%02x%02x}\n", cap[0], cap[1]);		free(cap);	}	return flags;}faim_internal int aim_putcap(aim_bstream_t *bs, fu32_t caps){	int i;	if (!bs)		return -EINVAL;	for (i = 0; aim_bstream_empty(bs); i++) {		if (aim_caps[i].flag == AIM_CAPS_LAST)			break;		if (caps & aim_caps[i].flag)			aimbs_putraw(bs, aim_caps[i].data, 0x10);	}	return 0;}

⌨️ 快捷键说明

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