int curtlv = 0;
int tlv1 = 0;
u_short curtype;
+ int lastvalid;
if (!buf || !outinfo)
* Screen name. Stored as an unterminated string prepended
* with an unsigned byte containing its length.
*/
- memcpy(outinfo->sn, &(buf[i+1]), buf[i]);
- outinfo->sn[(int)buf[i]] = '\0';
+ if (buf[i] < MAXSNLEN) {
+ memcpy(outinfo->sn, &(buf[i+1]), buf[i]);
+ outinfo->sn[(int)buf[i]] = '\0';
+ } else {
+ memcpy(outinfo->sn, &(buf[i+1]), MAXSNLEN-1);
+ outinfo->sn[MAXSNLEN] = '\0';
+ }
i = 1 + (int)buf[i];
/*
/*
* Parse out the Type-Length-Value triples as they're found.
*/
- while (curtlv < tlvcnt)
- {
- curtype = aimutil_get16(&buf[i]);
- switch (curtype)
- {
- /*
- * Type = 0x0001: Member Class.
- *
- * Specified as any of the following bitwise 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
- *
- * In some odd cases, we can end up with more
- * than one of these. We only want the first,
- * as the others may not be something we want.
- *
- */
- case 0x0001:
- if (tlv1) /* use only the first */
- break;
- outinfo->class = aimutil_get16(&buf[i+4]);
- tlv1++;
- break;
-
- /*
- * Type = 0x0002: Member-Since date.
- *
- * The time/date that the user originally
- * registered for the service, stored in
- * time_t format
- */
- case 0x0002:
- outinfo->membersince = aimutil_get32(&buf[i+4]);
- break;
-
- /*
- * Type = 0x0003: On-Since date.
- *
- * The time/date that the user started
- * their current session, stored in time_t
- * format.
- */
- case 0x0003:
- outinfo->onlinesince = aimutil_get32(&buf[i+4]);
- break;
-
- /*
- * Type = 0x0004: Idle time.
- *
- * Number of seconds since the user
- * actively used the service.
- */
- case 0x0004:
- outinfo->idletime = aimutil_get16(&buf[i+4]);
- break;
-
- /*
- * Type = 0x000d
- *
- * Capability information. Not real sure of
- * actual decoding. See comment on aim_bos_setprofile()
- * in aim_misc.c about the capability block, its the same.
- *
- */
- case 0x000d:
- {
- int len;
- len = aimutil_get16(buf+i+2);
- if (!len)
- break;
-
- outinfo->capabilities = aim_getcap(buf+i+4, len);
- }
- break;
+ while (curtlv < tlvcnt) {
+ lastvalid = 1;
+ curtype = aimutil_get16(&buf[i]);
+ switch (curtype) {
+ /*
+ * Type = 0x0000: Invalid
+ *
+ * AOL has been trying to throw these in just to break us.
+ * They're real nice guys over there at AOL.
+ *
+ * Just skip the two zero bytes and continue on. (This doesn't
+ * count towards tlvcnt!)
+ */
+ case 0x0000:
+ lastvalid = 0;
+ i += 2;
+ break;
- /*
- * Type = 0x000e
- *
- * Unknown. Always of zero length, and always only
- * on AOL users.
- *
- * Ignore.
- *
- */
- case 0x000e:
- break;
-
- /*
- * 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).
- *
- */
- case 0x000f:
- case 0x0010:
- outinfo->sessionlen = aimutil_get32(&buf[i+4]);
+ /*
+ * Type = 0x0001: Member Class.
+ *
+ * Specified as any of the following bitwise 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
+ *
+ * In some odd cases, we can end up with more
+ * than one of these. We only want the first,
+ * as the others may not be something we want.
+ *
+ */
+ case 0x0001:
+ if (tlv1) /* use only the first */
+ break;
+ outinfo->class = aimutil_get16(&buf[i+4]);
+ tlv1++;
+ break;
+
+ /*
+ * Type = 0x0002: Member-Since date.
+ *
+ * The time/date that the user originally
+ * registered for the service, stored in
+ * time_t format
+ */
+ case 0x0002:
+ outinfo->membersince = aimutil_get32(&buf[i+4]);
+ break;
+
+ /*
+ * Type = 0x0003: On-Since date.
+ *
+ * The time/date that the user started
+ * their current session, stored in time_t
+ * format.
+ */
+ case 0x0003:
+ outinfo->onlinesince = aimutil_get32(&buf[i+4]);
+ break;
+
+ /*
+ * Type = 0x0004: Idle time.
+ *
+ * Number of seconds since the user
+ * actively used the service.
+ */
+ case 0x0004:
+ outinfo->idletime = aimutil_get16(&buf[i+4]);
+ break;
+
+ /*
+ * Type = 0x000d
+ *
+ * Capability information. Not real sure of
+ * actual decoding. See comment on aim_bos_setprofile()
+ * in aim_misc.c about the capability block, its the same.
+ *
+ */
+ case 0x000d:
+ {
+ int len;
+ len = aimutil_get16(buf+i+2);
+ if (!len)
break;
-
- /*
- * 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.
- *
- */
- default:
+
+ outinfo->capabilities = aim_getcap(buf+i+4, len);
+ }
+ break;
+
+ /*
+ * Type = 0x000e
+ *
+ * Unknown. Always of zero length, and always only
+ * on AOL users.
+ *
+ * Ignore.
+ *
+ */
+ case 0x000e:
+ break;
+
+ /*
+ * 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).
+ *
+ */
+ case 0x000f:
+ case 0x0010:
+ outinfo->sessionlen = aimutil_get32(&buf[i+4]);
+ break;
+
+ /*
+ * 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.
+ *
+ */
+ default:
+ {
+ int len,z = 0, y = 0, x = 0;
+ char tmpstr[80];
+ printf("faim: userinfo: **warning: unexpected TLV:\n");
+ printf("faim: userinfo: sn =%s\n", outinfo->sn);
+ printf("faim: userinfo: curtlv=0x%04x\n", curtlv);
+ printf("faim: userinfo: type =0x%04x\n",aimutil_get16(&buf[i]));
+ printf("faim: userinfo: length=0x%04x\n", len = aimutil_get16(&buf[i+2]));
+ printf("faim: userinfo: data: \n");
+ while (z<len)
{
- int len,z = 0, y = 0, x = 0;
- char tmpstr[80];
- printf("faim: userinfo: **warning: unexpected TLV:\n");
- printf("faim: userinfo: sn =%s\n", outinfo->sn);
- printf("faim: userinfo: curtlv=0x%04x\n", curtlv);
- printf("faim: userinfo: type =0x%04x\n",aimutil_get16(&buf[i]));
- printf("faim: userinfo: length=0x%04x\n", len = aimutil_get16(&buf[i+2]));
- printf("faim: userinfo: data: \n");
- while (z<len)
+ x = sprintf(tmpstr, "faim: userinfo: ");
+ for (y = 0; y < 8; y++)
{
- x = sprintf(tmpstr, "faim: userinfo: ");
- for (y = 0; y < 8; y++)
+ if (z<len)
{
- if (z<len)
- {
- sprintf(tmpstr+x, "%02x ", buf[i+4+z]);
- z++;
- x += 3;
- }
- else
- break;
+ sprintf(tmpstr+x, "%02x ", buf[i+4+z]);
+ z++;
+ x += 3;
}
- printf("%s\n", tmpstr);
+ else
+ break;
}
+ printf("%s\n", tmpstr);
}
- break;
- }
- /*
- * No matter what, TLV triplets should always look like this:
- *
- * u_short type;
- * u_short length;
- * u_char data[length];
- *
- */
- i += (2 + 2 + aimutil_get16(&buf[i+2]));
-
+ }
+ break;
+ }
+ /*
+ * No matter what, TLV triplets should always look like this:
+ *
+ * u_short type;
+ * u_short length;
+ * u_char data[length];
+ *
+ */
+ if (lastvalid) {
+ i += (2 + 2 + aimutil_get16(&buf[i+2]));
curtlv++;
}
+ }
return i;
}