changeset 3459:d82f53194f09

[gaim-migrate @ 3507] DANCE! committer: Tailor Script <tailor@pidgin.im>
author Sean Egan <seanegan@gmail.com>
date Wed, 28 Aug 2002 07:24:12 +0000
parents 66b1ad9782a9
children 66c7cca774f5
files ChangeLog src/protocols/oscar/aim.h src/protocols/oscar/info.c src/protocols/oscar/tlv.c
diffstat 4 files changed, 122 insertions(+), 25 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Wed Aug 28 06:48:14 2002 +0000
+++ b/ChangeLog	Wed Aug 28 07:24:12 2002 +0000
@@ -52,6 +52,7 @@
 	  Buddies" tab (Thanks click81)
 	* Option to log IMs and Chats seperately.  (Thanks Etan
 	  Reisner)
+	* Nice Oscar changes--mostly internal (Thanks Mark Doliner)
 
 version 0.59 (06/24/2002):
 	* Hungarian translation added (Thanks, Sutto Zoltan)
--- a/src/protocols/oscar/aim.h	Wed Aug 28 06:48:14 2002 +0000
+++ b/src/protocols/oscar/aim.h	Wed Aug 28 07:24:12 2002 +0000
@@ -407,12 +407,13 @@
  */
 typedef struct {
 	char sn[MAXSNLEN+1];
-	fu16_t warnlevel;
-	fu16_t idletime;
+	fu16_t warnlevel; /* evil percent * 10 (999 = 99.9%) */
+	fu16_t idletime; /* in seconds */
 	fu16_t flags;
-	fu32_t membersince;
-	fu32_t onlinesince;
-	fu32_t sessionlen; 
+	fu32_t createtime; /* time_t */
+	fu32_t membersince; /* time_t */
+	fu32_t onlinesince; /* time_t */
+	fu32_t sessionlen;  /* in seconds */
 	fu32_t capabilities;
 	struct {
 		fu32_t status;
@@ -431,11 +432,13 @@
 #define AIM_USERINFO_PRESENT_ICQDATA      0x00000040
 #define AIM_USERINFO_PRESENT_CAPABILITIES 0x00000080
 #define AIM_USERINFO_PRESENT_SESSIONLEN   0x00000100
+#define AIM_USERINFO_PRESENT_CREATETIME   0x00000200
 
 faim_export const char *aim_userinfo_sn(aim_userinfo_t *ui);
 faim_export fu16_t aim_userinfo_flags(aim_userinfo_t *ui);
 faim_export fu16_t aim_userinfo_idle(aim_userinfo_t *ui);
 faim_export float aim_userinfo_warnlevel(aim_userinfo_t *ui);
+faim_export time_t aim_userinfo_createtime(aim_userinfo_t *ui);
 faim_export time_t aim_userinfo_membersince(aim_userinfo_t *ui);
 faim_export time_t aim_userinfo_onlinesince(aim_userinfo_t *ui);
 faim_export fu32_t aim_userinfo_sessionlen(aim_userinfo_t *ui);
--- a/src/protocols/oscar/info.c	Wed Aug 28 06:48:14 2002 +0000
+++ b/src/protocols/oscar/info.c	Wed Aug 28 07:24:12 2002 +0000
@@ -76,6 +76,15 @@
 	return (ui->warnlevel / 10);
 }
 
+faim_export time_t aim_userinfo_createtime(aim_userinfo_t *ui)
+{
+
+	if (!ui)
+		return 0;
+
+	return (time_t)ui->createtime;
+}
+
 faim_export time_t aim_userinfo_membersince(aim_userinfo_t *ui)
 {
 
@@ -278,6 +287,30 @@
 	return 0;
 }
 
+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;
+}
+
 /*
  * AIM is fairly regular about providing user info.  This is a generic 
  * routine to extract it in its standard form.
@@ -342,13 +375,20 @@
 
 		} else if (type == 0x0002) {
 			/*
-			 * Type = 0x0002: Member-Since date. 
+			 * 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->membersince = aimbs_get32(bs);
-			outinfo->present |= AIM_USERINFO_PRESENT_MEMBERSINCE;
+			outinfo->createtime = aimbs_get32(bs);
+			outinfo->present |= AIM_USERINFO_PRESENT_CREATETIME;
 
 		} else if (type == 0x0003) {
 			/*
@@ -373,6 +413,18 @@
 			 */
 			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.
+			 */
+			outinfo->membersince = aimbs_get32(bs);
+			outinfo->present |= AIM_USERINFO_PRESENT_MEMBERSINCE;
 
 		} else if (type == 0x0006) {
 			/*
@@ -442,6 +494,19 @@
 			outinfo->sessionlen = aimbs_get32(bs);
 			outinfo->present |= AIM_USERINFO_PRESENT_SESSIONLEN;
 
+		} else if (type == 0x001d) {
+			/*
+			 * Type 29: Unknown.
+			 *
+			 * Currently very rare. Always 18 bytes of mostly zero.
+			 */
+
+		} else if (type == 0x001e) {
+			/*
+			 * Type 30: Unknown.
+			 *
+			 * Always four bytes, but it doesn't look like an int.
+			 */
 		} else {
 
 			/*
@@ -455,9 +520,7 @@
 			 */
 			faimdprintf(sess, 0, "userinfo: **warning: unexpected TLV:\n");
 			faimdprintf(sess, 0, "userinfo:   sn    =%s\n", outinfo->sn);
-			faimdprintf(sess, 0, "userinfo:   type  =0x%04x\n",type);
-			faimdprintf(sess, 0, "userinfo:   length=0x%04x\n", length);
-
+			dumptlv(sess, type, bs, length);
 		}
 
 		/* Save ourselves. */
@@ -483,21 +546,29 @@
 	aimbs_put16(bs, info->warnlevel);
 
 
-	aim_addtlvtochain16(&tlvlist, 0x0001, info->flags);
-	aim_addtlvtochain32(&tlvlist, 0x0002, info->membersince);
-	aim_addtlvtochain32(&tlvlist, 0x0003, info->onlinesince);
-	aim_addtlvtochain16(&tlvlist, 0x0004, info->idletime);
+	if (info->present & AIM_USERINFO_PRESENT_FLAGS)
+		aim_addtlvtochain16(&tlvlist, 0x0001, info->flags);
+	if (info->present & AIM_USERINFO_PRESENT_MEMBERSINCE)
+		aim_addtlvtochain32(&tlvlist, 0x0002, info->membersince);
+	if (info->present & AIM_USERINFO_PRESENT_ONLINESINCE)
+		aim_addtlvtochain32(&tlvlist, 0x0003, info->onlinesince);
+	if (info->present & AIM_USERINFO_PRESENT_IDLE)
+		aim_addtlvtochain16(&tlvlist, 0x0004, info->idletime);
 
 #if ICQ_OSCAR_SUPPORT
 	if (atoi(info->sn) != 0) {
-		aim_addtlvtochain16(&tlvlist, 0x0006, info->icqinfo.status);
-		aim_addtlvtochain32(&tlvlist, 0x000a, info->icqinfo.ipaddr);
+		if (info->present & AIM_USERINFO_PRESENT_ICQEXTSTATUS)
+			aim_addtlvtochain16(&tlvlist, 0x0006, info->icqinfo.status);
+		if (info->present & AIM_USERINFO_PRESENT_ICQIPADDR)
+			aim_addtlvtochain32(&tlvlist, 0x000a, info->icqinfo.ipaddr);
 	}
 #endif
 
-	aim_addtlvtochain_caps(&tlvlist, 0x000d, info->capabilities);
-
-	aim_addtlvtochain32(&tlvlist, (fu16_t)((info->flags & AIM_FLAG_AOL) ? 0x0010 : 0x000f), info->sessionlen);
+	if (info->present & AIM_USERINFO_PRESENT_CAPABILITIES)
+		aim_addtlvtochain_caps(&tlvlist, 0x000d, info->capabilities);
+ 
+	if (info->present & AIM_USERINFO_PRESENT_SESSIONLEN)
+		aim_addtlvtochain32(&tlvlist, (fu16_t)((info->flags & AIM_FLAG_AOL) ? 0x0010 : 0x000f), info->sessionlen);
 
 	aimbs_put16(bs, aim_counttlvchain(&tlvlist));
 	aim_writetlvchain(bs, &tlvlist);
--- a/src/protocols/oscar/tlv.c	Wed Aug 28 06:48:14 2002 +0000
+++ b/src/protocols/oscar/tlv.c	Wed Aug 28 07:24:12 2002 +0000
@@ -46,9 +46,9 @@
 faim_internal aim_tlvlist_t *aim_readtlvchain(aim_bstream_t *bs)
 {
 	aim_tlvlist_t *list = NULL, *cur;
-	fu16_t type, length;
-
-	while (aim_bstream_empty(bs)) {
+	
+	while (aim_bstream_empty(bs) > 0) {
+		fu16_t type, length;
 
 		type = aimbs_get16(bs);
 		length = aimbs_get16(bs);
@@ -70,13 +70,35 @@
 #endif
 		else {
 
+			if (length > aim_bstream_empty(bs)) {
+				aim_freetlvchain(&list);
+				return NULL;
+			}
+
 			cur = (aim_tlvlist_t *)malloc(sizeof(aim_tlvlist_t));
+			if (!cur) {
+				aim_freetlvchain(&list);
+				return NULL;
+			}
+
 			memset(cur, 0, sizeof(aim_tlvlist_t));
 
-			cur->tlv = createtlv();	
+			cur->tlv = createtlv();
+			if (!cur->tlv) {
+				free(cur);
+				aim_freetlvchain(&list);
+				return NULL;
+			}
 			cur->tlv->type = type;
-			if ((cur->tlv->length = length))
+			if ((cur->tlv->length = length)) {
 			       cur->tlv->value = aimbs_getraw(bs, length);	
+			       if (!cur->tlv->value) {
+				       freetlv(&cur->tlv);
+				       free(cur);
+				       aim_freetlvchain(&list);
+				       return NULL;
+			       }
+			}
 
 			cur->next = list;
 			list = cur;