X-Git-Url: http://git.silcnet.org/gitweb/?p=silc.git;a=blobdiff_plain;f=apps%2Fsilcd%2Fidlist.c;h=2562c0f03d39ec1db2f4c252dd78a0fc9d0c0e38;hp=3de0c40e854f5cb86b6c0e5f76be07924d6433af;hb=413da0f8686910f5e627393157566ae729ca99c4;hpb=ee2d310105a20fe8b07ce042395187364e1bd58e diff --git a/apps/silcd/idlist.c b/apps/silcd/idlist.c index 3de0c40e..2562c0f0 100644 --- a/apps/silcd/idlist.c +++ b/apps/silcd/idlist.c @@ -2,15 +2,15 @@ idlist.c - Author: Pekka Riikonen + Author: Pekka Riikonen - Copyright (C) 1997 - 2001 Pekka Riikonen + Copyright (C) 1997 - 2003 Pekka Riikonen 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. - + 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 @@ -21,6 +21,7 @@ #include "serverincludes.h" #include "idlist.h" +#include "server_internal.h" /****************************************************************************** @@ -36,14 +37,19 @@ 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_send = idata->hmac_send; data->hmac_receive = idata->hmac_receive; + data->psn_send = idata->psn_send; + data->psn_receive = idata->psn_receive; + data->hash = idata->hash; data->public_key = idata->public_key; + memcpy(data->fingerprint, idata->fingerprint, sizeof(data->fingerprint)); + data->rekey = idata->rekey; data->last_receive = idata->last_receive; data->last_sent = idata->last_sent; - data->registered = idata->registered; + data->status = idata->status; + + data->created = time(0); /* Update creation time */ } /* Free's all data in the common ID entry data structure. */ @@ -62,25 +68,37 @@ void silc_idlist_del_data(void *entry) } silc_free(idata->rekey); } - if (idata->hmac_send) /* Same as idata->hmac_receive */ + if (idata->hmac_send) silc_hmac_free(idata->hmac_send); + if (idata->hmac_receive) + silc_hmac_free(idata->hmac_receive); + if (idata->hash) + silc_hash_free(idata->hash); if (idata->public_key) silc_pkcs_public_key_free(idata->public_key); + + idata->send_key = NULL; + idata->receive_key = NULL; + idata->rekey = NULL; + idata->hmac_send = NULL; + idata->hmac_receive = NULL; + idata->hash = NULL; + idata->public_key = NULL; } /* Purges ID cache */ SILC_TASK_CALLBACK_GLOBAL(silc_idlist_purge) { + SilcServer server = app_context; SilcIDListPurge i = (SilcIDListPurge)context; - SILC_LOG_DEBUG(("Start")); + SILC_LOG_DEBUG(("Purging cache")); silc_idcache_purge(i->cache); - silc_task_register(i->timeout_queue, 0, - silc_idlist_purge, - (void *)i, 600, 0, - SILC_TASK_TIMEOUT, SILC_TASK_PRI_LOW); + silc_schedule_task_add(server->schedule, 0, silc_idlist_purge, + (void *)i, i->timeout, 0, + SILC_TASK_TIMEOUT, SILC_TASK_PRI_LOW); } /****************************************************************************** @@ -94,8 +112,8 @@ SILC_TASK_CALLBACK_GLOBAL(silc_idlist_purge) when new server connects to us. We also add ourselves to cache with this function. */ -SilcServerEntry -silc_idlist_add_server(SilcIDList id_list, +SilcServerEntry +silc_idlist_add_server(SilcIDList id_list, char *server_name, int server_type, SilcServerID *id, SilcServerEntry router, void *connection) @@ -111,8 +129,8 @@ silc_idlist_add_server(SilcIDList id_list, server->router = router; server->connection = connection; - if (!silc_idcache_add(id_list->servers, server->server_name, - (void *)server->id, (void *)server, FALSE)) { + if (!silc_idcache_add(id_list->servers, server->server_name, + (void *)server->id, (void *)server, 0, NULL)) { silc_free(server); return NULL; } @@ -124,7 +142,7 @@ silc_idlist_add_server(SilcIDList id_list, SilcServerEntry silc_idlist_find_server_by_id(SilcIDList id_list, SilcServerID *id, - SilcIDCacheEntry *ret_entry) + bool registered, SilcIDCacheEntry *ret_entry) { SilcIDCacheEntry id_cache = NULL; SilcServerEntry server; @@ -135,15 +153,21 @@ silc_idlist_find_server_by_id(SilcIDList id_list, SilcServerID *id, SILC_LOG_DEBUG(("Server ID (%s)", silc_id_render(id, SILC_ID_SERVER))); - if (!silc_idcache_find_by_id_one(id_list->servers, (void *)id, + if (!silc_idcache_find_by_id_one(id_list->servers, (void *)id, &id_cache)) return NULL; server = (SilcServerEntry)id_cache->context; + if (server && registered && + !(server->data.status & SILC_IDLIST_STATUS_REGISTERED)) + return NULL; + if (ret_entry) *ret_entry = id_cache; + SILC_LOG_DEBUG(("Found")); + return server; } @@ -151,7 +175,7 @@ silc_idlist_find_server_by_id(SilcIDList id_list, SilcServerID *id, SilcServerEntry silc_idlist_find_server_by_name(SilcIDList id_list, char *name, - SilcIDCacheEntry *ret_entry) + bool registered, SilcIDCacheEntry *ret_entry) { SilcIDCacheEntry id_cache = NULL; SilcServerEntry server; @@ -162,7 +186,11 @@ silc_idlist_find_server_by_name(SilcIDList id_list, char *name, return NULL; server = (SilcServerEntry)id_cache->context; - + + if (server && registered && + !(server->data.status & SILC_IDLIST_STATUS_REGISTERED)) + return NULL; + if (ret_entry) *ret_entry = id_cache; @@ -175,13 +203,14 @@ silc_idlist_find_server_by_name(SilcIDList id_list, char *name, SilcServerEntry silc_idlist_find_server_by_conn(SilcIDList id_list, char *hostname, - int port, SilcIDCacheEntry *ret_entry) + int port, bool registered, + SilcIDCacheEntry *ret_entry) { SilcIDCacheList list = NULL; SilcIDCacheEntry id_cache = NULL; SilcServerEntry server = NULL; SilcSocketConnection sock; - + SILC_LOG_DEBUG(("Server by hostname %s and port %d", hostname, port)); if (!silc_idcache_get_all(id_list->servers, &list)) @@ -195,10 +224,10 @@ silc_idlist_find_server_by_conn(SilcIDList id_list, char *hostname, while (id_cache) { server = (SilcServerEntry)id_cache->context; sock = (SilcSocketConnection)server->connection; - + if (sock && ((sock->hostname && !strcasecmp(sock->hostname, hostname)) || (sock->ip && !strcasecmp(sock->ip, hostname))) - && sock->port == port) + && server->id->port == SILC_SWAB_16(port)) break; id_cache = NULL; @@ -207,9 +236,13 @@ silc_idlist_find_server_by_conn(SilcIDList id_list, char *hostname, if (!silc_idcache_list_next(list, &id_cache)) break; } - + silc_idcache_list_free(list); + if (server && registered && + !(server->data.status & SILC_IDLIST_STATUS_REGISTERED)) + return NULL; + if (ret_entry) *ret_entry = id_cache; @@ -218,7 +251,7 @@ silc_idlist_find_server_by_conn(SilcIDList id_list, char *hostname, return server; } -/* Replaces old Server ID with new one */ +/* Replaces old Server ID with new one */ SilcServerEntry silc_idlist_replace_server_id(SilcIDList id_list, SilcServerID *old_id, @@ -232,18 +265,21 @@ silc_idlist_replace_server_id(SilcIDList id_list, SilcServerID *old_id, SILC_LOG_DEBUG(("Replacing Server ID")); - if (!silc_idcache_find_by_id_one(id_list->servers, (void *)old_id, + if (!silc_idcache_find_by_id_one(id_list->servers, (void *)old_id, &id_cache)) return NULL; server = (SilcServerEntry)id_cache->context; + + /* Remove the old entry and add a new one */ + + silc_idcache_del_by_id(id_list->servers, (void *)server->id); + silc_free(server->id); server->id = new_id; - /* Remove the old entry and add a new one */ - silc_idcache_del_by_context(id_list->servers, server); - silc_idcache_add(id_list->servers, server->server_name, server->id, - server, FALSE); + silc_idcache_add(id_list->servers, server->server_name, server->id, + server, 0, NULL); SILC_LOG_DEBUG(("Found")); @@ -254,19 +290,22 @@ silc_idlist_replace_server_id(SilcIDList id_list, SilcServerID *old_id, int silc_idlist_del_server(SilcIDList id_list, SilcServerEntry entry) { - SILC_LOG_DEBUG(("Start")); - if (entry) { /* Remove from cache */ - if (entry->id) - if (!silc_idcache_del_by_id(id_list->servers, (void *)entry->id)) - return FALSE; + if (!silc_idcache_del_by_context(id_list->servers, entry)) { + SILC_LOG_DEBUG(("Unknown server, did not delete")); + return FALSE; + } + + SILC_LOG_DEBUG(("Deleting server %s id %s", entry->server_name ? + entry->server_name : "", + entry->id ? + silc_id_render(entry->id, SILC_ID_SERVER) : "")); /* Free data */ - if (entry->server_name) - silc_free(entry->server_name); - if (entry->id) - silc_free(entry->id); + silc_free(entry->server_name); + silc_free(entry->id); + silc_free(entry->server_info); memset(entry, 'F', sizeof(*entry)); silc_free(entry); @@ -292,9 +331,10 @@ int silc_idlist_del_server(SilcIDList id_list, SilcServerEntry entry) to be directly connected local client and `router' must be NULL. */ SilcClientEntry -silc_idlist_add_client(SilcIDList id_list, char *nickname, char *username, - char *userinfo, SilcClientID *id, - SilcServerEntry router, void *connection) +silc_idlist_add_client(SilcIDList id_list, char *nickname, char *username, + char *userinfo, SilcClientID *id, + SilcServerEntry router, void *connection, + int expire) { SilcClientEntry client; @@ -310,8 +350,8 @@ silc_idlist_add_client(SilcIDList id_list, char *nickname, char *username, client->channels = silc_hash_table_alloc(3, silc_hash_ptr, NULL, NULL, NULL, NULL, NULL, TRUE); - if (!silc_idcache_add(id_list->clients, nickname, (void *)client->id, - (void *)client, FALSE)) { + if (!silc_idcache_add(id_list->clients, nickname, (void *)client->id, + (void *)client, expire, NULL)) { silc_hash_table_free(client->channels); silc_free(client); return NULL; @@ -329,19 +369,21 @@ int silc_idlist_del_client(SilcIDList id_list, SilcClientEntry entry) if (entry) { /* Remove from cache */ - if (entry->id) - if (!silc_idcache_del_by_context(id_list->clients, entry)) - return FALSE; + if (!silc_idcache_del_by_context(id_list->clients, entry)) { + SILC_LOG_DEBUG(("Unknown client, did not delete")); + return FALSE; + } + + assert(!silc_hash_table_count(entry->channels)); /* Free data */ - if (entry->nickname) - silc_free(entry->nickname); - if (entry->username) - silc_free(entry->username); - if (entry->userinfo) - silc_free(entry->userinfo); - if (entry->id) - silc_free(entry->id); + silc_free(entry->nickname); + silc_free(entry->servername); + silc_free(entry->username); + silc_free(entry->userinfo); + silc_free(entry->id); + silc_free(entry->attrs); + silc_hash_table_free(entry->channels); memset(entry, 'F', sizeof(*entry)); silc_free(entry); @@ -356,35 +398,31 @@ int silc_idlist_del_client(SilcIDList id_list, SilcClientEntry entry) returned to `clients_count'. Caller must free the returned table. */ int silc_idlist_get_clients_by_nickname(SilcIDList id_list, char *nickname, - char *server, + char *server, SilcClientEntry **clients, - uint32 *clients_count) + SilcUInt32 *clients_count) { SilcIDCacheList list = NULL; SilcIDCacheEntry id_cache = NULL; - int i; SILC_LOG_DEBUG(("Start")); if (!silc_idcache_find_by_name(id_list->clients, nickname, &list)) return FALSE; - *clients = silc_realloc(*clients, - (silc_idcache_list_count(list) + *clients_count) * + *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)[(*clients_count)++] = (SilcClientEntry)id_cache->context; while (silc_idcache_list_next(list, &id_cache)) - (*clients)[i++] = (SilcClientEntry)id_cache->context; - + (*clients)[(*clients_count)++] = (SilcClientEntry)id_cache->context; + silc_idcache_list_free(list); - - *clients_count += i; - SILC_LOG_DEBUG(("Found %d clients", *clients_count)); + SILC_LOG_DEBUG(("Found total %d clients", *clients_count)); return TRUE; } @@ -395,17 +433,19 @@ int silc_idlist_get_clients_by_nickname(SilcIDList id_list, char *nickname, int silc_idlist_get_clients_by_hash(SilcIDList id_list, char *nickname, SilcHash md5hash, SilcClientEntry **clients, - uint32 *clients_count) + SilcUInt32 *clients_count) { SilcIDCacheList list = NULL; SilcIDCacheEntry id_cache = NULL; unsigned char hash[32]; - int i; SilcClientID client_id; + char nick[128 + 1]; SILC_LOG_DEBUG(("Start")); - silc_hash_make(md5hash, nickname, strlen(nickname), hash); + memset(nick, 0, sizeof(nick)); + silc_to_lower(nickname, nick, sizeof(nick) - 1); + silc_hash_make(md5hash, nick, strlen(nick), hash); /* As the Client ID is hashed in the ID cache by hashing only the hash from the Client ID, we can do a lookup with only the hash not the @@ -416,22 +456,19 @@ int silc_idlist_get_clients_by_hash(SilcIDList id_list, char *nickname, if (!silc_idcache_find_by_id(id_list->clients, &client_id, &list)) return FALSE; - *clients = silc_realloc(*clients, - (silc_idcache_list_count(list) + *clients_count) * + *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)[(*clients_count)++] = (SilcClientEntry)id_cache->context; while (silc_idcache_list_next(list, &id_cache)) - (*clients)[i++] = (SilcClientEntry)id_cache->context; - + (*clients)[(*clients_count)++] = (SilcClientEntry)id_cache->context; + silc_idcache_list_free(list); - - *clients_count += i; - SILC_LOG_DEBUG(("Found %d clients", *clients_count)); + SILC_LOG_DEBUG(("Found total %d clients", *clients_count)); return TRUE; } @@ -440,7 +477,7 @@ int silc_idlist_get_clients_by_hash(SilcIDList id_list, char *nickname, SilcClientEntry silc_idlist_find_client_by_id(SilcIDList id_list, SilcClientID *id, - SilcIDCacheEntry *ret_entry) + bool registered, SilcIDCacheEntry *ret_entry) { SilcIDCacheEntry id_cache = NULL; SilcClientEntry client; @@ -448,21 +485,25 @@ silc_idlist_find_client_by_id(SilcIDList id_list, SilcClientID *id, if (!id) return NULL; - SILC_LOG_DEBUG(("Client ID (%s)", + SILC_LOG_DEBUG(("Client ID (%s)", silc_id_render(id, SILC_ID_CLIENT))); /* Do extended search since the normal ID comparison function for Client ID's compares only the hash from the Client ID and not the entire ID. The silc_hash_client_id_compare compares the entire Client ID as we want to find one specific Client ID. */ - if (!silc_idcache_find_by_id_one_ext(id_list->clients, (void *)id, - NULL, NULL, + if (!silc_idcache_find_by_id_one_ext(id_list->clients, (void *)id, + NULL, NULL, silc_hash_client_id_compare, NULL, &id_cache)) return NULL; client = (SilcClientEntry)id_cache->context; + if (client && registered && + !(client->data.status & SILC_IDLIST_STATUS_REGISTERED)) + return NULL; + if (ret_entry) *ret_entry = id_cache; @@ -474,8 +515,9 @@ silc_idlist_find_client_by_id(SilcIDList id_list, SilcClientID *id, /* Replaces old Client ID with new one */ SilcClientEntry -silc_idlist_replace_client_id(SilcIDList id_list, SilcClientID *old_id, - SilcClientID *new_id) +silc_idlist_replace_client_id(SilcServer server, + SilcIDList id_list, SilcClientID *old_id, + SilcClientID *new_id, const char *nickname) { SilcIDCacheEntry id_cache = NULL; SilcClientEntry client; @@ -489,20 +531,37 @@ silc_idlist_replace_client_id(SilcIDList id_list, SilcClientID *old_id, Client ID's compares only the hash from the Client ID and not the entire ID. The silc_hash_client_id_compare compares the entire Client ID as we want to find one specific Client ID. */ - if (!silc_idcache_find_by_id_one_ext(id_list->clients, (void *)old_id, - NULL, NULL, + if (!silc_idcache_find_by_id_one_ext(id_list->clients, (void *)old_id, + NULL, NULL, silc_hash_client_id_compare, NULL, &id_cache)) return NULL; client = (SilcClientEntry)id_cache->context; + + /* Remove the old entry and add a new one */ + + if (!silc_idcache_del_by_context(id_list->clients, client)) + return NULL; + + /* Check if anyone is watching old nickname */ + if (server->server_type == SILC_ROUTER) + silc_server_check_watcher_list(server, client, nickname, + SILC_NOTIFY_TYPE_NICK_CHANGE); + silc_free(client->id); + silc_free(client->nickname); client->id = new_id; + client->nickname = nickname ? strdup(nickname) : NULL; - /* Remove the old entry and add a new one */ - silc_idcache_del_by_context(id_list->clients, client); - silc_idcache_add(id_list->clients, client->nickname, client->id, - client, FALSE); + /* Check if anyone is watching new nickname */ + if (server->server_type == SILC_ROUTER) + silc_server_check_watcher_list(server, client, nickname, + SILC_NOTIFY_TYPE_NICK_CHANGE); + + if (!silc_idcache_add(id_list->clients, client->nickname, client->id, + client, 0, NULL)) + return NULL; SILC_LOG_DEBUG(("Replaced")); @@ -516,20 +575,17 @@ void silc_idlist_client_destructor(SilcIDCache cache, { SilcClientEntry client; - SILC_LOG_DEBUG(("Start")); - client = (SilcClientEntry)entry->context; if (client) { - if (client->nickname) - silc_free(client->nickname); - if (client->username) - silc_free(client->username); - if (client->userinfo) - silc_free(client->userinfo); - if (client->id) - silc_free(client->id); - - memset(client, 'F', sizeof(*client)); + assert(!silc_hash_table_count(client->channels)); + silc_free(client->nickname); + silc_free(client->username); + silc_free(client->userinfo); + silc_free(client->id); + silc_free(client->attrs); + silc_hash_table_free(client->channels); + + memset(client, 'A', sizeof(*client)); silc_free(client); } } @@ -546,10 +602,13 @@ void silc_idlist_client_destructor(SilcIDCache cache, SilcChannelEntry silc_idlist_add_channel(SilcIDList id_list, char *channel_name, int mode, SilcChannelID *id, SilcServerEntry router, - SilcCipher channel_key, SilcHmac hmac) + SilcCipher channel_key, SilcHmac hmac, + int expire) { SilcChannelEntry channel; + SILC_LOG_DEBUG(("Adding new channel %s", channel_name)); + channel = silc_calloc(1, sizeof(*channel)); channel->channel_name = channel_name; channel->mode = mode; @@ -557,8 +616,9 @@ silc_idlist_add_channel(SilcIDList id_list, char *channel_name, int mode, channel->router = router; channel->channel_key = channel_key; channel->hmac = hmac; + channel->created = channel->updated = time(0); if (!channel->hmac) - if (!silc_hmac_alloc("hmac-sha1-96", NULL, &channel->hmac)) { + if (!silc_hmac_alloc(SILC_DEFAULT_HMAC, NULL, &channel->hmac)) { silc_free(channel); return NULL; } @@ -566,8 +626,8 @@ silc_idlist_add_channel(SilcIDList id_list, char *channel_name, int mode, channel->user_list = silc_hash_table_alloc(3, silc_hash_ptr, NULL, NULL, NULL, NULL, NULL, TRUE); - if (!silc_idcache_add(id_list->channels, channel->channel_name, - (void *)channel->id, (void *)channel, FALSE)) { + if (!silc_idcache_add(id_list->channels, channel->channel_name, + (void *)channel->id, (void *)channel, expire, NULL)) { silc_hmac_free(channel->hmac); silc_hash_table_free(channel->user_list); silc_free(channel); @@ -585,6 +645,10 @@ static void silc_idlist_del_channel_foreach(void *key, void *context, { SilcChannelClientEntry chl = (SilcChannelClientEntry)context; + SILC_LOG_DEBUG(("Removing client %s from channel %s", + chl->client->nickname ? chl->client->nickname : + (unsigned char *)"", chl->channel->channel_name)); + /* 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(chl->client->channels, chl->channel); @@ -595,40 +659,47 @@ static void silc_idlist_del_channel_foreach(void *key, void *context, int silc_idlist_del_channel(SilcIDList id_list, SilcChannelEntry entry) { - SILC_LOG_DEBUG(("Start")); - if (entry) { /* Remove from cache */ - if (entry->id) - if (!silc_idcache_del_by_id(id_list->channels, (void *)entry->id)) - return FALSE; + if (!silc_idcache_del_by_context(id_list->channels, entry)) { + SILC_LOG_DEBUG(("Unknown channel, did not delete")); + return FALSE; + } + + SILC_LOG_DEBUG(("Deleting channel %s", entry->channel_name)); + + /* 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(entry->user_list, silc_idlist_del_channel_foreach, + NULL); + silc_hash_table_free(entry->user_list); /* Free data */ - if (entry->channel_name) - silc_free(entry->channel_name); - if (entry->id) - silc_free(entry->id); - if (entry->topic) - silc_free(entry->topic); + silc_free(entry->channel_name); + silc_free(entry->id); + silc_free(entry->topic); + + if (entry->invite_list) + silc_hash_table_free(entry->invite_list); + if (entry->ban_list) + silc_hash_table_free(entry->ban_list); + if (entry->channel_key) silc_cipher_free(entry->channel_key); if (entry->key) { memset(entry->key, 0, entry->key_len / 8); silc_free(entry->key); } - if (entry->cipher) - silc_free(entry->cipher); - if (entry->hmac_name) - silc_free(entry->hmac_name); - if (entry->rekey) - silc_free(entry->rekey); - - /* 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(entry->user_list, silc_idlist_del_channel_foreach, - NULL); - silc_hash_table_free(entry->user_list); + silc_free(entry->cipher); + if (entry->hmac) + silc_hmac_free(entry->hmac); + silc_free(entry->hmac_name); + silc_free(entry->rekey); + if (entry->founder_key) + silc_pkcs_public_key_free(entry->founder_key); + if (entry->channel_pubkeys) + silc_hash_table_free(entry->channel_pubkeys); memset(entry, 'F', sizeof(*entry)); silc_free(entry); @@ -647,7 +718,7 @@ silc_idlist_find_channel_by_name(SilcIDList id_list, char *name, { SilcIDCacheEntry id_cache = NULL; - SILC_LOG_DEBUG(("Channel by name")); + SILC_LOG_DEBUG(("Channel by name %s", name)); if (!silc_idcache_find_by_name_one(id_list->channels, name, &id_cache)) return NULL; @@ -657,6 +728,9 @@ silc_idlist_find_channel_by_name(SilcIDList id_list, char *name, SILC_LOG_DEBUG(("Found")); + /* Touch channel */ + ((SilcChannelEntry)id_cache->context)->updated = time(NULL); + return id_cache->context; } @@ -685,6 +759,9 @@ silc_idlist_find_channel_by_id(SilcIDList id_list, SilcChannelID *id, SILC_LOG_DEBUG(("Found")); + /* Touch channel */ + channel->updated = time(NULL); + return channel; } @@ -703,21 +780,27 @@ silc_idlist_replace_channel_id(SilcIDList id_list, SilcChannelID *old_id, SILC_LOG_DEBUG(("Replacing Channel ID")); - if (!silc_idcache_find_by_id_one(id_list->channels, (void *)old_id, + if (!silc_idcache_find_by_id_one(id_list->channels, (void *)old_id, &id_cache)) return NULL; channel = (SilcChannelEntry)id_cache->context; + + /* Remove the old entry and add a new one */ + + silc_idcache_del_by_id(id_list->channels, (void *)channel->id); + silc_free(channel->id); channel->id = new_id; - /* Remove the old entry and add a new one */ - silc_idcache_del_by_context(id_list->channels, channel); - silc_idcache_add(id_list->channels, channel->channel_name, channel->id, - channel, FALSE); + silc_idcache_add(id_list->channels, channel->channel_name, channel->id, + channel, 0, NULL); SILC_LOG_DEBUG(("Replaced")); + /* Touch channel */ + channel->updated = time(NULL); + return channel; } @@ -726,7 +809,7 @@ silc_idlist_replace_channel_id(SilcIDList id_list, SilcChannelID *old_id, SilcChannelEntry * silc_idlist_get_channels(SilcIDList id_list, SilcChannelID *channel_id, - uint32 *channels_count) + SilcUInt32 *channels_count) { SilcIDCacheList list = NULL; SilcIDCacheEntry id_cache = NULL; @@ -740,14 +823,14 @@ silc_idlist_get_channels(SilcIDList id_list, SilcChannelID *channel_id, return NULL; channels = silc_calloc(silc_idcache_list_count(list), sizeof(*channels)); - + i = 0; silc_idcache_list_first(list, &id_cache); channels[i++] = (SilcChannelEntry)id_cache->context; - + while (silc_idcache_list_next(list, &id_cache)) channels[i++] = (SilcChannelEntry)id_cache->context; - + silc_idcache_list_free(list); } else { if (!silc_idcache_find_by_id_one(id_list->channels, channel_id, &id_cache))