mirror of
https://github.com/rakshasa/rtorrent.git
synced 2026-08-13 05:32:31 +00:00
* Added xmlrpc calls for peer snubbed, banned and disconnect.
git-svn-id: svn://rakshasa.no/libtorrent/trunk/rtorrent@1180 e378c898-3ddf-0310-93e7-cc216c733640
This commit is contained in:
+40
-1
@@ -418,7 +418,8 @@ p_multicall(core::Download* download, const torrent::Object::list_type& args) {
|
||||
torrent::Object resultRaw = torrent::Object::create_list();
|
||||
torrent::Object::list_type& result = resultRaw.as_list();
|
||||
|
||||
for (torrent::ConnectionList::const_iterator itr = download->connection_list()->begin(), last = download->connection_list()->end(); itr != last; itr++) {
|
||||
for (torrent::ConnectionList::const_iterator itr = download->connection_list()->begin(), last = download->connection_list()->end();
|
||||
itr != last; itr++) {
|
||||
torrent::Object::list_type& row = result.insert(result.end(), torrent::Object::create_list())->as_list();
|
||||
|
||||
for (torrent::Object::list_const_iterator cItr = ++args.begin(), cLast = args.end(); cItr != args.end(); cItr++) {
|
||||
@@ -431,6 +432,42 @@ p_multicall(core::Download* download, const torrent::Object::list_type& args) {
|
||||
return resultRaw;
|
||||
}
|
||||
|
||||
torrent::Object
|
||||
p_call_target(const torrent::Object::list_type& args) {
|
||||
if (args.empty() || args.begin() + 1 == args.end() || args.begin() + 2 == args.end())
|
||||
throw torrent::input_error("Too few arguments.");
|
||||
|
||||
// We ignore the first arg for now, but it will be used for
|
||||
// selecting what files to include.
|
||||
|
||||
// Add some pre-parsing of the commands, so we don't spend time
|
||||
// parsing and searching command map for every single call.
|
||||
torrent::Object::list_const_iterator itr = args.begin();
|
||||
|
||||
core::Download* download = control->core()->download_list()->find_hex_ptr(itr++->as_string().c_str());
|
||||
const std::string& peer_id = itr++->as_string();
|
||||
const std::string& command_key = itr++->as_string();
|
||||
|
||||
torrent::HashString hash;
|
||||
|
||||
if (peer_id.size() != 40 ||
|
||||
torrent::hash_string_from_hex_c_str(peer_id.c_str(), hash) == peer_id.c_str())
|
||||
throw torrent::input_error("Not a hash string.");
|
||||
|
||||
torrent::ConnectionList::iterator peerItr = download->connection_list()->find(hash.c_str());
|
||||
|
||||
if (peerItr == download->connection_list()->end())
|
||||
throw torrent::input_error("Could not find peer.");
|
||||
|
||||
if (itr == args.end())
|
||||
return rpc::commands.call(command_key.c_str());
|
||||
|
||||
if (itr + 1 == args.end())
|
||||
return rpc::commands.call(command_key.c_str(), *itr);
|
||||
|
||||
return rpc::commands.call(command_key.c_str(), torrent::Object::create_list_range(itr, args.end()));
|
||||
}
|
||||
|
||||
//
|
||||
// New download commands and macros:
|
||||
//
|
||||
@@ -730,4 +767,6 @@ initialize_command_download() {
|
||||
CMD2_DL_LIST ("f.multicall", std::tr1::bind(&f_multicall, std::tr1::placeholders::_1, std::tr1::placeholders::_2));
|
||||
CMD2_DL_LIST ("p.multicall", std::tr1::bind(&p_multicall, std::tr1::placeholders::_1, std::tr1::placeholders::_2));
|
||||
CMD2_DL_LIST ("t.multicall", std::tr1::bind(&t_multicall, std::tr1::placeholders::_1, std::tr1::placeholders::_2));
|
||||
|
||||
CMD2_ANY_LIST ("p.call_target", std::tr1::bind(&p_call_target, std::tr1::placeholders::_2));
|
||||
}
|
||||
|
||||
@@ -295,12 +295,23 @@ xmlrpc_find_tracker(core::Download* download, uint32_t index) {
|
||||
return download->tracker_list()->at(index);
|
||||
}
|
||||
|
||||
torrent::Peer*
|
||||
xmlrpc_find_peer(core::Download* download, const torrent::HashString& hash) {
|
||||
torrent::ConnectionList::iterator itr = download->connection_list()->find(hash.c_str());
|
||||
|
||||
if (itr == download->connection_list()->end())
|
||||
return NULL;
|
||||
|
||||
return *itr;
|
||||
}
|
||||
|
||||
void
|
||||
initialize_xmlrpc() {
|
||||
rpc::xmlrpc.initialize();
|
||||
rpc::xmlrpc.set_slot_find_download(rak::mem_fn(control->core()->download_list(), &core::DownloadList::find_hex_ptr));
|
||||
rpc::xmlrpc.set_slot_find_file(rak::ptr_fn(&xmlrpc_find_file));
|
||||
rpc::xmlrpc.set_slot_find_tracker(rak::ptr_fn(&xmlrpc_find_tracker));
|
||||
rpc::xmlrpc.set_slot_find_peer(rak::ptr_fn(&xmlrpc_find_peer));
|
||||
|
||||
unsigned int count = 0;
|
||||
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
#include <rak/string_manip.h>
|
||||
#include <torrent/bitfield.h>
|
||||
#include <torrent/rate.h>
|
||||
#include <torrent/peer/connection_list.h>
|
||||
#include <torrent/peer/peer.h>
|
||||
#include <torrent/peer/peer_info.h>
|
||||
|
||||
@@ -118,4 +119,12 @@ initialize_command_peer() {
|
||||
CMD2_PEER("p.down_total", std::tr1::bind(&torrent::Rate::total, std::tr1::bind(&torrent::Peer::down_rate, std::tr1::placeholders::_1)));
|
||||
CMD2_PEER("p.peer_rate", std::tr1::bind(&torrent::Rate::rate, std::tr1::bind(&torrent::Peer::peer_rate, std::tr1::placeholders::_1)));
|
||||
CMD2_PEER("p.peer_total", std::tr1::bind(&torrent::Rate::total, std::tr1::bind(&torrent::Peer::peer_rate, std::tr1::placeholders::_1)));
|
||||
|
||||
CMD2_PEER ("p.snubbed", std::tr1::bind(&torrent::Peer::is_snubbed, std::tr1::placeholders::_1));
|
||||
CMD2_PEER_VALUE_V("p.snubbed.set", std::tr1::bind(&torrent::Peer::set_snubbed, std::tr1::placeholders::_1, std::tr1::placeholders::_2));
|
||||
CMD2_PEER ("p.banned", std::tr1::bind(&torrent::Peer::is_banned, std::tr1::placeholders::_1));
|
||||
CMD2_PEER_VALUE_V("p.banned.set", std::tr1::bind(&torrent::Peer::set_banned, std::tr1::placeholders::_1, std::tr1::placeholders::_2));
|
||||
|
||||
CMD2_PEER_V("p.disconnect", std::tr1::bind(&torrent::Peer::disconnect, std::tr1::placeholders::_1, 0));
|
||||
CMD2_PEER_V("p.disconnect_delayed", std::tr1::bind(&torrent::Peer::disconnect, std::tr1::placeholders::_1, torrent::ConnectionList::disconnect_delayed));
|
||||
}
|
||||
|
||||
@@ -127,7 +127,7 @@ public:
|
||||
const mapped_type call(key_type key, target_type target, const mapped_type& args = mapped_type()) { return call_command(key, args, target); }
|
||||
const mapped_type call_catch(key_type key, target_type target, const mapped_type& args = mapped_type(), const char* err = "Command failed: ");
|
||||
|
||||
const mapped_type call_command (key_type key, const mapped_type& arg, target_type target = target_type((int)command_base::target_generic, NULL));
|
||||
const mapped_type call_command (key_type key, const mapped_type& arg, target_type target = target_type((int)command_base::target_generic, NULL));
|
||||
const mapped_type call_command (iterator itr, const mapped_type& arg, target_type target = target_type((int)command_base::target_generic, NULL));
|
||||
|
||||
const mapped_type call_command_d(key_type key, core::Download* download, const mapped_type& arg) { return call_command(key, arg, target_type((int)command_base::target_download, download)); }
|
||||
|
||||
@@ -120,14 +120,6 @@ CommandScheduler::call_item(value_type item) {
|
||||
|
||||
void
|
||||
CommandScheduler::parse(const std::string& key, const std::string& bufAbsolute, const std::string& bufInterval, const std::string& command) {
|
||||
// char key[21];
|
||||
// char bufAbsolute[21];
|
||||
// char bufInterval[21];
|
||||
// char command[2048];
|
||||
|
||||
// if (std::sscanf(arg.c_str(), "%20[^,],%20[^,],%20[^,],%2047[^\n]", key, bufAbsolute, bufInterval, command) != 4)
|
||||
// throw torrent::input_error("Invalid arguments to command.");
|
||||
|
||||
uint32_t absolute = parse_absolute(bufAbsolute.c_str());
|
||||
uint32_t interval = parse_interval(bufInterval.c_str());
|
||||
|
||||
|
||||
@@ -218,6 +218,9 @@ SCgiTask::event_error() {
|
||||
|
||||
bool
|
||||
SCgiTask::receive_write(const char* buffer, uint32_t length) {
|
||||
if (buffer == NULL || length > (100 << 20))
|
||||
throw torrent::internal_error("SCgiTask::receive_write(...) received bad input.");
|
||||
|
||||
// Need to cast due to a bug in MacOSX gcc-4.0.1.
|
||||
if (length + 256 > std::max(m_bufferSize, (unsigned int)default_buffer_size))
|
||||
realloc_buffer(length + 256, NULL, 0);
|
||||
|
||||
+21
-7
@@ -41,6 +41,8 @@
|
||||
#include <xmlrpc-c/server.h>
|
||||
#endif
|
||||
|
||||
#include <cctype>
|
||||
#include <rak/string_manip.h>
|
||||
#include <torrent/object.h>
|
||||
#include <torrent/exceptions.h>
|
||||
|
||||
@@ -175,29 +177,38 @@ xmlrpc_to_target(xmlrpc_env* env, xmlrpc_value* value) {
|
||||
// Trackers: "<hash>:t<index>"
|
||||
|
||||
int index;
|
||||
const char* end;
|
||||
const char* end_ptr = str + 42;
|
||||
|
||||
switch (str[41]) {
|
||||
case 'f':
|
||||
end = str + 42;
|
||||
index = ::strtol(str + 42, (char**)&end, 0);
|
||||
index = ::strtol(str + 42, (char**)&end_ptr, 0);
|
||||
|
||||
if (*str == '\0' || *end != '\0')
|
||||
if (*str == '\0' || *end_ptr != '\0')
|
||||
throw xmlrpc_error(XMLRPC_TYPE_ERROR, "Invalid index.");
|
||||
|
||||
target = rpc::make_target(XmlRpc::call_file, xmlrpc.get_slot_find_file()(download, index));
|
||||
break;
|
||||
|
||||
case 't':
|
||||
end = str + 42;
|
||||
index = ::strtol(str + 42, (char**)&end, 0);
|
||||
index = ::strtol(str + 42, (char**)&end_ptr, 0);
|
||||
|
||||
if (*str == '\0' || *end != '\0')
|
||||
if (*str == '\0' || *end_ptr != '\0')
|
||||
throw xmlrpc_error(XMLRPC_TYPE_ERROR, "Invalid index.");
|
||||
|
||||
target = rpc::make_target(XmlRpc::call_tracker, xmlrpc.get_slot_find_tracker()(download, index));
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
{
|
||||
torrent::HashString hash;
|
||||
const char* hash_end = torrent::hash_string_from_hex_c_str(str + 42, hash);
|
||||
|
||||
if (hash_end == end_ptr || *hash_end != '\0')
|
||||
throw xmlrpc_error(XMLRPC_TYPE_ERROR, "Not a hash string.");
|
||||
|
||||
target = rpc::make_target(XmlRpc::call_peer, xmlrpc.get_slot_find_peer()(download, hash));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
::free((void*)str);
|
||||
throw xmlrpc_error(XMLRPC_TYPE_ERROR, "Unsupported target type found.");
|
||||
@@ -496,6 +507,9 @@ XmlRpc::process(const char* inBuffer, uint32_t length, slot_write slotWrite) {
|
||||
|
||||
xmlrpc_mem_block* memblock = xmlrpc_registry_process_call(&localEnv, (xmlrpc_registry*)m_registry, NULL, inBuffer, length);
|
||||
|
||||
if (localEnv.fault_occurred && localEnv.fault_code == XMLRPC_INTERNAL_ERROR)
|
||||
throw torrent::internal_error("Internal error in XMLRPC.");
|
||||
|
||||
bool result = slotWrite((const char*)xmlrpc_mem_block_contents(memblock),
|
||||
xmlrpc_mem_block_size(memblock));
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#define RTORRENT_RPC_XMLRPC_H
|
||||
|
||||
#include <rak/functional_fun.h>
|
||||
#include <torrent/hash_string.h>
|
||||
|
||||
namespace core {
|
||||
class Download;
|
||||
@@ -56,6 +57,7 @@ public:
|
||||
typedef rak::function1<core::Download*, const char*> slot_find_download;
|
||||
typedef rak::function2<torrent::File*, core::Download*, uint32_t> slot_find_file;
|
||||
typedef rak::function2<torrent::Tracker*, core::Download*, uint32_t> slot_find_tracker;
|
||||
typedef rak::function2<torrent::Peer*, core::Download*, const torrent::HashString&> slot_find_peer;
|
||||
typedef rak::function2<bool, const char*, uint32_t> slot_write;
|
||||
|
||||
static const int dialect_generic = 0;
|
||||
@@ -94,6 +96,9 @@ public:
|
||||
slot_find_tracker& get_slot_find_tracker() { return m_slotFindTracker; }
|
||||
void set_slot_find_tracker(slot_find_tracker::base_type* slot) { m_slotFindTracker.set(slot); }
|
||||
|
||||
slot_find_peer& get_slot_find_peer() { return m_slotFindPeer; }
|
||||
void set_slot_find_peer(slot_find_peer::base_type* slot) { m_slotFindPeer.set(slot); }
|
||||
|
||||
static int64_t size_limit();
|
||||
static void set_size_limit(uint64_t size);
|
||||
|
||||
@@ -106,6 +111,7 @@ private:
|
||||
slot_find_download m_slotFindDownload;
|
||||
slot_find_file m_slotFindFile;
|
||||
slot_find_tracker m_slotFindTracker;
|
||||
slot_find_peer m_slotFindPeer;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -250,7 +250,7 @@ ElementPeerList::receive_ban_peer() {
|
||||
if (m_listItr == m_list.end())
|
||||
return;
|
||||
|
||||
(*m_listItr)->set_banned();
|
||||
(*m_listItr)->set_banned(true);
|
||||
m_download->download()->connection_list()->erase(*m_listItr, torrent::ConnectionList::disconnect_quick);
|
||||
|
||||
update_itr();
|
||||
|
||||
Reference in New Issue
Block a user