diff --git a/rak/error_number.h b/rak/error_number.h index dfe47b90..aa40deb9 100644 --- a/rak/error_number.h +++ b/rak/error_number.h @@ -63,7 +63,7 @@ public: bool is_valid() const { return m_errno != 0; } int value() const { return m_errno; } - const char* c_str() const { return strerror(m_errno); } + const char* c_str() const { return std::strerror(m_errno); } bool is_blocked_momentary() const { return m_errno == e_again || m_errno == e_intr; } bool is_blocked_prolonged() const { return m_errno == e_deadlk; } diff --git a/rak/timer.h b/rak/timer.h index 0a960ca9..cdb875ee 100644 --- a/rak/timer.h +++ b/rak/timer.h @@ -55,7 +55,12 @@ class timer { timer round_seconds() const { return (m_time / 1000000) * 1000000; } - timeval tval() const { return (timeval) { m_time / 1000000, m_time % 1000000}; } + timeval tval() const { + timeval val; + val.tv_sec = m_time / 1000000; + val.tv_usec = m_time % 1000000; + return val; + } static timer current(); static timer from_seconds(uint32_t seconds) { return rak::timer((uint64_t)seconds * 1000000); } diff --git a/src/Makefile.am b/src/Makefile.am index b0a6814a..128fc201 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -24,6 +24,7 @@ rtorrent_SOURCES = \ command_helpers.h \ command_local.cc \ command_network.cc \ + command_peer.cc \ command_tracker.cc \ command_ui.cc \ control.cc \ diff --git a/src/command_helpers.cc b/src/command_helpers.cc index bb508046..78a9281e 100644 --- a/src/command_helpers.cc +++ b/src/command_helpers.cc @@ -42,6 +42,7 @@ #include "rpc/command_variable.h" #include "rpc/command_download_slot.h" #include "rpc/command_file_slot.h" +#include "rpc/command_peer_slot.h" #include "rpc/command_tracker_slot.h" #include "globals.h" @@ -56,12 +57,15 @@ rpc::CommandDownloadSlot commandDownloadSlots[COMMAND_DOWNLOAD_SLOTS_SIZE]; rpc::CommandDownloadSlot* commandDownloadSlotsItr = commandDownloadSlots; rpc::CommandFileSlot commandFileSlots[COMMAND_FILE_SLOTS_SIZE]; rpc::CommandFileSlot* commandFileSlotsItr = commandFileSlots; +rpc::CommandPeerSlot commandPeerSlots[COMMAND_PEER_SLOTS_SIZE]; +rpc::CommandPeerSlot* commandPeerSlotsItr = commandPeerSlots; rpc::CommandTrackerSlot commandTrackerSlots[COMMAND_TRACKER_SLOTS_SIZE]; rpc::CommandTrackerSlot* commandTrackerSlotsItr = commandTrackerSlots; void initialize_command_download(); void initialize_command_events(); void initialize_command_file(); +void initialize_command_peer(); void initialize_command_local(); void initialize_command_network(); void initialize_command_tracker(); @@ -75,6 +79,7 @@ initialize_commands() { initialize_command_ui(); initialize_command_download(); initialize_command_file(); + initialize_command_peer(); initialize_command_tracker(); #ifdef ADDING_COMMANDS @@ -82,12 +87,14 @@ initialize_commands() { commandVariablesItr > commandVariables + COMMAND_VARIABLES_SIZE || commandDownloadSlotsItr > commandDownloadSlots + COMMAND_DOWNLOAD_SLOTS_SIZE || commandFileSlotsItr > commandFileSlots + COMMAND_FILE_SLOTS_SIZE || + commandPeerSlotsItr > commandPeerSlots + COMMAND_PEER_SLOTS_SIZE || commandTrackerSlotsItr > commandTrackerSlots + COMMAND_TRACKER_SLOTS_SIZE) #else if (commandSlotsItr != commandSlots + COMMAND_SLOTS_SIZE || commandVariablesItr != commandVariables + COMMAND_VARIABLES_SIZE || commandDownloadSlotsItr != commandDownloadSlots + COMMAND_DOWNLOAD_SLOTS_SIZE || commandFileSlotsItr != commandFileSlots + COMMAND_FILE_SLOTS_SIZE || + commandPeerSlotsItr != commandPeerSlots + COMMAND_PEER_SLOTS_SIZE || commandTrackerSlotsItr != commandTrackerSlots + COMMAND_TRACKER_SLOTS_SIZE) #endif throw torrent::internal_error("initialize_commands() static command array size mismatch."); diff --git a/src/command_helpers.h b/src/command_helpers.h index 57bd689f..46b99ce1 100644 --- a/src/command_helpers.h +++ b/src/command_helpers.h @@ -44,6 +44,7 @@ namespace rpc { class CommandVariable; class CommandDownloadSlot; class CommandFileSlot; + class CommandPeerSlot; class CommandTrackerSlot; } @@ -53,6 +54,7 @@ namespace rpc { #define COMMAND_VARIABLES_SIZE 100 #define COMMAND_DOWNLOAD_SLOTS_SIZE 100 #define COMMAND_FILE_SLOTS_SIZE 20 +#define COMMAND_PEER_SLOTS_SIZE 20 #define COMMAND_TRACKER_SLOTS_SIZE 15 #define ADDING_COMMANDS @@ -65,6 +67,8 @@ extern rpc::CommandDownloadSlot commandDownloadSlots[COMMAND_DOWNLOAD_SLOTS_SIZ extern rpc::CommandDownloadSlot* commandDownloadSlotsItr; extern rpc::CommandFileSlot commandFileSlots[COMMAND_FILE_SLOTS_SIZE]; extern rpc::CommandFileSlot* commandFileSlotsItr; +extern rpc::CommandPeerSlot commandPeerSlots[COMMAND_PEER_SLOTS_SIZE]; +extern rpc::CommandPeerSlot* commandPeerSlotsItr; extern rpc::CommandTrackerSlot commandTrackerSlots[COMMAND_TRACKER_SLOTS_SIZE]; extern rpc::CommandTrackerSlot* commandTrackerSlotsItr; diff --git a/src/command_peer.cc b/src/command_peer.cc new file mode 100644 index 00000000..6c94c4dc --- /dev/null +++ b/src/command_peer.cc @@ -0,0 +1,134 @@ +// rTorrent - BitTorrent client +// Copyright (C) 2005-2007, 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 +// +// Skomakerveien 33 +// 3185 Skoppum, NORWAY + +#include "config.h" + +#include +#include +#include + +#include "core/manager.h" +#include "rpc/command_slot.h" +#include "rpc/command_peer_slot.h" + +#include "globals.h" +#include "control.h" +#include "command_helpers.h" + +// void +// apply_f_set_priority(torrent::File* file, uint32_t value) { +// if (value > torrent::PRIORITY_HIGH) +// throw torrent::input_error("Invalid value."); + +// file->set_priority((torrent::priority_t)value); +// } + +// torrent::Object +// apply_f_path(torrent::File* file) { +// if (file->path()->empty()) +// return std::string(); + +// torrent::Object resultRaw(*file->path()->begin()); +// torrent::Object::string_type& result = resultRaw.as_string(); + +// for (torrent::Path::const_iterator itr = ++file->path()->begin(), last = file->path()->end(); itr != last; itr++) +// result += '/' + *itr; + +// return resultRaw; +// } + +// torrent::Object +// apply_f_path_components(torrent::File* file) { +// torrent::Object resultRaw(torrent::Object::TYPE_LIST); +// torrent::Object::list_type& result = resultRaw.as_list(); + +// for (torrent::Path::const_iterator itr = file->path()->begin(), last = file->path()->end(); itr != last; itr++) +// result.push_back(*itr); + +// return resultRaw; +// } + +// torrent::Object +// apply_f_path_depth(torrent::File* file) { +// return (int64_t)file->path()->size(); +// } + +#define ADD_CP_SLOT(key, function, slot, parm, doc) \ + commandPeerSlotsItr->set_slot(slot); \ + rpc::commands.insert_peer(key, commandPeerSlotsItr++, &rpc::CommandPeerSlot::function, rpc::CommandMap::flag_dont_delete, parm, doc); + +#define ADD_CP_SLOT_PUBLIC(key, function, slot, parm, doc) \ + commandPeerSlotsItr->set_slot(slot); \ + rpc::commands.insert_peer(key, commandPeerSlotsItr++, &rpc::CommandPeerSlot::function, rpc::CommandMap::flag_dont_delete | rpc::CommandMap::flag_public_xmlrpc, parm, doc); + +#define ADD_CP_VOID(key, slot) \ + ADD_CP_SLOT_PUBLIC("p.get_" key, call_unknown, rpc::object_f_fn(slot), "i:", "") + +#define ADD_CP_VALUE_UNI(key, get) \ + ADD_CP_SLOT_PUBLIC("p.get_" key, call_unknown, rpc::object_void_f_fn(get), "i:", "") + +#define ADD_CP_VALUE_BI(key, set, get) \ + ADD_CP_SLOT_PUBLIC("p.set_" key, call_value, rpc::object_value_f_fn(set), "i:i", "") \ + ADD_CP_SLOT_PUBLIC("p.get_" key, call_unknown, rpc::object_void_f_fn(get), "i:", "") + +#define ADD_CP_STRING_UNI(key, get) \ + ADD_CP_SLOT_PUBLIC("p.get_" key, call_unknown, rpc::object_void_f_fn(get), "s:", "") + +void +initialize_command_peer() { +// ADD_CP_VALUE_UNI("is_created", std::mem_fun(&torrent::Peer::is_created)); +// ADD_CP_VALUE_UNI("is_open", std::mem_fun(&torrent::Peer::is_open)); + +// ADD_CP_VALUE_UNI("size_bytes", std::mem_fun(&torrent::Peer::size_bytes)); +// ADD_CP_VALUE_UNI("size_chunks", std::mem_fun(&torrent::Peer::size_chunks)); +// ADD_CP_VALUE_UNI("completed_chunks", std::mem_fun(&torrent::Peer::completed_chunks)); + +// ADD_CP_VALUE_UNI("offset", std::mem_fun(&torrent::Peer::offset)); +// ADD_CP_VALUE_UNI("range_first", std::mem_fun(&torrent::Peer::range_first)); +// ADD_CP_VALUE_UNI("range_second", std::mem_fun(&torrent::Peer::range_second)); + +// ADD_CP_VALUE_BI("priority", std::ptr_fun(&apply_f_set_priority), std::mem_fun(&torrent::Peer::priority)); + +// ADD_CP_STRING_UNI("path", std::ptr_fun(&apply_f_path)); +// ADD_CP_STRING_UNI("path_components", std::ptr_fun(&apply_f_path_components)); +// ADD_CP_STRING_UNI("path_depth", std::ptr_fun(&apply_f_path_depth)); +// ADD_CP_STRING_UNI("frozen_path", std::mem_fun(&torrent::Peer::frozen_path)); + +// ADD_CP_VALUE_UNI("match_depth_prev", std::mem_fun(&torrent::Peer::match_depth_prev)); +// ADD_CP_VALUE_UNI("match_depth_next", std::mem_fun(&torrent::Peer::match_depth_next)); + +// ADD_CP_VALUE_UNI("last_touched", std::mem_fun(&torrent::Peer::last_touched)); +} diff --git a/src/core/download_factory.cc b/src/core/download_factory.cc index 4e102ca7..a2626c62 100644 --- a/src/core/download_factory.cc +++ b/src/core/download_factory.cc @@ -104,7 +104,9 @@ DownloadFactory::receive_load() { if (m_stream) throw torrent::internal_error("DownloadFactory::load() called on an object with m_stream != NULL"); - if (std::strncmp(m_uri.c_str(), "http://", 7) == 0) { + if (std::strncmp(m_uri.c_str(), "http://", 7) == 0 || + std::strncmp(m_uri.c_str(), "https://", 8) == 0 || + std::strncmp(m_uri.c_str(), "ftp://", 6) == 0) { // Http handling here. m_stream = new std::stringstream; HttpQueue::iterator itr = m_manager->http_queue()->insert(m_uri, m_stream); diff --git a/src/rpc/Makefile.am b/src/rpc/Makefile.am index 9ef45e1c..aa33195d 100644 --- a/src/rpc/Makefile.am +++ b/src/rpc/Makefile.am @@ -6,6 +6,8 @@ libsub_rpc_a_SOURCES = \ command_download_slot.h \ command_file_slot.cc \ command_file_slot.h \ + command_peer_slot.cc \ + command_peer_slot.h \ command_tracker_slot.cc \ command_tracker_slot.h \ command_map.cc \ diff --git a/src/rpc/command_map.cc b/src/rpc/command_map.cc index 5f36d27d..8e573d54 100644 --- a/src/rpc/command_map.cc +++ b/src/rpc/command_map.cc @@ -84,6 +84,14 @@ CommandMap::insert_file(key_type key, Command* variable, file_slot targetSlot, i itr->second.m_fileSlot = targetSlot; } +void +CommandMap::insert_peer(key_type key, Command* variable, peer_slot targetSlot, int flags, const char* parm, const char* doc) { + iterator itr = insert(key, variable, flags, parm, doc); + + itr->second.m_target = target_peer; + itr->second.m_peerSlot = targetSlot; +} + void CommandMap::insert_tracker(key_type key, Command* variable, tracker_slot targetSlot, int flags, const char* parm, const char* doc) { iterator itr = insert(key, variable, flags, parm, doc); @@ -103,10 +111,12 @@ CommandMap::insert(key_type key, const command_map_data_type src) { itr->second.m_target = src.m_target; + // This _should_ be optimized int just one assignment. switch (itr->second.m_target) { case target_generic: itr->second.m_genericSlot = src.m_genericSlot; break; case target_download: itr->second.m_downloadSlot = src.m_downloadSlot; break; case target_file: itr->second.m_fileSlot = src.m_fileSlot; break; + case target_peer: itr->second.m_peerSlot = src.m_peerSlot; break; case target_tracker: itr->second.m_trackerSlot = src.m_trackerSlot; break; default: throw torrent::internal_error("CommandMap::insert(...) Invalid target."); } @@ -123,10 +133,12 @@ CommandMap::call_command(key_type key, const mapped_type& arg, target_type targe (itr->second.m_target != target_generic && target.second == NULL)) throw torrent::input_error("Command type mis-match."); + // This _should_ be optimized int just two calls. switch (itr->second.m_target) { case target_generic: return itr->second.m_genericSlot(itr->second.m_variable, arg); case target_download: return itr->second.m_downloadSlot(itr->second.m_variable, (core::Download*)target.second, arg); case target_file: return itr->second.m_fileSlot(itr->second.m_variable, (torrent::File*)target.second, arg); + case target_peer: return itr->second.m_peerSlot(itr->second.m_variable, (torrent::Peer*)target.second, arg); case target_tracker: return itr->second.m_trackerSlot(itr->second.m_variable, (torrent::Tracker*)target.second, arg); default: throw torrent::internal_error("CommandMap::call_command(...) Invalid target."); } diff --git a/src/rpc/command_map.h b/src/rpc/command_map.h index fe2a2c1f..947f9812 100644 --- a/src/rpc/command_map.h +++ b/src/rpc/command_map.h @@ -48,6 +48,7 @@ namespace core { namespace torrent { class File; + class Peer; class Tracker; } @@ -66,6 +67,7 @@ struct command_map_data_type { typedef const torrent::Object (*generic_slot) (Command*, const torrent::Object&); typedef const torrent::Object (*download_slot)(Command*, core::Download*, const torrent::Object&); typedef const torrent::Object (*file_slot) (Command*, torrent::File*, const torrent::Object&); + typedef const torrent::Object (*peer_slot) (Command*, torrent::Peer*, const torrent::Object&); typedef const torrent::Object (*tracker_slot) (Command*, torrent::Tracker*, const torrent::Object&); command_map_data_type(Command* variable, int flags, const char* parm, const char* doc) : @@ -77,6 +79,7 @@ struct command_map_data_type { generic_slot m_genericSlot; download_slot m_downloadSlot; file_slot m_fileSlot; + peer_slot m_peerSlot; tracker_slot m_trackerSlot; }; @@ -94,6 +97,7 @@ public: typedef command_map_data_type::generic_slot generic_slot; typedef command_map_data_type::download_slot download_slot; typedef command_map_data_type::file_slot file_slot; + typedef command_map_data_type::peer_slot peer_slot; typedef command_map_data_type::tracker_slot tracker_slot; typedef torrent::Object mapped_type; @@ -112,7 +116,8 @@ public: static const int target_generic = 0; static const int target_download = 1; static const int target_file = 2; - static const int target_tracker = 3; + static const int target_peer = 3; + static const int target_tracker = 4; static const int flag_dont_delete = 0x1; static const int flag_public_xmlrpc = 0x2; @@ -125,16 +130,18 @@ public: iterator insert(key_type key, Command* variable, int flags, const char* parm, const char* doc); - void insert_generic(key_type key, Command* variable, generic_slot targetSlot, int flags, const char* parm, const char* doc); + void insert_generic (key_type key, Command* variable, generic_slot targetSlot, int flags, const char* parm, const char* doc); void insert_download(key_type key, Command* variable, download_slot targetSlot, int flags, const char* parm, const char* doc); - void insert_file(key_type key, Command* variable, file_slot targetSlot, int flags, const char* parm, const char* doc); - void insert_tracker(key_type key, Command* variable, tracker_slot targetSlot, int flags, const char* parm, const char* doc); + void insert_file (key_type key, Command* variable, file_slot targetSlot, int flags, const char* parm, const char* doc); + void insert_peer (key_type key, Command* variable, peer_slot targetSlot, int flags, const char* parm, const char* doc); + void insert_tracker (key_type key, Command* variable, tracker_slot targetSlot, int flags, const char* parm, const char* doc); void insert(key_type key, const command_map_data_type src); const mapped_type call_command(key_type key, const mapped_type& arg, target_type target = target_type((int)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)target_download, download)); } const mapped_type call_command_f(key_type key, torrent::File* file, const mapped_type& arg) { return call_command(key, arg, target_type((int)target_file, file)); } + const mapped_type call_command_p(key_type key, torrent::Peer* peer, const mapped_type& arg) { return call_command(key, arg, target_type((int)target_peer, peer)); } const mapped_type call_command_t(key_type key, torrent::Tracker* tracker, const mapped_type& arg) { return call_command(key, arg, target_type((int)target_tracker, tracker)); } private: diff --git a/src/rpc/command_peer_slot.cc b/src/rpc/command_peer_slot.cc new file mode 100644 index 00000000..a62f6a7f --- /dev/null +++ b/src/rpc/command_peer_slot.cc @@ -0,0 +1,123 @@ +// rTorrent - BitTorrent client +// Copyright (C) 2005-2007, 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 +// +// Skomakerveien 33 +// 3185 Skoppum, NORWAY + +#include "config.h" + +#include + +#include "parse.h" +#include "command_peer_slot.h" + +namespace rpc { + +const torrent::Object +CommandPeerSlot::call_unknown(Command* rawCommand, torrent::Peer* peer, const torrent::Object& rawArgs) { + CommandPeerSlot* command = static_cast(rawCommand); + + return command->m_slot(peer, rawArgs); +} + +const torrent::Object +CommandPeerSlot::call_list(Command* rawCommand, torrent::Peer* peer, const torrent::Object& rawArgs) { + CommandPeerSlot* command = static_cast(rawCommand); + + switch (rawArgs.type()) { + case torrent::Object::TYPE_LIST: + return command->m_slot(peer, rawArgs); + + case torrent::Object::TYPE_VALUE: + case torrent::Object::TYPE_STRING: + { + torrent::Object tmpList(torrent::Object::TYPE_LIST); + tmpList.as_list().push_back(rawArgs); + + return command->m_slot(peer, tmpList); + } + default: + throw torrent::input_error("Not a list."); + } +} + +const torrent::Object +CommandPeerSlot::call_value_base(Command* rawCommand, torrent::Peer* peer, const torrent::Object& rawArgs, int base, int unit) { + CommandPeerSlot* command = static_cast(rawCommand); + + const torrent::Object& arg = convert_to_single_argument(rawArgs); + + switch (arg.type()) { + case torrent::Object::TYPE_VALUE: + // Should shift this one too, so it gives the right unit. + return command->m_slot(peer, arg); + + case torrent::Object::TYPE_STRING: + { + torrent::Object argValue(torrent::Object::TYPE_VALUE); + + if (!parse_whole_value_nothrow(arg.as_string().c_str(), &argValue.as_value(), base, unit)) + throw torrent::input_error("Not a value."); + + return command->m_slot(peer, argValue); + } + default: + throw torrent::input_error("Not a value."); + } +} + +const torrent::Object +CommandPeerSlot::call_string(Command* rawCommand, torrent::Peer* peer, const torrent::Object& rawArgs) { + CommandPeerSlot* command = static_cast(rawCommand); + + const torrent::Object& arg = convert_to_single_argument(rawArgs); + + switch (arg.type()) { + case torrent::Object::TYPE_STRING: + return command->m_slot(peer, arg); + +// case torrent::Object::TYPE_NONE: +// throw torrent::input_error("CDS: void."); + +// case torrent::Object::TYPE_VALUE: +// throw torrent::input_error("CDS: value."); + +// case torrent::Object::TYPE_LIST: +// throw torrent::input_error("CDS: list."); + + default: + throw torrent::input_error("Not a string."); + } +} + +} diff --git a/src/rpc/command_peer_slot.h b/src/rpc/command_peer_slot.h new file mode 100644 index 00000000..920d1b02 --- /dev/null +++ b/src/rpc/command_peer_slot.h @@ -0,0 +1,176 @@ +// rTorrent - BitTorrent client +// Copyright (C) 2005-2007, 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 +// +// Skomakerveien 33 +// 3185 Skoppum, NORWAY + +#ifndef RTORRENT_RPC_COMMAND_PEER_SLOT_H +#define RTORRENT_RPC_COMMAND_PEER_SLOT_H + +#include +#include +#include +#include + +#include "command.h" + +namespace torrent { + class Peer; +} + +namespace rpc { + +class CommandPeerSlot : public Command { +public: + typedef rak::function2 slot_type; + + CommandPeerSlot() {} + + CommandPeerSlot(slot_type::base_type* s) { + m_slot.set(s); + } + + void set_slot(slot_type::base_type* s) { m_slot.set(s); } + + static const torrent::Object call_unknown(Command* rawCommand, torrent::Peer* peer, const torrent::Object& args); + + static const torrent::Object call_list(Command* rawCommand, torrent::Peer* peer, const torrent::Object& args); + static const torrent::Object call_string(Command* rawCommand, torrent::Peer* peer, const torrent::Object& args); + + static const torrent::Object call_value_base(Command* rawCommand, torrent::Peer* peer, const torrent::Object& args, int base, int unit); + + static const torrent::Object call_value(Command* rawCommand, torrent::Peer* peer, const torrent::Object& args) { return call_value_base(rawCommand, peer, args, 0, 1); } + static const torrent::Object call_value_kb(Command* rawCommand, torrent::Peer* peer, const torrent::Object& args) { return call_value_base(rawCommand, peer, args, 0, 1 << 10); } + + template + static const torrent::Object call_value(Command* rawCommand, torrent::Peer* peer, const torrent::Object& args) { return call_value_base(rawCommand, peer, args, base, unit); } + +// static const torrent::Object& get_list(Command* rawCommand, const torrent::Object& args); + +private: + slot_type m_slot; +}; + +// Some slots that convert torrent::Object arguments to proper +// function calls. + +template +class object_void_p_fn_t : public rak::function_base2 { +public: + object_void_p_fn_t(Func func) : m_func(func) {} + + virtual torrent::Object operator () (torrent::Peer* peer, const torrent::Object& arg1) { return torrent::Object(m_func(peer)); } + +private: + Func m_func; +}; + +template +class object_void_p_fn_t : public rak::function_base2 { +public: + object_void_p_fn_t(Func func) : m_func(func) {} + + virtual torrent::Object operator () (torrent::Peer* peer, const torrent::Object& arg1) { + m_func(peer); + return torrent::Object(); + } + +private: + Func m_func; +}; + +template +class object_value_p_fn1_t : public rak::function_base2 { +public: + object_value_p_fn1_t(Func func) : m_func(func) {} + + virtual torrent::Object operator () (torrent::Peer* peer, const torrent::Object& arg1) { + return torrent::Object((int64_t)m_func(peer, arg1.as_value())); + } + +private: + Func m_func; +}; + +template +class object_value_p_fn1_t : public rak::function_base2 { +public: + object_value_p_fn1_t(Func func) : m_func(func) {} + + virtual torrent::Object operator () (torrent::Peer* peer, const torrent::Object& arg1) { + m_func(peer, arg1.as_value()); + return torrent::Object(); + } + +private: + Func m_func; +}; + +template +class object_string_p_fn1_t : public rak::function_base2 { +public: + object_string_p_fn1_t(Func func) : m_func(func) {} + + virtual torrent::Object operator () (torrent::Peer* peer, const torrent::Object& arg1) { return torrent::Object(m_func(peer, arg1.as_string())); } + +private: + Func m_func; +}; + +template +class object_string_p_fn1_t : public rak::function_base2 { +public: + object_string_p_fn1_t(Func func) : m_func(func) {} + + virtual torrent::Object operator () (torrent::Peer* peer, const torrent::Object& arg1) { + m_func(peer, arg1.as_string()); + + return torrent::Object(); + } + +private: + Func m_func; +}; + +template object_void_p_fn_t* +object_p_fn(Return (*func)(torrent::Peer*)) { + return new object_void_p_fn_t(func); +} + +template object_void_p_fn_t* object_void_p_fn(Func func) { return new object_void_p_fn_t(func); } +template object_value_p_fn1_t* object_value_p_fn(Func func) { return new object_value_p_fn1_t(func); } +template object_string_p_fn1_t* object_string_p_fn(Func func) { return new object_string_p_fn1_t(func); } + +} + +#endif diff --git a/src/rpc/parse_commands.h b/src/rpc/parse_commands.h index 898360cb..caf65b92 100644 --- a/src/rpc/parse_commands.h +++ b/src/rpc/parse_commands.h @@ -105,9 +105,6 @@ inline void call_command_d_set_value(const char* key, core::Download* inline void call_command_d_set_string(const char* key, core::Download* download, const std::string& arg) { commands.call_command_d(key, download, torrent::Object(arg)); } inline void call_command_d_set_std_string(const std::string& key, core::Download* download, const std::string& arg) { commands.call_command_d(key.c_str(), download, torrent::Object(arg)); } -inline torrent::Object call_command_f(const char* key, torrent::File* file, const torrent::Object& obj) { return commands.call_command_f(key, file, obj); } -inline torrent::Object call_command_t(const char* key, torrent::Tracker* tracker, const torrent::Object& obj) { return commands.call_command_t(key, tracker, obj); } - inline torrent::Object call_command_d_range(const char* key, core::Download* download, torrent::Object::list_type::const_iterator first, torrent::Object::list_type::const_iterator last) { // Change to using range ctor. diff --git a/src/rpc/xmlrpc.cc b/src/rpc/xmlrpc.cc index 17329e81..18c5093d 100644 --- a/src/rpc/xmlrpc.cc +++ b/src/rpc/xmlrpc.cc @@ -397,7 +397,7 @@ xmlrpc_call_command_f(xmlrpc_env* env, xmlrpc_value* args, void* voidServerInfo) return NULL; try { - return object_to_xmlrpc(env, rpc::call_command_f((const char*)voidServerInfo, file, object)); + return object_to_xmlrpc(env, rpc::commands.call_command_f((const char*)voidServerInfo, file, object)); } catch (torrent::local_error& e) { xmlrpc_env_set_fault(env, XMLRPC_PARSE_ERROR, e.what()); @@ -414,7 +414,7 @@ xmlrpc_call_command_t(xmlrpc_env* env, xmlrpc_value* args, void* voidServerInfo) return NULL; try { - return object_to_xmlrpc(env, rpc::call_command_t((const char*)voidServerInfo, tracker, object)); + return object_to_xmlrpc(env, rpc::commands.call_command_t((const char*)voidServerInfo, tracker, object)); } catch (torrent::local_error& e) { xmlrpc_env_set_fault(env, XMLRPC_PARSE_ERROR, e.what());