mirror of
https://github.com/rakshasa/rtorrent.git
synced 2026-08-10 12:12:31 +00:00
* Set SO_REUSEADDR for the listening socket.
* Moved several settings to use the new variables and made the parser better. * Use "-O2" rather than "-O3". git-svn-id: svn://rakshasa.no/libtorrent/trunk/rtorrent@623 e378c898-3ddf-0310-93e7-cc216c733640
This commit is contained in:
+1
-1
@@ -5,7 +5,7 @@ AC_DEFUN([TORRENT_CHECK_CXXFLAGS], [
|
||||
if test -n "$CXXFLAGS"; then
|
||||
AC_MSG_RESULT([user-defined "$CXXFLAGS"])
|
||||
else
|
||||
CXXFLAGS="-O3 -Wall"
|
||||
CXXFLAGS="-O2 -Wall"
|
||||
AC_MSG_RESULT([default "$CXXFLAGS"])
|
||||
fi
|
||||
])
|
||||
|
||||
+2
-2
@@ -38,10 +38,10 @@
|
||||
#define RTORRENT_CONTROL_H
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <rak/timer.h>
|
||||
#include <rak/priority_queue_default.h>
|
||||
#include <torrent/torrent.h>
|
||||
|
||||
#include "globals.h"
|
||||
|
||||
namespace ui {
|
||||
class Root;
|
||||
}
|
||||
|
||||
+7
-5
@@ -50,6 +50,9 @@
|
||||
#include <torrent/bencode.h>
|
||||
#include <torrent/exceptions.h>
|
||||
|
||||
#include "utils/variable_map.h"
|
||||
|
||||
#include "globals.h"
|
||||
#include "curl_get.h"
|
||||
#include "download.h"
|
||||
#include "download_factory.h"
|
||||
@@ -85,10 +88,8 @@ delete_tied(Download* d) {
|
||||
|
||||
Manager::Manager() :
|
||||
m_pollManager(NULL),
|
||||
m_portRandom(false),
|
||||
m_portFirst(6890),
|
||||
m_portLast(6999),
|
||||
m_checkHash(true) {
|
||||
m_portLast(6999) {
|
||||
}
|
||||
|
||||
void
|
||||
@@ -245,7 +246,7 @@ Manager::check_hash(Download* d) {
|
||||
|
||||
void
|
||||
Manager::receive_download_done(Download* d) {
|
||||
if (m_checkHash) {
|
||||
if (control->variables()->get("check_hash").as_string() == "yes") {
|
||||
// Start the hash checking, send completed to tracker after
|
||||
// finishing.
|
||||
prepare_hash_check(d);
|
||||
@@ -263,7 +264,7 @@ Manager::listen_open() {
|
||||
if (m_portFirst > m_portLast)
|
||||
throw torrent::input_error("Invalid port range for listening");
|
||||
|
||||
if (m_portRandom) {
|
||||
if (control->variables()->get("port_random").as_string() == "yes") {
|
||||
int boundary = m_portFirst + random() % (m_portLast - m_portFirst + 1);
|
||||
|
||||
if (!torrent::listen_open(boundary, m_portLast) &&
|
||||
@@ -273,6 +274,7 @@ Manager::listen_open() {
|
||||
} else {
|
||||
if (!torrent::listen_open(m_portFirst, m_portLast))
|
||||
throw torrent::input_error("Could not open/bind a port for listening.");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -69,11 +69,8 @@ public:
|
||||
Log& get_log_important() { return m_logImportant; }
|
||||
Log& get_log_complete() { return m_logComplete; }
|
||||
|
||||
void set_port_random(bool v) { m_portRandom = v; }
|
||||
void set_port_range(int a, int b) { m_portFirst = a; m_portLast = b; }
|
||||
|
||||
void set_check_hash(bool state) { m_checkHash = state; }
|
||||
|
||||
// Really should find a more descriptive name.
|
||||
void initialize_first();
|
||||
void initialize_second();
|
||||
@@ -121,11 +118,8 @@ private:
|
||||
Log m_logImportant;
|
||||
Log m_logComplete;
|
||||
|
||||
bool m_portRandom;
|
||||
int m_portFirst;
|
||||
int m_portLast;
|
||||
|
||||
bool m_checkHash;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -121,30 +121,31 @@ print_download_info(char* buf, unsigned int length, core::Download* d) {
|
||||
(double)d->get_download().down_rate()->rate() / (1 << 10),
|
||||
(double)d->get_download().up_rate()->total() / (1 << 20)), 0);
|
||||
|
||||
//buf += std::max(0, snprintf(buf, length, " Left: "));
|
||||
buf = print_download_time_left(buf, length, d);
|
||||
buf = print_download_time_left(buf, last - buf, d);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
char*
|
||||
print_download_status(char* buf, unsigned int length, core::Download* d) {
|
||||
char* last = buf + length;
|
||||
|
||||
if (!d->get_download().is_active())
|
||||
buf += std::max(snprintf(buf, length, "Inactive: "), 0);
|
||||
buf += std::max(snprintf(buf, last - buf, "Inactive: "), 0);
|
||||
|
||||
if (d->get_download().is_hash_checking())
|
||||
buf += std::max(snprintf(buf, length, "Checking hash [%2i%%]",
|
||||
buf += std::max(snprintf(buf, last - buf, "Checking hash [%2i%%]",
|
||||
(d->get_download().chunks_hashed() * 100) / d->get_download().chunks_total()), 0);
|
||||
|
||||
else if (d->get_download().is_tracker_busy() &&
|
||||
d->get_download().tracker_focus() < d->get_download().size_trackers())
|
||||
buf += std::max(snprintf(buf, length, "Tracker[%i:%i]: Connecting to %s",
|
||||
buf += std::max(snprintf(buf, last - buf, "Tracker[%i:%i]: Connecting to %s",
|
||||
d->get_download().tracker(d->get_download().tracker_focus()).group(),
|
||||
d->get_download().tracker_focus(),
|
||||
d->get_download().tracker(d->get_download().tracker_focus()).url().c_str()), 0);
|
||||
|
||||
else if (!d->get_message().empty())
|
||||
buf += std::max(snprintf(buf, length, "%s", d->get_message().c_str()), 0);
|
||||
buf += std::max(snprintf(buf, last - buf, "%s", d->get_message().c_str()), 0);
|
||||
|
||||
else
|
||||
buf[0] = '\0';
|
||||
|
||||
@@ -120,7 +120,7 @@ WindowFileList::redraw() {
|
||||
|
||||
m_canvas->print(84, pos, "%i - %i",
|
||||
e.chunk_begin(),
|
||||
e.chunk_end());
|
||||
e.chunk_begin() != e.chunk_end() ? (e.chunk_end() - 1) : e.chunk_end());
|
||||
|
||||
++range.first;
|
||||
++pos;
|
||||
|
||||
@@ -40,3 +40,5 @@
|
||||
|
||||
rak::priority_queue_default taskScheduler;
|
||||
rak::timer cachedTime;
|
||||
|
||||
Control* control = NULL;
|
||||
|
||||
@@ -40,7 +40,11 @@
|
||||
#include <rak/timer.h>
|
||||
#include <rak/priority_queue_default.h>
|
||||
|
||||
#include "control.h"
|
||||
|
||||
extern rak::priority_queue_default taskScheduler;
|
||||
extern rak::timer cachedTime;
|
||||
|
||||
extern Control* control;
|
||||
|
||||
#endif
|
||||
|
||||
+18
-14
@@ -159,12 +159,12 @@ main(int argc, char** argv) {
|
||||
|
||||
cachedTime = rak::timer::current();
|
||||
|
||||
Control control;
|
||||
control = new Control;
|
||||
|
||||
srandom(cachedTime.usec());
|
||||
srand48(cachedTime.usec());
|
||||
|
||||
initialize_option_handler(&control);
|
||||
initialize_option_handler(control);
|
||||
|
||||
SignalHandler::set_ignore(SIGPIPE);
|
||||
SignalHandler::set_handler(SIGINT, sigc::mem_fun(control, &Control::receive_shutdown));
|
||||
@@ -172,17 +172,17 @@ main(int argc, char** argv) {
|
||||
SignalHandler::set_handler(SIGBUS, sigc::bind(sigc::ptr_fun(&do_panic), SIGBUS));
|
||||
SignalHandler::set_handler(SIGFPE, sigc::bind(sigc::ptr_fun(&do_panic), SIGFPE));
|
||||
|
||||
control.core()->initialize_first();
|
||||
control->core()->initialize_first();
|
||||
|
||||
OptionFile optionFile;
|
||||
optionFile.slot_option(sigc::mem_fun(control.variables(), &utils::VariableMap::set));
|
||||
optionFile.slot_option(sigc::mem_fun(control->variables(), &utils::VariableMap::process_command));
|
||||
|
||||
if (getenv("HOME") && !optionFile.process_file(getenv("HOME") + std::string("/.rtorrent.rc")))
|
||||
control.core()->get_log_important().push_front("Could not load \"~/.rtorrent.rc\".");
|
||||
control->core()->get_log_important().push_front("Could not load \"~/.rtorrent.rc\".");
|
||||
|
||||
int firstArg = parse_options(&control, control.variables(), argc, argv);
|
||||
int firstArg = parse_options(control, control->variables(), argc, argv);
|
||||
|
||||
control.initialize();
|
||||
control->initialize();
|
||||
|
||||
// Just to make sure we did all the stuff on the queue before
|
||||
// loading any torrents.
|
||||
@@ -192,38 +192,42 @@ main(int argc, char** argv) {
|
||||
|
||||
// Load session torrents and perform scheduled tasks to ensure
|
||||
// session torrents are loaded before arg torrents.
|
||||
load_session_torrents(&control);
|
||||
load_session_torrents(control);
|
||||
rak::priority_queue_perform(&taskScheduler, cachedTime);
|
||||
|
||||
load_arg_torrents(&control, argv + firstArg, argv + argc);
|
||||
load_arg_torrents(control, argv + firstArg, argv + argc);
|
||||
|
||||
control.display()->adjust_layout();
|
||||
control->display()->adjust_layout();
|
||||
|
||||
while (!control.is_shutdown_completed()) {
|
||||
control.inc_tick();
|
||||
while (!control->is_shutdown_completed()) {
|
||||
control->inc_tick();
|
||||
|
||||
cachedTime = rak::timer::current();
|
||||
rak::priority_queue_perform(&taskScheduler, cachedTime);
|
||||
|
||||
// Do shutdown check before poll, not after.
|
||||
control.core()->get_poll_manager()->poll(client_next_timeout());
|
||||
control->core()->get_poll_manager()->poll(client_next_timeout());
|
||||
}
|
||||
|
||||
control.cleanup();
|
||||
control->cleanup();
|
||||
|
||||
} catch (torrent::base_error& e) {
|
||||
display::Canvas::cleanup();
|
||||
delete control;
|
||||
|
||||
std::cout << "Caught exception: " << e.what() << std::endl;
|
||||
return -1;
|
||||
|
||||
} catch (std::exception& e) {
|
||||
display::Canvas::cleanup();
|
||||
delete control;
|
||||
|
||||
std::cout << e.what() << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
delete control;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
+19
-19
@@ -57,7 +57,7 @@ OptionFile::process_file(const std::string& filename) {
|
||||
|
||||
while (file.getline(buffer, max_size_line).good()) {
|
||||
lineNumber++;
|
||||
parse_line(buffer);
|
||||
m_slotOption(buffer);
|
||||
}
|
||||
|
||||
} catch (torrent::input_error& e) {
|
||||
@@ -69,28 +69,28 @@ OptionFile::process_file(const std::string& filename) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
OptionFile::parse_line(const char* line) {
|
||||
// void
|
||||
// OptionFile::parse_line(const char* line) {
|
||||
//const char* last = std::find(line, line + max_size_line, '\0');
|
||||
|
||||
if (line[0] == '#')
|
||||
return;
|
||||
// if (line[0] == '#')
|
||||
// return;
|
||||
|
||||
int result;
|
||||
char key[64];
|
||||
char opt[512];
|
||||
// int result;
|
||||
// char key[64];
|
||||
// char opt[512];
|
||||
|
||||
opt[0] = '\0';
|
||||
// opt[0] = '\0';
|
||||
|
||||
// Check for empty lines, and options within "abc".
|
||||
if ((result = std::sscanf(line, "%63s = \"%511[^\"]", key, opt)) != 2 &&
|
||||
(result = std::sscanf(line, "%63s = %511s", key, opt)) != 2 &&
|
||||
result == 1)
|
||||
throw torrent::input_error("Error parseing option file.");
|
||||
// // Check for empty lines, and options within "abc".
|
||||
// if ((result = std::sscanf(line, "%63s = \"%511[^\"]", key, opt)) != 2 &&
|
||||
// (result = std::sscanf(line, "%63s = %511s", key, opt)) != 2 &&
|
||||
// result == 1)
|
||||
// throw torrent::input_error("Error parseing option file.");
|
||||
|
||||
if (opt[0] == '"' && opt[1] == '"')
|
||||
opt[0] = '\0';
|
||||
// if (opt[0] == '"' && opt[1] == '"')
|
||||
// opt[0] = '\0';
|
||||
|
||||
if (result >= 1)
|
||||
m_slotOption(key, opt);
|
||||
}
|
||||
// if (result >= 1)
|
||||
// m_slotOption(key, opt);
|
||||
// }
|
||||
|
||||
+1
-1
@@ -46,7 +46,7 @@ public:
|
||||
static const int max_size_opt = 1024;
|
||||
static const int max_size_line = max_size_key + max_size_opt + 64;
|
||||
|
||||
typedef sigc::slot2<void, const std::string&, const std::string&> SlotStringPair;
|
||||
typedef sigc::slot1<void, const std::string&> SlotStringPair;
|
||||
|
||||
// Returns false when the file doesn't exist or cannot be opened.
|
||||
bool process_file(const std::string& filename);
|
||||
|
||||
+36
-43
@@ -55,6 +55,7 @@
|
||||
#include "utils/variable_generic.h"
|
||||
#include "utils/variable_map.h"
|
||||
|
||||
#include "globals.h"
|
||||
#include "control.h"
|
||||
#include "option_handler_rules.h"
|
||||
#include "command_scheduler.h"
|
||||
@@ -178,11 +179,6 @@ apply_port_range(Control* m, const std::string& arg) {
|
||||
m->core()->set_port_range(a, b);
|
||||
}
|
||||
|
||||
void
|
||||
apply_port_random(Control* m, const std::string& arg) {
|
||||
m->core()->set_port_random(arg == "yes");
|
||||
}
|
||||
|
||||
void
|
||||
apply_tracker_dump(Control* m, const std::string& arg) {
|
||||
if (arg == "yes")
|
||||
@@ -199,14 +195,6 @@ apply_use_udp_trackers(Control* m, const std::string& arg) {
|
||||
m->core()->get_download_list().slot_map_insert()["1_use_udp_trackers"] = sigc::bind(sigc::mem_fun(&core::Download::enable_udp_trackers), false);
|
||||
}
|
||||
|
||||
void
|
||||
apply_check_hash(Control* m, const std::string& arg) {
|
||||
if (arg == "yes")
|
||||
m->core()->set_check_hash(true);
|
||||
else
|
||||
m->core()->set_check_hash(false);
|
||||
}
|
||||
|
||||
void
|
||||
apply_http_proxy(Control* m, const std::string& arg) {
|
||||
m->core()->get_poll_manager()->get_http_stack()->set_http_proxy(arg);
|
||||
@@ -299,44 +287,49 @@ apply_schedule_remove(Control* m, const std::string& arg) {
|
||||
|
||||
void
|
||||
initialize_option_handler(Control* c) {
|
||||
c->variables()->insert("bind", new utils::VariableSlotString<>(NULL, rak::mem_fn(c->core(), &core::Manager::bind)));
|
||||
utils::VariableMap* variables = control->variables();
|
||||
|
||||
c->variables()->insert("ip", new utils::VariableSlotString<>(NULL, rak::bind_ptr_fn(&apply_ip, c)));
|
||||
c->variables()->insert("port_range", new utils::VariableSlotString<>(NULL, rak::bind_ptr_fn(&apply_port_range, c)));
|
||||
c->variables()->insert("port_random", new utils::VariableSlotString<>(NULL, rak::bind_ptr_fn(&apply_port_random, c)));
|
||||
// Cleaned up.
|
||||
variables->insert("check_hash", new utils::VariableValue("yes"));
|
||||
variables->insert("port_random", new utils::VariableValue("yes"));
|
||||
variables->insert("session", new utils::VariableSlotString<>(NULL, rak::mem_fn(&control->core()->get_download_store(), &core::DownloadStore::use)));
|
||||
|
||||
c->variables()->insert("check_hash", new utils::VariableSlotString<>(NULL, rak::bind_ptr_fn(&apply_check_hash, c)));
|
||||
c->variables()->insert("directory", new utils::VariableSlotString<>(NULL, rak::bind_ptr_fn(&apply_download_directory, c)));
|
||||
// Old.
|
||||
variables->insert("bind", new utils::VariableSlotString<>(NULL, rak::mem_fn(control->core(), &core::Manager::bind)));
|
||||
|
||||
c->variables()->insert("max_peers", new utils::VariableSlotValue<int, int>(NULL, rak::bind_ptr_fn(&apply_download_max_peers, c), "%i"));
|
||||
c->variables()->insert("min_peers", new utils::VariableSlotValue<int, int>(NULL, rak::bind_ptr_fn(&apply_download_min_peers, c), "%i"));
|
||||
c->variables()->insert("max_uploads", new utils::VariableSlotValue<int, int>(NULL, rak::bind_ptr_fn(&apply_download_max_uploads, c), "%i"));
|
||||
variables->insert("ip", new utils::VariableSlotString<>(NULL, rak::bind_ptr_fn(&apply_ip, c)));
|
||||
variables->insert("port_range", new utils::VariableSlotString<>(NULL, rak::bind_ptr_fn(&apply_port_range, c)));
|
||||
|
||||
c->variables()->insert("download_rate", new utils::VariableSlotValue<int, int>(NULL, rak::bind_ptr_fn(&apply_global_download_rate, c), "%i"));
|
||||
c->variables()->insert("upload_rate", new utils::VariableSlotValue<int, int>(NULL, rak::bind_ptr_fn(&apply_global_upload_rate, c), "%i"));
|
||||
variables->insert("directory", new utils::VariableSlotString<>(NULL, rak::bind_ptr_fn(&apply_download_directory, c)));
|
||||
|
||||
c->variables()->insert("hash_read_ahead", new utils::VariableSlotValue<int, int>(NULL, rak::bind_ptr_fn(&apply_hash_read_ahead, c), "%i"));
|
||||
c->variables()->insert("hash_interval", new utils::VariableSlotValue<int, int>(NULL, rak::bind_ptr_fn(&apply_hash_interval, c), "%i"));
|
||||
c->variables()->insert("hash_max_tries", new utils::VariableSlotValue<int, int>(NULL, rak::bind_ptr_fn(&apply_hash_max_tries, c), "%i"));
|
||||
c->variables()->insert("max_open_files", new utils::VariableSlotValue<int, int>(NULL, rak::bind_ptr_fn(&apply_max_open_files, c), "%i"));
|
||||
c->variables()->insert("max_open_sockets", new utils::VariableSlotValue<int, int>(NULL, rak::bind_ptr_fn(&apply_max_open_sockets, c), "%i"));
|
||||
variables->insert("max_peers", new utils::VariableSlotValue<int, int>(NULL, rak::bind_ptr_fn(&apply_download_max_peers, c), "%i"));
|
||||
variables->insert("min_peers", new utils::VariableSlotValue<int, int>(NULL, rak::bind_ptr_fn(&apply_download_min_peers, c), "%i"));
|
||||
variables->insert("max_uploads", new utils::VariableSlotValue<int, int>(NULL, rak::bind_ptr_fn(&apply_download_max_uploads, c), "%i"));
|
||||
|
||||
c->variables()->insert("umask", new utils::VariableSlotValue<int, int>(NULL, rak::bind_ptr_fn(&apply_umask, c), "%o"));
|
||||
variables->insert("download_rate", new utils::VariableSlotValue<int, int>(NULL, rak::bind_ptr_fn(&apply_global_download_rate, c), "%i"));
|
||||
variables->insert("upload_rate", new utils::VariableSlotValue<int, int>(NULL, rak::bind_ptr_fn(&apply_global_upload_rate, c), "%i"));
|
||||
|
||||
c->variables()->insert("connection_leech", new utils::VariableSlotString<>(NULL, rak::bind_ptr_fn(&apply_connection_leech, c)));
|
||||
c->variables()->insert("connection_seed", new utils::VariableSlotString<>(NULL, rak::bind_ptr_fn(&apply_connection_seed, c)));
|
||||
variables->insert("hash_read_ahead", new utils::VariableSlotValue<int, int>(NULL, rak::bind_ptr_fn(&apply_hash_read_ahead, c), "%i"));
|
||||
variables->insert("hash_interval", new utils::VariableSlotValue<int, int>(NULL, rak::bind_ptr_fn(&apply_hash_interval, c), "%i"));
|
||||
variables->insert("hash_max_tries", new utils::VariableSlotValue<int, int>(NULL, rak::bind_ptr_fn(&apply_hash_max_tries, c), "%i"));
|
||||
variables->insert("max_open_files", new utils::VariableSlotValue<int, int>(NULL, rak::bind_ptr_fn(&apply_max_open_files, c), "%i"));
|
||||
variables->insert("max_open_sockets", new utils::VariableSlotValue<int, int>(NULL, rak::bind_ptr_fn(&apply_max_open_sockets, c), "%i"));
|
||||
|
||||
c->variables()->insert("load", new utils::VariableSlotString<>(NULL, rak::bind_ptr_fn(&apply_load, c)));
|
||||
c->variables()->insert("load_start", new utils::VariableSlotString<>(NULL, rak::bind_ptr_fn(&apply_load_start, c)));
|
||||
c->variables()->insert("stop_untied", new utils::VariableSlotString<>(NULL, rak::bind_ptr_fn(&apply_stop_untied, c)));
|
||||
c->variables()->insert("remove_untied", new utils::VariableSlotString<>(NULL, rak::bind_ptr_fn(&apply_remove_untied, c)));
|
||||
variables->insert("umask", new utils::VariableSlotValue<int, int>(NULL, rak::bind_ptr_fn(&apply_umask, c), "%o"));
|
||||
|
||||
c->variables()->insert("session", new utils::VariableSlotString<>(NULL, rak::bind_ptr_fn(&apply_session_directory, c)));
|
||||
c->variables()->insert("encoding_list", new utils::VariableSlotString<>(NULL, rak::bind_ptr_fn(&apply_encoding_list, c)));
|
||||
c->variables()->insert("tracker_dump", new utils::VariableSlotString<>(NULL, rak::bind_ptr_fn(&apply_tracker_dump, c)));
|
||||
c->variables()->insert("use_udp_trackers", new utils::VariableSlotString<>(NULL, rak::bind_ptr_fn(&apply_use_udp_trackers, c)));
|
||||
variables->insert("connection_leech", new utils::VariableSlotString<>(NULL, rak::bind_ptr_fn(&apply_connection_leech, c)));
|
||||
variables->insert("connection_seed", new utils::VariableSlotString<>(NULL, rak::bind_ptr_fn(&apply_connection_seed, c)));
|
||||
|
||||
c->variables()->insert("http_proxy", new utils::VariableSlotString<>(NULL, rak::bind_ptr_fn(&apply_http_proxy, c)));
|
||||
c->variables()->insert("schedule", new utils::VariableSlotString<>(NULL, rak::bind_ptr_fn(&apply_schedule, c)));
|
||||
c->variables()->insert("schedule_remove", new utils::VariableSlotString<>(NULL, rak::bind_ptr_fn(&apply_schedule_remove, c)));
|
||||
variables->insert("load", new utils::VariableSlotString<>(NULL, rak::bind_ptr_fn(&apply_load, c)));
|
||||
variables->insert("load_start", new utils::VariableSlotString<>(NULL, rak::bind_ptr_fn(&apply_load_start, c)));
|
||||
variables->insert("stop_untied", new utils::VariableSlotString<>(NULL, rak::bind_ptr_fn(&apply_stop_untied, c)));
|
||||
variables->insert("remove_untied", new utils::VariableSlotString<>(NULL, rak::bind_ptr_fn(&apply_remove_untied, c)));
|
||||
|
||||
variables->insert("encoding_list", new utils::VariableSlotString<>(NULL, rak::bind_ptr_fn(&apply_encoding_list, c)));
|
||||
variables->insert("tracker_dump", new utils::VariableSlotString<>(NULL, rak::bind_ptr_fn(&apply_tracker_dump, c)));
|
||||
variables->insert("use_udp_trackers", new utils::VariableSlotString<>(NULL, rak::bind_ptr_fn(&apply_use_udp_trackers, c)));
|
||||
|
||||
variables->insert("http_proxy", new utils::VariableSlotString<>(NULL, rak::bind_ptr_fn(&apply_http_proxy, c)));
|
||||
variables->insert("schedule", new utils::VariableSlotString<>(NULL, rak::bind_ptr_fn(&apply_schedule, c)));
|
||||
variables->insert("schedule_remove", new utils::VariableSlotString<>(NULL, rak::bind_ptr_fn(&apply_schedule_remove, c)));
|
||||
}
|
||||
|
||||
@@ -40,17 +40,17 @@
|
||||
|
||||
namespace utils {
|
||||
|
||||
// VariableString::~VariableString() {
|
||||
// }
|
||||
VariableValue::~VariableValue() {
|
||||
}
|
||||
|
||||
// std::string
|
||||
// VariableString::get() {
|
||||
// return m_variable;
|
||||
// }
|
||||
const torrent::Bencode&
|
||||
VariableValue::get() {
|
||||
return m_variable;
|
||||
}
|
||||
|
||||
// void
|
||||
// VariableString::set(const std::string& arg) {
|
||||
// m_variable = arg;
|
||||
// }
|
||||
void
|
||||
VariableValue::set(const torrent::Bencode& arg) {
|
||||
m_variable = arg;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
|
||||
#include <cstdio>
|
||||
#include <string>
|
||||
#include <limits>
|
||||
#include <inttypes.h>
|
||||
#include <rak/functional_fun.h>
|
||||
#include <torrent/bencode.h>
|
||||
@@ -48,19 +49,18 @@
|
||||
|
||||
namespace utils {
|
||||
|
||||
// class VariableS : public Variable {
|
||||
// public:
|
||||
// VariableString(const std::string& v = "") : m_variable(v) {}
|
||||
// virtual ~VariableString();
|
||||
class VariableValue : public Variable {
|
||||
public:
|
||||
VariableValue(const torrent::Bencode& v = torrent::Bencode()) : m_variable(v) {}
|
||||
virtual ~VariableValue();
|
||||
|
||||
// virtual const torrent::Bencode& get();
|
||||
// virtual void set(const torrent::Bencode& arg);
|
||||
virtual const torrent::Bencode& get();
|
||||
virtual void set(const torrent::Bencode& arg);
|
||||
|
||||
// private:
|
||||
// std::string m_variable;
|
||||
// };
|
||||
private:
|
||||
torrent::Bencode m_variable;
|
||||
};
|
||||
|
||||
// VariableSlot?
|
||||
template <typename Get = std::string, typename Set = const std::string&>
|
||||
class VariableSlotString : public Variable {
|
||||
public:
|
||||
@@ -84,10 +84,16 @@ public:
|
||||
}
|
||||
|
||||
virtual void set(const torrent::Bencode& arg) {
|
||||
if (!arg.is_string())
|
||||
switch (arg.get_type()) {
|
||||
case torrent::Bencode::TYPE_STRING:
|
||||
m_slotSet(arg.as_string());
|
||||
break;
|
||||
case torrent::Bencode::TYPE_NONE:
|
||||
m_slotSet("");
|
||||
break;
|
||||
default:
|
||||
throw torrent::internal_error("VariableSlotString::set(...) got wrong type.");
|
||||
|
||||
m_slotSet(arg.as_string());
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -103,15 +109,19 @@ private:
|
||||
template <typename Get, typename Set>
|
||||
class VariableSlotValue : public Variable {
|
||||
public:
|
||||
typedef rak::function0<Get> SlotGet;
|
||||
typedef rak::function1<void, Set> SlotSet;
|
||||
typedef rak::function0<Get> SlotGet;
|
||||
typedef rak::function1<void, Set> SlotSet;
|
||||
typedef std::pair<int64_t, int64_t> Range;
|
||||
|
||||
VariableSlotValue(typename SlotGet::base_type* slotGet,
|
||||
typename SlotSet::base_type* slotSet,
|
||||
const char* pattern) {
|
||||
const char* pattern,
|
||||
Range range = Range(std::numeric_limits<int64_t>::min(),
|
||||
std::numeric_limits<int64_t>::max())) {
|
||||
m_slotGet.set(slotGet);
|
||||
m_slotSet.set(slotSet);
|
||||
m_pattern = pattern;
|
||||
m_range = range;
|
||||
}
|
||||
|
||||
virtual ~VariableSlotValue() {}
|
||||
@@ -148,6 +158,7 @@ private:
|
||||
SlotSet m_slotSet;
|
||||
|
||||
const char* m_pattern;
|
||||
Range m_range;
|
||||
|
||||
// Store the cache here to avoid unnessesary copying and such. This
|
||||
// should not result in any unresonable memory usage since few
|
||||
|
||||
@@ -82,16 +82,83 @@ VariableMap::set(const std::string& key, const torrent::Bencode& arg) {
|
||||
itr->second->set(arg);
|
||||
}
|
||||
|
||||
std::string::const_iterator
|
||||
parse_name(std::string::const_iterator first, std::string::const_iterator last, std::string* dest) {
|
||||
if (first == last || !std::isalpha(*first))
|
||||
throw torrent::input_error("Invalid start of name.");
|
||||
|
||||
for ( ; first != last && (std::isalnum(*first) || *first == '_'); ++first)
|
||||
dest->push_back(*first);
|
||||
|
||||
return first;
|
||||
}
|
||||
|
||||
std::string::const_iterator
|
||||
parse_unknown(std::string::const_iterator first, std::string::const_iterator last, torrent::Bencode* dest) {
|
||||
if (*first == '"') {
|
||||
std::string::const_iterator next = std::find_if(++first, last, std::bind2nd(std::equal_to<char>(), '"'));
|
||||
|
||||
if (first == last ||
|
||||
first == next ||
|
||||
next == last)
|
||||
throw torrent::input_error("Could not find closing '\"'.");
|
||||
|
||||
*dest = std::string(first, next);
|
||||
return ++next;
|
||||
|
||||
} else {
|
||||
// Add rak::or and check for ','.
|
||||
std::string::const_iterator next = std::find_if(first, last, std::ptr_fun(&std::isspace));
|
||||
|
||||
*dest = std::string(first, next);
|
||||
return next;
|
||||
}
|
||||
}
|
||||
|
||||
std::string::const_iterator
|
||||
parse_args(std::string::const_iterator first, std::string::const_iterator last, torrent::Bencode::List* dest) {
|
||||
first = std::find_if(first, last, std::not1(std::ptr_fun(&std::isspace)));
|
||||
|
||||
while (first != last) {
|
||||
dest->push_back(torrent::Bencode());
|
||||
|
||||
first = parse_unknown(first, last, &dest->back());
|
||||
first = std::find_if(first, last, std::not1(std::ptr_fun(&std::isspace)));
|
||||
|
||||
if (first != last && *first != ',')
|
||||
throw torrent::input_error("A string with blanks must be quoted.");
|
||||
}
|
||||
|
||||
return first;
|
||||
}
|
||||
|
||||
void
|
||||
VariableMap::process_command(const std::string& command) {
|
||||
std::string::size_type pos = command.find('=');
|
||||
std::string::const_iterator pos = command.begin();
|
||||
pos = std::find_if(pos, command.end(), std::not1(std::ptr_fun(&std::isspace)));
|
||||
|
||||
if (pos == std::string::npos)
|
||||
throw torrent::input_error("Option handler could not find '=' in command.");
|
||||
if (pos == command.end() || *pos == '#')
|
||||
return;
|
||||
|
||||
// Do sscanf, check for integer. Later move and make it smarter.
|
||||
// Replace with parse_unknown?
|
||||
std::string key;
|
||||
pos = parse_name(pos, command.end(), &key);
|
||||
pos = std::find_if(pos, command.end(), std::not1(std::ptr_fun(&std::isspace)));
|
||||
|
||||
if (pos == command.end() || *pos != '=')
|
||||
throw torrent::input_error("Could not find '='.");
|
||||
|
||||
set(command.substr(0, pos), torrent::Bencode(command.substr(pos + 1, std::string::npos)));
|
||||
torrent::Bencode args(torrent::Bencode::TYPE_LIST);
|
||||
parse_args(pos + 1, command.end(), &args.as_list());
|
||||
|
||||
if (args.as_list().empty())
|
||||
set(key, torrent::Bencode());
|
||||
|
||||
else if (++args.as_list().begin() == args.as_list().end())
|
||||
set(key, *args.as_list().begin());
|
||||
|
||||
else
|
||||
set(key, args);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user