mirror of
https://github.com/rakshasa/rtorrent.git
synced 2026-10-11 08:39:21 +00:00
* Bumped to 0.11.5/0.7.5.
* Added "call.set_upload_rate", "call.get_upload_rate" and "call.get_directory" XMLRPC calls. git-svn-id: svn://rakshasa.no/libtorrent/trunk/rtorrent@888 e378c898-3ddf-0310-93e7-cc216c733640
This commit is contained in:
+2
-2
@@ -1,4 +1,4 @@
|
|||||||
AC_INIT(rtorrent, 0.7.4, jaris@ifi.uio.no)
|
AC_INIT(rtorrent, 0.7.5, jaris@ifi.uio.no)
|
||||||
|
|
||||||
AM_INIT_AUTOMAKE
|
AM_INIT_AUTOMAKE
|
||||||
AM_CONFIG_HEADER(config.h)
|
AM_CONFIG_HEADER(config.h)
|
||||||
@@ -22,7 +22,7 @@ TORRENT_WITHOUT_NCURSESW()
|
|||||||
TORRENT_WITHOUT_STATVFS()
|
TORRENT_WITHOUT_STATVFS()
|
||||||
TORRENT_WITHOUT_STATFS()
|
TORRENT_WITHOUT_STATFS()
|
||||||
|
|
||||||
PKG_CHECK_MODULES(STUFF, sigc++-2.0 libcurl >= 7.12.0 libtorrent >= 0.11.3,
|
PKG_CHECK_MODULES(STUFF, sigc++-2.0 libcurl >= 7.12.0 libtorrent >= 0.11.5,
|
||||||
CXXFLAGS="$CXXFLAGS $STUFF_CFLAGS";
|
CXXFLAGS="$CXXFLAGS $STUFF_CFLAGS";
|
||||||
LIBS="$LIBS $STUFF_LIBS")
|
LIBS="$LIBS $STUFF_LIBS")
|
||||||
|
|
||||||
|
|||||||
@@ -312,6 +312,8 @@ apply_fast_cgi(const std::string& arg) {
|
|||||||
|
|
||||||
if (control->xmlrpc() == NULL) {
|
if (control->xmlrpc() == NULL) {
|
||||||
control->set_xmlrpc(new rpc::XmlRpc);
|
control->set_xmlrpc(new rpc::XmlRpc);
|
||||||
|
control->xmlrpc()->set_slot_call_command_get(rak::mem_fn(control->variable(), &utils::VariableMap::call_command_get));
|
||||||
|
control->xmlrpc()->set_slot_call_command_set(rak::mem_fn(control->variable(), &utils::VariableMap::call_command_set));
|
||||||
}
|
}
|
||||||
|
|
||||||
control->set_fast_cgi(new rpc::FastCgi(arg));
|
control->set_fast_cgi(new rpc::FastCgi(arg));
|
||||||
|
|||||||
+3
-4
@@ -43,15 +43,14 @@
|
|||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <rak/functional_fun.h>
|
|
||||||
#include <torrent/exceptions.h>
|
|
||||||
|
|
||||||
#include "globals.h"
|
#include "globals.h"
|
||||||
#include "control.h"
|
#include "control.h"
|
||||||
#include "core/manager.h"
|
#include "core/manager.h"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <torrent/exceptions.h>
|
||||||
|
|
||||||
#include "fast_cgi.h"
|
#include "fast_cgi.h"
|
||||||
|
|
||||||
namespace rpc {
|
namespace rpc {
|
||||||
@@ -174,7 +173,7 @@ void FastCgi::event_read() {}
|
|||||||
void FastCgi::event_write() {}
|
void FastCgi::event_write() {}
|
||||||
void FastCgi::event_error() {}
|
void FastCgi::event_error() {}
|
||||||
|
|
||||||
void FastCgi::receive_write(const char* buffer, uint32_t length);
|
bool FastCgi::receive_write(const char* buffer, uint32_t length) { return false; }
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
+1
-5
@@ -38,15 +38,11 @@
|
|||||||
#define RTORRENT_RPC_FAST_CGI_H
|
#define RTORRENT_RPC_FAST_CGI_H
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <rak/functional_fun.h>
|
||||||
#include <torrent/event.h>
|
#include <torrent/event.h>
|
||||||
|
|
||||||
struct FCGX_Request;
|
struct FCGX_Request;
|
||||||
|
|
||||||
namespace rak {
|
|
||||||
template <typename Result, typename Arg1, typename Arg2> class function2;
|
|
||||||
template <typename Result, typename Arg1, typename Arg2, typename Arg3> class function3;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace rpc {
|
namespace rpc {
|
||||||
|
|
||||||
class FastCgi : public torrent::Event {
|
class FastCgi : public torrent::Event {
|
||||||
|
|||||||
+113
-13
@@ -36,37 +36,128 @@
|
|||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
|
#ifdef HAVE_XMLRPC_C
|
||||||
|
#include <stdlib.h>
|
||||||
#include <xmlrpc.h>
|
#include <xmlrpc.h>
|
||||||
#include <xmlrpc_server.h>
|
#include <xmlrpc_server.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <torrent/object.h>
|
||||||
|
#include <torrent/exceptions.h>
|
||||||
|
|
||||||
#include "xmlrpc.h"
|
#include "xmlrpc.h"
|
||||||
|
|
||||||
namespace rpc {
|
namespace rpc {
|
||||||
|
|
||||||
xmlrpc_value*
|
#ifdef HAVE_XMLRPC_C
|
||||||
xmlrpc_test_add(xmlrpc_env* env, xmlrpc_value* value, void* serverInfo) {
|
|
||||||
// Grabbed from the XMLRPC-C examples.
|
struct server_info_t {
|
||||||
xmlrpc_int32 x, y, z;
|
server_info_t(const char* command, XmlRpc::slot_call_command* callCommand) :
|
||||||
|
m_command(command), m_callCommand(callCommand) {}
|
||||||
|
|
||||||
|
const char* m_command;
|
||||||
|
XmlRpc::slot_call_command* m_callCommand;
|
||||||
|
};
|
||||||
|
|
||||||
|
xmlrpc_value*
|
||||||
|
xmlrpc_call_command(xmlrpc_env* env, xmlrpc_value* args, void* voidServerInfo) {
|
||||||
|
torrent::Object object(torrent::Object::TYPE_LIST);
|
||||||
|
torrent::Object::list_type& objectList = object.as_list();
|
||||||
|
|
||||||
|
if (xmlrpc_value_type(args) != XMLRPC_TYPE_ARRAY)
|
||||||
|
throw torrent::internal_error("xmlrpc_value_type(args) != XMLRPC_TYPE_ARRAY");
|
||||||
|
|
||||||
|
unsigned int last = xmlrpc_array_size(env, args);
|
||||||
|
|
||||||
/* Parse our argument array. */
|
|
||||||
xmlrpc_parse_value(env, value, "(ii)", &x, &y);
|
|
||||||
if (env->fault_occurred)
|
if (env->fault_occurred)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* Add our two numbers. */
|
for (unsigned int i = 0; i != last; i++) {
|
||||||
z = x + y;
|
xmlrpc_value* value;
|
||||||
|
xmlrpc_array_read_item(env, args, i, &value);
|
||||||
|
|
||||||
/* Return our result. */
|
if (env->fault_occurred)
|
||||||
return xmlrpc_build_value(env, "i", z);
|
return NULL;
|
||||||
|
|
||||||
|
switch (xmlrpc_value_type(value)) {
|
||||||
|
case XMLRPC_TYPE_INT:
|
||||||
|
int v;
|
||||||
|
xmlrpc_read_int(env, value, &v);
|
||||||
|
|
||||||
|
objectList.push_back(torrent::Object((int64_t)v));
|
||||||
|
break;
|
||||||
|
|
||||||
|
// case XMLRPC_TYPE_BOOL:
|
||||||
|
// case XMLRPC_TYPE_DOUBLE:
|
||||||
|
// case XMLRPC_TYPE_DATETIME:
|
||||||
|
|
||||||
|
case XMLRPC_TYPE_STRING:
|
||||||
|
const char* valueString;
|
||||||
|
xmlrpc_read_string(env, value, &valueString);
|
||||||
|
|
||||||
|
if (env->fault_occurred)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
objectList.push_back(torrent::Object(std::string(valueString)));
|
||||||
|
|
||||||
|
// Urgh, seriously?
|
||||||
|
::free((void*)valueString);
|
||||||
|
break;
|
||||||
|
|
||||||
|
// case XMLRPC_TYPE_BASE64:
|
||||||
|
// case XMLRPC_TYPE_ARRAY:
|
||||||
|
// case XMLRPC_TYPE_STRUCT:
|
||||||
|
// case XMLRPC_TYPE_C_PTR:
|
||||||
|
// case XMLRPC_TYPE_NIL:
|
||||||
|
// case XMLRPC_TYPE_DEAD:
|
||||||
|
default:
|
||||||
|
xmlrpc_env_set_fault(env, XMLRPC_TYPE_ERROR, "Unsupported type found.");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (env->fault_occurred)
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
server_info_t* serverInfo = reinterpret_cast<server_info_t*>(voidServerInfo);
|
||||||
|
|
||||||
|
const torrent::Object& resultObject = (*serverInfo->m_callCommand)(serverInfo->m_command, object);
|
||||||
|
|
||||||
|
xmlrpc_value* result;
|
||||||
|
xmlrpc_int32 tmpInt;
|
||||||
|
|
||||||
|
switch (resultObject.type()) {
|
||||||
|
case torrent::Object::TYPE_VALUE:
|
||||||
|
tmpInt = resultObject.as_value();
|
||||||
|
result = xmlrpc_build_value(env, "i", tmpInt);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case torrent::Object::TYPE_STRING:
|
||||||
|
result = xmlrpc_string_new(env, resultObject.as_string().c_str());
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
tmpInt = 1;
|
||||||
|
result = xmlrpc_build_value(env, "i", tmpInt);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
|
||||||
|
} catch (torrent::local_error& e) {
|
||||||
|
xmlrpc_env_set_fault(env, XMLRPC_PARSE_ERROR, e.what());
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
XmlRpc::XmlRpc() : m_env(new xmlrpc_env) {
|
XmlRpc::XmlRpc() : m_env(new xmlrpc_env) {
|
||||||
xmlrpc_env_init(m_env);
|
xmlrpc_env_init(m_env);
|
||||||
|
|
||||||
m_registry = xmlrpc_registry_new(m_env);
|
m_registry = xmlrpc_registry_new(m_env);
|
||||||
|
|
||||||
// Move this out.
|
xmlrpc_registry_add_method_w_doc(m_env, m_registry, NULL, "call.set_upload_rate", &xmlrpc_call_command, new server_info_t("upload_rate", &m_slotSet), "i:i", "");
|
||||||
xmlrpc_registry_add_method_w_doc(m_env, m_registry, NULL, "my.test", &xmlrpc_test_add, new int, "i:ii", "Not much.");
|
xmlrpc_registry_add_method_w_doc(m_env, m_registry, NULL, "call.get_upload_rate", &xmlrpc_call_command, new server_info_t("upload_rate", &m_slotGet), "i:", "");
|
||||||
|
|
||||||
|
xmlrpc_registry_add_method_w_doc(m_env, m_registry, NULL, "call.get_directory", &xmlrpc_call_command, new server_info_t("directory", &m_slotGet), "s:", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
XmlRpc::~XmlRpc() {
|
XmlRpc::~XmlRpc() {
|
||||||
@@ -90,4 +181,13 @@ XmlRpc::process(const char* inBuffer, uint32_t length, slot_write slotWrite) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
XmlRpc::XmlRpc() { throw torrent::resource_error("XMLRPC not supported."); }
|
||||||
|
XmlRpc::~XmlRpc() {}
|
||||||
|
|
||||||
|
bool XmlRpc::process(const char* inBuffer, uint32_t length, slot_write slotWrite) { return false; }
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,20 +42,31 @@
|
|||||||
typedef struct _xmlrpc_env xmlrpc_env;
|
typedef struct _xmlrpc_env xmlrpc_env;
|
||||||
typedef struct _xmlrpc_registry xmlrpc_registry;
|
typedef struct _xmlrpc_registry xmlrpc_registry;
|
||||||
|
|
||||||
|
namespace torrent {
|
||||||
|
class Object;
|
||||||
|
}
|
||||||
|
|
||||||
namespace rpc {
|
namespace rpc {
|
||||||
|
|
||||||
class XmlRpc {
|
class XmlRpc {
|
||||||
public:
|
public:
|
||||||
typedef rak::function2<bool, const char*, uint32_t> slot_write;
|
typedef rak::function2<bool, const char*, uint32_t> slot_write;
|
||||||
|
typedef rak::function2<const torrent::Object&, const char*, const torrent::Object&> slot_call_command;
|
||||||
|
|
||||||
XmlRpc();
|
XmlRpc();
|
||||||
~XmlRpc();
|
~XmlRpc();
|
||||||
|
|
||||||
bool process(const char* inBuffer, uint32_t length, slot_write slotWrite);
|
bool process(const char* inBuffer, uint32_t length, slot_write slotWrite);
|
||||||
|
|
||||||
|
void set_slot_call_command_get(slot_call_command::base_type* s) { m_slotGet.set(s); }
|
||||||
|
void set_slot_call_command_set(slot_call_command::base_type* s) { m_slotSet.set(s); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
xmlrpc_env* m_env;
|
xmlrpc_env* m_env;
|
||||||
xmlrpc_registry* m_registry;
|
xmlrpc_registry* m_registry;
|
||||||
|
|
||||||
|
slot_call_command m_slotGet;
|
||||||
|
slot_call_command m_slotSet;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -66,13 +66,13 @@ public:
|
|||||||
static const char* string_to_value_unit(const char* pos, value_type* value, int base, int unit);
|
static const char* string_to_value_unit(const char* pos, value_type* value, int base, int unit);
|
||||||
static bool string_to_value_unit_nothrow(const char* pos, value_type* value, int base, int unit);
|
static bool string_to_value_unit_nothrow(const char* pos, value_type* value, int base, int unit);
|
||||||
|
|
||||||
protected:
|
|
||||||
Variable(const Variable&);
|
|
||||||
void operator = (const Variable&);
|
|
||||||
|
|
||||||
// Temporary hack, until torrent::Object is extended to allow
|
// Temporary hack, until torrent::Object is extended to allow
|
||||||
// references so we can return a copy, not a const reference.
|
// references so we can return a copy, not a const reference.
|
||||||
static const torrent::Object m_emptyObject;
|
static const torrent::Object m_emptyObject;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Variable(const Variable&);
|
||||||
|
void operator = (const Variable&);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -172,15 +172,22 @@ VariableValueSlot::get() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
VariableValueSlot::set(const torrent::Object& arg) {
|
VariableValueSlot::set(const torrent::Object& rawArg) {
|
||||||
if (!m_slotSet.is_valid())
|
if (!m_slotSet.is_valid())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
const torrent::Object* arg;
|
||||||
|
|
||||||
|
if (rawArg.type() == torrent::Object::TYPE_LIST && rawArg.as_list().size() == 1)
|
||||||
|
arg = &rawArg.as_list().front();
|
||||||
|
else
|
||||||
|
arg = &rawArg;
|
||||||
|
|
||||||
value_type value;
|
value_type value;
|
||||||
|
|
||||||
switch (arg.type()) {
|
switch (arg->type()) {
|
||||||
case torrent::Object::TYPE_STRING:
|
case torrent::Object::TYPE_STRING:
|
||||||
string_to_value_unit(arg.as_string().c_str(), &value, m_base, m_unit);
|
string_to_value_unit(arg->as_string().c_str(), &value, m_base, m_unit);
|
||||||
|
|
||||||
// Check if we hit the end of the input.
|
// Check if we hit the end of the input.
|
||||||
|
|
||||||
@@ -188,7 +195,7 @@ VariableValueSlot::set(const torrent::Object& arg) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case torrent::Object::TYPE_VALUE:
|
case torrent::Object::TYPE_VALUE:
|
||||||
m_slotSet(arg.as_value());
|
m_slotSet(arg->as_value());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -236,4 +236,16 @@ VariableMap::process_file(key_type path) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const VariableMap::mapped_type&
|
||||||
|
VariableMap::call_command_get(key_type key, const mapped_type& arg) {
|
||||||
|
return get(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
const VariableMap::mapped_type&
|
||||||
|
VariableMap::call_command_set(key_type key, const mapped_type& arg) {
|
||||||
|
set(key, arg);
|
||||||
|
|
||||||
|
return Variable::m_emptyObject;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -117,6 +117,11 @@ public:
|
|||||||
void process_stream(std::istream* str);
|
void process_stream(std::istream* str);
|
||||||
bool process_file(key_type path);
|
bool process_file(key_type path);
|
||||||
|
|
||||||
|
// The new API, which is atm just a wrapper over the old and
|
||||||
|
// requires seperate calls to get and set. These will be merged.
|
||||||
|
const mapped_type& call_command_get(key_type key, const mapped_type& arg);
|
||||||
|
const mapped_type& call_command_set(key_type key, const mapped_type& arg);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
VariableMap(const VariableMap&);
|
VariableMap(const VariableMap&);
|
||||||
void operator = (const VariableMap&);
|
void operator = (const VariableMap&);
|
||||||
|
|||||||
Reference in New Issue
Block a user