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

📄 family_locate.c

📁 Linux下的多协议即时通讯程序源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
			}		}		if (!identified)			purple_debug_misc("oscar", "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]);		g_free(cap);	}	return flags;}guint32aim_locate_getcaps_short(OscarData *od, ByteStream *bs, int len){	guint32 flags = 0;	int offset;	for (offset = 0; byte_stream_empty(bs) && (offset < len); offset += 0x02) {		guint8 *cap;		int i, identified;		cap = byte_stream_getraw(bs, 0x02);		for (i = 0, identified = 0; !(aim_caps[i].flag & OSCAR_CAPABILITY_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)			purple_debug_misc("oscar", "unknown short capability: {%02x%02x}\n", cap[0], cap[1]);		g_free(cap);	}	return flags;}intbyte_stream_putcaps(ByteStream *bs, guint32 caps){	int i;	if (!bs)		return -EINVAL;	for (i = 0; byte_stream_empty(bs); i++) {		if (aim_caps[i].flag == OSCAR_CAPABILITY_LAST)			break;		if (caps & aim_caps[i].flag)			byte_stream_putraw(bs, aim_caps[i].data, 0x10);	}	return 0;}#ifdef LOG_UNKNOWN_TLVstatic voiddumptlv(OscarData *od, guint16 type, ByteStream *bs, guint8 len){	int i;	if (!od || !bs || !len)		return;	purple_debug_misc("oscar", "userinfo:   type  =0x%04x\n", type);	purple_debug_misc("oscar", "userinfo:   length=0x%04x\n", len);	purple_debug_misc("oscar", "userinfo:   value:\n");	for (i = 0; i < len; i++) {		if ((i % 8) == 0)			purple_debug_misc("oscar", "\nuserinfo:        ");		purple_debug_misc("oscar", "0x%2x ", byte_stream_get8(bs));	}	purple_debug_misc("oscar", "\n");	return;}#endifvoidaim_info_free(aim_userinfo_t *info){	g_free(info->sn);	g_free(info->iconcsum);	g_free(info->info);	g_free(info->info_encoding);	g_free(info->status);	g_free(info->status_encoding);	g_free(info->itmsurl);	g_free(info->itmsurl_encoding);	g_free(info->away);	g_free(info->away_encoding);}/* * AIM is fairly regular about providing user info.  This is a generic * routine to extract it in its standard form. */intaim_info_extract(OscarData *od, ByteStream *bs, aim_userinfo_t *outinfo){	int curtlv, tlvcnt;	guint8 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 = byte_stream_get8(bs);	outinfo->sn = byte_stream_getstr(bs, snlen);	/*	 * Warning Level.  Stored as an unsigned short.	 */	outinfo->warnlevel = byte_stream_get16(bs);	/*	 * TLV Count. Unsigned short representing the number of	 * Type-Length-Value triples that follow.	 */	tlvcnt = byte_stream_get16(bs);	/*	 * Parse out the Type-Length-Value triples as they're found.	 */	for (curtlv = 0; curtlv < tlvcnt; curtlv++) {		int endpos;		guint16 type, length;		type = byte_stream_get16(bs);		length = byte_stream_get16(bs);		endpos = byte_stream_curpos(bs) + length;		if (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 = byte_stream_get16(bs);			outinfo->present |= AIM_USERINFO_PRESENT_FLAGS;		} else if (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 = byte_stream_get32(bs);			outinfo->present |= AIM_USERINFO_PRESENT_CREATETIME;		} else if (type == 0x0003) {			/*			 * On-Since date			 *			 * The time/date that the user started their current			 * session, stored in time_t format.			 */			outinfo->onlinesince = byte_stream_get32(bs);			outinfo->present |= AIM_USERINFO_PRESENT_ONLINESINCE;		} else if (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 = byte_stream_get16(bs);			outinfo->present |= AIM_USERINFO_PRESENT_IDLE;		} else if (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 = byte_stream_get32(bs);			outinfo->present |= AIM_USERINFO_PRESENT_MEMBERSINCE;		} else if (type == 0x0006) {			/*			 * ICQ Online Status			 *			 * ICQ's Away/DND/etc "enriched" status. Some decoding			 * of values done by Scott <darkagl@pcnet.com>			 */			byte_stream_get16(bs);			outinfo->icqinfo.status = byte_stream_get16(bs);			outinfo->present |= AIM_USERINFO_PRESENT_ICQEXTSTATUS;		} else if (type == 0x0008) {			/*			 * Client type, or some such.			 */		} else if (type == 0x000a) {			/*			 * ICQ User IP Address			 *			 * Ahh, the joy of ICQ security.			 */			outinfo->icqinfo.ipaddr = byte_stream_get32(bs);			outinfo->present |= AIM_USERINFO_PRESENT_ICQIPADDR;		} else if (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			 */			byte_stream_getrawbuf(bs, outinfo->icqinfo.crap, 0x25);			outinfo->present |= AIM_USERINFO_PRESENT_ICQDATA;		} else if (type == 0x000d) {			/*			 * OSCAR Capability information			 */			outinfo->capabilities |= aim_locate_getcaps(od, bs, length);			outinfo->present |= AIM_USERINFO_PRESENT_CAPABILITIES;		} else if (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 = byte_stream_get32(bs);			outinfo->present |= AIM_USERINFO_PRESENT_SESSIONLEN;		} else if (type == 0x0019) {			/*			 * OSCAR short capability information.  A shortened			 * form of the normal capabilities.			 */			outinfo->capabilities |= aim_locate_getcaps_short(od, bs, length);			outinfo->present |= AIM_USERINFO_PRESENT_CAPABILITIES;		} else if (type == 0x001a) {			/*			 * Type = 0x001a			 *			 * AOL short capability information.  A shortened			 * form of the normal capabilities.			 */		} else if (type == 0x001b) {			/*			 * Encryption certification MD5 checksum.			 */		} else if (type == 0x001d) {			/*			 * Buddy icon information and status/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 (byte_stream_curpos(bs) < endpos) {				type2 = byte_stream_get16(bs);				number = byte_stream_get8(bs);				length2 = byte_stream_get8(bs);				switch (type2) {					case 0x0000: { /* This is an official buddy icon? */						/* This is always 5 bytes of "0x02 01 d2 04 72"? */						byte_stream_advance(bs, length2);					} break;					case 0x0001: { /* A buddy icon checksum */						if ((length2 > 0) && ((number == 0x00) || (number == 0x01))) {							g_free(outinfo->iconcsum);							outinfo->iconcsumtype = number;							outinfo->iconcsum = byte_stream_getraw(bs, length2);							outinfo->iconcsumlen = length2;						} else							byte_stream_advance(bs, length2);					} break;					case 0x0002: { /* A status/available message */						g_free(outinfo->status);						g_free(outinfo->status_encoding);						if (length2 >= 4) {							outinfo->status_len = byte_stream_get16(bs);							outinfo->status = byte_stream_getstr(bs, outinfo->status_len);							if (byte_stream_get16(bs) == 0x0001) { /* We have an encoding */								byte_stream_get16(bs);								outinfo->status_encoding = byte_stream_getstr(bs, byte_stream_get16(bs));							} else {								/* No explicit encoding, client should use UTF-8 */								outinfo->status_encoding = NULL;							}						} else {							byte_stream_advance(bs, length2);							outinfo->status_len = 0;							outinfo->status = g_strdup("");							outinfo->status_encoding = NULL;						}					} break;					case 0x0009: { /* An iTunes Music Store link */						g_free(outinfo->itmsurl);						g_free(outinfo->itmsurl_encoding);						if (length2 >= 4) {							outinfo->itmsurl_len = byte_stream_get16(bs);							outinfo->itmsurl = byte_stream_getstr(bs, outinfo->itmsurl_len);							if (byte_stream_get16(bs) == 0x0001) {								/* We have an encoding */								byte_stream_get16(bs);								outinfo->itmsurl_encoding = byte_stream_getstr(bs, byte_stream_get16(bs));							} else {								/* No explicit encoding, client should use UTF-8 */								outinfo->itmsurl_encoding = NULL;							}						} else {							byte_stream_advance(bs, length2);							outinfo->itmsurl_len = 0;							outinfo->itmsurl = g_strdup("");							outinfo->itmsurl_encoding = NULL;						}					} break;					default: {						byte_stream_advance(bs, length2);					} break;				}			}		} else if (type == 0x001e) {			/*			 * Always four bytes, but it doesn't look like an int.			 */		} else if (type == 0x001f) {			/*			 * 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.			 *			 */#ifdef LOG_UNKNOWN_TLV			purple_debug_misc("oscar", "userinfo: **warning: unexpected TLV:\n");			purple_debug_misc("oscar", "userinfo:   sn    =%s\n", outinfo->sn);			dumptlv(od, type, bs, length);#endif		}		/* Save ourselves. */		byte_stream_setpos(bs, endpos);	}	aim_locate_adduserinfo(od, outinfo);	return 0;}/* * Inverse of aim_info_extract() */intaim_putuserinfo(ByteStream *bs, aim_userinfo_t *info){	GSList *tlvlist = NULL;	if (!bs || !info)		return -EINVAL;	byte_stream_put8(bs, strlen(info->sn));	byte_stream_putstr(bs, info->sn);	byte_stream_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... */#ifdef 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, (guint16)((info->flags & AIM_FLAG_AOL) ? 0x0010 : 0x000f), info->sessionlen);	byte_stream_put16(bs, aim_tlvlist_count(tlvlist));	aim_tlvlist_write(bs, &tlvlist);	aim_tlvlist_free(tlvlist);	return 0;}/* * Subtype 0x0001 */static interror(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *frame, aim_modsnac_t *snac, ByteStream *bs){	int ret = 0;	aim_rxcallback_t userfunc;	aim_snac_t *snac2;	guint16 reason;

⌨️ 快捷键说明

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