]> andersk Git - libfaim.git/blobdiff - aim_chat.c
- Fri Dec 1 23:48:38 UTC 2000
[libfaim.git] / aim_chat.c
index 83256f024dfdd200b718826c3395327528468a4b..85331edaf10b04e37660d4390b776604b0ddc658 100644 (file)
@@ -1,13 +1,13 @@
 /*
  * aim_chat.c
  *
- * Routines for the Chat service.  Nothing works (yet).
+ * Routines for the Chat service.
  *
  */
 
 #include <faim/aim.h> 
 
-char *aim_chat_getname(struct aim_conn_t *conn)
+faim_export char *aim_chat_getname(struct aim_conn_t *conn)
 {
   if (!conn)
     return NULL;
@@ -17,93 +17,84 @@ char *aim_chat_getname(struct aim_conn_t *conn)
   return (char *)conn->priv; /* yuck ! */
 }
 
-struct aim_conn_t *aim_chat_getconn(struct aim_session_t *sess, char *name)
+faim_export struct aim_conn_t *aim_chat_getconn(struct aim_session_t *sess, char *name)
 {
-  int i;
-
-  for (i=0;i<AIM_CONN_MAX;i++)
-    {
-      if (sess->conns[i].type == AIM_CONN_TYPE_CHAT)
-       {
-         if (sess->conns[i].priv)
-           if (!strcmp((char *)sess->conns[i].priv, name))
-             {
-               return &sess->conns[i];
-             }
-       }
+  struct aim_conn_t *cur;
+  
+  faim_mutex_lock(&sess->connlistlock);
+  for (cur = sess->connlist; cur; cur = cur->next) {
+    if (cur->type != AIM_CONN_TYPE_CHAT)
+      continue;
+    if (!cur->priv) {
+      printf("faim: chat: chat connection with no name! (fd = %d)\n", cur->fd);
+      continue;
     }
-  return NULL;
+    if (strcmp((char *)cur->priv, name) == 0)
+      break;
+  }
+  faim_mutex_unlock(&sess->connlistlock);
+
+  return cur;
 }
 
-int aim_chat_attachname(struct aim_conn_t *conn, char *roomname)
+faim_export int aim_chat_attachname(struct aim_conn_t *conn, char *roomname)
 {
   if (!conn || !roomname)
     return -1;
 
-  conn->priv = malloc(strlen(roomname)+1);
-  strcpy(conn->priv, roomname);
+  if (conn->priv)
+    free(conn->priv);
+
+  conn->priv = strdup(roomname);
 
   return 0;
 }
 
-u_long aim_chat_send_im(struct aim_session_t *sess,
-                       struct aim_conn_t *conn, 
-                       char *msg)
+faim_export unsigned long aim_chat_send_im(struct aim_session_t *sess,
+                                          struct aim_conn_t *conn, 
+                                          char *msg)
 {   
 
   int curbyte,i;
-  struct command_tx_struct newpacket;
+  struct command_tx_struct *newpacket;
 
   if (!sess || !conn || !msg)
     return 0;
   
-  newpacket.lock = 1; /* lock struct */
-  newpacket.type = 0x02; /* IMs are always family 0x02 */
-
-  /* 
-   * Since we must have a specific connection, then theres 
-   * no use in going on if we don't have one... 
-   */
-  if (!conn)
-    return sess->snac_nextid;
-  newpacket.conn = conn;
-
-  /*
-   * Its simplest to set this arbitrarily large and waste
-   * space.  Precalculating is costly here.
-   */
-  newpacket.commandlen = 1152;
+  if (!(newpacket = aim_tx_new(AIM_FRAMETYPE_OSCAR, 0x0002, conn, 1152)))
+    return -1;
 
-  newpacket.data = (u_char *) calloc(1, newpacket.commandlen);
+  newpacket->lock = 1; /* lock struct */
 
   curbyte  = 0;
-  curbyte += aim_putsnac(newpacket.data+curbyte, 
+  curbyte += aim_putsnac(newpacket->data+curbyte, 
                         0x000e, 0x0005, 0x0000, sess->snac_nextid);
 
   /* 
    * Generate a random message cookie 
-   *
    */
   for (i=0;i<8;i++)
-    curbyte += aimutil_put8(newpacket.data+curbyte, (u_char) random());
+    curbyte += aimutil_put8(newpacket->data+curbyte, (u_char) rand());
+
+  aim_cachecookie(sess, aim_mkcookie(newpacket->data+curbyte-8, AIM_COOKIETYPE_CHAT, NULL));
 
   /*
    * metaTLV start.  -- i assume this is a metaTLV.  it could be the
    *                    channel ID though.
    */
-  curbyte += aimutil_put16(newpacket.data+curbyte, 0x0003);
+  curbyte += aimutil_put16(newpacket->data+curbyte, 0x0003);
 
   /*
    * Type 1: Unknown.  Blank.
    */
-  curbyte += aimutil_put16(newpacket.data+curbyte, 0x0001);
-  curbyte += aimutil_put16(newpacket.data+curbyte, 0x0000);
+  curbyte += aimutil_put16(newpacket->data+curbyte, 0x0001);
+  curbyte += aimutil_put16(newpacket->data+curbyte, 0x0000);
   
   /*
    * Type 6: Unknown.  Blank.
    */
-  curbyte += aimutil_put16(newpacket.data+curbyte, 0x0006);
-  curbyte += aimutil_put16(newpacket.data+curbyte, 0x0000);
+  curbyte += aimutil_put16(newpacket->data+curbyte, 0x0006);
+  curbyte += aimutil_put16(newpacket->data+curbyte, 0x0000);
 
   /*
    * Type 5: Message block.  Contains more TLVs.
@@ -112,18 +103,18 @@ u_long aim_chat_send_im(struct aim_session_t *sess,
    * put in a message TLV however.  
    * 
    */
-  curbyte += aimutil_put16(newpacket.data+curbyte, 0x0005);
-  curbyte += aimutil_put16(newpacket.data+curbyte, strlen(msg)+4);
+  curbyte += aimutil_put16(newpacket->data+curbyte, 0x0005);
+  curbyte += aimutil_put16(newpacket->data+curbyte, strlen(msg)+4);
 
   /*
    * SubTLV: Type 1: Message
    */
-  curbyte += aim_puttlv_str(newpacket.data+curbyte, 0x0001, strlen(msg), msg);
+  curbyte += aim_puttlv_str(newpacket->data+curbyte, 0x0001, strlen(msg), msg);
   
-  newpacket.commandlen = curbyte;
+  newpacket->commandlen = curbyte;
 
-  newpacket.lock = 0;
-  aim_tx_enqueue(sess, &newpacket);
+  newpacket->lock = 0;
+  aim_tx_enqueue(sess, newpacket);
 
   return (sess->snac_nextid++);
 }
@@ -136,45 +127,36 @@ u_long aim_chat_send_im(struct aim_session_t *sess,
  * and room name.
  *
  */
-u_long aim_chat_join(struct aim_session_t *sess,
-                    struct aim_conn_t *conn, 
-                    u_short exchange,
-                    const char *roomname)
+faim_export unsigned long aim_chat_join(struct aim_session_t *sess,
+                                       struct aim_conn_t *conn, 
+                                       u_short exchange,
+                                       const char *roomname)
 {
-  struct command_tx_struct newpacket;
+  struct command_tx_struct *newpacket;
   int i;
 
   if (!sess || !conn || !roomname)
     return 0;
   
-  newpacket.lock = 1;
-  if (conn)
-    newpacket.conn = conn;
-  else
-    newpacket.conn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS);
+  if (!(newpacket = aim_tx_new(AIM_FRAMETYPE_OSCAR, 0x0002, conn, 10+9+strlen(roomname)+2)))
+    return -1;
 
-  newpacket.type = 0x02;
-  
-  newpacket.commandlen = 10 + 9 + strlen(roomname) + 2;
-  newpacket.data = (char *) malloc(newpacket.commandlen);
-  memset(newpacket.data, 0x00, newpacket.commandlen);
+  newpacket->lock = 1;
   
-  i = aim_putsnac(newpacket.data, 0x0001, 0x0004, 0x0000, sess->snac_nextid);
+  i = aim_putsnac(newpacket->data, 0x0001, 0x0004, 0x0000, sess->snac_nextid);
 
-  i+= aimutil_put16(newpacket.data+i, 0x000e);
+  i+= aimutil_put16(newpacket->data+i, 0x000e);
 
   /* 
    * this is techinally a TLV, but we can't use normal functions
    * because we need the extraneous nulls and other weird things.
    */
-  i+= aimutil_put16(newpacket.data+i, 0x0001);
-  i+= aimutil_put16(newpacket.data+i, 2+1+strlen(roomname)+2);
-  i+= aimutil_put16(newpacket.data+i, exchange);
-  i+= aimutil_put8(newpacket.data+i, strlen(roomname));
-  memcpy(newpacket.data+i, roomname, strlen(roomname));
-  i+= strlen(roomname);
-  //i+= aimutil_putstr(newpacket.data+i, roomname, strlen(roomname));
-  i+= aimutil_put16(newpacket.data+i, 0x0000);
+  i+= aimutil_put16(newpacket->data+i, 0x0001);
+  i+= aimutil_put16(newpacket->data+i, 2+1+strlen(roomname)+2);
+  i+= aimutil_put16(newpacket->data+i, exchange);
+  i+= aimutil_put8(newpacket->data+i, strlen(roomname));
+  i+= aimutil_putstr(newpacket->data+i, roomname, strlen(roomname));
+  i+= aimutil_put16(newpacket->data+i, 0x0000); /* instance? */
 
   /*
    * Chat hack.
@@ -185,11 +167,11 @@ u_long aim_chat_join(struct aim_session_t *sess,
    *      redirect!
    *
    */
-  sess->pendingjoin = (char *)malloc(strlen(roomname)+1);
-  strcpy(sess->pendingjoin, roomname);
+  sess->pendingjoin = strdup(roomname);
+  sess->pendingjoinexchange = exchange;
 
-  newpacket.lock = 0;
-  aim_tx_enqueue(sess, &newpacket);
+  newpacket->lock = 0;
+  aim_tx_enqueue(sess, newpacket);
 
 #if 0
   {
@@ -210,7 +192,7 @@ u_long aim_chat_join(struct aim_session_t *sess,
   return (sess->snac_nextid++);
 }
 
-int aim_chat_readroominfo(u_char *buf, struct aim_chat_roominfo *outinfo)
+faim_internal int aim_chat_readroominfo(u_char *buf, struct aim_chat_roominfo *outinfo)
 {
   int namelen = 0;
   int i = 0;
@@ -233,7 +215,7 @@ int aim_chat_readroominfo(u_char *buf, struct aim_chat_roominfo *outinfo)
   i += 2;
   
   return i;
-};
+}
 
 
 /*
@@ -243,9 +225,10 @@ int aim_chat_readroominfo(u_char *buf, struct aim_chat_roominfo *outinfo)
  * them to any of the 'Unknown's:
  *     - Language (English)
  *
+ * SNAC 000e/0002
  */
-int aim_chat_parse_infoupdate(struct aim_session_t *sess,
-                             struct command_rx_struct *command)
+faim_internal int aim_chat_parse_infoupdate(struct aim_session_t *sess,
+                                           struct command_rx_struct *command)
 {
   struct aim_userinfo_s *userinfo = NULL;
   rxcallback_t userfunc=NULL;  
@@ -257,12 +240,25 @@ int aim_chat_parse_infoupdate(struct aim_session_t *sess,
   u_short tlvcount = 0;
   struct aim_tlvlist_t *tlvlist;
   char *roomdesc = NULL;
+  struct aim_tlv_t *tmptlv;
+  unsigned short unknown_c9 = 0;
+  unsigned long creationtime = 0;
+  unsigned short maxmsglen = 0;
+  unsigned short unknown_d2 = 0, unknown_d5 = 0;
 
   i = 10;
   i += aim_chat_readroominfo(command->data+i, &roominfo);
   
   detaillevel = aimutil_get8(command->data+i);
   i++;
+
+  if (detaillevel != 0x02) {
+    if (detaillevel == 0x01)
+      printf("faim: chat_roomupdateinfo: detail level 1 not supported\n");
+    else
+      printf("faim: chat_roomupdateinfo: unknown detail level %d\n", detaillevel);
+    return 1;
+  }
   
   tlvcount = aimutil_get16(command->data+i);
   i += 2;
@@ -281,55 +277,53 @@ int aim_chat_parse_infoupdate(struct aim_session_t *sess,
   /*
    * Type 0x006f: Number of occupants.
    */
-  if (aim_gettlv(tlvlist, 0x006f, 1))
-    {
-      struct aim_tlv_t *tmptlv;
-      tmptlv = aim_gettlv(tlvlist, 0x006f, 1);
-
-      usercount = aimutil_get16(tmptlv->value);
-    }
+  if (aim_gettlv(tlvlist, 0x006f, 1)) {
+    struct aim_tlv_t *tmptlv;
+    tmptlv = aim_gettlv(tlvlist, 0x006f, 1);
+    
+    usercount = aimutil_get16(tmptlv->value);
+  }
 
   /*
    * Type 0x0073:  Occupant list.
    */
-  if (aim_gettlv(tlvlist, 0x0073, 1))
-    {  
-      int curoccupant = 0;
-      struct aim_tlv_t *tmptlv;
-
-      tmptlv = aim_gettlv(tlvlist, 0x0073, 1);
-
-      /* Allocate enough userinfo structs for all occupants */
-      userinfo = calloc(usercount, sizeof(struct aim_userinfo_s));
+  if (aim_gettlv(tlvlist, 0x0073, 1)) {        
+    int curoccupant = 0;
+    struct aim_tlv_t *tmptlv;
+    
+    tmptlv = aim_gettlv(tlvlist, 0x0073, 1);
 
-      i = 0;
-      while (curoccupant < usercount)
-       i += aim_extractuserinfo(tmptlv->value+i, &userinfo[curoccupant++]);
-    }
+    /* Allocate enough userinfo structs for all occupants */
+    userinfo = calloc(usercount, sizeof(struct aim_userinfo_s));
+    
+    i = 0;
+    while (curoccupant < usercount)
+      i += aim_extractuserinfo(tmptlv->value+i, &userinfo[curoccupant++]);
+  }
   
   /* 
-   * Type 0x00c9: Unknown.
+   * Type 0x00c9: Unknown. (2 bytes)
    */
-  if (aim_gettlv(tlvlist, 0x00c9, 1))
-    ;
+  if ((tmptlv = aim_gettlv(tlvlist, 0x00c9, 1)))
+    unknown_c9 = aimutil_get16(tmptlv->value);
   
   /* 
-   * Type 0x00ca: Creation date
+   * Type 0x00ca: Creation time (4 bytes)
    */
-  if (aim_gettlv(tlvlist, 0x00ca, 1))
-    ;
+  if ((tmptlv = aim_gettlv(tlvlist, 0x00ca, 1)))
+    creationtime = aimutil_get32(tmptlv->value);
 
   /* 
    * Type 0x00d1: Maximum Message Length
    */
-  if (aim_gettlv(tlvlist, 0x00d1, 1))
-    ;
+  if ((tmptlv = aim_gettlv(tlvlist, 0x00d1, 1)))
+    maxmsglen = aimutil_get16(tmptlv->value);
 
   /* 
-   * Type 0x00d2: Unknown.
+   * Type 0x00d2: Unknown. (2 bytes)
    */
-  if (aim_gettlv(tlvlist, 0x00d2, 1))
-    ;
+  if ((tmptlv = aim_gettlv(tlvlist, 0x00d2, 1)))
+    unknown_d2 = aimutil_get16(tmptlv->value);;
 
   /* 
    * Type 0x00d3: Room Description
@@ -338,23 +332,27 @@ int aim_chat_parse_infoupdate(struct aim_session_t *sess,
     roomdesc = aim_gettlv_str(tlvlist, 0x00d3, 1);
 
   /* 
-   * Type 0x00d5: Unknown.
+   * Type 0x00d5: Unknown. (1 byte)
    */
-  if (aim_gettlv(tlvlist, 0x00d5, 1))
-    ;
+  if ((tmptlv = aim_gettlv(tlvlist, 0x00d5, 1)))
+    unknown_d5 = aimutil_get8(tmptlv->value);;
 
 
   userfunc = aim_callhandler(command->conn, AIM_CB_FAM_CHT, AIM_CB_CHT_ROOMINFOUPDATE);
-  if (userfunc)
-    {
-      ret = userfunc(sess,
-                    command, 
-                    &roominfo,
-                    roomname,
-                    usercount,
-                    userinfo,  
-                    roomdesc);
-    }
+  if (userfunc) {
+    ret = userfunc(sess,
+                  command, 
+                  &roominfo,
+                  roomname,
+                  usercount,
+                  userinfo,    
+                  roomdesc,
+                  unknown_c9,
+                  creationtime,
+                  maxmsglen,
+                  unknown_d2,
+                  unknown_d5);
+  }    
   free(roominfo.name);
   free(userinfo);
   free(roomname);
@@ -364,57 +362,53 @@ int aim_chat_parse_infoupdate(struct aim_session_t *sess,
   return ret;
 }
 
-int aim_chat_parse_joined(struct aim_session_t *sess,
-                             struct command_rx_struct *command)
+faim_internal int aim_chat_parse_joined(struct aim_session_t *sess,
+                                       struct command_rx_struct *command)
 {
   struct aim_userinfo_s *userinfo = NULL;
   rxcallback_t userfunc=NULL;  
   int i = 10, curcount = 0, ret = 1;
 
-  while (i < command->commandlen)
-    {
-      curcount++;
-      userinfo = realloc(userinfo, curcount * sizeof(struct aim_userinfo_s));
-      i += aim_extractuserinfo(command->data+i, &userinfo[curcount-1]);
-    }
+  while (i < command->commandlen) {
+    curcount++;
+    userinfo = realloc(userinfo, curcount * sizeof(struct aim_userinfo_s));
+    i += aim_extractuserinfo(command->data+i, &userinfo[curcount-1]);
+  }
 
   userfunc = aim_callhandler(command->conn, AIM_CB_FAM_CHT, AIM_CB_CHT_USERJOIN);
-  if (userfunc)
-    {
-      ret = userfunc(sess,
-                    command, 
-                    curcount,
-                    userinfo);
-    }
+  if (userfunc) {      
+    ret = userfunc(sess,
+                  command, 
+                  curcount,
+                  userinfo);
+  }
 
   free(userinfo);
 
   return ret;
 }            
 
-int aim_chat_parse_leave(struct aim_session_t *sess,
-                             struct command_rx_struct *command)
+faim_internal int aim_chat_parse_leave(struct aim_session_t *sess,
+                                      struct command_rx_struct *command)
 {
 
   struct aim_userinfo_s *userinfo = NULL;
   rxcallback_t userfunc=NULL;  
   int i = 10, curcount = 0, ret = 1;
 
-  while (i < command->commandlen)
-    {
-      curcount++;
-      userinfo = realloc(userinfo, curcount * sizeof(struct aim_userinfo_s));
-      i += aim_extractuserinfo(command->data+i, &userinfo[curcount-1]);
-    }
+  while (i < command->commandlen) {
+    curcount++;
+    userinfo = realloc(userinfo, curcount * sizeof(struct aim_userinfo_s));
+    i += aim_extractuserinfo(command->data+i, &userinfo[curcount-1]);
+  }
 
   userfunc = aim_callhandler(command->conn, AIM_CB_FAM_CHT, AIM_CB_CHT_USERLEAVE);
-  if (userfunc)
-    {
-      ret = userfunc(sess,
-                    command, 
-                    curcount,
-                    userinfo);
-    }
+  if (userfunc) {
+    ret = userfunc(sess,
+                  command, 
+                  curcount,
+                  userinfo);
+  }
 
   free(userinfo);
 
@@ -426,27 +420,34 @@ int aim_chat_parse_leave(struct aim_session_t *sess,
  * code as channel 0x0003, however, since only the start
  * would be the same, we might as well do it here.
  */
-int aim_chat_parse_incoming(struct aim_session_t *sess,
-                             struct command_rx_struct *command)
+faim_internal int aim_chat_parse_incoming(struct aim_session_t *sess,
+                                         struct command_rx_struct *command)
 {
   struct aim_userinfo_s userinfo;
   rxcallback_t userfunc=NULL;  
   int ret = 1, i = 0, z = 0;
-  u_char cookie[8];
+  unsigned char cookie[8];
   int channel;
   struct aim_tlvlist_t *outerlist;
   char *msg = NULL;
+  struct aim_msgcookie_t *ck;
 
   memset(&userinfo, 0x00, sizeof(struct aim_userinfo_s));
 
   i = 10; /* skip snac */
 
   /*
-   * ICBM Cookie.  Ignore it.
+   * ICBM Cookie.  Cache it.
    */ 
   for (z=0; z<8; z++,i++)
     cookie[z] = command->data[i];
 
+  if ((ck = aim_uncachecookie(sess, cookie, AIM_COOKIETYPE_CHAT))) {
+    if (ck->data)
+      free(ck->data);
+    free(ck);
+  }
+
   /*
    * Channel ID
    *
@@ -459,11 +460,10 @@ int aim_chat_parse_incoming(struct aim_session_t *sess,
   channel = aimutil_get16(command->data+i);
   i += 2;
 
-  if (channel != 0x0003)
-    {
-      printf("faim: chat_incoming: unknown channel! (0x%04x)\n", channel);
-      return 1;
-    }
+  if (channel != 0x0003) {
+    printf("faim: chat_incoming: unknown channel! (0x%04x)\n", channel);
+    return 1;
+  }
 
   /*
    * Start parsing TLVs right away. 
@@ -473,13 +473,12 @@ int aim_chat_parse_incoming(struct aim_session_t *sess,
   /*
    * Type 0x0003: Source User Information
    */
-  if (aim_gettlv(outerlist, 0x0003, 1))
-    {
-      struct aim_tlv_t *userinfotlv;
-      
-      userinfotlv = aim_gettlv(outerlist, 0x0003, 1);
-      aim_extractuserinfo(userinfotlv->value, &userinfo);
-    }
+  if (aim_gettlv(outerlist, 0x0003, 1)) {
+    struct aim_tlv_t *userinfotlv;
+    
+    userinfotlv = aim_gettlv(outerlist, 0x0003, 1);
+    aim_extractuserinfo(userinfotlv->value, &userinfo);
+  }
 
   /*
    * Type 0x0001: Unknown.
@@ -521,159 +520,150 @@ int aim_chat_parse_incoming(struct aim_session_t *sess,
   return ret;
 }            
 
-u_long aim_chat_clientready(struct aim_session_t *sess,
-                           struct aim_conn_t *conn)
+faim_export unsigned long aim_chat_clientready(struct aim_session_t *sess,
+                                              struct aim_conn_t *conn)
 {
-  struct command_tx_struct newpacket;
+  struct command_tx_struct *newpacket;
   int i;
 
-  newpacket.lock = 1;
-  if (conn)
-    newpacket.conn = conn;
-  else
-    newpacket.conn = aim_getconn_type(sess, AIM_CONN_TYPE_CHAT);
-  newpacket.type = 0x02;
-  newpacket.commandlen = 0x20;
+  if (!(newpacket = aim_tx_new(AIM_FRAMETYPE_OSCAR, 0x0002, conn, 0x20)))
+    return -1;
 
-  newpacket.data = (char *) malloc(newpacket.commandlen);
-  i = aim_putsnac(newpacket.data, 0x0001, 0x0002, 0x0000, sess->snac_nextid);
+  newpacket->lock = 1;
 
-  i+= aimutil_put16(newpacket.data+i, 0x000e);
-  i+= aimutil_put16(newpacket.data+i, 0x0001);
+  i = aim_putsnac(newpacket->data, 0x0001, 0x0002, 0x0000, sess->snac_nextid);
 
-  i+= aimutil_put16(newpacket.data+i, 0x0004);
-  i+= aimutil_put16(newpacket.data+i, 0x0001);
+  i+= aimutil_put16(newpacket->data+i, 0x000e);
+  i+= aimutil_put16(newpacket->data+i, 0x0001);
 
-  i+= aimutil_put16(newpacket.data+i, 0x0001);
-  i+= aimutil_put16(newpacket.data+i, 0x0003);
+  i+= aimutil_put16(newpacket->data+i, 0x0004);
+  i+= aimutil_put16(newpacket->data+i, 0x0001);
 
-  i+= aimutil_put16(newpacket.data+i, 0x0004);
-  i+= aimutil_put16(newpacket.data+i, 0x0686);
+  i+= aimutil_put16(newpacket->data+i, 0x0001);
+  i+= aimutil_put16(newpacket->data+i, 0x0003);
 
-  newpacket.lock = 0;
-  aim_tx_enqueue(sess, &newpacket);
+  i+= aimutil_put16(newpacket->data+i, 0x0004);
+  i+= aimutil_put16(newpacket->data+i, 0x0686);
+
+  newpacket->lock = 0;
+  aim_tx_enqueue(sess, newpacket);
 
   return (sess->snac_nextid++);
 }
 
-int aim_chat_leaveroom(struct aim_session_t *sess, char *name)
+faim_export int aim_chat_leaveroom(struct aim_session_t *sess, char *name)
 {
-  int i;
+  struct aim_conn_t *conn;
 
-  for (i=0;i<AIM_CONN_MAX;i++)
-    {
-      if (sess->conns[i].type == AIM_CONN_TYPE_CHAT)
-       {
-         if (sess->conns[i].priv)
-           if (!strcmp((char *)sess->conns[i].priv, name))
-             {
-               aim_conn_close(&sess->conns[i]);
-               return 0;
-             }
-       }
-    }
-  return -1;
+  if ((conn = aim_chat_getconn(sess, name)))
+    aim_conn_close(conn);
+
+  if (!conn)
+    return -1;
+  return 0;
 }
 
 /*
  * conn must be a BOS connection!
  */
-u_long aim_chat_invite(struct aim_session_t *sess,
-                      struct aim_conn_t *conn,
-                      char *sn,
-                      char *msg,
-                      u_short exchange,
-                      char *roomname,
-                      u_short instance)
+faim_export unsigned long aim_chat_invite(struct aim_session_t *sess,
+                                         struct aim_conn_t *conn,
+                                         char *sn,
+                                         char *msg,
+                                         u_short exchange,
+                                         char *roomname,
+                                         u_short instance)
 {
-  struct command_tx_struct newpacket;
+  struct command_tx_struct *newpacket;
   int i,curbyte=0;
 
   if (!sess || !conn || !sn || !msg || !roomname)
-    return 0;
+    return -1;
 
-  newpacket.lock = 1;
-  if (conn)
-    newpacket.conn = conn;
-  else
-    newpacket.conn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS);
-  newpacket.type = 0x02;
-  newpacket.commandlen = 1152+strlen(sn)+strlen(roomname)+strlen(msg);
+  if (conn->type != AIM_CONN_TYPE_BOS)
+    return -1;
 
-  newpacket.data = (char *) malloc(newpacket.commandlen);
-  curbyte = aim_putsnac(newpacket.data, 0x0004, 0x0006, 0x0000, sess->snac_nextid);
+  if (!(newpacket = aim_tx_new(AIM_FRAMETYPE_OSCAR, 0x0002, conn, 1152+strlen(sn)+strlen(roomname)+strlen(msg))))
+    return -1;
+
+  newpacket->lock = 1;
+
+  curbyte = aim_putsnac(newpacket->data, 0x0004, 0x0006, 0x0000, sess->snac_nextid);
 
   /*
    * Cookie
    */
   for (i=0;i<8;i++)
-    curbyte += aimutil_put8(newpacket.data+curbyte, (u_char)rand());
+    curbyte += aimutil_put8(newpacket->data+curbyte, (u_char)rand());
+
+  /* XXX this should get uncached by the unwritten 'invite accept' handler */
+  aim_cachecookie(sess, aim_mkcookie(newpacket->data+curbyte-8, AIM_COOKIETYPE_CHAT, NULL));
 
   /*
    * Channel (2)
    */
-  curbyte += aimutil_put16(newpacket.data+curbyte, 0x0002);
+  curbyte += aimutil_put16(newpacket->data+curbyte, 0x0002);
 
   /*
    * Dest sn
    */
-  curbyte += aimutil_put8(newpacket.data+curbyte, strlen(sn));
-  curbyte += aimutil_putstr(newpacket.data+curbyte, sn, strlen(sn));
+  curbyte += aimutil_put8(newpacket->data+curbyte, strlen(sn));
+  curbyte += aimutil_putstr(newpacket->data+curbyte, sn, strlen(sn));
 
   /*
    * TLV t(0005)
    */
-  curbyte += aimutil_put16(newpacket.data+curbyte, 0x0005);
-  curbyte += aimutil_put16(newpacket.data+curbyte, 0x28+strlen(msg)+0x04+0x03+strlen(roomname)+0x02);
+  curbyte += aimutil_put16(newpacket->data+curbyte, 0x0005);
+  curbyte += aimutil_put16(newpacket->data+curbyte, 0x28+strlen(msg)+0x04+0x03+strlen(roomname)+0x02);
   
   /* 
    * Unknown info
    */
-  curbyte += aimutil_put16(newpacket.data+curbyte, 0x0000);
-  curbyte += aimutil_put16(newpacket.data+curbyte, 0x3131);
-  curbyte += aimutil_put16(newpacket.data+curbyte, 0x3538);
-  curbyte += aimutil_put16(newpacket.data+curbyte, 0x3446);
-  curbyte += aimutil_put16(newpacket.data+curbyte, 0x4100);
-  curbyte += aimutil_put16(newpacket.data+curbyte, 0x748f);
-  curbyte += aimutil_put16(newpacket.data+curbyte, 0x2420);
-  curbyte += aimutil_put16(newpacket.data+curbyte, 0x6287);
-  curbyte += aimutil_put16(newpacket.data+curbyte, 0x11d1);
-  curbyte += aimutil_put16(newpacket.data+curbyte, 0x8222);
-  curbyte += aimutil_put16(newpacket.data+curbyte, 0x4445);
-  curbyte += aimutil_put16(newpacket.data+curbyte, 0x5354);
-  curbyte += aimutil_put16(newpacket.data+curbyte, 0x0000);
+  curbyte += aimutil_put16(newpacket->data+curbyte, 0x0000);
+  curbyte += aimutil_put16(newpacket->data+curbyte, 0x3131);
+  curbyte += aimutil_put16(newpacket->data+curbyte, 0x3538);
+  curbyte += aimutil_put16(newpacket->data+curbyte, 0x3446);
+  curbyte += aimutil_put16(newpacket->data+curbyte, 0x4100);
+  curbyte += aimutil_put16(newpacket->data+curbyte, 0x748f);
+  curbyte += aimutil_put16(newpacket->data+curbyte, 0x2420);
+  curbyte += aimutil_put16(newpacket->data+curbyte, 0x6287);
+  curbyte += aimutil_put16(newpacket->data+curbyte, 0x11d1);
+  curbyte += aimutil_put16(newpacket->data+curbyte, 0x8222);
+  curbyte += aimutil_put16(newpacket->data+curbyte, 0x4445);
+  curbyte += aimutil_put16(newpacket->data+curbyte, 0x5354);
+  curbyte += aimutil_put16(newpacket->data+curbyte, 0x0000);
   
   /*
    * TLV t(000a) -- Unknown
    */
-  curbyte += aimutil_put16(newpacket.data+curbyte, 0x000a);
-  curbyte += aimutil_put16(newpacket.data+curbyte, 0x0002);
-  curbyte += aimutil_put16(newpacket.data+curbyte, 0x0001);
+  curbyte += aimutil_put16(newpacket->data+curbyte, 0x000a);
+  curbyte += aimutil_put16(newpacket->data+curbyte, 0x0002);
+  curbyte += aimutil_put16(newpacket->data+curbyte, 0x0001);
   
   /*
    * TLV t(000f) -- Unknown
    */
-  curbyte += aimutil_put16(newpacket.data+curbyte, 0x000f);
-  curbyte += aimutil_put16(newpacket.data+curbyte, 0x0000);
+  curbyte += aimutil_put16(newpacket->data+curbyte, 0x000f);
+  curbyte += aimutil_put16(newpacket->data+curbyte, 0x0000);
   
   /*
    * TLV t(000c) -- Invitation message
    */
-  curbyte += aim_puttlv_str(newpacket.data+curbyte, 0x000c, strlen(msg), msg);
+  curbyte += aim_puttlv_str(newpacket->data+curbyte, 0x000c, strlen(msg), msg);
 
   /*
    * TLV t(2711) -- Container for room information 
    */
-  curbyte += aimutil_put16(newpacket.data+curbyte, 0x2711);
-  curbyte += aimutil_put16(newpacket.data+curbyte, 3+strlen(roomname)+2);
-  curbyte += aimutil_put16(newpacket.data+curbyte, exchange);
-  curbyte += aimutil_put8(newpacket.data+curbyte, strlen(roomname));
-  curbyte += aimutil_putstr(newpacket.data+curbyte, roomname, strlen(roomname));
-  curbyte += aimutil_put16(newpacket.data+curbyte, instance);
-
-  newpacket.commandlen = curbyte;
-  newpacket.lock = 0;
-  aim_tx_enqueue(sess, &newpacket);
+  curbyte += aimutil_put16(newpacket->data+curbyte, 0x2711);
+  curbyte += aimutil_put16(newpacket->data+curbyte, 3+strlen(roomname)+2);
+  curbyte += aimutil_put16(newpacket->data+curbyte, exchange);
+  curbyte += aimutil_put8(newpacket->data+curbyte, strlen(roomname));
+  curbyte += aimutil_putstr(newpacket->data+curbyte, roomname, strlen(roomname));
+  curbyte += aimutil_put16(newpacket->data+curbyte, instance);
+
+  newpacket->commandlen = curbyte;
+  newpacket->lock = 0;
+  aim_tx_enqueue(sess, newpacket);
 
   return (sess->snac_nextid++);
 }
This page took 0.077386 seconds and 4 git commands to generate.