+ SILC_LOG_DEBUG(("Channel by name %s", name));
+
+ if (!silc_idcache_find_by_name_one(id_list->channels, name, &id_cache))
+ return NULL;
+
+ if (ret_entry)
+ *ret_entry = id_cache;
+
+ SILC_LOG_DEBUG(("Found"));
+
+ /* Touch channel */
+ ((SilcChannelEntry)id_cache->context)->updated = time(NULL);
+
+ return id_cache->context;
+}
+
+/* Finds channel by Channel ID. */
+
+SilcChannelEntry
+silc_idlist_find_channel_by_id(SilcIDList id_list, SilcChannelID *id,
+ SilcIDCacheEntry *ret_entry)
+{
+ SilcIDCacheEntry id_cache = NULL;
+ SilcChannelEntry channel;
+
+ if (!id)
+ return NULL;
+
+ SILC_LOG_DEBUG(("Channel ID (%s)",
+ silc_id_render(id, SILC_ID_CHANNEL)));
+
+ if (!silc_idcache_find_by_id_one(id_list->channels, (void *)id, &id_cache))
+ return NULL;
+
+ channel = (SilcChannelEntry)id_cache->context;
+
+ if (ret_entry)
+ *ret_entry = id_cache;
+
+ SILC_LOG_DEBUG(("Found"));
+
+ /* Touch channel */
+ channel->updated = time(NULL);
+
+ return channel;
+}
+
+/* Replaces old Channel ID with new one. This is done when router forces
+ normal server to change Channel ID. */
+
+SilcChannelEntry
+silc_idlist_replace_channel_id(SilcIDList id_list, SilcChannelID *old_id,
+ SilcChannelID *new_id)
+{
+ SilcIDCacheEntry id_cache = NULL;
+ SilcChannelEntry channel;
+ char *name;
+
+ if (!old_id || !new_id)
+ return NULL;
+
+ SILC_LOG_DEBUG(("Replacing Channel ID"));
+
+ if (!silc_idcache_find_by_id_one(id_list->channels, (void *)old_id,
+ &id_cache))
+ return NULL;
+
+ channel = (SilcChannelEntry)id_cache->context;
+ name = strdup(id_cache->name);
+
+ /* 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;
+
+ silc_idcache_add(id_list->channels, name, channel->id, channel, 0, NULL);
+
+ SILC_LOG_DEBUG(("Replaced"));
+
+ /* Touch channel */
+ channel->updated = time(NULL);
+
+ return channel;
+}
+
+/* Returns channels from the ID list. If the `channel_id' is NULL then
+ all channels are returned. */
+
+SilcChannelEntry *
+silc_idlist_get_channels(SilcIDList id_list, SilcChannelID *channel_id,
+ SilcUInt32 *channels_count)
+{
+ SilcIDCacheList list = NULL;
+ SilcIDCacheEntry id_cache = NULL;
+ SilcChannelEntry *channels = NULL;
+ int i = 0;
+
+ SILC_LOG_DEBUG(("Start"));
+
+ if (!channel_id) {
+ if (!silc_idcache_get_all(id_list->channels, &list))
+ 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))
+ return NULL;
+
+ i = 1;
+ channels = silc_calloc(1, sizeof(*channels));
+ channels[0] = (SilcChannelEntry)id_cache->context;