mirror of
https://github.com/transmission/transmission.git
synced 2026-04-18 07:56:33 +01:00
chore: fix misc-use-anonymous-namespace warnings from clang-tidy (#6488)
This commit is contained in:
292
cli/cli.cc
292
cli/cli.cc
@@ -30,23 +30,25 @@ using namespace libtransmission::Values;
|
|||||||
|
|
||||||
#define SPEED_K_STR "kB/s"
|
#define SPEED_K_STR "kB/s"
|
||||||
|
|
||||||
static auto constexpr LineWidth = int{ 80 };
|
namespace
|
||||||
|
{
|
||||||
|
auto constexpr LineWidth = int{ 80 };
|
||||||
|
|
||||||
static char constexpr MyConfigName[] = "transmission";
|
char constexpr MyConfigName[] = "transmission";
|
||||||
static char constexpr MyReadableName[] = "transmission-cli";
|
char constexpr MyReadableName[] = "transmission-cli";
|
||||||
static char constexpr Usage
|
char constexpr Usage
|
||||||
[] = "A fast and easy BitTorrent client\n"
|
[] = "A fast and easy BitTorrent client\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Usage: transmission-cli [options] <file|url|magnet>";
|
"Usage: transmission-cli [options] <file|url|magnet>";
|
||||||
|
|
||||||
static bool showVersion = false;
|
bool showVersion = false;
|
||||||
static bool verify = false;
|
bool verify = false;
|
||||||
static sig_atomic_t gotsig = false;
|
sig_atomic_t gotsig = false;
|
||||||
static sig_atomic_t manualUpdate = false;
|
sig_atomic_t manualUpdate = false;
|
||||||
|
|
||||||
static char const* torrentPath = nullptr;
|
char const* torrentPath = nullptr;
|
||||||
|
|
||||||
static auto constexpr Options = std::array<tr_option, 20>{
|
auto constexpr Options = std::array<tr_option, 20>{
|
||||||
{ { 'b', "blocklist", "Enable peer blocklists", "b", false, nullptr },
|
{ { 'b', "blocklist", "Enable peer blocklists", "b", false, nullptr },
|
||||||
{ 'B', "no-blocklist", "Disable peer blocklists", "B", false, nullptr },
|
{ 'B', "no-blocklist", "Disable peer blocklists", "B", false, nullptr },
|
||||||
{ 'd', "downlimit", "Set max download speed in " SPEED_K_STR, "d", true, "<speed>" },
|
{ 'd', "downlimit", "Set max download speed in " SPEED_K_STR, "d", true, "<speed>" },
|
||||||
@@ -76,11 +78,11 @@ static auto constexpr Options = std::array<tr_option, 20>{
|
|||||||
{ 0, nullptr, nullptr, nullptr, false, nullptr } }
|
{ 0, nullptr, nullptr, nullptr, false, nullptr } }
|
||||||
};
|
};
|
||||||
|
|
||||||
static int parseCommandLine(tr_variant*, int argc, char const** argv);
|
int parseCommandLine(tr_variant*, int argc, char const** argv);
|
||||||
|
|
||||||
static void sigHandler(int signal);
|
void sigHandler(int signal);
|
||||||
|
|
||||||
static std::string tr_strlratio(double ratio)
|
[[nodiscard]] std::string tr_strlratio(double ratio)
|
||||||
{
|
{
|
||||||
if (static_cast<int>(ratio) == TR_RATIO_NA)
|
if (static_cast<int>(ratio) == TR_RATIO_NA)
|
||||||
{
|
{
|
||||||
@@ -105,16 +107,16 @@ static std::string tr_strlratio(double ratio)
|
|||||||
return fmt::format(FMT_STRING("{:.0f}"), ratio);
|
return fmt::format(FMT_STRING("{:.0f}"), ratio);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool waitingOnWeb;
|
bool waitingOnWeb;
|
||||||
|
|
||||||
static void onTorrentFileDownloaded(tr_web::FetchResponse const& response)
|
void onTorrentFileDownloaded(tr_web::FetchResponse const& response)
|
||||||
{
|
{
|
||||||
auto* ctor = static_cast<tr_ctor*>(response.user_data);
|
auto* ctor = static_cast<tr_ctor*>(response.user_data);
|
||||||
tr_ctorSetMetainfo(ctor, std::data(response.body), std::size(response.body), nullptr);
|
tr_ctorSetMetainfo(ctor, std::data(response.body), std::size(response.body), nullptr);
|
||||||
waitingOnWeb = false;
|
waitingOnWeb = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string getStatusStr(tr_stat const* st)
|
[[nodiscard]] std::string getStatusStr(tr_stat const* st)
|
||||||
{
|
{
|
||||||
if (st->activity == TR_STATUS_CHECK_WAIT)
|
if (st->activity == TR_STATUS_CHECK_WAIT)
|
||||||
{
|
{
|
||||||
@@ -155,7 +157,7 @@ static std::string getStatusStr(tr_stat const* st)
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string getConfigDir(int argc, char const** argv)
|
[[nodiscard]] std::string getConfigDir(int argc, char const** argv)
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
char const* my_optarg;
|
char const* my_optarg;
|
||||||
@@ -175,6 +177,133 @@ static std::string getConfigDir(int argc, char const** argv)
|
|||||||
return tr_getDefaultConfigDir(MyConfigName);
|
return tr_getDefaultConfigDir(MyConfigName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---
|
||||||
|
|
||||||
|
int parseCommandLine(tr_variant* d, int argc, char const** argv)
|
||||||
|
{
|
||||||
|
int c;
|
||||||
|
char const* my_optarg;
|
||||||
|
|
||||||
|
while ((c = tr_getopt(Usage, argc, argv, std::data(Options), &my_optarg)) != TR_OPT_DONE)
|
||||||
|
{
|
||||||
|
switch (c)
|
||||||
|
{
|
||||||
|
case 'b':
|
||||||
|
tr_variantDictAddBool(d, TR_KEY_blocklist_enabled, true);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'B':
|
||||||
|
tr_variantDictAddBool(d, TR_KEY_blocklist_enabled, false);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'd':
|
||||||
|
tr_variantDictAddInt(d, TR_KEY_speed_limit_down, atoi(my_optarg));
|
||||||
|
tr_variantDictAddBool(d, TR_KEY_speed_limit_down_enabled, true);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'D':
|
||||||
|
tr_variantDictAddBool(d, TR_KEY_speed_limit_down_enabled, false);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'f':
|
||||||
|
tr_variantDictAddStr(d, TR_KEY_script_torrent_done_filename, my_optarg);
|
||||||
|
tr_variantDictAddBool(d, TR_KEY_script_torrent_done_enabled, true);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'g': /* handled above */
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'm':
|
||||||
|
tr_variantDictAddBool(d, TR_KEY_port_forwarding_enabled, true);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'M':
|
||||||
|
tr_variantDictAddBool(d, TR_KEY_port_forwarding_enabled, false);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'p':
|
||||||
|
tr_variantDictAddInt(d, TR_KEY_peer_port, atoi(my_optarg));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 't':
|
||||||
|
tr_variantDictAddStr(d, TR_KEY_peer_socket_tos, my_optarg);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'u':
|
||||||
|
tr_variantDictAddInt(d, TR_KEY_speed_limit_up, atoi(my_optarg));
|
||||||
|
tr_variantDictAddBool(d, TR_KEY_speed_limit_up_enabled, true);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'U':
|
||||||
|
tr_variantDictAddBool(d, TR_KEY_speed_limit_up_enabled, false);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'v':
|
||||||
|
verify = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'V':
|
||||||
|
showVersion = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'w':
|
||||||
|
tr_variantDictAddStr(d, TR_KEY_download_dir, my_optarg);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 910:
|
||||||
|
tr_variantDictAddInt(d, TR_KEY_encryption, TR_ENCRYPTION_REQUIRED);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 911:
|
||||||
|
tr_variantDictAddInt(d, TR_KEY_encryption, TR_ENCRYPTION_PREFERRED);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 912:
|
||||||
|
tr_variantDictAddInt(d, TR_KEY_encryption, TR_CLEAR_PREFERRED);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 500:
|
||||||
|
tr_variantDictAddBool(d, TR_KEY_sequentialDownload, true);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TR_OPT_UNK:
|
||||||
|
if (torrentPath == nullptr)
|
||||||
|
{
|
||||||
|
torrentPath = my_optarg;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void sigHandler(int signal)
|
||||||
|
{
|
||||||
|
switch (signal)
|
||||||
|
{
|
||||||
|
case SIGINT:
|
||||||
|
gotsig = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
#ifndef _WIN32
|
||||||
|
|
||||||
|
case SIGHUP:
|
||||||
|
manualUpdate = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
int tr_main(int argc, char* argv[])
|
int tr_main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
auto const init_mgr = tr_lib_init();
|
auto const init_mgr = tr_lib_init();
|
||||||
@@ -335,132 +464,3 @@ int tr_main(int argc, char* argv[])
|
|||||||
tr_sessionClose(h);
|
tr_sessionClose(h);
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***
|
|
||||||
****
|
|
||||||
****
|
|
||||||
***/
|
|
||||||
|
|
||||||
static int parseCommandLine(tr_variant* d, int argc, char const** argv)
|
|
||||||
{
|
|
||||||
int c;
|
|
||||||
char const* my_optarg;
|
|
||||||
|
|
||||||
while ((c = tr_getopt(Usage, argc, argv, std::data(Options), &my_optarg)) != TR_OPT_DONE)
|
|
||||||
{
|
|
||||||
switch (c)
|
|
||||||
{
|
|
||||||
case 'b':
|
|
||||||
tr_variantDictAddBool(d, TR_KEY_blocklist_enabled, true);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'B':
|
|
||||||
tr_variantDictAddBool(d, TR_KEY_blocklist_enabled, false);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'd':
|
|
||||||
tr_variantDictAddInt(d, TR_KEY_speed_limit_down, atoi(my_optarg));
|
|
||||||
tr_variantDictAddBool(d, TR_KEY_speed_limit_down_enabled, true);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'D':
|
|
||||||
tr_variantDictAddBool(d, TR_KEY_speed_limit_down_enabled, false);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'f':
|
|
||||||
tr_variantDictAddStr(d, TR_KEY_script_torrent_done_filename, my_optarg);
|
|
||||||
tr_variantDictAddBool(d, TR_KEY_script_torrent_done_enabled, true);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'g': /* handled above */
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'm':
|
|
||||||
tr_variantDictAddBool(d, TR_KEY_port_forwarding_enabled, true);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'M':
|
|
||||||
tr_variantDictAddBool(d, TR_KEY_port_forwarding_enabled, false);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'p':
|
|
||||||
tr_variantDictAddInt(d, TR_KEY_peer_port, atoi(my_optarg));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 't':
|
|
||||||
tr_variantDictAddStr(d, TR_KEY_peer_socket_tos, my_optarg);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'u':
|
|
||||||
tr_variantDictAddInt(d, TR_KEY_speed_limit_up, atoi(my_optarg));
|
|
||||||
tr_variantDictAddBool(d, TR_KEY_speed_limit_up_enabled, true);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'U':
|
|
||||||
tr_variantDictAddBool(d, TR_KEY_speed_limit_up_enabled, false);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'v':
|
|
||||||
verify = true;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'V':
|
|
||||||
showVersion = true;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'w':
|
|
||||||
tr_variantDictAddStr(d, TR_KEY_download_dir, my_optarg);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 910:
|
|
||||||
tr_variantDictAddInt(d, TR_KEY_encryption, TR_ENCRYPTION_REQUIRED);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 911:
|
|
||||||
tr_variantDictAddInt(d, TR_KEY_encryption, TR_ENCRYPTION_PREFERRED);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 912:
|
|
||||||
tr_variantDictAddInt(d, TR_KEY_encryption, TR_CLEAR_PREFERRED);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 500:
|
|
||||||
tr_variantDictAddBool(d, TR_KEY_sequentialDownload, true);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case TR_OPT_UNK:
|
|
||||||
if (torrentPath == nullptr)
|
|
||||||
{
|
|
||||||
torrentPath = my_optarg;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void sigHandler(int signal)
|
|
||||||
{
|
|
||||||
switch (signal)
|
|
||||||
{
|
|
||||||
case SIGINT:
|
|
||||||
gotsig = true;
|
|
||||||
break;
|
|
||||||
|
|
||||||
#ifndef _WIN32
|
|
||||||
|
|
||||||
case SIGHUP:
|
|
||||||
manualUpdate = true;
|
|
||||||
break;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -23,24 +23,26 @@
|
|||||||
#define SERVICE_CONTROL_PRESHUTDOWN 0x0000000F
|
#define SERVICE_CONTROL_PRESHUTDOWN 0x0000000F
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static LPCWSTR const service_name = L"TransmissionDaemon";
|
namespace
|
||||||
|
{
|
||||||
|
LPCWSTR constexpr service_name = L"TransmissionDaemon";
|
||||||
|
|
||||||
// If we can get rid of this global variable...
|
// If we can get rid of this global variable...
|
||||||
static tr_daemon* daemon;
|
static tr_daemon* daemon;
|
||||||
|
|
||||||
// ...these becomes a good candidates for being converted to 'class tr_daemon' members.
|
// ...these becomes a good candidates for being converted to 'class tr_daemon' members.
|
||||||
static SERVICE_STATUS_HANDLE status_handle = nullptr;
|
SERVICE_STATUS_HANDLE status_handle = nullptr;
|
||||||
static DWORD current_state = SERVICE_STOPPED;
|
DWORD current_state = SERVICE_STOPPED;
|
||||||
static HANDLE service_thread = nullptr;
|
HANDLE service_thread = nullptr;
|
||||||
static HANDLE service_stop_thread = nullptr;
|
HANDLE service_stop_thread = nullptr;
|
||||||
|
|
||||||
static void set_system_error(tr_error& error, DWORD code, char const* message)
|
void set_system_error(tr_error& error, DWORD code, char const* message)
|
||||||
{
|
{
|
||||||
auto const system_message = tr_win32_format_message(code);
|
auto const system_message = tr_win32_format_message(code);
|
||||||
error.set(code, fmt::format(FMT_STRING("{:s} ({:#08x}): {:s})"), message, code, system_message));
|
error.set(code, fmt::format(FMT_STRING("{:s} ({:#08x}): {:s})"), message, code, system_message));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void do_log_system_error(char const* file, int line, tr_log_level level, DWORD code, char const* message)
|
void do_log_system_error(char const* file, int line, tr_log_level level, DWORD code, char const* message)
|
||||||
{
|
{
|
||||||
auto const system_message = tr_win32_format_message(code);
|
auto const system_message = tr_win32_format_message(code);
|
||||||
tr_logAddMessage(file, line, level, fmt::format("{} ({:#x}): {}", message, code, system_message), "tr_daemon");
|
tr_logAddMessage(file, line, level, fmt::format("{} ({:#x}): {}", message, code, system_message), "tr_daemon");
|
||||||
@@ -57,13 +59,13 @@ static void do_log_system_error(char const* file, int line, tr_log_level level,
|
|||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
static BOOL WINAPI handle_console_ctrl(DWORD /*control_type*/)
|
BOOL WINAPI handle_console_ctrl(DWORD /*control_type*/)
|
||||||
{
|
{
|
||||||
daemon->stop();
|
daemon->stop();
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void update_service_status(
|
void update_service_status(
|
||||||
DWORD new_state,
|
DWORD new_state,
|
||||||
DWORD win32_exit_code,
|
DWORD win32_exit_code,
|
||||||
DWORD service_specific_exit_code,
|
DWORD service_specific_exit_code,
|
||||||
@@ -91,7 +93,7 @@ static void update_service_status(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned int __stdcall service_stop_thread_main(void* param)
|
unsigned int __stdcall service_stop_thread_main(void* param)
|
||||||
{
|
{
|
||||||
daemon->stop();
|
daemon->stop();
|
||||||
|
|
||||||
@@ -107,7 +109,7 @@ static unsigned int __stdcall service_stop_thread_main(void* param)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void stop_service(void)
|
void stop_service(void)
|
||||||
{
|
{
|
||||||
if (service_stop_thread != nullptr)
|
if (service_stop_thread != nullptr)
|
||||||
{
|
{
|
||||||
@@ -128,7 +130,7 @@ static void stop_service(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static DWORD WINAPI handle_service_ctrl(DWORD control_code, DWORD /*event_type*/, LPVOID /*event_data*/, LPVOID /*context*/)
|
DWORD WINAPI handle_service_ctrl(DWORD control_code, DWORD /*event_type*/, LPVOID /*event_data*/, LPVOID /*context*/)
|
||||||
{
|
{
|
||||||
switch (control_code)
|
switch (control_code)
|
||||||
{
|
{
|
||||||
@@ -150,12 +152,12 @@ static DWORD WINAPI handle_service_ctrl(DWORD control_code, DWORD /*event_type*/
|
|||||||
return ERROR_CALL_NOT_IMPLEMENTED;
|
return ERROR_CALL_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned int __stdcall service_thread_main(void* /*context*/)
|
unsigned int __stdcall service_thread_main(void* /*context*/)
|
||||||
{
|
{
|
||||||
return daemon->start(false);
|
return daemon->start(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static VOID WINAPI service_main(DWORD /*argc*/, LPWSTR* /*argv*/)
|
VOID WINAPI service_main(DWORD /*argc*/, LPWSTR* /*argv*/)
|
||||||
{
|
{
|
||||||
status_handle = RegisterServiceCtrlHandlerExW(service_name, &handle_service_ctrl, nullptr);
|
status_handle = RegisterServiceCtrlHandlerExW(service_name, &handle_service_ctrl, nullptr);
|
||||||
|
|
||||||
@@ -199,6 +201,7 @@ static VOID WINAPI service_main(DWORD /*argc*/, LPWSTR* /*argv*/)
|
|||||||
|
|
||||||
update_service_status(SERVICE_STOPPED, NO_ERROR, exit_code, 0, 0);
|
update_service_status(SERVICE_STOPPED, NO_ERROR, exit_code, 0, 0);
|
||||||
}
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
bool tr_daemon::setup_signals([[maybe_unused]] struct event*& sig_ev)
|
bool tr_daemon::setup_signals([[maybe_unused]] struct event*& sig_ev)
|
||||||
{
|
{
|
||||||
|
|||||||
133
daemon/daemon.cc
133
daemon/daemon.cc
@@ -63,21 +63,21 @@ struct tr_torrent;
|
|||||||
using namespace std::literals;
|
using namespace std::literals;
|
||||||
using libtransmission::Watchdir;
|
using libtransmission::Watchdir;
|
||||||
|
|
||||||
static char constexpr MyName[] = "transmission-daemon";
|
namespace
|
||||||
static char constexpr Usage[] = "Transmission " LONG_VERSION_STRING
|
{
|
||||||
" https://transmissionbt.com/\n"
|
char constexpr MyName[] = "transmission-daemon";
|
||||||
"A fast and easy BitTorrent client\n"
|
char constexpr Usage[] = "Transmission " LONG_VERSION_STRING
|
||||||
"\n"
|
" https://transmissionbt.com/\n"
|
||||||
"transmission-daemon is a headless Transmission session that can be\n"
|
"A fast and easy BitTorrent client\n"
|
||||||
"controlled via transmission-qt, transmission-remote, or its web interface.\n"
|
"\n"
|
||||||
"\n"
|
"transmission-daemon is a headless Transmission session that can be\n"
|
||||||
"Usage: transmission-daemon [options]";
|
"controlled via transmission-qt, transmission-remote, or its web interface.\n"
|
||||||
|
"\n"
|
||||||
|
"Usage: transmission-daemon [options]";
|
||||||
|
|
||||||
/***
|
// --- Config File
|
||||||
**** Config File
|
|
||||||
***/
|
|
||||||
|
|
||||||
static auto constexpr Options = std::array<tr_option, 45>{
|
auto constexpr Options = std::array<tr_option, 45>{
|
||||||
{ { 'a', "allowed", "Allowed IP addresses. (Default: " TR_DEFAULT_RPC_WHITELIST ")", "a", true, "<list>" },
|
{ { 'a', "allowed", "Allowed IP addresses. (Default: " TR_DEFAULT_RPC_WHITELIST ")", "a", true, "<list>" },
|
||||||
{ 'b', "blocklist", "Enable peer blocklists", "b", false, nullptr },
|
{ 'b', "blocklist", "Enable peer blocklists", "b", false, nullptr },
|
||||||
{ 'B', "no-blocklist", "Disable peer blocklists", "B", false, nullptr },
|
{ 'B', "no-blocklist", "Disable peer blocklists", "B", false, nullptr },
|
||||||
@@ -145,39 +145,7 @@ static auto constexpr Options = std::array<tr_option, 45>{
|
|||||||
{ 0, nullptr, nullptr, nullptr, false, nullptr } }
|
{ 0, nullptr, nullptr, nullptr, false, nullptr } }
|
||||||
};
|
};
|
||||||
|
|
||||||
bool tr_daemon::reopen_log_file(char const* filename)
|
[[nodiscard]] std::string getConfigDir(int argc, char const* const* argv)
|
||||||
{
|
|
||||||
auto error = tr_error{};
|
|
||||||
tr_sys_file_t const old_log_file = logfile_;
|
|
||||||
tr_sys_file_t const new_log_file = tr_sys_file_open(
|
|
||||||
filename,
|
|
||||||
TR_SYS_FILE_WRITE | TR_SYS_FILE_CREATE | TR_SYS_FILE_APPEND,
|
|
||||||
0666,
|
|
||||||
&error);
|
|
||||||
|
|
||||||
if (new_log_file == TR_BAD_SYS_FILE)
|
|
||||||
{
|
|
||||||
auto const errmsg = fmt::format(
|
|
||||||
"Couldn't open '{path}': {error} ({error_code})",
|
|
||||||
fmt::arg("path", filename),
|
|
||||||
fmt::arg("error", error.message()),
|
|
||||||
fmt::arg("error_code", error.code()));
|
|
||||||
fmt::print(stderr, "{:s}\n", errmsg);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
logfile_ = new_log_file;
|
|
||||||
logfile_flush_ = tr_sys_file_flush_possible(logfile_);
|
|
||||||
|
|
||||||
if (old_log_file != TR_BAD_SYS_FILE)
|
|
||||||
{
|
|
||||||
tr_sys_file_close(old_log_file);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static std::string getConfigDir(int argc, char const* const* argv)
|
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
char const* optstr;
|
char const* optstr;
|
||||||
@@ -196,7 +164,7 @@ static std::string getConfigDir(int argc, char const* const* argv)
|
|||||||
return tr_getDefaultConfigDir(MyName);
|
return tr_getDefaultConfigDir(MyName);
|
||||||
}
|
}
|
||||||
|
|
||||||
static auto onFileAdded(tr_session* session, std::string_view dirname, std::string_view basename)
|
auto onFileAdded(tr_session* session, std::string_view dirname, std::string_view basename)
|
||||||
{
|
{
|
||||||
auto const lowercase = tr_strlower(basename);
|
auto const lowercase = tr_strlower(basename);
|
||||||
auto const is_torrent = tr_strv_ends_with(lowercase, ".torrent"sv);
|
auto const is_torrent = tr_strv_ends_with(lowercase, ".torrent"sv);
|
||||||
@@ -281,7 +249,7 @@ static auto onFileAdded(tr_session* session, std::string_view dirname, std::stri
|
|||||||
return Watchdir::Action::Done;
|
return Watchdir::Action::Done;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char const* levelName(tr_log_level level)
|
[[nodiscard]] constexpr char const* levelName(tr_log_level level)
|
||||||
{
|
{
|
||||||
switch (level)
|
switch (level)
|
||||||
{
|
{
|
||||||
@@ -300,7 +268,7 @@ static char const* levelName(tr_log_level level)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void printMessage(
|
void printMessage(
|
||||||
tr_sys_file_t file,
|
tr_sys_file_t file,
|
||||||
tr_log_level level,
|
tr_log_level level,
|
||||||
std::string_view name,
|
std::string_view name,
|
||||||
@@ -362,7 +330,7 @@ static void printMessage(
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pumpLogMessages(tr_sys_file_t file, bool flush)
|
void pumpLogMessages(tr_sys_file_t file, bool flush)
|
||||||
{
|
{
|
||||||
tr_log_message* list = tr_logGetQueue();
|
tr_log_message* list = tr_logGetQueue();
|
||||||
|
|
||||||
@@ -379,6 +347,53 @@ static void pumpLogMessages(tr_sys_file_t file, bool flush)
|
|||||||
tr_logFreeQueue(list);
|
tr_logFreeQueue(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void periodic_update(evutil_socket_t /*fd*/, short /*what*/, void* arg)
|
||||||
|
{
|
||||||
|
static_cast<tr_daemon*>(arg)->periodic_update();
|
||||||
|
}
|
||||||
|
|
||||||
|
tr_rpc_callback_status on_rpc_callback(tr_session* /*session*/, tr_rpc_callback_type type, tr_torrent* /*tor*/, void* arg)
|
||||||
|
{
|
||||||
|
if (type == TR_RPC_SESSION_CLOSE)
|
||||||
|
{
|
||||||
|
static_cast<tr_daemon*>(arg)->stop();
|
||||||
|
}
|
||||||
|
return TR_RPC_OK;
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
bool tr_daemon::reopen_log_file(char const* filename)
|
||||||
|
{
|
||||||
|
auto error = tr_error{};
|
||||||
|
tr_sys_file_t const old_log_file = logfile_;
|
||||||
|
tr_sys_file_t const new_log_file = tr_sys_file_open(
|
||||||
|
filename,
|
||||||
|
TR_SYS_FILE_WRITE | TR_SYS_FILE_CREATE | TR_SYS_FILE_APPEND,
|
||||||
|
0666,
|
||||||
|
&error);
|
||||||
|
|
||||||
|
if (new_log_file == TR_BAD_SYS_FILE)
|
||||||
|
{
|
||||||
|
auto const errmsg = fmt::format(
|
||||||
|
"Couldn't open '{path}': {error} ({error_code})",
|
||||||
|
fmt::arg("path", filename),
|
||||||
|
fmt::arg("error", error.message()),
|
||||||
|
fmt::arg("error_code", error.code()));
|
||||||
|
fmt::print(stderr, "{:s}\n", errmsg);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
logfile_ = new_log_file;
|
||||||
|
logfile_flush_ = tr_sys_file_flush_possible(logfile_);
|
||||||
|
|
||||||
|
if (old_log_file != TR_BAD_SYS_FILE)
|
||||||
|
{
|
||||||
|
tr_sys_file_close(old_log_file);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void tr_daemon::report_status(void)
|
void tr_daemon::report_status(void)
|
||||||
{
|
{
|
||||||
double const up = tr_sessionGetRawSpeed_KBps(my_session_, TR_UP);
|
double const up = tr_sessionGetRawSpeed_KBps(my_session_, TR_UP);
|
||||||
@@ -400,24 +415,6 @@ void tr_daemon::periodic_update(void)
|
|||||||
report_status();
|
report_status();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void periodic_update(evutil_socket_t /*fd*/, short /*what*/, void* arg)
|
|
||||||
{
|
|
||||||
static_cast<tr_daemon*>(arg)->periodic_update();
|
|
||||||
}
|
|
||||||
|
|
||||||
static tr_rpc_callback_status on_rpc_callback(
|
|
||||||
tr_session* /*session*/,
|
|
||||||
tr_rpc_callback_type type,
|
|
||||||
tr_torrent* /*tor*/,
|
|
||||||
void* arg)
|
|
||||||
{
|
|
||||||
if (type == TR_RPC_SESSION_CLOSE)
|
|
||||||
{
|
|
||||||
static_cast<tr_daemon*>(arg)->stop();
|
|
||||||
}
|
|
||||||
return TR_RPC_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool tr_daemon::parse_args(int argc, char const* const* argv, bool* dump_settings, bool* foreground, int* exit_code)
|
bool tr_daemon::parse_args(int argc, char const* const* argv, bool* dump_settings, bool* foreground, int* exit_code)
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
|
|||||||
33
gtk/Prefs.cc
33
gtk/Prefs.cc
@@ -25,13 +25,9 @@ void gtr_pref_init(std::string_view config_dir)
|
|||||||
gl_confdir = config_dir;
|
gl_confdir = config_dir;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***
|
namespace
|
||||||
****
|
{
|
||||||
**** Preferences
|
[[nodiscard]] std::string get_default_download_dir()
|
||||||
****
|
|
||||||
***/
|
|
||||||
|
|
||||||
[[nodiscard]] static std::string get_default_download_dir()
|
|
||||||
{
|
{
|
||||||
if (auto dir = Glib::get_user_special_dir(TR_GLIB_USER_DIRECTORY(DOWNLOAD)); !std::empty(dir))
|
if (auto dir = Glib::get_user_special_dir(TR_GLIB_USER_DIRECTORY(DOWNLOAD)); !std::empty(dir))
|
||||||
{
|
{
|
||||||
@@ -50,7 +46,7 @@ void gtr_pref_init(std::string_view config_dir)
|
|||||||
* This is where we initialize the preferences file with the default values.
|
* This is where we initialize the preferences file with the default values.
|
||||||
* If you add a new preferences key, you /must/ add a default value here.
|
* If you add a new preferences key, you /must/ add a default value here.
|
||||||
*/
|
*/
|
||||||
[[nodiscard]] static tr_variant get_default_app_settings()
|
[[nodiscard]] tr_variant get_default_app_settings()
|
||||||
{
|
{
|
||||||
auto const dir = get_default_download_dir();
|
auto const dir = get_default_download_dir();
|
||||||
|
|
||||||
@@ -88,7 +84,7 @@ void gtr_pref_init(std::string_view config_dir)
|
|||||||
return tr_variant{ std::move(map) };
|
return tr_variant{ std::move(map) };
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ensure_sound_cmd_is_a_list(tr_variant* dict)
|
void ensure_sound_cmd_is_a_list(tr_variant* dict)
|
||||||
{
|
{
|
||||||
tr_quark const key = TR_KEY_torrent_complete_sound_command;
|
tr_quark const key = TR_KEY_torrent_complete_sound_command;
|
||||||
tr_variant* list = nullptr;
|
tr_variant* list = nullptr;
|
||||||
@@ -106,7 +102,7 @@ static void ensure_sound_cmd_is_a_list(tr_variant* dict)
|
|||||||
tr_variantListAddStr(list, "transmission torrent downloaded"sv);
|
tr_variantListAddStr(list, "transmission torrent downloaded"sv);
|
||||||
}
|
}
|
||||||
|
|
||||||
static tr_variant& getPrefs()
|
tr_variant& getPrefs()
|
||||||
{
|
{
|
||||||
static auto settings = tr_variant{};
|
static auto settings = tr_variant{};
|
||||||
|
|
||||||
@@ -119,10 +115,7 @@ static tr_variant& getPrefs()
|
|||||||
|
|
||||||
return settings;
|
return settings;
|
||||||
}
|
}
|
||||||
|
} // namespace
|
||||||
/***
|
|
||||||
****
|
|
||||||
***/
|
|
||||||
|
|
||||||
tr_variant& gtr_pref_get_all()
|
tr_variant& gtr_pref_get_all()
|
||||||
{
|
{
|
||||||
@@ -153,9 +146,7 @@ void gtr_pref_double_set(tr_quark const key, double value)
|
|||||||
tr_variantDictAddReal(&getPrefs(), key, value);
|
tr_variantDictAddReal(&getPrefs(), key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/***
|
// ---
|
||||||
****
|
|
||||||
***/
|
|
||||||
|
|
||||||
bool gtr_pref_flag_get(tr_quark const key)
|
bool gtr_pref_flag_get(tr_quark const key)
|
||||||
{
|
{
|
||||||
@@ -169,9 +160,7 @@ void gtr_pref_flag_set(tr_quark const key, bool value)
|
|||||||
tr_variantDictAddBool(&getPrefs(), key, value);
|
tr_variantDictAddBool(&getPrefs(), key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/***
|
// ---
|
||||||
****
|
|
||||||
***/
|
|
||||||
|
|
||||||
std::vector<std::string> gtr_pref_strv_get(tr_quark const key)
|
std::vector<std::string> gtr_pref_strv_get(tr_quark const key)
|
||||||
{
|
{
|
||||||
@@ -207,9 +196,7 @@ void gtr_pref_string_set(tr_quark const key, std::string_view value)
|
|||||||
tr_variantDictAddStr(&getPrefs(), key, value);
|
tr_variantDictAddStr(&getPrefs(), key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/***
|
// ---
|
||||||
****
|
|
||||||
***/
|
|
||||||
|
|
||||||
void gtr_pref_save(tr_session* session)
|
void gtr_pref_save(tr_session* session)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -25,9 +25,9 @@
|
|||||||
#define TR_CRYPTO_X509_FALLBACK
|
#define TR_CRYPTO_X509_FALLBACK
|
||||||
#include "libtransmission/crypto-utils-fallback.cc" // NOLINT(bugprone-suspicious-include)
|
#include "libtransmission/crypto-utils-fallback.cc" // NOLINT(bugprone-suspicious-include)
|
||||||
|
|
||||||
// ---
|
namespace
|
||||||
|
{
|
||||||
static void log_mbedtls_error(int error_code, char const* file, int line)
|
void log_mbedtls_error(int error_code, char const* file, int line)
|
||||||
{
|
{
|
||||||
if (tr_logLevelIsActive(TR_LOG_ERROR))
|
if (tr_logLevelIsActive(TR_LOG_ERROR))
|
||||||
{
|
{
|
||||||
@@ -48,7 +48,7 @@ static void log_mbedtls_error(int error_code, char const* file, int line)
|
|||||||
|
|
||||||
#define log_error(error_code) log_mbedtls_error((error_code), __FILE__, __LINE__)
|
#define log_error(error_code) log_mbedtls_error((error_code), __FILE__, __LINE__)
|
||||||
|
|
||||||
static bool check_mbedtls_result(int result, int expected_result, char const* file, int line)
|
bool check_mbedtls_result(int result, int expected_result, char const* file, int line)
|
||||||
{
|
{
|
||||||
bool const ret = result == expected_result;
|
bool const ret = result == expected_result;
|
||||||
|
|
||||||
@@ -65,14 +65,14 @@ static bool check_mbedtls_result(int result, int expected_result, char const* fi
|
|||||||
|
|
||||||
// ---
|
// ---
|
||||||
|
|
||||||
static int my_rand(void* /*context*/, unsigned char* buffer, size_t buffer_size)
|
int my_rand(void* /*context*/, unsigned char* buffer, size_t buffer_size)
|
||||||
{
|
{
|
||||||
// since we're initializing tr_rand_buffer()'s rng, we can't use tr_rand_buffer() here
|
// since we're initializing tr_rand_buffer()'s rng, we can't use tr_rand_buffer() here
|
||||||
tr_rand_buffer_std(buffer, buffer_size);
|
tr_rand_buffer_std(buffer, buffer_size);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static mbedtls_ctr_drbg_context* get_rng()
|
mbedtls_ctr_drbg_context* get_rng()
|
||||||
{
|
{
|
||||||
static mbedtls_ctr_drbg_context rng;
|
static mbedtls_ctr_drbg_context rng;
|
||||||
static bool rng_initialized = false;
|
static bool rng_initialized = false;
|
||||||
@@ -97,13 +97,10 @@ static mbedtls_ctr_drbg_context* get_rng()
|
|||||||
return &rng;
|
return &rng;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::recursive_mutex rng_mutex_;
|
std::recursive_mutex rng_mutex_;
|
||||||
|
|
||||||
// ---
|
// ---
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
|
|
||||||
class Sha1Impl final : public tr_sha1
|
class Sha1Impl final : public tr_sha1
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -31,9 +31,9 @@ using TR_WC_RNG = RNG;
|
|||||||
#define TR_CRYPTO_X509_FALLBACK
|
#define TR_CRYPTO_X509_FALLBACK
|
||||||
#include "crypto-utils-fallback.cc" // NOLINT(bugprone-suspicious-include)
|
#include "crypto-utils-fallback.cc" // NOLINT(bugprone-suspicious-include)
|
||||||
|
|
||||||
// ---
|
namespace
|
||||||
|
{
|
||||||
static void log_wolfssl_error(int error_code, char const* file, int line)
|
void log_wolfssl_error(int error_code, char const* file, int line)
|
||||||
{
|
{
|
||||||
if (tr_logLevelIsActive(TR_LOG_ERROR))
|
if (tr_logLevelIsActive(TR_LOG_ERROR))
|
||||||
{
|
{
|
||||||
@@ -49,7 +49,7 @@ static void log_wolfssl_error(int error_code, char const* file, int line)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool check_wolfssl_result(int result, char const* file, int line)
|
bool check_wolfssl_result(int result, char const* file, int line)
|
||||||
{
|
{
|
||||||
bool const ret = result == 0;
|
bool const ret = result == 0;
|
||||||
|
|
||||||
@@ -65,7 +65,7 @@ static bool check_wolfssl_result(int result, char const* file, int line)
|
|||||||
|
|
||||||
// ---
|
// ---
|
||||||
|
|
||||||
static TR_WC_RNG* get_rng()
|
TR_WC_RNG* get_rng()
|
||||||
{
|
{
|
||||||
static TR_WC_RNG rng;
|
static TR_WC_RNG rng;
|
||||||
static bool rng_initialized = false;
|
static bool rng_initialized = false;
|
||||||
@@ -83,13 +83,10 @@ static TR_WC_RNG* get_rng()
|
|||||||
return &rng;
|
return &rng;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::mutex rng_mutex_;
|
std::mutex rng_mutex_;
|
||||||
|
|
||||||
// ---
|
// ---
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
|
|
||||||
class Sha1Impl final : public tr_sha1
|
class Sha1Impl final : public tr_sha1
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -43,10 +43,12 @@ struct tr_sys_dir_win32
|
|||||||
std::string utf8_name;
|
std::string utf8_name;
|
||||||
};
|
};
|
||||||
|
|
||||||
static auto constexpr NativeLocalPathPrefix = L"\\\\?\\"sv;
|
namespace
|
||||||
static auto constexpr NativeUncPathPrefix = L"\\\\?\\UNC\\"sv;
|
{
|
||||||
|
auto constexpr NativeLocalPathPrefix = L"\\\\?\\"sv;
|
||||||
|
auto constexpr NativeUncPathPrefix = L"\\\\?\\UNC\\"sv;
|
||||||
|
|
||||||
static void set_system_error(tr_error* error, DWORD code)
|
void set_system_error(tr_error* error, DWORD code)
|
||||||
{
|
{
|
||||||
if (error != nullptr)
|
if (error != nullptr)
|
||||||
{
|
{
|
||||||
@@ -55,7 +57,7 @@ static void set_system_error(tr_error* error, DWORD code)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void set_system_error_if_file_found(tr_error* error, DWORD code)
|
void set_system_error_if_file_found(tr_error* error, DWORD code)
|
||||||
{
|
{
|
||||||
if (code != ERROR_FILE_NOT_FOUND && code != ERROR_PATH_NOT_FOUND && code != ERROR_NO_MORE_FILES)
|
if (code != ERROR_FILE_NOT_FOUND && code != ERROR_PATH_NOT_FOUND && code != ERROR_NO_MORE_FILES)
|
||||||
{
|
{
|
||||||
@@ -63,7 +65,7 @@ static void set_system_error_if_file_found(tr_error* error, DWORD code)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static constexpr time_t filetime_to_unix_time(FILETIME const& t)
|
constexpr time_t filetime_to_unix_time(FILETIME const& t)
|
||||||
{
|
{
|
||||||
uint64_t tmp = 0;
|
uint64_t tmp = 0;
|
||||||
tmp |= t.dwHighDateTime;
|
tmp |= t.dwHighDateTime;
|
||||||
@@ -75,7 +77,7 @@ static constexpr time_t filetime_to_unix_time(FILETIME const& t)
|
|||||||
return tmp / 1000000UL;
|
return tmp / 1000000UL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static constexpr auto stat_to_sys_path_info(DWORD attributes, DWORD size_low, DWORD size_high, FILETIME const& mtime)
|
constexpr auto stat_to_sys_path_info(DWORD attributes, DWORD size_low, DWORD size_high, FILETIME const& mtime)
|
||||||
{
|
{
|
||||||
auto info = tr_sys_path_info{};
|
auto info = tr_sys_path_info{};
|
||||||
|
|
||||||
@@ -101,19 +103,19 @@ static constexpr auto stat_to_sys_path_info(DWORD attributes, DWORD size_low, DW
|
|||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
static auto constexpr Slashes = "\\/"sv;
|
auto constexpr Slashes = "\\/"sv;
|
||||||
|
|
||||||
static constexpr bool is_slash(char c)
|
constexpr bool is_slash(char c)
|
||||||
{
|
{
|
||||||
return tr_strv_contains(Slashes, c);
|
return tr_strv_contains(Slashes, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
static constexpr bool is_unc_path(std::string_view path)
|
constexpr bool is_unc_path(std::string_view path)
|
||||||
{
|
{
|
||||||
return std::size(path) >= 2 && is_slash(path[0]) && path[1] == path[0];
|
return std::size(path) >= 2 && is_slash(path[0]) && path[1] == path[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool is_valid_path(std::string_view path)
|
bool is_valid_path(std::string_view path)
|
||||||
{
|
{
|
||||||
if (is_unc_path(path))
|
if (is_unc_path(path))
|
||||||
{
|
{
|
||||||
@@ -140,11 +142,6 @@ static bool is_valid_path(std::string_view path)
|
|||||||
return path.find_first_of("<>:\"|?*"sv) == path.npos;
|
return path.find_first_of("<>:\"|?*"sv) == path.npos;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
namespace path_to_native_path_helpers
|
|
||||||
{
|
|
||||||
|
|
||||||
auto path_to_fixed_native_path(std::string_view path)
|
auto path_to_fixed_native_path(std::string_view path)
|
||||||
{
|
{
|
||||||
auto wide_path = tr_win32_utf8_to_native(path);
|
auto wide_path = tr_win32_utf8_to_native(path);
|
||||||
@@ -168,15 +165,10 @@ auto path_to_fixed_native_path(std::string_view path)
|
|||||||
return wide_path;
|
return wide_path;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace path_to_native_path_helpers
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
/* Extending maximum path length limit up to ~32K. See "Naming Files, Paths, and Namespaces"
|
/* Extending maximum path length limit up to ~32K. See "Naming Files, Paths, and Namespaces"
|
||||||
https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247.aspx for more info */
|
https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247.aspx for more info */
|
||||||
static auto path_to_native_path(std::string_view path)
|
auto path_to_native_path(std::string_view path)
|
||||||
{
|
{
|
||||||
using namespace path_to_native_path_helpers;
|
|
||||||
|
|
||||||
if (is_unc_path(path))
|
if (is_unc_path(path))
|
||||||
{
|
{
|
||||||
// UNC path: "\\server\share" -> "\\?\UNC\server\share"
|
// UNC path: "\\server\share" -> "\\?\UNC\server\share"
|
||||||
@@ -197,7 +189,7 @@ static auto path_to_native_path(std::string_view path)
|
|||||||
return path_to_fixed_native_path(path);
|
return path_to_fixed_native_path(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string native_path_to_path(std::wstring_view wide_path)
|
std::string native_path_to_path(std::wstring_view wide_path)
|
||||||
{
|
{
|
||||||
if (std::empty(wide_path))
|
if (std::empty(wide_path))
|
||||||
{
|
{
|
||||||
@@ -221,7 +213,7 @@ static std::string native_path_to_path(std::wstring_view wide_path)
|
|||||||
return tr_win32_native_to_utf8(wide_path);
|
return tr_win32_native_to_utf8(wide_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
static tr_sys_file_t open_file(std::string_view path, DWORD access, DWORD disposition, DWORD flags, tr_error* error)
|
tr_sys_file_t open_file(std::string_view path, DWORD access, DWORD disposition, DWORD flags, tr_error* error)
|
||||||
{
|
{
|
||||||
tr_sys_file_t ret = TR_BAD_SYS_FILE;
|
tr_sys_file_t ret = TR_BAD_SYS_FILE;
|
||||||
|
|
||||||
@@ -245,7 +237,7 @@ static tr_sys_file_t open_file(std::string_view path, DWORD access, DWORD dispos
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool create_dir(std::string_view path, int flags, int /*permissions*/, bool okay_if_exists, tr_error* error)
|
bool create_dir(std::string_view path, int flags, int /*permissions*/, bool okay_if_exists, tr_error* error)
|
||||||
{
|
{
|
||||||
bool ret;
|
bool ret;
|
||||||
DWORD error_code = ERROR_SUCCESS;
|
DWORD error_code = ERROR_SUCCESS;
|
||||||
@@ -290,7 +282,7 @@ static bool create_dir(std::string_view path, int flags, int /*permissions*/, bo
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void create_temp_path(
|
void create_temp_path(
|
||||||
char* path_template,
|
char* path_template,
|
||||||
void (*callback)(char const* path, void* param, tr_error* error),
|
void (*callback)(char const* path, void* param, tr_error* error),
|
||||||
void* callback_param,
|
void* callback_param,
|
||||||
@@ -339,6 +331,72 @@ static void create_temp_path(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::optional<tr_sys_path_info> tr_sys_file_get_info_(tr_sys_file_t handle, tr_error* error)
|
||||||
|
{
|
||||||
|
TR_ASSERT(handle != TR_BAD_SYS_FILE);
|
||||||
|
|
||||||
|
auto attributes = BY_HANDLE_FILE_INFORMATION{};
|
||||||
|
if (GetFileInformationByHandle(handle, &attributes))
|
||||||
|
{
|
||||||
|
return stat_to_sys_path_info(
|
||||||
|
attributes.dwFileAttributes,
|
||||||
|
attributes.nFileSizeLow,
|
||||||
|
attributes.nFileSizeHigh,
|
||||||
|
attributes.ftLastWriteTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
set_system_error(error, GetLastError());
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<BY_HANDLE_FILE_INFORMATION> get_file_info(char const* path, tr_error* error)
|
||||||
|
{
|
||||||
|
auto const wpath = path_to_native_path(path);
|
||||||
|
if (std::empty(wpath))
|
||||||
|
{
|
||||||
|
set_system_error_if_file_found(error, GetLastError());
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
auto const handle = CreateFileW(wpath.c_str(), 0, 0, nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, nullptr);
|
||||||
|
if (handle == INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
set_system_error_if_file_found(error, GetLastError());
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Use GetFileInformationByHandleEx on >= Server 2012
|
||||||
|
auto info = BY_HANDLE_FILE_INFORMATION{};
|
||||||
|
if (!GetFileInformationByHandle(handle, &info))
|
||||||
|
{
|
||||||
|
set_system_error_if_file_found(error, GetLastError());
|
||||||
|
CloseHandle(handle);
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
CloseHandle(handle);
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
void file_open_temp_callback(char const* path, void* param, tr_error* error)
|
||||||
|
{
|
||||||
|
auto* const result = static_cast<tr_sys_file_t*>(param);
|
||||||
|
|
||||||
|
TR_ASSERT(result != nullptr);
|
||||||
|
|
||||||
|
*result = open_file(path, GENERIC_READ | GENERIC_WRITE, CREATE_NEW, FILE_ATTRIBUTE_TEMPORARY, error);
|
||||||
|
}
|
||||||
|
|
||||||
|
void dir_create_temp_callback(char const* path, void* param, tr_error* error)
|
||||||
|
{
|
||||||
|
auto* const result = static_cast<bool*>(param);
|
||||||
|
|
||||||
|
TR_ASSERT(result != nullptr);
|
||||||
|
|
||||||
|
*result = create_dir(path, 0, 0, false, error);
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
bool tr_sys_path_exists(char const* path, tr_error* error)
|
bool tr_sys_path_exists(char const* path, tr_error* error)
|
||||||
{
|
{
|
||||||
TR_ASSERT(path != nullptr);
|
TR_ASSERT(path != nullptr);
|
||||||
@@ -377,24 +435,6 @@ bool tr_sys_path_exists(char const* path, tr_error* error)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::optional<tr_sys_path_info> tr_sys_file_get_info_(tr_sys_file_t handle, tr_error* error)
|
|
||||||
{
|
|
||||||
TR_ASSERT(handle != TR_BAD_SYS_FILE);
|
|
||||||
|
|
||||||
auto attributes = BY_HANDLE_FILE_INFORMATION{};
|
|
||||||
if (GetFileInformationByHandle(handle, &attributes))
|
|
||||||
{
|
|
||||||
return stat_to_sys_path_info(
|
|
||||||
attributes.dwFileAttributes,
|
|
||||||
attributes.nFileSizeLow,
|
|
||||||
attributes.nFileSizeHigh,
|
|
||||||
attributes.ftLastWriteTime);
|
|
||||||
}
|
|
||||||
|
|
||||||
set_system_error(error, GetLastError());
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
std::optional<tr_sys_path_info> tr_sys_path_get_info(std::string_view path, int flags, tr_error* error)
|
std::optional<tr_sys_path_info> tr_sys_path_get_info(std::string_view path, int flags, tr_error* error)
|
||||||
{
|
{
|
||||||
if (auto const wide_path = path_to_native_path(path); std::empty(wide_path))
|
if (auto const wide_path = path_to_native_path(path); std::empty(wide_path))
|
||||||
@@ -449,35 +489,6 @@ bool tr_sys_path_is_relative(std::string_view path)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::optional<BY_HANDLE_FILE_INFORMATION> get_file_info(char const* path, tr_error* error)
|
|
||||||
{
|
|
||||||
auto const wpath = path_to_native_path(path);
|
|
||||||
if (std::empty(wpath))
|
|
||||||
{
|
|
||||||
set_system_error_if_file_found(error, GetLastError());
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
auto const handle = CreateFileW(wpath.c_str(), 0, 0, nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, nullptr);
|
|
||||||
if (handle == INVALID_HANDLE_VALUE)
|
|
||||||
{
|
|
||||||
set_system_error_if_file_found(error, GetLastError());
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Use GetFileInformationByHandleEx on >= Server 2012
|
|
||||||
auto info = BY_HANDLE_FILE_INFORMATION{};
|
|
||||||
if (!GetFileInformationByHandle(handle, &info))
|
|
||||||
{
|
|
||||||
set_system_error_if_file_found(error, GetLastError());
|
|
||||||
CloseHandle(handle);
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
CloseHandle(handle);
|
|
||||||
return info;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool tr_sys_path_is_same(char const* path1, char const* path2, tr_error* error)
|
bool tr_sys_path_is_same(char const* path1, char const* path2, tr_error* error)
|
||||||
{
|
{
|
||||||
TR_ASSERT(path1 != nullptr);
|
TR_ASSERT(path1 != nullptr);
|
||||||
@@ -899,15 +910,6 @@ tr_sys_file_t tr_sys_file_open(char const* path, int flags, int /*permissions*/,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void file_open_temp_callback(char const* path, void* param, tr_error* error)
|
|
||||||
{
|
|
||||||
auto* const result = static_cast<tr_sys_file_t*>(param);
|
|
||||||
|
|
||||||
TR_ASSERT(result != nullptr);
|
|
||||||
|
|
||||||
*result = open_file(path, GENERIC_READ | GENERIC_WRITE, CREATE_NEW, FILE_ATTRIBUTE_TEMPORARY, error);
|
|
||||||
}
|
|
||||||
|
|
||||||
tr_sys_file_t tr_sys_file_open_temp(char* path_template, tr_error* error)
|
tr_sys_file_t tr_sys_file_open_temp(char* path_template, tr_error* error)
|
||||||
{
|
{
|
||||||
TR_ASSERT(path_template != nullptr);
|
TR_ASSERT(path_template != nullptr);
|
||||||
@@ -1207,15 +1209,6 @@ bool tr_sys_dir_create(char const* path, int flags, int permissions, tr_error* e
|
|||||||
return create_dir(path, flags, permissions, true, error);
|
return create_dir(path, flags, permissions, true, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dir_create_temp_callback(char const* path, void* param, tr_error* error)
|
|
||||||
{
|
|
||||||
auto* const result = static_cast<bool*>(param);
|
|
||||||
|
|
||||||
TR_ASSERT(result != nullptr);
|
|
||||||
|
|
||||||
*result = create_dir(path, 0, 0, false, error);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool tr_sys_dir_create_temp(char* path_template, tr_error* error)
|
bool tr_sys_dir_create_temp(char* path_template, tr_error* error)
|
||||||
{
|
{
|
||||||
TR_ASSERT(path_template != nullptr);
|
TR_ASSERT(path_template != nullptr);
|
||||||
|
|||||||
@@ -175,7 +175,9 @@ void tr_netSetCongestionControl([[maybe_unused]] tr_socket_t s, [[maybe_unused]]
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static tr_socket_t createSocket(int domain, int type)
|
namespace
|
||||||
|
{
|
||||||
|
tr_socket_t createSocket(int domain, int type)
|
||||||
{
|
{
|
||||||
auto const sockfd = socket(domain, type, 0);
|
auto const sockfd = socket(domain, type, 0);
|
||||||
if (sockfd == TR_BAD_SOCKET)
|
if (sockfd == TR_BAD_SOCKET)
|
||||||
@@ -220,6 +222,7 @@ static tr_socket_t createSocket(int domain, int type)
|
|||||||
|
|
||||||
return sockfd;
|
return sockfd;
|
||||||
}
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
tr_peer_socket tr_netOpenPeerSocket(tr_session* session, tr_socket_address const& socket_address, bool client_is_seed)
|
tr_peer_socket tr_netOpenPeerSocket(tr_session* session, tr_socket_address const& socket_address, bool client_is_seed)
|
||||||
{
|
{
|
||||||
@@ -299,7 +302,9 @@ tr_peer_socket tr_netOpenPeerSocket(tr_session* session, tr_socket_address const
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static tr_socket_t tr_netBindTCPImpl(tr_address const& addr, tr_port port, bool suppress_msgs, int* err_out)
|
namespace
|
||||||
|
{
|
||||||
|
tr_socket_t tr_netBindTCPImpl(tr_address const& addr, tr_port port, bool suppress_msgs, int* err_out)
|
||||||
{
|
{
|
||||||
TR_ASSERT(addr.is_valid());
|
TR_ASSERT(addr.is_valid());
|
||||||
|
|
||||||
@@ -387,6 +392,7 @@ static tr_socket_t tr_netBindTCPImpl(tr_address const& addr, tr_port port, bool
|
|||||||
|
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
tr_socket_t tr_netBindTCP(tr_address const& addr, tr_port port, bool suppress_msgs)
|
tr_socket_t tr_netBindTCP(tr_address const& addr, tr_port port, bool suppress_msgs)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -106,10 +106,9 @@ struct EasyDeleter
|
|||||||
using easy_unique_ptr = std::unique_ptr<CURL, EasyDeleter>;
|
using easy_unique_ptr = std::unique_ptr<CURL, EasyDeleter>;
|
||||||
|
|
||||||
} // namespace curl_helpers
|
} // namespace curl_helpers
|
||||||
} // namespace
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
static CURLcode ssl_context_func(CURL* /*curl*/, void* ssl_ctx, void* /*user_data*/)
|
CURLcode ssl_context_func(CURL* /*curl*/, void* ssl_ctx, void* /*user_data*/)
|
||||||
{
|
{
|
||||||
auto const cert_store = tr_ssl_get_x509_store(ssl_ctx);
|
auto const cert_store = tr_ssl_get_x509_store(ssl_ctx);
|
||||||
if (cert_store == nullptr)
|
if (cert_store == nullptr)
|
||||||
@@ -162,6 +161,7 @@ static CURLcode ssl_context_func(CURL* /*curl*/, void* ssl_ctx, void* /*user_dat
|
|||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
} // namespace
|
||||||
|
|
||||||
// ---
|
// ---
|
||||||
|
|
||||||
|
|||||||
@@ -53,9 +53,7 @@
|
|||||||
class Prefs;
|
class Prefs;
|
||||||
class Session;
|
class Session;
|
||||||
|
|
||||||
/****
|
// ---
|
||||||
*****
|
|
||||||
****/
|
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
@@ -92,10 +90,20 @@ private:
|
|||||||
QTimer timer_;
|
QTimer timer_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace
|
constexpr tr_quark priorityKey(int priority)
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
{
|
||||||
|
switch (priority)
|
||||||
|
{
|
||||||
|
case TR_PRI_LOW:
|
||||||
|
return TR_KEY_priority_low;
|
||||||
|
|
||||||
|
case TR_PRI_HIGH:
|
||||||
|
return TR_KEY_priority_high;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return TR_KEY_priority_normal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int constexpr DebounceIntervalMSec = 100;
|
int constexpr DebounceIntervalMSec = 100;
|
||||||
int constexpr RefreshIntervalMSec = 4000;
|
int constexpr RefreshIntervalMSec = 4000;
|
||||||
@@ -124,44 +132,9 @@ int measureViewItem(QTreeWidget const* view, int column, QString const& text)
|
|||||||
return std::max(item_width, header_width);
|
return std::max(item_width, header_width);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString collateAddress(QString const& address)
|
|
||||||
{
|
|
||||||
auto collated = QString{};
|
|
||||||
|
|
||||||
if (auto ip_address = QHostAddress{}; ip_address.setAddress(address))
|
|
||||||
{
|
|
||||||
if (ip_address.protocol() == QAbstractSocket::IPv4Protocol)
|
|
||||||
{
|
|
||||||
quint32 const ipv4_address = ip_address.toIPv4Address();
|
|
||||||
collated = QStringLiteral("1-") + QString::fromUtf8(QByteArray::number(ipv4_address, 16).rightJustified(8, '0'));
|
|
||||||
}
|
|
||||||
else if (ip_address.protocol() == QAbstractSocket::IPv6Protocol)
|
|
||||||
{
|
|
||||||
Q_IPV6ADDR const ipv6_address = ip_address.toIPv6Address();
|
|
||||||
QByteArray tmp(16, '\0');
|
|
||||||
|
|
||||||
for (int i = 0; i < 16; ++i)
|
|
||||||
{
|
|
||||||
tmp[i] = ipv6_address[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
collated = QStringLiteral("2-") + QString::fromUtf8(tmp.toHex());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (collated.isEmpty())
|
|
||||||
{
|
|
||||||
collated = QStringLiteral("3-") + address.toLower();
|
|
||||||
}
|
|
||||||
|
|
||||||
return collated;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
/***
|
// ---
|
||||||
****
|
|
||||||
***/
|
|
||||||
|
|
||||||
class PeerItem : public QTreeWidgetItem
|
class PeerItem : public QTreeWidgetItem
|
||||||
{
|
{
|
||||||
@@ -233,11 +206,43 @@ private:
|
|||||||
|
|
||||||
return collated_address_;
|
return collated_address_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] static QString collateAddress(QString const& address)
|
||||||
|
{
|
||||||
|
auto collated = QString{};
|
||||||
|
|
||||||
|
if (auto ip_address = QHostAddress{}; ip_address.setAddress(address))
|
||||||
|
{
|
||||||
|
if (ip_address.protocol() == QAbstractSocket::IPv4Protocol)
|
||||||
|
{
|
||||||
|
quint32 const ipv4_address = ip_address.toIPv4Address();
|
||||||
|
collated = QStringLiteral("1-") +
|
||||||
|
QString::fromUtf8(QByteArray::number(ipv4_address, 16).rightJustified(8, '0'));
|
||||||
|
}
|
||||||
|
else if (ip_address.protocol() == QAbstractSocket::IPv6Protocol)
|
||||||
|
{
|
||||||
|
Q_IPV6ADDR const ipv6_address = ip_address.toIPv6Address();
|
||||||
|
QByteArray tmp(16, '\0');
|
||||||
|
|
||||||
|
for (int i = 0; i < 16; ++i)
|
||||||
|
{
|
||||||
|
tmp[i] = ipv6_address[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
collated = QStringLiteral("2-") + QString::fromUtf8(tmp.toHex());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (collated.isEmpty())
|
||||||
|
{
|
||||||
|
collated = QStringLiteral("3-") + address.toLower();
|
||||||
|
}
|
||||||
|
|
||||||
|
return collated;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/***
|
// ---
|
||||||
****
|
|
||||||
***/
|
|
||||||
|
|
||||||
// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
|
// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
|
||||||
int DetailsDialog::prev_tab_index_ = 0;
|
int DetailsDialog::prev_tab_index_ = 0;
|
||||||
@@ -328,9 +333,7 @@ void DetailsDialog::refreshPref(int key)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/***
|
// ---
|
||||||
****
|
|
||||||
***/
|
|
||||||
|
|
||||||
void DetailsDialog::refreshModel()
|
void DetailsDialog::refreshModel()
|
||||||
{
|
{
|
||||||
@@ -1317,9 +1320,7 @@ void DetailsDialog::setEnabled(bool enabled)
|
|||||||
ui_.tabs->setEnabled(enabled);
|
ui_.tabs->setEnabled(enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
/***
|
// ---
|
||||||
****
|
|
||||||
***/
|
|
||||||
|
|
||||||
void DetailsDialog::initInfoTab()
|
void DetailsDialog::initInfoTab()
|
||||||
{
|
{
|
||||||
@@ -1336,9 +1337,7 @@ void DetailsDialog::initInfoTab()
|
|||||||
cr->update();
|
cr->update();
|
||||||
}
|
}
|
||||||
|
|
||||||
/***
|
// ---
|
||||||
****
|
|
||||||
***/
|
|
||||||
|
|
||||||
void DetailsDialog::onShowTrackerScrapesToggled(bool val)
|
void DetailsDialog::onShowTrackerScrapesToggled(bool val)
|
||||||
{
|
{
|
||||||
@@ -1572,9 +1571,7 @@ void DetailsDialog::initOptionsTab()
|
|||||||
connect(ui_.singleUpSpin, &QSpinBox::editingFinished, this, &DetailsDialog::onSpinBoxEditingFinished);
|
connect(ui_.singleUpSpin, &QSpinBox::editingFinished, this, &DetailsDialog::onSpinBoxEditingFinished);
|
||||||
}
|
}
|
||||||
|
|
||||||
/***
|
// ---
|
||||||
****
|
|
||||||
***/
|
|
||||||
|
|
||||||
void DetailsDialog::initTrackerTab()
|
void DetailsDialog::initTrackerTab()
|
||||||
{
|
{
|
||||||
@@ -1616,9 +1613,7 @@ void DetailsDialog::initTrackerTab()
|
|||||||
onTrackerSelectionChanged();
|
onTrackerSelectionChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
/***
|
// ---
|
||||||
****
|
|
||||||
***/
|
|
||||||
|
|
||||||
void DetailsDialog::initPeersTab()
|
void DetailsDialog::initPeersTab()
|
||||||
{
|
{
|
||||||
@@ -1635,9 +1630,7 @@ void DetailsDialog::initPeersTab()
|
|||||||
ui_.peersView->setColumnWidth(COL_ADDRESS, measureViewItem(ui_.peersView, COL_ADDRESS, QStringLiteral("888.888.888.888")));
|
ui_.peersView->setColumnWidth(COL_ADDRESS, measureViewItem(ui_.peersView, COL_ADDRESS, QStringLiteral("888.888.888.888")));
|
||||||
}
|
}
|
||||||
|
|
||||||
/***
|
// ---
|
||||||
****
|
|
||||||
***/
|
|
||||||
|
|
||||||
void DetailsDialog::initFilesTab() const
|
void DetailsDialog::initFilesTab() const
|
||||||
{
|
{
|
||||||
@@ -1647,21 +1640,6 @@ void DetailsDialog::initFilesTab() const
|
|||||||
connect(ui_.filesView, &FileTreeView::wantedChanged, this, &DetailsDialog::onFileWantedChanged);
|
connect(ui_.filesView, &FileTreeView::wantedChanged, this, &DetailsDialog::onFileWantedChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
static constexpr tr_quark priorityKey(int priority)
|
|
||||||
{
|
|
||||||
switch (priority)
|
|
||||||
{
|
|
||||||
case TR_PRI_LOW:
|
|
||||||
return TR_KEY_priority_low;
|
|
||||||
|
|
||||||
case TR_PRI_HIGH:
|
|
||||||
return TR_KEY_priority_high;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return TR_KEY_priority_normal;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DetailsDialog::onFilePriorityChanged(file_indices_t const& indices, int priority)
|
void DetailsDialog::onFilePriorityChanged(file_indices_t const& indices, int priority)
|
||||||
{
|
{
|
||||||
torrentSet(priorityKey(priority), std::vector<int>{ std::begin(indices), std::end(indices) });
|
torrentSet(priorityKey(priority), std::vector<int>{ std::begin(indices), std::end(indices) });
|
||||||
|
|||||||
@@ -149,6 +149,25 @@ QString qtDayName(int day)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] bool isDescendantOf(QObject const* descendant, QObject const* ancestor)
|
||||||
|
{
|
||||||
|
if (ancestor == nullptr)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (descendant != nullptr)
|
||||||
|
{
|
||||||
|
if (descendant == ancestor)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
descendant = descendant->parent();
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
bool PrefsDialog::updateWidgetValue(QWidget* widget, int pref_key) const
|
bool PrefsDialog::updateWidgetValue(QWidget* widget, int pref_key) const
|
||||||
@@ -234,24 +253,6 @@ void PrefsDialog::linkWidgetToPref(QWidget* widget, int pref_key)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool isDescendantOf(QObject const* descendant, QObject const* ancestor)
|
|
||||||
{
|
|
||||||
if (ancestor == nullptr)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
while (descendant != nullptr)
|
|
||||||
{
|
|
||||||
if (descendant == ancestor)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
descendant = descendant->parent();
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrefsDialog::focusChanged(QWidget* old, QWidget* cur)
|
void PrefsDialog::focusChanged(QWidget* old, QWidget* cur)
|
||||||
{
|
{
|
||||||
// We don't want to change the preference every time there's a keystroke
|
// We don't want to change the preference every time there's a keystroke
|
||||||
@@ -334,9 +335,7 @@ void PrefsDialog::pathChanged(QString const& path)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/***
|
// ---
|
||||||
****
|
|
||||||
***/
|
|
||||||
|
|
||||||
void PrefsDialog::initRemoteTab()
|
void PrefsDialog::initRemoteTab()
|
||||||
{
|
{
|
||||||
@@ -356,9 +355,7 @@ void PrefsDialog::initRemoteTab()
|
|||||||
connect(ui_.openWebClientButton, &QAbstractButton::clicked, &session_, &Session::launchWebInterface);
|
connect(ui_.openWebClientButton, &QAbstractButton::clicked, &session_, &Session::launchWebInterface);
|
||||||
}
|
}
|
||||||
|
|
||||||
/***
|
// ---
|
||||||
****
|
|
||||||
***/
|
|
||||||
|
|
||||||
void PrefsDialog::altSpeedDaysEdited(int i)
|
void PrefsDialog::altSpeedDaysEdited(int i)
|
||||||
{
|
{
|
||||||
@@ -416,9 +413,7 @@ void PrefsDialog::initSpeedTab()
|
|||||||
connect(ui_.altSpeedLimitDaysCombo, qOverload<int>(&QComboBox::activated), this, &PrefsDialog::altSpeedDaysEdited);
|
connect(ui_.altSpeedLimitDaysCombo, qOverload<int>(&QComboBox::activated), this, &PrefsDialog::altSpeedDaysEdited);
|
||||||
}
|
}
|
||||||
|
|
||||||
/***
|
// ---
|
||||||
****
|
|
||||||
***/
|
|
||||||
|
|
||||||
void PrefsDialog::initDesktopTab()
|
void PrefsDialog::initDesktopTab()
|
||||||
{
|
{
|
||||||
@@ -429,9 +424,7 @@ void PrefsDialog::initDesktopTab()
|
|||||||
linkWidgetToPref(ui_.playSoundOnTorrentCompletedCheck, Prefs::COMPLETE_SOUND_ENABLED);
|
linkWidgetToPref(ui_.playSoundOnTorrentCompletedCheck, Prefs::COMPLETE_SOUND_ENABLED);
|
||||||
}
|
}
|
||||||
|
|
||||||
/***
|
// ---
|
||||||
****
|
|
||||||
***/
|
|
||||||
|
|
||||||
void PrefsDialog::onPortTested(bool isOpen)
|
void PrefsDialog::onPortTested(bool isOpen)
|
||||||
{
|
{
|
||||||
@@ -473,9 +466,7 @@ void PrefsDialog::initNetworkTab()
|
|||||||
connect(&session_, &Session::portTested, this, &PrefsDialog::onPortTested);
|
connect(&session_, &Session::portTested, this, &PrefsDialog::onPortTested);
|
||||||
}
|
}
|
||||||
|
|
||||||
/***
|
// ---
|
||||||
****
|
|
||||||
***/
|
|
||||||
|
|
||||||
void PrefsDialog::onBlocklistDialogDestroyed(QObject* o)
|
void PrefsDialog::onBlocklistDialogDestroyed(QObject* o)
|
||||||
{
|
{
|
||||||
@@ -540,9 +531,7 @@ void PrefsDialog::initPrivacyTab()
|
|||||||
updateBlocklistLabel();
|
updateBlocklistLabel();
|
||||||
}
|
}
|
||||||
|
|
||||||
/***
|
// ---
|
||||||
****
|
|
||||||
***/
|
|
||||||
|
|
||||||
void PrefsDialog::onIdleLimitChanged()
|
void PrefsDialog::onIdleLimitChanged()
|
||||||
{
|
{
|
||||||
@@ -656,9 +645,7 @@ void PrefsDialog::updateSeedingWidgetsLocality()
|
|||||||
ui_.doneSeedingScriptStack->setFixedHeight(ui_.doneSeedingScriptStack->currentWidget()->sizeHint().height());
|
ui_.doneSeedingScriptStack->setFixedHeight(ui_.doneSeedingScriptStack->currentWidget()->sizeHint().height());
|
||||||
}
|
}
|
||||||
|
|
||||||
/***
|
// ---
|
||||||
****
|
|
||||||
***/
|
|
||||||
|
|
||||||
PrefsDialog::PrefsDialog(Session& session, Prefs& prefs, QWidget* parent)
|
PrefsDialog::PrefsDialog(Session& session, Prefs& prefs, QWidget* parent)
|
||||||
: BaseDialog{ parent }
|
: BaseDialog{ parent }
|
||||||
@@ -719,9 +706,7 @@ void PrefsDialog::setPref(int key, QVariant const& v)
|
|||||||
refreshPref(key);
|
refreshPref(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
/***
|
// ---
|
||||||
****
|
|
||||||
***/
|
|
||||||
|
|
||||||
void PrefsDialog::sessionUpdated()
|
void PrefsDialog::sessionUpdated()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -20,8 +20,10 @@
|
|||||||
#include <libtransmission/variant.h>
|
#include <libtransmission/variant.h>
|
||||||
#include <libtransmission/version.h>
|
#include <libtransmission/version.h>
|
||||||
|
|
||||||
static char constexpr MyName[] = "transmission-edit";
|
namespace
|
||||||
static char constexpr Usage[] = "Usage: transmission-edit [options] torrent-file(s)";
|
{
|
||||||
|
char constexpr MyName[] = "transmission-edit";
|
||||||
|
char constexpr Usage[] = "Usage: transmission-edit [options] torrent-file(s)";
|
||||||
|
|
||||||
struct app_options
|
struct app_options
|
||||||
{
|
{
|
||||||
@@ -33,7 +35,7 @@ struct app_options
|
|||||||
bool show_version = false;
|
bool show_version = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
static auto constexpr Options = std::array<tr_option, 6>{
|
auto constexpr Options = std::array<tr_option, 6>{
|
||||||
{ { 'a', "add", "Add a tracker's announce URL", "a", true, "<url>" },
|
{ { 'a', "add", "Add a tracker's announce URL", "a", true, "<url>" },
|
||||||
{ 'd', "delete", "Delete a tracker's announce URL", "d", true, "<url>" },
|
{ 'd', "delete", "Delete a tracker's announce URL", "d", true, "<url>" },
|
||||||
{ 'r', "replace", "Search and replace a substring in the announce URLs", "r", true, "<old> <new>" },
|
{ 'r', "replace", "Search and replace a substring in the announce URLs", "r", true, "<old> <new>" },
|
||||||
@@ -42,7 +44,7 @@ static auto constexpr Options = std::array<tr_option, 6>{
|
|||||||
{ 0, nullptr, nullptr, nullptr, false, nullptr } }
|
{ 0, nullptr, nullptr, nullptr, false, nullptr } }
|
||||||
};
|
};
|
||||||
|
|
||||||
static int parseCommandLine(app_options& opts, int argc, char const* const* argv)
|
int parseCommandLine(app_options& opts, int argc, char const* const* argv)
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
char const* optarg;
|
char const* optarg;
|
||||||
@@ -91,7 +93,7 @@ static int parseCommandLine(app_options& opts, int argc, char const* const* argv
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool removeURL(tr_variant* metainfo, std::string_view url)
|
bool removeURL(tr_variant* metainfo, std::string_view url)
|
||||||
{
|
{
|
||||||
auto sv = std::string_view{};
|
auto sv = std::string_view{};
|
||||||
tr_variant* announce_list;
|
tr_variant* announce_list;
|
||||||
@@ -164,7 +166,7 @@ static bool removeURL(tr_variant* metainfo, std::string_view url)
|
|||||||
return changed;
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string replaceSubstr(std::string_view str, std::string_view oldval, std::string_view newval)
|
[[nodisard]] auto replaceSubstr(std::string_view str, std::string_view oldval, std::string_view newval)
|
||||||
{
|
{
|
||||||
auto ret = std::string{};
|
auto ret = std::string{};
|
||||||
|
|
||||||
@@ -183,7 +185,7 @@ static std::string replaceSubstr(std::string_view str, std::string_view oldval,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool replaceURL(tr_variant* metainfo, std::string_view oldval, std::string_view newval)
|
bool replaceURL(tr_variant* metainfo, std::string_view oldval, std::string_view newval)
|
||||||
{
|
{
|
||||||
auto sv = std::string_view{};
|
auto sv = std::string_view{};
|
||||||
tr_variant* announce_list;
|
tr_variant* announce_list;
|
||||||
@@ -228,7 +230,7 @@ static bool replaceURL(tr_variant* metainfo, std::string_view oldval, std::strin
|
|||||||
return changed;
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool announce_list_has_url(tr_variant* announce_list, char const* url)
|
[[nodiscard]] bool announce_list_has_url(tr_variant* announce_list, char const* url)
|
||||||
{
|
{
|
||||||
int tierCount = 0;
|
int tierCount = 0;
|
||||||
tr_variant* tier;
|
tr_variant* tier;
|
||||||
@@ -254,7 +256,7 @@ static bool announce_list_has_url(tr_variant* announce_list, char const* url)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool addURL(tr_variant* metainfo, char const* url)
|
bool addURL(tr_variant* metainfo, char const* url)
|
||||||
{
|
{
|
||||||
auto announce = std::string_view{};
|
auto announce = std::string_view{};
|
||||||
tr_variant* announce_list = nullptr;
|
tr_variant* announce_list = nullptr;
|
||||||
@@ -298,7 +300,7 @@ static bool addURL(tr_variant* metainfo, char const* url)
|
|||||||
return changed;
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool setSource(tr_variant* metainfo, char const* source_value)
|
bool setSource(tr_variant* metainfo, char const* source_value)
|
||||||
{
|
{
|
||||||
auto current_source = std::string_view{};
|
auto current_source = std::string_view{};
|
||||||
bool const had_source = tr_variantDictFindStrView(metainfo, TR_KEY_source, ¤t_source);
|
bool const had_source = tr_variantDictFindStrView(metainfo, TR_KEY_source, ¤t_source);
|
||||||
@@ -319,6 +321,7 @@ static bool setSource(tr_variant* metainfo, char const* source_value)
|
|||||||
|
|
||||||
return changed;
|
return changed;
|
||||||
}
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
int tr_main(int argc, char* argv[])
|
int tr_main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
|
|||||||
154
utils/remote.cc
154
utils/remote.cc
@@ -46,24 +46,26 @@ using namespace libtransmission::Values;
|
|||||||
#define SPEED_K_STR "kB/s"
|
#define SPEED_K_STR "kB/s"
|
||||||
#define MEM_M_STR "MiB"
|
#define MEM_M_STR "MiB"
|
||||||
|
|
||||||
static auto constexpr DefaultPort = int{ TR_DEFAULT_RPC_PORT };
|
namespace
|
||||||
static char constexpr DefaultHost[] = "localhost";
|
{
|
||||||
static char constexpr DefaultUrl[] = TR_DEFAULT_RPC_URL_STR "rpc/";
|
auto constexpr DefaultPort = int{ TR_DEFAULT_RPC_PORT };
|
||||||
|
char constexpr DefaultHost[] = "localhost";
|
||||||
|
char constexpr DefaultUrl[] = TR_DEFAULT_RPC_URL_STR "rpc/";
|
||||||
|
|
||||||
static char constexpr MyName[] = "transmission-remote";
|
char constexpr MyName[] = "transmission-remote";
|
||||||
static char constexpr Usage[] = "transmission-remote " LONG_VERSION_STRING
|
char constexpr Usage[] = "transmission-remote " LONG_VERSION_STRING
|
||||||
"\n"
|
"\n"
|
||||||
"A fast and easy BitTorrent client\n"
|
"A fast and easy BitTorrent client\n"
|
||||||
"https://transmissionbt.com/\n"
|
"https://transmissionbt.com/\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Usage: transmission-remote [host] [options]\n"
|
"Usage: transmission-remote [host] [options]\n"
|
||||||
" transmission-remote [port] [options]\n"
|
" transmission-remote [port] [options]\n"
|
||||||
" transmission-remote [host:port] [options]\n"
|
" transmission-remote [host:port] [options]\n"
|
||||||
" transmission-remote [http(s?)://host:port/transmission/] [options]\n"
|
" transmission-remote [http(s?)://host:port/transmission/] [options]\n"
|
||||||
"\n"
|
"\n"
|
||||||
"See the man page for detailed explanations and many examples.";
|
"See the man page for detailed explanations and many examples.";
|
||||||
|
|
||||||
static auto constexpr Arguments = TR_KEY_arguments;
|
auto constexpr Arguments = TR_KEY_arguments;
|
||||||
|
|
||||||
struct RemoteConfig
|
struct RemoteConfig
|
||||||
{
|
{
|
||||||
@@ -79,13 +81,9 @@ struct RemoteConfig
|
|||||||
bool use_ssl = false;
|
bool use_ssl = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
/***
|
// --- Display Utilities
|
||||||
****
|
|
||||||
**** Display Utilities
|
|
||||||
****
|
|
||||||
***/
|
|
||||||
|
|
||||||
static std::string etaToString(int64_t eta)
|
[[nodiscard]] std::string etaToString(int64_t eta)
|
||||||
{
|
{
|
||||||
if (eta < 0)
|
if (eta < 0)
|
||||||
{
|
{
|
||||||
@@ -125,7 +123,7 @@ static std::string etaToString(int64_t eta)
|
|||||||
return "∞";
|
return "∞";
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string tr_strltime(time_t seconds)
|
[[nodiscard]] auto tr_strltime(time_t seconds)
|
||||||
{
|
{
|
||||||
if (seconds < 0)
|
if (seconds < 0)
|
||||||
{
|
{
|
||||||
@@ -166,22 +164,22 @@ static std::string tr_strltime(time_t seconds)
|
|||||||
return fmt::format(FMT_STRING("{:s} ({:s})"), tmpstr, totstr);
|
return fmt::format(FMT_STRING("{:s} ({:s})"), tmpstr, totstr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string strlpercent(double x)
|
[[nodiscard]] auto strlpercent(double x)
|
||||||
{
|
{
|
||||||
return tr_strpercent(x);
|
return tr_strpercent(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string strlratio2(double ratio)
|
[[nodiscard]] auto strlratio2(double ratio)
|
||||||
{
|
{
|
||||||
return tr_strratio(ratio, "Inf");
|
return tr_strratio(ratio, "Inf");
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string strlratio(int64_t numerator, int64_t denominator)
|
[[nodiscard]] auto strlratio(int64_t numerator, int64_t denominator)
|
||||||
{
|
{
|
||||||
return strlratio2(tr_getRatio(numerator, denominator));
|
return strlratio2(tr_getRatio(numerator, denominator));
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string strlsize(int64_t bytes)
|
[[nodiscard]] auto strlsize(int64_t bytes)
|
||||||
{
|
{
|
||||||
if (bytes < 0)
|
if (bytes < 0)
|
||||||
{
|
{
|
||||||
@@ -212,13 +210,9 @@ enum
|
|||||||
TAG_TRACKERS
|
TAG_TRACKERS
|
||||||
};
|
};
|
||||||
|
|
||||||
/***
|
// --- Command-Line Arguments
|
||||||
****
|
|
||||||
**** Command-Line Arguments
|
|
||||||
****
|
|
||||||
***/
|
|
||||||
|
|
||||||
static auto constexpr Options = std::array<tr_option, 98>{
|
auto constexpr Options = std::array<tr_option, 98>{
|
||||||
{ { 'a', "add", "Add torrent files by filename or URL", "a", false, nullptr },
|
{ { 'a', "add", "Add torrent files by filename or URL", "a", false, nullptr },
|
||||||
{ 970, "alt-speed", "Use the alternate Limits", "as", false, nullptr },
|
{ 970, "alt-speed", "Use the alternate Limits", "as", false, nullptr },
|
||||||
{ 971, "no-alt-speed", "Don't use the alternate Limits", "AS", false, nullptr },
|
{ 971, "no-alt-speed", "Don't use the alternate Limits", "AS", false, nullptr },
|
||||||
@@ -350,12 +344,12 @@ static auto constexpr Options = std::array<tr_option, 98>{
|
|||||||
{ 0, nullptr, nullptr, nullptr, false, nullptr } }
|
{ 0, nullptr, nullptr, nullptr, false, nullptr } }
|
||||||
};
|
};
|
||||||
|
|
||||||
static void showUsage(void)
|
void showUsage()
|
||||||
{
|
{
|
||||||
tr_getopt_usage(MyName, Usage, std::data(Options));
|
tr_getopt_usage(MyName, Usage, std::data(Options));
|
||||||
}
|
}
|
||||||
|
|
||||||
static long numarg(char const* arg)
|
[[nodiscard]] auto numarg(char const* arg)
|
||||||
{
|
{
|
||||||
char* end = nullptr;
|
char* end = nullptr;
|
||||||
long const num = strtol(arg, &end, 10);
|
long const num = strtol(arg, &end, 10);
|
||||||
@@ -390,7 +384,7 @@ enum
|
|||||||
MODE_GROUP_GET = (1 << 15)
|
MODE_GROUP_GET = (1 << 15)
|
||||||
};
|
};
|
||||||
|
|
||||||
static int getOptMode(int val)
|
[[nodiscard]] int getOptMode(int val)
|
||||||
{
|
{
|
||||||
switch (val)
|
switch (val)
|
||||||
{
|
{
|
||||||
@@ -542,7 +536,7 @@ static int getOptMode(int val)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string getEncodedMetainfo(char const* filename)
|
[[nodiscard]] std::string getEncodedMetainfo(char const* filename)
|
||||||
{
|
{
|
||||||
if (auto contents = std::vector<char>{}; tr_sys_path_exists(filename) && tr_file_read(filename, contents))
|
if (auto contents = std::vector<char>{}; tr_sys_path_exists(filename) && tr_file_read(filename, contents))
|
||||||
{
|
{
|
||||||
@@ -552,7 +546,7 @@ static std::string getEncodedMetainfo(char const* filename)
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
static void addIdArg(tr_variant* args, std::string_view id_str, std::string_view fallback = "")
|
void addIdArg(tr_variant* args, std::string_view id_str, std::string_view fallback = "")
|
||||||
{
|
{
|
||||||
if (std::empty(id_str))
|
if (std::empty(id_str))
|
||||||
{
|
{
|
||||||
@@ -593,12 +587,12 @@ static void addIdArg(tr_variant* args, std::string_view id_str, std::string_view
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void addIdArg(tr_variant* args, RemoteConfig const& config, std::string_view fallback = "")
|
void addIdArg(tr_variant* args, RemoteConfig const& config, std::string_view fallback = "")
|
||||||
{
|
{
|
||||||
return addIdArg(args, config.torrent_ids, fallback);
|
return addIdArg(args, config.torrent_ids, fallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void addTime(tr_variant* args, tr_quark const key, char const* arg)
|
void addTime(tr_variant* args, tr_quark const key, char const* arg)
|
||||||
{
|
{
|
||||||
int time = 0;
|
int time = 0;
|
||||||
bool success = false;
|
bool success = false;
|
||||||
@@ -627,7 +621,7 @@ static void addTime(tr_variant* args, tr_quark const key, char const* arg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void addDays(tr_variant* args, tr_quark const key, char const* arg)
|
void addDays(tr_variant* args, tr_quark const key, char const* arg)
|
||||||
{
|
{
|
||||||
int days = 0;
|
int days = 0;
|
||||||
|
|
||||||
@@ -659,7 +653,7 @@ static void addDays(tr_variant* args, tr_quark const key, char const* arg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void addLabels(tr_variant* args, std::string_view comma_delimited_labels)
|
void addLabels(tr_variant* args, std::string_view comma_delimited_labels)
|
||||||
{
|
{
|
||||||
tr_variant* labels;
|
tr_variant* labels;
|
||||||
if (!tr_variantDictFindList(args, TR_KEY_labels, &labels))
|
if (!tr_variantDictFindList(args, TR_KEY_labels, &labels))
|
||||||
@@ -674,7 +668,7 @@ static void addLabels(tr_variant* args, std::string_view comma_delimited_labels)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setGroup(tr_variant* args, std::string_view group)
|
void setGroup(tr_variant* args, std::string_view group)
|
||||||
{
|
{
|
||||||
tr_variantDictAddStrView(args, TR_KEY_group, group);
|
tr_variantDictAddStrView(args, TR_KEY_group, group);
|
||||||
}
|
}
|
||||||
@@ -703,14 +697,14 @@ static void setGroup(tr_variant* args, std::string_view group)
|
|||||||
return files;
|
return files;
|
||||||
}
|
}
|
||||||
|
|
||||||
static auto constexpr FilesKeys = std::array<tr_quark, 4>{
|
auto constexpr FilesKeys = std::array<tr_quark, 4>{
|
||||||
TR_KEY_files,
|
TR_KEY_files,
|
||||||
TR_KEY_name,
|
TR_KEY_name,
|
||||||
TR_KEY_priorities,
|
TR_KEY_priorities,
|
||||||
TR_KEY_wanted,
|
TR_KEY_wanted,
|
||||||
};
|
};
|
||||||
|
|
||||||
static auto constexpr DetailsKeys = std::array<tr_quark, 53>{
|
auto constexpr DetailsKeys = std::array<tr_quark, 53>{
|
||||||
TR_KEY_activityDate,
|
TR_KEY_activityDate,
|
||||||
TR_KEY_addedDate,
|
TR_KEY_addedDate,
|
||||||
TR_KEY_bandwidthPriority,
|
TR_KEY_bandwidthPriority,
|
||||||
@@ -766,7 +760,7 @@ static auto constexpr DetailsKeys = std::array<tr_quark, 53>{
|
|||||||
TR_KEY_webseedsSendingToUs,
|
TR_KEY_webseedsSendingToUs,
|
||||||
};
|
};
|
||||||
|
|
||||||
static auto constexpr ListKeys = std::array<tr_quark, 15>{
|
auto constexpr ListKeys = std::array<tr_quark, 15>{
|
||||||
TR_KEY_addedDate,
|
TR_KEY_addedDate,
|
||||||
TR_KEY_error,
|
TR_KEY_error,
|
||||||
TR_KEY_errorString,
|
TR_KEY_errorString,
|
||||||
@@ -784,7 +778,7 @@ static auto constexpr ListKeys = std::array<tr_quark, 15>{
|
|||||||
TR_KEY_uploadRatio,
|
TR_KEY_uploadRatio,
|
||||||
};
|
};
|
||||||
|
|
||||||
static size_t writeFunc(void* ptr, size_t size, size_t nmemb, void* vbuf)
|
[[nodiscard]] size_t writeFunc(void* ptr, size_t size, size_t nmemb, void* vbuf)
|
||||||
{
|
{
|
||||||
auto* const buf = static_cast<evbuffer*>(vbuf);
|
auto* const buf = static_cast<evbuffer*>(vbuf);
|
||||||
size_t const byteCount = size * nmemb;
|
size_t const byteCount = size * nmemb;
|
||||||
@@ -793,7 +787,7 @@ static size_t writeFunc(void* ptr, size_t size, size_t nmemb, void* vbuf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* look for a session id in the header in case the server gives back a 409 */
|
/* look for a session id in the header in case the server gives back a 409 */
|
||||||
static size_t parseResponseHeader(void* ptr, size_t size, size_t nmemb, void* vconfig)
|
[[nodiscard]] size_t parseResponseHeader(void* ptr, size_t size, size_t nmemb, void* vconfig)
|
||||||
{
|
{
|
||||||
auto& config = *static_cast<RemoteConfig*>(vconfig);
|
auto& config = *static_cast<RemoteConfig*>(vconfig);
|
||||||
auto const* const line = static_cast<char const*>(ptr);
|
auto const* const line = static_cast<char const*>(ptr);
|
||||||
@@ -817,7 +811,7 @@ static size_t parseResponseHeader(void* ptr, size_t size, size_t nmemb, void* vc
|
|||||||
return line_len;
|
return line_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
static long getTimeoutSecs(std::string_view req)
|
[[nodiscard]] long getTimeoutSecs(std::string_view req)
|
||||||
{
|
{
|
||||||
if (req.find("\"method\":\"blocklist-update\""sv) != std::string_view::npos)
|
if (req.find("\"method\":\"blocklist-update\""sv) != std::string_view::npos)
|
||||||
{
|
{
|
||||||
@@ -827,7 +821,7 @@ static long getTimeoutSecs(std::string_view req)
|
|||||||
return 60L; /* default value */
|
return 60L; /* default value */
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string getStatusString(tr_variant* t)
|
[[nodiscard]] std::string getStatusString(tr_variant* t)
|
||||||
{
|
{
|
||||||
auto from_us = int64_t{};
|
auto from_us = int64_t{};
|
||||||
auto status = int64_t{};
|
auto status = int64_t{};
|
||||||
@@ -893,20 +887,20 @@ static std::string getStatusString(tr_variant* t)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static auto constexpr bandwidth_priority_names = std::array<std::string_view, 4>{
|
auto constexpr bandwidth_priority_names = std::array<std::string_view, 4>{
|
||||||
"Low"sv,
|
"Low"sv,
|
||||||
"Normal"sv,
|
"Normal"sv,
|
||||||
"High"sv,
|
"High"sv,
|
||||||
"Invalid"sv,
|
"Invalid"sv,
|
||||||
};
|
};
|
||||||
|
|
||||||
static char* format_date(char* buf, size_t buflen, time_t now)
|
char* format_date(char* buf, size_t buflen, time_t now)
|
||||||
{
|
{
|
||||||
*fmt::format_to_n(buf, buflen - 1, "{:%a %b %d %T %Y}", fmt::localtime(now)).out = '\0';
|
*fmt::format_to_n(buf, buflen - 1, "{:%a %b %d %T %Y}", fmt::localtime(now)).out = '\0';
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void printDetails(tr_variant* top)
|
void printDetails(tr_variant* top)
|
||||||
{
|
{
|
||||||
tr_variant* args;
|
tr_variant* args;
|
||||||
tr_variant* torrents;
|
tr_variant* torrents;
|
||||||
@@ -1238,7 +1232,7 @@ static void printDetails(tr_variant* top)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void printFileList(tr_variant* top)
|
void printFileList(tr_variant* top)
|
||||||
{
|
{
|
||||||
tr_variant* args;
|
tr_variant* args;
|
||||||
tr_variant* torrents;
|
tr_variant* torrents;
|
||||||
@@ -1308,7 +1302,7 @@ static void printFileList(tr_variant* top)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void printPeersImpl(tr_variant* peers)
|
void printPeersImpl(tr_variant* peers)
|
||||||
{
|
{
|
||||||
printf("%-40s %-12s %-5s %-6s %-6s %s\n", "Address", "Flags", "Done", "Down", "Up", "Client");
|
printf("%-40s %-12s %-5s %-6s %-6s %s\n", "Address", "Flags", "Done", "Down", "Up", "Client");
|
||||||
|
|
||||||
@@ -1341,7 +1335,7 @@ static void printPeersImpl(tr_variant* peers)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void printPeers(tr_variant* top)
|
void printPeers(tr_variant* top)
|
||||||
{
|
{
|
||||||
tr_variant* args;
|
tr_variant* args;
|
||||||
tr_variant* torrents;
|
tr_variant* torrents;
|
||||||
@@ -1366,7 +1360,7 @@ static void printPeers(tr_variant* top)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void printPiecesImpl(std::string_view raw, size_t piece_count)
|
void printPiecesImpl(std::string_view raw, size_t piece_count)
|
||||||
{
|
{
|
||||||
auto const str = tr_base64_decode(raw);
|
auto const str = tr_base64_decode(raw);
|
||||||
fmt::print(" ");
|
fmt::print(" ");
|
||||||
@@ -1391,7 +1385,7 @@ static void printPiecesImpl(std::string_view raw, size_t piece_count)
|
|||||||
fmt::print("\n");
|
fmt::print("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void printPieces(tr_variant* top)
|
void printPieces(tr_variant* top)
|
||||||
{
|
{
|
||||||
tr_variant* args;
|
tr_variant* args;
|
||||||
tr_variant* torrents;
|
tr_variant* torrents;
|
||||||
@@ -1419,7 +1413,7 @@ static void printPieces(tr_variant* top)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void printPortTest(tr_variant* top)
|
void printPortTest(tr_variant* top)
|
||||||
{
|
{
|
||||||
tr_variant* args;
|
tr_variant* args;
|
||||||
|
|
||||||
@@ -1434,7 +1428,7 @@ static void printPortTest(tr_variant* top)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void printTorrentList(tr_variant* top)
|
void printTorrentList(tr_variant* top)
|
||||||
{
|
{
|
||||||
tr_variant* args;
|
tr_variant* args;
|
||||||
tr_variant* list;
|
tr_variant* list;
|
||||||
@@ -1534,7 +1528,7 @@ static void printTorrentList(tr_variant* top)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void printTrackersImpl(tr_variant* trackerStats)
|
void printTrackersImpl(tr_variant* trackerStats)
|
||||||
{
|
{
|
||||||
for (size_t i = 0, n = tr_variantListSize(trackerStats); i < n; ++i)
|
for (size_t i = 0, n = tr_variantListSize(trackerStats); i < n; ++i)
|
||||||
{
|
{
|
||||||
@@ -1684,7 +1678,7 @@ static void printTrackersImpl(tr_variant* trackerStats)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void printTrackers(tr_variant* top)
|
void printTrackers(tr_variant* top)
|
||||||
{
|
{
|
||||||
tr_variant* args;
|
tr_variant* args;
|
||||||
tr_variant* torrents;
|
tr_variant* torrents;
|
||||||
@@ -1709,7 +1703,7 @@ static void printTrackers(tr_variant* top)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void printSession(tr_variant* top)
|
void printSession(tr_variant* top)
|
||||||
{
|
{
|
||||||
tr_variant* args;
|
tr_variant* args;
|
||||||
|
|
||||||
@@ -1939,7 +1933,7 @@ static void printSession(tr_variant* top)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void printSessionStats(tr_variant* top)
|
void printSessionStats(tr_variant* top)
|
||||||
{
|
{
|
||||||
tr_variant* args;
|
tr_variant* args;
|
||||||
tr_variant* d;
|
tr_variant* d;
|
||||||
@@ -1975,7 +1969,7 @@ static void printSessionStats(tr_variant* top)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void printGroups(tr_variant* top)
|
void printGroups(tr_variant* top)
|
||||||
{
|
{
|
||||||
tr_variant* args;
|
tr_variant* args;
|
||||||
tr_variant* groups;
|
tr_variant* groups;
|
||||||
@@ -2009,7 +2003,7 @@ static void printGroups(tr_variant* top)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void filterIds(tr_variant* top, RemoteConfig& config)
|
void filterIds(tr_variant* top, RemoteConfig& config)
|
||||||
{
|
{
|
||||||
tr_variant* args;
|
tr_variant* args;
|
||||||
tr_variant* list;
|
tr_variant* list;
|
||||||
@@ -2130,7 +2124,8 @@ static void filterIds(tr_variant* top, RemoteConfig& config)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static int processResponse(char const* rpcurl, std::string_view response, RemoteConfig& config)
|
|
||||||
|
int processResponse(char const* rpcurl, std::string_view response, RemoteConfig& config)
|
||||||
{
|
{
|
||||||
auto status = int{ EXIT_SUCCESS };
|
auto status = int{ EXIT_SUCCESS };
|
||||||
|
|
||||||
@@ -2251,7 +2246,7 @@ static int processResponse(char const* rpcurl, std::string_view response, Remote
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
static CURL* tr_curl_easy_init(struct evbuffer* writebuf, RemoteConfig& config)
|
CURL* tr_curl_easy_init(struct evbuffer* writebuf, RemoteConfig& config)
|
||||||
{
|
{
|
||||||
CURL* curl = curl_easy_init();
|
CURL* curl = curl_easy_init();
|
||||||
(void)curl_easy_setopt(curl, CURLOPT_USERAGENT, fmt::format(FMT_STRING("{:s}/{:s}"), MyName, LONG_VERSION_STRING).c_str());
|
(void)curl_easy_setopt(curl, CURLOPT_USERAGENT, fmt::format(FMT_STRING("{:s}/{:s}"), MyName, LONG_VERSION_STRING).c_str());
|
||||||
@@ -2304,7 +2299,7 @@ static CURL* tr_curl_easy_init(struct evbuffer* writebuf, RemoteConfig& config)
|
|||||||
return curl;
|
return curl;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tr_curl_easy_cleanup(CURL* curl)
|
void tr_curl_easy_cleanup(CURL* curl)
|
||||||
{
|
{
|
||||||
struct curl_slist* custom_headers = nullptr;
|
struct curl_slist* custom_headers = nullptr;
|
||||||
curl_easy_getinfo(curl, CURLINFO_PRIVATE, &custom_headers);
|
curl_easy_getinfo(curl, CURLINFO_PRIVATE, &custom_headers);
|
||||||
@@ -2317,7 +2312,7 @@ static void tr_curl_easy_cleanup(CURL* curl)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int flush(char const* rpcurl, tr_variant* benc, RemoteConfig& config)
|
int flush(char const* rpcurl, tr_variant* benc, RemoteConfig& config)
|
||||||
{
|
{
|
||||||
auto const json = tr_variant_serde::json().compact().to_string(*benc);
|
auto const json = tr_variant_serde::json().compact().to_string(*benc);
|
||||||
auto const scheme = config.use_ssl ? "https"sv : "http"sv;
|
auto const scheme = config.use_ssl ? "https"sv : "http"sv;
|
||||||
@@ -2384,7 +2379,7 @@ static int flush(char const* rpcurl, tr_variant* benc, RemoteConfig& config)
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
static tr_variant* ensure_sset(tr_variant& sset)
|
tr_variant* ensure_sset(tr_variant& sset)
|
||||||
{
|
{
|
||||||
if (sset.has_value())
|
if (sset.has_value())
|
||||||
{
|
{
|
||||||
@@ -2396,7 +2391,7 @@ static tr_variant* ensure_sset(tr_variant& sset)
|
|||||||
return tr_variantDictAddDict(&sset, Arguments, 0);
|
return tr_variantDictAddDict(&sset, Arguments, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static tr_variant* ensure_tset(tr_variant& tset)
|
tr_variant* ensure_tset(tr_variant& tset)
|
||||||
{
|
{
|
||||||
if (tset.has_value())
|
if (tset.has_value())
|
||||||
{
|
{
|
||||||
@@ -2408,7 +2403,7 @@ static tr_variant* ensure_tset(tr_variant& tset)
|
|||||||
return tr_variantDictAddDict(&tset, Arguments, 1);
|
return tr_variantDictAddDict(&tset, Arguments, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int processArgs(char const* rpcurl, int argc, char const* const* argv, RemoteConfig& config)
|
int processArgs(char const* rpcurl, int argc, char const* const* argv, RemoteConfig& config)
|
||||||
{
|
{
|
||||||
int status = EXIT_SUCCESS;
|
int status = EXIT_SUCCESS;
|
||||||
char const* optarg;
|
char const* optarg;
|
||||||
@@ -3221,7 +3216,7 @@ static int processArgs(char const* rpcurl, int argc, char const* const* argv, Re
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool parsePortString(char const* s, int* port)
|
bool parsePortString(char const* s, int* port)
|
||||||
{
|
{
|
||||||
int const errno_stack = errno;
|
int const errno_stack = errno;
|
||||||
errno = 0;
|
errno = 0;
|
||||||
@@ -3239,13 +3234,7 @@ static bool parsePortString(char const* s, int* port)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* [host:port] or [host] or [port] or [http(s?)://host:port/transmission/] */
|
/* [host:port] or [host] or [port] or [http(s?)://host:port/transmission/] */
|
||||||
static void getHostAndPortAndRpcUrl(
|
void getHostAndPortAndRpcUrl(int* argc, char** argv, std::string* host, int* port, std::string* rpcurl, RemoteConfig& config)
|
||||||
int* argc,
|
|
||||||
char** argv,
|
|
||||||
std::string* host,
|
|
||||||
int* port,
|
|
||||||
std::string* rpcurl,
|
|
||||||
RemoteConfig& config)
|
|
||||||
{
|
{
|
||||||
if (*argv[1] == '-')
|
if (*argv[1] == '-')
|
||||||
{
|
{
|
||||||
@@ -3300,6 +3289,7 @@ static void getHostAndPortAndRpcUrl(
|
|||||||
argv[i] = argv[i + 1];
|
argv[i] = argv[i + 1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
int tr_main(int argc, char* argv[])
|
int tr_main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
@@ -3327,7 +3317,7 @@ int tr_main(int argc, char* argv[])
|
|||||||
|
|
||||||
if (std::empty(rpcurl))
|
if (std::empty(rpcurl))
|
||||||
{
|
{
|
||||||
rpcurl = fmt::format(FMT_STRING("{:s}:{:d}{:s}"), host, port, DefaultUrl);
|
rpcurl = fmt::format("{:s}:{:d}{:s}", host, port, DefaultUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
return processArgs(rpcurl.c_str(), argc, (char const* const*)argv, config);
|
return processArgs(rpcurl.c_str(), argc, (char const* const*)argv, config);
|
||||||
|
|||||||
Reference in New Issue
Block a user