mirror of
https://github.com/rakshasa/rtorrent.git
synced 2026-10-09 15:49:20 +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 <functional>
|
||||||
#include <rak/file_stat.h>
|
#include <rak/file_stat.h>
|
||||||
|
#include <rak/path.h>
|
||||||
#include <torrent/connection_manager.h>
|
#include <torrent/connection_manager.h>
|
||||||
#include <torrent/tracker.h>
|
#include <torrent/tracker.h>
|
||||||
#include <torrent/tracker_list.h>
|
#include <torrent/tracker_list.h>
|
||||||
@@ -184,7 +185,25 @@ apply_scgi(const std::string& arg) {
|
|||||||
|
|
||||||
// Fix this...
|
// Fix this...
|
||||||
control->set_scgi(new rpc::SCgi);
|
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));
|
control->scgi()->set_slot_process(rak::mem_fn(control->xmlrpc(), &rpc::XmlRpc::process));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+33
-12
@@ -36,10 +36,11 @@
|
|||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <rak/socket_address.h>
|
||||||
|
#include <sys/un.h>
|
||||||
#include <torrent/connection_manager.h>
|
#include <torrent/connection_manager.h>
|
||||||
#include <torrent/poll.h>
|
#include <torrent/poll.h>
|
||||||
#include <torrent/torrent.h>
|
#include <torrent/torrent.h>
|
||||||
#include <rak/socket_address.h>
|
|
||||||
#include <torrent/exceptions.h>
|
#include <torrent/exceptions.h>
|
||||||
|
|
||||||
#include "utils/socket_fd.h"
|
#include "utils/socket_fd.h"
|
||||||
@@ -62,21 +63,43 @@ SCgi::~SCgi() {
|
|||||||
get_fd().clear();
|
get_fd().clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
void
|
||||||
SCgi::open(uint16_t port) {
|
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())
|
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 {
|
try {
|
||||||
rak::socket_address sa;
|
|
||||||
sa.sa_inet()->clear();
|
|
||||||
sa.sa_inet()->set_port(port);
|
|
||||||
|
|
||||||
if (!get_fd().set_nonblock() ||
|
if (!get_fd().set_nonblock() ||
|
||||||
!get_fd().set_reuse_address(true) ||
|
!get_fd().set_reuse_address(true) ||
|
||||||
!get_fd().bind(sa) ||
|
!get_fd().bind(*reinterpret_cast<rak::socket_address*>(sa), length) ||
|
||||||
!get_fd().listen(10))
|
!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();
|
torrent::connection_manager()->inc_socket_count();
|
||||||
|
|
||||||
@@ -90,8 +113,6 @@ SCgi::open(uint16_t port) {
|
|||||||
|
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|||||||
+4
-3
@@ -57,7 +57,8 @@ public:
|
|||||||
SCgi() {}
|
SCgi() {}
|
||||||
virtual ~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; }
|
const std::string path() const { return m_path; }
|
||||||
|
|
||||||
@@ -72,10 +73,10 @@ public:
|
|||||||
utils::SocketFd& get_fd() { return *reinterpret_cast<utils::SocketFd*>(&m_fileDesc); }
|
utils::SocketFd& get_fd() { return *reinterpret_cast<utils::SocketFd*>(&m_fileDesc); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void open(void* sa, unsigned int length);
|
||||||
|
|
||||||
std::string m_path;
|
std::string m_path;
|
||||||
|
|
||||||
slot_process m_slotProcess;
|
slot_process m_slotProcess;
|
||||||
|
|
||||||
SCgiTask m_task[10];
|
SCgiTask m_task[10];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -96,7 +96,10 @@ SCgiTask::event_read() {
|
|||||||
// Don't bother caching the parsed values, as we're likely to
|
// Don't bother caching the parsed values, as we're likely to
|
||||||
// receive all the data we need the first time.
|
// receive all the data we need the first time.
|
||||||
char* current;
|
char* current;
|
||||||
|
char* contentPos;
|
||||||
|
|
||||||
int headerSize = strtol(m_buffer, ¤t, 0);
|
int headerSize = strtol(m_buffer, ¤t, 0);
|
||||||
|
int contentSize;
|
||||||
|
|
||||||
if (current == m_buffer || current == m_position)
|
if (current == m_buffer || current == m_position)
|
||||||
// Need to validate the header size.
|
// Need to validate the header size.
|
||||||
@@ -111,8 +114,7 @@ SCgiTask::event_read() {
|
|||||||
if (std::memcmp(current, "CONTENT_LENGTH", 15) != 0)
|
if (std::memcmp(current, "CONTENT_LENGTH", 15) != 0)
|
||||||
goto event_read_failed;
|
goto event_read_failed;
|
||||||
|
|
||||||
char* contentPos;
|
contentSize = strtol(current + 15, &contentPos, 0);
|
||||||
int contentSize = strtol(current + 15, &contentPos, 0);
|
|
||||||
|
|
||||||
if (*contentPos != '\0' || contentSize <= 0)
|
if (*contentPos != '\0' || contentSize <= 0)
|
||||||
goto event_read_failed;
|
goto event_read_failed;
|
||||||
|
|||||||
@@ -120,6 +120,11 @@ SocketFd::open_datagram() {
|
|||||||
return (m_fd = socket(PF_INET, SOCK_DGRAM, 0)) != -1;
|
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
|
void
|
||||||
SocketFd::close() {
|
SocketFd::close() {
|
||||||
if (::close(m_fd) && errno == EBADF)
|
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());
|
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
|
bool
|
||||||
SocketFd::connect(const rak::socket_address& sa) {
|
SocketFd::connect(const rak::socket_address& sa) {
|
||||||
check_valid();
|
check_valid();
|
||||||
|
|||||||
@@ -69,11 +69,13 @@ public:
|
|||||||
|
|
||||||
bool open_stream();
|
bool open_stream();
|
||||||
bool open_datagram();
|
bool open_datagram();
|
||||||
|
bool open_local();
|
||||||
void close();
|
void close();
|
||||||
|
|
||||||
void clear() { m_fd = -1; }
|
void clear() { m_fd = -1; }
|
||||||
|
|
||||||
bool bind(const rak::socket_address& sa);
|
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 connect(const rak::socket_address& sa);
|
||||||
|
|
||||||
bool listen(int size);
|
bool listen(int size);
|
||||||
|
|||||||
Reference in New Issue
Block a user