From 69d1c9700a976b86559140562d3200314ac89c90 Mon Sep 17 00:00:00 2001 From: rakshasa Date: Wed, 13 May 2009 13:15:33 +0000 Subject: [PATCH] * Fixes the code that detects which peer was sending bad data. Peers are then automatically banned after sending three bad chunks. * Fixes a crash when parsing a malformed get_peers (or find_node) response throws an exception and fails to remove the corresponding transaction. Ticket #1622. * Fix automatic unchoking of new peers exceeding the max upload slots of the download. * Stops rtorrent from always creating and resizing ALL files, even those set to "off". Files will still be created, but with a size of zero, until a part of them is getting downloaded. This helps with filesystems that don't support sparse files (such as FAT, HFS+, and others). * Fix inefficient piece distribution due to linear chunk request strategy by randomizing position every few (on average 32) chunks, see ticket #190. * Fixes lack of return values for user-defined commands (using system.method.insert). When there are multiple commands, returns the result of the last one. git-svn-id: svn://rakshasa.no/libtorrent/trunk/rtorrent@1089 e378c898-3ddf-0310-93e7-cc216c733640 --- src/rpc/command_function.cc | 4 ++-- src/rpc/parse_commands.cc | 8 ++++++-- src/rpc/parse_commands.h | 17 +++++++++-------- 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/src/rpc/command_function.cc b/src/rpc/command_function.cc index 45e41d96..7f3c3313 100644 --- a/src/rpc/command_function.cc +++ b/src/rpc/command_function.cc @@ -68,14 +68,14 @@ CommandFunction::call(Command* rawCommand, target_type target, const torrent::Ob CommandFunction* command = reinterpret_cast(rawCommand); - parse_command_multiple(target, command->m_command.c_str(), command->m_command.c_str() + command->m_command.size()); + torrent::Object result = parse_command_multiple(target, command->m_command.c_str(), command->m_command.c_str() + command->m_command.size()); while (first-- != stack) { first->swap(*argument(std::distance(stack, first))); first->~Object(); } - return torrent::Object(); + return result; } const torrent::Object diff --git a/src/rpc/parse_commands.cc b/src/rpc/parse_commands.cc index 3cdc6fa9..16a1c17d 100644 --- a/src/rpc/parse_commands.cc +++ b/src/rpc/parse_commands.cc @@ -138,15 +138,19 @@ parse_command(target_type target, const char* first, const char* last) { return std::make_pair(commands.call_command(key.c_str(), args, target), first); } -void +torrent::Object parse_command_multiple(target_type target, const char* first, const char* last) { + parse_command_type result; + while (first != last) { // Should we check the return value? Probably not necessary as // parse_args throws on unquoted multi-word input. - parse_command_type result = parse_command(target, first, last); + result = parse_command(target, first, last); first = result.second; } + + return result.first; } parse_command_type diff --git a/src/rpc/parse_commands.h b/src/rpc/parse_commands.h index 11e9140d..64e1b4fc 100644 --- a/src/rpc/parse_commands.h +++ b/src/rpc/parse_commands.h @@ -60,13 +60,13 @@ typedef std::pair parse_command_type; // The generic parse command function, used by the rest. At some point // the 'download' parameter should be replaced by a more generic one. parse_command_type parse_command(target_type target, const char* first, const char* last); -void parse_command_multiple(target_type target, const char* first, const char* last); +torrent::Object parse_command_multiple(target_type target, const char* first, const char* last); // Make this take care of lists too. parse_command_type parse_command_object(target_type target, const torrent::Object& object); inline torrent::Object parse_command_single(target_type target, const char* first) { return parse_command(target, first, first + std::strlen(first)).first; } -inline void parse_command_multiple(target_type target, const char* first) { parse_command_multiple(target, first, first + std::strlen(first)); } +inline torrent::Object parse_command_multiple(target_type target, const char* first) { return parse_command_multiple(target, first, first + std::strlen(first)); } bool parse_command_file(const std::string& path); const char* parse_command_name(const char* first, const char* last, std::string* dest); @@ -81,12 +81,13 @@ parse_command_single_std(const std::string& cmd) { parse_command(make_target(), cmd.c_str(), cmd.c_str() + cmd.size()); } -inline void +inline torrent::Object parse_command_multiple_d_nothrow(core::Download* download, const std::string& cmd) { try { - parse_command_multiple(make_target(download), cmd.c_str(), cmd.c_str() + cmd.size()); + return parse_command_multiple(make_target(download), cmd.c_str(), cmd.c_str() + cmd.size()); } catch (torrent::input_error& e) { // Log? + return torrent::Object(); } } @@ -95,14 +96,14 @@ parse_command_d_single_std(core::Download* download, const std::string& cmd) { parse_command(make_target(download), cmd.c_str(), cmd.c_str() + cmd.size()); } -inline void +inline torrent::Object parse_command_multiple_std(const std::string& cmd) { - parse_command_multiple(make_target(), cmd.c_str(), cmd.c_str() + cmd.size()); + return parse_command_multiple(make_target(), cmd.c_str(), cmd.c_str() + cmd.size()); } -inline void +inline torrent::Object parse_command_d_multiple_std(core::Download* download, const std::string& cmd) { - parse_command_multiple(make_target(download), cmd.c_str(), cmd.c_str() + cmd.size()); + return parse_command_multiple(make_target(download), cmd.c_str(), cmd.c_str() + cmd.size()); } // inline torrent::Object call_command(const char* key, const torrent::Object& obj, target_type target = target_type((int)CommandMap::target_generic, NULL)) { return commands.call_command(key, obj); }