Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package rtorrent for openSUSE:Factory checked in at 2026-07-17 18:50:26 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/rtorrent (Old) and /work/SRC/openSUSE:Factory/.rtorrent.new.24530 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "rtorrent" Fri Jul 17 18:50:26 2026 rev:36 rq:1366410 version:0.16.18 Changes: -------- --- /work/SRC/openSUSE:Factory/rtorrent/rtorrent.changes 2026-07-06 12:35:55.814911837 +0200 +++ /work/SRC/openSUSE:Factory/.rtorrent.new.24530/rtorrent.changes 2026-07-17 18:51:52.490113595 +0200 @@ -1,0 +2,8 @@ +Fri Jul 17 13:04:34 UTC 2026 - Jan Engelhardt <[email protected]> + +- Update to release 0.16.18 + * Encryption settings have changed to be easier to use, and + changing listen or DHT ports can be done while rtorrent is + running. + +------------------------------------------------------------------- Old: ---- rtorrent-0.16.16.tar.gz New: ---- rtorrent-0.16.18.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ rtorrent.spec ++++++ --- /var/tmp/diff_new_pack.yjPZaI/_old 2026-07-17 18:51:53.262139692 +0200 +++ /var/tmp/diff_new_pack.yjPZaI/_new 2026-07-17 18:51:53.262139692 +0200 @@ -17,7 +17,7 @@ Name: rtorrent -Version: 0.16.16 +Version: 0.16.18 Release: 0 Summary: Console-based BitTorrent client License: SUSE-GPL-2.0+-with-openssl-exception ++++++ _scmsync.obsinfo ++++++ --- /var/tmp/diff_new_pack.yjPZaI/_old 2026-07-17 18:51:53.318141585 +0200 +++ /var/tmp/diff_new_pack.yjPZaI/_new 2026-07-17 18:51:53.322141721 +0200 @@ -1,5 +1,5 @@ -mtime: 1783276162 -commit: 95828eb58f3bcd696c17dc87550c5b6e2b67c6473d31aed1e5fda34746dff7b6 +mtime: 1784293489 +commit: bfced0b0c1b2d4600d77b3c01d9d7e1953cc0521e6f7abd48c14bf5c15016374 url: https://src.opensuse.org/jengelh/rtorrent revision: master ++++++ build.specials.obscpio ++++++ ++++++ build.specials.obscpio ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/.gitignore new/.gitignore --- old/.gitignore 1970-01-01 01:00:00.000000000 +0100 +++ new/.gitignore 2026-07-17 15:04:49.000000000 +0200 @@ -0,0 +1 @@ +.osc ++++++ rtorrent-0.16.16.tar.gz -> rtorrent-0.16.18.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rtorrent-0.16.16/configure new/rtorrent-0.16.18/configure --- old/rtorrent-0.16.16/configure 2026-07-03 17:14:22.000000000 +0200 +++ new/rtorrent-0.16.18/configure 2026-07-17 11:06:23.000000000 +0200 @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.72 for rtorrent 0.16.16. +# Generated by GNU Autoconf 2.72 for rtorrent 0.16.18. # # Report bugs to <[email protected]>. # @@ -614,8 +614,8 @@ # Identity of this package. PACKAGE_NAME='rtorrent' PACKAGE_TARNAME='rtorrent' -PACKAGE_VERSION='0.16.16' -PACKAGE_STRING='rtorrent 0.16.16' +PACKAGE_VERSION='0.16.18' +PACKAGE_STRING='rtorrent 0.16.18' PACKAGE_BUGREPORT='[email protected]' PACKAGE_URL='' @@ -1421,7 +1421,7 @@ # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -'configure' configures rtorrent 0.16.16 to adapt to many kinds of systems. +'configure' configures rtorrent 0.16.18 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1492,7 +1492,7 @@ if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of rtorrent 0.16.16:";; + short | recursive ) echo "Configuration of rtorrent 0.16.18:";; esac cat <<\_ACEOF @@ -1644,7 +1644,7 @@ test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -rtorrent configure 0.16.16 +rtorrent configure 0.16.18 generated by GNU Autoconf 2.72 Copyright (C) 2023 Free Software Foundation, Inc. @@ -2273,7 +2273,7 @@ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by rtorrent $as_me 0.16.16, which was +It was created by rtorrent $as_me 0.16.18, which was generated by GNU Autoconf 2.72. Invocation command line was $ $0$ac_configure_args_raw @@ -3966,7 +3966,7 @@ # Define the identity of the package. PACKAGE='rtorrent' - VERSION='0.16.16' + VERSION='0.16.18' printf "%s\n" "#define PACKAGE \"$PACKAGE\"" >>confdefs.h @@ -21491,19 +21491,19 @@ fi pkg_failed=no -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libtorrent >= 0.16.16" >&5 -printf %s "checking for libtorrent >= 0.16.16... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libtorrent >= 0.16.18" >&5 +printf %s "checking for libtorrent >= 0.16.18... " >&6; } if test -n "$DEPENDENCIES_CFLAGS"; then pkg_cv_DEPENDENCIES_CFLAGS="$DEPENDENCIES_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ - { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libtorrent >= 0.16.16\""; } >&5 - ($PKG_CONFIG --exists --print-errors "libtorrent >= 0.16.16") 2>&5 + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libtorrent >= 0.16.18\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libtorrent >= 0.16.18") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then - pkg_cv_DEPENDENCIES_CFLAGS=`$PKG_CONFIG --cflags "libtorrent >= 0.16.16" 2>/dev/null` + pkg_cv_DEPENDENCIES_CFLAGS=`$PKG_CONFIG --cflags "libtorrent >= 0.16.18" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes @@ -21515,12 +21515,12 @@ pkg_cv_DEPENDENCIES_LIBS="$DEPENDENCIES_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ - { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libtorrent >= 0.16.16\""; } >&5 - ($PKG_CONFIG --exists --print-errors "libtorrent >= 0.16.16") 2>&5 + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libtorrent >= 0.16.18\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libtorrent >= 0.16.18") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then - pkg_cv_DEPENDENCIES_LIBS=`$PKG_CONFIG --libs "libtorrent >= 0.16.16" 2>/dev/null` + pkg_cv_DEPENDENCIES_LIBS=`$PKG_CONFIG --libs "libtorrent >= 0.16.18" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes @@ -21541,14 +21541,14 @@ _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then - DEPENDENCIES_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libtorrent >= 0.16.16" 2>&1` + DEPENDENCIES_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libtorrent >= 0.16.18" 2>&1` else - DEPENDENCIES_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libtorrent >= 0.16.16" 2>&1` + DEPENDENCIES_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libtorrent >= 0.16.18" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$DEPENDENCIES_PKG_ERRORS" >&5 - as_fn_error $? "Package requirements (libtorrent >= 0.16.16) were not met: + as_fn_error $? "Package requirements (libtorrent >= 0.16.18) were not met: $DEPENDENCIES_PKG_ERRORS @@ -22893,6 +22893,20 @@ printf "%s\n" "#define LT_SMP_CACHE_BYTES 128" >>confdefs.h ;; + riscv32*|riscv64*) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: linux fallback RISC-V 64 bytes" >&5 +printf "%s\n" "linux fallback RISC-V 64 bytes" >&6; } + +printf "%s\n" "#define LT_SMP_CACHE_BYTES 64" >>confdefs.h + + ;; + loongarch32*|loongarch64*) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: linux fallback LoongArch 64 bytes" >&5 +printf "%s\n" "linux fallback LoongArch 64 bytes" >&6; } + +printf "%s\n" "#define LT_SMP_CACHE_BYTES 64" >>confdefs.h + + ;; *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unrecognized CPU arch on Linux header fallback" >&5 printf "%s\n" "unrecognized CPU arch on Linux header fallback" >&6; } @@ -23534,7 +23548,7 @@ # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by rtorrent $as_me 0.16.16, which was +This file was extended by rtorrent $as_me 0.16.18, which was generated by GNU Autoconf 2.72. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -23602,7 +23616,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config='$ac_cs_config_escaped' ac_cs_version="\\ -rtorrent config.status 0.16.16 +rtorrent config.status 0.16.18 configured by $0, generated by GNU Autoconf 2.72, with options \\"\$ac_cs_config\\" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rtorrent-0.16.16/configure.ac new/rtorrent-0.16.18/configure.ac --- old/rtorrent-0.16.16/configure.ac 2026-07-03 16:40:11.000000000 +0200 +++ new/rtorrent-0.16.18/configure.ac 2026-07-17 10:50:20.000000000 +0200 @@ -1,6 +1,6 @@ m4_pattern_allow([PKG_CHECK_EXISTS]) -AC_INIT([rtorrent],[0.16.16],[[email protected]]) +AC_INIT([rtorrent],[0.16.18],[[email protected]]) AC_CONFIG_HEADERS([config.h]) AC_CONFIG_MACRO_DIRS([scripts]) @@ -47,7 +47,7 @@ PKG_CHECK_MODULES([CPPUNIT], [cppunit],, [no_cppunit="yes"]) PKG_CHECK_MODULES([ZLIB], [zlib]) -PKG_CHECK_MODULES([DEPENDENCIES], [libtorrent >= 0.16.16]) +PKG_CHECK_MODULES([DEPENDENCIES], [libtorrent >= 0.16.18]) AC_LANG_PUSH(C++) TORRENT_WITH_XMLRPC_C diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rtorrent-0.16.16/scripts/common.m4 new/rtorrent-0.16.18/scripts/common.m4 --- old/rtorrent-0.16.16/scripts/common.m4 2026-07-03 16:40:11.000000000 +0200 +++ new/rtorrent-0.16.18/scripts/common.m4 2026-07-17 10:50:20.000000000 +0200 @@ -118,6 +118,14 @@ AC_MSG_RESULT([linux fallback enterprise 128 bytes]) AC_DEFINE([LT_SMP_CACHE_BYTES], 128, [Fallback 128-byte alignment for Linux enterprise hardware.]) ;; + riscv32*|riscv64*) + AC_MSG_RESULT([linux fallback RISC-V 64 bytes]) + AC_DEFINE([LT_SMP_CACHE_BYTES], 64, [Fallback 64-byte alignment for Linux RISC-V hardware.]) + ;; + loongarch32*|loongarch64*) + AC_MSG_RESULT([linux fallback LoongArch 64 bytes]) + AC_DEFINE([LT_SMP_CACHE_BYTES], 64, [Fallback 64-byte alignment for Linux LoongArch hardware.]) + ;; *) AC_MSG_RESULT([unrecognized CPU arch on Linux header fallback]) AC_MSG_FAILURE([Unrecognized CPU architecture ($host_cpu) on Linux fallback path. Aborting build.]) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rtorrent-0.16.16/src/command_dynamic.cc new/rtorrent-0.16.18/src/command_dynamic.cc --- old/rtorrent-0.16.16/src/command_dynamic.cc 2026-07-03 16:40:11.000000000 +0200 +++ new/rtorrent-0.16.18/src/command_dynamic.cc 2026-07-17 10:50:20.000000000 +0200 @@ -444,16 +444,18 @@ CMD2_ANY ("catch", std::bind(&cmd_catch, std::placeholders::_1, std::placeholders::_2)); - CMD2_ANY ("strings.choke_heuristics", std::bind(&torrent::option_list_strings, torrent::OPTION_CHOKE_HEURISTICS)); - CMD2_ANY ("strings.choke_heuristics.upload", std::bind(&torrent::option_list_strings, torrent::OPTION_CHOKE_HEURISTICS_UPLOAD)); - CMD2_ANY ("strings.choke_heuristics.download", std::bind(&torrent::option_list_strings, torrent::OPTION_CHOKE_HEURISTICS_DOWNLOAD)); - CMD2_ANY ("strings.connection_type", std::bind(&torrent::option_list_strings, torrent::OPTION_CONNECTION_TYPE)); - CMD2_ANY ("strings.encryption", std::bind(&torrent::option_list_strings, torrent::OPTION_ENCRYPTION)); - CMD2_ANY ("strings.ip_filter", std::bind(&torrent::option_list_strings, torrent::OPTION_IP_FILTER)); - CMD2_ANY ("strings.ip_tos", std::bind(&torrent::option_list_strings, torrent::OPTION_IP_TOS)); - CMD2_ANY ("strings.log_group", std::bind(&torrent::option_list_strings, torrent::OPTION_LOG_GROUP)); - CMD2_ANY ("strings.tracker_event", std::bind(&torrent::option_list_strings, torrent::OPTION_TRACKER_EVENT)); - CMD2_ANY ("strings.tracker_mode", std::bind(&torrent::option_list_strings, torrent::OPTION_TRACKER_MODE)); + CMD2_ANY ("strings.choke_heuristics", [](auto, auto) { return torrent::option_list_strings(torrent::OPTION_CHOKE_HEURISTICS); }); + CMD2_ANY ("strings.choke_heuristics.upload", [](auto, auto) { return torrent::option_list_strings(torrent::OPTION_CHOKE_HEURISTICS_UPLOAD); }); + CMD2_ANY ("strings.choke_heuristics.download", [](auto, auto) { return torrent::option_list_strings(torrent::OPTION_CHOKE_HEURISTICS_DOWNLOAD); }); + CMD2_ANY ("strings.connection_type", [](auto, auto) { return torrent::option_list_strings(torrent::OPTION_CONNECTION_TYPE); }); + CMD2_ANY ("strings.encryption", [](auto, auto) { return torrent::Object::create_list(); }); + CMD2_ANY ("strings.encryption.handshake", [](auto, auto) { return torrent::option_list_strings(torrent::OPTION_ENCRYPTION_HANDSHAKE); }); + CMD2_ANY ("strings.encryption.stream", [](auto, auto) { return torrent::option_list_strings(torrent::OPTION_ENCRYPTION_STREAM); }); + CMD2_ANY ("strings.ip_filter", [](auto, auto) { return torrent::option_list_strings(torrent::OPTION_IP_FILTER); }); + CMD2_ANY ("strings.ip_tos", [](auto, auto) { return torrent::option_list_strings(torrent::OPTION_IP_TOS); }); + CMD2_ANY ("strings.log_group", [](auto, auto) { return torrent::option_list_strings(torrent::OPTION_LOG_GROUP); }); + CMD2_ANY ("strings.tracker_event", [](auto, auto) { return torrent::option_list_strings(torrent::OPTION_TRACKER_EVENT); }); + CMD2_ANY ("strings.tracker_mode", [](auto, auto) { return torrent::option_list_strings(torrent::OPTION_TRACKER_MODE); }); // clang-format on #ifdef HAVE_XMLRPC_TINYXML2 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rtorrent-0.16.16/src/command_local.cc new/rtorrent-0.16.18/src/command_local.cc --- old/rtorrent-0.16.16/src/command_local.cc 2026-07-03 16:40:11.000000000 +0200 +++ new/rtorrent-0.16.18/src/command_local.cc 2026-07-17 10:50:20.000000000 +0200 @@ -8,10 +8,10 @@ #include <sys/types.h> #include <sys/stat.h> #include <torrent/torrent.h> -#include <torrent/chunk_manager.h> #include <torrent/data/file_manager.h> #include <torrent/data/chunk_utils.h> #include <torrent/runtime/runtime.h> +#include <torrent/runtime/memory_manager.h> #include <torrent/runtime/socket_manager.h> #include <torrent/utils/chrono.h> #include <torrent/utils/option_strings.h> @@ -188,13 +188,8 @@ void initialize_command_local() { core::DownloadList* dList = control->core()->download_list(); - torrent::ChunkManager* chunkManager = torrent::chunk_manager(); torrent::FileManager* fileManager = torrent::file_manager(); - if (rpc::call_command_value("method.use_deprecated") == 1) { - CMD_ANY_LIST ("file.append", std::bind(&cmd_file_append, std::placeholders::_2)); - } - CMD_ANY ("system.hostname", std::bind(&system_hostname)); CMD_ANY ("system.pid", std::bind(&getpid)); @@ -265,32 +260,34 @@ CMD_ANY_VALUE_V(category_name + ".max_alloc.set", [category](auto, auto& value) { torrent::runtime::socket_manager()->set_category_max_allocation(category, value); }); } - CMD_ANY ("pieces.sync.always_safe", std::bind(&CM_t::safe_sync, chunkManager)); - CMD_ANY_VALUE_V ("pieces.sync.always_safe.set", std::bind(&CM_t::set_safe_sync, chunkManager, std::placeholders::_2)); - CMD_ANY ("pieces.sync.safe_free_diskspace", std::bind(&CM_t::safe_free_diskspace, chunkManager)); - CMD_ANY ("pieces.sync.timeout", std::bind(&CM_t::timeout_sync, chunkManager)); - CMD_ANY_VALUE_V ("pieces.sync.timeout.set", std::bind(&CM_t::set_timeout_sync, chunkManager, std::placeholders::_2)); - CMD_ANY ("pieces.sync.timeout_safe", std::bind(&CM_t::timeout_safe_sync, chunkManager)); - CMD_ANY_VALUE_V ("pieces.sync.timeout_safe.set", std::bind(&CM_t::set_timeout_safe_sync, chunkManager, std::placeholders::_2)); - CMD_ANY ("pieces.sync.queue_size", std::bind(&CM_t::sync_queue_size, chunkManager)); - - CMD_ANY ("pieces.preload.type", std::bind(&CM_t::preload_type, chunkManager)); - CMD_ANY_VALUE_V ("pieces.preload.type.set", std::bind(&CM_t::set_preload_type, chunkManager, std::placeholders::_2)); - CMD_ANY ("pieces.preload.min_size", std::bind(&CM_t::preload_min_size, chunkManager)); - CMD_ANY_VALUE_V ("pieces.preload.min_size.set", std::bind(&CM_t::set_preload_min_size, chunkManager, std::placeholders::_2)); - CMD_ANY ("pieces.preload.min_rate", std::bind(&CM_t::preload_required_rate, chunkManager)); - CMD_ANY_VALUE_V ("pieces.preload.min_rate.set", std::bind(&CM_t::set_preload_required_rate, chunkManager, std::placeholders::_2)); - - CMD_ANY ("pieces.memory.current", std::bind(&CM_t::memory_usage, chunkManager)); - CMD_ANY ("pieces.memory.sync_queue", std::bind(&CM_t::sync_queue_memory_usage, chunkManager)); - CMD_ANY ("pieces.memory.block_count", std::bind(&CM_t::memory_block_count, chunkManager)); - CMD_ANY ("pieces.memory.max", std::bind(&CM_t::max_memory_usage, chunkManager)); - CMD_ANY_VALUE_V ("pieces.memory.max.set", std::bind(&CM_t::set_max_memory_usage, chunkManager, std::placeholders::_2)); - CMD_ANY ("pieces.stats_preloaded", std::bind(&CM_t::stats_preloaded, chunkManager)); - CMD_ANY ("pieces.stats_not_preloaded", std::bind(&CM_t::stats_not_preloaded, chunkManager)); + 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(); }); + CMD_ANY ("pieces.sync.timeout", [](auto, auto) { return torrent::runtime::memory_manager()->timeout_sync().count(); }); + CMD_ANY_VALUE_V ("pieces.sync.timeout.set", [](auto, auto& value) { return torrent::runtime::memory_manager()->set_timeout_sync(value); }); + // CMD_ANY ("pieces.sync.timeout_safe", [](auto, auto) { return torrent::runtime::memory_manager()->timeout_safe_sync(); }); + // CMD_ANY_VALUE_V ("pieces.sync.timeout_safe.set", [](auto, auto& value) { return torrent::runtime::memory_manager()->set_timeout_safe_sync(value); }); + CMD_ANY ("pieces.sync.timeout_safe", [](auto, auto) { return 0; }); + CMD_ANY_VALUE_V ("pieces.sync.timeout_safe.set", [](auto, auto) { }); + CMD_ANY ("pieces.sync.queue_size", [](auto, auto) { return torrent::runtime::memory_manager()->sync_queue_block_count(); }); + + CMD_ANY ("pieces.preload.type", [](auto, auto) { return torrent::runtime::memory_manager()->preload_type(); }); + CMD_ANY_VALUE_V ("pieces.preload.type.set", [](auto, auto& value) { return torrent::runtime::memory_manager()->set_preload_type(value); }); + CMD_ANY ("pieces.preload.min_size", [](auto, auto) { return torrent::runtime::memory_manager()->preload_min_size(); }); + CMD_ANY_VALUE_V ("pieces.preload.min_size.set", [](auto, auto& value) { return torrent::runtime::memory_manager()->set_preload_min_size(value); }); + CMD_ANY ("pieces.preload.min_rate", [](auto, auto) { return torrent::runtime::memory_manager()->preload_required_rate(); }); + CMD_ANY_VALUE_V ("pieces.preload.min_rate.set", [](auto, auto& value) { return torrent::runtime::memory_manager()->set_preload_required_rate(value); }); + CMD_ANY ("pieces.stats_preloaded", [](auto, auto) { return torrent::runtime::memory_manager()->stats_preloaded(); }); + CMD_ANY ("pieces.stats_not_preloaded", [](auto, auto) { return torrent::runtime::memory_manager()->stats_not_preloaded(); }); CMD_ANY ("pieces.stats.total_size", std::bind(&apply_pieces_stats_total_size)); + CMD_ANY ("pieces.memory.current", [](auto, auto) { return torrent::runtime::memory_manager()->memory_usage(); }); + CMD_ANY ("pieces.memory.sync_queue", [](auto, auto) { return torrent::runtime::memory_manager()->sync_queue_memory_usage(); }); + CMD_ANY ("pieces.memory.block_count", [](auto, auto) { return torrent::runtime::memory_manager()->memory_block_count(); }); + CMD_ANY ("pieces.memory.max", [](auto, auto) { return torrent::runtime::memory_manager()->max_memory_usage(); }); + CMD_ANY_VALUE_V ("pieces.memory.max.set", [](auto, auto& value) { return torrent::runtime::memory_manager()->set_max_memory_usage(value); }); + CMD_ANY ("pieces.hash.queue_size", std::bind(&torrent::main_thread::hash_queue_size)); CMD_VAR_BOOL ("pieces.hash.on_completion", true); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rtorrent-0.16.16/src/command_network.cc new/rtorrent-0.16.18/src/command_network.cc --- old/rtorrent-0.16.16/src/command_network.cc 2026-07-03 16:40:11.000000000 +0200 +++ new/rtorrent-0.16.18/src/command_network.cc 2026-07-17 10:50:20.000000000 +0200 @@ -9,7 +9,9 @@ #include <torrent/download/resource_manager.h> #include <torrent/net/http_stack.h> #include <torrent/net/socket_address.h> +#include <torrent/runtime/client_config.h> #include <torrent/runtime/network_config.h> +#include <torrent/runtime/network_manager.h> #include <torrent/runtime/proxy_manager.h> #include <torrent/runtime/runtime.h> #include <torrent/runtime/socket_manager.h> @@ -33,21 +35,115 @@ #endif torrent::Object +listen_port_range() { + auto port_range = torrent::runtime::client_config()->listen_port_range(); + + return std::to_string(port_range.first) + "-" + std::to_string(port_range.second); +} + +void +set_listen_port_range(const std::string& arg) { + unsigned int port_first{}, port_last{}; + + if (std::sscanf(arg.c_str(), "%i-%i", &port_first, &port_last) != 2) + throw torrent::input_error("Invalid port_range argument."); + + if (port_first >= (1 << 16) || port_last >= (1 << 16)) + throw torrent::input_error("Port range out-of-bounds."); + + torrent::runtime::client_config()->set_listen_port_range(port_first, port_last); +} + +torrent::Object +get_encryption() { + auto encryption_modes = torrent::runtime::network_config()->encryption_modes(); + + return torrent::option_to_str_or_throw(torrent::OPTION_ENCRYPTION_HANDSHAKE, encryption_modes.first) + "," + + torrent::option_to_str_or_throw(torrent::OPTION_ENCRYPTION_STREAM, encryption_modes.second); +} + +torrent::Object +get_handshake_encryption() { + auto encryption_modes = torrent::runtime::network_config()->encryption_modes(); + + return torrent::option_to_str_or_throw(torrent::OPTION_ENCRYPTION_MODE, encryption_modes.first); +} + +torrent::Object +get_stream_encryption() { + auto encryption_modes = torrent::runtime::network_config()->encryption_modes(); + + return torrent::option_to_str_or_throw(torrent::OPTION_ENCRYPTION_MODE, encryption_modes.second); +} + +torrent::Object +apply_obsolete_encryption(const torrent::Object::list_type& args) { + torrent::encryption_mode handshake_mode{torrent::ENCRYPTION_MODE_ALLOW}; + torrent::encryption_mode stream_mode{torrent::ENCRYPTION_MODE_ALLOW}; + + for (auto& itr : args) { + auto arg = itr.as_string(); + + if (arg == "none") { + handshake_mode = torrent::ENCRYPTION_MODE_DENY; + stream_mode = torrent::ENCRYPTION_MODE_DENY; + break; + + } else if (arg == "allow_incoming") { + } else if (arg == "try_outgoing") { + } else if (arg == "require") { + handshake_mode = torrent::ENCRYPTION_MODE_REQUIRE; + + } else if (arg == "require_RC4" || arg == "require_rc4") { + handshake_mode = torrent::ENCRYPTION_MODE_REQUIRE; + stream_mode = torrent::ENCRYPTION_MODE_REQUIRE; + break; + + } else if (arg == "enable_retry") { + } else if (arg == "prefer_plaintext") { + } else { + throw torrent::input_error("Invalid encryption option: '" + arg + "'"); + } + } + + lt_log_print(torrent::LOG_WARN, "Obsolete encryption options used, use 'handshake_{deny,allow,prefer,require}, stream_{deny,allow,prefer,require}' instead."); + + torrent::runtime::network_config()->set_encryption_modes(handshake_mode, stream_mode); + return {}; +} + +torrent::Object apply_encryption(const torrent::Object::list_type& args) { - uint32_t options_mask = torrent::runtime::NetworkConfig::encryption_none; + if (args.empty()) + throw torrent::input_error("No encryption options specified."); + + torrent::encryption_mode encryption_mode, handshake_mode, stream_mode; - for (const auto& arg : args) { - uint32_t opt = torrent::option_find_string(torrent::OPTION_ENCRYPTION, arg.as_string().c_str()); + if (args.size() == 1) { + try { + encryption_mode = static_cast<torrent::encryption_mode>(torrent::option_find_string_str(torrent::OPTION_ENCRYPTION_MODE, args.front().as_string())); - if (opt == torrent::runtime::NetworkConfig::encryption_none) - options_mask = torrent::runtime::NetworkConfig::encryption_none; - else - options_mask |= opt; + } catch (torrent::input_error& e) { + return apply_obsolete_encryption(args); + } + + torrent::runtime::network_config()->set_encryption_modes(encryption_mode, encryption_mode); + return {}; } - torrent::runtime::network_config()->set_encryption_options(options_mask); + if (args.size() != 2) + return apply_obsolete_encryption(args); - return torrent::Object(); + try { + handshake_mode = static_cast<torrent::encryption_mode>(torrent::option_find_string_str(torrent::OPTION_ENCRYPTION_HANDSHAKE, args.front().as_string())); + stream_mode = static_cast<torrent::encryption_mode>(torrent::option_find_string_str(torrent::OPTION_ENCRYPTION_STREAM, args.back().as_string())); + + } catch (torrent::input_error& e) { + return apply_obsolete_encryption(args); + } + + torrent::runtime::network_config()->set_encryption_modes(handshake_mode, stream_mode); + return {}; } torrent::Object @@ -220,17 +316,22 @@ auto http_stack = torrent::net_thread::http_stack(); auto nw_config = torrent::runtime::network_config(); - // Isn't port_open used? - CMD_VAR_BOOL ("network.port_open", true); - CMD_VAR_BOOL ("network.port_random", true); - CMD_VAR_STRING ("network.port_range", "6881-6999"); - - CMD_ANY ("network.listen.port", [](auto, auto) { return torrent::runtime::listen_port(); }); - CMD_ANY ("network.listen.backlog", [nw_config](auto, auto) { return nw_config->listen_backlog(); }); - CMD_ANY_VALUE_V ("network.listen.backlog.set", [nw_config](auto, auto& value) { return nw_config->set_listen_backlog(value); }); - - CMD_VAR_BOOL ("protocol.pex", true); - CMD_ANY_LIST ("protocol.encryption.set", [](auto, auto& args) { return apply_encryption(args); }); + CMD_ANY ("network.listen.port", [](auto, auto) { return torrent::runtime::network_manager()->listen_port(); }); + CMD_ANY_VALUE_V ("network.listen.port.set", [](auto, auto& value) { return torrent::runtime::network_manager()->set_listen_port(value); }); + CMD_ANY ("network.listen.port.random", [](auto, auto) { return torrent::runtime::client_config()->listen_port_random(); }); + CMD_ANY_VALUE_V ("network.listen.port.random.set", [](auto, auto& value) { return torrent::runtime::client_config()->set_listen_port_random(value); }); + CMD_ANY ("network.listen.port.range", [](auto, auto) { return listen_port_range(); }); + CMD_ANY_STRING_V("network.listen.port.range.set", [](auto, auto& value) { return set_listen_port_range(value); }); + CMD_ANY ("network.listen.backlog", [](auto, auto) { return torrent::runtime::network_config()->listen_backlog(); }); + CMD_ANY_VALUE_V ("network.listen.backlog.set", [](auto, auto& value) { return torrent::runtime::network_config()->set_listen_backlog(value); }); + + CMD_ANY ("protocol.pex", [](auto, auto) { return torrent::runtime::client_config()->is_pex_enabled(); }); + CMD_ANY_VALUE_V ("protocol.pex.set", [](auto, auto& value) { return torrent::runtime::client_config()->set_pex_enabled(value); }); + + CMD_ANY_LIST ("protocol.encryption", [](auto, auto) { return get_encryption(); }); + CMD_ANY_LIST ("protocol.encryption.set", [](auto, auto& args) { return apply_encryption(args); }); + CMD_ANY_LIST ("protocol.encryption.handshake", [](auto, auto) { return get_handshake_encryption(); }); + CMD_ANY_LIST ("protocol.encryption.stream", [](auto, auto) { return get_stream_encryption(); }); CMD_VAR_STRING ("protocol.connection.leech", "leech"); CMD_VAR_STRING ("protocol.connection.seed", "seed"); @@ -301,8 +402,10 @@ CMD_ANY ("network.xmlrpc.size_limit", [](auto, auto) { return rpc::rpc.size_limit(); }); CMD_ANY_VALUE_V ("network.xmlrpc.size_limit.set", [](auto, auto& arg) { return rpc::rpc.set_size_limit(arg); }); - CMD_VAR_BOOL ("network.rpc.use_xmlrpc", true); - CMD_VAR_BOOL ("network.rpc.use_jsonrpc", true); + CMD_ANY ("network.rpc.use_xmlrpc", [](auto, auto) { return rpc::rpc.use_xmlrpc(); }); + CMD_ANY_VALUE_V ("network.rpc.use_xmlrpc.set", [](auto, auto& arg) { return rpc::rpc.set_use_xmlrpc(arg); }); + CMD_ANY ("network.rpc.use_jsonrpc", [](auto, auto) { return rpc::rpc.use_jsonrpc(); }); + CMD_ANY_VALUE_V ("network.rpc.use_jsonrpc.set", [](auto, auto& arg) { return rpc::rpc.set_use_jsonrpc(arg); }); CMD_ANY ("network.block.ipv4", [nw_config](auto, auto) { return nw_config->is_block_ipv4(); }); CMD_ANY_VALUE_V ("network.block.ipv4.set", [nw_config](auto, auto& value) { return nw_config->set_block_ipv4(value); }); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rtorrent-0.16.16/src/command_tracker.cc new/rtorrent-0.16.18/src/command_tracker.cc --- old/rtorrent-0.16.16/src/command_tracker.cc 2026-07-03 16:40:11.000000000 +0200 +++ new/rtorrent-0.16.18/src/command_tracker.cc 2026-07-17 10:50:20.000000000 +0200 @@ -142,7 +142,7 @@ lt_log_print(torrent::LOG_DHT_ERROR, "dht.port.set is no longer supported, use dht.override_port.set", 0); }); CMD2_ANY ("dht.override_port", [](auto, auto) { return torrent::runtime::network_config()->override_dht_port(); }); - CMD2_ANY_VALUE_V ("dht.override_port.set", [](auto, auto& value) { return torrent::runtime::network_config()->set_override_dht_port(value); }); + CMD2_ANY_VALUE_V ("dht.override_port.set", [](auto, auto& value) { return torrent::runtime::network_manager()->set_dht_port(value); }); CMD2_ANY_STRING ("dht.add_node", [](auto, auto& str) { return apply_dht_add_node(str); }); CMD2_ANY ("dht.statistics", [](auto, auto) { return control->dht_manager()->dht_statistics(); }); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rtorrent-0.16.16/src/control.cc new/rtorrent-0.16.18/src/control.cc --- old/rtorrent-0.16.16/src/control.cc 2026-07-03 16:40:11.000000000 +0200 +++ new/rtorrent-0.16.18/src/control.cc 2026-07-17 10:50:20.000000000 +0200 @@ -70,9 +70,6 @@ display::Window::slot_unschedule([this](display::Window* w) { m_display->unschedule(w); }); display::Window::slot_adjust([this]() { m_display->adjust_layout(); }); - torrent::net_thread::http_stack()->set_user_agent(USER_AGENT); - - m_core->listen_open(); m_core->set_hashing_view(*m_view_manager->find_throw("hashing")); m_ui->init(this); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rtorrent-0.16.16/src/core/dht_manager.cc new/rtorrent-0.16.18/src/core/dht_manager.cc --- old/rtorrent-0.16.16/src/core/dht_manager.cc 2026-07-03 16:40:11.000000000 +0200 +++ new/rtorrent-0.16.18/src/core/dht_manager.cc 2026-07-17 10:50:20.000000000 +0200 @@ -8,6 +8,7 @@ #include <torrent/object_stream.h> #include <torrent/rate.h> #include <torrent/runtime/network_manager.h> +#include <torrent/runtime/runtime.h> #include <torrent/tracker/dht_controller.h> #include <torrent/utils/log.h> @@ -141,18 +142,29 @@ void DhtManager::set_mode_by_user(const std::string& arg) { - for (int i = 0; i < dht_settings_num; i++) { - if (arg == dht_settings[i]) { - m_set_by_user = true; - return set_mode_directly(i); - } + unsigned int mode = [arg]() { + for (int i = 0; i < dht_settings_num; i++) { + if (arg == dht_settings[i]) + return i; + } + + throw torrent::input_error("Invalid dht mode: " + arg); + }(); + + m_set_by_user = true; + + if (!torrent::runtime::is_network_initialized()) { + m_start = mode; + return; } + + set_mode_directly(mode); } void DhtManager::set_mode_directly(unsigned int mode) { if (mode >= dht_settings_num) - throw torrent::input_error("Invalid argument."); + throw torrent::input_error("Invalid dht mode."); m_start = mode; @@ -164,8 +176,10 @@ void DhtManager::set_auto_if_untouched_and_has_session() { - if (m_set_by_user) + if (m_set_by_user) { + set_mode_directly(m_start); return; + } if (rpc::call_command_string("session.path").empty()) { LT_LOG("DHT auto-start disabled, session path not set.", 0); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rtorrent-0.16.16/src/core/download_factory.cc new/rtorrent-0.16.18/src/core/download_factory.cc --- old/rtorrent-0.16.16/src/core/download_factory.cc 2026-07-03 16:40:11.000000000 +0200 +++ new/rtorrent-0.16.18/src/core/download_factory.cc 2026-07-17 10:50:20.000000000 +0200 @@ -15,6 +15,7 @@ #include <torrent/rate.h> #include <torrent/data/file_utils.h> #include <torrent/net/http_stack.h> +#include <torrent/runtime/client_config.h> #include <torrent/utils/string_manip.h> #include "control.h" @@ -104,40 +105,42 @@ throw torrent::internal_error("DownloadFactory::load*() called on an object with m_stream != NULL"); if (is_network_uri(m_uri)) { - // Http handling here. m_stream.reset(new std::stringstream); - HttpQueue::iterator itr = m_manager->http_queue()->insert(m_uri, m_stream); + auto done_fn = [this]() { receive_loaded(); }; + auto failed_fn = [this](const std::string& error) { receive_failed(error); }; - itr->add_done_slot(torrent::this_thread::thread(), [this]() { receive_loaded(); }); - itr->add_failed_slot(torrent::this_thread::thread(), [this](const std::string& error) { receive_failed(error); }); + m_manager->http_queue()->insert(m_uri, m_stream, done_fn, failed_fn); m_variables["tied_to_file"] = (int64_t)false; + return; + } - } else if (is_magnet_uri(m_uri)) { + if (is_magnet_uri(m_uri)) { // DEBUG: Use m_object. m_stream.reset(new std::stringstream()); *m_stream << "d10:magnet-uri" << m_uri.length() << ":" << m_uri << "e"; m_variables["tied_to_file"] = (int64_t)false; + receive_loaded(); + return; + } - } else { - std::fstream stream(expand_path(m_uri).c_str(), std::ios::in | std::ios::binary); + std::fstream stream(expand_path(m_uri).c_str(), std::ios::in | std::ios::binary); - if (!stream.is_open()) - return receive_failed("Could not open file"); + if (!stream.is_open()) + return receive_failed("Could not open file"); - m_object = new torrent::Object; - stream >> *m_object; + m_object = new torrent::Object; + stream >> *m_object; - if (!stream.good()) - return receive_failed("Reading torrent file failed"); + if (!stream.good()) + return receive_failed("Reading torrent file failed"); - m_isFile = true; + m_isFile = true; - receive_loaded(); - } + receive_loaded(); } void @@ -269,7 +272,7 @@ if (!m_session && m_variables["tied_to_file"].as_value()) rpc::call_command("d.tied_to_file.set", m_uri.empty() ? m_variables["tied_file"] : m_uri, rpc::make_target(download)); - rpc::call_command("d.peer_exchange.set", rpc::call_command_value("protocol.pex"), rpc::make_target(download)); + rpc::call_command("d.peer_exchange.set", torrent::runtime::client_config()->is_pex_enabled(), rpc::make_target(download)); torrent::resume_load_addresses(*download->download(), resumeObject); torrent::resume_load_file_priorities(*download->download(), resumeObject); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rtorrent-0.16.16/src/core/http_queue.cc new/rtorrent-0.16.18/src/core/http_queue.cc --- old/rtorrent-0.16.16/src/core/http_queue.cc 2026-07-03 16:40:11.000000000 +0200 +++ new/rtorrent-0.16.18/src/core/http_queue.cc 2026-07-17 10:50:20.000000000 +0200 @@ -9,7 +9,8 @@ namespace core { HttpQueue::iterator -HttpQueue::insert(const std::string& url, std::shared_ptr<std::ostream> stream) { +HttpQueue::insert(const std::string& url, std::shared_ptr<std::ostream> stream, + std::function<void()> done_fn, std::function<void(const std::string&)> failed_fn) { auto itr = base_type::insert(end(), torrent::net::HttpGet(url, stream)); itr->set_max_file_size(15 << 20); @@ -18,11 +19,11 @@ for (auto& slot : m_signal_insert) slot(*itr); - itr->add_done_slot(torrent::this_thread::thread(), [this, itr]() { erase(itr); }); - itr->add_failed_slot(torrent::this_thread::thread(), [this, itr](auto) { erase(itr); }); + itr->add_done_slot(torrent::this_thread::thread(), std::move(done_fn)); + itr->add_done_slot(torrent::this_thread::thread(), [this, itr]() { erase(itr); }); - // TODO: Downloading http torrents doesn't seem to work. - // TODO: Quitting no longer works. + itr->add_failed_slot(torrent::this_thread::thread(), std::move(failed_fn)); + itr->add_failed_slot(torrent::this_thread::thread(), [this, itr](auto) { erase(itr); }); torrent::net_thread::http_stack()->start_get(*itr); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rtorrent-0.16.16/src/core/http_queue.h new/rtorrent-0.16.18/src/core/http_queue.h --- old/rtorrent-0.16.16/src/core/http_queue.h 2026-07-03 16:40:11.000000000 +0200 +++ new/rtorrent-0.16.18/src/core/http_queue.h 2026-07-17 10:50:20.000000000 +0200 @@ -39,7 +39,8 @@ // // Consider adding a flag to indicate whetever HttpQueue should // delete the stream. - iterator insert(const std::string& url, std::shared_ptr<std::ostream> stream); + iterator insert(const std::string& url, std::shared_ptr<std::ostream> stream, + std::function<void()> done_fn, std::function<void(const std::string&)> failed_fn); void erase(iterator itr); void clear(); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rtorrent-0.16.16/src/core/manager.cc new/rtorrent-0.16.18/src/core/manager.cc --- old/rtorrent-0.16.16/src/core/manager.cc 2026-07-03 16:40:11.000000000 +0200 +++ new/rtorrent-0.16.18/src/core/manager.cc 2026-07-17 10:50:20.000000000 +0200 @@ -33,6 +33,8 @@ #include "core/http_queue.h" #include "core/view.h" +#include <torrent/runtime/client_config.h> + namespace core { const int Manager::create_start; @@ -161,40 +163,6 @@ } void -Manager::listen_open() { - // This stuff really should be moved outside of manager, make it - // part of the init script. - if (!rpc::call_command_value("network.port_open")) - return; - - int portFirst, portLast; - torrent::Object portRange = rpc::call_command("network.port_range"); - - if (!portRange.is_string()) - throw torrent::input_error("Invalid port_range argument type."); - - if (std::sscanf(portRange.as_string().c_str(), "%i-%i", &portFirst, &portLast) != 2) - throw torrent::input_error("Invalid port_range argument."); - - if (portFirst > portLast || portLast >= (1 << 16)) - throw torrent::input_error("Invalid port range."); - - if (rpc::call_command_value("network.port_random")) { - int boundary = portFirst + random() % (portLast - portFirst + 1); - - if (torrent::runtime::network_manager()->listen_open(boundary, portLast) || - torrent::runtime::network_manager()->listen_open(portFirst, boundary)) - return; - - } else { - if (torrent::runtime::network_manager()->listen_open(portFirst, portLast)) - return; - } - - throw torrent::input_error("Could not open/bind port for listening: " + std::string(std::strerror(errno))); -} - -void Manager::receive_http_failed(std::string msg) { push_log_std("Http download error: \"" + msg + "\""); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rtorrent-0.16.16/src/core/manager.h new/rtorrent-0.16.18/src/core/manager.h --- old/rtorrent-0.16.16/src/core/manager.h 2026-07-03 16:40:11.000000000 +0200 +++ new/rtorrent-0.16.18/src/core/manager.h 2026-07-17 10:50:20.000000000 +0200 @@ -55,8 +55,6 @@ void cleanup(); - void listen_open(); - const std::string& magnet_path(); void set_magnet_path(const std::string& path); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rtorrent-0.16.16/src/input/input_event.cc new/rtorrent-0.16.18/src/input/input_event.cc --- old/rtorrent-0.16.16/src/input/input_event.cc 2026-07-03 16:40:11.000000000 +0200 +++ new/rtorrent-0.16.18/src/input/input_event.cc 2026-07-17 10:50:20.000000000 +0200 @@ -13,7 +13,6 @@ InputEvent::insert() { torrent::this_thread::poll()->open(this); torrent::this_thread::poll()->insert_read(this); - torrent::this_thread::poll()->insert_error(this); } void diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rtorrent-0.16.16/src/input/input_event.h new/rtorrent-0.16.18/src/input/input_event.h --- old/rtorrent-0.16.16/src/input/input_event.h 2026-07-03 16:40:11.000000000 +0200 +++ new/rtorrent-0.16.18/src/input/input_event.h 2026-07-17 10:50:20.000000000 +0200 @@ -11,7 +11,7 @@ public: typedef std::function<void (int)> slot_int; - InputEvent(int fd) { m_fileDesc = fd; } + InputEvent(int fd) { set_file_descriptor(fd); } const char* type_name() const override { return "input"; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rtorrent-0.16.16/src/main.cc new/rtorrent-0.16.18/src/main.cc --- old/rtorrent-0.16.16/src/main.cc 2026-07-03 16:40:11.000000000 +0200 +++ new/rtorrent-0.16.18/src/main.cc 2026-07-17 10:50:20.000000000 +0200 @@ -11,6 +11,9 @@ #include <torrent/exceptions.h> #include <torrent/data/chunk_utils.h> #include <torrent/net/fd.h> +#include <torrent/net/http_stack.h> +#include <torrent/runtime/memory_manager.h> +#include <torrent/runtime/runtime.h> #include <torrent/utils/chrono.h> #include <torrent/utils/log.h> @@ -149,8 +152,8 @@ SignalHandler::set_sigaction_handler(SIGBUS, &handle_sigbus); - torrent::log_add_group_output(torrent::LOG_NOTICE, "important"); - torrent::log_add_group_output(torrent::LOG_DHT_ERROR, "important"); + torrent::log_add_group_output(torrent::LOG_NOTICE, "important"); + torrent::log_add_group_output(torrent::LOG_DHT_ERROR, "important"); torrent::log_add_group_output(torrent::LOG_INFO, "complete"); torrent::log_add_group_output(torrent::LOG_DHT_ERROR, "complete"); @@ -417,6 +420,20 @@ lt_log_print(torrent::LOG_WARN, "The 'throttle.ip' command is deprecated and does nothing."); return torrent::Object(); }); + + CMD_ANY("network.port_open", [](auto, auto) { + lt_log_print(torrent::LOG_WARN, "The 'network.port_open' command is deprecated and does nothing."); + return torrent::Object(); + }); + CMD_ANY("network.port_open.set", [](auto, auto) { + lt_log_print(torrent::LOG_WARN, "The 'network.port_open.set' command is deprecated and does nothing."); + return torrent::Object(); + }); + + CMD_REDIRECT("network.port_random", "network.listen.port.random"); + CMD_REDIRECT("network.port_random.set", "network.listen.port.random.set"); + CMD_REDIRECT("network.port_range", "network.listen.port.range"); + CMD_REDIRECT("network.port_range.set", "network.listen.port.range.set"); } { @@ -444,10 +461,14 @@ }); LT_LOG("seeded srandom and srand48 (seed:%u)", random_seed); + LT_LOG("max memory usage: %" PRIu64, torrent::runtime::memory_manager()->max_memory_usage()); control->initialize(); control->ui()->load_input_history(); + torrent::net_thread::http_stack()->set_user_agent(USER_AGENT); + torrent::runtime::initialize_network(); + // Load session torrents and perform scheduled tasks to ensure session torrents are loaded // before arg torrents. control->dht_manager()->set_auto_if_untouched_and_has_session(); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rtorrent-0.16.16/src/rpc/command.h new/rtorrent-0.16.18/src/rpc/command.h --- old/rtorrent-0.16.16/src/rpc/command.h 2026-07-03 16:40:11.000000000 +0200 +++ new/rtorrent-0.16.18/src/rpc/command.h 2026-07-17 10:50:20.000000000 +0200 @@ -55,12 +55,11 @@ base_type(src.first, src.second), third(src.third) {} }; -typedef rt_triple<int, void*, void*> target_type; - class command_base; -typedef const torrent::Object (*command_base_call_type)(command_base*, target_type, const torrent::Object&); -typedef std::function<torrent::Object (target_type, const torrent::Object&)> base_function; +using target_type = rt_triple<int, void*, void*>; +using base_function = std::function<torrent::Object (target_type, const torrent::Object&)>; +using command_base_call_type = const torrent::Object (command_base*, target_type, const torrent::Object&); template <typename tmpl> struct command_base_is_valid {}; template <command_base_call_type tmpl_func> struct command_base_is_type {}; @@ -84,17 +83,18 @@ typedef const torrent::Object (*download_pair_slot) (command_base*, core::Download*, core::Download*, const torrent::Object&); - static const int target_generic = 0; - static const int target_any = 1; - static const int target_download = 2; - static const int target_peer = 3; - static const int target_tracker = 4; - static const int target_file = 5; - static const int target_file_itr = 6; + static constexpr int target_generic = 0; + static constexpr int target_any = 1; + static constexpr int target_download = 2; + static constexpr int target_peer = 3; + static constexpr int target_tracker = 4; + static constexpr int target_file = 5; + static constexpr int target_file_itr = 6; + static constexpr int target_download_pair = 7; - static const int target_download_pair = 7; + static constexpr unsigned int max_arguments = 10; - static const unsigned int max_arguments = 10; + static constexpr std::size_t optimal_alignment = std::max(alignof(std::max_align_t), alignof(base_function)); struct stack_type { torrent::Object* begin() { return reinterpret_cast<torrent::Object*>(buffer); } @@ -169,8 +169,7 @@ template <typename T> void set_function(T s, [[maybe_unused]] int value = command_base_is_valid<T>::value) { static_assert(sizeof(T) <= sizeof(t_pod), "t_pod storage overflow"); - static_assert(alignof(std::max_align_t) % alignof(T) == 0, "t_pod alignment insufficient for type"); - static_assert(alignof(std::max_align_t) >= alignof(T), "t_pod structural capacity mismatch"); + static_assert(optimal_alignment >= alignof(T), "t_pod alignment insufficient for type"); if (m_dest_helper) m_dest_helper(t_pod); @@ -200,7 +199,7 @@ using copy_fn_t = void (*)(void* dest, const void* src); using dest_fn_t = void (*)(void* ptr); - alignas(std::max_align_t) char t_pod[sizeof(base_function)]; + alignas(optimal_alignment) char t_pod[sizeof(base_function)]; copy_fn_t m_copy_helper; dest_fn_t m_dest_helper; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rtorrent-0.16.16/src/rpc/exec_file.cc new/rtorrent-0.16.18/src/rpc/exec_file.cc --- old/rtorrent-0.16.16/src/rpc/exec_file.cc 2026-07-03 16:40:11.000000000 +0200 +++ new/rtorrent-0.16.18/src/rpc/exec_file.cc 2026-07-17 10:50:20.000000000 +0200 @@ -1,5 +1,6 @@ #include "config.h" +#include <cassert> #include <cerrno> #include <cstring> #include <fcntl.h> @@ -8,7 +9,9 @@ #include <unistd.h> #include <sys/types.h> #include <sys/wait.h> +#include <torrent/net/fd.h> #include <torrent/system/thread.h> +#include <torrent/system/types.h> #include "exec_file.h" #include "parse.h" @@ -22,6 +25,8 @@ int ExecFile::execute(const char* file, char* const* argv, int flags) { + assert(!((flags & flag_capture) && (flags & flag_background))); + // Write the executed command and its parameters to the log fd. [[maybe_unused]] int result; @@ -46,19 +51,11 @@ posix_spawnattr_t attr; posix_spawnattr_init(&attr); - short spawn_flags = 0; - // Try to avoid leaking open fds to the spawned process. Prefer POSIX_SPAWN_CLOEXEC_DEFAULT // (macOS-only) or posix_spawn_file_actions_addclosefrom_np (glibc >= 2.34, FreeBSD >= 13.1). // // Other platforms like musl libc, OpenBSD and NetBSD must rely on explicit O_CLOEXEC. -#if defined(POSIX_SPAWN_CLOEXEC_DEFAULT) - spawn_flags |= POSIX_SPAWN_CLOEXEC_DEFAULT; -#elif defined(HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCLOSEFROM_NP) - posix_spawn_file_actions_addclosefrom_np(&actions, 3); -#endif - // Handle standard input redirection (/dev/null), posix_spawn_file_actions_addopen handles opening // and dup2 natively if (posix_spawn_file_actions_addopen(&actions, 0, "/dev/null", O_RDWR, 0) != 0) { @@ -66,18 +63,18 @@ posix_spawn_file_actions_addclose(&actions, 0); } - int pipe_fd[2] = {-1, -1}; - - if ((flags & flag_capture) && pipe(pipe_fd)) - throw torrent::input_error("ExecFile::execute(...) Pipe creation failed."); + int pipe_0 = -1; + int pipe_1 = -1; // Handle standard output redirection if (flags & flag_capture) { - posix_spawn_file_actions_adddup2(&actions, pipe_fd[1], 1); + torrent::fd_open_pipe(pipe_0, pipe_1); + + posix_spawn_file_actions_adddup2(&actions, pipe_1, 1); // Ensure the write end of the pipe is closed in the child after duplicating. - posix_spawn_file_actions_addclose(&actions, pipe_fd[1]); - posix_spawn_file_actions_addclose(&actions, pipe_fd[0]); + posix_spawn_file_actions_addclose(&actions, pipe_0); + posix_spawn_file_actions_addclose(&actions, pipe_1); } else if (m_log_fd != -1) { posix_spawn_file_actions_adddup2(&actions, m_log_fd, 1); @@ -92,6 +89,14 @@ posix_spawn_file_actions_addopen(&actions, 2, "/dev/null", O_RDWR, 0); } + short spawn_flags = 0; + +#if defined(POSIX_SPAWN_CLOEXEC_DEFAULT) + spawn_flags |= POSIX_SPAWN_CLOEXEC_DEFAULT; +#elif defined(HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCLOSEFROM_NP) + posix_spawn_file_actions_addclosefrom_np(&actions, 3); +#endif + if (flags & flag_background) { #ifdef POSIX_SPAWN_SETSID spawn_flags |= POSIX_SPAWN_SETSID; @@ -110,31 +115,31 @@ posix_spawnattr_destroy(&attr); if (spawn_status != 0) { - if (pipe_fd[0] != -1) - ::close(pipe_fd[0]); + if (pipe_0 != -1) + torrent::fd_close(pipe_0); - if (pipe_fd[1] != -1) - ::close(pipe_fd[1]); + if (pipe_1 != -1) + torrent::fd_close(pipe_1); - throw torrent::input_error("ExecFile::execute(...) posix_spawn failed: " + std::string(std::strerror(spawn_status))); + throw torrent::input_error("ExecFile::execute() posix_spawn failed: " + torrent::system::errno_enum_str(spawn_status)); } if (flags & flag_capture) { m_capture = std::string(); - ::close(pipe_fd[1]); + torrent::fd_close(pipe_1); char buffer[4096]; ssize_t length; do { - length = read(pipe_fd[0], buffer, sizeof(buffer)); + length = read(pipe_0, buffer, sizeof(buffer)); if (length > 0) m_capture += std::string(buffer, length); } while (length > 0); - ::close(pipe_fd[0]); + torrent::fd_close(pipe_0); if (m_log_fd != -1) { result = write(m_log_fd, "Captured output:\n", sizeof("Captured output:\n")); @@ -151,7 +156,7 @@ int status; - while (waitpid(child_pid, &status, 0) == -1) { + while (::waitpid(child_pid, &status, 0) == -1) { switch (errno) { case EINTR: continue; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rtorrent-0.16.16/src/rpc/rpc_manager.cc new/rtorrent-0.16.18/src/rpc/rpc_manager.cc --- old/rtorrent-0.16.16/src/rpc/rpc_manager.cc 2026-07-03 16:40:11.000000000 +0200 +++ new/rtorrent-0.16.18/src/rpc/rpc_manager.cc 2026-07-17 10:50:20.000000000 +0200 @@ -113,25 +113,20 @@ RpcManager::process(RPCType type, const char* in_buffer, uint32_t length, slot_response_callback callback) { switch (type) { case RPCType::XML: - // TODO: 'network.rpc.use_xmlrpc' should be a bool in RpcManager, not a command variable. - if (m_xmlrpc.is_valid() && rpc::call_command_value("network.rpc.use_xmlrpc")) { - return m_xmlrpc.process(in_buffer, length, callback); - - } else { + if (!m_xmlrpc.is_valid() || !m_use_xmlrpc) { const std::string response = "<?xml version=\"1.0\"?><methodResponse><fault><value><struct><member><name>faultCode</name><value><i8>-501</i8></value></member><member><name>faultString</name><value><string>XML-RPC not supported</string></value></member></struct></value></fault></methodResponse>"; return callback(response.c_str(), response.size()); } - break; - case RPCType::JSON: - if (rpc::call_command_value("network.rpc.use_jsonrpc")) { - return m_jsonrpc.process(in_buffer, length, callback); + return m_xmlrpc.process(in_buffer, length, callback); - } else { + case RPCType::JSON: + if (!m_use_jsonrpc) { const std::string response = "{\"jsonrpc\":\"2.0\",\"error\":{\"code\":-32601,\"message\":\"JSON-RPC not supported\"},\"id\":null}"; return callback(response.c_str(), response.size()); } - break; + + return m_jsonrpc.process(in_buffer, length, callback); default: throw torrent::input_error("invalid parameters: unknown RPC type"); @@ -172,32 +167,6 @@ m_jsonrpc.cleanup(); } -bool -RpcManager::is_type_enabled(RPCType type) const { - switch (type) { - case RPCType::XML: - return m_is_xmlrpc_enabled; - case RPCType::JSON: - return m_is_jsonrpc_enabled; - default: - throw torrent::input_error("invalid parameters: unknown RPC type"); - } -} - -void -RpcManager::set_type_enabled(RPCType type, bool enabled) { - switch (type) { - case RPCType::XML: - m_is_xmlrpc_enabled = enabled; - break; - case RPCType::JSON: - m_is_jsonrpc_enabled = enabled; - break; - default: - throw torrent::input_error("invalid parameters: unknown RPC type"); - } -} - void RpcManager::insert_command(const char* name, const char* parm, const char* doc) { m_xmlrpc.insert_command(name, parm, doc); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rtorrent-0.16.16/src/rpc/rpc_manager.h new/rtorrent-0.16.18/src/rpc/rpc_manager.h --- old/rtorrent-0.16.16/src/rpc/rpc_manager.h 2026-07-03 16:40:11.000000000 +0200 +++ new/rtorrent-0.16.18/src/rpc/rpc_manager.h 2026-07-17 10:50:20.000000000 +0200 @@ -67,8 +67,11 @@ int dialect() { return m_xmlrpc.dialect(); } void set_dialect(int dialect) { m_xmlrpc.set_dialect(dialect); } - bool is_type_enabled(RPCType type) const; - void set_type_enabled(RPCType type, bool enabled); + bool use_xmlrpc() const; + void set_use_xmlrpc(bool v); + + bool use_jsonrpc() const; + void set_use_jsonrpc(bool v); bool process(RPCType type, const char* in_buffer, uint32_t length, slot_response_callback callback); bool process_untrusted(RPCType type, const char* in_buffer, uint32_t length, slot_response_callback callback); @@ -102,8 +105,9 @@ JsonRpc m_jsonrpc; bool m_handlers_initialized{}; - bool m_is_jsonrpc_enabled{true}; - bool m_is_xmlrpc_enabled{true}; + + bool m_use_jsonrpc{true}; + bool m_use_xmlrpc{true}; std::atomic<bool> m_scgi_allow_compression{true}; std::atomic<unsigned int> m_scgi_min_compress_size{1000}; @@ -116,6 +120,11 @@ extern RpcManager rpc; +inline bool RpcManager::use_xmlrpc() const { return m_use_xmlrpc; } +inline void RpcManager::set_use_xmlrpc(bool v) { m_use_xmlrpc = v; } +inline bool RpcManager::use_jsonrpc() const { return m_use_jsonrpc; } +inline void RpcManager::set_use_jsonrpc(bool v) { m_use_jsonrpc = v; } + } // namespace rpc #endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rtorrent-0.16.16/src/rpc/scgi.cc new/rtorrent-0.16.18/src/rpc/scgi.cc --- old/rtorrent-0.16.16/src/rpc/scgi.cc 2026-07-03 16:40:11.000000000 +0200 +++ new/rtorrent-0.16.18/src/rpc/scgi.cc 2026-07-17 10:50:20.000000000 +0200 @@ -111,7 +111,6 @@ torrent::this_thread::poll()->open(this); torrent::this_thread::poll()->insert_read(this); - torrent::this_thread::poll()->insert_error(this); } // TODO: This should close the fd to avoid reuse. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rtorrent-0.16.16/src/rpc/scgi_task.cc new/rtorrent-0.16.18/src/rpc/scgi_task.cc --- old/rtorrent-0.16.16/src/rpc/scgi_task.cc 2026-07-03 16:40:11.000000000 +0200 +++ new/rtorrent-0.16.18/src/rpc/scgi_task.cc 2026-07-17 10:50:20.000000000 +0200 @@ -27,7 +27,7 @@ SCgiTask::SCgiTask() : m_callback_id(torrent::system::make_callback_id()) { - set_file_descriptor(-1); + reset_file_descriptor(); } void @@ -49,7 +49,6 @@ torrent::this_thread::poll()->open(this); torrent::this_thread::poll()->insert_read(this); - torrent::this_thread::poll()->insert_error(this); auto lock = std::lock_guard<std::mutex>(m_result_mutex); @@ -65,7 +64,7 @@ torrent::this_thread::poll()->remove_and_close(this); torrent::fd_close(file_descriptor()); - set_file_descriptor(-1); + reset_file_descriptor(); }; void @@ -79,7 +78,7 @@ torrent::this_thread::poll()->remove_and_close(this); torrent::fd_close(file_descriptor()); - set_file_descriptor(-1); + reset_file_descriptor(); }); // The callbacks are guaranteed to be finished/canceled at this point. @@ -98,7 +97,7 @@ if (read_length <= 0) throw torrent::internal_error("SCgiTask::event_read() no space in buffer for event_read."); - int bytes = ::recv(m_fileDesc, m_buffer.data() + m_position, read_length, 0); + int bytes = ::recv(file_descriptor(), m_buffer.data() + m_position, read_length, 0); if (bytes <= 0) { if (bytes == 0 || !(errno == EAGAIN || errno == EINTR)) @@ -181,7 +180,7 @@ void SCgiTask::event_write() { - int bytes = ::send(m_fileDesc, m_buffer.data() + m_position, m_buffer.size() - m_position, 0); + int bytes = ::send(file_descriptor(), m_buffer.data() + m_position, m_buffer.size() - m_position, 0); if (bytes == -1) { if (!(errno == EAGAIN || errno == EINTR)) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rtorrent-0.16.16/src/rpc/scgi_task.h new/rtorrent-0.16.18/src/rpc/scgi_task.h --- old/rtorrent-0.16.16/src/rpc/scgi_task.h 2026-07-03 16:40:11.000000000 +0200 +++ new/rtorrent-0.16.18/src/rpc/scgi_task.h 2026-07-17 10:50:20.000000000 +0200 @@ -22,8 +22,8 @@ const char* type_name() const override { return "scgi-task"; } - bool is_open() const { return m_fileDesc != -1; } - bool is_available() const { return m_fileDesc == -1; } + bool is_open() const { return file_descriptor() != -1; } + bool is_available() const { return file_descriptor() == -1; } void open(SCgi* parent, int fd); void cancel_open(); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rtorrent-0.16.16/src/ui/download.cc new/rtorrent-0.16.18/src/ui/download.cc --- old/rtorrent-0.16.16/src/ui/download.cc 2026-07-03 16:40:11.000000000 +0200 +++ new/rtorrent-0.16.18/src/ui/download.cc 2026-07-17 10:50:20.000000000 +0200 @@ -3,7 +3,6 @@ #include <cassert> #include <torrent/exceptions.h> -#include <torrent/chunk_manager.h> #include <torrent/throttle.h> #include <torrent/torrent.h> #include <torrent/data/file_list.h> @@ -31,10 +30,10 @@ namespace ui { -Download::Download(core::Download* d) : - m_download(d) { +Download::Download(core::Download* d) + : m_download(d) { - m_windowDownloadStatus = new WDownloadStatus(d); + m_windowDownloadStatus = std::make_unique<WDownloadStatus>(d); m_windowDownloadStatus->set_bottom(true); m_uiArray[DISPLAY_MENU] = create_menu(); @@ -60,8 +59,6 @@ assert(!is_active() && "ui::Download::~Download() called on an active object."); std::for_each(m_uiArray, m_uiArray + DISPLAY_MAX_SIZE, [](ElementBase* eb) { delete eb; }); - - delete m_windowDownloadStatus; } inline ElementBase* @@ -171,7 +168,7 @@ m_frame = frame; m_frame->initialize_row(2); - m_frame->frame(1)->initialize_window(m_windowDownloadStatus); + m_frame->frame(1)->initialize_window(m_windowDownloadStatus.get()); m_windowDownloadStatus->set_active(true); activate_display_menu(DISPLAY_PEER_LIST); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rtorrent-0.16.16/src/ui/download.h new/rtorrent-0.16.18/src/ui/download.h --- old/rtorrent-0.16.16/src/ui/download.h 2026-07-03 16:40:11.000000000 +0200 +++ new/rtorrent-0.16.18/src/ui/download.h 2026-07-17 10:50:20.000000000 +0200 @@ -1,37 +1,3 @@ -// rTorrent - BitTorrent client -// Copyright (C) 2005-2011, Jari Sundell -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// In addition, as a special exception, the copyright holders give -// permission to link the code of portions of this program with the -// OpenSSL library under certain conditions as described in each -// individual source file, and distribute linked combinations -// including the two. -// -// You must obey the GNU General Public License in all respects for -// all of the code used other than OpenSSL. If you modify file(s) -// with this exception, you may extend this exception to your version -// of the file(s), but you are not obligated to do so. If you do not -// wish to do so, delete this exception statement from your version. -// If you delete this exception statement from all source files in the -// program, then also delete it here. -// -// Contact: Jari Sundell <[email protected]> - - #ifndef RTORRENT_UI_DOWNLOAD_H #define RTORRENT_UI_DOWNLOAD_H @@ -113,7 +79,7 @@ bool m_focusDisplay{}; - WDownloadStatus* m_windowDownloadStatus; + std::unique_ptr<WDownloadStatus> m_windowDownloadStatus; }; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rtorrent-0.16.16/src/ui/element_log_complete.h new/rtorrent-0.16.18/src/ui/element_log_complete.h --- old/rtorrent-0.16.16/src/ui/element_log_complete.h 2026-07-03 16:40:11.000000000 +0200 +++ new/rtorrent-0.16.18/src/ui/element_log_complete.h 2026-07-17 10:50:20.000000000 +0200 @@ -15,13 +15,13 @@ class ElementLogComplete : public ElementBase { public: - typedef display::WindowLogComplete WLogComplete; + using WLogComplete = display::WindowLogComplete; ElementLogComplete(torrent::log_buffer* l); ~ElementLogComplete() override; - void activate(display::Frame* frame, bool focus = true); - void disable(); + void activate(display::Frame* frame, bool focus = true) override; + void disable() override; display::Window* window(); @@ -32,7 +32,9 @@ torrent::log_buffer* m_log; - align_cacheline std::atomic<bool> m_log_updating{}; + align_cacheline + + std::atomic<bool> m_log_updating{}; }; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rtorrent-0.16.16/test/rpc/test_parse_options.cc new/rtorrent-0.16.18/test/rpc/test_parse_options.cc --- old/rtorrent-0.16.16/test/rpc/test_parse_options.cc 2026-07-03 16:40:11.000000000 +0200 +++ new/rtorrent-0.16.18/test/rpc/test_parse_options.cc 2026-07-17 10:50:20.000000000 +0200 @@ -169,20 +169,3 @@ FLAG_LT_LOG_ASSERT_ERROR("resume_data|rpc_dump"); } - -#define FLAGS_LT_ENCRYPTION_ASSERT(flags, result) \ - CPPUNIT_ASSERT(rpc::parse_option_flags(flags, std::bind(&torrent::option_find_string_str, torrent::OPTION_ENCRYPTION, std::placeholders::_1)) == (result)) - -#define FLAGS_LT_ENCRYPTION_ASSERT_ERROR(flags) \ - ASSERT_CATCH_INPUT_ERROR(rpc::parse_option_flags(flags, std::bind(&torrent::option_find_string_str, torrent::OPTION_ENCRYPTION, std::placeholders::_1))) - -void -TestParseOptions::test_flags_libtorrent() { - FLAGS_LT_ENCRYPTION_ASSERT("", torrent::runtime::NetworkConfig::encryption_none); - FLAGS_LT_ENCRYPTION_ASSERT("none", torrent::runtime::NetworkConfig::encryption_none); - FLAGS_LT_ENCRYPTION_ASSERT("require_rc4", torrent::runtime::NetworkConfig::encryption_require_RC4); - FLAGS_LT_ENCRYPTION_ASSERT("require_RC4", torrent::runtime::NetworkConfig::encryption_require_RC4); - FLAGS_LT_ENCRYPTION_ASSERT("require_RC4 | enable_retry", torrent::runtime::NetworkConfig::encryption_require_RC4 | torrent::runtime::NetworkConfig::encryption_enable_retry); - - FLAGS_LT_ENCRYPTION_ASSERT_ERROR("require_"); -} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rtorrent-0.16.16/test/rpc/test_parse_options.h new/rtorrent-0.16.18/test/rpc/test_parse_options.h --- old/rtorrent-0.16.16/test/rpc/test_parse_options.h 2026-07-03 16:40:11.000000000 +0200 +++ new/rtorrent-0.16.18/test/rpc/test_parse_options.h 2026-07-17 10:50:20.000000000 +0200 @@ -14,7 +14,6 @@ CPPUNIT_TEST(test_flags_print_flags); CPPUNIT_TEST(test_flag_libtorrent); - CPPUNIT_TEST(test_flags_libtorrent); CPPUNIT_TEST_SUITE_END(); @@ -30,5 +29,4 @@ void test_flags_print_flags(); void test_flag_libtorrent(); - void test_flags_libtorrent(); };
