]> andersk Git - libfaim.git/blobdiff - aim_info.c
Added some debugging printfs to help track down the SNAC userinf problem.
[libfaim.git] / aim_info.c
index 9d085a6d167c54b8918d88a4bfcda72c66189a6d..92e1f78ab7c69127dd049d1b1b0583cb0d69dfeb 100644 (file)
@@ -7,16 +7,22 @@
  */
 
 
-#include "aim.h" /* for most everything */
+#include <faim/aim.h>
 
-u_long aim_getinfo(struct aim_conn_t *conn, const char *sn)
+u_long aim_getinfo(struct aim_session_t *sess,
+                  struct aim_conn_t *conn, 
+                  const char *sn)
 {
   struct command_tx_struct newpacket;
+  int i = 0;
+
+  if (!sess || !conn || !sn)
+    return 0;
 
   if (conn)
     newpacket.conn = conn;
   else
-    newpacket.conn = aim_getconn_type(AIM_CONN_TYPE_BOS);
+    newpacket.conn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS);
 
   newpacket.lock = 1;
   newpacket.type = 0x0002;
@@ -24,29 +30,30 @@ u_long aim_getinfo(struct aim_conn_t *conn, const char *sn)
   newpacket.commandlen = 12 + 1 + strlen(sn);
   newpacket.data = (char *) malloc(newpacket.commandlen);
 
-  aim_putsnac(newpacket.data, 0x0002, 0x0005, 0x0000, aim_snac_nextid);
+  i = aim_putsnac(newpacket.data, 0x0002, 0x0005, 0x0000, sess->snac_nextid);
 
-  aimutil_put16(newpacket.data+10, 0x0001);
-  aimutil_put8(newpacket.data+12, strlen(sn));
-  aimutil_putstr(newpacket.data+13, sn, strlen(sn));
+  i += aimutil_put16(newpacket.data+i, 0x0001);
+  i += aimutil_put8(newpacket.data+i, strlen(sn));
+  i += aimutil_putstr(newpacket.data+i, sn, strlen(sn));
 
-  aim_tx_enqueue(&newpacket);
+  newpacket.lock = 0;
+  aim_tx_enqueue(sess, &newpacket);
 
   {
     struct aim_snac_t snac;
     
-    snac.id = aim_snac_nextid;
+    snac.id = sess->snac_nextid;
     snac.family = 0x0002;
     snac.type = 0x0005;
     snac.flags = 0x0000;
 
     snac.data = malloc(strlen(sn)+1);
-    memcpy(snac.data, sn, strlen(sn)+1);
+    strcpy(snac.data, sn);
 
-    aim_newsnac(&snac);
+    aim_newsnac(sess, &snac);
   }
 
-  return (aim_snac_nextid++);
+  return (sess->snac_nextid++);
 }
 
 /*
@@ -106,6 +113,7 @@ int aim_extractuserinfo(u_char *buf, struct aim_userinfo_s *outinfo)
           *      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,
@@ -150,6 +158,31 @@ int aim_extractuserinfo(u_char *buf, struct aim_userinfo_s *outinfo)
        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:
+         break;
+
+         /*
+          * Type = 0x000e
+          *
+          * Unknown.  Always of zero length, and always only
+          * on AOL users.
+          *
+          * Ignore.
+          *
+          */
+       case 0x000e:
+         break;
          
          /*
           * Type = 0x000f: Session Length. (AIM)
@@ -227,7 +260,8 @@ int aim_extractuserinfo(u_char *buf, struct aim_userinfo_s *outinfo)
  * through aim_extractuserinfo() however.
  *
  */
-int aim_parse_oncoming_middle(struct command_rx_struct *command)
+int aim_parse_oncoming_middle(struct aim_session_t *sess,
+                             struct command_rx_struct *command)
 {
   struct aim_userinfo_s userinfo;
   u_int i = 0;
@@ -238,87 +272,95 @@ int aim_parse_oncoming_middle(struct command_rx_struct *command)
 
   userfunc = aim_callhandler(command->conn, AIM_CB_FAM_BUD, AIM_CB_BUD_ONCOMING);
   if (userfunc)
-    i = userfunc(command, &userinfo);
+    i = userfunc(sess, command, &userinfo);
 
   return 1;
 }
 
+/*
+ * Offgoing Buddy notifications contain no useful
+ * information other than the name it applies to.
+ *
+ */
+int aim_parse_offgoing_middle(struct aim_session_t *sess,
+                             struct command_rx_struct *command)
+{
+  char sn[MAXSNLEN+1];
+  u_int i = 0;
+  rxcallback_t userfunc=NULL;
+
+  /* Protect against future SN length extensions */
+  strncpy(sn, command->data+11, (((int)(command->data+10))<=MAXSNLEN)?(int)command->data+10:MAXSNLEN);
+
+  userfunc = aim_callhandler(command->conn, AIM_CB_FAM_BUD, AIM_CB_BUD_OFFGOING);
+  if (userfunc)
+    i = userfunc(sess, command, sn);
+
+  return 1;
+}
 
 /*
  * This parses the user info stuff out all nice and pretty then calls 
  * the higher-level callback (in the user app).
  *
  */
-int aim_parse_userinfo_middle(struct command_rx_struct *command)
+int aim_parse_userinfo_middle(struct aim_session_t *sess,
+                             struct command_rx_struct *command)
 {
   struct aim_userinfo_s userinfo;
   char *prof_encoding = NULL;
   char *prof = NULL;
   u_int i = 0;
   rxcallback_t userfunc=NULL;
+  struct aim_tlvlist_t *tlvlist;
 
   {
     u_long snacid = 0x000000000;
     struct aim_snac_t *snac = NULL;
 
     snacid = aimutil_get32(&command->data[6]);
-    snac = aim_remsnac(snacid);
-
-    free(snac->data);
-    free(snac);
+    snac = aim_remsnac(sess, snacid);
+
+    if (snac)
+      {
+       if (snac->data)
+         free(snac->data);
+       else
+         printf("faim: parse_userinfo_middle: warning: no ->data in cached SNAC\n");
+       free(snac);
+      }
+    else
+      printf("faim: parseuserinfo_middle: warning: no SNAC cached with for this response (%08lx)\n", snacid);
 
   }
   
   i = 10;
-  i += aim_extractuserinfo(command->data+i, &userinfo);
-
-  if (i < command->commandlen)
-    {
-      if (aimutil_get16(&command->data[i]) == 0x0001)
-        {
-          int len = 0;
-
-         len = aimutil_get16(&command->data[i+2]);
-
-          prof_encoding = (char *) malloc(len+1);
-          memcpy(prof_encoding, &(command->data[i+4]), len);
-          prof_encoding[len] = '\0';
-
-          i += (2+2+len);
-        }
-      else
-        {
-          printf("faim: userinfo: **warning: unexpected TLV after TLVblock t(%02x%02x) l(%02x%02x)\n", command->data[i], command->data[i+1], command->data[i+2], command->data[i+3]);
-          i += 2 + 2 + command->data[i+3];
-        }
-    }
 
-  if (i < command->commandlen)
-    {
-      if (aimutil_get16(&command->data[i]) == 0x0002)
-       {
-         int len = 0;
-         len = aimutil_get16(&command->data[i+2]);
-         
-         prof = (char *) malloc(len+1);
-         memcpy(prof, &(command->data[i+4]), len);
-         prof[len] = '\0';
-       }
-      else
-       printf("faim:userinfo: **warning: profile not found, but still have data\n");
-    }
+  /*
+   * extractuserinfo will give us the basic metaTLV information
+   */
+  i += aim_extractuserinfo(command->data+i, &userinfo);
+  
+  /*
+   * However, in this command, there's usually more TLVs following...
+   */ 
+  tlvlist = aim_readtlvchain(command->data+i, command->commandlen-i);
+  prof_encoding = aim_gettlv_str(tlvlist, 0x0001, 1);
+  prof = aim_gettlv_str(tlvlist, 0x0002, 1);
 
   userfunc = aim_callhandler(command->conn, AIM_CB_FAM_LOC, AIM_CB_LOC_USERINFO);
   if (userfunc)
     {
-      i = userfunc(command, 
+      i = userfunc(sess,
+                  command, 
                   &userinfo, 
                   prof_encoding, 
                   prof); 
     }
-
+  
   free(prof_encoding);
   free(prof);
+  aim_freetlvchain(&tlvlist);
 
   return 1;
 }
This page took 0.041717 seconds and 4 git commands to generate.