From 3092a583cab0917fbafa3674c831d8bae6bb9c3d Mon Sep 17 00:00:00 2001 From: rakshasa Date: Thu, 2 Jun 2005 18:31:02 +0000 Subject: [PATCH] Adding a bunch of options. git-svn-id: svn://rakshasa.no/libtorrent/trunk/rtorrent@450 e378c898-3ddf-0310-93e7-cc216c733640 --- TODO | 4 +- doc/rtorrent.rc | 31 +++++++++++ src/core/manager.cc | 24 -------- src/core/manager.h | 16 ------ src/display/window_statusbar.cc | 4 +- src/main.cc | 29 +++++++--- src/option_handler_rules.cc | 67 +++++++++++++++++++++++ src/option_handler_rules.h | 97 +++++++++++++++++++++++++++++++-- 8 files changed, 217 insertions(+), 55 deletions(-) create mode 100644 doc/rtorrent.rc diff --git a/TODO b/TODO index 69075137..eeea15fa 100644 --- a/TODO +++ b/TODO @@ -33,4 +33,6 @@ Recheck hash key. Seperate download management from core::management. -Allow switching/cycling of tracker. \ No newline at end of file +Allow switching/cycling of tracker. + +Remember to add virtual dtor to OptionHandlerBase \ No newline at end of file diff --git a/doc/rtorrent.rc b/doc/rtorrent.rc new file mode 100644 index 00000000..94a5b51d --- /dev/null +++ b/doc/rtorrent.rc @@ -0,0 +1,31 @@ +# This is an example resource file for rTorrent. Copy to +# ~/.rtorrent.rc and enable/modify the options as needed. + +# Minumum amount of peers to connect per torrent, if available. +# min_peers = 40 + +# Minumum amount of peers to connect per torrent. +# max_peers = 100 + +# Maximum number of simultanious uploads per torrent. +# max_uploads = 15 + +# Global download rate in KiB. "0" for unlimited. +# download_rate = 0 + +# Global upload rate in KiB. "0" for unlimited. +# upload_rate = 0 + +# Default directory to save downloaded files. Note it doesn't support +# space yet. +# directory = ./ + +# The ip address reported to the tracker. +# ip = 127.0.0.1 + +# The ip address the listening socket and outgoing connections is +# bound to. +# bind = 127.0.0.1 + +# Port range to use for listening. +# port = 6890-6999 diff --git a/src/core/manager.cc b/src/core/manager.cc index f89ba489..7c82c6d3 100644 --- a/src/core/manager.cc +++ b/src/core/manager.cc @@ -124,21 +124,6 @@ Manager::stop(Download* d) { } } -void -Manager::set_dns(const std::string& dns) { - // TODO: Switch with the inet version of this thingie. - unsigned int a, b, c, d; - - if (std::sscanf(dns.c_str(), "%i.%i.%i.%i", &a, &b, &c, &d) != 4 || - (a >= 256 || b >= 256 || c >= 256 || d >= 256)) - throw std::runtime_error("Tried to set invalid ip address."); - - std::stringstream str; - str << a << '.' << b << '.' << c << '.' << d; - - m_dns = str.str(); -} - void Manager::receive_http_failed(std::string msg) { m_logImportant.push_front("Http download error: \"" + msg + "\""); @@ -180,15 +165,6 @@ Manager::create_final(std::istream* s) { void Manager::setup_download(Download* d) { - // These should be in m_defaultSettings. - d->get_download().set_ip(m_dns); - - if (!m_defaultRoot.empty()) - d->get_download().set_root_dir(m_defaultRoot + - (d->get_download().get_entry_size() > 1 ? - d->get_download().get_name() : - "")); - m_defaultSettings.for_each(d); if (m_debugTracker >= 0) diff --git a/src/core/manager.h b/src/core/manager.h index 6b025665..35fee60f 100644 --- a/src/core/manager.h +++ b/src/core/manager.h @@ -67,14 +67,9 @@ public: void start(Download* d); void stop(Download* d); - const std::string& get_dns() { return m_dns; } - void set_dns(const std::string& dns); - void set_port_range(int a, int b) { m_portFirst = a; m_portLast = b; } void set_listen_ip(const std::string& ip) { m_listenIp = ip; } - void set_default_root(const std::string& path); - void debug_tracker() { m_debugTracker = 0; } private: @@ -100,24 +95,13 @@ private: Log m_logImportant; Log m_logComplete; - std::string m_dns; int m_portFirst; int m_portLast; std::string m_listenIp; - std::string m_defaultRoot; - int m_debugTracker; }; -inline void -Manager::set_default_root(const std::string& path) { - m_defaultRoot = path; - - if (!m_defaultRoot.empty() && *m_defaultRoot.rbegin() != '/') - m_defaultRoot.push_back('/'); -} - } #endif diff --git a/src/display/window_statusbar.cc b/src/display/window_statusbar.cc index aace1efd..5f901c0a 100644 --- a/src/display/window_statusbar.cc +++ b/src/display/window_statusbar.cc @@ -56,9 +56,9 @@ WindowStatusbar::redraw() { else pos = snprintf(buf + pos, 128 - pos, "%-3i", (int)torrent::get(torrent::THROTTLE_READ_CONST_RATE) / 1024); - m_canvas->print(0, 0, "Throttle U/D: %s Listen: %s:%i Handshakes: %i", + m_canvas->print(0, 0, "Throttle U/D: %s Listen: %i Handshakes: %i", buf, - m_core->get_dns().empty() ? "" : m_core->get_dns().c_str(), + //m_core->get_dns().empty() ? "" : m_core->get_dns().c_str(), (int)torrent::get(torrent::LISTEN_PORT), (int)torrent::get(torrent::HANDSHAKES_TOTAL)); } diff --git a/src/main.cc b/src/main.cc index 3d993b7a..85e787ef 100644 --- a/src/main.cc +++ b/src/main.cc @@ -95,15 +95,16 @@ int parse_options(ui::Control* c, OptionHandler* optionHandler, int argc, char** argv) { OptionParser optionParser; + // Converted. optionParser.insert_flag('h', sigc::ptr_fun(&print_help)); optionParser.insert_flag('t', sigc::mem_fun(c->get_core(), &core::Manager::debug_tracker)); - optionParser.insert_option('b', sigc::mem_fun(c->get_core(), &core::Manager::set_listen_ip)); - optionParser.insert_option('d', sigc::mem_fun(c->get_core(), &core::Manager::set_default_root)); - optionParser.insert_option('i', sigc::mem_fun(c->get_core(), &core::Manager::set_dns)); + optionParser.insert_option('b', sigc::bind<0>(sigc::mem_fun(*optionHandler, &OptionHandler::process), "bind")); + optionParser.insert_option('d', sigc::bind<0>(sigc::mem_fun(*optionHandler, &OptionHandler::process), "directory")); + optionParser.insert_option('i', sigc::bind<0>(sigc::mem_fun(*optionHandler, &OptionHandler::process), "ip")); + optionParser.insert_option('p', sigc::bind<0>(sigc::mem_fun(*optionHandler, &OptionHandler::process), "port")); optionParser.insert_option('s', sigc::mem_fun(c->get_core().get_download_store(), &core::DownloadStore::activate)); - optionParser.insert_int_pair('p', sigc::mem_fun(c->get_core(), &core::Manager::set_port_range)); optionParser.insert_option_list('o', sigc::mem_fun(*optionHandler, &OptionHandler::process)); return optionParser.process(argc, argv); @@ -113,9 +114,18 @@ void initialize_option_handler(ui::Control* c, OptionHandler* optionHandler) { core::DownloadSlotMap* dsm = &c->get_core().get_default_settings(); - optionHandler->insert("min_peers", new OptionHandlerDownloadInt<&apply_download_min_peers, &validate_download_peers>(dsm)); - optionHandler->insert("max_peers", new OptionHandlerDownloadInt<&apply_download_max_peers, &validate_download_peers>(dsm)); - optionHandler->insert("max_uploads", new OptionHandlerDownloadInt<&apply_download_max_uploads, &validate_download_peers>(dsm)); + optionHandler->insert("min_peers", new OptionHandlerDownloadInt(dsm, &apply_download_min_peers, &validate_download_peers)); + optionHandler->insert("max_peers", new OptionHandlerDownloadInt(dsm, &apply_download_max_peers, &validate_download_peers)); + optionHandler->insert("max_uploads", new OptionHandlerDownloadInt(dsm, &apply_download_max_uploads, &validate_download_peers)); + + optionHandler->insert("download_rate", new OptionHandlerInt(c, &apply_global_download_rate, &validate_rate)); + optionHandler->insert("upload_rate", new OptionHandlerInt(c, &apply_global_upload_rate, &validate_rate)); + + optionHandler->insert("directory", new OptionHandlerDownloadString(dsm, &apply_download_directory, &validate_directory)); + optionHandler->insert("ip", new OptionHandlerDownloadString(dsm, &apply_download_ip, &validate_ip)); + + optionHandler->insert("bind", new OptionHandlerString(c, &apply_bind, &validate_ip)); + optionHandler->insert("port", new OptionHandlerString(c, &apply_port_range, &validate_port_range)); } void @@ -180,7 +190,9 @@ main(int argc, char** argv) { SignalHandler::set_handler(SIGSEGV, sigc::bind(sigc::ptr_fun(&do_panic), SIGSEGV)); SignalHandler::set_handler(SIGBUS, sigc::bind(sigc::ptr_fun(&do_panic), SIGBUS)); - load_option_file("./test_options", &optionHandler); + if (getenv("HOME")) + load_option_file(getenv("HOME") + std::string("/.rtorrent.rc"), &optionHandler); + int firstArg = parse_options(&uiControl, &optionHandler, argc, argv); initialize_display(&uiControl); @@ -265,6 +277,7 @@ print_help() { std::cout << " -p - Set port range for incoming connections" << std::endl; std::cout << " -d Save torrents to this directory by default" << std::endl; std::cout << " -s Set the session directory" << std::endl; + std::cout << " -o key=opt,... Set options, see 'rtorrent.rc' file" << std::endl; std::cout << std::endl; std::cout << "Main view keys:" << std::endl; std::cout << " backspace Add a torrent url or path" << std::endl; diff --git a/src/option_handler_rules.cc b/src/option_handler_rules.cc index 9c0df41f..64f899c7 100644 --- a/src/option_handler_rules.cc +++ b/src/option_handler_rules.cc @@ -22,13 +22,42 @@ #include "config.h" +#include +#include + +#include "ui/control.h" #include "option_handler_rules.h" +bool +validate_ip(const std::string& arg) { + struct in_addr addr; + + return inet_aton(arg.c_str(), &addr); +} + +bool +validate_directory(const std::string& arg) { + return true; +} + +bool +validate_port_range(const std::string& arg) { + int a, b; + + return std::sscanf(arg.c_str(), "%i-%i", &a, &b) == 2 && + a <= b && a > 0 && b < (1 << 16); +} + bool validate_download_peers(int arg) { return arg > 0 && arg < (1 << 16); } +bool +validate_rate(int arg) { + return arg >= 0 && arg < (1 << 24); +} + void apply_download_min_peers(core::Download* d, int arg) { d->get_download().set_peers_min(arg); @@ -43,3 +72,41 @@ void apply_download_max_uploads(core::Download* d, int arg) { d->get_download().set_uploads_max(arg); } + +void +apply_download_directory(core::Download* d, const std::string& arg) { + d->get_download().set_root_dir(arg + + (!arg.empty() && *arg.rbegin() != '/' ? "/" : "") + + (d->get_download().get_entry_size() > 1 ? d->get_download().get_name() : "")); +} + +void +apply_download_ip(core::Download* d, const std::string& arg) { + d->get_download().set_ip(arg); +} + +void +apply_global_download_rate(ui::Control* m, int arg) { + torrent::set(torrent::THROTTLE_READ_CONST_RATE, arg * 1024); +} + +void +apply_global_upload_rate(ui::Control* m, int arg) { + torrent::set(torrent::THROTTLE_ROOT_CONST_RATE, arg * 1024); +} + +void +apply_bind(ui::Control* m, const std::string& arg) { + m->get_core().set_listen_ip(arg); +} + +// The arg string *must* have been checked with validate_port_range +// first. +void +apply_port_range(ui::Control* m, const std::string& arg) { + int a = 0, b = 0; + + std::sscanf(arg.c_str(), "%i-%i", &a, &b); + + m->get_core().set_port_range(a, b); +} diff --git a/src/option_handler_rules.h b/src/option_handler_rules.h index 0123748c..02a15798 100644 --- a/src/option_handler_rules.h +++ b/src/option_handler_rules.h @@ -30,29 +30,118 @@ #include "option_handler.h" #include "core/download_slot_map.h" +namespace ui { + class Control; +} + +bool validate_ip(const std::string& arg); +bool validate_directory(const std::string& arg); +bool validate_port_range(const std::string& arg); + bool validate_download_peers(int arg); +bool validate_rate(int arg); void apply_download_min_peers(core::Download* d, int arg); void apply_download_max_peers(core::Download* d, int arg); void apply_download_max_uploads(core::Download* d, int arg); -template +void apply_download_directory(core::Download* d, const std::string& arg); +void apply_download_ip(core::Download* d, const std::string& arg); + +void apply_global_download_rate(ui::Control* m, int arg); +void apply_global_upload_rate(ui::Control* m, int arg); + +void apply_bind(ui::Control* m, const std::string& arg); +void apply_port_range(ui::Control* m, const std::string& arg); + class OptionHandlerDownloadInt : public OptionHandlerBase { public: - OptionHandlerDownloadInt(core::DownloadSlotMap* m) : m_map(m) {} + typedef void (*Apply)(core::Download*, int); + typedef bool (*Validate)(int); + + OptionHandlerDownloadInt(core::DownloadSlotMap* m, Apply a, Validate v) : + m_map(m), m_apply(a), m_validate(v) {} virtual void process(const std::string& key, const std::string& arg) { int a; if (std::sscanf(arg.c_str(), "%i", &a) != 1 || - !Validate(a)) + !m_validate(a)) throw std::runtime_error("Invalid argument for \"" + key + "\": \"" + arg + "\""); - (*m_map)[key] = sigc::bind(sigc::ptr_fun(Apply), a); + (*m_map)[key] = sigc::bind(sigc::ptr_fun(m_apply), a); } private: core::DownloadSlotMap* m_map; + Apply m_apply; + Validate m_validate; +}; + +class OptionHandlerString : public OptionHandlerBase { +public: + typedef bool (*Validate)(const std::string&); + typedef void (*Apply)(ui::Control*, const std::string&); + + OptionHandlerString(ui::Control* c, Apply a, Validate v) : + m_control(c), m_apply(a), m_validate(v) {} + + virtual void process(const std::string& key, const std::string& arg) { + if (!m_validate(arg)) + throw std::runtime_error("Invalid argument for \"" + key + "\": \"" + arg + "\""); + + m_apply(m_control, arg); + } + +private: + ui::Control* m_control; + Apply m_apply; + Validate m_validate; +}; + +class OptionHandlerInt : public OptionHandlerBase { +public: + typedef bool (*Validate)(int); + typedef void (*Apply)(ui::Control*, int); + + OptionHandlerInt(ui::Control* c, Apply a, Validate v) : + m_control(c), m_apply(a), m_validate(v) {} + + virtual void process(const std::string& key, const std::string& arg) { + int a; + + if (std::sscanf(arg.c_str(), "%i", &a) != 1 || + !m_validate(a)) + throw std::runtime_error("Invalid argument for \"" + key + "\": \"" + arg + "\""); + + m_apply(m_control, a); + } + +private: + ui::Control* m_control; + Apply m_apply; + Validate m_validate; +}; + +class OptionHandlerDownloadString : public OptionHandlerBase { +public: + typedef void (*Apply)(core::Download*, const std::string&); + typedef bool (*Validate)(const std::string&); + + OptionHandlerDownloadString(core::DownloadSlotMap* m, Apply a, Validate v) : + m_map(m), m_apply(a), m_validate(v) {} + + virtual void process(const std::string& key, const std::string& arg) { + if (!m_validate(arg)) + throw std::runtime_error("Invalid argument for \"" + key + "\": \"" + arg + "\""); + + (*m_map)[key] = sigc::bind(sigc::ptr_fun(m_apply), arg); + } + +private: + core::DownloadSlotMap* m_map; + Apply m_apply; + Validate m_validate; }; #endif