diff --git a/src/Makefile.am b/src/Makefile.am index e53c2f96..1c4ccfef 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -195,6 +195,7 @@ libsub_root_a_SOURCES = \ command_tracker.cc \ command_scheduler.cc \ command_string.cc \ + command_system.cc \ command_ui.cc \ control.cc \ control.h \ diff --git a/src/command_download.cc b/src/command_download.cc index 36aee870..a910c178 100644 --- a/src/command_download.cc +++ b/src/command_download.cc @@ -142,16 +142,6 @@ apply_d_delete_tied(core::Download* download) { return torrent::Object(); } -void -apply_d_directory(core::Download* download, const std::string& name) { - if (!download->file_list()->is_multi_file()) - download->set_root_directory(name); - else if (name.empty() || *name.rbegin() == '/') - download->set_root_directory(name + download->info()->name().str()); - else - download->set_root_directory(name + "/" + download->info()->name().str()); -} - torrent::Object apply_d_connection_type(core::Download* download, const std::string& name) { torrent::Download::ConnectionType t = @@ -884,12 +874,11 @@ initialize_command_download() { CMD2_DL_LIST ("d.tracker.insert", std::bind(&download_tracker_insert, std::placeholders::_1, std::placeholders::_2)); CMD2_DL_VALUE_V ("d.tracker.send_scrape", [](auto download, uint64_t arg) { download->tracker_controller().scrape_request(arg); }); - CMD2_DL ("d.directory", CMD2_ON_FL(root_dir)); - CMD2_DL ("d.directory.realpath.or_empty", [](auto* download, auto) { return resolve_path(download->file_list()->root_dir()); }); - CMD2_DL ("d.directory.realpath.or_throw", [](auto* download, auto) { return resolve_path_or_throw(download->file_list()->root_dir()); }); - CMD2_DL_STRING_V("d.directory.set", std::bind(&apply_d_directory, std::placeholders::_1, std::placeholders::_2)); - CMD2_DL ("d.directory_base", CMD2_ON_FL(root_dir)); - CMD2_DL_STRING_V("d.directory_base.set", std::bind(&core::Download::set_root_directory, std::placeholders::_1, std::placeholders::_2)); + CMD2_DL ("d.directory", CMD2_ON_FL(root_dir)); + CMD2_DL ("d.directory.realpath.or_empty", [](auto* download, auto) { return resolve_path(download->file_list()->root_dir()); }); + CMD2_DL ("d.directory.realpath.or_throw", [](auto* download, auto) { return resolve_path_or_throw(download->file_list()->root_dir()); }); + CMD2_DL_STRING_V("d.directory.set", [](auto* download, auto arg) { download->set_directory(arg); }); + CMD2_DL_STRING_V("d.directory.base.set", [](auto* download, auto arg) { download->set_base_directory(arg); }); CMD2_DL ("d.priority", std::bind(&core::Download::priority, std::placeholders::_1)); CMD2_DL ("d.priority_str", std::bind(&retrieve_d_priority_str, std::placeholders::_1)); @@ -950,7 +939,6 @@ initialize_command_download() { rpc::rpc.mark_safe("d.name.or_base64"); rpc::rpc.mark_safe("d.name.or_as_binary"); rpc::rpc.mark_safe("d.directory"); - rpc::rpc.mark_safe("d.directory_base"); rpc::rpc.mark_safe("d.creation_date"); rpc::rpc.mark_safe("d.load_date"); rpc::rpc.mark_safe("d.up.rate"); diff --git a/src/command_helpers.cc b/src/command_helpers.cc index 512d1a6a..fee22018 100644 --- a/src/command_helpers.cc +++ b/src/command_helpers.cc @@ -20,6 +20,7 @@ void initialize_command_throttle(); void initialize_command_tracker(); void initialize_command_scheduler(); void initialize_command_string(); +void initialize_command_system(); void initialize_command_ui(); void @@ -39,4 +40,5 @@ initialize_commands() { initialize_command_tracker(); initialize_command_scheduler(); initialize_command_string(); + initialize_command_system(); } diff --git a/src/command_local.cc b/src/command_local.cc index 5b5a1aea..ab73fe15 100644 --- a/src/command_local.cc +++ b/src/command_local.cc @@ -1,35 +1,16 @@ #include "config.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include -#include -#include #include -#include +#include "command_helpers.h" +#include "control.h" #include "core/download.h" -#include "core/download_list.h" #include "core/manager.h" #include "rpc/parse_commands.h" +#include "rpc/lua.h" #include "rpc/scgi.h" #include "session/session_manager.h" -#include "utils/file_status_cache.h" - -#include "globals.h" -#include "rpc/lua.h" -#include "control.h" -#include "command_helpers.h" typedef torrent::ChunkManager CM_t; typedef torrent::FileManager FM_t; @@ -45,49 +26,6 @@ apply_pieces_stats_total_size() { return size; } -torrent::Object -system_env(const torrent::Object::string_type& arg) { - if (arg.empty()) - throw torrent::input_error("system.env: Missing variable name."); - - char* val = getenv(arg.c_str()); - return std::string(val ? val : ""); -} - -torrent::Object -system_hostname() { - char buffer[1024]; - - if (gethostname(buffer, 1023) == -1) - throw torrent::input_error("Unable to read hostname."); - -// if (shorten) -// *std::find(buffer, buffer + 1023, '.') = '\0'; - - return std::string(buffer); -} - -torrent::Object -system_get_cwd() { - char* buffer = getcwd(NULL, 0); - - if (buffer == NULL) - throw torrent::input_error("Unable to read cwd."); - - torrent::Object result = torrent::Object(std::string(buffer)); - free(buffer); - - return result; -} - -torrent::Object -system_set_cwd(const torrent::Object::string_type& rawArgs) { - if (::chdir(rawArgs.c_str()) != 0) - throw torrent::input_error("Could not change current working directory."); - - return torrent::Object(); -} - inline torrent::Object::list_const_iterator post_increment(torrent::Object::list_const_iterator& itr, const torrent::Object::list_const_iterator& last) { if (itr == last) @@ -187,97 +125,10 @@ cmd_file_append(const torrent::Object::list_type& args) { return torrent::Object(); } -uint32_t -checked_socket_value(int64_t value, const char* label) { - if (value < 0 || value > std::numeric_limits::max()) - throw torrent::input_error(std::string("Invalid ") + label + " value."); - - return static_cast(value); -} - void initialize_command_local() { core::DownloadList* dList = control->core()->download_list(); - CMD_ANY ("system.hostname", std::bind(&system_hostname)); - CMD_ANY ("system.pid", std::bind(&getpid)); - - CMD_VAR_C_STRING("system.api_version", (int64_t)API_VERSION); - CMD_VAR_C_STRING("system.client_version", PACKAGE_VERSION); - CMD_VAR_C_STRING("system.library_version", torrent::runtime::version()); - - CMD_VAR_VALUE ("system.file.allocate", 0); - CMD_VAR_VALUE ("system.file.max_size", (int64_t)512 << 30); - CMD_VAR_VALUE ("system.file.split_size", -1); - CMD_VAR_STRING ("system.file.split_suffix", ".part"); - - CMD_ANY ("system.file_status_cache.size", std::bind(&utils::FileStatusCache::size, - (utils::FileStatusCache::base_type*)control->core()->file_status_cache())); - CMD_ANY_V ("system.file_status_cache.prune", std::bind(&utils::FileStatusCache::prune, control->core()->file_status_cache())); - - CMD_VAR_BOOL ("file.prioritize_toc", 0); - CMD_VAR_LIST ("file.prioritize_toc.first"); - CMD_VAR_LIST ("file.prioritize_toc.last"); - - CMD_ANY ("system.files.advise_random", [](auto, auto) { return torrent::file_manager()->advise_random(); }); - CMD_ANY_VALUE_V ("system.files.advise_random.set", [](auto, auto& value) { return torrent::file_manager()->set_advise_random(value); }); - CMD_ANY ("system.files.advise_random.hashing", [](auto, auto) { return torrent::file_manager()->advise_random_hashing(); }); - CMD_ANY_VALUE_V ("system.files.advise_random.hashing.set", [](auto, auto& value) { return torrent::file_manager()->set_advise_random_hashing(value); }); - CMD_ANY ("system.files.session.fdatasync", [](auto, auto) { return session_thread::manager()->use_fsyncdisk(); }); - CMD_ANY_VALUE_V ("system.files.session.fdatasync.set", [](auto, auto& value) { return session_thread::manager()->set_use_fsyncdisk(value); }); - - CMD_ANY ("system.files.close_idle", [](auto, auto) { return torrent::file_manager()->close_idle_timeout().count(); }); - CMD_ANY_VALUE_V ("system.files.close_idle.set", [](auto, auto& value) { return torrent::file_manager()->set_close_idle_timeout(value * 1s); }); - - CMD_ANY ("system.files.opened_counter", [](auto, auto) { return torrent::file_manager()->files_opened_counter(); }); - CMD_ANY ("system.files.closed_counter", [](auto, auto) { return torrent::file_manager()->files_closed_counter(); }); - CMD_ANY ("system.files.failed_counter", [](auto, auto) { return torrent::file_manager()->files_failed_counter(); }); - - CMD_ANY_STRING ("system.env", [](auto, auto& str) { return system_env(str); }); - - CMD_ANY ("system.time", [](auto, auto) { return torrent::this_thread::cached_seconds().count(); }); - CMD_ANY ("system.time_seconds", [](auto, auto) { return torrent::utils::cast_seconds(torrent::utils::time_since_epoch()).count(); }); - CMD_ANY ("system.time_usec", [](auto, auto) { return torrent::utils::time_since_epoch().count(); }); - - CMD_ANY_VALUE_V ("system.umask.set", [](auto, auto& value) { return ::umask(value); }); - - CMD_VAR_BOOL ("system.daemon", false); - - CMD_ANY_V ("system.shutdown.normal", [](auto, auto) { control->receive_normal_shutdown(); }); - CMD_ANY_V ("system.shutdown.quick", [](auto, auto) { control->receive_quick_shutdown(); }); - - CMD_REDIRECT_NO_EXPORT("system.shutdown", "system.shutdown.normal"); - - CMD_ANY ("system.cwd", [](auto, auto) { return system_get_cwd(); }); - CMD_ANY_STRING ("system.cwd.set", [](auto, auto& str) { return system_set_cwd(str); }); - - CMD_ANY ("system.sockets.size", [](auto, auto) { return torrent::runtime::socket_manager()->size(); }); - CMD_ANY ("system.sockets.max_size", [](auto, auto) { return torrent::runtime::socket_manager()->max_size(); }); - CMD_ANY_VALUE_V ("system.sockets.max_size.set", [](auto, auto& value) { return torrent::runtime::socket_manager()->set_max_size_and_adjust(checked_socket_value(value, "socket max size")); }); - CMD_ANY_V ("system.sockets.adjust_alloc", [](auto, auto) { torrent::runtime::socket_manager()->adjust_allocation(); }); - CMD_ANY ("system.sockets.reserved_alloc", [](auto, auto) { return torrent::runtime::socket_manager()->reserved_allocation(); }); - CMD_ANY ("system.sockets.available_alloc", [](auto, auto) { return torrent::runtime::socket_manager()->available_allocation(); }); - - for (uint32_t i = 0; i < torrent::runtime::SocketManager::category_count; ++i) { - auto category = static_cast(i); - auto category_name = "system.sockets." + torrent::option_to_str_or_throw(torrent::OPTION_SOCKET_CATEGORY, i); - - CMD_ANY (category_name + ".size", [category](auto, auto) { return torrent::runtime::socket_manager()->category_managed_size(category); }); - CMD_ANY (category_name + ".max_size", [category](auto, auto) { return torrent::runtime::socket_manager()->category_max_size(category); }); - - if (i == 0) { - CMD_ANY (category_name + ".min_alloc", [](auto, auto) { return torrent::runtime::socket_manager()->generic_min_allocation(); }); - continue; - } - - CMD_ANY (category_name + ".max_alloc.limit", [category](auto, auto) { return torrent::runtime::socket_manager()->category_alloc_limit(category); }); - CMD_ANY (category_name + ".min_alloc.limit", [category](auto, auto) { return torrent::runtime::socket_manager()->category_alloc_minimum(category); }); - CMD_ANY (category_name + ".min_alloc", [category](auto, auto) { return torrent::runtime::socket_manager()->category_min_allocation(category); }); - CMD_ANY (category_name + ".max_alloc", [category](auto, auto) { return torrent::runtime::socket_manager()->category_max_allocation(category); }); - CMD_ANY_VALUE_V(category_name + ".min_alloc.set", [category](auto, auto& value) { torrent::runtime::socket_manager()->set_category_min_allocation(category, checked_socket_value(value, "socket min alloc")); }); - CMD_ANY_VALUE_V(category_name + ".max_alloc.set", [category](auto, auto& value) { torrent::runtime::socket_manager()->set_category_max_allocation(category, checked_socket_value(value, "socket max alloc")); }); - } - CMD_ANY ("pieces.sync.always_safe", [](auto, auto) { return torrent::runtime::memory_manager()->safe_sync(); }); CMD_ANY_VALUE_V ("pieces.sync.always_safe.set", [](auto, auto& value) { return torrent::runtime::memory_manager()->set_safe_sync(value); }); CMD_ANY ("pieces.sync.safe_free_diskspace", [](auto, auto) { return torrent::runtime::memory_manager()->sync_safe_free_diskspace(); }); @@ -361,38 +212,6 @@ initialize_command_local() { CMD_ANY_LIST ("group.insert", std::bind(&group_insert, std::placeholders::_2)); - rpc::rpc.mark_safe("system.api_version"); - rpc::rpc.mark_safe("system.client_version"); - rpc::rpc.mark_safe("system.library_version"); - rpc::rpc.mark_safe("system.time"); - rpc::rpc.mark_safe("system.time_seconds"); - rpc::rpc.mark_safe("system.time_usec"); - rpc::rpc.mark_safe("system.file.max_size"); - rpc::rpc.mark_safe("system.file.split_size"); - rpc::rpc.mark_safe("system.file.split_suffix"); - - rpc::rpc.mark_safe("system.sockets.size"); - rpc::rpc.mark_safe("system.sockets.max_size"); - rpc::rpc.mark_safe("system.sockets.reserved_alloc"); - rpc::rpc.mark_safe("system.sockets.available_alloc"); - - for (uint32_t i = 0; i < torrent::runtime::SocketManager::category_count; ++i) { - auto category_name = "system.sockets." + torrent::option_to_str_or_throw(torrent::OPTION_SOCKET_CATEGORY, i); - - rpc::rpc.mark_safe(category_name + ".size"); - rpc::rpc.mark_safe(category_name + ".max_size"); - - if (i == 0) { - rpc::rpc.mark_safe(category_name + ".min_alloc"); - continue; - } - - rpc::rpc.mark_safe(category_name + ".max_alloc.limit"); - rpc::rpc.mark_safe(category_name + ".min_alloc.limit"); - rpc::rpc.mark_safe(category_name + ".min_alloc"); - rpc::rpc.mark_safe(category_name + ".max_alloc"); - } - rpc::rpc.mark_safe("directory.default"); rpc::rpc.mark_safe("session.path"); rpc::rpc.mark_safe("session.path.realpath.or_empty"); diff --git a/src/command_system.cc b/src/command_system.cc new file mode 100644 index 00000000..4615acd2 --- /dev/null +++ b/src/command_system.cc @@ -0,0 +1,195 @@ +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "command_helpers.h" +#include "control.h" +#include "globals.h" +#include "core/manager.h" +#include "session/session_manager.h" +#include "utils/file_status_cache.h" + + +torrent::Object +system_env(const torrent::Object::string_type& arg) { + if (arg.empty()) + throw torrent::input_error("system.env: Missing variable name."); + + char* val = getenv(arg.c_str()); + return std::string(val ? val : ""); +} + +torrent::Object +system_hostname() { + char buffer[1024]; + + if (gethostname(buffer, 1023) == -1) + throw torrent::input_error("Unable to read hostname."); + +// if (shorten) +// *std::find(buffer, buffer + 1023, '.') = '\0'; + + return std::string(buffer); +} + +torrent::Object +system_get_cwd() { + char* buffer = getcwd(NULL, 0); + + if (buffer == NULL) + throw torrent::input_error("Unable to read cwd."); + + torrent::Object result = torrent::Object(std::string(buffer)); + free(buffer); + + return result; +} + +torrent::Object +system_set_cwd(const torrent::Object::string_type& rawArgs) { + if (::chdir(rawArgs.c_str()) != 0) + throw torrent::input_error("Could not change current working directory."); + + return torrent::Object(); +} + +uint32_t +checked_socket_value(int64_t value, const char* label) { + if (value < 0 || value > std::numeric_limits::max()) + throw torrent::input_error(std::string("Invalid ") + label + " value."); + + return static_cast(value); +} + +void +initialize_command_system() { + CMD_ANY ("system.hostname", std::bind(&system_hostname)); + CMD_ANY ("system.pid", std::bind(&getpid)); + + CMD_VAR_C_STRING("system.api_version", (int64_t)API_VERSION); + CMD_VAR_C_STRING("system.client_version", PACKAGE_VERSION); + CMD_VAR_C_STRING("system.library_version", torrent::runtime::version()); + + CMD_ANY ("system.torrent_name.use_sanitized", [](auto, auto) { return torrent::runtime::client_config()->torrent_name_use_sanitized(); }); + CMD_ANY_VALUE_V ("system.torrent_name.use_sanitized.set", [](auto, auto& value) { return torrent::runtime::client_config()->set_torrent_name_use_sanitized(value); }); + + CMD_VAR_VALUE ("system.file.allocate", 0); + CMD_VAR_VALUE ("system.file.max_size", (int64_t)512 << 30); + CMD_VAR_VALUE ("system.file.split_size", -1); + CMD_VAR_STRING ("system.file.split_suffix", ".part"); + + CMD_ANY ("system.file_name.replace_slash", [](auto, auto) { return torrent::runtime::client_config()->file_name_replace_slash(); }); + CMD_ANY_STRING_V("system.file_name.replace_slash.set", [](auto, auto& str) { return torrent::runtime::client_config()->set_file_name_replace_slash(str); }); + + CMD_ANY ("system.file_status_cache.size", [](auto, auto) { return control->core()->file_status_cache()->size(); }); + CMD_ANY_V ("system.file_status_cache.prune", [](auto, auto) { return control->core()->file_status_cache()->prune(); }); + + CMD_VAR_BOOL ("file.prioritize_toc", 0); + CMD_VAR_LIST ("file.prioritize_toc.first"); + CMD_VAR_LIST ("file.prioritize_toc.last"); + + CMD_ANY ("system.files.advise_random", [](auto, auto) { return torrent::file_manager()->advise_random(); }); + CMD_ANY_VALUE_V ("system.files.advise_random.set", [](auto, auto& value) { return torrent::file_manager()->set_advise_random(value); }); + CMD_ANY ("system.files.advise_random.hashing", [](auto, auto) { return torrent::file_manager()->advise_random_hashing(); }); + CMD_ANY_VALUE_V ("system.files.advise_random.hashing.set", [](auto, auto& value) { return torrent::file_manager()->set_advise_random_hashing(value); }); + CMD_ANY ("system.files.session.fdatasync", [](auto, auto) { return session_thread::manager()->use_fsyncdisk(); }); + CMD_ANY_VALUE_V ("system.files.session.fdatasync.set", [](auto, auto& value) { return session_thread::manager()->set_use_fsyncdisk(value); }); + + CMD_ANY ("system.files.close_idle", [](auto, auto) { return torrent::file_manager()->close_idle_timeout().count(); }); + CMD_ANY_VALUE_V ("system.files.close_idle.set", [](auto, auto& value) { return torrent::file_manager()->set_close_idle_timeout(value * 1s); }); + + CMD_ANY ("system.files.opened_counter", [](auto, auto) { return torrent::file_manager()->files_opened_counter(); }); + CMD_ANY ("system.files.closed_counter", [](auto, auto) { return torrent::file_manager()->files_closed_counter(); }); + CMD_ANY ("system.files.failed_counter", [](auto, auto) { return torrent::file_manager()->files_failed_counter(); }); + + CMD_ANY_STRING ("system.env", [](auto, auto& str) { return system_env(str); }); + + CMD_ANY ("system.time", [](auto, auto) { return torrent::this_thread::cached_seconds().count(); }); + CMD_ANY ("system.time_seconds", [](auto, auto) { return torrent::utils::cast_seconds(torrent::utils::time_since_epoch()).count(); }); + CMD_ANY ("system.time_usec", [](auto, auto) { return torrent::utils::time_since_epoch().count(); }); + + CMD_ANY_VALUE_V ("system.umask.set", [](auto, auto& value) { return ::umask(value); }); + + CMD_VAR_BOOL ("system.daemon", false); + + CMD_ANY_V ("system.shutdown.normal", [](auto, auto) { control->receive_normal_shutdown(); }); + CMD_ANY_V ("system.shutdown.quick", [](auto, auto) { control->receive_quick_shutdown(); }); + + CMD_REDIRECT_NO_EXPORT("system.shutdown", "system.shutdown.normal"); + + CMD_ANY ("system.cwd", [](auto, auto) { return system_get_cwd(); }); + CMD_ANY_STRING ("system.cwd.set", [](auto, auto& str) { return system_set_cwd(str); }); + + CMD_ANY ("system.sockets.size", [](auto, auto) { return torrent::runtime::socket_manager()->size(); }); + CMD_ANY ("system.sockets.max_size", [](auto, auto) { return torrent::runtime::socket_manager()->max_size(); }); + CMD_ANY_VALUE_V ("system.sockets.max_size.set", [](auto, auto& value) { + return torrent::runtime::socket_manager()->set_max_size_and_adjust(checked_socket_value(value, "socket max size")); + }); + CMD_ANY_V ("system.sockets.adjust_alloc", [](auto, auto) { torrent::runtime::socket_manager()->adjust_allocation(); }); + CMD_ANY ("system.sockets.reserved_alloc", [](auto, auto) { return torrent::runtime::socket_manager()->reserved_allocation(); }); + CMD_ANY ("system.sockets.available_alloc", [](auto, auto) { return torrent::runtime::socket_manager()->available_allocation(); }); + + for (uint32_t i = 0; i < torrent::runtime::SocketManager::category_count; ++i) { + auto category = static_cast(i); + auto category_name = "system.sockets." + torrent::option_to_str_or_throw(torrent::OPTION_SOCKET_CATEGORY, i); + + CMD_ANY (category_name + ".size", [category](auto, auto) { return torrent::runtime::socket_manager()->category_managed_size(category); }); + CMD_ANY (category_name + ".max_size", [category](auto, auto) { return torrent::runtime::socket_manager()->category_max_size(category); }); + + if (i == 0) { + CMD_ANY (category_name + ".min_alloc", [](auto, auto) { return torrent::runtime::socket_manager()->generic_min_allocation(); }); + continue; + } + + CMD_ANY (category_name + ".max_alloc.limit", [category](auto, auto) { return torrent::runtime::socket_manager()->category_alloc_limit(category); }); + CMD_ANY (category_name + ".min_alloc.limit", [category](auto, auto) { return torrent::runtime::socket_manager()->category_alloc_minimum(category); }); + CMD_ANY (category_name + ".min_alloc", [category](auto, auto) { return torrent::runtime::socket_manager()->category_min_allocation(category); }); + CMD_ANY (category_name + ".max_alloc", [category](auto, auto) { return torrent::runtime::socket_manager()->category_max_allocation(category); }); + CMD_ANY_VALUE_V(category_name + ".min_alloc.set", [category](auto, auto& value) { + torrent::runtime::socket_manager()->set_category_min_allocation(category, checked_socket_value(value, "socket min alloc")); + }); + CMD_ANY_VALUE_V(category_name + ".max_alloc.set", [category](auto, auto& value) { + torrent::runtime::socket_manager()->set_category_max_allocation(category, checked_socket_value(value, "socket max alloc")); + }); + } + + rpc::rpc.mark_safe("system.api_version"); + rpc::rpc.mark_safe("system.client_version"); + rpc::rpc.mark_safe("system.library_version"); + rpc::rpc.mark_safe("system.time"); + rpc::rpc.mark_safe("system.time_seconds"); + rpc::rpc.mark_safe("system.time_usec"); + rpc::rpc.mark_safe("system.file.max_size"); + rpc::rpc.mark_safe("system.file.split_size"); + rpc::rpc.mark_safe("system.file.split_suffix"); + + rpc::rpc.mark_safe("system.sockets.size"); + rpc::rpc.mark_safe("system.sockets.max_size"); + rpc::rpc.mark_safe("system.sockets.reserved_alloc"); + rpc::rpc.mark_safe("system.sockets.available_alloc"); + + for (uint32_t i = 0; i < torrent::runtime::SocketManager::category_count; ++i) { + auto category_name = "system.sockets." + torrent::option_to_str_or_throw(torrent::OPTION_SOCKET_CATEGORY, i); + + rpc::rpc.mark_safe(category_name + ".size"); + rpc::rpc.mark_safe(category_name + ".max_size"); + + if (i == 0) { + rpc::rpc.mark_safe(category_name + ".min_alloc"); + continue; + } + + rpc::rpc.mark_safe(category_name + ".max_alloc.limit"); + rpc::rpc.mark_safe(category_name + ".min_alloc.limit"); + rpc::rpc.mark_safe(category_name + ".min_alloc"); + rpc::rpc.mark_safe(category_name + ".max_alloc"); + } +} diff --git a/src/control.h b/src/control.h index dfc287d4..ceb3656e 100644 --- a/src/control.h +++ b/src/control.h @@ -118,4 +118,6 @@ private: std::atomic m_shutdown_quick{}; }; +extern Control* control; + #endif diff --git a/src/core/download.cc b/src/core/download.cc index 98772344..4167cbaa 100644 --- a/src/core/download.cc +++ b/src/core/download.cc @@ -101,7 +101,18 @@ Download::set_throttle_name(const std::string& name) { } void -Download::set_root_directory(const std::string& path) { +Download::set_directory(const std::string& path) { + if (!m_download.file_list()->is_multi_file()) + return set_base_directory(path); + + if (path.empty() || *path.rbegin() == '/') + return set_base_directory(path + m_download.info()->name_sanitized()); + + set_base_directory(path + "/" + m_download.info()->name_sanitized()); +} + +void +Download::set_base_directory(const std::string& path) { // If the download is open, hashed and has completed chunks make // sure to verify that the download files are still present. // diff --git a/src/core/download.h b/src/core/download.h index 61c34867..046034d8 100644 --- a/src/core/download.h +++ b/src/core/download.h @@ -79,7 +79,8 @@ public: uint32_t resume_flags() { return m_resumeFlags; } void set_resume_flags(uint32_t flags) { m_resumeFlags = flags; } - void set_root_directory(const std::string& path); + void set_directory(const std::string& path); + void set_base_directory(const std::string& path); void set_throttle_name(const std::string& name); diff --git a/src/main.cc b/src/main.cc index 87683667..e0630786 100644 --- a/src/main.cc +++ b/src/main.cc @@ -379,6 +379,12 @@ main(int argc, char** argv) { lt_log_print(torrent::LOG_WARN, "network.max_open_files.set is deprecated, use system.sockets.files.min_alloc.set instead."); }); + // TODO: Keep d.directory_base for a while as it is widely used. + CMD_REDIRECT("d.directory_base", "d.directory"); + CMD_REDIRECT("d.directory_base.set", "d.directory.base.set"); + + rpc::rpc.mark_safe("d.directory_base"); + // if (rpc::call_command_value("method.use_intermediate") == 1) { // } else if (rpc::call_command_value("method.use_intermediate") == 2) { diff --git a/test/Makefile.am b/test/Makefile.am index 550051f8..f8f546c6 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -51,8 +51,8 @@ rtorrent_Test_Rpc_SOURCES = $(rtorrent_Test_Common) \ rtorrent_Test_Src_SOURCES = $(rtorrent_Test_Common) \ src/test_command_dynamic.cc \ src/test_command_dynamic.h \ - src/test_command_local.cc \ - src/test_command_local.h \ + src/test_command_system.cc \ + src/test_command_system.h \ src/test_command_path.cc \ src/test_command_path.h \ src/test_command_string.cc \ diff --git a/test/src/test_command_local.cc b/test/src/test_command_system.cc similarity index 83% rename from test/src/test_command_local.cc rename to test/src/test_command_system.cc index bde49046..2ddf937f 100644 --- a/test/src/test_command_local.cc +++ b/test/src/test_command_system.cc @@ -1,6 +1,6 @@ #include "config.h" -#include "test/src/test_command_local.h" +#include "test/src/test_command_system.h" #include #include @@ -10,12 +10,12 @@ #include "globals.h" #include "rpc/parse_commands.h" -CPPUNIT_TEST_SUITE_REGISTRATION(TestCommandLocal); +CPPUNIT_TEST_SUITE_REGISTRATION(TestCommandSystem); -void initialize_command_local(); +void initialize_command_system(); void -TestCommandLocal::setUp() { +TestCommandSystem::setUp() { torrent::initialize_main_thread(); torrent::initialize(); @@ -23,16 +23,16 @@ TestCommandLocal::setUp() { control = new Control; if (!rpc::commands.has("system.sockets.size")) - initialize_command_local(); + initialize_command_system(); } void -TestCommandLocal::tearDown() { +TestCommandSystem::tearDown() { torrent::cleanup(); } void -TestCommandLocal::test_socket_category_commands() { +TestCommandSystem::test_socket_category_commands() { for (uint32_t i = 0; i < torrent::runtime::SocketManager::category_count; ++i) { auto category = static_cast(i); auto name = "system.sockets." + torrent::option_to_str_or_throw(torrent::OPTION_SOCKET_CATEGORY, i); diff --git a/test/src/test_command_local.h b/test/src/test_command_system.h similarity index 69% rename from test/src/test_command_local.h rename to test/src/test_command_system.h index 652febfc..7dfd7d2b 100644 --- a/test/src/test_command_local.h +++ b/test/src/test_command_system.h @@ -1,7 +1,7 @@ #include "test/helpers/test_fixture.h" -class TestCommandLocal : public test_fixture { - CPPUNIT_TEST_SUITE(TestCommandLocal); +class TestCommandSystem : public test_fixture { + CPPUNIT_TEST_SUITE(TestCommandSystem); CPPUNIT_TEST(test_socket_category_commands);