+/* Finds server by Server ID */
+
+SilcServerEntry
+silc_idlist_find_server_by_id(SilcIDList id_list, SilcServerID *id,
+ bool registered, SilcIDCacheEntry *ret_entry)
+{
+ SilcIDCacheEntry id_cache = NULL;
+ SilcServerEntry server;
+
+ if (!id)
+ return NULL;
+
+ 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,
+ &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;
+}
+
+/* Find server by name */
+
+SilcServerEntry
+silc_idlist_find_server_by_name(SilcIDList id_list, char *name,
+ bool registered, SilcIDCacheEntry *ret_entry)
+{
+ SilcIDCacheEntry id_cache = NULL;
+ SilcServerEntry server;
+
+ SILC_LOG_DEBUG(("Server by name `%s'", name));
+
+ if (!silc_idcache_find_by_name_one(id_list->servers, name, &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;
+}
+
+/* Find server by connection parameters, hostname and port */
+
+SilcServerEntry
+silc_idlist_find_server_by_conn(SilcIDList id_list, char *hostname,
+ 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))
+ return NULL;
+
+ if (!silc_idcache_list_first(list, &id_cache)) {
+ silc_idcache_list_free(list);
+ return NULL;
+ }
+
+ 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)))
+ && server->id->port == htons(port))
+ break;
+
+ id_cache = NULL;
+ server = NULL;
+
+ 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;
+
+ SILC_LOG_DEBUG(("Found"));
+
+ return server;
+}
+
+/* Replaces old Server ID with new one */
+
+SilcServerEntry
+silc_idlist_replace_server_id(SilcIDList id_list, SilcServerID *old_id,
+ SilcServerID *new_id)
+{
+ SilcIDCacheEntry id_cache = NULL;
+ SilcServerEntry server;
+
+ if (!old_id || !new_id)
+ return NULL;
+
+ SILC_LOG_DEBUG(("Replacing Server 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;
+
+ silc_idcache_add(id_list->servers, server->server_name, server->id,
+ server, 0, NULL);
+
+ SILC_LOG_DEBUG(("Found"));
+
+ return server;
+}
+
+/* Removes and free's server entry from ID list */
+
+int silc_idlist_del_server(SilcIDList id_list, SilcServerEntry entry)
+{
+ if (entry) {
+ /* Remove from cache */
+ if (!silc_idcache_del_by_context(id_list->servers, entry))
+ 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 */
+ silc_free(entry->server_name);
+ silc_free(entry->id);
+ silc_free(entry->server_info);
+
+ memset(entry, 'F', sizeof(*entry));
+ silc_free(entry);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+