diff libfaim/aim_info.c @ 445:e4c34ca88d9b

[gaim-migrate @ 455] Hehehehehe Libfaim got updated, gaim got updated. btw, gaim/faim can't sign in yet, don't ask me why. it's not my fault. committer: Tailor Script <tailor@pidgin.im>
author Eric Warmenhoven <eric@warmenhoven.org>
date Thu, 29 Jun 2000 20:40:28 +0000
parents 0f14e6d8a51b
children 88f8f98de02d
line wrap: on
line diff
--- a/libfaim/aim_info.c	Thu Jun 29 19:38:18 2000 +0000
+++ b/libfaim/aim_info.c	Thu Jun 29 20:40:28 2000 +0000
@@ -25,7 +25,7 @@
   if (!sess || !conn || !sn)
     return 0;
 
-  if (!(newpacket = aim_tx_new(0x0002, conn, 12+1+strlen(sn))))
+  if (!(newpacket = aim_tx_new(AIM_FRAMETYPE_OSCAR, 0x0002, conn, 12+1+strlen(sn))))
     return -1;
 
   newpacket->lock = 1;
@@ -88,6 +88,66 @@
    0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}
 };
 
+u_short aim_getcap(unsigned char *capblock, int buflen)
+{
+  u_short ret = 0;
+  int y;
+  int offset = 0;
+
+  while (offset < buflen) {
+    for(y=0; y < (sizeof(aim_caps)/0x10); y++) {
+      if (memcmp(&aim_caps[y], capblock+offset, 0x10) == 0) {
+	switch(y) {
+	case 0: ret |= AIM_CAPS_BUDDYICON; break;
+	case 1: ret |= AIM_CAPS_VOICE; break;
+	case 2: ret |= AIM_CAPS_IMIMAGE; break;
+	case 3: ret |= AIM_CAPS_CHAT; break;
+	case 4: ret |= AIM_CAPS_GETFILE; break;
+	case 5: ret |= AIM_CAPS_SENDFILE; break;
+	default: ret |= 0xff00; break;
+	}
+      }
+    }
+    offset += 0x10;
+  } 
+  return ret;
+}
+
+int aim_putcap(unsigned char *capblock, int buflen, u_short caps)
+{
+  int offset = 0;
+
+  if (!capblock)
+    return -1;
+
+  if ((caps & AIM_CAPS_BUDDYICON) && (offset < buflen)) {
+    memcpy(capblock+offset, aim_caps[0], sizeof(aim_caps[0]));
+    offset += sizeof(aim_caps[1]);
+  }
+  if ((caps & AIM_CAPS_VOICE) && (offset < buflen)) {
+    memcpy(capblock+offset, aim_caps[1], sizeof(aim_caps[1]));
+    offset += sizeof(aim_caps[1]);
+  }
+  if ((caps & AIM_CAPS_IMIMAGE) && (offset < buflen)) {
+    memcpy(capblock+offset, aim_caps[2], sizeof(aim_caps[2]));
+    offset += sizeof(aim_caps[2]);
+  }
+  if ((caps & AIM_CAPS_CHAT) && (offset < buflen)) {
+    memcpy(capblock+offset, aim_caps[3], sizeof(aim_caps[3]));
+    offset += sizeof(aim_caps[3]);
+  }
+  if ((caps & AIM_CAPS_GETFILE) && (offset < buflen)) {
+    memcpy(capblock+offset, aim_caps[4], sizeof(aim_caps[4]));
+    offset += sizeof(aim_caps[4]);
+  }
+  if ((caps & AIM_CAPS_SENDFILE) && (offset < buflen)) {
+    memcpy(capblock+offset, aim_caps[5], sizeof(aim_caps[5]));
+    offset += sizeof(aim_caps[5]);
+  }
+
+  return offset;
+}
+
 /*
  * AIM is fairly regular about providing user info.  This
  * is a generic routine to extract it in its standard form.
@@ -99,6 +159,7 @@
   int curtlv = 0;
   int tlv1 = 0;
   u_short curtype;
+  int lastvalid;
 
 
   if (!buf || !outinfo)
@@ -111,8 +172,13 @@
    * 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];
 
   /*
@@ -131,180 +197,177 @@
   /* 
    * 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.
-	   *
-	   * Ignore.
-	   *
-	   */
-	case 0x000d:
-	  {
-	    int z,y; 
-	    int len;
-	    len = aimutil_get16(buf+i+2);
-	    if (!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;
 
-	    for (z = 0; z < len; z+=0x10) {
-	      for(y=0; y < 6; y++) {
-		if (memcmp(&aim_caps[y], buf+i+4+z, 0x10) == 0) {
-		  switch(y) {
-		  case 0: outinfo->capabilities |= AIM_CAPS_BUDDYICON; break;
-		  case 1: outinfo->capabilities |= AIM_CAPS_VOICE; break;
-		  case 2: outinfo->capabilities |= AIM_CAPS_IMIMAGE; break;
-		  case 3: outinfo->capabilities |= AIM_CAPS_CHAT; break;
-		  case 4: outinfo->capabilities |= AIM_CAPS_GETFILE; break;
-		  case 5: outinfo->capabilities |= AIM_CAPS_SENDFILE; break;
-		  default: outinfo->capabilities |= 0xff00; break;
-		  }
-		}
-	      }
-	    }
-	  }
-	  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)
-	      {
-		x = sprintf(tmpstr, "faim: userinfo:      ");
-		for (y = 0; y < 8; y++)
-		  {
-		    if (z<len)
-		      {
-			sprintf(tmpstr+x, "%02x ", buf[i+4+z]);
-			z++;
-			x += 3;
-		      }
-		    else
-		      break;
-		  }
-		printf("%s\n", tmpstr);
-	      }
-	  }
-	  break;
-	}  
+      /*
+       * 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;
+      
       /*
-       * No matter what, TLV triplets should always look like this:
+       * 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.
        *
-       *   u_short type;
-       *   u_short length;
-       *   u_char  data[length];
+       * 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.
        *
        */
-      i += (2 + 2 + aimutil_get16(&buf[i+2]));
+    case 0x000d:
+      {
+	int len;
+	len = aimutil_get16(buf+i+2);
+	if (!len)
+	  break;
+	
+	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)
+	  {
+	    x = sprintf(tmpstr, "faim: userinfo:      ");
+	    for (y = 0; y < 8; y++)
+	      {
+		if (z<len)
+		  {
+		    sprintf(tmpstr+x, "%02x ", buf[i+4+z]);
+		    z++;
+		    x += 3;
+		  }
+		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];
+     *
+     */
+    if (lastvalid) {
+      i += (2 + 2 + aimutil_get16(&buf[i+2])); 	   
       curtlv++;
     }
+  }
   
   return i;
 }
@@ -478,7 +541,7 @@
   if (!sess || !conn || !info)
     return 0;
 
-  if (!(tx = aim_tx_new(0x0002, conn, 1152)))
+  if (!(tx = aim_tx_new(AIM_FRAMETYPE_OSCAR, 0x0002, conn, 1152)))
     return -1;
 
   tx->lock = 1;
@@ -506,7 +569,7 @@
   if (!sess || !conn || !sn)
     return 0;
 
-  if (!(tx = aim_tx_new(0x0002, conn, 10+1+strlen(sn))))
+  if (!(tx = aim_tx_new(AIM_FRAMETYPE_OSCAR, 0x0002, conn, 10+1+strlen(sn))))
     return -1;
 
   tx->lock = 1;