* Added a default low_diskspace check for 500MB.

* Properly catch the exceptions being thrown by the 'in_*' events.

* Expand ~ in ExecFile.


git-svn-id: svn://rakshasa.no/libtorrent/trunk/rtorrent@950 e378c898-3ddf-0310-93e7-cc216c733640
This commit is contained in:
rakshasa
2007-08-07 15:14:57 +00:00
parent 37bc4c85c4
commit ef794b8eda
9 changed files with 62 additions and 22 deletions
+1 -1
View File
@@ -1,4 +1,4 @@
AC_INIT(rtorrent, 0.7.6, jaris@ifi.uio.no)
AC_INIT(rtorrent, 0.7.7, jaris@ifi.uio.no)
AM_INIT_AUTOMAKE
AM_CONFIG_HEADER(config.h)
+15
View File
@@ -58,6 +58,21 @@ path_expand(const std::string& path) {
return home + path.substr(1);
}
inline char*
path_expand(const char* src, char* first, char* last) {
if (*src == '~') {
char* home = std::getenv("HOME");
if (home == NULL)
return first;
first += strlcpy(first, home, std::distance(first, last));
src++;
}
return first + strlcpy(first, src, std::distance(first, last));
}
}
#endif
+4 -4
View File
@@ -62,18 +62,18 @@ torrent::Object
apply_on_state_change(core::DownloadList::slot_map* slotMap, const torrent::Object& rawArgs) {
const torrent::Object::list_type& args = rawArgs.as_list();
if (args.size() < 2)
throw torrent::input_error("Too few arguments.");
if (args.size() == 0 || args.size() > 2)
throw torrent::input_error("Wrong number of arguments.");
if (args.front().as_string().empty())
throw torrent::input_error("Empty key.");
std::string key = "1_state_" + args.front().as_string();
if (args.back().as_string().empty())
if (args.size() == 1)
slotMap->erase(key);
else
(*slotMap)[key] = sigc::bind(sigc::ptr_fun(&rpc::parse_command_d_multiple_std), rpc::convert_list_to_command(++args.begin(), args.end()));
(*slotMap)[key] = sigc::bind(sigc::ptr_fun(&rpc::parse_command_d_multiple_std), args.back().as_string());
return torrent::Object();
}
+2 -2
View File
@@ -59,7 +59,7 @@ initialize_command_local() {
core::DownloadList* dList = control->core()->download_list();
core::DownloadStore* dStore = control->core()->download_store();
ADD_VARIABLE_C_STRING("client_version", PACKAGE_VERSION);
ADD_VARIABLE_C_STRING("client_version", PACKAGE_VERSION);
ADD_VARIABLE_C_STRING("library_version", torrent::version());
ADD_VARIABLE_VALUE("max_file_size", -1);
@@ -83,5 +83,5 @@ initialize_command_local() {
ADD_COMMAND_VALUE_TRI_OCT("umask", rak::make_mem_fun(control, &Control::set_umask), rak::make_mem_fun(control, &Control::umask));
ADD_COMMAND_STRING_TRI("working_directory", rak::make_mem_fun(control, &Control::set_working_directory), rak::make_mem_fun(control, &Control::working_directory));
ADD_COMMAND_LIST("execute", rak::mem_fn(&rpc::execFile, &rpc::ExecFile::execute_object));
ADD_COMMAND_LIST("execute", rak::bind2_mem_fn(&rpc::execFile, &rpc::ExecFile::execute_object, rpc::ExecFile::flag_throw | rpc::ExecFile::flag_expand_tilde));
}
+8 -1
View File
@@ -73,7 +73,11 @@ struct download_list_call {
download_list_call(Download* d) : m_download(d) {}
void operator () (const DownloadList::slot_map::value_type& s) {
s.second(m_download);
try {
s.second(m_download);
} catch (torrent::input_error& e) {
control->core()->push_log((std::string("Download event action failed: ") + e.what()).c_str());
}
}
Download* m_download;
@@ -561,6 +565,9 @@ DownloadList::confirm_finished(Download* download) {
// up/downloaded baseline.
download->download()->tracker_list().send_completed();
// Close before calling on_finished to ensure the user can do stuff
// like change move the downloaded files and change the directory.
close_throw(download);
std::for_each(slot_map_finished().begin(), slot_map_finished().end(), download_list_call(download));
if (!download->is_active() && rpc::call_command_d_value("get_d_state", download) == 1)
+1
View File
@@ -220,6 +220,7 @@ main(int argc, char** argv) {
//"schedule = scheduler,10,10,download_scheduler=\n"
"schedule = session_save,1800,1800,session_save=\n"
"schedule = low_diskspace,5,60,close_low_diskspace=500M\n"
// Changing these will bork the (non-existant) scheduler.
"view_add = scheduler\n"
+23 -11
View File
@@ -37,6 +37,7 @@
#include "config.h"
#include <unistd.h>
#include <rak/path.h>
#include <sys/types.h>
#include <sys/wait.h>
@@ -73,12 +74,12 @@ ExecFile::execute(const char* file, char* const* argv) {
}
torrent::Object
ExecFile::execute_object(const torrent::Object& rawArgs) {
char* argsBuffer[128];
ExecFile::execute_object(const torrent::Object& rawArgs, int flags) {
char* argsBuffer[max_args];
char** argsCurrent = argsBuffer;
// Size of strings are less than 24.
char valueBuffer[3072];
// Size of value strings are less than 24.
char valueBuffer[buffer_size];
char* valueCurrent = valueBuffer;
const torrent::Object::list_type& args = rawArgs.as_list();
@@ -87,18 +88,27 @@ ExecFile::execute_object(const torrent::Object& rawArgs) {
throw torrent::input_error("Too few arguments.");
for (torrent::Object::list_type::const_iterator itr = args.begin(), last = args.end(); itr != last; itr++, argsCurrent++) {
if (argsCurrent == argsBuffer + 128 - 1)
if (argsCurrent == argsBuffer + max_args - 1)
throw torrent::input_error("Too many arguments.");
switch (itr->type()) {
case torrent::Object::TYPE_STRING:
*argsCurrent = const_cast<char*>(itr->as_string().c_str());
break;
{
const std::string& str = itr->as_string();
if ((flags & flag_expand_tilde) && *str.c_str() == '~') {
*argsCurrent = valueCurrent;
valueCurrent = rak::path_expand(str.c_str(), valueCurrent, valueBuffer + buffer_size) + 1;
} else {
*argsCurrent = const_cast<char*>(str.c_str());
}
break;
}
case torrent::Object::TYPE_VALUE:
*argsCurrent = valueCurrent;
valueCurrent += std::max(snprintf(valueCurrent, valueBuffer + 3072 - valueCurrent, "%lli", itr->as_value()), 0);
valueCurrent += snprintf(valueCurrent, valueBuffer + buffer_size - valueCurrent, "%lli", itr->as_value()) + 1;
break;
default:
@@ -108,12 +118,14 @@ ExecFile::execute_object(const torrent::Object& rawArgs) {
*argsCurrent = NULL;
// Check if we overflowed the valueBuffer.
int status = execute(argsBuffer[0], argsBuffer);
if (status != 0)
throw torrent::input_error("ExecFile::execute_object(...) status != 0.");
if ((flags & flag_throw) && status != 0)
throw torrent::input_error("Bad return code.");
return torrent::Object();
return torrent::Object((int64_t)status);
}
}
+7 -2
View File
@@ -43,10 +43,15 @@ namespace rpc {
class ExecFile {
public:
static const unsigned int max_args = 128;
static const unsigned int buffer_size = 4096;
static const int flag_throw = 0x1;
static const int flag_expand_tilde = 0x2;
int execute(const char* file, char* const* argv);
torrent::Object execute_object(const torrent::Object& rawArgs);
torrent::Object execute_object(const torrent::Object& rawArgs, int flags);
private:
+1 -1
View File
@@ -94,7 +94,7 @@ SocketFd::set_dont_route(bool state) {
// SocketFd::set_bind_to_device(const char* device) {
// check_valid();
// struct ifreq ifr;
// strncpy(ifr.ifr_name, device, IFNAMSIZ);
// strlcpy(ifr.ifr_name, device, IFNAMSIZ);
// return setsockopt(m_fd, SOL_SOCKET, SO_BINDTODEVICE, &ifr, sizeof(ifr)) == 0;
// }