updates.
[silc.git] / apps / silcd / idlist.c
index 99b375e762eab456bd8569cae99a46e7af18e477..e6f79f3c3bd8838b3b01fcdd89d370ee8c933263 100644 (file)
@@ -36,10 +36,10 @@ void silc_idlist_add_data(void *entry, SilcIDListData idata)
   SilcIDListData data = (SilcIDListData)entry;
   data->send_key = idata->send_key;
   data->receive_key = idata->receive_key;
+  data->rekey = idata->rekey;
   data->hash = idata->hash;
-  data->hmac = idata->hmac;
-  data->hmac_key = idata->hmac_key;
-  data->hmac_key_len = idata->hmac_key_len;
+  data->hmac_send = idata->hmac_send;
+  data->hmac_receive = idata->hmac_receive;
   data->public_key = idata->public_key;
   data->last_receive = idata->last_receive;
   data->last_sent = idata->last_sent;
@@ -55,12 +55,15 @@ void silc_idlist_del_data(void *entry)
     silc_cipher_free(idata->send_key);
   if (idata->receive_key)
     silc_cipher_free(idata->receive_key);
-  if (idata->hmac)
-    silc_hmac_free(idata->hmac);
-  if (idata->hmac_key) {
-    memset(idata->hmac_key, 0, idata->hmac_key_len);
-    silc_free(idata->hmac_key);
+  if (idata->rekey) {
+    if (idata->rekey->send_enc_key) {
+      memset(idata->rekey->send_enc_key, 0, idata->rekey->enc_key_len);
+      silc_free(idata->rekey->send_enc_key);
+    }
+    silc_free(idata->rekey);
   }
+  if (idata->hmac_send)                /* Same as idata->hmac_receive */
+    silc_hmac_free(idata->hmac_send);
   if (idata->public_key)
     silc_pkcs_public_key_free(idata->public_key);
 }
@@ -248,13 +251,16 @@ silc_idlist_replace_server_id(SilcIDList id_list, SilcServerID *old_id,
 
 /* Removes and free's server entry from ID list */
 
-void silc_idlist_del_server(SilcIDList id_list, SilcServerEntry entry)
+int silc_idlist_del_server(SilcIDList id_list, SilcServerEntry entry)
 {
+  SILC_LOG_DEBUG(("Start"));
+
   if (entry) {
     /* Remove from cache */
     if (entry->id)
-      silc_idcache_del_by_id(id_list->servers, SILC_ID_SERVER, 
-                            (void *)entry->id);
+      if (!silc_idcache_del_by_id(id_list->servers, SILC_ID_SERVER, 
+                                 (void *)entry->id))
+       return FALSE;
 
     /* Free data */
     if (entry->server_name)
@@ -264,7 +270,10 @@ void silc_idlist_del_server(SilcIDList id_list, SilcServerEntry entry)
 
     memset(entry, 'F', sizeof(*entry));
     silc_free(entry);
+    return TRUE;
   }
+
+  return FALSE;
 }
 
 /******************************************************************************
@@ -284,7 +293,7 @@ void silc_idlist_del_server(SilcIDList id_list, SilcServerEntry entry)
 
 SilcClientEntry
 silc_idlist_add_client(SilcIDList id_list, unsigned char *nickname, 
-                      unsigned int nickname_len, char *username, 
+                      uint32 nickname_len, char *username, 
                       char *userinfo, SilcClientID *id, 
                       SilcServerEntry router, void *connection)
 {
@@ -317,6 +326,8 @@ silc_idlist_add_client(SilcIDList id_list, unsigned char *nickname,
 
 int silc_idlist_del_client(SilcIDList id_list, SilcClientEntry entry)
 {
+  SILC_LOG_DEBUG(("Start"));
+
   if (entry) {
     /* Remove from cache */
     if (entry->id)
@@ -346,35 +357,36 @@ int silc_idlist_del_client(SilcIDList id_list, SilcClientEntry entry)
 /* Returns all clients matching requested nickname. Number of clients is
    returned to `clients_count'. Caller must free the returned table. */
 
-SilcClientEntry *
-silc_idlist_get_clients_by_nickname(SilcIDList id_list, char *nickname,
-                                   char *server, unsigned int *clients_count)
+int silc_idlist_get_clients_by_nickname(SilcIDList id_list, char *nickname,
+                                       char *server, 
+                                       SilcClientEntry **clients,
+                                       uint32 *clients_count)
 {
   SilcIDCacheList list = NULL;
   SilcIDCacheEntry id_cache = NULL;
-  SilcClientEntry *clients;
   int i;
 
   SILC_LOG_DEBUG(("Start"));
 
   if (!silc_idcache_find_by_data(id_list->clients, nickname, &list))
-    return NULL;
+    return FALSE;
 
-  clients = silc_calloc(silc_idcache_list_count(list), sizeof(*clients));
+  *clients = silc_realloc(*clients, 
+                         (silc_idcache_list_count(list) + *clients_count) * 
+                         sizeof(**clients));
 
   i = 0;
   silc_idcache_list_first(list, &id_cache);
-  clients[i++] = (SilcClientEntry)id_cache->context;
+  (*clients)[i++] = (SilcClientEntry)id_cache->context;
 
   while (silc_idcache_list_next(list, &id_cache))
-    clients[i++] = (SilcClientEntry)id_cache->context;
+    (*clients)[i++] = (SilcClientEntry)id_cache->context;
   
   silc_idcache_list_free(list);
   
-  if (clients_count)
-    *clients_count = i;
+  *clients_count += i;
 
-  return clients;
+  return TRUE;
 }
 
 /* Returns all clients matching requested nickname. Number of clients is
@@ -384,14 +396,13 @@ silc_idlist_get_clients_by_nickname(SilcIDList id_list, char *nickname,
    list may have hash.  Thus, this is not fully reliable function.
    Instead this should probably check the hash from the list of client ID's. */
 
-SilcClientEntry *
-silc_idlist_get_clients_by_hash(SilcIDList id_list, char *nickname,
-                               SilcHash md5hash,
-                               unsigned int *clients_count)
+int silc_idlist_get_clients_by_hash(SilcIDList id_list, char *nickname,
+                                   SilcHash md5hash,
+                                   SilcClientEntry **clients,
+                                   uint32 *clients_count)
 {
   SilcIDCacheList list = NULL;
   SilcIDCacheEntry id_cache = NULL;
-  SilcClientEntry *clients;
   unsigned char hash[32];
   int i;
 
@@ -400,23 +411,24 @@ silc_idlist_get_clients_by_hash(SilcIDList id_list, char *nickname,
   silc_hash_make(md5hash, nickname, strlen(nickname), hash);
 
   if (!silc_idcache_find_by_data(id_list->clients, hash, &list))
-    return NULL;
+    return FALSE;
 
-  clients = silc_calloc(silc_idcache_list_count(list), sizeof(*clients));
+  *clients = silc_realloc(*clients, 
+                         (silc_idcache_list_count(list) + *clients_count) * 
+                         sizeof(**clients));
 
   i = 0;
   silc_idcache_list_first(list, &id_cache);
-  clients[i++] = (SilcClientEntry)id_cache->context;
+  (*clients)[i++] = (SilcClientEntry)id_cache->context;
 
   while (silc_idcache_list_next(list, &id_cache))
-    clients[i++] = (SilcClientEntry)id_cache->context;
+    (*clients)[i++] = (SilcClientEntry)id_cache->context;
   
   silc_idcache_list_free(list);
   
-  if (clients_count)
-    *clients_count = i;
+  *clients_count += i;
 
-  return clients;
+  return TRUE;
 }
 
 /* Finds client by nickname hash. */
@@ -446,7 +458,7 @@ silc_idlist_find_client_by_hash(SilcIDList id_list, char *nickname,
   while (id_cache) {
     client = (SilcClientEntry)id_cache->context;
     
-    if (client && !SILC_ID_COMPARE_HASH(client->id, hash))
+    if (client && SILC_ID_COMPARE_HASH(client->id, hash))
       break;
 
     id_cache = NULL;
@@ -520,7 +532,7 @@ silc_idlist_replace_client_id(SilcIDList id_list, SilcClientID *old_id,
 
   /* If the old ID Cache data was the hash value of the old Client ID
      replace it with the hash of new Client ID */
-  if (id_cache->data && !SILC_ID_COMPARE_HASH(old_id, id_cache->data)) {
+  if (id_cache->data && SILC_ID_COMPARE_HASH(old_id, id_cache->data)) {
     silc_free(id_cache->data);
     id_cache->data = silc_calloc(sizeof(new_id->hash), sizeof(unsigned char));
     memcpy(id_cache->data, new_id->hash, sizeof(new_id->hash));
@@ -604,6 +616,8 @@ silc_idlist_add_channel(SilcIDList id_list, char *channel_name, int mode,
 
 int silc_idlist_del_channel(SilcIDList id_list, SilcChannelEntry entry)
 {
+  SILC_LOG_DEBUG(("Start"));
+
   if (entry) {
     SilcChannelClientEntry chl;
 
@@ -630,6 +644,8 @@ int silc_idlist_del_channel(SilcIDList id_list, SilcChannelEntry entry)
       silc_free(entry->cipher);
     if (entry->hmac_name)
       silc_free(entry->hmac_name);
+    if (entry->rekey)
+      silc_free(entry->rekey);
 
     /* Free all data, free also any reference from the client's channel
        list since they share the same memory. */
@@ -744,7 +760,7 @@ silc_idlist_replace_channel_id(SilcIDList id_list, SilcChannelID *old_id,
 
 SilcChannelEntry *
 silc_idlist_get_channels(SilcIDList id_list, SilcChannelID *channel_id,
-                        unsigned int *channels_count)
+                        uint32 *channels_count)
 {
   SilcIDCacheList list = NULL;
   SilcIDCacheEntry id_cache = NULL;