mirror of
https://github.com/rakshasa/rtorrent.git
synced 2026-08-07 18:52:30 +00:00
* Added support for named pipes and proper parseing of arguments for
SCGI. git-svn-id: svn://rakshasa.no/libtorrent/trunk/rtorrent@906 e378c898-3ddf-0310-93e7-cc216c733640
This commit is contained in:
+20
-1
@@ -38,6 +38,7 @@
|
||||
|
||||
#include <functional>
|
||||
#include <rak/file_stat.h>
|
||||
#include <rak/path.h>
|
||||
#include <torrent/connection_manager.h>
|
||||
#include <torrent/tracker.h>
|
||||
#include <torrent/tracker_list.h>
|
||||
@@ -184,7 +185,25 @@ apply_scgi(const std::string& arg) {
|
||||
|
||||
// Fix this...
|
||||
control->set_scgi(new rpc::SCgi);
|
||||
control->scgi()->open(5000);
|
||||
|
||||
try {
|
||||
int port;
|
||||
char dummy;
|
||||
|
||||
if (std::sscanf(arg.c_str(), ":%i%c", &port, &dummy) == 1) {
|
||||
if (port <= 0 || port >= (1 << 16))
|
||||
throw torrent::input_error("Invalid port number.");
|
||||
|
||||
control->scgi()->open_port(port);
|
||||
|
||||
} else {
|
||||
control->scgi()->open_named(rak::path_expand(arg));
|
||||
}
|
||||
|
||||
} catch (torrent::local_error& e) {
|
||||
throw torrent::input_error(e.what());
|
||||
}
|
||||
|
||||
control->scgi()->set_slot_process(rak::mem_fn(control->xmlrpc(), &rpc::XmlRpc::process));
|
||||
}
|
||||
|
||||
|
||||
+33
-12
@@ -36,10 +36,11 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <rak/socket_address.h>
|
||||
#include <sys/un.h>
|
||||
#include <torrent/connection_manager.h>
|
||||
#include <torrent/poll.h>
|
||||
#include <torrent/torrent.h>
|
||||
#include <rak/socket_address.h>
|
||||
#include <torrent/exceptions.h>
|
||||
|
||||
#include "utils/socket_fd.h"
|
||||
@@ -62,21 +63,43 @@ SCgi::~SCgi() {
|
||||
get_fd().clear();
|
||||
}
|
||||
|
||||
bool
|
||||
SCgi::open(uint16_t port) {
|
||||
void
|
||||
SCgi::open_port(uint16_t port) {
|
||||
rak::socket_address sa;
|
||||
sa.sa_inet()->clear();
|
||||
sa.sa_inet()->set_port(port);
|
||||
|
||||
if (!get_fd().open_stream())
|
||||
throw torrent::resource_error("Could not allocate socket for listening.");
|
||||
throw torrent::resource_error("Could not open socket for listening.");
|
||||
|
||||
open(sa.c_sockaddr(), sa.length());
|
||||
}
|
||||
|
||||
void
|
||||
SCgi::open_named(const std::string& filename) {
|
||||
if (filename.empty() || filename.size() > 4096)
|
||||
throw torrent::resource_error("Invalid filename length.");
|
||||
|
||||
char buffer[sizeof(sockaddr_un) + filename.size()];
|
||||
sockaddr_un* sa = reinterpret_cast<sockaddr_un*>(buffer);
|
||||
|
||||
sa->sun_family = AF_LOCAL;
|
||||
std::memcpy(sa->sun_path, filename.c_str(), filename.size() + 1);
|
||||
|
||||
if (!get_fd().open_local())
|
||||
throw torrent::resource_error("Could not open socket for listening.");
|
||||
|
||||
open(sa, offsetof(struct sockaddr_un, sun_path) + filename.size() + 1);
|
||||
}
|
||||
|
||||
void
|
||||
SCgi::open(void* sa, unsigned int length) {
|
||||
try {
|
||||
rak::socket_address sa;
|
||||
sa.sa_inet()->clear();
|
||||
sa.sa_inet()->set_port(port);
|
||||
|
||||
if (!get_fd().set_nonblock() ||
|
||||
!get_fd().set_reuse_address(true) ||
|
||||
!get_fd().bind(sa) ||
|
||||
!get_fd().bind(*reinterpret_cast<rak::socket_address*>(sa), length) ||
|
||||
!get_fd().listen(10))
|
||||
throw torrent::resource_error("Could not allocate socket for listening.");
|
||||
throw torrent::resource_error("Could not prepare socket for listening.");
|
||||
|
||||
torrent::connection_manager()->inc_socket_count();
|
||||
|
||||
@@ -90,8 +113,6 @@ SCgi::open(uint16_t port) {
|
||||
|
||||
throw e;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
+4
-3
@@ -57,7 +57,8 @@ public:
|
||||
SCgi() {}
|
||||
virtual ~SCgi();
|
||||
|
||||
bool open(uint16_t port);
|
||||
void open_port(uint16_t port);
|
||||
void open_named(const std::string& filename);
|
||||
|
||||
const std::string path() const { return m_path; }
|
||||
|
||||
@@ -72,10 +73,10 @@ public:
|
||||
utils::SocketFd& get_fd() { return *reinterpret_cast<utils::SocketFd*>(&m_fileDesc); }
|
||||
|
||||
private:
|
||||
void open(void* sa, unsigned int length);
|
||||
|
||||
std::string m_path;
|
||||
|
||||
slot_process m_slotProcess;
|
||||
|
||||
SCgiTask m_task[10];
|
||||
};
|
||||
|
||||
|
||||
@@ -96,7 +96,10 @@ SCgiTask::event_read() {
|
||||
// Don't bother caching the parsed values, as we're likely to
|
||||
// receive all the data we need the first time.
|
||||
char* current;
|
||||
char* contentPos;
|
||||
|
||||
int headerSize = strtol(m_buffer, ¤t, 0);
|
||||
int contentSize;
|
||||
|
||||
if (current == m_buffer || current == m_position)
|
||||
// Need to validate the header size.
|
||||
@@ -111,8 +114,7 @@ SCgiTask::event_read() {
|
||||
if (std::memcmp(current, "CONTENT_LENGTH", 15) != 0)
|
||||
goto event_read_failed;
|
||||
|
||||
char* contentPos;
|
||||
int contentSize = strtol(current + 15, &contentPos, 0);
|
||||
contentSize = strtol(current + 15, &contentPos, 0);
|
||||
|
||||
if (*contentPos != '\0' || contentSize <= 0)
|
||||
goto event_read_failed;
|
||||
|
||||
@@ -120,6 +120,11 @@ SocketFd::open_datagram() {
|
||||
return (m_fd = socket(PF_INET, SOCK_DGRAM, 0)) != -1;
|
||||
}
|
||||
|
||||
bool
|
||||
SocketFd::open_local() {
|
||||
return (m_fd = socket(PF_LOCAL, SOCK_DGRAM, 0)) != -1;
|
||||
}
|
||||
|
||||
void
|
||||
SocketFd::close() {
|
||||
if (::close(m_fd) && errno == EBADF)
|
||||
@@ -133,6 +138,13 @@ SocketFd::bind(const rak::socket_address& sa) {
|
||||
return !::bind(m_fd, sa.c_sockaddr(), sa.length());
|
||||
}
|
||||
|
||||
bool
|
||||
SocketFd::bind(const rak::socket_address& sa, unsigned int length) {
|
||||
check_valid();
|
||||
|
||||
return !::bind(m_fd, sa.c_sockaddr(), length);
|
||||
}
|
||||
|
||||
bool
|
||||
SocketFd::connect(const rak::socket_address& sa) {
|
||||
check_valid();
|
||||
|
||||
@@ -69,11 +69,13 @@ public:
|
||||
|
||||
bool open_stream();
|
||||
bool open_datagram();
|
||||
bool open_local();
|
||||
void close();
|
||||
|
||||
void clear() { m_fd = -1; }
|
||||
|
||||
bool bind(const rak::socket_address& sa);
|
||||
bool bind(const rak::socket_address& sa, unsigned int length);
|
||||
bool connect(const rak::socket_address& sa);
|
||||
|
||||
bool listen(int size);
|
||||
|
||||
Reference in New Issue
Block a user