mirror of
https://github.com/rakshasa/rtorrent.git
synced 2026-08-05 17:52:29 +00:00
Added special syntax to config files to enable log categories early.
This commit is contained in:
@@ -197,6 +197,8 @@ libsub_root_a_SOURCES = \
|
||||
globals.h \
|
||||
option_parser.cc \
|
||||
option_parser.h \
|
||||
setup.cc \
|
||||
setup.h \
|
||||
signal_handler.cc \
|
||||
signal_handler.h
|
||||
|
||||
|
||||
+8
-39
@@ -8,53 +8,23 @@
|
||||
#include <torrent/utils/log.h>
|
||||
#include <torrent/utils/option_strings.h>
|
||||
|
||||
#include "globals.h"
|
||||
#include "control.h"
|
||||
#include "command_helpers.h"
|
||||
#include "globals.h"
|
||||
#include "setup.h"
|
||||
#include "core/download.h"
|
||||
#include "core/download_list.h"
|
||||
#include "core/manager.h"
|
||||
#include "rpc/parse_commands.h"
|
||||
|
||||
static const int log_flag_use_gz = 0x1;
|
||||
static const int log_flag_append_pid = 0x2;
|
||||
static const int log_flag_append_file = 0x4;
|
||||
static const int log_flag_flush = 0x8;
|
||||
|
||||
void
|
||||
log_add_group_output_str(const char* group_name, const char* output_id) {
|
||||
int log_group = torrent::option_find_string(torrent::OPTION_LOG_GROUP, group_name);
|
||||
torrent::log_add_group_output(log_group, output_id);
|
||||
}
|
||||
|
||||
torrent::Object
|
||||
apply_log_open(int output_flags, const torrent::Object::list_type& args) {
|
||||
if (args.size() < 2)
|
||||
throw torrent::input_error("Invalid number of arguments.");
|
||||
apply_log_open(int output_flags, const torrent::Object::list_type& raw_args) {
|
||||
std::vector<std::string> args;
|
||||
|
||||
torrent::Object::list_const_iterator itr = args.begin();
|
||||
|
||||
auto output_id = (itr++)->as_string();
|
||||
auto file_name = expand_path((itr++)->as_string());
|
||||
|
||||
if ((output_flags & log_flag_append_pid)) {
|
||||
char buffer[32];
|
||||
snprintf(buffer, 32, ".%li", (long)getpid());
|
||||
|
||||
file_name += buffer;
|
||||
}
|
||||
|
||||
bool append = (output_flags & log_flag_append_file);
|
||||
bool flush = (output_flags & log_flag_flush);
|
||||
|
||||
if ((output_flags & log_flag_use_gz))
|
||||
torrent::log_open_gz_file_output(output_id.c_str(), file_name.c_str(), append);
|
||||
else
|
||||
torrent::log_open_file_output(output_id.c_str(), file_name.c_str(), append, flush);
|
||||
|
||||
while (itr != args.end())
|
||||
log_add_group_output_str((itr++)->as_string().c_str(), output_id.c_str());
|
||||
for (const auto& arg : raw_args)
|
||||
args.push_back(arg.as_string());
|
||||
|
||||
apply_log_open_str(output_flags, args);
|
||||
return torrent::Object();
|
||||
}
|
||||
|
||||
@@ -63,8 +33,7 @@ apply_log_add_output(const torrent::Object::list_type& args) {
|
||||
if (args.size() != 2)
|
||||
throw torrent::input_error("Invalid number of arguments.");
|
||||
|
||||
log_add_group_output_str(args.front().as_string().c_str(),
|
||||
args.back().as_string().c_str());
|
||||
log_add_group_output_str(args.front().as_string(), args.back().as_string());
|
||||
|
||||
return torrent::Object();
|
||||
}
|
||||
|
||||
+2
-2
@@ -16,12 +16,12 @@ expand_path(const std::string& path) {
|
||||
|
||||
if (path[0] == '~') {
|
||||
if (path.size() >= 2 && path[1] != '/')
|
||||
throw torrent::input_error("Could not expand ~ in session path, only '~' or '~/...' is supported.");
|
||||
throw torrent::input_error("Could not expand ~ in path, only '~' or '~/...' is supported.");
|
||||
|
||||
const char* home = std::getenv("HOME");
|
||||
|
||||
if (home == nullptr || *home == '\0')
|
||||
throw torrent::input_error("Could not expand ~ in session path, HOME environment variable not set.");
|
||||
throw torrent::input_error("Could not expand ~ in path, HOME environment variable not set.");
|
||||
|
||||
return home + path.substr(1);
|
||||
}
|
||||
|
||||
+37
-97
@@ -20,7 +20,6 @@
|
||||
|
||||
#include "core/dht_manager.h"
|
||||
#include "core/download.h"
|
||||
#include "core/download_factory.h"
|
||||
#include "core/manager.h"
|
||||
#include "display/canvas.h"
|
||||
#include "display/window.h"
|
||||
@@ -30,15 +29,15 @@
|
||||
#include "rpc/command_scheduler_item.h"
|
||||
#include "rpc/parse_commands.h"
|
||||
#include "scgi/thread_scgi.h"
|
||||
#include "session/download_storer.h"
|
||||
#include "session/thread_session.h"
|
||||
#include "session/session_manager.h"
|
||||
#include "session/thread_session.h"
|
||||
#include "ui/root.h"
|
||||
#include "utils/directory.h"
|
||||
|
||||
#include "control.h"
|
||||
#include "command_helpers.h"
|
||||
#include "globals.h"
|
||||
#include "setup.h"
|
||||
#include "signal_handler.h"
|
||||
#include "option_parser.h"
|
||||
|
||||
@@ -50,37 +49,6 @@ void do_panic(int signum);
|
||||
void print_help();
|
||||
void initialize_commands();
|
||||
|
||||
void do_nothing() {}
|
||||
void do_nothing_str(const std::string&) {}
|
||||
|
||||
int
|
||||
parse_options(int argc, char** argv) {
|
||||
try {
|
||||
OptionParser optionParser;
|
||||
|
||||
// Converted.
|
||||
optionParser.insert_flag('h', std::bind(&print_help));
|
||||
optionParser.insert_flag('n', std::bind(&do_nothing_str, std::placeholders::_1));
|
||||
optionParser.insert_flag('D', std::bind(&do_nothing_str, std::placeholders::_1));
|
||||
optionParser.insert_flag('I', std::bind(&do_nothing_str, std::placeholders::_1));
|
||||
optionParser.insert_flag('K', std::bind(&do_nothing_str, std::placeholders::_1));
|
||||
|
||||
optionParser.insert_option('b', std::bind(&rpc::call_command_set_string, "network.bind_address.set", std::placeholders::_1));
|
||||
optionParser.insert_option('d', std::bind(&rpc::call_command_set_string, "directory.default.set", std::placeholders::_1));
|
||||
optionParser.insert_option('i', std::bind(&rpc::call_command_set_string, "ip", std::placeholders::_1));
|
||||
optionParser.insert_option('p', std::bind(&rpc::call_command_set_string, "network.port_range.set", std::placeholders::_1));
|
||||
optionParser.insert_option('s', std::bind(&rpc::call_command_set_string, "session", std::placeholders::_1));
|
||||
|
||||
optionParser.insert_option('O', std::bind(&rpc::parse_command_single_std, std::placeholders::_1));
|
||||
optionParser.insert_option_list('o', std::bind(&rpc::call_command_set_std_string, std::placeholders::_1, std::placeholders::_2));
|
||||
|
||||
return optionParser.process(argc, argv);
|
||||
|
||||
} catch (torrent::input_error& e) {
|
||||
throw torrent::input_error("Failed to parse command line option: " + std::string(e.what()));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
initialize_rpc_slots() {
|
||||
rpc::rpc.slot_find_download() = [](const char* hash) {
|
||||
@@ -110,43 +78,6 @@ initialize_rpc_slots() {
|
||||
};
|
||||
}
|
||||
|
||||
void
|
||||
load_session_torrents() {
|
||||
utils::Directory entries = session::DownloadStorer::get_formated_entries(session_thread::manager()->path());
|
||||
|
||||
for (const auto& entry : entries) {
|
||||
// We don't really support session torrents that are links. These
|
||||
// would be overwritten anyway on exit, and thus not really be
|
||||
// useful.
|
||||
if (!entry.is_file())
|
||||
continue;
|
||||
|
||||
core::DownloadFactory* f = new core::DownloadFactory(control->core());
|
||||
|
||||
// Replace with session torrent flag.
|
||||
f->set_session(true);
|
||||
f->set_init_load(true);
|
||||
f->slot_finished([f](){ delete f; });
|
||||
f->load(entries.path() + entry.s_name);
|
||||
f->commit();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
load_arg_torrents(char** first, char** last) {
|
||||
//std::for_each(begin, end, std::bind1st(std::mem_fun(&core::Manager::insert), &control->get_core()));
|
||||
for (; first != last; ++first) {
|
||||
core::DownloadFactory* f = new core::DownloadFactory(control->core());
|
||||
|
||||
// Replace with session torrent flag.
|
||||
f->set_start(true);
|
||||
f->set_init_load(true);
|
||||
f->slot_finished([f](){ delete f; });
|
||||
f->load(*first);
|
||||
f->commit();
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
client_perform() {
|
||||
// Use throw exclusively.
|
||||
@@ -176,19 +107,36 @@ main(int argc, char** argv) {
|
||||
srandom(random_seed);
|
||||
srand48(random_seed);
|
||||
|
||||
torrent::initialize_main_thread();
|
||||
torrent::log_initialize();
|
||||
|
||||
// TODO: Create a fake thread object for initializing other processes and enabling logging.
|
||||
torrent::initialize_main_thread();
|
||||
|
||||
SignalHandler::set_ignore(SIGPIPE);
|
||||
SignalHandler::set_handler(SIGSEGV, std::bind(&do_panic, SIGSEGV));
|
||||
SignalHandler::set_handler(SIGILL, std::bind(&do_panic, SIGILL));
|
||||
SignalHandler::set_handler(SIGFPE, std::bind(&do_panic, SIGFPE));
|
||||
|
||||
// Limited list of commands with the following format:
|
||||
//
|
||||
// cat ~/.rtorrent.rc:
|
||||
//
|
||||
// # do:log.open_file=system,/usr/rakshasa/system.log
|
||||
// # do:log.add_output=system,system
|
||||
//
|
||||
parse_config_file(argc, argv, [](auto& path) {
|
||||
if (path.empty())
|
||||
return;
|
||||
|
||||
parse_config_file_comments(path);
|
||||
});
|
||||
|
||||
control = new Control;
|
||||
|
||||
SignalHandler::set_ignore(SIGPIPE);
|
||||
SignalHandler::set_handler(SIGINT, std::bind(&Control::receive_normal_shutdown, control));
|
||||
SignalHandler::set_handler(SIGHUP, std::bind(&Control::receive_normal_shutdown, control));
|
||||
SignalHandler::set_handler(SIGTERM, std::bind(&Control::receive_quick_shutdown, control));
|
||||
SignalHandler::set_handler(SIGWINCH, std::bind(&display::Manager::force_redraw, control->display()));
|
||||
SignalHandler::set_handler(SIGSEGV, std::bind(&do_panic, SIGSEGV));
|
||||
SignalHandler::set_handler(SIGILL, std::bind(&do_panic, SIGILL));
|
||||
SignalHandler::set_handler(SIGFPE, std::bind(&do_panic, SIGFPE));
|
||||
|
||||
SignalHandler::set_sigaction_handler(SIGBUS, &handle_sigbus);
|
||||
|
||||
@@ -200,7 +148,7 @@ main(int argc, char** argv) {
|
||||
// threads. Use '--enable-interrupt-socket' when configuring
|
||||
// LibTorrent to enable this workaround.
|
||||
if (torrent::utils::Thread::should_handle_sigusr1())
|
||||
SignalHandler::set_handler(SIGUSR1, std::bind(&do_nothing));
|
||||
SignalHandler::set_handler(SIGUSR1, []() {});
|
||||
|
||||
torrent::log_add_group_output(torrent::LOG_NOTICE, "important");
|
||||
torrent::log_add_group_output(torrent::LOG_DHT_ERROR, "important");
|
||||
@@ -459,23 +407,16 @@ main(int argc, char** argv) {
|
||||
}
|
||||
}
|
||||
|
||||
int firstArg = parse_options(argc, argv);
|
||||
int firstArg = parse_main_options(argc, argv);
|
||||
|
||||
if (OptionParser::has_flag('n', argc, argv)) {
|
||||
lt_log_print(torrent::LOG_WARN, "Ignoring rtorrent.rc.");
|
||||
} else {
|
||||
char* config_dir = std::getenv("XDG_CONFIG_HOME");
|
||||
char* home_dir = std::getenv("HOME");
|
||||
parse_config_file(argc, argv, [](auto& path) {
|
||||
if (path.empty()) {
|
||||
lt_log_print(torrent::LOG_WARN, "Ignoring rtorrent.rc.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (config_dir != NULL && config_dir[0] == '/' &&
|
||||
access((std::string(config_dir) + "/rtorrent/rtorrent.rc").c_str(), F_OK) != -1) {
|
||||
rpc::parse_command_single(rpc::make_target(), "try_import = " + std::string(config_dir) + "/rtorrent/rtorrent.rc");
|
||||
} else if (home_dir != NULL && access((std::string(home_dir) + "/.config/rtorrent/rtorrent.rc").c_str(), F_OK) != -1) {
|
||||
rpc::parse_command_single(rpc::make_target(), "try_import = ~/.config/rtorrent/rtorrent.rc");
|
||||
} else {
|
||||
rpc::parse_command_single(rpc::make_target(), "try_import = ~/.rtorrent.rc");
|
||||
}
|
||||
}
|
||||
rpc::parse_command_single(rpc::make_target(), "try_import=" + path);
|
||||
});
|
||||
|
||||
LT_LOG("seeded srandom and srand48 (seed:%u)", random_seed);
|
||||
|
||||
@@ -485,11 +426,8 @@ main(int argc, char** argv) {
|
||||
// Load session torrents and perform scheduled tasks to ensure
|
||||
// session torrents are loaded before arg torrents.
|
||||
control->dht_manager()->load_dht_cache();
|
||||
load_session_torrents();
|
||||
|
||||
// TODO: Check if this is required.
|
||||
// rak::priority_queue_perform(&taskScheduler, cachedTime);
|
||||
|
||||
load_session_torrents(session_thread::manager()->path());
|
||||
load_arg_torrents(argv + firstArg, argv + argc);
|
||||
|
||||
// Make sure we update the display before any scheduled tasks can
|
||||
@@ -616,7 +554,9 @@ do_panic(int signum) {
|
||||
// Use the default signal handler in the future to avoid infinit
|
||||
// loops.
|
||||
SignalHandler::set_default(signum);
|
||||
display::Canvas::cleanup();
|
||||
|
||||
if (control != nullptr)
|
||||
display::Canvas::cleanup();
|
||||
|
||||
std::stringstream output;
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#include "config.h"
|
||||
|
||||
#include "option_parser.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#include <cstdio>
|
||||
@@ -8,8 +10,6 @@
|
||||
#include <stdexcept>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "option_parser.h"
|
||||
|
||||
void
|
||||
OptionParser::insert_flag(char c, slot_string s) {
|
||||
m_container[c].m_slot = s;
|
||||
|
||||
@@ -1,37 +1,3 @@
|
||||
// rTorrent - BitTorrent client
|
||||
// Copyright (C) 2005-2011, Jari Sundell
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
// In addition, as a special exception, the copyright holders give
|
||||
// permission to link the code of portions of this program with the
|
||||
// OpenSSL library under certain conditions as described in each
|
||||
// individual source file, and distribute linked combinations
|
||||
// including the two.
|
||||
//
|
||||
// You must obey the GNU General Public License in all respects for
|
||||
// all of the code used other than OpenSSL. If you modify file(s)
|
||||
// with this exception, you may extend this exception to your version
|
||||
// of the file(s), but you are not obligated to do so. If you do not
|
||||
// wish to do so, delete this exception statement from your version.
|
||||
// If you delete this exception statement from all source files in the
|
||||
// program, then also delete it here.
|
||||
//
|
||||
// Contact: Jari Sundell <sundell.software@gmail.com>
|
||||
|
||||
|
||||
#ifndef RTORRENT_OPTION_PARSER_H
|
||||
#define RTORRENT_OPTION_PARSER_H
|
||||
|
||||
|
||||
@@ -151,23 +151,21 @@ parse_command_file(const std::string& path) {
|
||||
try {
|
||||
unsigned int getCount = 0;
|
||||
|
||||
while (file.good()
|
||||
&& !file.getline(buffer + getCount, 4096 - getCount).fail()) {
|
||||
|
||||
while (file.good() && !file.getline(buffer + getCount, 4096 - getCount).fail()) {
|
||||
if (file.gcount() == 0)
|
||||
throw torrent::internal_error("parse_command_file(...) file.gcount() == 0.");
|
||||
|
||||
int lineLength = file.gcount() - 1;
|
||||
int line_length = file.gcount() - 1;
|
||||
// In case we are at the end of the file and the last character is
|
||||
// not a line feed, we'll just increase the read character count so
|
||||
// that the last would also be included in option line.
|
||||
if (file.eof() && file.get() != '\n')
|
||||
lineLength++;
|
||||
line_length++;
|
||||
|
||||
int escaped = parse_count_escaped(buffer + getCount, buffer + getCount + lineLength);
|
||||
int escaped = parse_count_escaped(buffer + getCount, buffer + getCount + line_length);
|
||||
|
||||
lineNumber++;
|
||||
getCount += lineLength;
|
||||
getCount += line_length;
|
||||
|
||||
if (getCount == 4096 - 1)
|
||||
throw torrent::input_error("Exceeded max line length.");
|
||||
|
||||
+220
@@ -0,0 +1,220 @@
|
||||
#include "config.h"
|
||||
|
||||
#include "setup.h"
|
||||
|
||||
#include <fstream>
|
||||
#include <unistd.h>
|
||||
#include <torrent/exceptions.h>
|
||||
#include <torrent/utils/log.h>
|
||||
#include <torrent/utils/option_strings.h>
|
||||
|
||||
#include "control.h"
|
||||
#include "globals.h"
|
||||
#include "option_parser.h"
|
||||
#include "core/download_factory.h"
|
||||
#include "rpc/parse_commands.h"
|
||||
#include "session/download_storer.h"
|
||||
#include "utils/directory.h"
|
||||
|
||||
void do_panic(int signum);
|
||||
void print_help();
|
||||
|
||||
//
|
||||
// Parse command line args and config files:
|
||||
//
|
||||
|
||||
int
|
||||
parse_main_options(int argc, char** argv) {
|
||||
try {
|
||||
OptionParser optionParser;
|
||||
|
||||
// Converted.
|
||||
optionParser.insert_flag('h', [](auto&) { print_help(); });
|
||||
optionParser.insert_flag('n', [](auto&) { });
|
||||
optionParser.insert_flag('D', [](auto&) { });
|
||||
optionParser.insert_flag('I', [](auto&) { });
|
||||
optionParser.insert_flag('K', [](auto&) { });
|
||||
|
||||
optionParser.insert_option('b', [](auto& arg) { rpc::call_command_set_string("network.bind_address.set", arg); });
|
||||
optionParser.insert_option('d', [](auto& arg) { rpc::call_command_set_string("directory.default.set", arg); });
|
||||
optionParser.insert_option('i', [](auto& arg) { rpc::call_command_set_string("ip", arg); });
|
||||
optionParser.insert_option('p', [](auto& arg) { rpc::call_command_set_string("network.port_range.set", arg); });
|
||||
optionParser.insert_option('s', [](auto& arg) { rpc::call_command_set_string("session", arg); });
|
||||
|
||||
optionParser.insert_option('O', [](auto& arg) { rpc::parse_command_single_std(arg); });
|
||||
optionParser.insert_option_list('o', [](auto& arg1, auto& arg2) { rpc::call_command_set_std_string(arg1, arg2); });
|
||||
|
||||
return optionParser.process(argc, argv);
|
||||
|
||||
} catch (torrent::input_error& e) {
|
||||
throw torrent::input_error("Failed to parse command line option: " + std::string(e.what()));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
parse_config_file(int argc, char** argv, std::function<void (const std::string&)> parse_fn) {
|
||||
if (OptionParser::has_flag('n', argc, argv))
|
||||
return parse_fn("");
|
||||
|
||||
char* config_dir = std::getenv("XDG_CONFIG_HOME");
|
||||
char* home_dir = std::getenv("HOME");
|
||||
|
||||
if (config_dir != nullptr && config_dir[0] == '/' && access((std::string(config_dir) + "/rtorrent/rtorrent.rc").c_str(), F_OK) != -1)
|
||||
return parse_fn(std::string(config_dir) + "/rtorrent/rtorrent.rc");
|
||||
|
||||
if (home_dir == nullptr)
|
||||
throw torrent::input_error("Could not find home directory, HOME environment variable not set.");
|
||||
|
||||
if (access((std::string(home_dir) + "/.config/rtorrent/rtorrent.rc").c_str(), F_OK) != -1)
|
||||
return parse_fn(std::string(home_dir) + "/.config/rtorrent/rtorrent.rc");
|
||||
|
||||
return parse_fn(std::string(home_dir) + "/.rtorrent.rc");
|
||||
}
|
||||
|
||||
void
|
||||
config_comment_log(const std::string& command, const std::string& raw_args) {
|
||||
std::vector<std::string> args;
|
||||
size_t pos{};
|
||||
|
||||
while (pos < raw_args.size()) {
|
||||
size_t next_pos = raw_args.find(',', pos);
|
||||
|
||||
if (next_pos == std::string::npos)
|
||||
next_pos = raw_args.size();
|
||||
|
||||
args.push_back(raw_args.substr(pos, next_pos - pos));
|
||||
pos = next_pos + 1;
|
||||
}
|
||||
|
||||
if (command == "log.add_output")
|
||||
log_add_group_output_str(args[0], args[1]);
|
||||
else if (command == "log.open_file")
|
||||
apply_log_open_str(0, args);
|
||||
else if (command == "log.open_file.flush")
|
||||
apply_log_open_str(log_flag_flush, args);
|
||||
else if (command == "log.open_gz_file")
|
||||
apply_log_open_str(log_flag_use_gz, args);
|
||||
else if (command == "log.open_file_pid")
|
||||
apply_log_open_str(log_flag_append_pid, args);
|
||||
else if (command == "log.open_gz_file_pid")
|
||||
apply_log_open_str(log_flag_append_pid | log_flag_use_gz, args);
|
||||
else if (command == "log.append_file")
|
||||
apply_log_open_str(log_flag_append_file, args);
|
||||
else if (command == "log.append_file.flush")
|
||||
apply_log_open_str(log_flag_append_file | log_flag_flush, args);
|
||||
else if (command == "log.append_gz_file")
|
||||
apply_log_open_str(log_flag_append_file | log_flag_use_gz, args);
|
||||
else
|
||||
throw torrent::input_error("Unknown log command: " + command);
|
||||
}
|
||||
|
||||
// Call special commands in the format "# do:command=args" in the config file.
|
||||
void
|
||||
parse_config_file_comments(const std::string& path) {
|
||||
std::fstream file(path, std::ios::in);
|
||||
|
||||
if (!file.is_open())
|
||||
return;
|
||||
|
||||
std::string line;
|
||||
|
||||
while (std::getline(file, line)) {
|
||||
if (line.size() <= 5 || line.compare(0, 5, "# do:") != 0)
|
||||
continue;
|
||||
|
||||
auto equal_pos = line.find('=');
|
||||
|
||||
if (equal_pos == std::string::npos)
|
||||
throw torrent::input_error("Invalid command in config file comment: " + line);
|
||||
|
||||
std::string command = line.substr(5, equal_pos - 5);
|
||||
std::string args = line.substr(equal_pos + 1);
|
||||
|
||||
if (command.empty())
|
||||
throw torrent::input_error("Invalid command in config file comment: " + line);
|
||||
|
||||
if (command.compare(0, 4, "log.") == 0)
|
||||
config_comment_log(command, args);
|
||||
else
|
||||
throw torrent::input_error("Unknown command in config file comment: " + line);
|
||||
|
||||
lt_log_print(torrent::LOG_NOTICE, "Pre-config command: %s=%s", command.c_str(), args.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Torrents:
|
||||
//
|
||||
|
||||
void
|
||||
load_session_torrents(const std::string& path) {
|
||||
auto entries = session::DownloadStorer::get_formated_entries(path);
|
||||
|
||||
for (const auto& entry : entries) {
|
||||
// We don't really support session torrents that are links. These
|
||||
// would be overwritten anyway on exit, and thus not really be
|
||||
// useful.
|
||||
if (!entry.is_file())
|
||||
continue;
|
||||
|
||||
auto* f = new core::DownloadFactory(control->core());
|
||||
|
||||
f->set_session(true);
|
||||
f->set_init_load(true);
|
||||
f->slot_finished([f](){ delete f; });
|
||||
f->load(entries.path() + entry.s_name);
|
||||
f->commit();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
load_arg_torrents(char** first, char** last) {
|
||||
for (; first != last; ++first) {
|
||||
auto* f = new core::DownloadFactory(control->core());
|
||||
|
||||
f->set_start(true);
|
||||
f->set_init_load(true);
|
||||
f->slot_finished([f](){ delete f; });
|
||||
f->load(*first);
|
||||
f->commit();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Logging:
|
||||
//
|
||||
|
||||
void
|
||||
log_add_group_output_str(const std::string& group_name, const std::string& output_id) {
|
||||
int log_group = torrent::option_find_string(torrent::OPTION_LOG_GROUP, group_name.c_str());
|
||||
|
||||
torrent::log_add_group_output(log_group, output_id.c_str());
|
||||
}
|
||||
|
||||
void
|
||||
apply_log_open_str(int output_flags, const std::vector<std::string>& args) {
|
||||
if (args.size() < 2)
|
||||
throw torrent::input_error("Invalid number of arguments.");
|
||||
|
||||
auto output_id = args[0];
|
||||
auto file_name = expand_path(args[1]);
|
||||
|
||||
if ((output_flags & log_flag_append_pid)) {
|
||||
char buffer[32];
|
||||
snprintf(buffer, 32, ".%li", (long)getpid());
|
||||
|
||||
file_name += buffer;
|
||||
}
|
||||
|
||||
bool append = (output_flags & log_flag_append_file);
|
||||
bool flush = (output_flags & log_flag_flush);
|
||||
|
||||
if ((output_flags & log_flag_use_gz))
|
||||
torrent::log_open_gz_file_output(output_id.c_str(), file_name.c_str(), append);
|
||||
else
|
||||
torrent::log_open_file_output(output_id.c_str(), file_name.c_str(), append, flush);
|
||||
|
||||
for (size_t i = 2; i < args.size(); i++)
|
||||
log_add_group_output_str(args[i], output_id);
|
||||
}
|
||||
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
#ifndef RTORRENT_SETUP_H
|
||||
#define RTORRENT_SETUP_H
|
||||
|
||||
#include <functional>
|
||||
#include <string>
|
||||
|
||||
int parse_main_options(int argc, char** argv);
|
||||
void parse_config_file(int argc, char** argv, std::function<void (const std::string&)> parse_fn);
|
||||
void parse_config_file_comments(const std::string& path);
|
||||
|
||||
void load_session_torrents(const std::string& path);
|
||||
void load_arg_torrents(char** first, char** last);
|
||||
|
||||
static constexpr int log_flag_use_gz = 0x1;
|
||||
static constexpr int log_flag_append_pid = 0x2;
|
||||
static constexpr int log_flag_append_file = 0x4;
|
||||
static constexpr int log_flag_flush = 0x8;
|
||||
|
||||
void log_add_group_output_str(const std::string& group_name, const std::string& output_id);
|
||||
void apply_log_open_str(int output_flags, const std::vector<std::string>& args);
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user