+ SilcServerCommandContext cmd = (SilcServerCommandContext)context;
+ SilcServer server = cmd->server;
+ SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
+ SilcServerID *server_id;
+ SilcServerEntry server_entry;
+ unsigned char *tmp;
+ unsigned int tmp_len;
+
+ SILC_SERVER_COMMAND_CHECK_ARGC(SILC_COMMAND_CLOSE, cmd, 0, 0);
+
+ /* Check whether client has the permissions. */
+ if (client->mode == SILC_UMODE_NONE) {
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_CLOSE,
+ SILC_STATUS_ERR_NO_SERVER_PRIV);
+ goto out;
+ }
+
+ /* Get the server ID */
+ tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
+ if (!tmp) {
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_CLOSE,
+ SILC_STATUS_ERR_NO_SERVER_ID);
+ goto out;
+ }
+ server_id = silc_id_payload_parse_id(tmp, tmp_len);
+ if (!server_id) {
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_CLOSE,
+ SILC_STATUS_ERR_NO_SERVER_ID);
+ goto out;
+ }
+
+ /* Check that the server ID is valid and that I have an active
+ connection to it. Check only local list as it holds the local
+ connections. */
+ server_entry = silc_idlist_find_server_by_id(server->local_list,
+ server_id, NULL);
+ if (!server_entry) {
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_CLOSE,
+ SILC_STATUS_ERR_NO_SERVER_ID);
+ goto out;
+ }
+
+ /* Close the connection to the server */
+ silc_server_free_sock_user_data(server, server_entry->connection);
+ silc_server_disconnect_remote(server, server_entry->connection,
+ "Server closed connection: "
+ "Closed by operator");
+
+ /* Send reply to the sender */
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_INVITE,
+ SILC_STATUS_OK);
+
+ out:
+ silc_server_command_free(cmd);