updates. New data types.
[silc.git] / lib / silcclient / client.c
index 8bbf3b10bdd4fb91437a52800e96e938ad46b15c..8f40f8599085e273d2e021f2d2a9603e49cf06c8 100644 (file)
@@ -653,14 +653,16 @@ SILC_TASK_CALLBACK_GLOBAL(silc_client_packet_process)
       /* If connection is disconnecting already we will finally
         close the connection */
       if (SILC_IS_DISCONNECTING(sock)) {
-       client->ops->disconnect(client, conn);
-       silc_client_close_connection(client, conn);
+       if (sock == conn->sock)
+         client->ops->disconnect(client, conn);
+       silc_client_close_connection(client, sock, conn);
        return;
       }
       
       SILC_LOG_DEBUG(("EOF from connection %d", sock->sock));
-      client->ops->disconnect(client, conn);
-      silc_client_close_connection(client, conn);
+      if (sock == conn->sock)
+       client->ops->disconnect(client, conn);
+      silc_client_close_connection(client, sock, conn);
       return;
     }
 
@@ -744,7 +746,7 @@ SILC_TASK_CALLBACK(silc_client_packet_parse_real)
   silc_client_packet_parse_type(client, sock, packet);
 
  out:
-  silc_buffer_clear(sock->inbuf);
+  /*  silc_buffer_clear(sock->inbuf); */
   silc_packet_context_free(packet);
   silc_free(parse_ctx);
 }
@@ -852,8 +854,8 @@ void silc_client_packet_parse_type(SilcClient client,
     break;
 
   case SILC_PACKET_KEY_EXCHANGE:
-    if (sock->protocol && sock->protocol->protocol->type 
-       == SILC_PROTOCOL_CLIENT_KEY_EXCHANGE) {
+    if (sock->protocol && sock->protocol->protocol && 
+       sock->protocol->protocol->type == SILC_PROTOCOL_CLIENT_KEY_EXCHANGE) {
       SilcClientKEInternalContext *proto_ctx = 
        (SilcClientKEInternalContext *)sock->protocol->context;
 
@@ -876,8 +878,8 @@ void silc_client_packet_parse_type(SilcClient client,
     break;
 
   case SILC_PACKET_KEY_EXCHANGE_1:
-    if (sock->protocol && sock->protocol->protocol->type 
-       == SILC_PROTOCOL_CLIENT_KEY_EXCHANGE) {
+    if (sock->protocol && sock->protocol->protocol && 
+       sock->protocol->protocol->type == SILC_PROTOCOL_CLIENT_KEY_EXCHANGE) {
       SilcClientKEInternalContext *proto_ctx = 
        (SilcClientKEInternalContext *)sock->protocol->context;
 
@@ -900,8 +902,8 @@ void silc_client_packet_parse_type(SilcClient client,
     }
     break;
   case SILC_PACKET_KEY_EXCHANGE_2:
-    if (sock->protocol && sock->protocol->protocol->type 
-       == SILC_PROTOCOL_CLIENT_KEY_EXCHANGE) {
+    if (sock->protocol && sock->protocol->protocol && 
+       sock->protocol->protocol->type == SILC_PROTOCOL_CLIENT_KEY_EXCHANGE) {
       SilcClientKEInternalContext *proto_ctx = 
        (SilcClientKEInternalContext *)sock->protocol->context;
 
@@ -980,7 +982,7 @@ void silc_client_packet_send(SilcClient client,
                             SilcCipher cipher,
                             SilcHmac hmac,
                             unsigned char *data, 
-                            unsigned int data_len, 
+                            uint32 data_len, 
                             int force_send)
 {
   SilcPacketContext packetdata;
@@ -1055,12 +1057,23 @@ void silc_client_packet_send(SilcClient client,
 }
 
 /* Closes connection to remote end. Free's all allocated data except
-   for some information such as nickname etc. that are valid at all time. */
+   for some information such as nickname etc. that are valid at all time. 
+   If the `sock' is NULL then the conn->sock will be used.  If `sock' is
+   provided it will be checked whether the sock and `conn->sock' are the
+   same (they can be different, ie. a socket can use `conn' as its
+   connection but `conn->sock' might be actually a different connection
+   than the `sock'). */
 
 void silc_client_close_connection(SilcClient client,
+                                 SilcSocketConnection sock,
                                  SilcClientConnection conn)
 {
-  SilcSocketConnection sock = conn->sock;
+  int del = FALSE;
+
+  if (!sock || (sock && conn->sock == sock))
+    del = TRUE;
+  if (!sock)
+    sock = conn->sock;
 
   /* We won't listen for this connection anymore */
   silc_schedule_unset_listen_fd(sock->sock);
@@ -1072,13 +1085,13 @@ void silc_client_close_connection(SilcClient client,
   /* Close the actual connection */
   silc_net_close_connection(sock->sock);
 
-  client->ops->say(client, sock->user_data,
-                  "Closed connection to host %s", sock->hostname);
-
   /* Free everything */
-  if (sock->user_data) {
+  if (del && sock->user_data) {
     /* XXX Free all client entries and channel entries. */
 
+    client->ops->say(client, sock->user_data,
+                    "Closed connection to host %s", sock->hostname);
+
     /* Clear ID caches */
     silc_idcache_del_all(conn->client_cache);
     silc_idcache_del_all(conn->channel_cache);
@@ -1145,7 +1158,7 @@ void silc_client_disconnected_by_server(SilcClient client,
   silc_free(msg);
 
   SILC_SET_DISCONNECTED(sock);
-  silc_client_close_connection(client, sock->user_data);
+  silc_client_close_connection(client, sock, sock->user_data);
 }
 
 /* Received error message from server. Display it on the screen. 
@@ -1221,7 +1234,7 @@ void silc_client_receive_new_id(SilcClient client,
 SilcChannelEntry silc_client_new_channel_id(SilcClient client,
                                            SilcSocketConnection sock,
                                            char *channel_name,
-                                           unsigned int mode, 
+                                           uint32 mode, 
                                            SilcIDPayload idp)
 {
   SilcClientConnection conn = (SilcClientConnection)sock->user_data;
@@ -1330,7 +1343,7 @@ void silc_client_replace_from_channels(SilcClient client,
 
 /* Parses mode mask and returns the mode as string. */
 
-char *silc_client_chmode(unsigned int mode, SilcChannelEntry channel)
+char *silc_client_chmode(uint32 mode, SilcChannelEntry channel)
 {
   char string[100];
 
@@ -1360,6 +1373,9 @@ char *silc_client_chmode(unsigned int mode, SilcChannelEntry channel)
   if (mode & SILC_CHANNEL_MODE_PASSPHRASE)
     strncat(string, "a", 1);
 
+  if (mode & SILC_CHANNEL_MODE_FOUNDER_AUTH)
+    strncat(string, "f", 1);
+
   if (mode & SILC_CHANNEL_MODE_CIPHER) {
     char cipher[30];
     memset(cipher, 0, sizeof(cipher));
@@ -1383,7 +1399,7 @@ char *silc_client_chmode(unsigned int mode, SilcChannelEntry channel)
 
 /* Parses channel user mode mask and returns te mode as string */
 
-char *silc_client_chumode(unsigned int mode)
+char *silc_client_chumode(uint32 mode)
 {
   char string[4];
 
@@ -1403,7 +1419,7 @@ char *silc_client_chumode(unsigned int mode)
 
 /* Parses channel user mode and returns it as special mode character. */
 
-char *silc_client_chumode_char(unsigned int mode)
+char *silc_client_chumode_char(uint32 mode)
 {
   char string[4];
 
@@ -1453,7 +1469,7 @@ void silc_client_process_failure(SilcClient client,
                                 SilcPacketContext *packet)
 {
   SilcClientFailureContext *f;
-  unsigned int failure = 0;
+  uint32 failure = 0;
 
   if (sock->protocol) {
     if (packet->buffer->len >= 4)