]> andersk Git - libfaim.git/blobdiff - aim_chat.c
- Wed Nov 8 02:23:25 UTC 2000
[libfaim.git] / aim_chat.c
index 03650aca716cdd221ea5d93b1d6e193bcf1daebc..ee40b0ab281107bdb9669f7d907a1f1b5c3c303a 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,25 +17,23 @@ 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;
+  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 (strcmp((char *)cur->priv, name) == 0)
+      break;
+  }
+  faim_mutex_unlock(&sess->connlistlock);
 
-  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];
-             }
-       }
-    }
-  return NULL;
+  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;
@@ -46,9 +44,9 @@ int aim_chat_attachname(struct aim_conn_t *conn, char *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;
@@ -57,7 +55,7 @@ u_long aim_chat_send_im(struct aim_session_t *sess,
   if (!sess || !conn || !msg)
     return 0;
   
-  if (!(newpacket = aim_tx_new(0x0002, conn, 1152)))
+  if (!(newpacket = aim_tx_new(AIM_FRAMETYPE_OSCAR, 0x0002, conn, 1152)))
     return -1;
 
   newpacket->lock = 1; /* lock struct */
@@ -70,7 +68,9 @@ u_long aim_chat_send_im(struct aim_session_t *sess,
    * 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
@@ -121,10 +121,10 @@ 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;
   int i;
@@ -132,7 +132,7 @@ u_long aim_chat_join(struct aim_session_t *sess,
   if (!sess || !conn || !roomname)
     return 0;
   
-  if (!(newpacket = aim_tx_new(0x0002, conn, 10+9+strlen(roomname)+2)))
+  if (!(newpacket = aim_tx_new(AIM_FRAMETYPE_OSCAR, 0x0002, conn, 10+9+strlen(roomname)+2)))
     return -1;
 
   newpacket->lock = 1;
@@ -188,7 +188,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;
@@ -211,7 +211,7 @@ int aim_chat_readroominfo(u_char *buf, struct aim_chat_roominfo *outinfo)
   i += 2;
   
   return i;
-};
+}
 
 
 /*
@@ -221,9 +221,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;  
@@ -235,12 +236,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 2 not supported\n");
+    else
+      printf("faim: chat_roomupdateinfo: unknown detail level %d\n", detaillevel);
+    return 1;
+  }
   
   tlvcount = aimutil_get16(command->data+i);
   i += 2;
@@ -259,55 +273,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
@@ -316,23 +328,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);
@@ -342,57 +358,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);
 
@@ -404,8 +416,8 @@ 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;  
@@ -420,11 +432,13 @@ int aim_chat_parse_incoming(struct aim_session_t *sess,
   i = 10; /* skip snac */
 
   /*
-   * ICBM Cookie.  Ignore it.
+   * ICBM Cookie.  Cache it.
    */ 
   for (z=0; z<8; z++,i++)
     cookie[z] = command->data[i];
 
+  aim_cachecookie(sess, aim_mkcookie(cookie, AIM_COOKIETYPE_ICBM, NULL));
+
   /*
    * Channel ID
    *
@@ -437,11 +451,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. 
@@ -451,13 +464,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.
@@ -499,13 +511,13 @@ 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;
   int i;
 
-  if (!(newpacket = aim_tx_new(0x0002, conn, 0x20)))
+  if (!(newpacket = aim_tx_new(AIM_FRAMETYPE_OSCAR, 0x0002, conn, 0x20)))
     return -1;
 
   newpacket->lock = 1;
@@ -530,35 +542,28 @@ u_long aim_chat_clientready(struct aim_session_t *sess,
   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_kill(sess, &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;
   int i,curbyte=0;
@@ -566,7 +571,7 @@ u_long aim_chat_invite(struct aim_session_t *sess,
   if (!sess || !conn || !sn || !msg || !roomname)
     return 0;
 
-  if (!(newpacket = aim_tx_new(0x0002, conn, 1152+strlen(sn)+strlen(roomname)+strlen(msg))))
+  if (!(newpacket = aim_tx_new(AIM_FRAMETYPE_OSCAR, 0x0002, conn, 1152+strlen(sn)+strlen(roomname)+strlen(msg))))
     return -1;
 
   newpacket->lock = 1;
@@ -578,6 +583,7 @@ u_long aim_chat_invite(struct aim_session_t *sess,
    */
   for (i=0;i<8;i++)
     curbyte += aimutil_put8(newpacket->data+curbyte, (u_char)rand());
+  aim_cachecookie(sess, aim_mkcookie(newpacket->data+curbyte-8, AIM_COOKIETYPE_CHAT, NULL));
 
   /*
    * Channel (2)
This page took 0.056001 seconds and 4 git commands to generate.