mirror of
https://github.com/rakshasa/rtorrent.git
synced 2026-10-22 00:56:18 +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
|
if test -n "$CXXFLAGS"; then
|
||||||
AC_MSG_RESULT([user-defined "$CXXFLAGS"])
|
AC_MSG_RESULT([user-defined "$CXXFLAGS"])
|
||||||
else
|
else
|
||||||
CXXFLAGS="-O3 -Wall"
|
CXXFLAGS="-O2 -Wall"
|
||||||
AC_MSG_RESULT([default "$CXXFLAGS"])
|
AC_MSG_RESULT([default "$CXXFLAGS"])
|
||||||
fi
|
fi
|
||||||
])
|
])
|
||||||
|
|||||||
+2
-2
@@ -38,10 +38,10 @@
|
|||||||
#define RTORRENT_CONTROL_H
|
#define RTORRENT_CONTROL_H
|
||||||
|
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
|
#include <rak/timer.h>
|
||||||
|
#include <rak/priority_queue_default.h>
|
||||||
#include <torrent/torrent.h>
|
#include <torrent/torrent.h>
|
||||||
|
|
||||||
#include "globals.h"
|
|
||||||
|
|
||||||
namespace ui {
|
namespace ui {
|
||||||
class Root;
|
class Root;
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-5
@@ -50,6 +50,9 @@
|
|||||||
#include <torrent/bencode.h>
|
#include <torrent/bencode.h>
|
||||||
#include <torrent/exceptions.h>
|
#include <torrent/exceptions.h>
|
||||||
|
|
||||||
|
#include "utils/variable_map.h"
|
||||||
|
|
||||||
|
#include "globals.h"
|
||||||
#include "curl_get.h"
|
#include "curl_get.h"
|
||||||
#include "download.h"
|
#include "download.h"
|
||||||
#include "download_factory.h"
|
#include "download_factory.h"
|
||||||
@@ -85,10 +88,8 @@ delete_tied(Download* d) {
|
|||||||
|
|
||||||
Manager::Manager() :
|
Manager::Manager() :
|
||||||
m_pollManager(NULL),
|
m_pollManager(NULL),
|
||||||
m_portRandom(false),
|
|
||||||
m_portFirst(6890),
|
m_portFirst(6890),
|
||||||
m_portLast(6999),
|
m_portLast(6999) {
|
||||||
m_checkHash(true) {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -245,7 +246,7 @@ Manager::check_hash(Download* d) {
|
|||||||
|
|
||||||
void
|
void
|
||||||
Manager::receive_download_done(Download* d) {
|
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
|
// Start the hash checking, send completed to tracker after
|
||||||
// finishing.
|
// finishing.
|
||||||
prepare_hash_check(d);
|
prepare_hash_check(d);
|
||||||
@@ -263,7 +264,7 @@ Manager::listen_open() {
|
|||||||
if (m_portFirst > m_portLast)
|
if (m_portFirst > m_portLast)
|
||||||
throw torrent::input_error("Invalid port range for listening");
|
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);
|
int boundary = m_portFirst + random() % (m_portLast - m_portFirst + 1);
|
||||||
|
|
||||||
if (!torrent::listen_open(boundary, m_portLast) &&
|
if (!torrent::listen_open(boundary, m_portLast) &&
|
||||||
@@ -273,6 +274,7 @@ Manager::listen_open() {
|
|||||||
} else {
|
} else {
|
||||||
if (!torrent::listen_open(m_portFirst, m_portLast))
|
if (!torrent::listen_open(m_portFirst, m_portLast))
|
||||||
throw torrent::input_error("Could not open/bind a port for listening.");
|
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_important() { return m_logImportant; }
|
||||||
Log& get_log_complete() { return m_logComplete; }
|
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_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.
|
// Really should find a more descriptive name.
|
||||||
void initialize_first();
|
void initialize_first();
|
||||||
void initialize_second();
|
void initialize_second();
|
||||||
@@ -121,11 +118,8 @@ private:
|
|||||||
Log m_logImportant;
|
Log m_logImportant;
|
||||||
Log m_logComplete;
|
Log m_logComplete;
|
||||||
|
|
||||||
bool m_portRandom;
|
|
||||||
int m_portFirst;
|
int m_portFirst;
|
||||||
int m_portLast;
|
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().down_rate()->rate() / (1 << 10),
|
||||||
(double)d->get_download().up_rate()->total() / (1 << 20)), 0);
|
(double)d->get_download().up_rate()->total() / (1 << 20)), 0);
|
||||||
|
|
||||||
//buf += std::max(0, snprintf(buf, length, " Left: "));
|
buf = print_download_time_left(buf, last - buf, d);
|
||||||
buf = print_download_time_left(buf, length, d);
|
|
||||||
|
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
char*
|
char*
|
||||||
print_download_status(char* buf, unsigned int length, core::Download* d) {
|
print_download_status(char* buf, unsigned int length, core::Download* d) {
|
||||||
|
char* last = buf + length;
|
||||||
|
|
||||||
if (!d->get_download().is_active())
|
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())
|
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);
|
(d->get_download().chunks_hashed() * 100) / d->get_download().chunks_total()), 0);
|
||||||
|
|
||||||
else if (d->get_download().is_tracker_busy() &&
|
else if (d->get_download().is_tracker_busy() &&
|
||||||
d->get_download().tracker_focus() < d->get_download().size_trackers())
|
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(d->get_download().tracker_focus()).group(),
|
||||||
d->get_download().tracker_focus(),
|
d->get_download().tracker_focus(),
|
||||||
d->get_download().tracker(d->get_download().tracker_focus()).url().c_str()), 0);
|
d->get_download().tracker(d->get_download().tracker_focus()).url().c_str()), 0);
|
||||||
|
|
||||||
else if (!d->get_message().empty())
|
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
|
else
|
||||||
buf[0] = '\0';
|
buf[0] = '\0';
|
||||||
|
|||||||
@@ -120,7 +120,7 @@ WindowFileList::redraw() {
|
|||||||
|
|
||||||
m_canvas->print(84, pos, "%i - %i",
|
m_canvas->print(84, pos, "%i - %i",
|
||||||
e.chunk_begin(),
|
e.chunk_begin(),
|
||||||
e.chunk_end());
|
e.chunk_begin() != e.chunk_end() ? (e.chunk_end() - 1) : e.chunk_end());
|
||||||
|
|
||||||
++range.first;
|
++range.first;
|
||||||
++pos;
|
++pos;
|
||||||
|
|||||||
@@ -40,3 +40,5 @@
|
|||||||
|
|
||||||
rak::priority_queue_default taskScheduler;
|
rak::priority_queue_default taskScheduler;
|
||||||
rak::timer cachedTime;
|
rak::timer cachedTime;
|
||||||
|
|
||||||
|
Control* control = NULL;
|
||||||
|
|||||||
@@ -40,7 +40,11 @@
|
|||||||
#include <rak/timer.h>
|
#include <rak/timer.h>
|
||||||
#include <rak/priority_queue_default.h>
|
#include <rak/priority_queue_default.h>
|
||||||
|
|
||||||
|
#include "control.h"
|
||||||
|
|
||||||
extern rak::priority_queue_default taskScheduler;
|
extern rak::priority_queue_default taskScheduler;
|
||||||
extern rak::timer cachedTime;
|
extern rak::timer cachedTime;
|
||||||
|
|
||||||
|
extern Control* control;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+18
-14
@@ -159,12 +159,12 @@ main(int argc, char** argv) {
|
|||||||
|
|
||||||
cachedTime = rak::timer::current();
|
cachedTime = rak::timer::current();
|
||||||
|
|
||||||
Control control;
|
control = new Control;
|
||||||
|
|
||||||
srandom(cachedTime.usec());
|
srandom(cachedTime.usec());
|
||||||
srand48(cachedTime.usec());
|
srand48(cachedTime.usec());
|
||||||
|
|
||||||
initialize_option_handler(&control);
|
initialize_option_handler(control);
|
||||||
|
|
||||||
SignalHandler::set_ignore(SIGPIPE);
|
SignalHandler::set_ignore(SIGPIPE);
|
||||||
SignalHandler::set_handler(SIGINT, sigc::mem_fun(control, &Control::receive_shutdown));
|
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(SIGBUS, sigc::bind(sigc::ptr_fun(&do_panic), SIGBUS));
|
||||||
SignalHandler::set_handler(SIGFPE, sigc::bind(sigc::ptr_fun(&do_panic), SIGFPE));
|
SignalHandler::set_handler(SIGFPE, sigc::bind(sigc::ptr_fun(&do_panic), SIGFPE));
|
||||||
|
|
||||||
control.core()->initialize_first();
|
control->core()->initialize_first();
|
||||||
|
|
||||||
OptionFile optionFile;
|
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")))
|
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
|
// Just to make sure we did all the stuff on the queue before
|
||||||
// loading any torrents.
|
// loading any torrents.
|
||||||
@@ -192,38 +192,42 @@ main(int argc, char** argv) {
|
|||||||
|
|
||||||
// Load session torrents and perform scheduled tasks to ensure
|
// Load session torrents and perform scheduled tasks to ensure
|
||||||
// session torrents are loaded before arg torrents.
|
// session torrents are loaded before arg torrents.
|
||||||
load_session_torrents(&control);
|
load_session_torrents(control);
|
||||||
rak::priority_queue_perform(&taskScheduler, cachedTime);
|
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()) {
|
while (!control->is_shutdown_completed()) {
|
||||||
control.inc_tick();
|
control->inc_tick();
|
||||||
|
|
||||||
cachedTime = rak::timer::current();
|
cachedTime = rak::timer::current();
|
||||||
rak::priority_queue_perform(&taskScheduler, cachedTime);
|
rak::priority_queue_perform(&taskScheduler, cachedTime);
|
||||||
|
|
||||||
// Do shutdown check before poll, not after.
|
// 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) {
|
} catch (torrent::base_error& e) {
|
||||||
display::Canvas::cleanup();
|
display::Canvas::cleanup();
|
||||||
|
delete control;
|
||||||
|
|
||||||
std::cout << "Caught exception: " << e.what() << std::endl;
|
std::cout << "Caught exception: " << e.what() << std::endl;
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
} catch (std::exception& e) {
|
} catch (std::exception& e) {
|
||||||
display::Canvas::cleanup();
|
display::Canvas::cleanup();
|
||||||
|
delete control;
|
||||||
|
|
||||||
std::cout << e.what() << std::endl;
|
std::cout << e.what() << std::endl;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
delete control;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+19
-19
@@ -57,7 +57,7 @@ OptionFile::process_file(const std::string& filename) {
|
|||||||
|
|
||||||
while (file.getline(buffer, max_size_line).good()) {
|
while (file.getline(buffer, max_size_line).good()) {
|
||||||
lineNumber++;
|
lineNumber++;
|
||||||
parse_line(buffer);
|
m_slotOption(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (torrent::input_error& e) {
|
} catch (torrent::input_error& e) {
|
||||||
@@ -69,28 +69,28 @@ OptionFile::process_file(const std::string& filename) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
// void
|
||||||
OptionFile::parse_line(const char* line) {
|
// OptionFile::parse_line(const char* line) {
|
||||||
//const char* last = std::find(line, line + max_size_line, '\0');
|
//const char* last = std::find(line, line + max_size_line, '\0');
|
||||||
|
|
||||||
if (line[0] == '#')
|
// if (line[0] == '#')
|
||||||
return;
|
// return;
|
||||||
|
|
||||||
int result;
|
// int result;
|
||||||
char key[64];
|
// char key[64];
|
||||||
char opt[512];
|
// char opt[512];
|
||||||
|
|
||||||
opt[0] = '\0';
|
// opt[0] = '\0';
|
||||||
|
|
||||||
// Check for empty lines, and options within "abc".
|
// // Check for empty lines, and options within "abc".
|
||||||
if ((result = std::sscanf(line, "%63s = \"%511[^\"]", key, opt)) != 2 &&
|
// if ((result = std::sscanf(line, "%63s = \"%511[^\"]", key, opt)) != 2 &&
|
||||||
(result = std::sscanf(line, "%63s = %511s", key, opt)) != 2 &&
|
// (result = std::sscanf(line, "%63s = %511s", key, opt)) != 2 &&
|
||||||
result == 1)
|
// result == 1)
|
||||||
throw torrent::input_error("Error parseing option file.");
|
// throw torrent::input_error("Error parseing option file.");
|
||||||
|
|
||||||
if (opt[0] == '"' && opt[1] == '"')
|
// if (opt[0] == '"' && opt[1] == '"')
|
||||||
opt[0] = '\0';
|
// opt[0] = '\0';
|
||||||
|
|
||||||
if (result >= 1)
|
// if (result >= 1)
|
||||||
m_slotOption(key, opt);
|
// m_slotOption(key, opt);
|
||||||
}
|
// }
|
||||||
|
|||||||
+1
-1
@@ -46,7 +46,7 @@ public:
|
|||||||
static const int max_size_opt = 1024;
|
static const int max_size_opt = 1024;
|
||||||
static const int max_size_line = max_size_key + max_size_opt + 64;
|
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.
|
// Returns false when the file doesn't exist or cannot be opened.
|
||||||
bool process_file(const std::string& filename);
|
bool process_file(const std::string& filename);
|
||||||
|
|||||||
+36
-43
@@ -55,6 +55,7 @@
|
|||||||
#include "utils/variable_generic.h"
|
#include "utils/variable_generic.h"
|
||||||
#include "utils/variable_map.h"
|
#include "utils/variable_map.h"
|
||||||
|
|
||||||
|
#include "globals.h"
|
||||||
#include "control.h"
|
#include "control.h"
|
||||||
#include "option_handler_rules.h"
|
#include "option_handler_rules.h"
|
||||||
#include "command_scheduler.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);
|
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
|
void
|
||||||
apply_tracker_dump(Control* m, const std::string& arg) {
|
apply_tracker_dump(Control* m, const std::string& arg) {
|
||||||
if (arg == "yes")
|
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);
|
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
|
void
|
||||||
apply_http_proxy(Control* m, const std::string& arg) {
|
apply_http_proxy(Control* m, const std::string& arg) {
|
||||||
m->core()->get_poll_manager()->get_http_stack()->set_http_proxy(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
|
void
|
||||||
initialize_option_handler(Control* c) {
|
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)));
|
// Cleaned up.
|
||||||
c->variables()->insert("port_range", new utils::VariableSlotString<>(NULL, rak::bind_ptr_fn(&apply_port_range, c)));
|
variables->insert("check_hash", new utils::VariableValue("yes"));
|
||||||
c->variables()->insert("port_random", new utils::VariableSlotString<>(NULL, rak::bind_ptr_fn(&apply_port_random, c)));
|
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)));
|
// Old.
|
||||||
c->variables()->insert("directory", new utils::VariableSlotString<>(NULL, rak::bind_ptr_fn(&apply_download_directory, c)));
|
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"));
|
variables->insert("ip", new utils::VariableSlotString<>(NULL, rak::bind_ptr_fn(&apply_ip, c)));
|
||||||
c->variables()->insert("min_peers", new utils::VariableSlotValue<int, int>(NULL, rak::bind_ptr_fn(&apply_download_min_peers, c), "%i"));
|
variables->insert("port_range", new utils::VariableSlotString<>(NULL, rak::bind_ptr_fn(&apply_port_range, c)));
|
||||||
c->variables()->insert("max_uploads", new utils::VariableSlotValue<int, int>(NULL, rak::bind_ptr_fn(&apply_download_max_uploads, c), "%i"));
|
|
||||||
|
|
||||||
c->variables()->insert("download_rate", new utils::VariableSlotValue<int, int>(NULL, rak::bind_ptr_fn(&apply_global_download_rate, c), "%i"));
|
variables->insert("directory", new utils::VariableSlotString<>(NULL, rak::bind_ptr_fn(&apply_download_directory, c)));
|
||||||
c->variables()->insert("upload_rate", new utils::VariableSlotValue<int, int>(NULL, rak::bind_ptr_fn(&apply_global_upload_rate, c), "%i"));
|
|
||||||
|
|
||||||
c->variables()->insert("hash_read_ahead", new utils::VariableSlotValue<int, int>(NULL, rak::bind_ptr_fn(&apply_hash_read_ahead, c), "%i"));
|
variables->insert("max_peers", new utils::VariableSlotValue<int, int>(NULL, rak::bind_ptr_fn(&apply_download_max_peers, c), "%i"));
|
||||||
c->variables()->insert("hash_interval", new utils::VariableSlotValue<int, int>(NULL, rak::bind_ptr_fn(&apply_hash_interval, c), "%i"));
|
variables->insert("min_peers", new utils::VariableSlotValue<int, int>(NULL, rak::bind_ptr_fn(&apply_download_min_peers, c), "%i"));
|
||||||
c->variables()->insert("hash_max_tries", new utils::VariableSlotValue<int, int>(NULL, rak::bind_ptr_fn(&apply_hash_max_tries, 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("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"));
|
|
||||||
|
|
||||||
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)));
|
variables->insert("hash_read_ahead", new utils::VariableSlotValue<int, int>(NULL, rak::bind_ptr_fn(&apply_hash_read_ahead, c), "%i"));
|
||||||
c->variables()->insert("connection_seed", new utils::VariableSlotString<>(NULL, rak::bind_ptr_fn(&apply_connection_seed, c)));
|
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)));
|
variables->insert("umask", new utils::VariableSlotValue<int, int>(NULL, rak::bind_ptr_fn(&apply_umask, c), "%o"));
|
||||||
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)));
|
|
||||||
|
|
||||||
c->variables()->insert("session", new utils::VariableSlotString<>(NULL, rak::bind_ptr_fn(&apply_session_directory, c)));
|
variables->insert("connection_leech", new utils::VariableSlotString<>(NULL, rak::bind_ptr_fn(&apply_connection_leech, c)));
|
||||||
c->variables()->insert("encoding_list", new utils::VariableSlotString<>(NULL, rak::bind_ptr_fn(&apply_encoding_list, c)));
|
variables->insert("connection_seed", new utils::VariableSlotString<>(NULL, rak::bind_ptr_fn(&apply_connection_seed, 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)));
|
|
||||||
|
|
||||||
c->variables()->insert("http_proxy", new utils::VariableSlotString<>(NULL, rak::bind_ptr_fn(&apply_http_proxy, c)));
|
variables->insert("load", new utils::VariableSlotString<>(NULL, rak::bind_ptr_fn(&apply_load, c)));
|
||||||
c->variables()->insert("schedule", new utils::VariableSlotString<>(NULL, rak::bind_ptr_fn(&apply_schedule, c)));
|
variables->insert("load_start", new utils::VariableSlotString<>(NULL, rak::bind_ptr_fn(&apply_load_start, c)));
|
||||||
c->variables()->insert("schedule_remove", new utils::VariableSlotString<>(NULL, rak::bind_ptr_fn(&apply_schedule_remove, 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 {
|
namespace utils {
|
||||||
|
|
||||||
// VariableString::~VariableString() {
|
VariableValue::~VariableValue() {
|
||||||
// }
|
}
|
||||||
|
|
||||||
// std::string
|
const torrent::Bencode&
|
||||||
// VariableString::get() {
|
VariableValue::get() {
|
||||||
// return m_variable;
|
return m_variable;
|
||||||
// }
|
}
|
||||||
|
|
||||||
// void
|
void
|
||||||
// VariableString::set(const std::string& arg) {
|
VariableValue::set(const torrent::Bencode& arg) {
|
||||||
// m_variable = arg;
|
m_variable = arg;
|
||||||
// }
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,6 +39,7 @@
|
|||||||
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <limits>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <rak/functional_fun.h>
|
#include <rak/functional_fun.h>
|
||||||
#include <torrent/bencode.h>
|
#include <torrent/bencode.h>
|
||||||
@@ -48,19 +49,18 @@
|
|||||||
|
|
||||||
namespace utils {
|
namespace utils {
|
||||||
|
|
||||||
// class VariableS : public Variable {
|
class VariableValue : public Variable {
|
||||||
// public:
|
public:
|
||||||
// VariableString(const std::string& v = "") : m_variable(v) {}
|
VariableValue(const torrent::Bencode& v = torrent::Bencode()) : m_variable(v) {}
|
||||||
// virtual ~VariableString();
|
virtual ~VariableValue();
|
||||||
|
|
||||||
// virtual const torrent::Bencode& get();
|
virtual const torrent::Bencode& get();
|
||||||
// virtual void set(const torrent::Bencode& arg);
|
virtual void set(const torrent::Bencode& arg);
|
||||||
|
|
||||||
// private:
|
private:
|
||||||
// std::string m_variable;
|
torrent::Bencode m_variable;
|
||||||
// };
|
};
|
||||||
|
|
||||||
// VariableSlot?
|
|
||||||
template <typename Get = std::string, typename Set = const std::string&>
|
template <typename Get = std::string, typename Set = const std::string&>
|
||||||
class VariableSlotString : public Variable {
|
class VariableSlotString : public Variable {
|
||||||
public:
|
public:
|
||||||
@@ -84,10 +84,16 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void set(const torrent::Bencode& arg) {
|
virtual void set(const torrent::Bencode& arg) {
|
||||||
if (!arg.is_string())
|
switch (arg.get_type()) {
|
||||||
throw torrent::internal_error("VariableSlotString::set(...) got wrong type.");
|
case torrent::Bencode::TYPE_STRING:
|
||||||
|
|
||||||
m_slotSet(arg.as_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.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -105,13 +111,17 @@ class VariableSlotValue : public Variable {
|
|||||||
public:
|
public:
|
||||||
typedef rak::function0<Get> SlotGet;
|
typedef rak::function0<Get> SlotGet;
|
||||||
typedef rak::function1<void, Set> SlotSet;
|
typedef rak::function1<void, Set> SlotSet;
|
||||||
|
typedef std::pair<int64_t, int64_t> Range;
|
||||||
|
|
||||||
VariableSlotValue(typename SlotGet::base_type* slotGet,
|
VariableSlotValue(typename SlotGet::base_type* slotGet,
|
||||||
typename SlotSet::base_type* slotSet,
|
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_slotGet.set(slotGet);
|
||||||
m_slotSet.set(slotSet);
|
m_slotSet.set(slotSet);
|
||||||
m_pattern = pattern;
|
m_pattern = pattern;
|
||||||
|
m_range = range;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~VariableSlotValue() {}
|
virtual ~VariableSlotValue() {}
|
||||||
@@ -148,6 +158,7 @@ private:
|
|||||||
SlotSet m_slotSet;
|
SlotSet m_slotSet;
|
||||||
|
|
||||||
const char* m_pattern;
|
const char* m_pattern;
|
||||||
|
Range m_range;
|
||||||
|
|
||||||
// Store the cache here to avoid unnessesary copying and such. This
|
// Store the cache here to avoid unnessesary copying and such. This
|
||||||
// should not result in any unresonable memory usage since few
|
// 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);
|
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
|
void
|
||||||
VariableMap::process_command(const std::string& command) {
|
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)
|
if (pos == command.end() || *pos == '#')
|
||||||
throw torrent::input_error("Option handler could not find '=' in command.");
|
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)));
|
||||||
|
|
||||||
set(command.substr(0, pos), torrent::Bencode(command.substr(pos + 1, std::string::npos)));
|
if (pos == command.end() || *pos != '=')
|
||||||
|
throw torrent::input_error("Could not find '='.");
|
||||||
|
|
||||||
|
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