+
+/* Removes servers that are originated from the `from'. The server
+ entry is deleted in this function. If `remove_clients' is TRUE then
+ all clients originated from the server are removed too, and server
+ signoff is sent. Note that this does not remove the `from'. This
+ also does not remove locally connected servers. */
+
+void silc_server_remove_servers_by_server(SilcServer server,
+ SilcServerEntry from,
+ bool remove_clients)
+{
+ SilcIDCacheList list = NULL;
+ SilcIDCacheEntry id_cache = NULL;
+ SilcServerEntry server_entry = NULL;
+
+ SILC_LOG_DEBUG(("Removing servers by %s",
+ from->server_name ? from->server_name : "server"));
+
+ if (silc_idcache_get_all(server->local_list->servers, &list)) {
+ if (silc_idcache_list_first(list, &id_cache)) {
+ while (id_cache) {
+ server_entry = (SilcServerEntry)id_cache->context;
+ if (SILC_IS_LOCAL(server_entry) || server_entry == server->id_entry ||
+ server_entry->router != from || server_entry == from) {
+ if (!silc_idcache_list_next(list, &id_cache))
+ break;
+ else
+ continue;
+ }
+
+ /* Remove clients owned by this server */
+ if (remove_clients)
+ silc_server_remove_clients_by_server(server, from, server_entry,
+ TRUE);
+
+ /* Remove the server */
+ silc_idlist_del_server(server->local_list, server_entry);
+
+ if (!silc_idcache_list_next(list, &id_cache))
+ break;
+ }
+ }
+ silc_idcache_list_free(list);
+ }
+
+ if (silc_idcache_get_all(server->global_list->servers, &list)) {
+ if (silc_idcache_list_first(list, &id_cache)) {
+ while (id_cache) {
+ server_entry = (SilcServerEntry)id_cache->context;
+ if (SILC_IS_LOCAL(server_entry) || server_entry == server->id_entry ||
+ server_entry->router != from || server_entry == from) {
+ if (!silc_idcache_list_next(list, &id_cache))
+ break;
+ else
+ continue;
+ }
+
+ /* Remove clients owned by this server */
+ if (remove_clients)
+ silc_server_remove_clients_by_server(server, from, server_entry,
+ TRUE);
+
+ /* Remove the server */
+ silc_idlist_del_server(server->global_list, server_entry);
+
+ if (!silc_idcache_list_next(list, &id_cache))
+ break;
+ }
+ }
+ silc_idcache_list_free(list);
+ }
+}
+