]> andersk Git - libfaim.git/blobdiff - aim_rxhandlers.c
Added some debugging printfs to help track down the SNAC userinf problem.
[libfaim.git] / aim_rxhandlers.c
index 196adde9ed830a0a659915be14e22aea1221d377..9fa45d9ee1826e2533b769f0ca46aa1d246f6a67 100644 (file)
-
 /*
-  aim_rxhandlers.c
-
-  This file contains most all of the incoming packet handlers, along
-  with aim_rxdispatch(), the Rx dispatcher.  Queue/list management is
-  actually done in aim_rxqueue.c.
-  
* aim_rxhandlers.c
+ *
* This file contains most all of the incoming packet handlers, along
* with aim_rxdispatch(), the Rx dispatcher.  Queue/list management is
* actually done in aim_rxqueue.c.
+ *
  */
 
+#include <faim/aim.h>
 
-#include "aim.h" /* for most everything */
-
-
-int bleck(struct command_rx_struct *workingPtr, ...)
+/*
+ * Bleck functions get called when there's no non-bleck functions
+ * around to cleanup the mess...
+ */
+int bleck(struct aim_session_t *sess,struct command_rx_struct *workingPtr, ...)
 {
   u_short family;
   u_short subtype;
-  family = (workingPtr->data[0] << 8) + workingPtr->data[1];
-  subtype = (workingPtr->data[2] << 8) + workingPtr->data[3];
-#if debug > 0
-  fprintf(stderr, "bleck: null handler for %04x/%04x\n", family, subtype);
-#endif
-  return 1;
-}
 
-int bleck2(struct command_rx_struct *workingPtr, ...)
-{
-  u_short family;
-  u_short subtype;
-  family = (workingPtr->data[0] << 8) + workingPtr->data[1];
-  subtype = (workingPtr->data[2] << 8) + workingPtr->data[3];
-  printf("OLDbleck: called for %04x/%04x -- OBSOLETE\n", family, subtype);
+  u_short maxf;
+  u_short maxs;
+
+  /* XXX: this is ugly. and big just for debugging. */
+  char *literals[14][25] = {
+    {"Invalid", 
+     NULL
+    },
+    {"General", 
+     "Invalid",
+     "Error",
+     "Client Ready",
+     "Server Ready",
+     "Service Request",
+     "Redirect",
+     "Rate Information Request",
+     "Rate Information",
+     "Rate Information Ack",
+     NULL,
+     "Rate Information Change",
+     "Server Pause",
+     NULL,
+     "Server Resume",
+     "Request Personal User Information",
+     "Personal User Information",
+     "Evil Notification",
+     NULL,
+     "Migration notice",
+     "Message of the Day",
+     "Set Privacy Flags",
+     "Well Known URL",
+     "NOP"
+    },
+    {"Location", 
+      "Invalid",
+      "Error",
+      "Request Rights",
+      "Rights Information", 
+      "Set user information", 
+      "Request User Information", 
+      "User Information", 
+      "Watcher Sub Request",
+      "Watcher Notification"
+    },
+    {"Buddy List Management", 
+      "Invalid", 
+      "Error", 
+      "Request Rights",
+      "Rights Information",
+      "Add Buddy", 
+      "Remove Buddy", 
+      "Watcher List Query", 
+      "Watcher List Response", 
+      "Watcher SubRequest", 
+      "Watcher Notification", 
+      "Reject Notification", 
+      "Oncoming Buddy", 
+      "Offgoing Buddy"
+    },
+    {"Messeging", 
+      "Invalid",
+      "Error", 
+      "Add ICBM Parameter",
+      "Remove ICBM Parameter", 
+      "Request Parameter Information",
+      "Parameter Information",
+      "Outgoing Message", 
+      "Incoming Message",
+      "Evil Request",
+      "Evil Reply", 
+      "Missed Calls",
+      "Message Error", 
+      "Host Ack"
+    },
+    {"Advertisements", 
+      "Invalid", 
+      "Error", 
+      "Request Ad",
+      "Ad Data (GIFs)"
+    },
+    {"Invitation / Client-to-Client", 
+     "Invalid",
+     "Error",
+     "Invite a Friend",
+     "Invitation Ack"
+    },
+    {"Administrative", 
+      "Invalid",
+      "Error",
+      "Information Request",
+      "Information Reply",
+      "Information Change Request",
+      "Information Chat Reply",
+      "Account Confirm Request",
+      "Account Confirm Reply",
+      "Account Delete Request",
+      "Account Delete Reply"
+    },
+    {"Popups", 
+      "Invalid",
+      "Error",
+      "Display Popup"
+    },
+    {"BOS", 
+      "Invalid",
+      "Error",
+      "Request Rights",
+      "Rights Response",
+      "Set group permission mask",
+      "Add permission list entries",
+      "Delete permission list entries",
+      "Add deny list entries",
+      "Delete deny list entries",
+      "Server Error"
+    },
+    {"User Lookup", 
+      "Invalid",
+      "Error",
+      "Search Request",
+      "Search Response"
+    },
+    {"Stats", 
+      "Invalid",
+      "Error",
+      "Set minimum report interval",
+      "Report Events"
+    },
+    {"Translate", 
+      "Invalid",
+      "Error",
+      "Translate Request",
+      "Translate Reply",
+    },
+    {"Chat Navigation", 
+      "Invalid",
+      "Error",
+      "Request rights",
+      "Request Exchange Information",
+      "Request Room Information",
+      "Request Occupant List",
+      "Search for Room",
+      "Outgoing Message", 
+      "Incoming Message",
+      "Evil Request", 
+      "Evil Reply", 
+      "Chat Error",
+    }
+  };
+
+  maxf = sizeof(literals) / sizeof(literals[0]);
+  maxs = sizeof(literals[0]) / sizeof(literals[0][0]);
+
+  family = aimutil_get16(workingPtr->data+0);
+  subtype= aimutil_get16(workingPtr->data+2);
+
+  if((family < maxf) && (subtype+1 < maxs) && (literals[family][subtype] != NULL))
+    printf("bleck: null handler for %04x/%04x (%s)\n", family, subtype, literals[family][subtype+1]);
+  else
+    printf("bleck: null handler for %04x/%04x (no literal)\n",family,subtype);
+
   return 1;
 }
 
-int aim_conn_addhandler(struct aim_conn_t *conn,
+int aim_conn_addhandler(struct aim_session_t *sess,
+                       struct aim_conn_t *conn,
                        u_short family,
                        u_short type,
                        rxcallback_t newhandler,
@@ -114,7 +262,8 @@ rxcallback_t aim_callhandler(struct aim_conn_t *conn,
   return aim_callhandler(conn, family, 0xffff);
 }
 
-int aim_callhandler_noparam(struct aim_conn_t *conn,
+int aim_callhandler_noparam(struct aim_session_t *sess,
+                           struct aim_conn_t *conn,
                            u_short family,
                            u_short type,
                            struct command_rx_struct *ptr)
@@ -122,7 +271,7 @@ int aim_callhandler_noparam(struct aim_conn_t *conn,
   rxcallback_t userfunc = NULL;
   userfunc = aim_callhandler(conn, family, type);
   if (userfunc)
-    return userfunc(ptr);
+    return userfunc(sess, ptr);
   return 0;
 }
 
@@ -149,165 +298,204 @@ int aim_callhandler_noparam(struct aim_conn_t *conn,
   TODO: Allow for NULL handlers.
   
  */
-int aim_rxdispatch(void)
+int aim_rxdispatch(struct aim_session_t *sess)
 {
   int i = 0;
   struct command_rx_struct *workingPtr = NULL;
   
-  if (aim_queue_incoming == NULL)
+  if (sess->queue_incoming == NULL)
     /* this shouldn't really happen, unless the main loop's select is broke  */
     printf("parse_generic: incoming packet queue empty.\n");
   else
     {
-      workingPtr = aim_queue_incoming;
+      workingPtr = sess->queue_incoming;
       for (i = 0; workingPtr != NULL; i++)
        {
          switch(workingPtr->conn->type)
            {
            case AIM_CONN_TYPE_AUTH:
-             if ( (workingPtr->data[0] == 0x00) && 
-                  (workingPtr->data[1] == 0x00) &&
-                  (workingPtr->data[2] == 0x00) &&
-                  (workingPtr->data[3] == 0x01) )
-               {
+             {
+               u_long head;
+
+               head = aimutil_get32(workingPtr->data);
+               if (head == 0x00000001)
+                 {
 #if debug > 0
-                 fprintf(stderr, "got connection ack on auth line\n");
+                   printf("got connection ack on auth line\n");
 #endif
-                 workingPtr->handled = 1;
-               }
-             else
-               {
-                 /* any user callbacks will be called from here */
-                 workingPtr->handled = aim_authparse(workingPtr);
-               }
+                   workingPtr->handled = 1;
+                 }
+               else
+                 {
+                   u_short family,subtype;
+
+                   family = aimutil_get16(workingPtr->data);
+                   subtype = aimutil_get16(workingPtr->data+2);
+                   
+                   switch (family)
+                     {
+                       /* New login protocol */
+#ifdef SNACLOGIN
+                     case 0x0017:
+                       if (subtype == 0x0001)
+                         workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0017, 0x0001, workingPtr);
+                       else if (subtype == 0x0003)
+                         workingPtr->handled = aim_authparse(sess, workingPtr);
+                       else if (subtype == 0x0007)
+                         workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0017, 0x0007, workingPtr);
+                       else
+                         workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0017, 0xffff, workingPtr);
+                       break;
+#else
+                       /* XXX: this isnt foolproof */
+                     case 0x0001:
+                       if (subtype == 0x0003)
+                         workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, AIM_CB_FAM_GEN, AIM_CB_GEN_SERVERREADY, workingPtr);
+                       else
+                         workingPtr->handled = aim_authparse(sess, workingPtr);
+                       break;
+                     case 0x0007:
+                       if (subtype == 0x0005)
+                         workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, AIM_CB_FAM_ADM, AIM_CB_ADM_INFOCHANGE_REPLY, workingPtr);
+                       break;
+                     default:
+                       /* Old login protocol */
+                       /* any user callbacks will be called from here */
+                       workingPtr->handled = aim_authparse(sess, workingPtr);
+#endif
+                     }
+                 }
+             }
              break;
            case AIM_CONN_TYPE_BOS:
              {
                u_short family;
                u_short subtype;
-               family = (workingPtr->data[0] << 8) + workingPtr->data[1];
-               subtype = (workingPtr->data[2] << 8) + workingPtr->data[3];
+
+               family = aimutil_get16(workingPtr->data);
+               subtype = aimutil_get16(workingPtr->data+2);
+
                switch (family)
                  {
                  case 0x0000: /* not really a family, but it works */
                    if (subtype == 0x0001)
-                     workingPtr->handled = aim_callhandler_noparam(workingPtr->conn, 0x0000, 0x0001, workingPtr);
+                     workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0000, 0x0001, workingPtr);
                    else
-                     workingPtr->handled = aim_callhandler_noparam(workingPtr->conn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_UNKNOWN, workingPtr);
+                     workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_UNKNOWN, workingPtr);
                    break;
                  case 0x0001: /* Family: General */
                    switch (subtype)
                      {
                      case 0x0001:
-                       workingPtr->handled = aim_parse_generalerrs(workingPtr);
+                       workingPtr->handled = aim_parse_generalerrs(sess, workingPtr);
                        break;
                      case 0x0003:
-                       workingPtr->handled = aim_callhandler_noparam(workingPtr->conn, 0x0001, 0x0003, workingPtr);
+                       workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0001, 0x0003, workingPtr);
                        break;
                      case 0x0005:
-                       workingPtr->handled = aim_handleredirect_middle(workingPtr);
+                       workingPtr->handled = aim_handleredirect_middle(sess, workingPtr);
                        break;
                      case 0x0007:
-                       workingPtr->handled = aim_callhandler_noparam(workingPtr->conn, 0x0001, 0x0007, workingPtr);
+                       workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0001, 0x0007, workingPtr);
                        break;
                      case 0x000a:
-                       workingPtr->handled = aim_callhandler_noparam(workingPtr->conn, 0x0001, 0x000a, workingPtr);
+                       workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0001, 0x000a, workingPtr);
                        break;
                      case 0x000f:
-                       workingPtr->handled = aim_callhandler_noparam(workingPtr->conn, 0x0001, 0x000f, workingPtr);
+                       workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0001, 0x000f, workingPtr);
                        break;
                      case 0x0013:
-                       workingPtr->handled = aim_callhandler_noparam(workingPtr->conn, 0x0001, 0x0013, workingPtr);
+                       workingPtr->handled = aim_parsemotd_middle(sess, workingPtr);
                        break;
                      default:
-                       workingPtr->handled = aim_callhandler_noparam(workingPtr->conn, AIM_CB_FAM_GEN, AIM_CB_GEN_DEFAULT, workingPtr);
+                       workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, AIM_CB_FAM_GEN, AIM_CB_GEN_DEFAULT, workingPtr);
                      }
                    break;
                  case 0x0002: /* Family: Location */
                    switch (subtype)
                      {
                      case 0x0001:
-                       workingPtr->handled = aim_callhandler_noparam(workingPtr->conn, 0x0002, 0x0001, workingPtr);
+                       workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0002, 0x0001, workingPtr);
                        break;
                      case 0x0003:
-                       workingPtr->handled = aim_callhandler_noparam(workingPtr->conn, 0x0002, 0x0003, workingPtr);
+                       workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0002, 0x0003, workingPtr);
                        break;
                      case 0x0006:
-                       workingPtr->handled = aim_parse_userinfo_middle(workingPtr);
+                       workingPtr->handled = aim_parse_userinfo_middle(sess, workingPtr);
                        break;
                      default:
-                       workingPtr->handled = aim_callhandler_noparam(workingPtr->conn, AIM_CB_FAM_LOC, AIM_CB_LOC_DEFAULT, workingPtr);
+                       workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, AIM_CB_FAM_LOC, AIM_CB_LOC_DEFAULT, workingPtr);
                      }
                    break;
                  case 0x0003: /* Family: Buddy List */
                    switch (subtype)
                      {
                      case 0x0001:
-                       workingPtr->handled = aim_parse_generalerrs(workingPtr);
+                       workingPtr->handled = aim_parse_generalerrs(sess, workingPtr);
                        break;
                      case 0x0003:
-                       workingPtr->handled = aim_callhandler_noparam(workingPtr->conn, 0x0003, 0x0003, workingPtr);
+                       workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0003, 0x0003, workingPtr);
                        break;
                      case 0x000b: /* oncoming buddy */
-                       workingPtr->handled = aim_parse_oncoming_middle(workingPtr);
+                       workingPtr->handled = aim_parse_oncoming_middle(sess, workingPtr);
                        break;
                      case 0x000c: /* offgoing buddy */
-                       workingPtr->handled = aim_callhandler_noparam(workingPtr->conn, 0x0003, 0x000c, workingPtr);
+                       workingPtr->handled = aim_parse_offgoing_middle(sess, workingPtr);
                        break;
                      default:
-                       workingPtr->handled = aim_callhandler_noparam(workingPtr->conn, AIM_CB_FAM_BUD, AIM_CB_BUD_DEFAULT, workingPtr);
+                       workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, AIM_CB_FAM_BUD, AIM_CB_BUD_DEFAULT, workingPtr);
                      }
                    break;
                  case 0x0004: /* Family: Messeging */
                    switch (subtype)
                      {
                      case 0x0001:
-                       workingPtr->handled = aim_callhandler_noparam(workingPtr->conn, 0x0004, 0x0001, workingPtr);
+                       workingPtr->handled = aim_parse_msgerror_middle(sess, workingPtr);
                        break;
                      case 0x0005:
-                       workingPtr->handled = aim_callhandler_noparam(workingPtr->conn, 0x0004, 0x0005, workingPtr);
+                       workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0004, 0x0005, workingPtr);
                        break;
                      case 0x0007:
-                       workingPtr->handled = aim_parse_incoming_im_middle(workingPtr);
+                       workingPtr->handled = aim_parse_incoming_im_middle(sess, workingPtr);
                        break;
                      case 0x000a:
-                       workingPtr->handled = aim_callhandler_noparam(workingPtr->conn, 0x0004, 0x000a, workingPtr);
+                       workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0004, 0x000a, workingPtr);
                        break;
                      default:
-                       workingPtr->handled = aim_callhandler_noparam(workingPtr->conn, AIM_CB_FAM_MSG, AIM_CB_MSG_DEFAULT, workingPtr);
+                       workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, AIM_CB_FAM_MSG, AIM_CB_MSG_DEFAULT, workingPtr);
                      }
                    break;
                  case 0x0009:
                    if (subtype == 0x0001)
-                     workingPtr->handled = aim_parse_generalerrs(workingPtr);
+                     workingPtr->handled = aim_parse_generalerrs(sess, workingPtr);
                    else if (subtype == 0x0003)
-                     workingPtr->handled = aim_callhandler_noparam(workingPtr->conn, 0x0009, 0x0003, workingPtr);
+                     workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0009, 0x0003, workingPtr);
                    else
-                     workingPtr->handled = aim_callhandler_noparam(workingPtr->conn, AIM_CB_FAM_BOS, AIM_CB_BOS_DEFAULT, workingPtr);
+                     workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, AIM_CB_FAM_BOS, AIM_CB_BOS_DEFAULT, workingPtr);
                    break;
                  case 0x000a:  /* Family: User lookup */
                    switch (subtype)
                      {
                      case 0x0001:
-                       workingPtr->handled = aim_callhandler_noparam(workingPtr->conn, 0x000a, 0x0001, workingPtr);
+                       workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x000a, 0x0001, workingPtr);
                        break;
                      case 0x0003:
-                       workingPtr->handled = aim_callhandler_noparam(workingPtr->conn, 0x000a, 0x0003, workingPtr);
+                       workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x000a, 0x0003, workingPtr);
                        break;
                      default:
-                       workingPtr->handled = aim_callhandler_noparam(workingPtr->conn, AIM_CB_FAM_LOK, AIM_CB_LOK_DEFAULT, workingPtr);
+                       workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, AIM_CB_FAM_LOK, AIM_CB_LOK_DEFAULT, workingPtr);
                      }
                    break;
                  case 0x000b:
                    if (subtype == 0x0001)
-                     workingPtr->handled = aim_parse_generalerrs(workingPtr);
+                     workingPtr->handled = aim_parse_generalerrs(sess, workingPtr);
                    else if (subtype == 0x0002)
-                     workingPtr->handled = aim_callhandler_noparam(workingPtr->conn, 0x000b, 0x0002, workingPtr);
+                     workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x000b, 0x0002, workingPtr);
                    else
-                     workingPtr->handled = aim_callhandler_noparam(workingPtr->conn, AIM_CB_FAM_STS, AIM_CB_STS_DEFAULT, workingPtr);
+                     workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, AIM_CB_FAM_STS, AIM_CB_STS_DEFAULT, workingPtr);
                    break;
                  default:
-                   workingPtr->handled = aim_callhandler_noparam(workingPtr->conn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_UNKNOWN, workingPtr);
+                   workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_UNKNOWN, workingPtr);
                    break;
                  }
              }
@@ -316,229 +504,154 @@ int aim_rxdispatch(void)
              {
                u_short family;
                u_short subtype;
-               family = (workingPtr->data[0] << 8) + workingPtr->data[1];
-               subtype = (workingPtr->data[2] << 8) + workingPtr->data[3];
-               if ( (workingPtr->data[0] == 0x00) &&
-                    (workingPtr->data[1] == 0x02) &&
-                    (workingPtr->data[2] == 0x00) &&
-                    (workingPtr->data[3] == 0x06) )
+               family = aimutil_get16(workingPtr->data);
+               subtype= aimutil_get16(workingPtr->data+2);
+
+               if ((family == 0x0002) && (subtype == 0x0006))
                  {
                    workingPtr->handled = 1;
                    aim_conn_setstatus(workingPtr->conn, AIM_CONN_STATUS_READY);
                  }
+               else if ((family == 0x000d) && (subtype == 0x0009))
+                 workingPtr->handled = aim_chatnav_parse_info(sess, workingPtr);
                else
                  {
-                   workingPtr->handled = aim_callhandler_noparam(workingPtr->conn, family, subtype, workingPtr);
+                   workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, family, subtype, workingPtr);
                  }
              }
              break;
            case AIM_CONN_TYPE_CHAT:
-             fprintf(stderr, "\nAHH! Dont know what to do with CHAT stuff yet!\n");
-             workingPtr->handled = aim_callhandler_noparam(workingPtr->conn, AIM_CB_FAM_CHT, AIM_CB_CHT_DEFAULT, workingPtr);
+             {
+               u_short family, subtype;
+
+               family = aimutil_get16(workingPtr->data);
+               subtype= aimutil_get16(workingPtr->data+2);
+               
+               if ((family == 0x0000) && (subtype == 0x00001))
+                 workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0000, 0x0001, workingPtr);
+               else if (family == 0x0001)
+                 {
+                   if (subtype == 0x0001)
+                     workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0001, 0x0001, workingPtr);
+                   else if (subtype == 0x0003)
+                     workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0001, 0x0003, workingPtr);
+                   else if (subtype == 0x0007)
+                     workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0001, 0x0007, workingPtr);
+                   else
+                     printf("Chat: unknown snac %04x/%04x\n", family, subtype);
+                 }
+               else if (family == 0x000e)
+                 {
+                   if (subtype == 0x0002)
+                     workingPtr->handled = aim_chat_parse_infoupdate(sess, workingPtr);
+                   else if (subtype == 0x0003)
+                     workingPtr->handled = aim_chat_parse_joined(sess, workingPtr);    
+                   else if (subtype == 0x0004)
+                     workingPtr->handled = aim_chat_parse_leave(sess, workingPtr);     
+                   else if (subtype == 0x0006)
+                     workingPtr->handled = aim_chat_parse_incoming(sess, workingPtr);
+                   else        
+                     printf("Chat: unknown snac %04x/%04x\n", family, subtype); 
+                 }
+               else
+                 {
+                   printf("Chat: unknown snac %04x/%04x\n", family, subtype);
+                   workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, AIM_CB_FAM_CHT, AIM_CB_CHT_DEFAULT, workingPtr);
+                 }
+             }
              break;
            default:
-             fprintf(stderr, "\nAHHHHH! UNKNOWN CONNECTION TYPE! (0x%02x)\n\n", workingPtr->conn->type);
-             workingPtr->handled = aim_callhandler_noparam(workingPtr->conn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_UNKNOWN, workingPtr);
+             printf("\nAHHHHH! UNKNOWN CONNECTION TYPE! (0x%02x)\n\n", workingPtr->conn->type);
+             workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_UNKNOWN, workingPtr);
              break;
            }
-             /* move to next command */
+         /* move to next command */
          workingPtr = workingPtr->next;
        }
     }
 
-  aim_queue_incoming = aim_purge_rxqueue(aim_queue_incoming);
+  sess->queue_incoming = aim_purge_rxqueue(sess->queue_incoming);
   
   return 0;
 }
 
-/*
- * TODO: check and cure memory leakage in this function.
- */
-int aim_authparse(struct command_rx_struct *command)
+int aim_parsemotd_middle(struct aim_session_t *sess,
+                             struct command_rx_struct *command, ...)
 {
   rxcallback_t userfunc = NULL;
-  int iserror = 0;
-  struct aim_tlv_t *tlv = NULL;
-  char *errorurl = NULL;
-  short errorcode = 0x00;
-  u_int z = 0;
-
-  if ( (command->data[0] == 0x00) &&
-       (command->data[1] == 0x01) &&
-       (command->data[2] == 0x00) &&
-       (command->data[3] == 0x03) )
-    {
-      /* "server ready"  -- can be ignored */
-      userfunc = aim_callhandler(command->conn, AIM_CB_FAM_GEN, AIM_CB_GEN_SERVERREADY);
-    }
-  else if ( (command->data[0] == 0x00) &&
-           (command->data[1] == 0x07) &&
-           (command->data[2] == 0x00) &&
-           (command->data[3] == 0x05) )
-    {
-      /* "information change reply" */
-      userfunc = aim_callhandler(command->conn, AIM_CB_FAM_ADM, AIM_CB_ADM_INFOCHANGE_REPLY);
-    }
-  else
-    {
-      /* anything else -- usually used for login; just parse as pure TLVs */
-
-      /*
-       * Free up the loginstruct first.
-       */
-      if (aim_logininfo.screen_name)
-       {
-         free(aim_logininfo.screen_name);
-         aim_logininfo.screen_name = NULL;
-       }
-      if (aim_logininfo.BOSIP)
-       {
-         free(aim_logininfo.BOSIP);
-         aim_logininfo.BOSIP = NULL;
-       }
-      if (aim_logininfo.cookie)
-       {
-         free(aim_logininfo.cookie);
-         aim_logininfo.cookie = NULL;
-       }
-      if (aim_logininfo.email)
-       {
-         free(aim_logininfo.email);
-         aim_logininfo.email = NULL;
-       }
-      aim_logininfo.regstatus = 0;
-
-      /* all this block does is figure out if it's an
-        error or a success, nothing more */
-      while (z < command->commandlen)
-       {
-         tlv = aim_grabtlvstr(&(command->data[z]));
-         switch(tlv->type) 
-           {
-           case 0x0001: /* screen name */
-             aim_logininfo.screen_name = tlv->value;
-             z += 2 + 2 + tlv->length;
-             free(tlv);
-             tlv = NULL;
-             break;
-           case 0x0004: /* error URL */
-             errorurl = tlv->value;
-             z += 2 + 2 + tlv->length;
-             free(tlv);
-             tlv = NULL;
-             break;
-           case 0x0005: /* BOS IP */
-             aim_logininfo.BOSIP = tlv->value;
-             z += 2 + 2 + tlv->length;
-             free(tlv);
-             tlv = NULL;
-             break;
-           case 0x0006: /* auth cookie */
-             aim_logininfo.cookie = tlv->value;
-             z += 2 + 2 + tlv->length;
-             free(tlv);
-             tlv=NULL;
-             break;
-           case 0x0011: /* email addy */
-             aim_logininfo.email = tlv->value;
-             z += 2 + 2 + tlv->length;
-             free(tlv);
-             tlv = NULL;
-             break;
-           case 0x0013: /* registration status */
-             aim_logininfo.regstatus = *(tlv->value);
-             z += 2 + 2 + tlv->length;
-             aim_freetlv(&tlv);
-             break;
-           case 0x0008: /* error code */
-             errorcode = *(tlv->value);
-             z += 2 + 2 + tlv->length;
-             aim_freetlv(&tlv);
-             iserror = 1;
-             break;
-           default:
-         z += 2 + 2 + tlv->length;
-         aim_freetlv(&tlv);
-         /* dunno */
-           }
-       }
+  char *msg;
+  int ret=1;
+  struct aim_tlvlist_t *tlvlist;
+  u_short id;
+
+  /*
+   * Dunno.
+   */
+  id = aimutil_get16(command->data+10);
+
+  /* 
+   * TLVs follow 
+   */
+  tlvlist = aim_readtlvchain(command->data+12, command->commandlen-12);
+  
+  msg = aim_gettlv_str(tlvlist, 0x000b, 1);
+  
+  userfunc = aim_callhandler(command->conn, 0x0001, 0x0013);
+  if (userfunc)
+    ret =  userfunc(sess, command, id, msg);
 
-      if (iserror && 
-         errorurl)
-       {
-         userfunc = aim_callhandler(command->conn, AIM_CB_FAM_GEN, AIM_CB_GEN_ERROR);
-         if (userfunc)
-           return userfunc(command, &aim_logininfo, errorurl, errorcode);
-         return 0;
-       }
-      else if (aim_logininfo.screen_name && 
-              aim_logininfo.cookie && aim_logininfo.BOSIP)
-       {
-         userfunc = aim_callhandler(command->conn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_AUTHSUCCESS);
-         if (userfunc)
-           return userfunc(command, &aim_logininfo);
-         return 0;
-       }
-      else
-       userfunc = aim_callhandler(command->conn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_AUTHOTHER);
-    }
+  aim_freetlvchain(&tlvlist);
 
-  if (userfunc)
-    return userfunc(command);
-  printf("handler not available!\n");
-  return 0;
+  return ret;
+  
 }
 
-/*
- * TODO: check for and cure any memory leaks here.
- */
-int aim_handleredirect_middle(struct command_rx_struct *command, ...)
+int aim_handleredirect_middle(struct aim_session_t *sess,
+                             struct command_rx_struct *command, ...)
 {
-  struct aim_tlv_t *tlv = NULL;
-  u_int z = 10;
+  struct aim_tlv_t *tmptlv = NULL;
   int serviceid = 0x00;
-  char *cookie = NULL;
+  char cookie[AIM_COOKIELEN];
   char *ip = NULL;
   rxcallback_t userfunc = NULL;
+  struct aim_tlvlist_t *tlvlist;
+  int ret = 1;
+  
+  tlvlist = aim_readtlvchain(command->data+10, command->commandlen-10);
+  
+  tmptlv = aim_gettlv(tlvlist, 0x000d, 1);
+  serviceid = aimutil_get16(tmptlv->value);
+
+  ip = aim_gettlv_str(tlvlist, 0x0005, 1);
+  
+  tmptlv = aim_gettlv(tlvlist, 0x0006, 1);
+  memcpy(cookie, tmptlv->value, AIM_COOKIELEN);
 
-  while (z < command->commandlen)
+  if (serviceid == AIM_CONN_TYPE_CHAT)
     {
-      tlv = aim_grabtlvstr(&(command->data[z]));
-      switch(tlv->type)
-       {
-       case 0x000d:  /* service id */
-         aim_freetlv(&tlv);
-         /* regrab as an int */
-         tlv = aim_grabtlv(&(command->data[z]));
-         serviceid = (tlv->value[0] << 8) + tlv->value[1]; /* hehe */
-         z += 2 + 2 + tlv->length;
-         aim_freetlv(&tlv);
-         break;
-       case 0x0005:  /* service server IP */
-         ip = tlv->value;
-         z += 2 + 2 + tlv->length;
-         free(tlv);
-         tlv = NULL;
-         break;
-       case 0x0006: /* auth cookie */
-         cookie = tlv->value;
-         z += 2 + 2 + tlv->length;
-         free(tlv);
-         tlv = NULL;
-         break;
-       default:
-         /* dunno */
-         z += 2 + 2 + tlv->length;
-         aim_freetlv(&tlv);
-       }
+      /*
+       * Chat hack.
+       *
+       */
+      userfunc = aim_callhandler(command->conn, 0x0001, 0x0005);
+      if (userfunc)
+       ret =  userfunc(sess, command, serviceid, ip, cookie, sess->pendingjoin);
+      free(sess->pendingjoin);
+      sess->pendingjoin = NULL;
     }
-  userfunc = aim_callhandler(command->conn, 0x0001, 0x0005);
-  if (userfunc)
-    return userfunc(command, serviceid, ip, cookie);
-  return 0;
+  else
+    {
+      userfunc = aim_callhandler(command->conn, 0x0001, 0x0005);
+      if (userfunc)
+       ret =  userfunc(sess, command, serviceid, ip, cookie);
+    }
+  aim_freetlvchain(&tlvlist);
+
+  return ret;
 }
 
-int aim_parse_unknown(struct command_rx_struct *command, ...)
+int aim_parse_unknown(struct aim_session_t *sess,
+                     struct command_rx_struct *command, ...)
 {
   u_int i = 0;
 
@@ -564,18 +677,20 @@ int aim_parse_unknown(struct command_rx_struct *command, ...)
  * Middle handler for 0x0001 snac of each family.
  *
  */
-int aim_parse_generalerrs(struct command_rx_struct *command, ...)
+int aim_parse_generalerrs(struct aim_session_t *sess,
+                         struct command_rx_struct *command, ...)
 {
   u_short family;
   u_short subtype;
-  family = (command->data[0] << 8) + command->data[1];
-  subtype = (command->data[2] << 8) + command->data[3];
+  
+  family = aimutil_get16(command->data+0);
+  subtype= aimutil_get16(command->data+2);
   
   switch(family)
     {
     default:
       /* Unknown family */
-      return aim_callhandler_noparam(command->conn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_UNKNOWN, command);
+      return aim_callhandler_noparam(sess, command->conn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_UNKNOWN, command);
     }
 
   return 1;
This page took 0.084504 seconds and 4 git commands to generate.