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

📄 locate.c

📁 oscar message protocol stack
💻 C
📖 第 1 页 / 共 3 页
字号:
static void dumptlv(aim_session_t *sess, fu16_t type, aim_bstream_t *bs, fu8_t len){	int i;	if (!sess || !bs || !len)		return;	faimdprintf(sess, 0, "userinfo:   type  =0x%04x\n", type);	faimdprintf(sess, 0, "userinfo:   length=0x%04x\n", len);	faimdprintf(sess, 0, "userinfo:   value:\n");	for (i = 0; i < len; i++) {		if ((i % 8) == 0)			faimdprintf(sess, 0, "\nuserinfo:        ");		faimdprintf(sess, 0, "0x%2x ", aimbs_get8(bs));	}	faimdprintf(sess, 0, "\n");	return;}faim_internal void aim_info_free(aim_userinfo_t *info){	free(info->sn);	free(info->iconcsum);	free(info->info);	free(info->info_encoding);	free(info->avail);	free(info->avail_encoding);	free(info->away);	free(info->away_encoding);}/* * AIM is fairly regular about providing user info.  This is a generic  * routine to extract it in its standard form. */faim_internal int aim_info_extract(aim_session_t *sess, aim_bstream_t *bs, aim_userinfo_t *outinfo){	int curtlv, tlvcnt;	fu8_t snlen;	if (!bs || !outinfo)		return -EINVAL;	/* Clear out old data first */	memset(outinfo, 0x00, sizeof(aim_userinfo_t));	/*	 * Screen name.  Stored as an unterminated string prepended with a 	 * byte containing its length.	 */	snlen = aimbs_get8(bs);	outinfo->sn = aimbs_getstr(bs, snlen);	/*	 * Warning Level.  Stored as an unsigned short.	 */	outinfo->warnlevel = aimbs_get16(bs);	/*	 * TLV Count. Unsigned short representing the number of 	 * Type-Length-Value triples that follow.	 */	tlvcnt = aimbs_get16(bs);	/* 	 * Parse out the Type-Length-Value triples as they're found.	 */	for (curtlv = 0; curtlv < tlvcnt; curtlv++) {		int endpos;		fu16_t type, length;		type = aimbs_get16(bs);		length = aimbs_get16(bs);		endpos = aim_bstream_curpos(bs) + length;		if (type == 0x0001) {			/*			 * Type = 0x0001: User flags			 * 			 * Specified as any of the following ORed together:			 *      0x0001  Trial (user less than 60days)			 *      0x0002  Unknown bit 2			 *      0x0004  AOL Main Service user			 *      0x0008  Unknown bit 4			 *      0x0010  Free (AIM) user 			 *      0x0020  Away			 *      0x0400  ActiveBuddy			 *			 */			outinfo->flags = aimbs_get16(bs);			outinfo->present |= AIM_USERINFO_PRESENT_FLAGS;		} else if (type == 0x0002) {			/*			 * Type = 0x0002: Account creation time. 			 *			 * The time/date that the user originally registered for			 * the service, stored in time_t format.			 *			 * I'm not sure how this differs from type 5 ("member			 * since").			 *			 * Note: This is the field formerly known as "member			 * since".  All these years and I finally found out			 * that I got the name wrong.			 */			outinfo->createtime = aimbs_get32(bs);			outinfo->present |= AIM_USERINFO_PRESENT_CREATETIME;		} else if (type == 0x0003) {			/*			 * Type = 0x0003: On-Since date.			 *			 * The time/date that the user started their current 			 * session, stored in time_t format.			 */			outinfo->onlinesince = aimbs_get32(bs);			outinfo->present |= AIM_USERINFO_PRESENT_ONLINESINCE;		} else if (type == 0x0004) {			/*			 * Type = 0x0004: Idle time.			 *			 * Number of minutes since the user actively used the 			 * service.			 *			 * Note that the client tells the server when to start			 * counting idle times, so this may or may not be 			 * related to reality.			 */			outinfo->idletime = aimbs_get16(bs);			outinfo->present |= AIM_USERINFO_PRESENT_IDLE;		} else if (type == 0x0005) {			/*			 * Type = 0x0005: Member since date. 			 *			 * The time/date that the user originally registered for			 * the service, stored in time_t format.			 *			 * This is sometimes sent instead of type 2 ("account			 * creation time"), particularly in the self-info.			 * And particularly for ICQ?			 */			outinfo->membersince = aimbs_get32(bs);			outinfo->present |= AIM_USERINFO_PRESENT_MEMBERSINCE;		} else if (type == 0x0006) {			/*			 * Type = 0x0006: ICQ Online Status			 *			 * ICQ's Away/DND/etc "enriched" status. Some decoding 			 * of values done by Scott <darkagl@pcnet.com>			 */			aimbs_get16(bs);			outinfo->icqinfo.status = aimbs_get16(bs);			outinfo->present |= AIM_USERINFO_PRESENT_ICQEXTSTATUS;		} else if (type == 0x0008) {			/*			 * Type = 0x0008			 *			 * Client type, or some such.			 */		} else if (type == 0x000a) {			/*			 * Type = 0x000a			 *			 * ICQ User IP Address.			 * Ahh, the joy of ICQ security.			 */			outinfo->icqinfo.ipaddr = aimbs_get32(bs);			outinfo->present |= AIM_USERINFO_PRESENT_ICQIPADDR;		} else if (type == 0x000c) {			/* 			 * Type = 0x000c			 *			 * random crap containing the IP address,			 * apparently a port number, and some Other Stuff.			 *			 * Format is:			 * 4 bytes - Our IP address, 0xc0 a8 01 2b for 192.168.1.43			 * 			 *			 */			aimbs_getrawbuf(bs, outinfo->icqinfo.crap, 0x25);			outinfo->present |= AIM_USERINFO_PRESENT_ICQDATA;		} else if (type == 0x000d) {			/*			 * Type = 0x000d			 *			 * OSCAR Capability information.			 *			 */			outinfo->capabilities |= aim_locate_getcaps(sess, bs, length);			outinfo->present |= AIM_USERINFO_PRESENT_CAPABILITIES;		} else if (type == 0x000e) {			/*			 * Type = 0x000e			 *			 * AOL capability information.			 *			 */		} else if ((type == 0x000f) || (type == 0x0010)) {			/*			 * Type = 0x000f: Session Length. (AIM)			 * Type = 0x0010: Session Length. (AOL)			 *			 * The duration, in seconds, of the user's current 			 * session.			 *			 * Which TLV type this comes in depends on the			 * service the user is using (AIM or AOL).			 *			 */			outinfo->sessionlen = aimbs_get32(bs);			outinfo->present |= AIM_USERINFO_PRESENT_SESSIONLEN;		} else if (type == 0x0019) {			/*			 * Type = 0x0019			 *			 * OSCAR short capability information.  A shortened 			 * form of the normal capabilities.			 */			outinfo->capabilities |= aim_locate_getcaps_short(sess, bs, length);			outinfo->present |= AIM_USERINFO_PRESENT_CAPABILITIES;		} else if (type == 0x001b) {			/*			 * Type = 0x001a			 *			 * AOL short capability information.  A shortened 			 * form of the normal capabilities.			 */		} else if (type == 0x001b) {			/*			 * Type = 0x0019			 *			 * Encryption certification MD5 checksum.			 */		} else if (type == 0x001d) {			/*			 * Type = 0x001d			 *			 * Buddy icon information and available messages.			 *			 * This almost seems like the AIM protocol guys gave 			 * the iChat guys a Type, and the iChat guys tried to 			 * cram as much cool shit into it as possible.  Then 			 * the Windows AIM guys were like, "hey, that's 			 * pretty neat, let's copy those prawns."			 *			 * In that spirit, this can contain a custom message, 			 * kind of like an away message, but you're not away 			 * (it's called an "available" message).  Or it can 			 * contain information about the buddy icon the user 			 * has stored on the server.			 */			int type2, number, length2;			while (aim_bstream_curpos(bs) < endpos) {				type2 = aimbs_get16(bs);				number = aimbs_get8(bs);				length2 = aimbs_get8(bs);				switch (type2) {					case 0x0000: { /* This is an official buddy icon? */						/* This is always 5 bytes of "0x02 01 d2 04 72"? */						aim_bstream_advance(bs, length2);					} break;					case 0x0001: { /* A buddy icon checksum */						if ((length2 > 0) && (number == 0x01)) {							free(outinfo->iconcsum);							outinfo->iconcsum = aimbs_getraw(bs, length2);							outinfo->iconcsumlen = length2;						} else							aim_bstream_advance(bs, length2);					} break;					case 0x0002: { /* An available message */						if (length2 > 4) {							free(outinfo->avail);							outinfo->avail_len = aimbs_get16(bs);							outinfo->avail = aimbs_getstr(bs, outinfo->avail_len);							if (aimbs_get16(bs) == 0x0001) { /* We have an encoding */								aimbs_get16(bs);								outinfo->avail_encoding = aimbs_getstr(bs, aimbs_get16(bs));							} else {								/* No explicit encoding, client should use UTF-8 */								outinfo->avail_encoding = NULL;							}						} else							aim_bstream_advance(bs, length2);					} break;					default: {						aim_bstream_advance(bs, length2);					} break;				}			}		} else if (type == 0x001e) {			/*			 * Type 30: Unknown.			 *			 * Always four bytes, but it doesn't look like an int.			 */		} else if (type == 0x001f) {			/*			 * Type 31: Unknown.			 *			 * Seen on a buddy using DeadAIM.  Data was 4 bytes:			 * 0x00 00 00 10			 */		} else {			/*			 * Reaching here indicates that either AOL has			 * added yet another TLV for us to deal with, 			 * or the parsing has gone Terribly Wrong.			 *			 * Either way, inform the owner and attempt			 * recovery.			 *			 */			faimdprintf(sess, 0, "userinfo: **warning: unexpected TLV:\n");			faimdprintf(sess, 0, "userinfo:   sn    =%s\n", outinfo->sn);			dumptlv(sess, type, bs, length);		}		/* Save ourselves. */		aim_bstream_setpos(bs, endpos);	}	aim_locate_adduserinfo(sess, outinfo);	return 0;}/* * Inverse of aim_info_extract() */faim_internal int aim_putuserinfo(aim_bstream_t *bs, aim_userinfo_t *info){	aim_tlvlist_t *tlvlist = NULL;	if (!bs || !info)		return -EINVAL;	aimbs_put8(bs, strlen(info->sn));	aimbs_putraw(bs, info->sn, strlen(info->sn));	aimbs_put16(bs, info->warnlevel);	if (info->present & AIM_USERINFO_PRESENT_FLAGS)		aim_tlvlist_add_16(&tlvlist, 0x0001, info->flags);	if (info->present & AIM_USERINFO_PRESENT_MEMBERSINCE)		aim_tlvlist_add_32(&tlvlist, 0x0002, info->membersince);	if (info->present & AIM_USERINFO_PRESENT_ONLINESINCE)		aim_tlvlist_add_32(&tlvlist, 0x0003, info->onlinesince);	if (info->present & AIM_USERINFO_PRESENT_IDLE)		aim_tlvlist_add_16(&tlvlist, 0x0004, info->idletime);/* XXX - So, ICQ_OSCAR_SUPPORT is never defined anywhere... */#if ICQ_OSCAR_SUPPORT	if (atoi(info->sn) != 0) {		if (info->present & AIM_USERINFO_PRESENT_ICQEXTSTATUS)			aim_tlvlist_add_16(&tlvlist, 0x0006, info->icqinfo.status);		if (info->present & AIM_USERINFO_PRESENT_ICQIPADDR)			aim_tlvlist_add_32(&tlvlist, 0x000a, info->icqinfo.ipaddr);	}#endif	if (info->present & AIM_USERINFO_PRESENT_CAPABILITIES)		aim_tlvlist_add_caps(&tlvlist, 0x000d, info->capabilities); 	if (info->present & AIM_USERINFO_PRESENT_SESSIONLEN)		aim_tlvlist_add_32(&tlvlist, (fu16_t)((info->flags & AIM_FLAG_AOL) ? 0x0010 : 0x000f), info->sessionlen);	aimbs_put16(bs, aim_tlvlist_count(&tlvlist));	aim_tlvlist_write(bs, &tlvlist);	aim_tlvlist_free(&tlvlist);	return 0;}/* * Subtype 0x0001 */static int error(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_snac_t *snac2;	fu16_t reason;	char *sn;	int was_explicit;	if (!(snac2 = aim_remsnac(sess, snac->id))) {		faimdprintf(sess, 0, "faim: locate.c, error(): received response from unknown request!\n");		return 0;	}	if ((snac2->family != 0x0002) && (snac2->type != 0x0015)) {		faimdprintf(sess, 0, "faim: locate.c, error(): received response from invalid request! %d\n", snac2->family);		return 0;	}	if (!(sn = snac2->data)) {		faimdprintf(sess, 0, "faim: locate.c, error(): received response from request without a screen name!\n");		return 0;	}	reason = aimbs_get16(bs);	/*	 * Remove this screen name from our queue.  If the client requested 	 * this buddy's info explicitly, then notify them that we do not have 	 * info for this buddy.	 */	was_explicit = aim_locate_gotuserinfo(sess, sn);	if (was_explicit == TRUE)		if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))			ret = userfunc(sess, rx, reason, sn);	if (snac2)		free(snac2->data);	free(snac2);	return ret;}/* * Subtype 0x0002 * * Request Location services rights. *

⌨️ 快捷键说明

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