Integer type name change.
[silc.git] / lib / silcclient / idlist.c
index 0dd94e4ae9cc364d5c23bc20c4ad92733f047119..e361a5027c39226a6357ddc12873c97abe9790b4 100644 (file)
@@ -1,6 +1,6 @@
 /*
 
-  idlist.c
+  idlist.c 
 
   Author: Pekka Riikonen <priikone@silcnet.org>
 
@@ -8,9 +8,8 @@
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
-  the Free Software Foundation; either version 2 of the License, or
-  (at your option) any later version.
-  
+  the Free Software Foundation; version 2 of the License.
+
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
@@ -19,7 +18,8 @@
 */
 /* $Id$ */
 
-#include "clientlibincludes.h"
+#include "silcincludes.h"
+#include "silcclient.h"
 #include "client_internal.h"
 
 /******************************************************************************
@@ -41,7 +41,7 @@ SilcClientEntry *silc_client_get_clients_local(SilcClient client,
                                               SilcClientConnection conn,
                                               const char *nickname,
                                               const char *format,
-                                              uint32 *clients_count)
+                                              SilcUInt32 *clients_count)
 {
   SilcIDCacheEntry id_cache;
   SilcIDCacheList list = NULL;
@@ -123,7 +123,7 @@ SILC_CLIENT_CMD_FUNC(get_client_callback)
 {
   GetClientInternal i = (GetClientInternal)context;
   SilcClientEntry *clients;
-  uint32 clients_count;
+  SilcUInt32 clients_count;
 
   /* Get the clients */
   clients = silc_client_get_clients_local(i->client, i->conn,
@@ -283,7 +283,7 @@ SilcClientEntry silc_idlist_get_client(SilcClient client,
 typedef struct {
   SilcClient client;
   SilcClientConnection conn;
-  uint32 list_count;
+  SilcUInt32 list_count;
   SilcBuffer client_id_list;
   SilcGetClientCallback completion;
   void *context;
@@ -295,14 +295,14 @@ SILC_CLIENT_CMD_FUNC(get_clients_list_callback)
   SilcIDCacheEntry id_cache = NULL;
   SilcBuffer client_id_list = i->client_id_list;
   SilcClientEntry *clients = NULL;
-  uint32 clients_count = 0;
+  SilcUInt32 clients_count = 0;
   bool found = FALSE;
   int c;
 
   SILC_LOG_DEBUG(("Start"));
 
   for (c = 0; c < i->list_count; c++) {
-    uint16 idp_len;
+    SilcUInt16 idp_len;
     SilcClientID *client_id;
 
     /* Get Client ID */
@@ -352,7 +352,7 @@ SILC_CLIENT_CMD_FUNC(get_clients_list_callback)
 
 void silc_client_get_clients_by_list(SilcClient client,
                                     SilcClientConnection conn,
-                                    uint32 list_count,
+                                    SilcUInt32 list_count,
                                     SilcBuffer client_id_list,
                                     SilcGetClientCallback completion,
                                     void *context)
@@ -360,7 +360,7 @@ void silc_client_get_clients_by_list(SilcClient client,
   SilcIDCacheEntry id_cache = NULL;
   int i;
   unsigned char **res_argv = NULL;
-  uint32 *res_argv_lens = NULL, *res_argv_types = NULL, res_argc = 0;
+  SilcUInt32 *res_argv_lens = NULL, *res_argv_types = NULL, res_argc = 0;
   GetClientsByListInternal in;
 
   SILC_LOG_DEBUG(("Start"));
@@ -374,7 +374,7 @@ void silc_client_get_clients_by_list(SilcClient client,
   in->context = context;
 
   for (i = 0; i < list_count; i++) {
-    uint16 idp_len;
+    SilcUInt16 idp_len;
     SilcClientID *client_id;
     SilcClientEntry entry;
 
@@ -567,7 +567,7 @@ void silc_client_get_client_by_id_resolve(SilcClient client,
 SilcClientEntry
 silc_client_add_client(SilcClient client, SilcClientConnection conn,
                       char *nickname, char *username, 
-                      char *userinfo, SilcClientID *id, uint32 mode)
+                      char *userinfo, SilcClientID *id, SilcUInt32 mode)
 {
   SilcClientEntry client_entry;
   char *nick = NULL;
@@ -586,6 +586,8 @@ silc_client_add_client(SilcClient client, SilcClientConnection conn,
   client_entry->mode = mode;
   if (nick)
     client_entry->nickname = strdup(nick);
+  client_entry->channels = silc_hash_table_alloc(1, silc_hash_ptr, NULL, NULL,
+                                                NULL, NULL, NULL, TRUE);
 
   /* Format the nickname */
   silc_client_nickname_format(client, conn, client_entry);
@@ -597,6 +599,7 @@ silc_client_add_client(SilcClient client, SilcClientConnection conn,
     silc_free(client_entry->username);
     silc_free(client_entry->hostname);
     silc_free(client_entry->server);
+    silc_hash_table_free(client_entry->channels);
     silc_free(client_entry);
     return NULL;
   }
@@ -612,7 +615,7 @@ void silc_client_update_client(SilcClient client,
                               const char *nickname,
                               const char *username,
                               const char *userinfo,
-                              uint32 mode)
+                              SilcUInt32 mode)
 {
   char *nick = NULL;
 
@@ -653,6 +656,7 @@ void silc_client_del_client_entry(SilcClient client,
   silc_free(client_entry->server);
   silc_free(client_entry->id);
   silc_free(client_entry->fingerprint);
+  silc_hash_table_free(client_entry->channels);
   if (client_entry->send_key)
     silc_cipher_free(client_entry->send_key);
   if (client_entry->receive_key)
@@ -680,12 +684,69 @@ bool silc_client_del_client(SilcClient client, SilcClientConnection conn,
   return ret;
 }
 
+/* Add new channel entry to the ID Cache */
+
+SilcChannelEntry silc_client_add_channel(SilcClient client,
+                                        SilcClientConnection conn,
+                                        const char *channel_name,
+                                        SilcUInt32 mode, 
+                                        SilcChannelID *channel_id)
+{
+  SilcChannelEntry channel;
+
+  SILC_LOG_DEBUG(("Start"));
+
+  channel = silc_calloc(1, sizeof(*channel));
+  channel->channel_name = strdup(channel_name);
+  channel->id = channel_id;
+  channel->mode = mode;
+  channel->user_list = silc_hash_table_alloc(1, silc_hash_ptr, NULL, NULL,
+                                            NULL, NULL, NULL, TRUE);
+
+  /* Put it to the ID cache */
+  if (!silc_idcache_add(conn->channel_cache, channel->channel_name, 
+                       (void *)channel->id, (void *)channel, 0, NULL)) {
+    silc_free(channel->channel_name);
+    silc_hash_table_free(channel->user_list);
+    silc_free(channel);
+    return NULL;
+  }
+
+  return channel;
+}
+
+/* Foreach callbcak to free all users from the channel when deleting a
+   channel entry. */
+
+static void silc_client_del_channel_foreach(void *key, void *context,
+                                           void *user_context)
+{
+  SilcChannelUser chu = (SilcChannelUser)context;
+
+  SILC_LOG_DEBUG(("Start"));
+
+  /* Remove the context from the client's channel hash table as that
+     table and channel's user_list hash table share this same context. */
+  silc_hash_table_del(chu->client->channels, chu->channel);
+  silc_free(chu);
+}
+
 /* Removes channel from the cache by the channel entry. */
 
 bool silc_client_del_channel(SilcClient client, SilcClientConnection conn,
                             SilcChannelEntry channel)
 {
   bool ret = silc_idcache_del_by_context(conn->channel_cache, channel);
+
+  SILC_LOG_DEBUG(("Start"));
+
+  /* Free all client entrys from the users list. The silc_hash_table_free
+     will free all the entries so they are not freed at the foreach 
+     callback. */
+  silc_hash_table_foreach(channel->user_list, silc_client_del_channel_foreach,
+                         NULL);
+  silc_hash_table_free(channel->user_list);
+
   silc_free(channel->channel_name);
   silc_free(channel->id);
   silc_free(channel->key);
@@ -704,6 +765,30 @@ bool silc_client_del_channel(SilcClient client, SilcClientConnection conn,
   return ret;
 }
 
+/* Replaces the channel ID of the `channel' to `new_id'. Returns FALSE
+   if the ID could not be changed. */
+
+bool silc_client_replace_channel_id(SilcClient client,
+                                   SilcClientConnection conn,
+                                   SilcChannelEntry channel,
+                                   SilcChannelID *new_id)
+{
+  if (!new_id)
+    return FALSE;
+
+  SILC_LOG_DEBUG(("Old Channel ID id(%s)", 
+                 silc_id_render(channel->id, SILC_ID_CHANNEL)));
+  SILC_LOG_DEBUG(("New Channel ID id(%s)", 
+                 silc_id_render(new_id, SILC_ID_CHANNEL)));
+
+  silc_idcache_del_by_id(conn->channel_cache, channel->id);
+  silc_free(channel->id);
+  channel->id = new_id;
+  return silc_idcache_add(conn->channel_cache, channel->channel_name, 
+                         (void *)channel->id, (void *)channel, 0, NULL);
+
+}
+
 /* Finds entry for channel by the channel name. Returns the entry or NULL
    if the entry was not found. It is found only if the client is joined
    to the channel. */
@@ -816,39 +901,6 @@ void silc_client_get_channel_by_id_resolve(SilcClient client,
                              (void *)i);
 }
 
-/* Find channel entry by ID. This routine is used internally by the library. */
-
-SilcChannelEntry silc_idlist_get_channel_by_id(SilcClient client,
-                                              SilcClientConnection conn,
-                                              SilcChannelID *channel_id,
-                                              int query)
-{
-  SilcBuffer idp;
-  SilcChannelEntry channel;
-
-  SILC_LOG_DEBUG(("Start"));
-
-  channel = silc_client_get_channel_by_id(client, conn, channel_id);
-  if (channel)
-    return channel;
-
-  if (query) {
-    /* Register our own command reply for this command */
-    silc_client_command_register(client, SILC_COMMAND_IDENTIFY, NULL, NULL,
-                                silc_client_command_reply_identify_i, 0,
-                                ++conn->cmd_ident);
-
-    /* Send the command */
-    idp = silc_id_payload_encode(channel_id, SILC_ID_CHANNEL);
-    silc_client_command_send(client, conn, SILC_COMMAND_IDENTIFY, 
-                            conn->cmd_ident,
-                            1, 5, idp->data, idp->len);
-    silc_buffer_free(idp);
-  }
-
-  return NULL;
-}
-
 /* Finds entry for server by the server name. */
 
 SilcServerEntry silc_client_get_server(SilcClient client,
@@ -915,7 +967,7 @@ void silc_client_nickname_format(SilcClient client,
   char *newnick = NULL;
   int i, off = 0, len;
   SilcClientEntry *clients;
-  uint32 clients_count = 0;
+  SilcUInt32 clients_count = 0;
   SilcClientEntry unformatted = NULL;
 
   SILC_LOG_DEBUG(("Start"));