]> andersk Git - libfaim.git/blobdiff - src/rxhandlers.c
- Mon Sep 3 18:48:26 PDT 2001
[libfaim.git] / src / rxhandlers.c
index 19baded0cf9071f1bbf2c8f02eb9dab7386e34af..33b51f0d8e547200858a082acd715b14141d62b3 100644 (file)
 #define FAIM_INTERNAL
 #include <aim.h>
 
-static aim_module_t *findmodule(struct aim_session_t *sess, const char *name)
+struct aim_rxcblist_s {
+       fu16_t family;
+       fu16_t type;
+       aim_rxcallback_t handler;
+       u_short flags;
+       struct aim_rxcblist_s *next;
+};
+
+static aim_module_t *findmodule(aim_session_t *sess, const char *name)
 {
-  aim_module_t *cur;
+       aim_module_t *cur;
 
-  for (cur = (aim_module_t *)sess->modlistv; cur; cur = cur->next) {
-    if (strcmp(name, cur->name) == 0)
-      return cur;
-  }
+       for (cur = (aim_module_t *)sess->modlistv; cur; cur = cur->next) {
+               if (strcmp(name, cur->name) == 0)
+                       return cur;
+       }
 
-  return NULL;
+       return NULL;
 }
 
-faim_internal int aim__registermodule(struct aim_session_t *sess, int (*modfirst)(struct aim_session_t *, aim_module_t *))
+faim_internal int aim__registermodule(aim_session_t *sess, int (*modfirst)(aim_session_t *, aim_module_t *))
 {
-  aim_module_t *mod;
+       aim_module_t *mod;
 
-  if (!sess || !modfirst)
-    return -1;
+       if (!sess || !modfirst)
+               return -1;
 
-  if (!(mod = malloc(sizeof(aim_module_t))))
-    return -1;
-  memset(mod, 0, sizeof(aim_module_t));
+       if (!(mod = malloc(sizeof(aim_module_t))))
+               return -1;
+       memset(mod, 0, sizeof(aim_module_t));
 
-  if (modfirst(sess, mod) == -1) {
-    free(mod);
-    return -1;
-  }
+       if (modfirst(sess, mod) == -1) {
+               free(mod);
+               return -1;
+       }
 
-  if (findmodule(sess, mod->name)) {
-    if (mod->shutdown)
-      mod->shutdown(sess, mod);
-    free(mod);
-    return -1;
-  }
+       if (findmodule(sess, mod->name)) {
+               if (mod->shutdown)
+                       mod->shutdown(sess, mod);
+               free(mod);
+               return -1;
+       }
 
-  mod->next = (aim_module_t *)sess->modlistv;
-  (aim_module_t *)sess->modlistv = mod;
+       mod->next = (aim_module_t *)sess->modlistv;
+       (aim_module_t *)sess->modlistv = mod;
 
-  faimdprintf(sess, 1, "registered module %s (family 0x%04x)\n", mod->name, mod->family);
+       faimdprintf(sess, 1, "registered module %s (family 0x%04x)\n", mod->name, mod->family);
 
-  return 0;
+       return 0;
 }
 
-faim_internal void aim__shutdownmodules(struct aim_session_t *sess)
+faim_internal void aim__shutdownmodules(aim_session_t *sess)
 {
-  aim_module_t *cur;
+       aim_module_t *cur;
 
-  for (cur = (aim_module_t *)sess->modlistv; cur; ) {
-    aim_module_t *tmp;
+       for (cur = (aim_module_t *)sess->modlistv; cur; ) {
+               aim_module_t *tmp;
 
-    tmp = cur->next;
+               tmp = cur->next;
 
-    if (cur->shutdown)
-      cur->shutdown(sess, cur);
+               if (cur->shutdown)
+                       cur->shutdown(sess, cur);
 
-    free(cur);
+               free(cur);
 
-    cur = tmp;
-  }
+               cur = tmp;
+       }
 
-  sess->modlistv = NULL;
+       sess->modlistv = NULL;
 
-  return;
+       return;
 }
 
-static int consumesnac(struct aim_session_t *sess, struct command_rx_struct *rx)
+static int consumesnac(aim_session_t *sess, aim_frame_t *rx)
 {
-  aim_module_t *cur;
-  aim_modsnac_t snac;
+       aim_module_t *cur;
+       aim_modsnac_t snac;
 
-  snac.family = aimutil_get16(rx->data+0);
-  snac.subtype = aimutil_get16(rx->data+2);
-  snac.flags = aimutil_get16(rx->data+4);
-  snac.id = aimutil_get32(rx->data+6);
+       if (aim_bstream_empty(&rx->data) < 10)
+               return 0;
 
-  for (cur = (aim_module_t *)sess->modlistv; cur; cur = cur->next) {
+       snac.family = aimbs_get16(&rx->data);
+       snac.subtype = aimbs_get16(&rx->data);
+       snac.flags = aimbs_get16(&rx->data);
+       snac.id = aimbs_get32(&rx->data);
 
-    if (!(cur->flags & AIM_MODFLAG_MULTIFAMILY) && 
-       (cur->family != snac.family))
-      continue;
+       for (cur = (aim_module_t *)sess->modlistv; cur; cur = cur->next) {
 
-    if (cur->snachandler(sess, cur, rx, &snac, rx->data+10, rx->commandlen-10))
-      return 1;
+               if (!(cur->flags & AIM_MODFLAG_MULTIFAMILY) && 
+                               (cur->family != snac.family))
+                       continue;
 
-  }
+               if (cur->snachandler(sess, cur, rx, &snac, &rx->data))
+                       return 1;
 
-  return 0;
+       }
+
+       return 0;
 }
 
-static int consumenonsnac(struct aim_session_t *sess, struct command_rx_struct *rx, unsigned short family, unsigned short subtype)
+static int consumenonsnac(aim_session_t *sess, aim_frame_t *rx, fu16_t family, fu16_t subtype)
 {
-  aim_module_t *cur;
-  aim_modsnac_t snac;
+       aim_module_t *cur;
+       aim_modsnac_t snac;
 
-  snac.family = family;
-  snac.subtype = subtype;
-  snac.flags = snac.id = 0;
+       snac.family = family;
+       snac.subtype = subtype;
+       snac.flags = snac.id = 0;
 
-  for (cur = (aim_module_t *)sess->modlistv; cur; cur = cur->next) {
+       for (cur = (aim_module_t *)sess->modlistv; cur; cur = cur->next) {
 
-    if (!(cur->flags & AIM_MODFLAG_MULTIFAMILY) && 
-       (cur->family != snac.family))
-      continue;
+               if (!(cur->flags & AIM_MODFLAG_MULTIFAMILY) && 
+                               (cur->family != snac.family))
+                       continue;
 
-    if (cur->snachandler(sess, cur, rx, &snac, rx->data, rx->commandlen))
-      return 1;
+               if (cur->snachandler(sess, cur, rx, &snac, &rx->data))
+                       return 1;
 
-  }
+       }
 
-  return 0;
+       return 0;
+}
+
+static int negchan_middle(aim_session_t *sess, aim_frame_t *fr)
+{
+       aim_tlvlist_t *tlvlist;
+       char *msg = NULL;
+       fu16_t code = 0;
+       aim_rxcallback_t userfunc;
+       int ret = 1;
+
+       if (aim_bstream_empty(&fr->data) == 0) {
+               /* XXX should do something with this */
+               return 1;
+       }
+
+       /* Used only by the older login protocol */
+       /* XXX remove this special case? */
+       if (fr->conn->type == AIM_CONN_TYPE_AUTH)
+               return consumenonsnac(sess, fr, 0x0017, 0x0003);
+
+       tlvlist = aim_readtlvchain(&fr->data);
+
+       if (aim_gettlv(tlvlist, 0x0009, 1))
+               code = aim_gettlv16(tlvlist, 0x0009, 1);
+
+       if (aim_gettlv(tlvlist, 0x000b, 1))
+               msg = aim_gettlv_str(tlvlist, 0x000b, 1);
+
+       if ((userfunc = aim_callhandler(sess, fr->conn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNERR))) 
+               ret = userfunc(sess, fr, code, msg);
+
+       aim_freetlvchain(&tlvlist);
+
+       free(msg);
+
+       return ret;
 }
 
 /*
  * Bleck functions get called when there's no non-bleck functions
  * around to cleanup the mess...
  */
-faim_internal int bleck(struct aim_session_t *sess,struct command_rx_struct *workingPtr, ...)
+faim_internal int bleck(aim_session_t *sess, aim_frame_t *frame, ...)
 {
-  u_short family;
-  u_short 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))
-    faimdprintf(sess, 0, "bleck: null handler for %04x/%04x (%s)\n", family, subtype, literals[family][subtype+1]);
-  else
-    faimdprintf(sess, 0, "bleck: null handler for %04x/%04x (no literal)\n",family,subtype);
-
-  return 1;
+       fu16_t family, subtype;
+       fu16_t maxf, maxs;
+
+       static const char *channels[6] = {
+               "Invalid (0)",
+               "FLAP Version",
+               "SNAC",
+               "Invalid (3)",
+               "Negotiation",
+               "FLAP NOP"
+       };
+       static const int maxchannels = 5;
+       
+       /* XXX: this is ugly. and big just for debugging. */
+       static const 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]);
+
+       if (frame->hdr.flap.type == 0x02) {
+
+               family = aimbs_get16(&frame->data);
+               subtype = aimbs_get16(&frame->data);
+               
+               if ((family < maxf) && (subtype+1 < maxs) && (literals[family][subtype] != NULL))
+                       faimdprintf(sess, 0, "bleck: channel %s: null handler for %04x/%04x (%s)\n", channels[frame->hdr.flap.type], family, subtype, literals[family][subtype+1]);
+               else
+                       faimdprintf(sess, 0, "bleck: channel %s: null handler for %04x/%04x (no literal)\n", channels[frame->hdr.flap.type], family, subtype);
+       } else {
+
+               if (frame->hdr.flap.type <= maxchannels)
+                       faimdprintf(sess, 0, "bleck: channel %s (0x%02x)\n", channels[frame->hdr.flap.type], frame->hdr.flap.type);
+               else
+                       faimdprintf(sess, 0, "bleck: unknown channel 0x%02x\n", frame->hdr.flap.type);
+
+       }
+               
+       return 1;
 }
 
-faim_export int aim_conn_addhandler(struct aim_session_t *sess,
-                                   struct aim_conn_t *conn,
-                                   u_short family,
-                                   u_short type,
-                                   aim_rxcallback_t newhandler,
-                                   u_short flags)
+faim_export int aim_conn_addhandler(aim_session_t *sess, aim_conn_t *conn, fu16_t family, fu16_t type, aim_rxcallback_t newhandler, fu16_t flags)
 {
-  struct aim_rxcblist_t *newcb;
-
-  if (!conn)
-    return -1;
-
-  faimdprintf(sess, 1, "aim_conn_addhandler: adding for %04x/%04x\n", family, type);
-
-  if (!(newcb = (struct aim_rxcblist_t *)calloc(1, sizeof(struct aim_rxcblist_t))))
-    return -1;
-  newcb->family = family;
-  newcb->type = type;
-  newcb->flags = flags;
-  if (!newhandler)
-    newcb->handler = &bleck;
-  else
-    newcb->handler = newhandler;
-  newcb->next = NULL;
-  
-  if (!conn->handlerlist)
-    conn->handlerlist = newcb;
-  else {
-    struct aim_rxcblist_t *cur;
-
-    cur = conn->handlerlist;
-
-    while (cur->next)
-      cur = cur->next;
-    cur->next = newcb;
-  }
-
-  return 0;
+       struct aim_rxcblist_s *newcb;
+
+       if (!conn)
+               return -1;
+
+       faimdprintf(sess, 1, "aim_conn_addhandler: adding for %04x/%04x\n", family, type);
+
+       if (!(newcb = (struct aim_rxcblist_s *)calloc(1, sizeof(struct aim_rxcblist_s))))
+               return -1;
+
+       newcb->family = family;
+       newcb->type = type;
+       newcb->flags = flags;
+       newcb->handler = newhandler ? newhandler : bleck;
+       newcb->next = NULL;
+
+       if (!conn->handlerlist)
+               conn->handlerlist = (void *)newcb;
+       else {
+               struct aim_rxcblist_s *cur;
+
+               for (cur = (struct aim_rxcblist_s *)conn->handlerlist; cur->next; cur = cur->next)
+                       ;
+               cur->next = newcb;
+       }
+
+       return 0;
 }
 
-faim_export int aim_clearhandlers(struct aim_conn_t *conn)
+faim_export int aim_clearhandlers(aim_conn_t *conn)
 {
struct aim_rxcblist_t *cur;
      struct aim_rxcblist_s *cur;
 
- if (!conn)
-   return -1;
      if (!conn)
+               return -1;
 
for (cur = conn->handlerlist; cur; ) {
-   struct aim_rxcblist_t *tmp;
      for (cur = (struct aim_rxcblist_s *)conn->handlerlist; cur; ) {
+               struct aim_rxcblist_s *tmp;
 
-   tmp = cur->next;
-   free(cur);
-   cur = tmp;
- }
- conn->handlerlist = NULL;
+               tmp = cur->next;
+               free(cur);
+               cur = tmp;
      }
      conn->handlerlist = NULL;
 
- return 0;
      return 0;
 }
 
-faim_internal aim_rxcallback_t aim_callhandler(struct aim_session_t *sess,
-                                              struct aim_conn_t *conn,
-                                              unsigned short family,
-                                              unsigned short type)
+faim_internal aim_rxcallback_t aim_callhandler(aim_session_t *sess, aim_conn_t *conn, fu16_t family, fu16_t type)
 {
-  struct aim_rxcblist_t *cur;
+       struct aim_rxcblist_s *cur;
+
+       if (!conn)
+               return NULL;
 
-  if (!conn)
-    return NULL;
+       faimdprintf(sess, 1, "aim_callhandler: calling for %04x/%04x\n", family, type);
 
-  faimdprintf(sess, 1, "aim_callhandler: calling for %04x/%04x\n", family, type);
-  
-  for (cur = conn->handlerlist; cur; cur = cur->next) {
-    if ((cur->family == family) && (cur->type == type))
-      return cur->handler;
-  }
+       for (cur = (struct aim_rxcblist_s *)conn->handlerlist; cur; cur = cur->next) {
+               if ((cur->family == family) && (cur->type == type))
+                       return cur->handler;
+       }
 
-  if (type == AIM_CB_SPECIAL_DEFAULT) {
-    faimdprintf(sess, 1, "aim_callhandler: no default handler for family 0x%04x\n", family);
-    return NULL; /* prevent infinite recursion */
-  }
+       if (type == AIM_CB_SPECIAL_DEFAULT) {
+               faimdprintf(sess, 1, "aim_callhandler: no default handler for family 0x%04x\n", family);
+               return NULL; /* prevent infinite recursion */
+       }
 
-  faimdprintf(sess, 1, "aim_callhandler: no handler for  0x%04x/0x%04x\n", family, type);
+       faimdprintf(sess, 1, "aim_callhandler: no handler for  0x%04x/0x%04x\n", family, type);
 
-  return aim_callhandler(sess, conn, family, AIM_CB_SPECIAL_DEFAULT);
+       return aim_callhandler(sess, conn, family, AIM_CB_SPECIAL_DEFAULT);
 }
 
-faim_internal 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)
+faim_internal void aim_clonehandlers(aim_session_t *sess, aim_conn_t *dest, aim_conn_t *src)
 {
-  aim_rxcallback_t userfunc = NULL;
-  userfunc = aim_callhandler(sess, conn, family, type);
-  if (userfunc)
-    return userfunc(sess, ptr);
-  return 1; /* XXX */
-}
+       struct aim_rxcblist_s *cur;
 
-/*
-  aim_rxdispatch()
-
-  Basically, heres what this should do:
-    1) Determine correct packet handler for this packet
-    2) Mark the packet handled (so it can be dequeued in purge_queue())
-    3) Send the packet to the packet handler
-    4) Go to next packet in the queue and start over
-    5) When done, run purge_queue() to purge handled commands
-
-  Note that any unhandlable packets should probably be left in the
-  queue.  This is the best way to prevent data loss.  This means
-  that a single packet may get looked at by this function multiple
-  times.  This is more good than bad!  This behavior may change.
-
-  Aren't queue's fun? 
-
-  TODO: Get rid of all the ugly if's.
-  TODO: Clean up.
-  TODO: More support for mid-level handlers.
-  TODO: Allow for NULL handlers.
-  
- */
-faim_export int aim_rxdispatch(struct aim_session_t *sess)
-{
-  int i = 0;
-  struct command_rx_struct *workingPtr = NULL;
-  static int critical = 0;
-  
-  if (critical)
-    return 0; /* don't call recursively! */
-
-  critical = 1;
-
-  if (sess->queue_incoming == NULL) {
-    faimdprintf(sess, 1, "parse_generic: incoming packet queue empty.\n");
-  } else {
-    workingPtr = sess->queue_incoming;
-    for (i = 0; workingPtr != NULL; workingPtr = workingPtr->next, i++) {
-      unsigned short family,subtype;
-
-      /*
-       * XXX: This is still fairly ugly.
-       */
-      if (workingPtr->handled)
-       continue;
-
-      /*
-       * This is a debugging/sanity check only and probably could/should be removed
-       * for stable code.
-       */
-      if (((workingPtr->hdrtype == AIM_FRAMETYPE_OFT) && 
-          (workingPtr->conn->type != AIM_CONN_TYPE_RENDEZVOUS)) || 
-         ((workingPtr->hdrtype == AIM_FRAMETYPE_OSCAR) && 
-          (workingPtr->conn->type == AIM_CONN_TYPE_RENDEZVOUS))) {
-       faimdprintf(sess, 0, "rxhandlers: incompatible frame type %d on connection type 0x%04x\n", workingPtr->hdrtype, workingPtr->conn->type);
-       workingPtr->handled = 1;
-       continue;
-      }
-
-      if (workingPtr->conn->type == AIM_CONN_TYPE_RENDEZVOUS) {
-       /* make sure that we only get OFT frames on these connections */
-       if (workingPtr->hdrtype != AIM_FRAMETYPE_OFT) {
-         faimdprintf(sess, 0, "internal error: non-OFT frames on OFT connection\n");
-         workingPtr->handled = 1; /* get rid of it */
-       } else {
-         /* XXX: implement this */
-         faimdprintf(sess, 0, "faim: OFT frame!\n");
-         workingPtr->handled = 1; /* get rid of it */
+       for (cur = (struct aim_rxcblist_s *)src->handlerlist; cur; cur = cur->next) {
+               aim_conn_addhandler(sess, dest, cur->family, cur->type, 
+                                               cur->handler, cur->flags);
        }
-       continue;
-      }
-
-      if (workingPtr->conn->type == AIM_CONN_TYPE_RENDEZVOUS_OUT) {
-       /* not possible */
-       faimdprintf(sess, 0, "rxdispatch called on RENDEZVOUS_OUT connection!\n");
-       workingPtr->handled = 1;
-       continue;
-      }
-
-      if ((workingPtr->commandlen == 4) && 
-         (aimutil_get32(workingPtr->data) == 0x00000001)) {
-       workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_FLAPVER, workingPtr);
-       continue;
-      } 
-
-      if (workingPtr->hdr.oscar.type == 0x04) {
-       workingPtr->handled = aim_negchan_middle(sess, workingPtr);
-       continue;
-      }
-
-      if ((workingPtr->handled = consumesnac(sess, workingPtr)))
-       continue;
-         
-      if (!workingPtr->handled) {
-       family = aimutil_get16(workingPtr->data);
-       subtype = aimutil_get16(workingPtr->data+2);
-
-       faimdprintf(sess, 1, "warning: unhandled packet %04x/%04x\n", family, subtype);
-       consumenonsnac(sess, workingPtr, 0xffff, 0xffff); /* last chance! */
-       workingPtr->handled = 1;
-      }
-    }
-  }
-
-  /* 
-   * This doesn't have to be called here.  It could easily be done
-   * by a seperate thread or something. It's an administrative operation,
-   * and can take a while. Though the less you call it the less memory
-   * you'll have :)
-   */
-  aim_purge_rxqueue(sess);
-
-  critical = 0;
-  
-  return 0;
+
+       return;
 }
 
-faim_internal int aim_parse_unknown(struct aim_session_t *sess,
-                                         struct command_rx_struct *command, ...)
+faim_internal int aim_callhandler_noparam(aim_session_t *sess, aim_conn_t *conn,fu16_t family, fu16_t type, aim_frame_t *ptr)
 {
-  u_int i = 0;
+       aim_rxcallback_t userfunc;
 
-  if (!sess || !command)
-    return 1;
+       if ((userfunc = aim_callhandler(sess, conn, family, type)))
+               return userfunc(sess, ptr);
 
-  faimdprintf(sess, 1, "\nRecieved unknown packet:");
+       return 1; /* XXX */
+}
 
-  for (i = 0; i < command->commandlen; i++)
-    {
-      if ((i % 8) == 0)
-       faimdprintf(sess, 1, "\n\t");
+/*
+ * aim_rxdispatch()
+ *
+ * Basically, heres what this should do:
+ *   1) Determine correct packet handler for this packet
+ *   2) Mark the packet handled (so it can be dequeued in purge_queue())
+ *   3) Send the packet to the packet handler
+ *   4) Go to next packet in the queue and start over
+ *   5) When done, run purge_queue() to purge handled commands
+ *
+ * TODO: Clean up.
+ * TODO: More support for mid-level handlers.
+ * TODO: Allow for NULL handlers.
+ *
+ */
+faim_export void aim_rxdispatch(aim_session_t *sess)
+{
+       int i;
+       aim_frame_t *cur;
+
+       for (cur = sess->queue_incoming, i = 0; cur; cur = cur->next, i++) {
+
+               /*
+                * XXX: This is still fairly ugly.
+                */
+
+               if (cur->handled)
+                       continue;
+
+               /*
+                * This is a debugging/sanity check only and probably 
+                * could/should be removed for stable code.
+                */
+               if (((cur->hdrtype == AIM_FRAMETYPE_OFT) && 
+                  (cur->conn->type != AIM_CONN_TYPE_RENDEZVOUS)) || 
+                 ((cur->hdrtype == AIM_FRAMETYPE_FLAP) && 
+                  (cur->conn->type == AIM_CONN_TYPE_RENDEZVOUS))) {
+                       faimdprintf(sess, 0, "rxhandlers: incompatible frame type %d on connection type 0x%04x\n", cur->hdrtype, cur->conn->type);
+                       cur->handled = 1;
+                       continue;
+               }
+
+               if (cur->conn->type == AIM_CONN_TYPE_RENDEZVOUS) {
+                       if (cur->hdrtype != AIM_FRAMETYPE_OFT) {
+                               faimdprintf(sess, 0, "internal error: non-OFT frames on OFT connection\n");
+                               cur->handled = 1; /* get rid of it */
+                       } else {
+                               /* XXX: implement this */
+                               faimdprintf(sess, 0, "faim: OFT frame!\n");
+                               cur->handled = 1; /* get rid of it */
+                       }
+                       continue;
+               }
+
+               if (cur->conn->type == AIM_CONN_TYPE_RENDEZVOUS_OUT) {
+                       /* not possible */
+                       faimdprintf(sess, 0, "rxdispatch called on RENDEZVOUS_OUT connection!\n");
+                       cur->handled = 1;
+                       continue;
+               }
+
+               if (cur->hdr.flap.type == 0x01) {
+                       
+                       cur->handled = aim_callhandler_noparam(sess, cur->conn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_FLAPVER, cur); /* XXX use consumenonsnac */
+                       
+                       continue;
+                       
+               } else if (cur->hdr.flap.type == 0x02) {
+
+                       if ((cur->handled = consumesnac(sess, cur)))
+                               continue;
+
+               } else if (cur->hdr.flap.type == 0x04) {
+
+                       cur->handled = negchan_middle(sess, cur);
+                       continue;
+
+               } else if (cur->hdr.flap.type == 0x05)
+                       ;
+               
+               if (!cur->handled) {
+                       consumenonsnac(sess, cur, 0xffff, 0xffff); /* last chance! */
+                       cur->handled = 1;
+               }
+       }
 
-      faimdprintf(sess, 1, "0x%2x ", command->data[i]);
-    }
-  
-  faimdprintf(sess, 1, "\n\n");
+       /* 
+        * This doesn't have to be called here.  It could easily be done
+        * by a seperate thread or something. It's an administrative operation,
+        * and can take a while. Though the less you call it the less memory
+        * you'll have :)
+        */
+       aim_purge_rxqueue(sess);
 
-  return 1;
+       return;
 }
 
-
-faim_internal int aim_negchan_middle(struct aim_session_t *sess,
-                                    struct command_rx_struct *command)
+faim_internal int aim_parse_unknown(aim_session_t *sess, aim_frame_t *frame, ...)
 {
-  struct aim_tlvlist_t *tlvlist;
-  char *msg = NULL;
-  unsigned short code = 0;
-  aim_rxcallback_t userfunc = NULL;
-  int ret = 1;
-
-  /* Used only by the older login protocol */
-  /* XXX remove this special case? */
-  if (command->conn->type == AIM_CONN_TYPE_AUTH)
-    return consumenonsnac(sess, command, 0x0017, 0x0003);
+       int i;
 
-  tlvlist = aim_readtlvchain(command->data, command->commandlen);
+       faimdprintf(sess, 1, "\nRecieved unknown packet:");
 
-  if (aim_gettlv(tlvlist, 0x0009, 1))
-    code = aim_gettlv16(tlvlist, 0x0009, 1);
+       for (i = 0; aim_bstream_empty(&frame->data); i++) {
+               if ((i % 8) == 0)
+                       faimdprintf(sess, 1, "\n\t");
 
-  if (aim_gettlv(tlvlist, 0x000b, 1))
-    msg = aim_gettlv_str(tlvlist, 0x000b, 1);
+               faimdprintf(sess, 1, "0x%2x ", aimbs_get8(&frame->data));
+       }
 
-  if ((userfunc = aim_callhandler(sess, command->conn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNERR))) 
-    ret = userfunc(sess, command, code, msg);
+       faimdprintf(sess, 1, "\n\n");
 
-  aim_freetlvchain(&tlvlist);
+       return 1;
+}
 
-  if (msg)
-    free(msg);
 
-  return ret;
-}
 
This page took 0.091426 seconds and 4 git commands to generate.