mirror of
https://github.com/rakshasa/rtorrent.git
synced 2026-08-06 18:22:32 +00:00
Compare commits
32 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a526ba58e9 | |||
| efd9507149 | |||
| 3d91dfdb33 | |||
| 30cec98799 | |||
| b825906034 | |||
| b05ecb5c5a | |||
| 900be334dc | |||
| 3a1da2fe34 | |||
| 70750a2bd3 | |||
| 1d2c424a70 | |||
| 8550facf43 | |||
| 184ead294a | |||
| 84bfc491ba | |||
| a2e0eca6e3 | |||
| 92eecdfd52 | |||
| 14219666c5 | |||
| a79a844dac | |||
| 59b6a013ce | |||
| b38f80e597 | |||
| 2d2a756a3c | |||
| 891a6ba69d | |||
| 2be730e4b3 | |||
| bf53700f97 | |||
| 946dc54f9b | |||
| ea2347734b | |||
| 5206e6cb88 | |||
| 48f82c17c2 | |||
| 675625255d | |||
| 658e9f7578 | |||
| e7a80c7b18 | |||
| 677f8f45c8 | |||
| ba1ba3096a |
@@ -14,7 +14,6 @@ EXTRA_DIST= \
|
||||
rak/path.h \
|
||||
rak/partial_queue.h \
|
||||
rak/regex.h \
|
||||
rak/socket_address.h \
|
||||
rak/string_manip.h \
|
||||
rak/unordered_vector.h \
|
||||
scripts/checks.m4 \
|
||||
|
||||
@@ -41,7 +41,7 @@ cd rtorrent
|
||||
|
||||
## Install build dependencies
|
||||
|
||||
Install [libtorrent](https://libtorrent.org/) with the same version rTorrent.
|
||||
Install [libtorrent](https://github.com/rakshasa/libtorrent) with the same version rTorrent.
|
||||
|
||||
Generate configure scripts:
|
||||
|
||||
@@ -57,7 +57,7 @@ docbook2man rtorrent.1.xml
|
||||
|
||||
Man pages output to "doc/rtorrent.1".
|
||||
|
||||
RTorrent follows the development of [libtorrent](https://libtorrent.org/) closely, and thus the versions must be in sync.
|
||||
RTorrent follows the development of [libtorrent](https://github.com/rakshasa/libtorrent) closely, and thus the versions must be in sync.
|
||||
|
||||
## USAGE
|
||||
|
||||
|
||||
+3
-3
@@ -1,6 +1,6 @@
|
||||
m4_pattern_allow([PKG_CHECK_EXISTS])
|
||||
|
||||
AC_INIT([rtorrent],[0.16.0],[sundell.software@gmail.com])
|
||||
AC_INIT([rtorrent],[0.16.4],[sundell.software@gmail.com])
|
||||
|
||||
AC_CONFIG_HEADERS([config.h])
|
||||
AC_CONFIG_MACRO_DIRS([scripts])
|
||||
@@ -11,7 +11,7 @@ LT_INIT
|
||||
|
||||
AC_PROG_CXX
|
||||
|
||||
AC_DEFINE([API_VERSION], [16], [api version])
|
||||
AC_DEFINE([API_VERSION], [18], [api version])
|
||||
|
||||
# Filter out unwanted flags added by autoconf on some systems, e.g. MacOS.
|
||||
TORRENT_REMOVE_UNWANTED(CXX, $CXX, -std=c++11 -std=gnu++11)
|
||||
@@ -48,7 +48,7 @@ if test "x$ax_cv_ncursesw" != xyes && test "x$ax_cv_ncurses" != xyes; then
|
||||
fi
|
||||
|
||||
PKG_CHECK_MODULES([CPPUNIT], [cppunit],, [no_cppunit="yes"])
|
||||
PKG_CHECK_MODULES([DEPENDENCIES], [libtorrent >= 0.16.0])
|
||||
PKG_CHECK_MODULES([DEPENDENCIES], [libtorrent >= 0.16.4])
|
||||
|
||||
AC_LANG_PUSH(C++)
|
||||
TORRENT_WITH_XMLRPC_C
|
||||
|
||||
+14
-4
@@ -4,20 +4,30 @@
|
||||
|
||||
# log.open_file = "log name", "file path"
|
||||
|
||||
log.open_file = "rtorrent.log", (cat,/tmp/rtorrent.log.,(system.pid))
|
||||
log.open_file = "rtorrent.log", (cat,/tmp/rtorrent.log.,(system.pid))
|
||||
|
||||
A newly opened log file is not connected to any logging events.
|
||||
|
||||
Some control over formatting will be provided at a later date.
|
||||
|
||||
## Appending to log files
|
||||
|
||||
log.append_file = "rtorrent.log", "/tmp/rtorrent.log"
|
||||
|
||||
The `log.open_file` clears any existing contents of the file. If you'd
|
||||
prefer to have a single log file that persists across application
|
||||
restarts, you can use the `log.append_file` in place of the
|
||||
`log.open_file` configuration key.
|
||||
|
||||
## Adding outputs to events
|
||||
|
||||
# log.add_output = "logging event", "log name"
|
||||
|
||||
log.add_output = "info", "rtorrent.log"
|
||||
|
||||
log.add_output = "dht_debug", "tracker.log"
|
||||
log.add_output = "tracker_debug", "tracker.log"
|
||||
log.add_output = "dht_all", "tracker.log"
|
||||
log.add_output = "tracker_events", "tracker.log"
|
||||
log.add_output = "tracker_requests", "tracker.log"
|
||||
|
||||
Each log handle can be added to multiple different logging events.
|
||||
|
||||
@@ -31,7 +41,7 @@ Each log handle can be added to multiple different logging events.
|
||||
"debug"
|
||||
|
||||
The above events receive logging events from all the sub-groups
|
||||
displayed below, and each event also reciving events from the event
|
||||
displayed below, and each event also receiving events from the event
|
||||
above in importance.
|
||||
|
||||
Thus some high-volume sub-group events such as “tracker\_debug” are not
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
\begin{verbatim}
|
||||
# log.open_file = "log name", "file path"
|
||||
|
||||
log.open_file = "rtorrent.log", (cat,/tmp/rtorrent.log.,(system.pid))
|
||||
log.open_file = "rtorrent.log", (cat,/tmp/rtorrent.log.,(system.pid))
|
||||
\end{verbatim}
|
||||
|
||||
A newly opened log file is not connected to any logging events.
|
||||
@@ -20,8 +20,9 @@ Some control over formatting will be provided at a later date.
|
||||
|
||||
log.add_output = "info", "rtorrent.log"
|
||||
|
||||
log.add_output = "dht_debug", "tracker.log"
|
||||
log.add_output = "tracker_debug", "tracker.log"
|
||||
log.add_output = "dht_all", "tracker.log"
|
||||
log.add_output = "tracker_events", "tracker.log"
|
||||
log.add_output = "tracker_requests", "tracker.log"
|
||||
\end{verbatim}
|
||||
|
||||
Each log handle can be added to multiple different logging events.
|
||||
|
||||
@@ -101,8 +101,11 @@ schedule2 = watch_load, 11, 10, ((load.verbose, (cat, (cfg.watch), "load/*.torre
|
||||
# Levels = critical error warn notice info debug
|
||||
# Groups = connection_* dht_* peer_* rpc_* storage_* thread_* tracker_* torrent_*
|
||||
print = (cat, "Logging to ", (cfg.logfile))
|
||||
|
||||
log.open_file = "log", (cfg.logfile)
|
||||
|
||||
log.add_output = "info", "log"
|
||||
##log.add_output = "tracker_debug", "log"
|
||||
#log.add_output = "tracker_events", "log"
|
||||
#log.add_output = "tracker_requests", "log"
|
||||
|
||||
### END of rtorrent.rc ###
|
||||
|
||||
@@ -136,6 +136,7 @@ rc.schedule2('watch_load', '11', '10', 'load.verbose=(cat, (cfg.watch), "load/*.
|
||||
rc.print('Logging to '..rc.cfg.logfile())
|
||||
rc.log.open_file('log', rc.cfg.logfile())
|
||||
rc.log.add_output('info', 'log')
|
||||
--rc.log.add_output('tracker_debug', 'log')
|
||||
--rc.log.add_output('tracker_events', 'log')
|
||||
--rc.log.add_output('tracker_requests', 'log')
|
||||
|
||||
--[[ END of rtorrent.rc.lua ]]--
|
||||
|
||||
@@ -0,0 +1,343 @@
|
||||
{
|
||||
<insert_a_suppression_name_here>
|
||||
Memcheck:Cond
|
||||
...
|
||||
fun:__76-*
|
||||
}
|
||||
{
|
||||
<insert_a_suppression_name_here>
|
||||
Memcheck:Value8
|
||||
...
|
||||
fun:__76-*
|
||||
}
|
||||
{
|
||||
<insert_a_suppression_name_here>
|
||||
Memcheck:Value8
|
||||
...
|
||||
fun:__80-*
|
||||
}
|
||||
{
|
||||
<insert_a_suppression_name_here>
|
||||
Memcheck:Cond
|
||||
...
|
||||
fun:__93-*
|
||||
}
|
||||
{
|
||||
<insert_a_suppression_name_here>
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:__93-*
|
||||
}
|
||||
{
|
||||
<insert_a_suppression_name_here>
|
||||
Memcheck:Cond
|
||||
...
|
||||
fun:__108-*
|
||||
}
|
||||
{
|
||||
<insert_a_suppression_name_here>
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:__108-*
|
||||
}
|
||||
{
|
||||
<insert_a_suppression_name_here>
|
||||
Memcheck:Value8
|
||||
...
|
||||
fun:__108-*
|
||||
}
|
||||
{
|
||||
<insert_a_suppression_name_here>
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:-[CFPrefsPlistSource setDomainIdentifier:]
|
||||
}
|
||||
{
|
||||
<insert_a_suppression_name_here>
|
||||
Memcheck:Cond
|
||||
...
|
||||
fun:-[CFPrefsSearchListSource alreadylocked_copyValueForKey:]
|
||||
}
|
||||
{
|
||||
<insert_a_suppression_name_here>
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:-[CFPrefsSearchListSource alreadylocked_copyValueForKey:]
|
||||
}
|
||||
{
|
||||
<insert_a_suppression_name_here>
|
||||
Memcheck:Value8
|
||||
...
|
||||
fun:-[CFPrefsSearchListSource alreadylocked_copyValueForKey:]
|
||||
}
|
||||
{
|
||||
<insert_a_suppression_name_here>
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:-[CFPrefsSearchListSource addNamedVolatileSourceForIdentifier:]
|
||||
}
|
||||
{
|
||||
<insert_a_suppression_name_here>
|
||||
Memcheck:Cond
|
||||
...
|
||||
fun:-[CFPrefsSearchListSource handleReply:toRequestNewDataMessage:onConnection:retryCount:error:]
|
||||
}
|
||||
{
|
||||
<insert_a_suppression_name_here>
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:-[CFPrefsSearchListSource addSourceForIdentifier:user:byHost:container:]
|
||||
}
|
||||
{
|
||||
<insert_a_suppression_name_here>
|
||||
Memcheck:Value8
|
||||
...
|
||||
fun:-[CFPrefsSearchListSource handleReply:toRequestNewDataMessage:onConnection:retryCount:error:]
|
||||
}
|
||||
{
|
||||
<insert_a_suppression_name_here>
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:-[CFPrefsSearchListSource handleReply:toRequestNewDataMessage:onConnection:retryCount:error:]
|
||||
}
|
||||
{
|
||||
<insert_a_suppression_name_here>
|
||||
Memcheck:Value8
|
||||
...
|
||||
fun:-[CFPrefsSearchListSource handleReply:toRequestNewDataMessage:onConnection:retryCount:error:]
|
||||
}
|
||||
{
|
||||
<insert_a_suppression_name_here>
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:-[_CFXPreferences copyAppValueForKey:identifier:container:configurationURL:]
|
||||
}
|
||||
{
|
||||
<insert_a_suppression_name_here>
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:-[_CFXPreferences withSearchListForIdentifier:container:cloudConfigurationURL:perform:]
|
||||
}
|
||||
{
|
||||
<insert_a_suppression_name_here>
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:-[_CFXPreferences withSearchLists:]
|
||||
}
|
||||
{
|
||||
<insert_a_suppression_name_here>
|
||||
Memcheck:Value8
|
||||
...
|
||||
fun:-[CFPrefsSource copyValueForKey:]
|
||||
}
|
||||
{
|
||||
<insert_a_suppression_name_here>
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:-[OS_xpc_object dealloc]
|
||||
}
|
||||
{
|
||||
<insert_a_suppression_name_here>
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:_CF*
|
||||
}
|
||||
{
|
||||
<insert_a_suppression_name_here>
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:__CF*
|
||||
}
|
||||
{
|
||||
<insert_a_suppression_name_here>
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:_NS*
|
||||
}
|
||||
{
|
||||
<insert_a_suppression_name_here>
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:getSuperclassMetadata
|
||||
}
|
||||
{
|
||||
<insert_a_suppression_name_here>
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:_ZN5dyld*
|
||||
}
|
||||
{
|
||||
<insert_a_suppression_name_here>
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:_ZNK5dyld*
|
||||
}
|
||||
{
|
||||
<insert_a_suppression_name_here>
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:___ZNK5dyld*
|
||||
}
|
||||
{
|
||||
<insert_a_suppression_name_here>
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:_dyld_*
|
||||
}
|
||||
{
|
||||
<insert_a_suppression_name_here>
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:*_dyld_*
|
||||
}
|
||||
{
|
||||
<insert_a_suppression_name_here>
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:___SC_getApplicationBundleID_block_invoke
|
||||
}
|
||||
{
|
||||
<insert_a_suppression_name_here>
|
||||
Memcheck:Cond
|
||||
...
|
||||
fun:xpc_*
|
||||
}
|
||||
{
|
||||
<insert_a_suppression_name_here>
|
||||
Memcheck:Value8
|
||||
...
|
||||
fun:xpc_*
|
||||
}
|
||||
{
|
||||
<insert_a_suppression_name_here>
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:_xpc_*
|
||||
}
|
||||
{
|
||||
<insert_a_suppression_name_here>
|
||||
Memcheck:Cond
|
||||
...
|
||||
fun:_xpc_*
|
||||
}
|
||||
{
|
||||
<insert_a_suppression_name_here>
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:_libxpc_*
|
||||
}
|
||||
{
|
||||
<insert_a_suppression_name_here>
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:si_module_with_name
|
||||
}
|
||||
{
|
||||
<insert_a_suppression_name_here>
|
||||
Memcheck:Cond
|
||||
...
|
||||
fun:_dispatch_*
|
||||
}
|
||||
{
|
||||
<insert_a_suppression_name_here>
|
||||
Memcheck:Value8
|
||||
...
|
||||
fun:_dispatch_*
|
||||
}
|
||||
{
|
||||
<insert_a_suppression_name_here>
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:_dispatch_*
|
||||
}
|
||||
{
|
||||
<insert_a_suppression_name_here>
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:*_swift_*
|
||||
}
|
||||
{
|
||||
<insert_a_suppression_name_here>
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:libdispatch_init
|
||||
}
|
||||
{
|
||||
<insert_a_suppression_name_here>
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:_os_*
|
||||
}
|
||||
{
|
||||
<insert_a_suppression_name_here>
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:_od_*
|
||||
}
|
||||
{
|
||||
<insert_a_suppression_name_here>
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:_objc_init
|
||||
}
|
||||
{
|
||||
<insert_a_suppression_name_here>
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:_notify_*
|
||||
}
|
||||
{
|
||||
<insert_a_suppression_name_here>
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:bootstrap_*
|
||||
}
|
||||
{
|
||||
<insert_a_suppression_name_here>
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:$ss*
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
<insert_a_suppression_name_here>
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:loadlocale
|
||||
fun:setlocale
|
||||
fun:main
|
||||
}
|
||||
{
|
||||
<insert_a_suppression_name_here>
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:initscr
|
||||
fun:_ZN7display6Canvas10initializeEv
|
||||
fun:_ZN7Control10initializeEv
|
||||
fun:main
|
||||
}
|
||||
{
|
||||
<insert_a_suppression_name_here>
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:assume_default_colors_sp
|
||||
fun:_ZN7display6Canvas10initializeEv
|
||||
fun:_ZN7Control10initializeEv
|
||||
fun:main
|
||||
}
|
||||
{
|
||||
<insert_a_suppression_name_here>
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:start_color_sp
|
||||
fun:_ZN7display6Canvas10initializeEv
|
||||
fun:_ZN7Control10initializeEv
|
||||
fun:main
|
||||
}
|
||||
{
|
||||
<insert_a_suppression_name_here>
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:_ZN7display6Canvas10initializeEv
|
||||
}
|
||||
+4
-39
@@ -1,36 +1,3 @@
|
||||
// rak - Rakshasa's toolbox
|
||||
// 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
|
||||
|
||||
// Wrapper for addrinfo with focus on zero-copy conversion to and from
|
||||
// the c-type and wrapper.
|
||||
//
|
||||
@@ -41,7 +8,7 @@
|
||||
#define RAK_ADDRESS_INFO_H
|
||||
|
||||
#include <netdb.h>
|
||||
#include <rak/socket_address.h>
|
||||
#include <cstring>
|
||||
|
||||
namespace rak {
|
||||
|
||||
@@ -57,13 +24,11 @@ public:
|
||||
|
||||
int socket_type() const { return m_addrinfo.ai_socktype; }
|
||||
void set_socket_type(int t) { m_addrinfo.ai_socktype = t; }
|
||||
|
||||
|
||||
int protocol() const { return m_addrinfo.ai_protocol; }
|
||||
void set_protocol(int p) { m_addrinfo.ai_protocol = p; }
|
||||
|
||||
size_t length() const { return m_addrinfo.ai_addrlen; }
|
||||
|
||||
socket_address* address() { return reinterpret_cast<socket_address*>(m_addrinfo.ai_addr); }
|
||||
size_t length() const { return m_addrinfo.ai_addrlen; }
|
||||
|
||||
addrinfo* c_addrinfo() { return &m_addrinfo; }
|
||||
const addrinfo* c_addrinfo() const { return &m_addrinfo; }
|
||||
@@ -86,7 +51,7 @@ address_info::get_address_info(const char* node, int pfamily, int stype, address
|
||||
hints.clear();
|
||||
hints.set_family(pfamily);
|
||||
hints.set_socket_type(stype);
|
||||
|
||||
|
||||
return ::getaddrinfo(node, NULL, hints.c_addrinfo(), reinterpret_cast<addrinfo**>(ai));
|
||||
}
|
||||
|
||||
|
||||
@@ -1,557 +0,0 @@
|
||||
// rak - Rakshasa's toolbox
|
||||
// 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 <sundell.software@gmail.com>
|
||||
|
||||
|
||||
// Wrappers for the various sockaddr types with focus on zero-copy
|
||||
// casting between the original type and the wrapper class.
|
||||
//
|
||||
// The default ctor does not initialize any data.
|
||||
//
|
||||
// _n suffixes indicate that the argument or return value is in
|
||||
// network byte order, _h that they are in hardware byte order.
|
||||
|
||||
// Add define for inet6 scope id?
|
||||
|
||||
#ifndef RAK_SOCKET_ADDRESS_H
|
||||
#define RAK_SOCKET_ADDRESS_H
|
||||
|
||||
#include <cinttypes>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
namespace rak {
|
||||
|
||||
class socket_address_inet;
|
||||
class socket_address_inet6;
|
||||
|
||||
class socket_address {
|
||||
public:
|
||||
static const sa_family_t af_inet = AF_INET;
|
||||
static const int pf_inet = PF_INET;
|
||||
static const sa_family_t af_inet6 = AF_INET6;
|
||||
static const int pf_inet6 = PF_INET6;
|
||||
static const sa_family_t af_unspec = AF_UNSPEC;
|
||||
static const int pf_unspec = PF_UNSPEC;
|
||||
|
||||
#ifdef AF_LOCAL
|
||||
static const sa_family_t af_local = AF_LOCAL;
|
||||
static const int pf_local = PF_LOCAL;
|
||||
#else
|
||||
static const sa_family_t af_local = AF_UNIX;
|
||||
static const int pf_local = PF_UNIX;
|
||||
#endif
|
||||
|
||||
bool is_any() const;
|
||||
bool is_valid() const;
|
||||
bool is_bindable() const;
|
||||
bool is_address_any() const;
|
||||
|
||||
bool is_valid_inet_class() const { return family() == af_inet || family() == af_inet6; }
|
||||
|
||||
void clear() { std::memset(this, 0, sizeof(socket_address)); set_family(); }
|
||||
|
||||
sa_family_t family() const { return m_sockaddr.sa_family; }
|
||||
void set_family() { m_sockaddr.sa_family = af_unspec; }
|
||||
|
||||
uint16_t port() const;
|
||||
void set_port(uint16_t p);
|
||||
|
||||
std::string address_str() const;
|
||||
bool address_c_str(char* buf, socklen_t size) const;
|
||||
|
||||
std::string pretty_address_str() const;
|
||||
|
||||
// Attemts to set it as an inet, then an inet6 address. It will
|
||||
// never set anything but net addresses, no local/unix.
|
||||
bool set_address_str(const std::string& a) { return set_address_c_str(a.c_str()); }
|
||||
bool set_address_c_str(const char* a);
|
||||
|
||||
uint32_t length() const;
|
||||
|
||||
socket_address_inet* sa_inet() { return reinterpret_cast<socket_address_inet*>(this); }
|
||||
const socket_address_inet* sa_inet() const { return reinterpret_cast<const socket_address_inet*>(this); }
|
||||
|
||||
sockaddr* c_sockaddr() { return &m_sockaddr; }
|
||||
sockaddr_in* c_sockaddr_inet() { return &m_sockaddrInet; }
|
||||
|
||||
const sockaddr* c_sockaddr() const { return &m_sockaddr; }
|
||||
const sockaddr_in* c_sockaddr_inet() const { return &m_sockaddrInet; }
|
||||
|
||||
socket_address_inet6* sa_inet6() { return reinterpret_cast<socket_address_inet6*>(this); }
|
||||
const socket_address_inet6* sa_inet6() const { return reinterpret_cast<const socket_address_inet6*>(this); }
|
||||
|
||||
sockaddr_in6* c_sockaddr_inet6() { return &m_sockaddrInet6; }
|
||||
const sockaddr_in6* c_sockaddr_inet6() const { return &m_sockaddrInet6; }
|
||||
|
||||
// Copy a socket address which has the length 'length. Zero out any
|
||||
// extranous bytes and ensure it does not go beyond the size of this
|
||||
// struct.
|
||||
void copy(const socket_address& src, size_t length);
|
||||
void copy_sockaddr(const sockaddr* src);
|
||||
|
||||
static socket_address* cast_from(sockaddr* sa) { return reinterpret_cast<socket_address*>(sa); }
|
||||
static const socket_address* cast_from(const sockaddr* sa) { return reinterpret_cast<const socket_address*>(sa); }
|
||||
|
||||
// The different families will be sorted according to the
|
||||
// sa_family_t's numeric value.
|
||||
bool operator == (const socket_address& rhs) const;
|
||||
bool operator < (const socket_address& rhs) const;
|
||||
|
||||
bool operator == (const sockaddr& rhs) const { return *this == *cast_from(&rhs); }
|
||||
bool operator == (const sockaddr* rhs) const { return *this == *cast_from(rhs); }
|
||||
bool operator < (const sockaddr& rhs) const { return *this == *cast_from(&rhs); }
|
||||
bool operator < (const sockaddr* rhs) const { return *this == *cast_from(rhs); }
|
||||
|
||||
private:
|
||||
union {
|
||||
sockaddr m_sockaddr;
|
||||
sockaddr_in m_sockaddrInet;
|
||||
sockaddr_in6 m_sockaddrInet6;
|
||||
};
|
||||
};
|
||||
|
||||
// Remember to set the AF_INET.
|
||||
|
||||
class socket_address_inet {
|
||||
public:
|
||||
bool is_any() const { return is_port_any() && is_address_any(); }
|
||||
bool is_valid() const { return !is_port_any() && !is_address_any(); }
|
||||
bool is_port_any() const { return port() == 0; }
|
||||
bool is_address_any() const { return m_sockaddr.sin_addr.s_addr == htonl(INADDR_ANY); }
|
||||
|
||||
void clear() { std::memset(this, 0, sizeof(socket_address_inet)); set_family(); }
|
||||
|
||||
uint16_t port() const { return ntohs(m_sockaddr.sin_port); }
|
||||
uint16_t port_n() const { return m_sockaddr.sin_port; }
|
||||
void set_port(uint16_t p) { m_sockaddr.sin_port = htons(p); }
|
||||
void set_port_n(uint16_t p) { m_sockaddr.sin_port = p; }
|
||||
|
||||
// Should address() return the uint32_t?
|
||||
in_addr address() const { return m_sockaddr.sin_addr; }
|
||||
uint32_t address_h() const { return ntohl(m_sockaddr.sin_addr.s_addr); }
|
||||
uint32_t address_n() const { return m_sockaddr.sin_addr.s_addr; }
|
||||
std::string address_str() const;
|
||||
bool address_c_str(char* buf, socklen_t size) const;
|
||||
|
||||
void set_address(in_addr a) { m_sockaddr.sin_addr = a; }
|
||||
void set_address_h(uint32_t a) { m_sockaddr.sin_addr.s_addr = htonl(a); }
|
||||
void set_address_n(uint32_t a) { m_sockaddr.sin_addr.s_addr = a; }
|
||||
bool set_address_str(const std::string& a) { return set_address_c_str(a.c_str()); }
|
||||
bool set_address_c_str(const char* a);
|
||||
|
||||
void set_address_any() { set_port(0); set_address_h(INADDR_ANY); }
|
||||
|
||||
sa_family_t family() const { return m_sockaddr.sin_family; }
|
||||
void set_family() { m_sockaddr.sin_family = AF_INET; }
|
||||
|
||||
sockaddr* c_sockaddr() { return reinterpret_cast<sockaddr*>(&m_sockaddr); }
|
||||
sockaddr_in* c_sockaddr_inet() { return &m_sockaddr; }
|
||||
|
||||
const sockaddr* c_sockaddr() const { return reinterpret_cast<const sockaddr*>(&m_sockaddr); }
|
||||
const sockaddr_in* c_sockaddr_inet() const { return &m_sockaddr; }
|
||||
|
||||
socket_address_inet6 to_mapped_address() const;
|
||||
|
||||
bool operator == (const socket_address_inet& rhs) const;
|
||||
bool operator < (const socket_address_inet& rhs) const;
|
||||
|
||||
private:
|
||||
struct sockaddr_in m_sockaddr;
|
||||
};
|
||||
|
||||
class socket_address_inet6 {
|
||||
public:
|
||||
bool is_any() const { return is_port_any() && is_address_any(); }
|
||||
bool is_valid() const { return !is_port_any() && !is_address_any(); }
|
||||
bool is_port_any() const { return port() == 0; }
|
||||
bool is_address_any() const { return std::memcmp(&m_sockaddr.sin6_addr, &in6addr_any, sizeof(in6_addr)) == 0; }
|
||||
|
||||
void clear() { std::memset(this, 0, sizeof(socket_address_inet6)); set_family(); }
|
||||
|
||||
uint16_t port() const { return ntohs(m_sockaddr.sin6_port); }
|
||||
uint16_t port_n() const { return m_sockaddr.sin6_port; }
|
||||
void set_port(uint16_t p) { m_sockaddr.sin6_port = htons(p); }
|
||||
void set_port_n(uint16_t p) { m_sockaddr.sin6_port = p; }
|
||||
|
||||
in6_addr address() const { return m_sockaddr.sin6_addr; }
|
||||
const in6_addr* address_ptr() const { return &m_sockaddr.sin6_addr; }
|
||||
std::string address_str() const;
|
||||
bool address_c_str(char* buf, socklen_t size) const;
|
||||
|
||||
void set_address(in6_addr a) { m_sockaddr.sin6_addr = a; }
|
||||
bool set_address_str(const std::string& a) { return set_address_c_str(a.c_str()); }
|
||||
bool set_address_c_str(const char* a);
|
||||
|
||||
void set_address_any() { set_port(0); set_address(in6addr_any); }
|
||||
|
||||
std::string pretty_address_str() const;
|
||||
|
||||
sa_family_t family() const { return m_sockaddr.sin6_family; }
|
||||
void set_family() { m_sockaddr.sin6_family = AF_INET6; }
|
||||
|
||||
sockaddr* c_sockaddr() { return reinterpret_cast<sockaddr*>(&m_sockaddr); }
|
||||
sockaddr_in6* c_sockaddr_inet6() { return &m_sockaddr; }
|
||||
|
||||
const sockaddr* c_sockaddr() const { return reinterpret_cast<const sockaddr*>(&m_sockaddr); }
|
||||
const sockaddr_in6* c_sockaddr_inet6() const { return &m_sockaddr; }
|
||||
|
||||
socket_address normalize_address() const;
|
||||
|
||||
bool operator == (const socket_address_inet6& rhs) const;
|
||||
bool operator < (const socket_address_inet6& rhs) const;
|
||||
|
||||
private:
|
||||
struct sockaddr_in6 m_sockaddr;
|
||||
};
|
||||
|
||||
inline bool
|
||||
socket_address::is_any() const {
|
||||
switch (family()) {
|
||||
case af_inet:
|
||||
return sa_inet()->is_any();
|
||||
case af_inet6:
|
||||
return sa_inet6()->is_any();
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
inline bool
|
||||
socket_address::is_valid() const {
|
||||
switch (family()) {
|
||||
case af_inet:
|
||||
return sa_inet()->is_valid();
|
||||
case af_inet6:
|
||||
return sa_inet6()->is_valid();
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
inline bool
|
||||
socket_address::is_bindable() const {
|
||||
switch (family()) {
|
||||
case af_inet:
|
||||
return !sa_inet()->is_address_any();
|
||||
case af_inet6:
|
||||
return !sa_inet6()->is_address_any();
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
inline bool
|
||||
socket_address::is_address_any() const {
|
||||
switch (family()) {
|
||||
case af_inet:
|
||||
return sa_inet()->is_address_any();
|
||||
case af_inet6:
|
||||
return sa_inet6()->is_address_any();
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
inline uint16_t
|
||||
socket_address::port() const {
|
||||
switch (family()) {
|
||||
case af_inet:
|
||||
return sa_inet()->port();
|
||||
case af_inet6:
|
||||
return sa_inet6()->port();
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
inline void
|
||||
socket_address::set_port(uint16_t p) {
|
||||
switch (family()) {
|
||||
case af_inet:
|
||||
return sa_inet()->set_port(p);
|
||||
case af_inet6:
|
||||
return sa_inet6()->set_port(p);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
inline std::string
|
||||
socket_address::address_str() const {
|
||||
switch (family()) {
|
||||
case af_inet:
|
||||
return sa_inet()->address_str();
|
||||
case af_inet6:
|
||||
return sa_inet6()->address_str();
|
||||
default:
|
||||
return std::string();
|
||||
}
|
||||
}
|
||||
|
||||
inline bool
|
||||
socket_address::address_c_str(char* buf, socklen_t size) const {
|
||||
switch (family()) {
|
||||
case af_inet:
|
||||
return sa_inet()->address_c_str(buf, size);
|
||||
case af_inet6:
|
||||
return sa_inet6()->address_c_str(buf, size);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
inline std::string
|
||||
socket_address::pretty_address_str() const {
|
||||
switch (family()) {
|
||||
case af_inet:
|
||||
return sa_inet()->address_str();
|
||||
case af_inet6:
|
||||
return sa_inet6()->pretty_address_str();
|
||||
case af_unspec:
|
||||
return std::string("unspec");
|
||||
default:
|
||||
return std::string("invalid");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
inline bool
|
||||
socket_address::set_address_c_str(const char* a) {
|
||||
if (sa_inet()->set_address_c_str(a)) {
|
||||
sa_inet()->set_family();
|
||||
return true;
|
||||
|
||||
} else if (sa_inet6()->set_address_c_str(a)) {
|
||||
sa_inet6()->set_family();
|
||||
return true;
|
||||
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Is the zero length really needed, should we require some length?
|
||||
inline uint32_t
|
||||
socket_address::length() const {
|
||||
switch(family()) {
|
||||
case af_inet:
|
||||
return sizeof(sockaddr_in);
|
||||
case af_inet6:
|
||||
return sizeof(sockaddr_in6);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
inline void
|
||||
socket_address::copy(const socket_address& src, size_t length) {
|
||||
length = std::min(length, sizeof(socket_address));
|
||||
|
||||
std::memset(this, 0, sizeof(socket_address));
|
||||
std::memcpy(this, &src, length);
|
||||
}
|
||||
|
||||
inline void
|
||||
socket_address::copy_sockaddr(const sockaddr* src) {
|
||||
std::memset(this, 0, sizeof(socket_address));
|
||||
std::memcpy(static_cast<void*>(this), src, socket_address::cast_from(src)->length());
|
||||
}
|
||||
|
||||
inline bool
|
||||
socket_address::operator == (const socket_address& rhs) const {
|
||||
if (family() != rhs.family())
|
||||
return false;
|
||||
|
||||
switch (family()) {
|
||||
case af_inet:
|
||||
return *sa_inet() == *rhs.sa_inet();
|
||||
case af_inet6:
|
||||
return *sa_inet6() == *rhs.sa_inet6();
|
||||
default:
|
||||
throw std::logic_error("socket_address::operator == (rhs) invalid type comparison.");
|
||||
}
|
||||
}
|
||||
|
||||
inline bool
|
||||
socket_address::operator < (const socket_address& rhs) const {
|
||||
if (family() != rhs.family())
|
||||
return family() < rhs.family();
|
||||
|
||||
switch (family()) {
|
||||
case af_inet:
|
||||
return *sa_inet() < *rhs.sa_inet();
|
||||
case af_inet6:
|
||||
return *sa_inet6() < *rhs.sa_inet6();
|
||||
default:
|
||||
throw std::logic_error("socket_address::operator < (rhs) invalid type comparison.");
|
||||
}
|
||||
}
|
||||
|
||||
inline std::string
|
||||
socket_address_inet::address_str() const {
|
||||
char buf[INET_ADDRSTRLEN];
|
||||
|
||||
if (!address_c_str(buf, INET_ADDRSTRLEN))
|
||||
return std::string();
|
||||
|
||||
return std::string(buf);
|
||||
}
|
||||
|
||||
inline bool
|
||||
socket_address_inet::address_c_str(char* buf, socklen_t size) const {
|
||||
return inet_ntop(family(), &m_sockaddr.sin_addr, buf, size);
|
||||
}
|
||||
|
||||
inline bool
|
||||
socket_address_inet::set_address_c_str(const char* a) {
|
||||
return inet_pton(AF_INET, a, &m_sockaddr.sin_addr);
|
||||
}
|
||||
|
||||
inline socket_address_inet6
|
||||
socket_address_inet::to_mapped_address() const {
|
||||
uint32_t addr32[4];
|
||||
addr32[0] = 0;
|
||||
addr32[1] = 0;
|
||||
addr32[2] = htonl(0xffff);
|
||||
addr32[3] = m_sockaddr.sin_addr.s_addr;
|
||||
|
||||
socket_address_inet6 sa;
|
||||
sa.clear();
|
||||
sa.set_address(*reinterpret_cast<in6_addr *>(addr32));
|
||||
sa.set_port_n(m_sockaddr.sin_port);
|
||||
return sa;
|
||||
}
|
||||
|
||||
inline bool
|
||||
socket_address_inet::operator == (const socket_address_inet& rhs) const {
|
||||
return
|
||||
m_sockaddr.sin_addr.s_addr == rhs.m_sockaddr.sin_addr.s_addr &&
|
||||
m_sockaddr.sin_port == rhs.m_sockaddr.sin_port;
|
||||
}
|
||||
|
||||
inline bool
|
||||
socket_address_inet::operator < (const socket_address_inet& rhs) const {
|
||||
return
|
||||
m_sockaddr.sin_addr.s_addr < rhs.m_sockaddr.sin_addr.s_addr ||
|
||||
(m_sockaddr.sin_addr.s_addr == rhs.m_sockaddr.sin_addr.s_addr &&
|
||||
m_sockaddr.sin_port < rhs.m_sockaddr.sin_port);
|
||||
}
|
||||
|
||||
inline std::string
|
||||
socket_address_inet6::address_str() const {
|
||||
char buf[INET6_ADDRSTRLEN];
|
||||
|
||||
if (!address_c_str(buf, INET6_ADDRSTRLEN))
|
||||
return std::string();
|
||||
|
||||
return std::string(buf);
|
||||
}
|
||||
|
||||
inline bool
|
||||
socket_address_inet6::address_c_str(char* buf, socklen_t size) const {
|
||||
return inet_ntop(family(), &m_sockaddr.sin6_addr, buf, size);
|
||||
}
|
||||
|
||||
inline bool
|
||||
socket_address_inet6::set_address_c_str(const char* a) {
|
||||
return inet_pton(AF_INET6, a, &m_sockaddr.sin6_addr);
|
||||
}
|
||||
|
||||
inline std::string
|
||||
socket_address_inet6::pretty_address_str() const {
|
||||
char buf[INET6_ADDRSTRLEN + 2 + 6];
|
||||
|
||||
if (inet_ntop(family(), &m_sockaddr.sin6_addr, buf + 1, INET6_ADDRSTRLEN) == NULL)
|
||||
return std::string();
|
||||
|
||||
buf[0] = '[';
|
||||
|
||||
char* last_char = (char*)std::memchr(buf + 1, 0, INET6_ADDRSTRLEN);
|
||||
|
||||
// TODO: Throw exception here.
|
||||
|
||||
if (last_char == NULL || last_char >= buf + 1 + INET6_ADDRSTRLEN)
|
||||
throw std::logic_error("inet_ntop for inet6 returned bad buffer");
|
||||
|
||||
*(last_char++) = ']';
|
||||
|
||||
if (!is_port_any()) {
|
||||
if (snprintf(last_char, 7, ":%" PRIu16, port()) == -1)
|
||||
return std::string("error"); // TODO: Throw here.
|
||||
|
||||
} else {
|
||||
*last_char = '\0';
|
||||
}
|
||||
|
||||
return std::string(buf);
|
||||
}
|
||||
|
||||
inline socket_address
|
||||
socket_address_inet6::normalize_address() const {
|
||||
const uint32_t *addr32 = reinterpret_cast<const uint32_t *>(m_sockaddr.sin6_addr.s6_addr);
|
||||
if (addr32[0] == 0 && addr32[1] == 0 && addr32[2] == htonl(0xffff)) {
|
||||
socket_address addr4;
|
||||
addr4.sa_inet()->set_family();
|
||||
addr4.sa_inet()->set_address_n(addr32[3]);
|
||||
addr4.sa_inet()->set_port_n(m_sockaddr.sin6_port);
|
||||
return addr4;
|
||||
}
|
||||
return *reinterpret_cast<const socket_address*>(this);
|
||||
}
|
||||
|
||||
inline bool
|
||||
socket_address_inet6::operator == (const socket_address_inet6& rhs) const {
|
||||
return
|
||||
memcmp(&m_sockaddr.sin6_addr, &rhs.m_sockaddr.sin6_addr, sizeof(in6_addr)) == 0 &&
|
||||
m_sockaddr.sin6_port == rhs.m_sockaddr.sin6_port;
|
||||
}
|
||||
|
||||
inline bool
|
||||
socket_address_inet6::operator < (const socket_address_inet6& rhs) const {
|
||||
int addr_comp = memcmp(&m_sockaddr.sin6_addr, &rhs.m_sockaddr.sin6_addr, sizeof(in6_addr));
|
||||
return
|
||||
addr_comp < 0 ||
|
||||
(addr_comp == 0 ||
|
||||
m_sockaddr.sin6_port < rhs.m_sockaddr.sin6_port);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
+2
-1
@@ -30,7 +30,8 @@ AC_DEFUN([TORRENT_REMOVE_UNWANTED],
|
||||
$1="$2"
|
||||
else
|
||||
result=`echo "${values_to_check}" | $GREP -Fvx -- "${unwanted_values}" | $GREP -v '^$'`
|
||||
$1=$(echo "$result" | tr -d '\n')
|
||||
# join with spaces, squeeze repeats, and trim trailing space
|
||||
$1=$(printf '%s\n' "$result" | tr '\n' ' ' | sed 's/ */ /g; s/ *$//')
|
||||
fi
|
||||
])
|
||||
|
||||
|
||||
+12
-20
@@ -6,9 +6,7 @@
|
||||
#include <netdb.h>
|
||||
#include <unistd.h>
|
||||
#include <rak/file_stat.h>
|
||||
#include <rak/error_number.h>
|
||||
#include <rak/path.h>
|
||||
#include <rak/socket_address.h>
|
||||
#include <rak/string_manip.h>
|
||||
#include <rak/regex.h>
|
||||
#include <torrent/rate.h>
|
||||
@@ -104,22 +102,19 @@ apply_d_change_link(core::Download* download, const torrent::Object::list_type&
|
||||
|
||||
switch (changeType) {
|
||||
case 0:
|
||||
if (symlink(target.c_str(), link.c_str()) == -1){
|
||||
lt_log_print(torrent::LOG_TORRENT_WARN, "create_link failed: %s",
|
||||
rak::error_number::current().c_str());
|
||||
}
|
||||
if (symlink(target.c_str(), link.c_str()) == -1)
|
||||
lt_log_print(torrent::LOG_TORRENT_WARN, "create_link failed: %s", std::strerror(errno));
|
||||
|
||||
break;
|
||||
|
||||
case 1:
|
||||
{
|
||||
rak::file_stat fileStat;
|
||||
rak::error_number::clear_global();
|
||||
errno = 0;
|
||||
|
||||
if (!fileStat.update_link(link) || !fileStat.is_link() || unlink(link.c_str()) == -1)
|
||||
lt_log_print(torrent::LOG_TORRENT_WARN, "delete_link failed: %s", std::strerror(errno));
|
||||
|
||||
if (!fileStat.update_link(link) || !fileStat.is_link() ||
|
||||
unlink(link.c_str()) == -1){
|
||||
lt_log_print(torrent::LOG_TORRENT_WARN, "delete_link failed: %s",
|
||||
rak::error_number::current().c_str());
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@@ -137,7 +132,7 @@ apply_d_delete_tied(core::Download* download) {
|
||||
return torrent::Object();
|
||||
|
||||
if (::unlink(rak::path_expand(tie).c_str()) == -1)
|
||||
control->core()->push_log_std("Could not unlink tied file: " + std::string(rak::error_number::current().c_str()));
|
||||
control->core()->push_log_std("Could not unlink tied file: " + std::string(std::strerror(errno)));
|
||||
|
||||
rpc::call_command("d.tied_to_file.set", std::string(), rpc::make_target(download));
|
||||
return torrent::Object();
|
||||
@@ -544,16 +539,13 @@ download_set_variable_string(core::Download* download, const torrent::Object::st
|
||||
//
|
||||
|
||||
torrent::Object
|
||||
d_list_push_back_string(core::Download* download, const torrent::Object& rawArgs, const char* first_key, const char* second_key) {
|
||||
auto& arg = rawArgs.as_string();
|
||||
d_list_push_back_string(core::Download* download, const std::string& arg, const char* first_key, const char* second_key) {
|
||||
download_get_variable(download, first_key, second_key).as_list().push_back(arg);
|
||||
|
||||
return torrent::Object();
|
||||
}
|
||||
|
||||
torrent::Object
|
||||
d_list_push_back_unique_string(core::Download* download, const torrent::Object& rawArgs, const char* first_key, const char* second_key) {
|
||||
auto& arg = rawArgs.as_string();
|
||||
d_list_push_back_unique_string(core::Download* download, const std::string& arg, const char* first_key, const char* second_key) {
|
||||
torrent::Object::list_type& list = download_get_variable(download, first_key, second_key).as_list();
|
||||
|
||||
if (std::none_of(list.begin(), list.end(), [arg](const torrent::Object& obj) { return torrent::object_equal(obj, arg); }))
|
||||
@@ -774,8 +766,8 @@ initialize_command_download() {
|
||||
CMD2_DL ("d.views", std::bind(&download_get_variable, std::placeholders::_1, "rtorrent", "views"));
|
||||
CMD2_DL ("d.views.has", std::bind(&d_list_has, std::placeholders::_1, std::placeholders::_2, "rtorrent", "views"));
|
||||
CMD2_DL ("d.views.remove", std::bind(&d_list_remove, std::placeholders::_1, std::placeholders::_2, "rtorrent", "views"));
|
||||
CMD2_DL ("d.views.push_back", std::bind(&d_list_push_back_string, std::placeholders::_1, std::placeholders::_2, "rtorrent", "views"));
|
||||
CMD2_DL ("d.views.push_back_unique", std::bind(&d_list_push_back_unique_string, std::placeholders::_1, std::placeholders::_2, "rtorrent", "views"));
|
||||
CMD2_DL_STRING ("d.views.push_back", std::bind(&d_list_push_back_string, std::placeholders::_1, std::placeholders::_2, "rtorrent", "views"));
|
||||
CMD2_DL_STRING ("d.views.push_back_unique", std::bind(&d_list_push_back_unique_string, std::placeholders::_1, std::placeholders::_2, "rtorrent", "views"));
|
||||
|
||||
// This command really needs to be improved, so we have proper
|
||||
// logging support.
|
||||
|
||||
@@ -411,7 +411,7 @@ initialize_command_dynamic() {
|
||||
|
||||
// Keep these for future use when we deprecate more commands.
|
||||
CMD2_VAR_BOOL ("method.use_deprecated", false);
|
||||
CMD2_VAR_VALUE ("method.use_intermediate", 0);
|
||||
CMD2_VAR_VALUE ("method.use_intermediate", 3);
|
||||
|
||||
CMD2_ANY_LIST ("method.insert", std::bind(&system_method_insert, std::placeholders::_2));
|
||||
CMD2_ANY_LIST ("method.insert.value", std::bind(&system_method_insert_object, std::placeholders::_2, rpc::object_storage::flag_value_type));
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
torrent::Object
|
||||
apply_on_ratio(const torrent::Object& rawArgs) {
|
||||
auto& group_name = rawArgs.as_string();
|
||||
auto view_itr = control->view_manager()->find(rpc::commands.call("group2." + group_name + ".view", rpc::make_target()).as_string());
|
||||
auto view_itr = control->view_manager()->find(rpc::commands.call("group." + group_name + ".view", rpc::make_target()).as_string());
|
||||
|
||||
if (view_itr == control->view_manager()->end())
|
||||
throw torrent::input_error("Could not find view.");
|
||||
@@ -33,9 +33,9 @@ apply_on_ratio(const torrent::Object& rawArgs) {
|
||||
// first argument: minimum ratio to reach
|
||||
// second argument: minimum upload amount to reach [optional]
|
||||
// third argument: maximum ratio to reach [optional]
|
||||
int64_t min_ratio = rpc::commands.call("group2." + group_name + ".ratio.min", rpc::make_target()).as_value();
|
||||
int64_t max_ratio = rpc::commands.call("group2." + group_name + ".ratio.max", rpc::make_target()).as_value();
|
||||
int64_t min_upload = rpc::commands.call("group2." + group_name + ".ratio.upload", rpc::make_target()).as_value();
|
||||
int64_t min_ratio = rpc::commands.call("group." + group_name + ".ratio.min", rpc::make_target()).as_value();
|
||||
int64_t max_ratio = rpc::commands.call("group." + group_name + ".ratio.max", rpc::make_target()).as_value();
|
||||
int64_t min_upload = rpc::commands.call("group." + group_name + ".ratio.upload", rpc::make_target()).as_value();
|
||||
|
||||
std::vector<core::Download*> downloads;
|
||||
|
||||
|
||||
@@ -1,37 +1,3 @@
|
||||
// rTorrent - BitTorrent client
|
||||
// Copyright (C) 2005-2011, 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 <sundell.software@gmail.com>
|
||||
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <torrent/exceptions.h>
|
||||
|
||||
+9
-12
@@ -100,24 +100,21 @@ void initialize_commands();
|
||||
CMD2_ANY(key, std::bind(&rpc::command_function_call_object, torrent::Object(torrent::raw_string::from_c_str(cmds)), \
|
||||
std::placeholders::_1, std::placeholders::_2));
|
||||
|
||||
#define CMD2_REDIRECT(from_key, to_key) \
|
||||
#define CMD2_REDIRECT(from_key, to_key) \
|
||||
rpc::commands.create_redirect(from_key, to_key, rpc::CommandMap::flag_public_rpc | rpc::CommandMap::flag_dont_delete);
|
||||
#define CMD2_REDIRECT_GENERIC(from_key, to_key) \
|
||||
rpc::commands.create_redirect(from_key, to_key, rpc::CommandMap::flag_public_rpc | rpc::CommandMap::flag_no_target | rpc::CommandMap::flag_dont_delete);
|
||||
#define CMD2_REDIRECT_GENERIC_NO_EXPORT(from_key, to_key) \
|
||||
rpc::commands.create_redirect(from_key, to_key, rpc::CommandMap::flag_no_target | rpc::CommandMap::flag_dont_delete);
|
||||
#define CMD2_REDIRECT_NO_EXPORT(from_key, to_key) \
|
||||
rpc::commands.create_redirect(from_key, to_key, rpc::CommandMap::flag_dont_delete);
|
||||
#define CMD2_REDIRECT_MUTABLE(from_key, to_key) \
|
||||
rpc::commands.create_redirect(from_key, to_key, rpc::CommandMap::flag_public_rpc);
|
||||
#define CMD2_REDIRECT_STR(from_key, to_key) \
|
||||
rpc::commands.create_redirect(from_key, to_key, rpc::CommandMap::flag_public_rpc);
|
||||
#define CMD2_REDIRECT_STR_NO_EXPORT(from_key, to_key) \
|
||||
rpc::commands.create_redirect(from_key, to_key, 0);
|
||||
#define CMD2_REDIRECT_FILE(from_key, to_key) \
|
||||
rpc::commands.create_redirect(from_key, to_key, rpc::CommandMap::flag_public_rpc | rpc::CommandMap::flag_file_target | rpc::CommandMap::flag_dont_delete);
|
||||
#define CMD2_REDIRECT_TRACKER(from_key, to_key) \
|
||||
rpc::commands.create_redirect(from_key, to_key, rpc::CommandMap::flag_public_rpc | rpc::CommandMap::flag_tracker_target | rpc::CommandMap::flag_dont_delete);
|
||||
|
||||
#define CMD2_REDIRECT_GENERIC_STR(from_key, to_key) \
|
||||
rpc::commands.create_redirect(from_key, to_key, \
|
||||
rpc::CommandMap::flag_public_rpc | rpc::CommandMap::flag_no_target);
|
||||
|
||||
#define CMD2_REDIRECT_GENERIC_STR_NO_EXPORT(from_key, to_key) \
|
||||
rpc::commands.create_redirect(from_key, to_key, \
|
||||
rpc::CommandMap::flag_no_target);
|
||||
|
||||
//
|
||||
// Conversion of return types:
|
||||
|
||||
+15
-27
@@ -116,34 +116,22 @@ group_insert(const torrent::Object::list_type& args) {
|
||||
"schedule_remove2=group." + name + ".ratio"));
|
||||
rpc::commands.call("method.insert", rpc::create_object_list("group." + name + ".ratio.command", "simple",
|
||||
"d.try_close= ;d.ignore_commands.set=1"));
|
||||
rpc::commands.call("method.insert", rpc::create_object_list("group2." + name + ".view", "string", view));
|
||||
rpc::commands.call("method.insert", rpc::create_object_list("group2." + name + ".ratio.min", "value", (int64_t)200));
|
||||
rpc::commands.call("method.insert", rpc::create_object_list("group2." + name + ".ratio.max", "value", (int64_t)300));
|
||||
rpc::commands.call("method.insert", rpc::create_object_list("group2." + name + ".ratio.upload", "value", (int64_t)20 << 20));
|
||||
rpc::commands.call("method.insert", rpc::create_object_list("group." + name + ".view", "string", view));
|
||||
rpc::commands.call("method.insert", rpc::create_object_list("group." + name + ".ratio.min", "value", (int64_t)200));
|
||||
rpc::commands.call("method.insert", rpc::create_object_list("group." + name + ".ratio.max", "value", (int64_t)300));
|
||||
rpc::commands.call("method.insert", rpc::create_object_list("group." + name + ".ratio.upload", "value", (int64_t)20 << 20));
|
||||
|
||||
if (rpc::call_command_value("method.use_intermediate") == 1) {
|
||||
// Deprecated in 0.7.0:
|
||||
if (rpc::call_command_value("method.use_intermediate") == 3) {
|
||||
// Cleaned up in 0.16.1:
|
||||
|
||||
CMD2_REDIRECT_GENERIC_STR("group." + name + ".view", "group2." + name + ".view");
|
||||
CMD2_REDIRECT_GENERIC_STR("group." + name + ".view.set", "group2." + name + ".view.set");
|
||||
CMD2_REDIRECT_GENERIC_STR("group." + name + ".ratio.min", "group2." + name + ".ratio.min");
|
||||
CMD2_REDIRECT_GENERIC_STR("group." + name + ".ratio.min.set", "group2." + name + ".ratio.min.set");
|
||||
CMD2_REDIRECT_GENERIC_STR("group." + name + ".ratio.max", "group2." + name + ".ratio.max");
|
||||
CMD2_REDIRECT_GENERIC_STR("group." + name + ".ratio.max.set", "group2." + name + ".ratio.max.set");
|
||||
CMD2_REDIRECT_GENERIC_STR("group." + name + ".ratio.upload", "group2." + name + ".ratio.upload");
|
||||
CMD2_REDIRECT_GENERIC_STR("group." + name + ".ratio.upload.set", "group2." + name + ".ratio.upload.set");
|
||||
|
||||
} if (rpc::call_command_value("method.use_intermediate") == 2) {
|
||||
// Deprecated in 0.7.0:
|
||||
|
||||
CMD2_REDIRECT_GENERIC_STR_NO_EXPORT("group." + name + ".view", "group2." + name + ".view");
|
||||
CMD2_REDIRECT_GENERIC_STR_NO_EXPORT("group." + name + ".view.set", "group2." + name + ".view.set");
|
||||
CMD2_REDIRECT_GENERIC_STR_NO_EXPORT("group." + name + ".ratio.min", "group2." + name + ".ratio.min");
|
||||
CMD2_REDIRECT_GENERIC_STR_NO_EXPORT("group." + name + ".ratio.min.set", "group2." + name + ".ratio.min.set");
|
||||
CMD2_REDIRECT_GENERIC_STR_NO_EXPORT("group." + name + ".ratio.max", "group2." + name + ".ratio.max");
|
||||
CMD2_REDIRECT_GENERIC_STR_NO_EXPORT("group." + name + ".ratio.max.set", "group2." + name + ".ratio.max.set");
|
||||
CMD2_REDIRECT_GENERIC_STR_NO_EXPORT("group." + name + ".ratio.upload", "group2." + name + ".ratio.upload");
|
||||
CMD2_REDIRECT_GENERIC_STR_NO_EXPORT("group." + name + ".ratio.upload.set", "group2." + name + ".ratio.upload.set");
|
||||
CMD2_REDIRECT_MUTABLE("group2." + name + ".view", "group." + name + ".view");
|
||||
CMD2_REDIRECT_MUTABLE("group2." + name + ".view.set", "group." + name + ".view.set");
|
||||
CMD2_REDIRECT_MUTABLE("group2." + name + ".ratio.min", "group." + name + ".ratio.min");
|
||||
CMD2_REDIRECT_MUTABLE("group2." + name + ".ratio.min.set", "group." + name + ".ratio.min.set");
|
||||
CMD2_REDIRECT_MUTABLE("group2." + name + ".ratio.max", "group." + name + ".ratio.max");
|
||||
CMD2_REDIRECT_MUTABLE("group2." + name + ".ratio.max.set", "group." + name + ".ratio.max.set");
|
||||
CMD2_REDIRECT_MUTABLE("group2." + name + ".ratio.upload", "group." + name + ".ratio.upload");
|
||||
CMD2_REDIRECT_MUTABLE("group2." + name + ".ratio.upload.set", "group." + name + ".ratio.upload.set");
|
||||
}
|
||||
|
||||
return name;
|
||||
@@ -248,7 +236,7 @@ initialize_command_local() {
|
||||
|
||||
CMD2_ANY_V ("system.shutdown.normal", std::bind(&Control::receive_normal_shutdown, control));
|
||||
CMD2_ANY_V ("system.shutdown.quick", std::bind(&Control::receive_quick_shutdown, control));
|
||||
CMD2_REDIRECT_GENERIC_NO_EXPORT("system.shutdown", "system.shutdown.normal");
|
||||
CMD2_REDIRECT_NO_EXPORT("system.shutdown", "system.shutdown.normal");
|
||||
|
||||
CMD2_ANY ("system.cwd", std::bind(&system_get_cwd));
|
||||
CMD2_ANY_STRING ("system.cwd.set", std::bind(&system_set_cwd, std::placeholders::_2));
|
||||
|
||||
+86
-68
@@ -7,10 +7,12 @@
|
||||
#include <rak/path.h>
|
||||
#include <torrent/torrent.h>
|
||||
#include <torrent/rate.h>
|
||||
#include <torrent/connection_manager.h>
|
||||
#include <torrent/data/file_manager.h>
|
||||
#include <torrent/download/resource_manager.h>
|
||||
#include <torrent/net/http_stack.h>
|
||||
#include <torrent/net/network_config.h>
|
||||
#include <torrent/net/network_manager.h>
|
||||
#include <torrent/net/socket_address.h>
|
||||
#include <torrent/tracker/tracker.h>
|
||||
#include <torrent/utils/log.h>
|
||||
#include <torrent/utils/option_strings.h>
|
||||
@@ -28,18 +30,18 @@
|
||||
|
||||
torrent::Object
|
||||
apply_encryption(const torrent::Object::list_type& args) {
|
||||
uint32_t options_mask = torrent::ConnectionManager::encryption_none;
|
||||
uint32_t options_mask = torrent::net::NetworkConfig::encryption_none;
|
||||
|
||||
for (const auto& arg : args) {
|
||||
uint32_t opt = torrent::option_find_string(torrent::OPTION_ENCRYPTION, arg.as_string().c_str());
|
||||
|
||||
if (opt == torrent::ConnectionManager::encryption_none)
|
||||
options_mask = torrent::ConnectionManager::encryption_none;
|
||||
if (opt == torrent::net::NetworkConfig::encryption_none)
|
||||
options_mask = torrent::net::NetworkConfig::encryption_none;
|
||||
else
|
||||
options_mask |= opt;
|
||||
}
|
||||
|
||||
torrent::connection_manager()->set_encryption_options(options_mask);
|
||||
torrent::config::network_config()->set_encryption_options(options_mask);
|
||||
|
||||
return torrent::Object();
|
||||
}
|
||||
@@ -51,7 +53,7 @@ apply_tos(const torrent::Object::string_type& arg) {
|
||||
if (!rpc::parse_whole_value_nothrow(arg.c_str(), &value, 16, 1))
|
||||
value = torrent::option_find_string(torrent::OPTION_IP_TOS, arg.c_str());
|
||||
|
||||
torrent::connection_manager()->set_priority(value);
|
||||
torrent::config::network_config()->set_priority(value);
|
||||
|
||||
return torrent::Object();
|
||||
}
|
||||
@@ -85,8 +87,7 @@ apply_scgi(const std::string& arg, int type) {
|
||||
rpc::SCgi* scgi = new rpc::SCgi;
|
||||
|
||||
rak::address_info* ai = NULL;
|
||||
rak::socket_address sa;
|
||||
rak::socket_address* saPtr;
|
||||
torrent::sa_unique_ptr sa;
|
||||
|
||||
try {
|
||||
int port, err;
|
||||
@@ -97,17 +98,17 @@ apply_scgi(const std::string& arg, int type) {
|
||||
switch (type) {
|
||||
case 1:
|
||||
if (std::sscanf(arg.c_str(), ":%i%c", &port, &dummy) == 1) {
|
||||
sa.sa_inet()->clear();
|
||||
saPtr = &sa;
|
||||
sa = torrent::sa_make_inet();
|
||||
|
||||
lt_log_print(torrent::LOG_RPC_EVENTS, "SCGI socket is open to any address and is a security risk");
|
||||
|
||||
} else if (std::sscanf(arg.c_str(), "%1023[^:]:%i%c", address, &port, &dummy) == 2 ||
|
||||
std::sscanf(arg.c_str(), "[%64[^]]]:%i%c", address, &port, &dummy) == 2) { // [xx::xx]:port format
|
||||
if ((err = rak::address_info::get_address_info(address,PF_UNSPEC, SOCK_STREAM, &ai)) != 0)
|
||||
|
||||
if ((err = rak::address_info::get_address_info(address, PF_UNSPEC, SOCK_STREAM, &ai)) != 0)
|
||||
throw torrent::input_error("Could not bind address: " + std::string(rak::address_info::strerror(err)) + ".");
|
||||
|
||||
saPtr = ai->address();
|
||||
sa = torrent::sa_copy(ai->c_addrinfo()->ai_addr);
|
||||
|
||||
lt_log_print(torrent::LOG_RPC_EVENTS, "SCGI socket is bound to an address and might be a security risk");
|
||||
|
||||
@@ -118,8 +119,8 @@ apply_scgi(const std::string& arg, int type) {
|
||||
if (port <= 0 || port >= (1 << 16))
|
||||
throw torrent::input_error("Invalid port number.");
|
||||
|
||||
saPtr->set_port(port);
|
||||
scgi->open_port(saPtr, saPtr->length(), rpc::call_command_value("network.scgi.dont_route"));
|
||||
torrent::sap_set_port(sa, port);
|
||||
scgi->open_port(sa.get(), torrent::sap_length(sa), rpc::call_command_value("network.scgi.dont_route"));
|
||||
|
||||
break;
|
||||
|
||||
@@ -165,8 +166,10 @@ apply_xmlrpc_dialect(const std::string& arg) {
|
||||
void
|
||||
initialize_command_network() {
|
||||
auto cm = torrent::connection_manager();
|
||||
auto fileManager = torrent::file_manager();
|
||||
auto file_manager = torrent::file_manager();
|
||||
auto http_stack = torrent::net_thread::http_stack();
|
||||
auto nw_config = torrent::config::network_config();
|
||||
auto nw_manager = torrent::runtime::network_manager();
|
||||
|
||||
CMD2_ANY_STRING ("encoding.add", std::bind(&apply_encoding_list, std::placeholders::_2));
|
||||
|
||||
@@ -175,76 +178,91 @@ initialize_command_network() {
|
||||
CMD2_VAR_BOOL ("network.port_random", true);
|
||||
CMD2_VAR_STRING ("network.port_range", "6881-6999");
|
||||
|
||||
CMD2_ANY ("network.listen.port", std::bind(&torrent::ConnectionManager::listen_port, cm));
|
||||
CMD2_ANY ("network.listen.backlog", std::bind(&torrent::ConnectionManager::listen_backlog, cm));
|
||||
CMD2_ANY_VALUE_V ("network.listen.backlog.set", std::bind(&torrent::ConnectionManager::set_listen_backlog, cm, std::placeholders::_2));
|
||||
CMD2_ANY ("network.listen.port", [nw_manager](auto, auto) { return nw_manager->listen_port(); });
|
||||
CMD2_ANY ("network.listen.backlog", [nw_config](auto, auto) { return nw_config->listen_backlog(); });
|
||||
CMD2_ANY_VALUE_V ("network.listen.backlog.set", [nw_config](auto, auto& value) { return nw_config->set_listen_backlog(value); });
|
||||
|
||||
CMD2_VAR_BOOL ("protocol.pex", true);
|
||||
CMD2_ANY_LIST ("protocol.encryption.set", std::bind(&apply_encryption, std::placeholders::_2));
|
||||
CMD2_VAR_BOOL ("protocol.pex", true);
|
||||
CMD2_ANY_LIST ("protocol.encryption.set", [](auto, auto& args) { return apply_encryption(args); });
|
||||
|
||||
CMD2_VAR_STRING ("protocol.connection.leech", "leech");
|
||||
CMD2_VAR_STRING ("protocol.connection.seed", "seed");
|
||||
CMD2_VAR_STRING ("protocol.connection.leech", "leech");
|
||||
CMD2_VAR_STRING ("protocol.connection.seed", "seed");
|
||||
|
||||
CMD2_VAR_STRING ("protocol.choke_heuristics.up.leech", "upload_leech");
|
||||
CMD2_VAR_STRING ("protocol.choke_heuristics.up.seed", "upload_leech");
|
||||
CMD2_VAR_STRING ("protocol.choke_heuristics.up.leech", "upload_leech");
|
||||
CMD2_VAR_STRING ("protocol.choke_heuristics.up.seed", "upload_leech");
|
||||
CMD2_VAR_STRING ("protocol.choke_heuristics.down.leech", "download_leech");
|
||||
CMD2_VAR_STRING ("protocol.choke_heuristics.down.seed", "download_leech");
|
||||
|
||||
CMD2_ANY ("network.http.cacert", [http_stack](auto, auto) { return http_stack->http_cacert(); });
|
||||
CMD2_ANY_STRING_V("network.http.cacert.set", [http_stack](auto, auto& str) { return http_stack->set_http_cacert(str); });
|
||||
CMD2_ANY ("network.http.capath", [http_stack](auto, auto) { return http_stack->http_capath(); });
|
||||
CMD2_ANY_STRING_V("network.http.capath.set", [http_stack](auto, auto& str) { return http_stack->set_http_capath(str); });
|
||||
CMD2_ANY ("network.http.dns_cache_timeout", [http_stack](auto, auto) { return http_stack->dns_timeout(); });
|
||||
CMD2_ANY_VALUE_V ("network.http.dns_cache_timeout.set", [http_stack](auto, auto& value) { return http_stack->set_dns_timeout(value); });
|
||||
CMD2_ANY ("network.http.current_open", [http_stack](auto, auto) { return http_stack->active(); });
|
||||
CMD2_ANY ("network.http.max_open", [http_stack](auto, auto) { return http_stack->max_active(); });
|
||||
CMD2_ANY_VALUE_V ("network.http.max_open.set", [http_stack](auto, auto& value) { return http_stack->set_max_active(value); });
|
||||
CMD2_ANY ("network.http.proxy_address", [http_stack](auto, auto) { return http_stack->http_proxy(); });
|
||||
CMD2_ANY_STRING_V("network.http.proxy_address.set", [http_stack](auto, auto& str) { return http_stack->set_http_proxy(str); });
|
||||
CMD2_ANY ("network.http.ssl_verify_host", [http_stack](auto, auto) { return http_stack->ssl_verify_host(); });
|
||||
CMD2_ANY_VALUE_V ("network.http.ssl_verify_host.set", [http_stack](auto, auto& value) { return http_stack->set_ssl_verify_host(value); });
|
||||
CMD2_ANY ("network.http.ssl_verify_peer", [http_stack](auto, auto) { return http_stack->ssl_verify_peer(); });
|
||||
CMD2_ANY_VALUE_V ("network.http.ssl_verify_peer.set", [http_stack](auto, auto& value) { return http_stack->set_ssl_verify_peer(value); });
|
||||
CMD2_ANY ("network.http.cacert", [http_stack](auto, auto) { return http_stack->http_cacert(); });
|
||||
CMD2_ANY_STRING_V("network.http.cacert.set", [http_stack](auto, auto& str) { return http_stack->set_http_cacert(str); });
|
||||
CMD2_ANY ("network.http.capath", [http_stack](auto, auto) { return http_stack->http_capath(); });
|
||||
CMD2_ANY_STRING_V("network.http.capath.set", [http_stack](auto, auto& str) { return http_stack->set_http_capath(str); });
|
||||
CMD2_ANY ("network.http.dns_cache_timeout", [http_stack](auto, auto) { return http_stack->dns_timeout(); });
|
||||
CMD2_ANY_VALUE_V ("network.http.dns_cache_timeout.set", [http_stack](auto, auto& value) { return http_stack->set_dns_timeout(value); });
|
||||
CMD2_ANY ("network.http.current_open", [http_stack](auto, auto) { return http_stack->size(); });
|
||||
CMD2_ANY ("network.http.max_cache_connections", [http_stack](auto, auto) { return http_stack->max_cache_connections(); });
|
||||
CMD2_ANY_VALUE_V ("network.http.max_cache_connections.set", [http_stack](auto, auto& value) { return http_stack->set_max_cache_connections(value); });
|
||||
CMD2_ANY ("network.http.max_host_connections", [http_stack](auto, auto) { return http_stack->max_host_connections(); });
|
||||
CMD2_ANY_VALUE_V ("network.http.max_host_connections.set", [http_stack](auto, auto& value) { return http_stack->set_max_host_connections(value); });
|
||||
CMD2_ANY ("network.http.max_total_connections", [http_stack](auto, auto) { return http_stack->max_total_connections(); });
|
||||
CMD2_ANY_VALUE_V ("network.http.max_total_connections.set", [http_stack](auto, auto& value) { return http_stack->set_max_total_connections(value); });
|
||||
CMD2_ANY ("network.http.proxy_address", [http_stack](auto, auto) { return http_stack->http_proxy(); });
|
||||
CMD2_ANY_STRING_V("network.http.proxy_address.set", [http_stack](auto, auto& str) { return http_stack->set_http_proxy(str); });
|
||||
CMD2_ANY ("network.http.ssl_verify_host", [http_stack](auto, auto) { return http_stack->ssl_verify_host(); });
|
||||
CMD2_ANY_VALUE_V ("network.http.ssl_verify_host.set", [http_stack](auto, auto& value) { return http_stack->set_ssl_verify_host(value); });
|
||||
CMD2_ANY ("network.http.ssl_verify_peer", [http_stack](auto, auto) { return http_stack->ssl_verify_peer(); });
|
||||
CMD2_ANY_VALUE_V ("network.http.ssl_verify_peer.set", [http_stack](auto, auto& value) { return http_stack->set_ssl_verify_peer(value); });
|
||||
|
||||
CMD2_ANY ("network.send_buffer.size", std::bind(&torrent::ConnectionManager::send_buffer_size, cm));
|
||||
CMD2_ANY_VALUE_V ("network.send_buffer.size.set", std::bind(&torrent::ConnectionManager::set_send_buffer_size, cm, std::placeholders::_2));
|
||||
CMD2_ANY ("network.receive_buffer.size", std::bind(&torrent::ConnectionManager::receive_buffer_size, cm));
|
||||
CMD2_ANY_VALUE_V ("network.receive_buffer.size.set", std::bind(&torrent::ConnectionManager::set_receive_buffer_size, cm, std::placeholders::_2));
|
||||
CMD2_ANY_STRING ("network.tos.set", std::bind(&apply_tos, std::placeholders::_2));
|
||||
CMD2_ANY ("network.send_buffer.size", [nw_config](auto, auto) { return nw_config->send_buffer_size(); });
|
||||
CMD2_ANY_VALUE_V ("network.send_buffer.size.set", [nw_config](auto, auto& value) { return nw_config->set_send_buffer_size(value); });
|
||||
CMD2_ANY ("network.receive_buffer.size", [nw_config](auto, auto) { return nw_config->receive_buffer_size(); });
|
||||
CMD2_ANY_VALUE_V ("network.receive_buffer.size.set", [nw_config](auto, auto& value) { return nw_config->set_receive_buffer_size(value); });
|
||||
CMD2_ANY_STRING ("network.tos.set", [](auto, auto& str) { return apply_tos(str); });
|
||||
|
||||
CMD2_ANY ("network.bind_address", std::bind(&core::Manager::bind_address, control->core()));
|
||||
CMD2_ANY_STRING_V("network.bind_address.set", std::bind(&core::Manager::set_bind_address, control->core(), std::placeholders::_2));
|
||||
CMD2_ANY ("network.local_address", std::bind(&core::Manager::local_address, control->core()));
|
||||
CMD2_ANY_STRING_V("network.local_address.set", std::bind(&core::Manager::set_local_address, control->core(), std::placeholders::_2));
|
||||
CMD2_ANY ("network.proxy_address", std::bind(&core::Manager::proxy_address, control->core()));
|
||||
CMD2_ANY_STRING_V("network.proxy_address.set", std::bind(&core::Manager::set_proxy_address, control->core(), std::placeholders::_2));
|
||||
CMD2_ANY ("network.bind_address", [nw_config](auto, auto) { return nw_config->bind_address_best_match_str(); });
|
||||
CMD2_ANY_STRING_V("network.bind_address.set", [nw_config](auto, auto& str) { return nw_config->set_bind_address_str(str); });
|
||||
CMD2_ANY ("network.bind_address.ipv4", [nw_config](auto, auto) { return nw_config->bind_inet_address_str(); });
|
||||
CMD2_ANY_STRING_V("network.bind_address.ipv4.set", [nw_config](auto, auto& str) { return nw_config->set_bind_inet_address_str(str); });
|
||||
CMD2_ANY ("network.bind_address.ipv6", [nw_config](auto, auto) { return nw_config->bind_inet6_address_str(); });
|
||||
CMD2_ANY_STRING_V("network.bind_address.ipv6.set", [nw_config](auto, auto& str) { return nw_config->set_bind_inet6_address_str(str); });
|
||||
|
||||
CMD2_ANY ("network.open_files", std::bind(&torrent::FileManager::open_files, fileManager));
|
||||
CMD2_ANY ("network.max_open_files", std::bind(&torrent::FileManager::max_open_files, fileManager));
|
||||
CMD2_ANY_VALUE_V ("network.max_open_files.set", std::bind(&torrent::FileManager::set_max_open_files, fileManager, std::placeholders::_2));
|
||||
CMD2_ANY ("network.total_handshakes", std::bind(&torrent::total_handshakes));
|
||||
CMD2_ANY ("network.open_sockets", std::bind(&torrent::ConnectionManager::size, cm));
|
||||
CMD2_ANY ("network.max_open_sockets", std::bind(&torrent::ConnectionManager::max_size, cm));
|
||||
CMD2_ANY_VALUE_V ("network.max_open_sockets.set", std::bind(&torrent::ConnectionManager::set_max_size, cm, std::placeholders::_2));
|
||||
CMD2_ANY ("network.local_address", [nw_config](auto, auto) { return nw_config->local_address_best_match_str(); });
|
||||
CMD2_ANY_STRING_V("network.local_address.set", [nw_config](auto, auto& str) { return nw_config->set_local_address_str(str); });
|
||||
CMD2_ANY ("network.local_address.ipv4", [nw_config](auto, auto) { return nw_config->local_inet_address_str(); });
|
||||
CMD2_ANY_STRING_V("network.local_address.ipv4.set", [nw_config](auto, auto& str) { return nw_config->set_local_inet_address_str(str); });
|
||||
CMD2_ANY ("network.local_address.ipv6", [nw_config](auto, auto) { return nw_config->local_inet6_address_str(); });
|
||||
CMD2_ANY_STRING_V("network.local_address.ipv6.set", [nw_config](auto, auto& str) { return nw_config->set_local_inet6_address_str(str); });
|
||||
|
||||
CMD2_ANY ("network.proxy_address", [nw_config](auto, auto) { return nw_config->proxy_address_str(); });
|
||||
CMD2_ANY_STRING_V("network.proxy_address.set", [](auto, auto& str) { return control->core()->set_proxy_address(str); });
|
||||
|
||||
CMD2_ANY ("network.open_files", [file_manager](auto, auto) { return file_manager->open_files(); });
|
||||
CMD2_ANY ("network.max_open_files", [file_manager](auto, auto) { return file_manager->max_open_files(); });
|
||||
CMD2_ANY_VALUE_V ("network.max_open_files.set", [file_manager](auto, auto& value) { return file_manager->set_max_open_files(value); });
|
||||
CMD2_ANY ("network.total_handshakes", [](auto, auto) { return torrent::total_handshakes(); });
|
||||
CMD2_ANY ("network.open_sockets", [cm](auto, auto) { return cm->size(); });
|
||||
CMD2_ANY ("network.max_open_sockets", [cm](auto, auto) { return cm->max_size(); });
|
||||
CMD2_ANY_VALUE_V ("network.max_open_sockets.set", [cm](auto, auto& value) { return cm->set_max_size(value); });
|
||||
|
||||
CMD2_ANY_STRING ("network.scgi.open_port", std::bind(&apply_scgi, std::placeholders::_2, 1));
|
||||
CMD2_ANY_STRING ("network.scgi.open_local", std::bind(&apply_scgi, std::placeholders::_2, 2));
|
||||
CMD2_VAR_BOOL ("network.scgi.dont_route", false);
|
||||
|
||||
CMD2_ANY_STRING ("network.xmlrpc.dialect.set", [](const auto&, const auto& arg) { return apply_xmlrpc_dialect(arg); })
|
||||
CMD2_ANY ("network.xmlrpc.size_limit", [](const auto&, const auto&){ return rpc::rpc.size_limit(); });
|
||||
CMD2_ANY_VALUE_V ("network.xmlrpc.size_limit.set", [](const auto&, const auto& arg){ return rpc::rpc.set_size_limit(arg); });
|
||||
CMD2_ANY ("network.xmlrpc.size_limit", [](const auto&, const auto&) { return rpc::rpc.size_limit(); });
|
||||
CMD2_ANY_VALUE_V ("network.xmlrpc.size_limit.set", [](const auto&, const auto& arg) { return rpc::rpc.set_size_limit(arg); });
|
||||
|
||||
CMD2_VAR_BOOL ("network.rpc.use_xmlrpc", true);
|
||||
CMD2_VAR_BOOL ("network.rpc.use_jsonrpc", true);
|
||||
|
||||
CMD2_ANY ("network.block.ipv4", std::bind(&torrent::ConnectionManager::is_block_ipv4, cm));
|
||||
CMD2_ANY_VALUE_V ("network.block.ipv4.set", std::bind(&torrent::ConnectionManager::set_block_ipv4, cm, std::placeholders::_2));
|
||||
CMD2_ANY ("network.block.ipv6", std::bind(&torrent::ConnectionManager::is_block_ipv6, cm));
|
||||
CMD2_ANY_VALUE_V ("network.block.ipv6.set", std::bind(&torrent::ConnectionManager::set_block_ipv6, cm, std::placeholders::_2));
|
||||
CMD2_ANY ("network.block.ipv4in6", std::bind(&torrent::ConnectionManager::is_block_ipv4in6, cm));
|
||||
CMD2_ANY_VALUE_V ("network.block.ipv4in6.set", std::bind(&torrent::ConnectionManager::set_block_ipv4in6, cm, std::placeholders::_2));
|
||||
|
||||
CMD2_ANY ("network.prefer.ipv6", std::bind(&torrent::ConnectionManager::is_prefer_ipv6, cm));
|
||||
CMD2_ANY_VALUE_V ("network.prefer.ipv6.set", std::bind(&torrent::ConnectionManager::set_prefer_ipv6, cm, std::placeholders::_2));
|
||||
CMD2_ANY ("network.block.ipv4", [nw_config](auto, auto) { return nw_config->is_block_ipv4(); });
|
||||
CMD2_ANY_VALUE_V ("network.block.ipv4.set", [nw_config](auto, auto& value) { return nw_config->set_block_ipv4(value); });
|
||||
CMD2_ANY ("network.block.ipv6", [nw_config](auto, auto) { return nw_config->is_block_ipv6(); });
|
||||
CMD2_ANY_VALUE_V ("network.block.ipv6.set", [nw_config](auto, auto& value) { return nw_config->set_block_ipv6(value); });
|
||||
CMD2_ANY ("network.block.ipv4in6", [nw_config](auto, auto) { return nw_config->is_block_ipv4in6(); });
|
||||
CMD2_ANY_VALUE_V ("network.block.ipv4in6.set", [nw_config](auto, auto& value) { return nw_config->set_block_ipv4in6(value); });
|
||||
CMD2_ANY ("network.block.outgoing", [nw_config](auto, auto) { return nw_config->is_block_outgoing(); });
|
||||
CMD2_ANY_VALUE_V ("network.block.outgoing.set", [nw_config](auto, auto& value) { return nw_config->set_block_outgoing(value); });
|
||||
CMD2_ANY ("network.prefer.ipv6", [nw_config](auto, auto) { return nw_config->is_prefer_ipv6(); });
|
||||
CMD2_ANY_VALUE_V ("network.prefer.ipv6.set", [nw_config](auto, auto& value) { return nw_config->set_prefer_ipv6(value); });
|
||||
}
|
||||
|
||||
+8
-43
@@ -1,45 +1,9 @@
|
||||
// rTorrent - BitTorrent client
|
||||
// Copyright (C) 2005-2011, 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 <sundell.software@gmail.com>
|
||||
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <rak/error_number.h>
|
||||
#include <rak/path.h>
|
||||
#include <rak/socket_address.h>
|
||||
#include <rak/string_manip.h>
|
||||
#include <torrent/bitfield.h>
|
||||
#include <torrent/rate.h>
|
||||
#include <torrent/net/socket_address.h>
|
||||
#include <torrent/peer/connection_list.h>
|
||||
#include <torrent/peer/peer.h>
|
||||
#include <torrent/peer/peer_info.h>
|
||||
@@ -67,17 +31,18 @@ retrieve_p_id_html(torrent::Peer* peer) {
|
||||
|
||||
torrent::Object
|
||||
retrieve_p_address(torrent::Peer* peer) {
|
||||
const rak::socket_address *addr = rak::socket_address::cast_from(peer->peer_info()->socket_address());
|
||||
auto sa = peer->peer_info()->socket_address();
|
||||
auto addr_str = torrent::sa_addr_str(sa);
|
||||
|
||||
if (addr->family() == rak::socket_address::af_inet6)
|
||||
return "[" + addr->address_str() + "]";
|
||||
else
|
||||
return addr->address_str();
|
||||
if (sa->sa_family == AF_INET6)
|
||||
return "[" + addr_str + "]";
|
||||
|
||||
return addr_str;
|
||||
}
|
||||
|
||||
torrent::Object
|
||||
retrieve_p_port(torrent::Peer* peer) {
|
||||
return rak::socket_address::cast_from(peer->peer_info()->socket_address())->port();
|
||||
return torrent::sa_port(peer->peer_info()->socket_address());
|
||||
}
|
||||
|
||||
torrent::Object
|
||||
|
||||
+19
-46
@@ -1,47 +1,14 @@
|
||||
// rTorrent - BitTorrent client
|
||||
// Copyright (C) 2005-2011, 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 <sundell.software@gmail.com>
|
||||
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <rak/address_info.h>
|
||||
#include <torrent/throttle.h>
|
||||
#include <torrent/rate.h>
|
||||
#include <torrent/download/resource_manager.h>
|
||||
#include <torrent/net/socket_address.h>
|
||||
|
||||
#include "core/manager.h"
|
||||
#include "ui/root.h"
|
||||
#include "rak/address_info.h"
|
||||
#include "rpc/parse.h"
|
||||
#include "rpc/parse_commands.h"
|
||||
|
||||
@@ -57,13 +24,16 @@ parse_address_range(const torrent::Object::list_type& args, torrent::Object::lis
|
||||
rak::address_info* ai;
|
||||
|
||||
ret = std::sscanf(itr->as_string().c_str(), "%1023[^/]/%d%c", host, &prefixWidth, &dummy);
|
||||
|
||||
if (ret < 1 || rak::address_info::get_address_info(host, PF_INET, SOCK_STREAM, &ai) != 0)
|
||||
throw torrent::input_error("Could not resolve host.");
|
||||
|
||||
uint32_t begin, end;
|
||||
rak::socket_address sa;
|
||||
sa.copy(*ai->address(), ai->length());
|
||||
begin = end = sa.sa_inet()->address_h();
|
||||
auto sa = torrent::sa_copy(ai->c_addrinfo()->ai_addr);
|
||||
auto sa_addr = htonl(reinterpret_cast<sockaddr_in*>(sa.get())->sin_addr.s_addr);
|
||||
|
||||
begin = end = sa_addr;
|
||||
|
||||
rak::address_info::free_address_info(ai);
|
||||
|
||||
if (ret == 2) {
|
||||
@@ -71,18 +41,21 @@ parse_address_range(const torrent::Object::list_type& args, torrent::Object::lis
|
||||
throw torrent::input_error("Cannot specify both network and range end.");
|
||||
|
||||
uint32_t netmask = std::numeric_limits<uint32_t>::max() << (32 - prefixWidth);
|
||||
if (prefixWidth >= 32 || sa.sa_inet()->address_h() & ~netmask)
|
||||
|
||||
if (prefixWidth >= 32 || sa_addr & ~netmask)
|
||||
throw torrent::input_error("Invalid address/prefix.");
|
||||
|
||||
end = sa.sa_inet()->address_h() | ~netmask;
|
||||
end = sa_addr | ~netmask;
|
||||
|
||||
} else if (++itr != args.end()) {
|
||||
if (rak::address_info::get_address_info(itr->as_string().c_str(), PF_INET, SOCK_STREAM, &ai) != 0)
|
||||
throw torrent::input_error("Could not resolve host.");
|
||||
|
||||
sa.copy(*ai->address(), ai->length());
|
||||
sa = torrent::sa_copy(ai->c_addrinfo()->ai_addr);
|
||||
sa_addr = htonl(reinterpret_cast<sockaddr_in*>(sa.get())->sin_addr.s_addr);
|
||||
|
||||
rak::address_info::free_address_info(ai);
|
||||
end = sa.sa_inet()->address_h();
|
||||
end = sa_addr;
|
||||
}
|
||||
|
||||
// convert to [begin, end) making sure the end doesn't overflow
|
||||
@@ -194,10 +167,10 @@ initialize_command_throttle() {
|
||||
CMD2_VAR_VALUE ("throttle.max_downloads.div._val", 1);
|
||||
CMD2_VAR_VALUE ("throttle.max_downloads.global._val", 0);
|
||||
|
||||
CMD2_REDIRECT_GENERIC("throttle.max_uploads.div", "throttle.max_uploads.div._val");
|
||||
CMD2_REDIRECT_GENERIC("throttle.max_uploads.global", "throttle.max_uploads.global._val");
|
||||
CMD2_REDIRECT_GENERIC("throttle.max_downloads.div", "throttle.max_downloads.div._val");
|
||||
CMD2_REDIRECT_GENERIC("throttle.max_downloads.global", "throttle.max_downloads.global._val");
|
||||
CMD2_REDIRECT ("throttle.max_uploads.div", "throttle.max_uploads.div._val");
|
||||
CMD2_REDIRECT ("throttle.max_uploads.global", "throttle.max_uploads.global._val");
|
||||
CMD2_REDIRECT ("throttle.max_downloads.div", "throttle.max_downloads.div._val");
|
||||
CMD2_REDIRECT ("throttle.max_downloads.global", "throttle.max_downloads.global._val");
|
||||
|
||||
CMD2_ANY_VALUE ("throttle.max_uploads.div.set", std::bind(&throttle_update, "throttle.max_uploads.div._val.set", std::placeholders::_2));
|
||||
CMD2_ANY_VALUE ("throttle.max_uploads.global.set", std::bind(&throttle_update, "throttle.max_uploads.global._val.set", std::placeholders::_2));
|
||||
|
||||
+14
-9
@@ -3,8 +3,8 @@
|
||||
#include <cassert>
|
||||
#include <cstdio>
|
||||
#include <netdb.h>
|
||||
#include <rak/address_info.h>
|
||||
#include <rak/error_number.h>
|
||||
#include <torrent/net/network_config.h>
|
||||
#include <torrent/net/network_manager.h>
|
||||
#include <torrent/net/resolver.h>
|
||||
#include <torrent/tracker/dht_controller.h>
|
||||
#include <torrent/tracker/tracker.h>
|
||||
@@ -28,7 +28,7 @@ tracker_set_enabled(torrent::tracker::Tracker* tracker, bool state) {
|
||||
|
||||
torrent::Object
|
||||
apply_dht_add_node(const std::string& arg) {
|
||||
if (!torrent::dht_controller()->is_valid())
|
||||
if (!torrent::runtime::network_manager()->is_dht_valid())
|
||||
throw torrent::input_error("DHT not enabled.");
|
||||
|
||||
int port;
|
||||
@@ -59,7 +59,7 @@ apply_dht_add_node(const std::string& arg) {
|
||||
}
|
||||
|
||||
lt_log_print(torrent::LOG_DHT_CONTROLLER, "dht.add_node : %s", host_str.c_str());
|
||||
torrent::dht_controller()->add_node(sa.get(), port);
|
||||
torrent::runtime::network_manager()->dht_add_peer_node(sa.get(), port);
|
||||
});
|
||||
|
||||
return torrent::Object();
|
||||
@@ -142,11 +142,16 @@ initialize_command_tracker() {
|
||||
CMD2_VAR_VALUE ("trackers.numwant", -1);
|
||||
CMD2_VAR_BOOL ("trackers.use_udp", true);
|
||||
|
||||
auto dht_manager = control->dht_manager();
|
||||
|
||||
CMD2_ANY_STRING_V ("dht.mode.set", std::bind(&core::DhtManager::set_mode, control->dht_manager(), std::placeholders::_2));
|
||||
// TODO: This should query DhtController.
|
||||
CMD2_VAR_VALUE ("dht.port", int64_t(6881));
|
||||
CMD2_ANY ("dht.port", [](auto, auto) { return torrent::runtime::network_manager()->dht_controller()->port(); });
|
||||
CMD2_ANY_VALUE_V ("dht.port.set", [](auto, auto) {
|
||||
lt_log_print(torrent::LOG_DHT_ERROR, "dht.port.set is no longer supported, use dht.override_port.set", 0);
|
||||
});
|
||||
CMD2_ANY ("dht.override_port", std::bind(&torrent::net::NetworkConfig::override_dht_port, torrent::config::network_config()));
|
||||
CMD2_ANY_VALUE_V ("dht.override_port.set", std::bind(&torrent::net::NetworkConfig::set_override_dht_port, torrent::config::network_config(), std::placeholders::_2));
|
||||
|
||||
CMD2_ANY_STRING ("dht.add_node", std::bind(&apply_dht_add_node, std::placeholders::_2));
|
||||
CMD2_ANY ("dht.statistics", std::bind(&core::DhtManager::dht_statistics, control->dht_manager()));
|
||||
CMD2_ANY ("dht.throttle.name", std::bind(&core::DhtManager::throttle_name, control->dht_manager()));
|
||||
CMD2_ANY_STRING_V ("dht.throttle.name.set", std::bind(&core::DhtManager::set_throttle_name, control->dht_manager(), std::placeholders::_2));
|
||||
CMD2_ANY ("dht.statistics", std::bind(&core::DhtManager::dht_statistics, dht_manager));
|
||||
}
|
||||
|
||||
+11
-12
@@ -4,8 +4,8 @@
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <torrent/connection_manager.h>
|
||||
#include <torrent/net/http_stack.h>
|
||||
#include <torrent/net/network_manager.h>
|
||||
#include <torrent/utils/directory_events.h>
|
||||
|
||||
#include "core/dht_manager.h"
|
||||
@@ -38,9 +38,9 @@ Control::Control()
|
||||
m_lua_engine(new rpc::LuaEngine()),
|
||||
m_directory_events(new torrent::directory_events()) {
|
||||
|
||||
m_core = std::make_unique<core::Manager>();
|
||||
m_viewManager = std::make_unique<core::ViewManager>();
|
||||
m_dhtManager = std::make_unique<core::DhtManager>();
|
||||
m_core = std::make_unique<core::Manager>();
|
||||
m_view_manager = std::make_unique<core::ViewManager>();
|
||||
m_dht_manager = std::make_unique<core::DhtManager>();
|
||||
|
||||
m_inputStdin->slot_pressed(std::bind(&input::Manager::pressed, m_input.get(), std::placeholders::_1));
|
||||
|
||||
@@ -50,7 +50,7 @@ Control::Control()
|
||||
}
|
||||
|
||||
Control::~Control() {
|
||||
m_viewManager.reset();
|
||||
m_view_manager.reset();
|
||||
|
||||
m_ui.reset();
|
||||
m_display.reset();
|
||||
@@ -58,6 +58,8 @@ Control::~Control() {
|
||||
|
||||
void
|
||||
Control::initialize() {
|
||||
worker_thread->start_thread();
|
||||
|
||||
display::Canvas::initialize();
|
||||
display::Window::slot_schedule([this](display::Window* w, std::chrono::microseconds t) { m_display->schedule(w, t); });
|
||||
display::Window::slot_unschedule([this](display::Window* w) { m_display->unschedule(w); });
|
||||
@@ -67,9 +69,7 @@ Control::initialize() {
|
||||
|
||||
m_core->listen_open();
|
||||
m_core->download_store()->enable(rpc::call_command_value("session.use_lock"));
|
||||
m_core->set_hashing_view(*m_viewManager->find_throw("hashing"));
|
||||
|
||||
m_dhtManager->set_port(torrent::connection_manager()->listen_port());
|
||||
m_core->set_hashing_view(*m_view_manager->find_throw("hashing"));
|
||||
|
||||
m_ui->init(this);
|
||||
|
||||
@@ -83,9 +83,8 @@ Control::cleanup() {
|
||||
|
||||
torrent::this_thread::scheduler()->erase(&m_task_shutdown);
|
||||
|
||||
if(!display::Canvas::daemon()) {
|
||||
if(!display::Canvas::daemon())
|
||||
m_inputStdin->remove(torrent::this_thread::poll());
|
||||
}
|
||||
|
||||
m_core->download_store()->disable();
|
||||
|
||||
@@ -114,7 +113,7 @@ Control::is_shutdown_completed() {
|
||||
|
||||
// TODO: We keep http requests in the queue for a while after, so improve this check to ignore
|
||||
// those.
|
||||
if (torrent::net_thread::http_stack()->active() != 0 || !core()->http_queue()->empty())
|
||||
if (torrent::net_thread::http_stack()->size() != 0 || !core()->http_queue()->empty())
|
||||
return false;
|
||||
|
||||
return torrent::is_inactive();
|
||||
@@ -128,7 +127,7 @@ Control::handle_shutdown() {
|
||||
if (worker_thread->is_active())
|
||||
worker_thread->stop_thread_wait();
|
||||
|
||||
torrent::connection_manager()->listen_close();
|
||||
torrent::runtime::network_manager()->listen_close();
|
||||
|
||||
m_directory_events->close();
|
||||
m_core->shutdown(false);
|
||||
|
||||
+4
-4
@@ -57,8 +57,8 @@ public:
|
||||
void receive_quick_shutdown() { m_shutdownReceived = true; m_shutdownQuick = true; }
|
||||
|
||||
core::Manager* core() { return m_core.get(); }
|
||||
core::ViewManager* view_manager() { return m_viewManager.get(); }
|
||||
core::DhtManager* dht_manager() { return m_dhtManager.get(); }
|
||||
core::ViewManager* view_manager() { return m_view_manager.get(); }
|
||||
core::DhtManager* dht_manager() { return m_dht_manager.get(); }
|
||||
|
||||
ui::Root* ui() { return m_ui.get(); }
|
||||
display::Manager* display() { return m_display.get(); }
|
||||
@@ -82,8 +82,8 @@ private:
|
||||
void operator = (const Control&);
|
||||
|
||||
std::unique_ptr<core::Manager> m_core;
|
||||
std::unique_ptr<core::ViewManager> m_viewManager;
|
||||
std::unique_ptr<core::DhtManager> m_dhtManager;
|
||||
std::unique_ptr<core::ViewManager> m_view_manager;
|
||||
std::unique_ptr<core::DhtManager> m_dht_manager;
|
||||
|
||||
std::unique_ptr<ui::Root> m_ui;
|
||||
std::unique_ptr<display::Manager> m_display;
|
||||
|
||||
+28
-59
@@ -1,22 +1,22 @@
|
||||
#include "config.h"
|
||||
|
||||
#include "dht_manager.h"
|
||||
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <torrent/object.h>
|
||||
#include <torrent/object_stream.h>
|
||||
#include <torrent/net/network_manager.h>
|
||||
#include <torrent/rate.h>
|
||||
#include <torrent/tracker/dht_controller.h>
|
||||
#include <torrent/utils/log.h>
|
||||
|
||||
#include "rpc/parse_commands.h"
|
||||
|
||||
#include "globals.h"
|
||||
|
||||
#include "control.h"
|
||||
#include "dht_manager.h"
|
||||
#include "download.h"
|
||||
#include "download_store.h"
|
||||
#include "globals.h"
|
||||
#include "manager.h"
|
||||
#include "rpc/parse_commands.h"
|
||||
|
||||
#define LT_LOG(log_fmt, ...) \
|
||||
lt_log_print_subsystem(torrent::LOG_DHT_CONTROLLER, "dht_manager", log_fmt, __VA_ARGS__);
|
||||
@@ -33,16 +33,6 @@ DhtManager::~DhtManager() {
|
||||
torrent::this_thread::scheduler()->erase(&m_stop_timeout);
|
||||
}
|
||||
|
||||
void
|
||||
DhtManager::set_port(uint16_t port) {
|
||||
if (torrent::dht_controller()->is_active()) {
|
||||
LT_LOG_ERROR("cannot change port while DHT is active", 0);
|
||||
throw torrent::input_error("cannot change port while DHT is active");
|
||||
}
|
||||
|
||||
m_port = port;
|
||||
}
|
||||
|
||||
void
|
||||
DhtManager::load_dht_cache() {
|
||||
if (m_start == dht_disable || !control->core()->download_store()->is_enabled()) {
|
||||
@@ -71,7 +61,7 @@ DhtManager::load_dht_cache() {
|
||||
LT_LOG("could not open cache file (path:%s)", cache_filename.c_str());
|
||||
}
|
||||
|
||||
torrent::dht_controller()->initialize(cache);
|
||||
torrent::runtime::network_manager()->dht_controller()->initialize(cache);
|
||||
|
||||
if (m_start == dht_on)
|
||||
start_dht();
|
||||
@@ -81,33 +71,22 @@ void
|
||||
DhtManager::start_dht() {
|
||||
torrent::this_thread::scheduler()->erase(&m_stop_timeout);
|
||||
|
||||
if (!torrent::dht_controller()->is_valid()) {
|
||||
if (!torrent::runtime::network_manager()->is_dht_valid()) {
|
||||
LT_LOG("server start skipped, manager is uninitialized", 0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (torrent::dht_controller()->is_active()) {
|
||||
if (torrent::runtime::network_manager()->is_dht_active()) {
|
||||
LT_LOG("server start skipped, already active", 0);
|
||||
return;
|
||||
}
|
||||
|
||||
torrent::ThrottlePair throttles = control->core()->get_throttle(m_throttleName);
|
||||
torrent::dht_controller()->set_upload_throttle(throttles.first);
|
||||
torrent::dht_controller()->set_download_throttle(throttles.second);
|
||||
|
||||
if (m_port <= 0) {
|
||||
LT_LOG("server start skipped, port not set", 0);
|
||||
return;
|
||||
}
|
||||
|
||||
LT_LOG("starting server : port=%" PRIu16, m_port);
|
||||
|
||||
if (!torrent::dht_controller()->start(m_port)) {
|
||||
if (!torrent::runtime::network_manager()->dht_controller()->start()) {
|
||||
m_start = dht_off;
|
||||
return;
|
||||
}
|
||||
|
||||
torrent::dht_controller()->reset_statistics();
|
||||
torrent::runtime::network_manager()->dht_controller()->reset_statistics();
|
||||
|
||||
m_update_timeout.slot() = std::bind(&DhtManager::update, this);
|
||||
|
||||
@@ -126,17 +105,19 @@ DhtManager::stop_dht() {
|
||||
torrent::this_thread::scheduler()->erase(&m_update_timeout);
|
||||
torrent::this_thread::scheduler()->erase(&m_stop_timeout);
|
||||
|
||||
if (torrent::dht_controller()->is_active()) {
|
||||
if (torrent::runtime::network_manager()->is_dht_active()) {
|
||||
LT_LOG("stopping server", 0);
|
||||
|
||||
log_statistics(true);
|
||||
torrent::dht_controller()->stop();
|
||||
torrent::runtime::network_manager()->dht_controller()->stop();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
DhtManager::save_dht_cache() {
|
||||
if (!control->core()->download_store()->is_enabled() || !torrent::dht_controller()->is_valid())
|
||||
if (!control->core()->download_store()->is_enabled())
|
||||
return;
|
||||
if (!torrent::runtime::network_manager()->is_dht_valid())
|
||||
return;
|
||||
|
||||
std::string filename = control->core()->download_store()->path() + "rtorrent.dht_cache";
|
||||
@@ -147,7 +128,7 @@ DhtManager::save_dht_cache() {
|
||||
return;
|
||||
|
||||
torrent::Object cache = torrent::Object::create_map();
|
||||
cache_file << *torrent::dht_controller()->store_cache(&cache);
|
||||
cache_file << *torrent::runtime::network_manager()->dht_controller()->store_cache(&cache);
|
||||
|
||||
if (!cache_file.good())
|
||||
return;
|
||||
@@ -178,7 +159,7 @@ DhtManager::set_mode(const std::string& arg) {
|
||||
|
||||
void
|
||||
DhtManager::update() {
|
||||
if (!torrent::dht_controller()->is_active())
|
||||
if (!torrent::runtime::network_manager()->is_dht_active())
|
||||
throw torrent::internal_error("DhtManager::update called with DHT inactive.");
|
||||
|
||||
if (m_start == dht_auto && !m_stop_timeout.is_scheduled()) {
|
||||
@@ -203,17 +184,17 @@ DhtManager::update() {
|
||||
|
||||
bool
|
||||
DhtManager::log_statistics(bool force) {
|
||||
auto stats = torrent::dht_controller()->get_statistics();
|
||||
auto stats = torrent::runtime::network_manager()->dht_controller()->get_statistics();
|
||||
|
||||
// Check for firewall problems.
|
||||
|
||||
if (stats.cycle > 2 && stats.queries_sent - m_dhtPrevQueriesSent > 100 && stats.queries_received == m_dhtPrevQueriesReceived) {
|
||||
// We should have had clients ping us at least but have received
|
||||
// nothing, that means the UDP port is probably unreachable.
|
||||
if (torrent::dht_controller()->is_receiving_requests())
|
||||
if (torrent::runtime::network_manager()->is_dht_active_and_receiving_requests())
|
||||
LT_LOG("listening port appears to be unreachable, no queries received", 0);
|
||||
|
||||
torrent::dht_controller()->set_receive_requests(false);
|
||||
torrent::runtime::network_manager()->dht_controller()->set_receive_requests(false);
|
||||
}
|
||||
|
||||
if (stats.queries_sent - m_dhtPrevQueriesSent > stats.num_nodes * 2 + 20 && stats.replies_received == m_dhtPrevRepliesReceived) {
|
||||
@@ -228,7 +209,7 @@ DhtManager::log_statistics(bool force) {
|
||||
m_warned = false;
|
||||
|
||||
if (stats.queries_received > m_dhtPrevQueriesReceived)
|
||||
torrent::dht_controller()->set_receive_requests(true);
|
||||
torrent::runtime::network_manager()->dht_controller()->set_receive_requests(true);
|
||||
|
||||
// Nothing to log while bootstrapping, but check again every minute.
|
||||
if (stats.cycle <= 1) {
|
||||
@@ -250,13 +231,11 @@ DhtManager::log_statistics(bool force) {
|
||||
if ((force && stats.cycle != m_dhtPrevCycle) || stats.cycle == 3 || stats.cycle > m_dhtPrevCycle + 7) {
|
||||
char buffer[256];
|
||||
snprintf(buffer, sizeof(buffer),
|
||||
"DHT statistics: %d queries in, %d queries out, %d replies received, %lld bytes read, %lld bytes sent, "
|
||||
"DHT statistics: %d queries in, %d queries out, %d replies received, "
|
||||
"%d known nodes in %d buckets, %d peers (highest: %d) tracked in %d torrents.",
|
||||
stats.queries_received - m_dhtPrevQueriesReceived,
|
||||
stats.queries_sent - m_dhtPrevQueriesSent,
|
||||
stats.replies_received - m_dhtPrevRepliesReceived,
|
||||
(long long unsigned int)(stats.down_rate.total() - m_dhtPrevBytesDown),
|
||||
(long long unsigned int)(stats.up_rate.total() - m_dhtPrevBytesUp),
|
||||
stats.num_nodes,
|
||||
stats.num_buckets,
|
||||
stats.num_peers,
|
||||
@@ -269,8 +248,6 @@ DhtManager::log_statistics(bool force) {
|
||||
m_dhtPrevQueriesSent = stats.queries_sent;
|
||||
m_dhtPrevRepliesReceived = stats.replies_received;
|
||||
m_dhtPrevQueriesReceived = stats.queries_received;
|
||||
m_dhtPrevBytesUp = stats.up_rate.total();
|
||||
m_dhtPrevBytesDown = stats.down_rate.total();
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -281,11 +258,11 @@ DhtManager::dht_statistics() {
|
||||
torrent::Object dhtStats = torrent::Object::create_map();
|
||||
|
||||
dhtStats.insert_key("dht", dht_settings[m_start]);
|
||||
dhtStats.insert_key("active", torrent::dht_controller()->is_active());
|
||||
dhtStats.insert_key("throttle", m_throttleName);
|
||||
dhtStats.insert_key("active", torrent::runtime::network_manager()->is_dht_active());
|
||||
dhtStats.insert_key("throttle", "");
|
||||
|
||||
if (torrent::dht_controller()->is_active()) {
|
||||
auto stats = torrent::dht_controller()->get_statistics();
|
||||
if (torrent::runtime::network_manager()->is_dht_active()) {
|
||||
auto stats = torrent::runtime::network_manager()->dht_controller()->get_statistics();
|
||||
|
||||
dhtStats.insert_key("cycle", stats.cycle);
|
||||
dhtStats.insert_key("queries_received", stats.queries_received);
|
||||
@@ -293,8 +270,8 @@ DhtManager::dht_statistics() {
|
||||
dhtStats.insert_key("replies_received", stats.replies_received);
|
||||
dhtStats.insert_key("errors_received", stats.errors_received);
|
||||
dhtStats.insert_key("errors_caught", stats.errors_caught);
|
||||
dhtStats.insert_key("bytes_read", stats.down_rate.total());
|
||||
dhtStats.insert_key("bytes_written", stats.up_rate.total());
|
||||
dhtStats.insert_key("bytes_read", int64_t());
|
||||
dhtStats.insert_key("bytes_written", int64_t());
|
||||
dhtStats.insert_key("nodes", stats.num_nodes);
|
||||
dhtStats.insert_key("buckets", stats.num_buckets);
|
||||
dhtStats.insert_key("peers", stats.num_peers);
|
||||
@@ -305,12 +282,4 @@ DhtManager::dht_statistics() {
|
||||
return dhtStats;
|
||||
}
|
||||
|
||||
void
|
||||
DhtManager::set_throttle_name(const std::string& throttleName) {
|
||||
if (torrent::dht_controller()->is_active())
|
||||
throw torrent::input_error("Cannot set DHT throttle while active.");
|
||||
|
||||
m_throttleName = throttleName;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -10,9 +10,6 @@ class DhtManager {
|
||||
public:
|
||||
~DhtManager();
|
||||
|
||||
uint16_t port() const { return m_port; }
|
||||
void set_port(uint16_t port);
|
||||
|
||||
void load_dht_cache();
|
||||
void save_dht_cache();
|
||||
torrent::Object dht_statistics();
|
||||
@@ -23,9 +20,6 @@ public:
|
||||
|
||||
void set_mode(const std::string& arg);
|
||||
|
||||
void set_throttle_name(const std::string& throttleName);
|
||||
const std::string& throttle_name() const { return m_throttleName; }
|
||||
|
||||
private:
|
||||
static const int dht_disable = 0;
|
||||
static const int dht_off = 1;
|
||||
@@ -49,11 +43,7 @@ private:
|
||||
torrent::utils::SchedulerEntry m_stop_timeout;
|
||||
|
||||
bool m_warned{};
|
||||
|
||||
int m_start{dht_off};
|
||||
uint16_t m_port{0};
|
||||
|
||||
std::string m_throttleName;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
+15
-76
@@ -7,7 +7,6 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/select.h>
|
||||
#include <rak/address_info.h>
|
||||
#include <rak/error_number.h>
|
||||
#include <rak/regex.h>
|
||||
#include <rak/path.h>
|
||||
#include <rak/string_manip.h>
|
||||
@@ -19,6 +18,9 @@
|
||||
#include <torrent/object_stream.h>
|
||||
#include <torrent/throttle.h>
|
||||
#include <torrent/net/http_stack.h>
|
||||
#include <torrent/net/network_config.h>
|
||||
#include <torrent/net/network_manager.h>
|
||||
#include <torrent/net/socket_address.h>
|
||||
#include <torrent/utils/log.h>
|
||||
|
||||
#include "rpc/parse_commands.h"
|
||||
@@ -97,7 +99,10 @@ Manager::set_address_throttle(uint32_t begin, uint32_t end, torrent::ThrottlePai
|
||||
|
||||
torrent::ThrottlePair
|
||||
Manager::get_address_throttle(const sockaddr* addr) {
|
||||
return m_addressThrottles.get(rak::socket_address::cast_from(addr)->sa_inet()->address_h(), torrent::ThrottlePair(nullptr, nullptr));
|
||||
if (addr->sa_family != AF_INET)
|
||||
return torrent::ThrottlePair(nullptr, nullptr);
|
||||
|
||||
return m_addressThrottles.get(ntohl(reinterpret_cast<const sockaddr_in*>(addr)->sin_addr.s_addr), torrent::ThrottlePair(nullptr, nullptr));
|
||||
}
|
||||
|
||||
int64_t
|
||||
@@ -171,84 +176,16 @@ Manager::listen_open() {
|
||||
if (rpc::call_command_value("network.port_random")) {
|
||||
int boundary = portFirst + random() % (portLast - portFirst + 1);
|
||||
|
||||
if (torrent::connection_manager()->listen_open(boundary, portLast) ||
|
||||
torrent::connection_manager()->listen_open(portFirst, boundary))
|
||||
if (torrent::runtime::network_manager()->listen_open(boundary, portLast) ||
|
||||
torrent::runtime::network_manager()->listen_open(portFirst, boundary))
|
||||
return;
|
||||
|
||||
} else {
|
||||
if (torrent::connection_manager()->listen_open(portFirst, portLast))
|
||||
if (torrent::runtime::network_manager()->listen_open(portFirst, portLast))
|
||||
return;
|
||||
}
|
||||
|
||||
throw torrent::input_error("Could not open/bind port for listening: " + std::string(rak::error_number::current().c_str()));
|
||||
}
|
||||
|
||||
std::string
|
||||
Manager::bind_address() const {
|
||||
return rak::socket_address::cast_from(torrent::connection_manager()->bind_address())->address_str();
|
||||
}
|
||||
|
||||
void
|
||||
Manager::set_bind_address(const std::string& addr) {
|
||||
int err;
|
||||
rak::address_info* ai;
|
||||
|
||||
if ((err = rak::address_info::get_address_info(addr.c_str(), PF_INET, SOCK_STREAM, &ai)) != 0 &&
|
||||
(err = rak::address_info::get_address_info(addr.c_str(), PF_INET6, SOCK_STREAM, &ai)) != 0)
|
||||
throw torrent::input_error("Could not set bind address: " + std::string(rak::address_info::strerror(err)) + ".");
|
||||
|
||||
try {
|
||||
|
||||
if (torrent::connection_manager()->listen_port() != 0) {
|
||||
torrent::connection_manager()->listen_close();
|
||||
torrent::connection_manager()->set_bind_address(ai->address()->c_sockaddr());
|
||||
listen_open();
|
||||
|
||||
} else {
|
||||
torrent::connection_manager()->set_bind_address(ai->address()->c_sockaddr());
|
||||
}
|
||||
|
||||
if (ai->address()->is_address_any())
|
||||
torrent::net_thread::http_stack()->set_bind_address(std::string());
|
||||
else
|
||||
torrent::net_thread::http_stack()->set_bind_address(ai->address()->address_str());
|
||||
|
||||
rak::address_info::free_address_info(ai);
|
||||
|
||||
} catch (torrent::input_error& e) {
|
||||
rak::address_info::free_address_info(ai);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
std::string
|
||||
Manager::local_address() const {
|
||||
return rak::socket_address::cast_from(torrent::connection_manager()->local_address())->address_str();
|
||||
}
|
||||
|
||||
void
|
||||
Manager::set_local_address(const std::string& addr) {
|
||||
int err;
|
||||
rak::address_info* ai;
|
||||
|
||||
if ((err = rak::address_info::get_address_info(addr.c_str(), PF_INET, SOCK_STREAM, &ai)) != 0 &&
|
||||
(err = rak::address_info::get_address_info(addr.c_str(), PF_INET6, SOCK_STREAM, &ai)) != 0)
|
||||
throw torrent::input_error("Could not set local address: " + std::string(rak::address_info::strerror(err)) + ".");
|
||||
|
||||
try {
|
||||
|
||||
torrent::connection_manager()->set_local_address(ai->address()->c_sockaddr());
|
||||
rak::address_info::free_address_info(ai);
|
||||
|
||||
} catch (torrent::input_error& e) {
|
||||
rak::address_info::free_address_info(ai);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
std::string
|
||||
Manager::proxy_address() const {
|
||||
return rak::socket_address::cast_from(torrent::connection_manager()->proxy_address())->address_str();
|
||||
throw torrent::input_error("Could not open/bind port for listening: " + std::string(std::strerror(errno)));
|
||||
}
|
||||
|
||||
void
|
||||
@@ -271,8 +208,10 @@ Manager::set_proxy_address(const std::string& addr) {
|
||||
|
||||
try {
|
||||
|
||||
ai->address()->set_port(port);
|
||||
torrent::connection_manager()->set_proxy_address(ai->address()->c_sockaddr());
|
||||
auto sa = torrent::sa_copy(ai->c_addrinfo()->ai_addr);
|
||||
torrent::sap_set_port(sa, port);
|
||||
|
||||
torrent::config::network_config()->set_proxy_address(sa.get());
|
||||
|
||||
rak::address_info::free_address_info(ai);
|
||||
|
||||
|
||||
@@ -61,13 +61,6 @@ public:
|
||||
|
||||
void listen_open();
|
||||
|
||||
std::string bind_address() const;
|
||||
void set_bind_address(const std::string& addr);
|
||||
|
||||
std::string local_address() const;
|
||||
void set_local_address(const std::string& addr);
|
||||
|
||||
std::string proxy_address() const;
|
||||
void set_proxy_address(const std::string& addr);
|
||||
|
||||
void shutdown(bool force);
|
||||
|
||||
+38
-30
@@ -11,23 +11,31 @@
|
||||
|
||||
namespace display {
|
||||
|
||||
bool Canvas::m_isInitialized = false;
|
||||
bool Canvas::m_isDaemon = false;
|
||||
bool Canvas::m_initialized{};
|
||||
bool Canvas::m_daemon{};
|
||||
|
||||
// Maps ncurses color IDs to a ncurses attribute int
|
||||
std::unordered_map<int, int> Canvas::m_attr_map = {};
|
||||
|
||||
Canvas::Canvas(int x, int y, int width, int height) {
|
||||
if (!m_isDaemon) {
|
||||
if (!m_daemon) {
|
||||
m_window = newwin(height, width, y, x);
|
||||
|
||||
if (m_window == NULL)
|
||||
if (m_window == nullptr)
|
||||
throw torrent::internal_error("Could not allocate ncurses canvas.");
|
||||
}
|
||||
}
|
||||
|
||||
Canvas::~Canvas() {
|
||||
if (!m_daemon && m_window != nullptr) {
|
||||
delwin(m_window);
|
||||
m_window = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Canvas::resize(int x, int y, int w, int h) {
|
||||
if (!m_isDaemon) {
|
||||
if (!m_daemon) {
|
||||
wresize(m_window, h, w);
|
||||
mvwin(m_window, y, x);
|
||||
}
|
||||
@@ -35,7 +43,7 @@ Canvas::resize(int x, int y, int w, int h) {
|
||||
|
||||
void
|
||||
Canvas::print_attributes(unsigned int x, unsigned int y, const char* first, const char* last, const attributes_list* attributes) {
|
||||
if (!m_isDaemon) {
|
||||
if (!m_daemon) {
|
||||
move(x, y);
|
||||
|
||||
attr_t org_attr;
|
||||
@@ -68,14 +76,13 @@ Canvas::print_attributes(unsigned int x, unsigned int y, const char* first, cons
|
||||
|
||||
void
|
||||
Canvas::initialize() {
|
||||
if (m_isInitialized)
|
||||
return;
|
||||
if (m_initialized)
|
||||
throw torrent::internal_error("Canvas::initialize() called more than once.");
|
||||
|
||||
m_isDaemon = rpc::call_command_value("system.daemon");
|
||||
m_daemon = rpc::call_command_value("system.daemon");
|
||||
m_initialized = true;
|
||||
|
||||
m_isInitialized = true;
|
||||
|
||||
if (!m_isDaemon) {
|
||||
if (!m_daemon) {
|
||||
initscr();
|
||||
start_color();
|
||||
use_default_colors();
|
||||
@@ -88,6 +95,19 @@ Canvas::initialize() {
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Canvas::cleanup() {
|
||||
if (!m_initialized)
|
||||
return;
|
||||
|
||||
m_initialized = false;
|
||||
|
||||
if (!m_daemon) {
|
||||
noraw();
|
||||
endwin();
|
||||
}
|
||||
}
|
||||
|
||||
// Function wrapper for what possibly is a macro
|
||||
int
|
||||
get_colors() {
|
||||
@@ -102,7 +122,7 @@ Canvas::build_colors() {
|
||||
// This may get called early in the start process by the config
|
||||
// file, so we need to delay building until initscr() has a chance
|
||||
// to run
|
||||
if (!m_isInitialized || m_isDaemon)
|
||||
if (!m_initialized || m_daemon)
|
||||
return;
|
||||
|
||||
// basic color names, index maps to ncurses COLOR_*
|
||||
@@ -115,7 +135,9 @@ Canvas::build_colors() {
|
||||
|
||||
for (int k = 1; k < RCOLOR_MAX; k++) {
|
||||
init_pair(k, -1, -1);
|
||||
|
||||
std::string color_def = rpc::call_command_string(color_vars[k]);
|
||||
|
||||
if (color_def.empty())
|
||||
continue; // Use terminal default if definition is empty
|
||||
|
||||
@@ -126,6 +148,7 @@ Canvas::build_colors() {
|
||||
|
||||
// Process string as space-separated words
|
||||
size_t start = 0, end = 0;
|
||||
|
||||
while (true) {
|
||||
end = color_def.find(' ', start);
|
||||
std::string word = color_def.substr(start, end - start);
|
||||
@@ -169,10 +192,8 @@ Canvas::build_colors() {
|
||||
|
||||
// Check that fg & bg color index is valid
|
||||
if ((color[0] != -1 && color[0] >= get_colors()) || (color[1] != -1 && color[1] >= get_colors())) {
|
||||
char buf[33];
|
||||
snprintf(buf, 33, "%d", get_colors());
|
||||
Canvas::cleanup();
|
||||
throw torrent::input_error(color_def + ": your terminal only supports " + buf + " colors.");
|
||||
throw torrent::input_error(color_def + ": your terminal only supports " + std::to_string(get_colors()) + " colors.");
|
||||
}
|
||||
|
||||
m_attr_map[k] = attr; // overwrite or insert the value
|
||||
@@ -196,24 +217,11 @@ Canvas::build_colors() {
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Canvas::cleanup() {
|
||||
if (!m_isInitialized)
|
||||
return;
|
||||
|
||||
m_isInitialized = false;
|
||||
|
||||
if (!m_isDaemon) {
|
||||
noraw();
|
||||
endwin();
|
||||
}
|
||||
}
|
||||
|
||||
std::pair<int, int>
|
||||
Canvas::term_size() {
|
||||
struct winsize ws;
|
||||
|
||||
if (!m_isDaemon) {
|
||||
if (!m_daemon) {
|
||||
if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) == 0)
|
||||
return std::pair<int, int>(ws.ws_col, ws.ws_row);
|
||||
}
|
||||
|
||||
+29
-34
@@ -54,9 +54,10 @@ public:
|
||||
|
||||
// Initialize stdscr.
|
||||
static void initialize();
|
||||
static void build_colors();
|
||||
static void cleanup();
|
||||
|
||||
static void build_colors();
|
||||
|
||||
static int get_screen_width();
|
||||
static int get_screen_height();
|
||||
|
||||
@@ -64,15 +65,15 @@ public:
|
||||
|
||||
static void do_update();
|
||||
|
||||
static bool daemon() { return m_isDaemon; }
|
||||
static bool daemon() { return m_daemon; }
|
||||
static const attributes_map& attr_map() { return m_attr_map; }
|
||||
|
||||
private:
|
||||
Canvas(const Canvas&);
|
||||
void operator=(const Canvas&);
|
||||
|
||||
static bool m_isInitialized;
|
||||
static bool m_isDaemon;
|
||||
static bool m_initialized;
|
||||
static bool m_daemon;
|
||||
|
||||
// Maps ncurses color IDs to a ncurses attribute int
|
||||
static std::unordered_map<int, int> m_attr_map;
|
||||
@@ -80,57 +81,51 @@ private:
|
||||
WINDOW* m_window;
|
||||
};
|
||||
|
||||
inline Canvas::~Canvas() {
|
||||
if (!m_isDaemon) {
|
||||
delwin(m_window);
|
||||
}
|
||||
}
|
||||
|
||||
inline void
|
||||
Canvas::refresh() {
|
||||
if (!m_isDaemon) {
|
||||
if (!m_daemon) {
|
||||
wnoutrefresh(m_window);
|
||||
}
|
||||
}
|
||||
|
||||
inline void
|
||||
Canvas::refresh_std() {
|
||||
if (!m_isDaemon) {
|
||||
if (!m_daemon) {
|
||||
wnoutrefresh(stdscr);
|
||||
}
|
||||
}
|
||||
|
||||
inline void
|
||||
Canvas::redraw() {
|
||||
if (!m_isDaemon) {
|
||||
if (!m_daemon) {
|
||||
redrawwin(m_window);
|
||||
}
|
||||
}
|
||||
|
||||
inline void
|
||||
Canvas::redraw_std() {
|
||||
if (!m_isDaemon) {
|
||||
if (!m_daemon) {
|
||||
redrawwin(stdscr);
|
||||
}
|
||||
}
|
||||
|
||||
inline void
|
||||
Canvas::resize(int w, int h) {
|
||||
if (!m_isDaemon) {
|
||||
if (!m_daemon) {
|
||||
wresize(m_window, h, w);
|
||||
}
|
||||
}
|
||||
|
||||
inline void
|
||||
Canvas::resize_term(int x, int y) {
|
||||
if (!m_isDaemon) {
|
||||
if (!m_daemon) {
|
||||
resizeterm(y, x);
|
||||
}
|
||||
}
|
||||
|
||||
inline void
|
||||
Canvas::resize_term(std::pair<int, int> dim) {
|
||||
if (!m_isDaemon) {
|
||||
if (!m_daemon) {
|
||||
resizeterm(dim.second, dim.first);
|
||||
}
|
||||
}
|
||||
@@ -139,7 +134,7 @@ inline unsigned int
|
||||
Canvas::get_x() {
|
||||
int x;
|
||||
[[maybe_unused]] int y;
|
||||
if (!m_isDaemon) {
|
||||
if (!m_daemon) {
|
||||
getyx(m_window, y, x);
|
||||
} else {
|
||||
x = 1;
|
||||
@@ -150,7 +145,7 @@ Canvas::get_x() {
|
||||
inline unsigned int
|
||||
Canvas::get_y() {
|
||||
int x, y;
|
||||
if (!m_isDaemon) {
|
||||
if (!m_daemon) {
|
||||
getyx(m_window, y, x);
|
||||
} else {
|
||||
y = 1;
|
||||
@@ -162,7 +157,7 @@ inline unsigned int
|
||||
Canvas::width() {
|
||||
int x;
|
||||
[[maybe_unused]] int y;
|
||||
if (!m_isDaemon) {
|
||||
if (!m_daemon) {
|
||||
getmaxyx(m_window, y, x);
|
||||
} else {
|
||||
x = 80;
|
||||
@@ -173,7 +168,7 @@ Canvas::width() {
|
||||
inline unsigned int
|
||||
Canvas::height() {
|
||||
int x, y;
|
||||
if (!m_isDaemon) {
|
||||
if (!m_daemon) {
|
||||
getmaxyx(m_window, y, x);
|
||||
} else {
|
||||
y = 24;
|
||||
@@ -183,21 +178,21 @@ Canvas::height() {
|
||||
|
||||
inline void
|
||||
Canvas::move(unsigned int x, unsigned int y) {
|
||||
if (!m_isDaemon) {
|
||||
if (!m_daemon) {
|
||||
wmove(m_window, y, x);
|
||||
}
|
||||
}
|
||||
|
||||
inline void
|
||||
Canvas::erase() {
|
||||
if (!m_isDaemon) {
|
||||
if (!m_daemon) {
|
||||
werase(m_window);
|
||||
}
|
||||
}
|
||||
|
||||
inline void
|
||||
Canvas::erase_std() {
|
||||
if (!m_isDaemon) {
|
||||
if (!m_daemon) {
|
||||
werase(stdscr);
|
||||
}
|
||||
}
|
||||
@@ -206,7 +201,7 @@ inline void
|
||||
Canvas::print(const char* str, ...) {
|
||||
va_list arglist;
|
||||
|
||||
if (!m_isDaemon) {
|
||||
if (!m_daemon) {
|
||||
va_start(arglist, str);
|
||||
vw_printw(m_window, const_cast<char*>(str), arglist);
|
||||
va_end(arglist);
|
||||
@@ -217,7 +212,7 @@ inline void
|
||||
Canvas::print(unsigned int x, unsigned int y, const char* str, ...) {
|
||||
va_list arglist;
|
||||
|
||||
if (!m_isDaemon) {
|
||||
if (!m_daemon) {
|
||||
va_start(arglist, str);
|
||||
wmove(m_window, y, x);
|
||||
vw_printw(m_window, const_cast<char*>(str), arglist);
|
||||
@@ -227,35 +222,35 @@ Canvas::print(unsigned int x, unsigned int y, const char* str, ...) {
|
||||
|
||||
inline void
|
||||
Canvas::print_char(const chtype ch) {
|
||||
if (!m_isDaemon) {
|
||||
if (!m_daemon) {
|
||||
waddch(m_window, ch);
|
||||
}
|
||||
}
|
||||
|
||||
inline void
|
||||
Canvas::print_char(unsigned int x, unsigned int y, const chtype ch) {
|
||||
if (!m_isDaemon) {
|
||||
if (!m_daemon) {
|
||||
mvwaddch(m_window, y, x, ch);
|
||||
}
|
||||
}
|
||||
|
||||
inline void
|
||||
Canvas::set_attr(unsigned int x, unsigned int y, unsigned int n, int attr, int color) {
|
||||
if (!m_isDaemon) {
|
||||
if (!m_daemon) {
|
||||
mvwchgat(m_window, y, x, n, attr, color, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
inline void
|
||||
Canvas::set_attr(unsigned int x, unsigned int y, unsigned int n, ColorKind k) {
|
||||
if (!m_isDaemon) {
|
||||
if (!m_daemon) {
|
||||
mvwchgat(m_window, y, x, n, m_attr_map[k], k, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
inline void
|
||||
Canvas::set_default_attributes(int attr) {
|
||||
if (!m_isDaemon) {
|
||||
if (!m_daemon) {
|
||||
(void)wattrset(m_window, attr);
|
||||
}
|
||||
}
|
||||
@@ -264,7 +259,7 @@ inline int
|
||||
Canvas::get_screen_width() {
|
||||
int x;
|
||||
[[maybe_unused]] int y;
|
||||
if (!m_isDaemon) {
|
||||
if (!m_daemon) {
|
||||
getmaxyx(stdscr, y, x);
|
||||
} else {
|
||||
x = 80;
|
||||
@@ -275,7 +270,7 @@ Canvas::get_screen_width() {
|
||||
inline int
|
||||
Canvas::get_screen_height() {
|
||||
int x, y;
|
||||
if (!m_isDaemon) {
|
||||
if (!m_daemon) {
|
||||
getmaxyx(stdscr, y, x);
|
||||
} else {
|
||||
y = 24;
|
||||
@@ -285,7 +280,7 @@ Canvas::get_screen_height() {
|
||||
|
||||
inline void
|
||||
Canvas::do_update() {
|
||||
if (!m_isDaemon) {
|
||||
if (!m_daemon) {
|
||||
doupdate();
|
||||
}
|
||||
}
|
||||
|
||||
+14
-49
@@ -1,47 +1,12 @@
|
||||
// rTorrent - BitTorrent client
|
||||
// Copyright (C) 2005-2011, 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 <sundell.software@gmail.com>
|
||||
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "display/frame.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
|
||||
#include <rak/algorithm.h>
|
||||
#include <torrent/exceptions.h>
|
||||
|
||||
#include "frame.h"
|
||||
#include "window.h"
|
||||
#include "display/window.h"
|
||||
|
||||
namespace display {
|
||||
|
||||
@@ -137,7 +102,7 @@ Frame::preferred_size() const {
|
||||
|
||||
for (size_type i = 0; i < m_containerSize; ++i) {
|
||||
bounds_type p = m_container[i]->preferred_size();
|
||||
|
||||
|
||||
accum.minWidth += p.minWidth;
|
||||
accum.minHeight += p.minHeight;
|
||||
|
||||
@@ -221,7 +186,7 @@ Frame::clear() {
|
||||
m_window->set_offscreen(true);
|
||||
|
||||
break;
|
||||
|
||||
|
||||
case TYPE_ROW:
|
||||
case TYPE_COLUMN:
|
||||
for (size_type i = 0; i < m_containerSize; ++i) {
|
||||
@@ -335,10 +300,10 @@ Frame::balance_row(uint32_t x, uint32_t y, uint32_t width, uint32_t height) {
|
||||
dynamic_type dynamicFrames[max_size];
|
||||
|
||||
int remaining = height;
|
||||
|
||||
|
||||
for (Frame **itr = m_container, **last = m_container + m_containerSize; itr != last; ++itr) {
|
||||
bounds_type bounds = (*itr)->preferred_size();
|
||||
|
||||
|
||||
if ((*itr)->is_height_dynamic()) {
|
||||
(*itr)->m_height = 0;
|
||||
dynamicFrames[dynamicSize++] = std::make_pair(*itr, bounds);
|
||||
@@ -367,11 +332,11 @@ Frame::balance_row(uint32_t x, uint32_t y, uint32_t width, uint32_t height) {
|
||||
|
||||
for (dynamic_type *itr = dynamicFrames, *last = dynamicFrames + dynamicSize; itr != last; ++itr) {
|
||||
uint32_t adjust = (std::max(remaining, 0) + std::distance(itr, last) - 1) / std::distance(itr, last);
|
||||
|
||||
|
||||
adjust += itr->first->m_height;
|
||||
adjust = std::max(adjust, itr->second.minHeight);
|
||||
adjust = std::min(adjust, itr->second.maxHeight);
|
||||
|
||||
|
||||
remaining -= adjust - itr->first->m_height;
|
||||
|
||||
retry = retry || itr->first->m_height != adjust;
|
||||
@@ -410,10 +375,10 @@ Frame::balance_column(uint32_t x, uint32_t y, uint32_t width, uint32_t height) {
|
||||
dynamic_type dynamicFrames[max_size];
|
||||
|
||||
int remaining = width;
|
||||
|
||||
|
||||
for (Frame **itr = m_container, **last = m_container + m_containerSize; itr != last; ++itr) {
|
||||
bounds_type bounds = (*itr)->preferred_size();
|
||||
|
||||
|
||||
if ((*itr)->is_width_dynamic()) {
|
||||
(*itr)->m_width = 0;
|
||||
dynamicFrames[dynamicSize++] = std::make_pair(*itr, bounds);
|
||||
@@ -423,7 +388,7 @@ Frame::balance_column(uint32_t x, uint32_t y, uint32_t width, uint32_t height) {
|
||||
remaining -= bounds.minWidth;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Sort the dynamic frames by the min size in the direction we are
|
||||
// interested in. Then try to satisfy the largest first, and if we
|
||||
// have any remaining space we can use that to extend it and any
|
||||
@@ -442,11 +407,11 @@ Frame::balance_column(uint32_t x, uint32_t y, uint32_t width, uint32_t height) {
|
||||
|
||||
for (dynamic_type *itr = dynamicFrames, *last = dynamicFrames + dynamicSize; itr != last; ++itr) {
|
||||
uint32_t adjust = (std::max(remaining, 0) + std::distance(itr, last) - 1) / std::distance(itr, last);
|
||||
|
||||
|
||||
adjust += itr->first->m_width;
|
||||
adjust = std::max(adjust, itr->second.minWidth);
|
||||
adjust = std::min(adjust, itr->second.maxWidth);
|
||||
|
||||
|
||||
remaining -= adjust - itr->first->m_width;
|
||||
|
||||
retry = retry || itr->first->m_width != adjust;
|
||||
|
||||
+2
-35
@@ -1,41 +1,8 @@
|
||||
// rTorrent - BitTorrent client
|
||||
// Copyright (C) 2005-2011, 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 <sundell.software@gmail.com>
|
||||
|
||||
|
||||
#ifndef RTORRENT_DISPLAY_FRAME_H
|
||||
#define RTORRENT_DISPLAY_FRAME_H
|
||||
|
||||
#include <cinttypes>
|
||||
#include <utility>
|
||||
|
||||
namespace display {
|
||||
|
||||
@@ -121,7 +88,7 @@ private:
|
||||
|
||||
union {
|
||||
Window* m_window;
|
||||
|
||||
|
||||
struct {
|
||||
size_type m_containerSize;
|
||||
Frame* m_container[max_size];
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#include <torrent/utils/scheduler.h>
|
||||
|
||||
#include "frame.h"
|
||||
#include "display/frame.h"
|
||||
|
||||
namespace display {
|
||||
|
||||
|
||||
@@ -50,16 +50,16 @@ TextElementStringBase::print(char* first, char* last, Canvas::attributes_list* a
|
||||
return first;
|
||||
|
||||
if (m_flags & flag_escape_hex) {
|
||||
char buffer[last - first];
|
||||
char* bufferLast = copy_string(buffer, buffer + (last - first), target);
|
||||
auto buffer = std::make_unique<char[]>(last - first);
|
||||
char* bufferLast = copy_string(buffer.get(), buffer.get() + (last - first), target);
|
||||
|
||||
first = rak::transform_hex(buffer, bufferLast, first, last);
|
||||
first = rak::transform_hex(buffer.get(), bufferLast, first, last);
|
||||
|
||||
} else if (m_flags & flag_escape_html) {
|
||||
char buffer[last - first];
|
||||
char* bufferLast = copy_string(buffer, buffer + (last - first), target);
|
||||
auto buffer = std::make_unique<char[]>(last - first);
|
||||
char* bufferLast = copy_string(buffer.get(), buffer.get() + (last - first), target);
|
||||
|
||||
first = rak::copy_escape_html(buffer, bufferLast, first, last);
|
||||
first = rak::copy_escape_html(buffer.get(), bufferLast, first, last);
|
||||
|
||||
} else {
|
||||
first = copy_string(first, last, target);
|
||||
|
||||
+29
-18
@@ -6,7 +6,6 @@
|
||||
#include <cstdio>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
#include <rak/socket_address.h>
|
||||
#include <torrent/exceptions.h>
|
||||
#include <torrent/connection_manager.h>
|
||||
#include <torrent/rate.h>
|
||||
@@ -17,6 +16,9 @@
|
||||
#include <torrent/data/file_manager.h>
|
||||
#include <torrent/download/resource_manager.h>
|
||||
#include <torrent/net/http_stack.h>
|
||||
#include <torrent/net/network_config.h>
|
||||
#include <torrent/net/network_manager.h>
|
||||
#include <torrent/net/socket_address.h>
|
||||
#include <torrent/peer/client_info.h>
|
||||
|
||||
#include "control.h"
|
||||
@@ -29,7 +31,7 @@
|
||||
namespace display {
|
||||
|
||||
char*
|
||||
print_string(char* first, char* last, char* str) {
|
||||
print_string(char* first, char* last, const char* str) {
|
||||
if (first == last)
|
||||
return first;
|
||||
|
||||
@@ -78,17 +80,9 @@ print_ddmmyyyy(char* first, char* last, time_t t) {
|
||||
return print_buffer(first, last, "%02u/%02u/%04u", u->tm_mday, (u->tm_mon + 1), (1900 + u->tm_year));
|
||||
}
|
||||
|
||||
char*
|
||||
print_address(char* first, char* last, const rak::socket_address* sa) {
|
||||
if (!sa->address_c_str(first, last - first))
|
||||
return first;
|
||||
|
||||
return std::find(first, last, '\0');
|
||||
}
|
||||
|
||||
inline char*
|
||||
print_address(char* first, char* last, const sockaddr* sa) {
|
||||
return print_address(first, last, rak::socket_address::cast_from(sa));
|
||||
return print_string(first, last, torrent::sa_addr_str(sa).c_str());
|
||||
}
|
||||
|
||||
char*
|
||||
@@ -382,20 +376,37 @@ print_status_info(char* first, char* last) {
|
||||
|
||||
first = print_buffer(first, last, " KB]");
|
||||
|
||||
first = print_buffer(first, last, " [Port: %i]", (unsigned int)torrent::connection_manager()->listen_port());
|
||||
first = print_buffer(first, last, " [Port: %i]", (unsigned int)torrent::runtime::network_manager()->listen_port());
|
||||
|
||||
if (!rak::socket_address::cast_from(torrent::connection_manager()->local_address())->is_address_any()) {
|
||||
auto local_address = torrent::config::network_config()->local_address_best_match();
|
||||
|
||||
if (!torrent::sa_is_any(local_address.get())) {
|
||||
first = print_buffer(first, last, " [Local ");
|
||||
first = print_address(first, last, torrent::connection_manager()->local_address());
|
||||
first = print_address(first, last, local_address.get());
|
||||
first = print_buffer(first, last, "]");
|
||||
}
|
||||
|
||||
if (first > last)
|
||||
throw torrent::internal_error("print_status_info(...) wrote past end of the buffer.");
|
||||
|
||||
if (!rak::socket_address::cast_from(torrent::connection_manager()->bind_address())->is_address_any()) {
|
||||
auto bind_inet_address = torrent::config::network_config()->bind_inet_address();
|
||||
auto bind_inet6_address = torrent::config::network_config()->bind_inet6_address();
|
||||
bool show_bind_inet = !torrent::sa_is_any(bind_inet_address.get());
|
||||
bool show_bind_inet6 = !torrent::sa_is_any(bind_inet6_address.get());
|
||||
|
||||
if (show_bind_inet || show_bind_inet6) {
|
||||
first = print_buffer(first, last, " [Bind ");
|
||||
first = print_address(first, last, torrent::connection_manager()->bind_address());
|
||||
|
||||
if (show_bind_inet)
|
||||
first = print_address(first, last, bind_inet_address.get());
|
||||
|
||||
if (show_bind_inet6) {
|
||||
if (show_bind_inet)
|
||||
first = print_buffer(first, last, " / ");
|
||||
|
||||
first = print_address(first, last, bind_inet6_address.get());
|
||||
}
|
||||
|
||||
first = print_buffer(first, last, "]");
|
||||
}
|
||||
|
||||
@@ -413,8 +424,8 @@ print_status_extra(char* first, char* last) {
|
||||
torrent::resource_manager()->max_download_unchoked());
|
||||
|
||||
first = print_buffer(first, last, " [H %u/%u]",
|
||||
torrent::net_thread::http_stack()->active(),
|
||||
torrent::net_thread::http_stack()->max_active());
|
||||
torrent::net_thread::http_stack()->size(),
|
||||
torrent::net_thread::http_stack()->max_total_connections());
|
||||
|
||||
first = print_buffer(first, last, " [S %i/%i/%i]",
|
||||
torrent::total_handshakes(),
|
||||
|
||||
@@ -31,8 +31,6 @@ Window::Window(Canvas* canvas, int flags, extent_type min_width, extent_type min
|
||||
Window::~Window() {
|
||||
if (is_active())
|
||||
m_slot_unschedule(this);
|
||||
|
||||
delete m_canvas;
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -89,7 +89,7 @@ protected:
|
||||
static SlotWindow m_slot_unschedule;
|
||||
static Slot m_slot_adjust;
|
||||
|
||||
Canvas* m_canvas;
|
||||
std::unique_ptr<Canvas> m_canvas;
|
||||
|
||||
int m_flags;
|
||||
|
||||
|
||||
@@ -1,37 +1,3 @@
|
||||
// rTorrent - BitTorrent client
|
||||
// Copyright (C) 2005-2011, 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 <sundell.software@gmail.com>
|
||||
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "canvas.h"
|
||||
|
||||
@@ -1,37 +1,3 @@
|
||||
// rTorrent - BitTorrent client
|
||||
// Copyright (C) 2005-2011, 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 <sundell.software@gmail.com>
|
||||
|
||||
|
||||
#ifndef RTORRENT_DISPLAY_WINDOW_INPUT_H
|
||||
#define RTORRENT_DISPLAY_WINDOW_INPUT_H
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
#include "config.h"
|
||||
|
||||
#include <stdexcept>
|
||||
#include <rak/socket_address.h>
|
||||
#include <torrent/rate.h>
|
||||
#include <torrent/data/block_transfer.h>
|
||||
#include <torrent/data/piece.h>
|
||||
#include <torrent/net/socket_address.h>
|
||||
#include <torrent/peer/client_list.h>
|
||||
#include <torrent/peer/peer_info.h>
|
||||
|
||||
@@ -63,7 +63,7 @@ WindowPeerList::redraw() {
|
||||
|
||||
x = 0;
|
||||
|
||||
std::string ip_address = rak::socket_address::cast_from(p->address())->address_str();
|
||||
auto ip_address = torrent::sa_addr_str(p->address());
|
||||
|
||||
if (ip_address.size() >= 24) {
|
||||
ip_address.replace(ip_address.begin() + 21, ip_address.end(), "...");
|
||||
@@ -92,7 +92,7 @@ WindowPeerList::redraw() {
|
||||
peerType = 'u';
|
||||
else if (p->peer_info()->is_preferred())
|
||||
peerType = 'p';
|
||||
else
|
||||
else
|
||||
peerType = ' ';
|
||||
|
||||
m_canvas->print(x, y, "%c%c/%c%c/%c%c",
|
||||
|
||||
@@ -7,13 +7,13 @@
|
||||
namespace input {
|
||||
|
||||
void
|
||||
InputEvent::insert(torrent::Poll* p) {
|
||||
InputEvent::insert(torrent::net::Poll* p) {
|
||||
p->open(this);
|
||||
p->insert_read(this);
|
||||
}
|
||||
|
||||
void
|
||||
InputEvent::remove(torrent::Poll* p) {
|
||||
InputEvent::remove(torrent::net::Poll* p) {
|
||||
p->remove_read(this);
|
||||
p->close(this);
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include <functional>
|
||||
|
||||
#include <torrent/event.h>
|
||||
#include <torrent/poll.h>
|
||||
#include <torrent/net/poll.h>
|
||||
|
||||
namespace input {
|
||||
|
||||
@@ -14,8 +14,8 @@ public:
|
||||
|
||||
InputEvent(int fd) { m_fileDesc = fd; }
|
||||
|
||||
void insert(torrent::Poll* p);
|
||||
void remove(torrent::Poll* p);
|
||||
void insert(torrent::net::Poll* p);
|
||||
void remove(torrent::net::Poll* p);
|
||||
|
||||
void event_read();
|
||||
void event_write();
|
||||
|
||||
+85
-61
@@ -1,7 +1,5 @@
|
||||
#include "config.h"
|
||||
|
||||
#define __STDC_FORMAT_MACROS
|
||||
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
@@ -12,6 +10,7 @@
|
||||
#include <torrent/torrent.h>
|
||||
#include <torrent/exceptions.h>
|
||||
#include <torrent/data/chunk_utils.h>
|
||||
#include <torrent/net/fd.h>
|
||||
#include <torrent/utils/chrono.h>
|
||||
#include <torrent/utils/log.h>
|
||||
#include <rak/error_number.h>
|
||||
@@ -216,6 +215,7 @@ main(int argc, char** argv) {
|
||||
torrent::initialize();
|
||||
torrent::set_main_thread_slots(std::bind(&client_perform));
|
||||
|
||||
// TODO: Move to controller.
|
||||
worker_thread = new ThreadWorker();
|
||||
worker_thread->init_thread();
|
||||
|
||||
@@ -281,7 +281,7 @@ main(int argc, char** argv) {
|
||||
"file.prioritize_toc.first.set = {*.avi,*.mp4,*.mkv,*.gz}\n"
|
||||
"file.prioritize_toc.last.set = {*.zip}\n"
|
||||
|
||||
// Allow setting 'group2.view' as constant, so that we can't
|
||||
// Allow setting 'group.view' as constant, so that we can't
|
||||
// modify the value. And look into the possibility of making
|
||||
// 'const' use non-heap memory, as we know they can't be
|
||||
// erased.
|
||||
@@ -352,72 +352,78 @@ main(int argc, char** argv) {
|
||||
// Functions that might not get depracted as they are nice for
|
||||
// configuration files, and thus might do with just some
|
||||
// cleanup.
|
||||
CMD2_REDIRECT_GENERIC("upload_rate", "throttle.global_up.max_rate.set_kb");
|
||||
CMD2_REDIRECT_GENERIC("download_rate", "throttle.global_down.max_rate.set_kb");
|
||||
CMD2_REDIRECT("upload_rate", "throttle.global_up.max_rate.set_kb");
|
||||
CMD2_REDIRECT("download_rate", "throttle.global_down.max_rate.set_kb");
|
||||
|
||||
CMD2_REDIRECT_GENERIC("ratio.enable", "group.seeding.ratio.enable");
|
||||
CMD2_REDIRECT_GENERIC("ratio.disable", "group.seeding.ratio.disable");
|
||||
CMD2_REDIRECT_GENERIC("ratio.min", "group2.seeding.ratio.min");
|
||||
CMD2_REDIRECT_GENERIC("ratio.max", "group2.seeding.ratio.max");
|
||||
CMD2_REDIRECT_GENERIC("ratio.upload", "group2.seeding.ratio.upload");
|
||||
CMD2_REDIRECT_GENERIC("ratio.min.set", "group2.seeding.ratio.min.set");
|
||||
CMD2_REDIRECT_GENERIC("ratio.max.set", "group2.seeding.ratio.max.set");
|
||||
CMD2_REDIRECT_GENERIC("ratio.upload.set", "group2.seeding.ratio.upload.set");
|
||||
CMD2_REDIRECT("ratio.enable", "group.seeding.ratio.enable");
|
||||
CMD2_REDIRECT("ratio.disable", "group.seeding.ratio.disable");
|
||||
CMD2_REDIRECT("ratio.min", "group.seeding.ratio.min");
|
||||
CMD2_REDIRECT("ratio.max", "group.seeding.ratio.max");
|
||||
CMD2_REDIRECT("ratio.upload", "group.seeding.ratio.upload");
|
||||
CMD2_REDIRECT("ratio.min.set", "group.seeding.ratio.min.set");
|
||||
CMD2_REDIRECT("ratio.max.set", "group.seeding.ratio.max.set");
|
||||
CMD2_REDIRECT("ratio.upload.set", "group.seeding.ratio.upload.set");
|
||||
|
||||
CMD2_REDIRECT_GENERIC("encryption", "protocol.encryption.set");
|
||||
CMD2_REDIRECT_GENERIC("encoding_list", "encoding.add");
|
||||
CMD2_REDIRECT("encryption", "protocol.encryption.set");
|
||||
CMD2_REDIRECT("encoding_list", "encoding.add");
|
||||
|
||||
CMD2_REDIRECT_GENERIC("connection_leech", "protocol.connection.leech.set");
|
||||
CMD2_REDIRECT_GENERIC("connection_seed", "protocol.connection.seed.set");
|
||||
CMD2_REDIRECT("connection_leech", "protocol.connection.leech.set");
|
||||
CMD2_REDIRECT("connection_seed", "protocol.connection.seed.set");
|
||||
|
||||
CMD2_REDIRECT ("min_peers", "throttle.min_peers.normal.set");
|
||||
CMD2_REDIRECT ("max_peers", "throttle.max_peers.normal.set");
|
||||
CMD2_REDIRECT ("min_peers_seed", "throttle.min_peers.seed.set");
|
||||
CMD2_REDIRECT ("max_peers_seed", "throttle.max_peers.seed.set");
|
||||
CMD2_REDIRECT("min_peers", "throttle.min_peers.normal.set");
|
||||
CMD2_REDIRECT("max_peers", "throttle.max_peers.normal.set");
|
||||
CMD2_REDIRECT("min_peers_seed", "throttle.min_peers.seed.set");
|
||||
CMD2_REDIRECT("max_peers_seed", "throttle.max_peers.seed.set");
|
||||
|
||||
CMD2_REDIRECT ("min_uploads", "throttle.min_uploads.set");
|
||||
CMD2_REDIRECT ("max_uploads", "throttle.max_uploads.set");
|
||||
CMD2_REDIRECT ("min_downloads", "throttle.min_downloads.set");
|
||||
CMD2_REDIRECT ("max_downloads", "throttle.max_downloads.set");
|
||||
CMD2_REDIRECT("min_uploads", "throttle.min_uploads.set");
|
||||
CMD2_REDIRECT("max_uploads", "throttle.max_uploads.set");
|
||||
CMD2_REDIRECT("min_downloads", "throttle.min_downloads.set");
|
||||
CMD2_REDIRECT("max_downloads", "throttle.max_downloads.set");
|
||||
|
||||
CMD2_REDIRECT ("max_uploads_div", "throttle.max_uploads.div.set");
|
||||
CMD2_REDIRECT ("max_uploads_global", "throttle.max_uploads.global.set");
|
||||
CMD2_REDIRECT ("max_downloads_div", "throttle.max_downloads.div.set");
|
||||
CMD2_REDIRECT ("max_downloads_global", "throttle.max_downloads.global.set");
|
||||
CMD2_REDIRECT("max_uploads_div", "throttle.max_uploads.div.set");
|
||||
CMD2_REDIRECT("max_uploads_global", "throttle.max_uploads.global.set");
|
||||
CMD2_REDIRECT("max_downloads_div", "throttle.max_downloads.div.set");
|
||||
CMD2_REDIRECT("max_downloads_global", "throttle.max_downloads.global.set");
|
||||
|
||||
CMD2_REDIRECT_GENERIC("max_memory_usage", "pieces.memory.max.set");
|
||||
CMD2_REDIRECT("max_memory_usage", "pieces.memory.max.set");
|
||||
|
||||
CMD2_REDIRECT ("bind", "network.bind_address.set");
|
||||
CMD2_REDIRECT ("ip", "network.local_address.set");
|
||||
CMD2_REDIRECT ("port_range", "network.port_range.set");
|
||||
CMD2_REDIRECT("bind", "network.bind_address.set");
|
||||
CMD2_REDIRECT("ip", "network.local_address.set");
|
||||
CMD2_REDIRECT("port_range", "network.port_range.set");
|
||||
|
||||
CMD2_REDIRECT_GENERIC("dht", "dht.mode.set");
|
||||
CMD2_REDIRECT_GENERIC("dht_port", "dht.port.set");
|
||||
CMD2_REDIRECT("dht", "dht.mode.set");
|
||||
|
||||
CMD2_REDIRECT ("port_random", "network.port_random.set");
|
||||
CMD2_REDIRECT ("proxy_address", "network.proxy_address.set");
|
||||
CMD2_REDIRECT("port_random", "network.port_random.set");
|
||||
CMD2_REDIRECT("proxy_address", "network.proxy_address.set");
|
||||
|
||||
CMD2_REDIRECT ("scgi_port", "network.scgi.open_port");
|
||||
CMD2_REDIRECT ("scgi_local", "network.scgi.open_local");
|
||||
CMD2_REDIRECT("scgi_port", "network.scgi.open_port");
|
||||
CMD2_REDIRECT("scgi_local", "network.scgi.open_local");
|
||||
|
||||
CMD2_REDIRECT_GENERIC("directory", "directory.default.set");
|
||||
CMD2_REDIRECT_GENERIC("session", "session.path.set");
|
||||
CMD2_REDIRECT("directory", "directory.default.set");
|
||||
CMD2_REDIRECT("session", "session.path.set");
|
||||
|
||||
CMD2_REDIRECT ("check_hash", "pieces.hash.on_completion.set");
|
||||
CMD2_REDIRECT("check_hash", "pieces.hash.on_completion.set");
|
||||
|
||||
CMD2_REDIRECT ("key_layout", "keys.layout.set");
|
||||
CMD2_REDIRECT("key_layout", "keys.layout.set");
|
||||
|
||||
CMD2_REDIRECT_GENERIC("to_gm_time", "convert.gm_time");
|
||||
CMD2_REDIRECT_GENERIC("to_gm_date", "convert.gm_date");
|
||||
CMD2_REDIRECT_GENERIC("to_time", "convert.time");
|
||||
CMD2_REDIRECT_GENERIC("to_date", "convert.date");
|
||||
CMD2_REDIRECT_GENERIC("to_elapsed_time", "convert.elapsed_time");
|
||||
CMD2_REDIRECT_GENERIC("to_kb", "convert.kb");
|
||||
CMD2_REDIRECT_GENERIC("to_mb", "convert.mb");
|
||||
CMD2_REDIRECT_GENERIC("to_xb", "convert.xb");
|
||||
CMD2_REDIRECT_GENERIC("to_throttle", "convert.throttle");
|
||||
CMD2_REDIRECT("to_gm_time", "convert.gm_time");
|
||||
CMD2_REDIRECT("to_gm_date", "convert.gm_date");
|
||||
CMD2_REDIRECT("to_time", "convert.time");
|
||||
CMD2_REDIRECT("to_date", "convert.date");
|
||||
CMD2_REDIRECT("to_elapsed_time", "convert.elapsed_time");
|
||||
CMD2_REDIRECT("to_kb", "convert.kb");
|
||||
CMD2_REDIRECT("to_mb", "convert.mb");
|
||||
CMD2_REDIRECT("to_xb", "convert.xb");
|
||||
CMD2_REDIRECT("to_throttle", "convert.throttle");
|
||||
|
||||
CMD2_REDIRECT ("torrent_list_layout", "ui.torrent_list.layout.set");
|
||||
CMD2_REDIRECT("torrent_list_layout", "ui.torrent_list.layout.set");
|
||||
|
||||
// Deprecate:
|
||||
|
||||
CMD2_VAR_STRING("dht.throttle.name", "deprecated");
|
||||
|
||||
CMD2_REDIRECT("network.http.max_open", "network.http.max_total_connections");
|
||||
CMD2_REDIRECT("network.http.max_open.set", "network.http.max_total_connections.set");
|
||||
|
||||
// Deprecated commands. Don't use these anymore.
|
||||
//
|
||||
@@ -425,22 +431,35 @@ main(int argc, char** argv) {
|
||||
// call style, where the first argument is the target.
|
||||
|
||||
// if (rpc::call_command_value("method.use_intermediate") == 1) {
|
||||
// CMD2_REDIRECT_GENERIC("execute", "execute2");
|
||||
// CMD2_REDIRECT("execute", "execute2");
|
||||
|
||||
// CMD2_REDIRECT_GENERIC("schedule", "schedule2");
|
||||
// CMD2_REDIRECT_GENERIC("schedule_remove", "schedule_remove2");
|
||||
// CMD2_REDIRECT("schedule", "schedule2");
|
||||
// CMD2_REDIRECT("schedule_remove", "schedule_remove2");
|
||||
|
||||
// } else if (rpc::call_command_value("method.use_intermediate") == 2) {
|
||||
// Allow for use in config files, etc, just don't export it.
|
||||
// CMD2_REDIRECT_GENERIC_NO_EXPORT("execute", "execute2");
|
||||
// CMD2_REDIRECT_NO_EXPORT("execute", "execute2");
|
||||
|
||||
// CMD2_REDIRECT_GENERIC_NO_EXPORT("schedule", "schedule2");
|
||||
// CMD2_REDIRECT_GENERIC_NO_EXPORT("schedule_remove", "schedule_remove2");
|
||||
// CMD2_REDIRECT_NO_EXPORT("schedule", "schedule2");
|
||||
// CMD2_REDIRECT_NO_EXPORT("schedule_remove", "schedule_remove2");
|
||||
// }
|
||||
|
||||
// if (rpc::call_command_value("method.use_deprecated") == 1) {
|
||||
// }
|
||||
|
||||
{
|
||||
auto fd = torrent::fd_open_family(torrent::fd_flag_stream, AF_INET6);
|
||||
|
||||
if (fd == -1) {
|
||||
if (errno == EAFNOSUPPORT) {
|
||||
lt_log_print(torrent::LOG_WARN, "disabling ipv6 support, not available on system");
|
||||
rpc::call_command_set_value("network.block.ipv6.set", true);
|
||||
}
|
||||
} else {
|
||||
torrent::fd_close(fd);
|
||||
}
|
||||
}
|
||||
|
||||
int firstArg = parse_options(argc, argv);
|
||||
|
||||
if (OptionParser::has_flag('n', argc, argv)) {
|
||||
@@ -480,8 +499,6 @@ main(int argc, char** argv) {
|
||||
control->display()->adjust_layout();
|
||||
control->display()->receive_update();
|
||||
|
||||
worker_thread->start_thread();
|
||||
|
||||
rpc::commands.call_catch("event.system.startup_done", rpc::make_target(), "startup_done", "System startup_done event action failed: ");
|
||||
|
||||
torrent::utils::Thread::self()->event_loop();
|
||||
@@ -498,6 +515,8 @@ main(int argc, char** argv) {
|
||||
|
||||
lt_log_print_dump(torrent::LOG_CRITICAL, e.backtrace().c_str(), e.backtrace().size(),
|
||||
"Caught internal_error: '%s'.", e.what());
|
||||
|
||||
torrent::log_cleanup();
|
||||
return -1;
|
||||
|
||||
} catch (std::exception& e) {
|
||||
@@ -506,13 +525,18 @@ main(int argc, char** argv) {
|
||||
std::cout << "rtorrent: caught" << typeid(e).name() << " : " << e.what() << std::endl;
|
||||
|
||||
lt_log_print(torrent::LOG_CRITICAL, "Caught exception: '%s'.", e.what());
|
||||
|
||||
torrent::log_cleanup();
|
||||
return -1;
|
||||
}
|
||||
|
||||
torrent::log_cleanup();
|
||||
|
||||
delete control;
|
||||
control = nullptr;
|
||||
|
||||
delete worker_thread;
|
||||
worker_thread = nullptr;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -53,9 +53,8 @@ public:
|
||||
static const int flag_is_redirect = 0x20;
|
||||
static const int flag_has_redirects = 0x40;
|
||||
|
||||
static const int flag_no_target = 0x100;
|
||||
static const int flag_file_target = 0x200;
|
||||
static const int flag_tracker_target = 0x400;
|
||||
static const int flag_file_target = 0x100;
|
||||
static const int flag_tracker_target = 0x200;
|
||||
|
||||
CommandMap() = default;
|
||||
|
||||
|
||||
+7
-9
@@ -122,18 +122,16 @@ jsonrpc_call_command(const std::string& method, const json& params) {
|
||||
std::function<void()> deleter = []() {};
|
||||
utils::scope_guard guard([&deleter]() { deleter(); });
|
||||
|
||||
if (!(itr->second.m_flags & CommandMap::flag_no_target)) {
|
||||
// Provide a blank target if none was provided
|
||||
if (params_object_list.empty())
|
||||
params_object_list.push_back("");
|
||||
// Provide a blank target if none was provided
|
||||
if (params_object_list.empty())
|
||||
params_object_list.push_back("");
|
||||
|
||||
if (!params_object_list.begin()->is_string())
|
||||
throw torrent::input_error("invalid parameters: target must be a string");
|
||||
if (!params_object_list.begin()->is_string())
|
||||
throw torrent::input_error("invalid parameters: target must be a string");
|
||||
|
||||
RpcManager::object_to_target(params_object_list.begin()->as_string(), itr->second.m_flags, &target, &deleter);
|
||||
RpcManager::object_to_target(params_object_list.begin()->as_string(), itr->second.m_flags, &target, &deleter);
|
||||
|
||||
params_object_list.erase(params_object_list.begin());
|
||||
}
|
||||
params_object_list.erase(params_object_list.begin());
|
||||
|
||||
const auto& result = rpc::commands.call_command(itr, params_object, target);
|
||||
|
||||
|
||||
+4
-4
@@ -405,12 +405,12 @@ convert_to_value_nothrow(const torrent::Object& src, int64_t* value, int base, i
|
||||
case torrent::Object::TYPE_RAW_STRING: {
|
||||
const torrent::raw_string& str = src.as_raw_string();
|
||||
|
||||
char buffer[str.size() + 1];
|
||||
std::memcpy(buffer, str.data(), str.size());
|
||||
auto buffer = std::make_unique<char[]>(str.size() + 1);
|
||||
std::memcpy(buffer.get(), str.data(), str.size());
|
||||
buffer[str.size()] = '\0';
|
||||
|
||||
return parse_skip_wspace(parse_value(buffer, value, base, unit), buffer + str.size())
|
||||
== buffer + str.size();
|
||||
return parse_skip_wspace(parse_value(buffer.get(), value, base, unit), buffer.get() + str.size())
|
||||
== buffer.get() + str.size();
|
||||
}
|
||||
case torrent::Object::TYPE_NONE:
|
||||
*value = 0;
|
||||
|
||||
@@ -15,24 +15,18 @@ ExecFile execFile;
|
||||
|
||||
void
|
||||
RpcManager::object_to_target(const torrent::Object& obj, int call_flags, rpc::target_type* target, std::function<void()>* deleter) {
|
||||
if (call_flags & CommandMap::flag_no_target)
|
||||
return;
|
||||
|
||||
if (!obj.is_string()) {
|
||||
if (!obj.is_string())
|
||||
throw torrent::input_error("invalid parameters: target must be a string");
|
||||
}
|
||||
|
||||
std::string target_string = obj.as_string();
|
||||
bool require_index = (call_flags & (CommandMap::flag_tracker_target | CommandMap::flag_file_target));
|
||||
|
||||
if (target_string.size() == 0 && !require_index) {
|
||||
if (target_string.size() == 0 && !require_index)
|
||||
return;
|
||||
}
|
||||
|
||||
// Length of SHA1 hash is 40
|
||||
if (target_string.size() < 40) {
|
||||
if (target_string.size() < 40)
|
||||
throw torrent::input_error("invalid parameters: invalid target");
|
||||
}
|
||||
|
||||
char type = 'd';
|
||||
std::string hash;
|
||||
|
||||
+19
-13
@@ -1,13 +1,13 @@
|
||||
#include "config.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <rak/error_number.h>
|
||||
#include <rak/socket_address.h>
|
||||
#include <sys/un.h>
|
||||
#include <torrent/connection_manager.h>
|
||||
#include <torrent/poll.h>
|
||||
#include <torrent/torrent.h>
|
||||
#include <torrent/exceptions.h>
|
||||
#include <torrent/net/fd.h>
|
||||
#include <torrent/net/poll.h>
|
||||
#include <torrent/net/socket_address.h>
|
||||
|
||||
#include "control.h"
|
||||
#include "globals.h"
|
||||
@@ -41,7 +41,7 @@ void
|
||||
SCgi::open_port(void* sa, unsigned int length, bool dontRoute) {
|
||||
if (!get_fd().open_stream() ||
|
||||
(dontRoute && !get_fd().set_dont_route(true)))
|
||||
throw torrent::resource_error("Could not open socket for listening: " + std::string(rak::error_number::current().c_str()));
|
||||
throw torrent::resource_error("Could not open socket for listening: " + std::string(std::strerror(errno)));
|
||||
|
||||
open(sa, length);
|
||||
}
|
||||
@@ -51,8 +51,8 @@ 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);
|
||||
auto buffer = std::make_unique<char[]>(sizeof(sockaddr_un) + filename.size());
|
||||
sockaddr_un* sa = reinterpret_cast<sockaddr_un*>(buffer.get());
|
||||
|
||||
#ifdef __sun__
|
||||
sa->sun_family = AF_UNIX;
|
||||
@@ -74,9 +74,9 @@ SCgi::open(void* sa, unsigned int length) {
|
||||
try {
|
||||
if (!get_fd().set_nonblock() ||
|
||||
!get_fd().set_reuse_address(true) ||
|
||||
!get_fd().bind(*reinterpret_cast<rak::socket_address*>(sa), length) ||
|
||||
!get_fd().bind_sa(reinterpret_cast<sockaddr*>(sa), length) ||
|
||||
!get_fd().listen(max_tasks))
|
||||
throw torrent::resource_error("Could not prepare socket for listening: " + std::string(rak::error_number::current().c_str()));
|
||||
throw torrent::resource_error("Could not prepare socket for listening: " + std::string(std::strerror(errno)));
|
||||
|
||||
torrent::connection_manager()->inc_socket_count();
|
||||
|
||||
@@ -108,18 +108,24 @@ SCgi::deactivate() {
|
||||
|
||||
void
|
||||
SCgi::event_read() {
|
||||
rak::socket_address sa;
|
||||
utils::SocketFd fd;
|
||||
while (true) {
|
||||
int fd = torrent::fd_accept(get_fd().get_fd());
|
||||
|
||||
if (fd == -1) {
|
||||
if (errno == EAGAIN || errno == EWOULDBLOCK)
|
||||
break;
|
||||
|
||||
throw torrent::resource_error("Listener port accept() failed: " + std::string(std::strerror(errno)));
|
||||
}
|
||||
|
||||
while ((fd = get_fd().accept(&sa)).is_valid()) {
|
||||
SCgiTask* task = std::find_if(m_task, m_task + max_tasks, std::mem_fn(&SCgiTask::is_available));
|
||||
|
||||
if (task == m_task + max_tasks) {
|
||||
fd.close();
|
||||
torrent::fd_close(fd);
|
||||
continue;
|
||||
}
|
||||
|
||||
task->open(this, fd.get_fd());
|
||||
task->open(this, fd);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <torrent/exceptions.h>
|
||||
#include <torrent/poll.h>
|
||||
#include <torrent/torrent.h>
|
||||
#include <torrent/net/poll.h>
|
||||
#include <torrent/utils/log.h>
|
||||
#include <torrent/utils/thread.h>
|
||||
|
||||
|
||||
@@ -4,10 +4,27 @@
|
||||
|
||||
#include "parse_commands.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <torrent/exceptions.h>
|
||||
|
||||
namespace rpc {
|
||||
|
||||
std::vector<std::unique_ptr<const char>> XmlRpc::m_command_names;
|
||||
|
||||
const char*
|
||||
XmlRpc::store_command_name(const char* name) {
|
||||
if (::strnlen(name, 8192) == 8192)
|
||||
throw torrent::input_error("XMLRPC command name too long, limit is 8192 characters.");
|
||||
|
||||
for (const auto& itr : m_command_names) {
|
||||
if (::strcmp(itr.get(), name) == 0)
|
||||
return itr.get();
|
||||
}
|
||||
|
||||
m_command_names.push_back(std::unique_ptr<const char>(::strdup(name)));
|
||||
return m_command_names.back().get();
|
||||
}
|
||||
|
||||
#ifndef HAVE_XMLRPC_C
|
||||
#ifndef HAVE_XMLRPC_TINYXML2
|
||||
|
||||
|
||||
+4
-1
@@ -59,6 +59,10 @@ public:
|
||||
void set_size_limit(uint64_t size);
|
||||
|
||||
private:
|
||||
static const char* store_command_name(const char* name);
|
||||
|
||||
static std::vector<std::unique_ptr<const char>> m_command_names;
|
||||
|
||||
slot_download m_slotFindDownload;
|
||||
slot_file m_slotFindFile;
|
||||
slot_tracker m_slotFindTracker;
|
||||
@@ -73,7 +77,6 @@ private:
|
||||
// Only used by tinyxml2
|
||||
bool m_isValid;
|
||||
uint64_t m_sizeLimit{SCgiTask::max_content_size};
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
+44
-38
@@ -8,9 +8,9 @@
|
||||
#include <cctype>
|
||||
#include <string>
|
||||
#include <stdlib.h>
|
||||
#include <rak/string_manip.h>
|
||||
#include <torrent/object.h>
|
||||
#include <torrent/exceptions.h>
|
||||
#include <torrent/utils/string_manip.h>
|
||||
#include <xmlrpc-c/server.h>
|
||||
|
||||
#include "rpc_manager.h"
|
||||
@@ -219,7 +219,7 @@ xmlrpc_to_object(xmlrpc_env* env, xmlrpc_value* value, int call_type, rpc::targe
|
||||
if (env->fault_occurred)
|
||||
throw xmlrpc_error_c(env);
|
||||
|
||||
if (target->first == XmlRpc::call_download &&
|
||||
if (target != nullptr && target->first == XmlRpc::call_download &&
|
||||
(call_type == XmlRpc::call_file || call_type == XmlRpc::call_tracker)) {
|
||||
// If we have a download target and the call type requires
|
||||
// another contained type, then we try to use the next
|
||||
@@ -282,24 +282,20 @@ object_to_xmlrpc(xmlrpc_env* env, const torrent::Object& object) {
|
||||
// The versions that support I8 do implicit utf-8 validation.
|
||||
xmlrpc_value* result = xmlrpc_string_new(env, object.as_string().c_str());
|
||||
#else
|
||||
xmlrpc_value* result{};
|
||||
|
||||
// In older versions, xmlrpc-c doesn't validate the utf-8 encoding itself.
|
||||
xmlrpc_validate_utf8(env, object.as_string().c_str(), object.as_string().length());
|
||||
|
||||
xmlrpc_value* result = env->fault_occurred ? NULL : xmlrpc_string_new(env, object.as_string().c_str());
|
||||
if (!env->fault_occurred)
|
||||
result = xmlrpc_string_new(env, object.as_string().c_str());
|
||||
#endif
|
||||
|
||||
if (env->fault_occurred) {
|
||||
xmlrpc_env_clean(env);
|
||||
xmlrpc_env_init(env);
|
||||
|
||||
const std::string& str = object.as_string();
|
||||
char buffer[str.size() + 1];
|
||||
char* dst = buffer;
|
||||
for (char itr : str)
|
||||
*dst++ = ((itr < 0x20 && itr != '\r' && itr != '\n' && itr != '\t') || (itr & 0x80)) ? '?' : itr;
|
||||
*dst = 0;
|
||||
|
||||
result = xmlrpc_string_new(env, buffer);
|
||||
return xmlrpc_string_new(env, torrent::utils::string_with_escape_codes(object.as_string()).c_str());
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -361,10 +357,12 @@ object_to_xmlrpc(xmlrpc_env* env, const torrent::Object& object) {
|
||||
|
||||
xmlrpc_value*
|
||||
xmlrpc_call_command(xmlrpc_env* env, xmlrpc_value* args, void* voidServerInfo) {
|
||||
CommandMap::iterator itr = commands.find((const char*)voidServerInfo);
|
||||
auto server_info = static_cast<const char*>(voidServerInfo);
|
||||
|
||||
CommandMap::iterator itr = commands.find(server_info);
|
||||
|
||||
if (itr == commands.end()) {
|
||||
xmlrpc_env_set_fault(env, XMLRPC_PARSE_ERROR, ("Command \"" + std::string((const char*)voidServerInfo) + "\" does not exist.").c_str());
|
||||
xmlrpc_env_set_fault(env, XMLRPC_PARSE_ERROR, ("Command \"" + std::string(server_info) + "\" does not exist.").c_str());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -375,9 +373,7 @@ xmlrpc_call_command(xmlrpc_env* env, xmlrpc_value* args, void* voidServerInfo) {
|
||||
torrent::Object object;
|
||||
rpc::target_type target = rpc::make_target();
|
||||
|
||||
if (itr->second.m_flags & CommandMap::flag_no_target)
|
||||
xmlrpc_to_object(env, args, XmlRpc::call_generic, &target, &deleter).swap(object);
|
||||
else if (itr->second.m_flags & CommandMap::flag_file_target)
|
||||
if (itr->second.m_flags & CommandMap::flag_file_target)
|
||||
xmlrpc_to_object(env, args, XmlRpc::call_file, &target, &deleter).swap(object);
|
||||
else if (itr->second.m_flags & CommandMap::flag_tracker_target)
|
||||
xmlrpc_to_object(env, args, XmlRpc::call_tracker, &target, &deleter).swap(object);
|
||||
@@ -399,6 +395,11 @@ xmlrpc_call_command(xmlrpc_env* env, xmlrpc_value* args, void* voidServerInfo) {
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
XmlRpc::is_valid() const {
|
||||
return m_env != NULL;
|
||||
}
|
||||
|
||||
void
|
||||
XmlRpc::initialize() {
|
||||
#ifndef XMLRPC_HAVE_I8
|
||||
@@ -423,34 +424,42 @@ XmlRpc::cleanup() {
|
||||
|
||||
bool
|
||||
XmlRpc::process(const char* inBuffer, uint32_t length, slot_write slotWrite) {
|
||||
xmlrpc_env localEnv;
|
||||
xmlrpc_env_init(&localEnv);
|
||||
xmlrpc_env local_env;
|
||||
xmlrpc_env_init(&local_env);
|
||||
|
||||
xmlrpc_mem_block* memblock = xmlrpc_registry_process_call(&localEnv, (xmlrpc_registry*)m_registry, NULL, inBuffer, length);
|
||||
xmlrpc_mem_block* memblock = xmlrpc_registry_process_call(&local_env, (xmlrpc_registry*)m_registry, NULL, inBuffer, length);
|
||||
|
||||
if (localEnv.fault_occurred && localEnv.fault_code == XMLRPC_INTERNAL_ERROR)
|
||||
if (local_env.fault_occurred && local_env.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));
|
||||
|
||||
xmlrpc_mem_block_free(memblock);
|
||||
xmlrpc_env_clean(&localEnv);
|
||||
xmlrpc_env_clean(&local_env);
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
XmlRpc::insert_command(const char* name, const char* parm, const char* doc) {
|
||||
xmlrpc_env localEnv;
|
||||
xmlrpc_env_init(&localEnv);
|
||||
xmlrpc_env local_env;
|
||||
xmlrpc_env_init(&local_env);
|
||||
|
||||
xmlrpc_registry_add_method_w_doc(&localEnv, (xmlrpc_registry*)m_registry, NULL, name,
|
||||
&xmlrpc_call_command, const_cast<char*>(name), parm, doc);
|
||||
auto stored_name = store_command_name(name);
|
||||
|
||||
if (localEnv.fault_occurred)
|
||||
xmlrpc_registry_add_method_w_doc(&local_env,
|
||||
(xmlrpc_registry*)m_registry,
|
||||
nullptr,
|
||||
stored_name,
|
||||
&xmlrpc_call_command,
|
||||
(void*)stored_name,
|
||||
parm,
|
||||
doc);
|
||||
|
||||
if (local_env.fault_occurred)
|
||||
throw torrent::internal_error("Fault occured while inserting xmlrpc call.");
|
||||
|
||||
xmlrpc_env_clean(&localEnv);
|
||||
xmlrpc_env_clean(&local_env);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -458,8 +467,8 @@ XmlRpc::set_dialect(int dialect) {
|
||||
if (!is_valid())
|
||||
throw torrent::input_error("Cannot select XMLRPC dialect before it is initialized.");
|
||||
|
||||
xmlrpc_env localEnv;
|
||||
xmlrpc_env_init(&localEnv);
|
||||
xmlrpc_env local_env;
|
||||
xmlrpc_env_init(&local_env);
|
||||
|
||||
switch (dialect) {
|
||||
case dialect_generic:
|
||||
@@ -467,25 +476,25 @@ XmlRpc::set_dialect(int dialect) {
|
||||
|
||||
#ifdef XMLRPC_HAVE_I8
|
||||
case dialect_i8:
|
||||
xmlrpc_registry_set_dialect(&localEnv, (xmlrpc_registry*)m_registry, xmlrpc_dialect_i8);
|
||||
xmlrpc_registry_set_dialect(&local_env, (xmlrpc_registry*)m_registry, xmlrpc_dialect_i8);
|
||||
break;
|
||||
|
||||
case dialect_apache:
|
||||
xmlrpc_registry_set_dialect(&localEnv, (xmlrpc_registry*)m_registry, xmlrpc_dialect_apache);
|
||||
xmlrpc_registry_set_dialect(&local_env, (xmlrpc_registry*)m_registry, xmlrpc_dialect_apache);
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
xmlrpc_env_clean(&localEnv);
|
||||
xmlrpc_env_clean(&local_env);
|
||||
throw torrent::input_error("Unsupported XMLRPC dialect selected.");
|
||||
}
|
||||
|
||||
if (localEnv.fault_occurred) {
|
||||
xmlrpc_env_clean(&localEnv);
|
||||
if (local_env.fault_occurred) {
|
||||
xmlrpc_env_clean(&local_env);
|
||||
throw torrent::input_error("Unsupported XMLRPC dialect selected.");
|
||||
}
|
||||
|
||||
xmlrpc_env_clean(&localEnv);
|
||||
xmlrpc_env_clean(&local_env);
|
||||
m_dialect = dialect;
|
||||
}
|
||||
|
||||
@@ -502,9 +511,6 @@ XmlRpc::set_size_limit(uint64_t size) {
|
||||
xmlrpc_limit_set(XMLRPC_XML_SIZE_LIMIT_ID, size);
|
||||
}
|
||||
|
||||
bool
|
||||
XmlRpc::is_valid() const { return m_env != NULL; }
|
||||
|
||||
} // namespace rpc
|
||||
|
||||
#endif
|
||||
|
||||
@@ -204,12 +204,10 @@ execute_command(std::string method_name, const tinyxml2::XMLElement* params_elem
|
||||
const auto* child = params_element->FirstChildElement("param");
|
||||
|
||||
if (child != nullptr) {
|
||||
if (!(cmd_itr->second.m_flags & CommandMap::flag_no_target)) {
|
||||
std::function<void()> deleter = []() {};
|
||||
std::function<void()> deleter = []() {};
|
||||
|
||||
RpcManager::object_to_target(xml_value_to_object(child->FirstChildElement("value")), cmd_itr->second.m_flags, &target, &deleter);
|
||||
child = child->NextSiblingElement("param");
|
||||
}
|
||||
RpcManager::object_to_target(xml_value_to_object(child->FirstChildElement("value")), cmd_itr->second.m_flags, &target, &deleter);
|
||||
child = child->NextSiblingElement("param");
|
||||
|
||||
// Parse out any other params
|
||||
while (child != nullptr) {
|
||||
@@ -223,12 +221,10 @@ execute_command(std::string method_name, const tinyxml2::XMLElement* params_elem
|
||||
const auto* child = params_element->FirstChildElement("data")->FirstChildElement("value");
|
||||
|
||||
if (child != nullptr) {
|
||||
if (!(cmd_itr->second.m_flags & CommandMap::flag_no_target)) {
|
||||
std::function<void()> deleter = []() {};
|
||||
std::function<void()> deleter = []() {};
|
||||
|
||||
RpcManager::object_to_target(xml_value_to_object(child), cmd_itr->second.m_flags, &target, &deleter);
|
||||
child = child->NextSiblingElement("value");
|
||||
}
|
||||
RpcManager::object_to_target(xml_value_to_object(child), cmd_itr->second.m_flags, &target, &deleter);
|
||||
child = child->NextSiblingElement("value");
|
||||
|
||||
while (child != nullptr) {
|
||||
params.push_back(xml_value_to_object(child));
|
||||
|
||||
@@ -116,7 +116,7 @@ DownloadList::activate_display(Display displayType) {
|
||||
m_uiArray[m_state] = NULL;
|
||||
|
||||
break;
|
||||
|
||||
|
||||
case DISPLAY_DOWNLOAD_LIST:
|
||||
m_uiArray[DISPLAY_DOWNLOAD_LIST]->disable();
|
||||
|
||||
@@ -130,7 +130,7 @@ DownloadList::activate_display(Display displayType) {
|
||||
case DISPLAY_STRING_LIST:
|
||||
m_uiArray[m_state]->disable();
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -152,7 +152,7 @@ DownloadList::activate_display(Display displayType) {
|
||||
|
||||
download->activate(m_frame);
|
||||
download->slot_exit(std::bind(&DownloadList::activate_display, this, DISPLAY_DOWNLOAD_LIST));
|
||||
|
||||
|
||||
m_uiArray[DISPLAY_DOWNLOAD] = download;
|
||||
break;
|
||||
}
|
||||
@@ -273,7 +273,7 @@ DownloadList::receive_exit_input(Input type) {
|
||||
set_escdelay(1000);
|
||||
|
||||
input::TextInput* input = control->ui()->current_input();
|
||||
|
||||
|
||||
// We should check that this object is the one holding the input.
|
||||
if (input == NULL)
|
||||
return;
|
||||
|
||||
@@ -1,37 +1,3 @@
|
||||
// rTorrent - BitTorrent client
|
||||
// Copyright (C) 2005-2011, 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 <sundell.software@gmail.com>
|
||||
|
||||
|
||||
#ifndef RTORRENT_UI_DOWNLOAD_LIST_H
|
||||
#define RTORRENT_UI_DOWNLOAD_LIST_H
|
||||
|
||||
|
||||
+15
-8
@@ -83,13 +83,13 @@ Root::init(Control* c) {
|
||||
|
||||
m_downloadList = std::make_unique<DownloadList>();
|
||||
|
||||
display::Frame* rootFrame = m_control->display()->root_frame();
|
||||
auto root_frame = m_control->display()->root_frame();
|
||||
|
||||
rootFrame->initialize_row(5);
|
||||
rootFrame->frame(0)->initialize_window(m_windowTitle.get());
|
||||
rootFrame->frame(2)->initialize_window(m_windowHttpQueue.get());
|
||||
rootFrame->frame(3)->initialize_window(m_windowInput.get());
|
||||
rootFrame->frame(4)->initialize_window(m_windowStatusbar.get());
|
||||
root_frame->initialize_row(5);
|
||||
root_frame->frame(0)->initialize_window(m_windowTitle.get());
|
||||
root_frame->frame(2)->initialize_window(m_windowHttpQueue.get());
|
||||
root_frame->frame(3)->initialize_window(m_windowInput.get());
|
||||
root_frame->frame(4)->initialize_window(m_windowStatusbar.get());
|
||||
|
||||
m_windowTitle->set_active(true);
|
||||
m_windowStatusbar->set_active(true);
|
||||
@@ -97,7 +97,7 @@ Root::init(Control* c) {
|
||||
|
||||
setup_keys();
|
||||
|
||||
m_downloadList->activate(rootFrame->frame(1));
|
||||
m_downloadList->activate(root_frame->frame(1));
|
||||
}
|
||||
|
||||
void
|
||||
@@ -111,7 +111,14 @@ Root::cleanup() {
|
||||
m_control->display()->root_frame()->clear();
|
||||
m_control->input()->erase(&m_bindings);
|
||||
|
||||
m_control = NULL;
|
||||
// Destroy windows in reverse order of creation.
|
||||
m_windowStatusbar = nullptr;
|
||||
m_windowInput = nullptr;
|
||||
m_windowHttpQueue = nullptr;
|
||||
m_windowTitle = nullptr;
|
||||
m_downloadList = nullptr;
|
||||
|
||||
m_control = nullptr;
|
||||
}
|
||||
|
||||
const char*
|
||||
|
||||
+15
-121
@@ -1,37 +1,3 @@
|
||||
// libTorrent - BitTorrent library
|
||||
// Copyright (C) 2005-2011, 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 <sundell.software@gmail.com>
|
||||
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <errno.h>
|
||||
@@ -44,9 +10,9 @@
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <rak/socket_address.h>
|
||||
|
||||
#include <torrent/exceptions.h>
|
||||
#include <torrent/net/socket_address.h>
|
||||
|
||||
#include "socket_fd.h"
|
||||
|
||||
namespace utils {
|
||||
@@ -131,11 +97,11 @@ SocketFd::get_error() const {
|
||||
|
||||
bool
|
||||
SocketFd::open_stream() {
|
||||
m_fd = socket(rak::socket_address::pf_inet6, SOCK_STREAM, IPPROTO_TCP);
|
||||
m_fd = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
|
||||
|
||||
if (m_fd == -1) {
|
||||
m_ipv6_socket = false;
|
||||
return (m_fd = socket(rak::socket_address::pf_inet, SOCK_STREAM, IPPROTO_TCP)) != -1;
|
||||
return (m_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) != -1;
|
||||
}
|
||||
|
||||
m_ipv6_socket = true;
|
||||
@@ -146,10 +112,10 @@ SocketFd::open_stream() {
|
||||
|
||||
bool
|
||||
SocketFd::open_datagram() {
|
||||
m_fd = socket(rak::socket_address::pf_inet6, SOCK_DGRAM, 0);
|
||||
m_fd = socket(AF_INET6, SOCK_DGRAM, 0);
|
||||
if (m_fd == -1) {
|
||||
m_ipv6_socket = false;
|
||||
return (m_fd = socket(rak::socket_address::pf_inet, SOCK_DGRAM, 0)) != -1;
|
||||
return (m_fd = socket(AF_INET, SOCK_DGRAM, 0)) != -1;
|
||||
}
|
||||
m_ipv6_socket = true;
|
||||
|
||||
@@ -159,7 +125,7 @@ SocketFd::open_datagram() {
|
||||
|
||||
bool
|
||||
SocketFd::open_local() {
|
||||
return (m_fd = socket(rak::socket_address::pf_local, SOCK_STREAM, 0)) != -1;
|
||||
return (m_fd = socket(AF_LOCAL, SOCK_STREAM, 0)) != -1;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -169,55 +135,18 @@ SocketFd::close() {
|
||||
}
|
||||
|
||||
bool
|
||||
SocketFd::bind(const rak::socket_address& sa) {
|
||||
SocketFd::bind_sa(const sockaddr* sa, unsigned int length) {
|
||||
check_valid();
|
||||
|
||||
if (m_ipv6_socket && sa.family() == rak::socket_address::pf_inet) {
|
||||
rak::socket_address_inet6 sa_mapped = sa.sa_inet()->to_mapped_address();
|
||||
return !::bind(m_fd, sa_mapped.c_sockaddr(), sizeof(sa_mapped));
|
||||
if (m_ipv6_socket && sa->sa_family == AF_INET) {
|
||||
if (length < sizeof(sockaddr_in))
|
||||
throw torrent::input_error("SocketFd::bind_sa: invalid sockaddr length for AF_INET");
|
||||
|
||||
auto mapped_sa = torrent::sin6_to_v4mapped_in(reinterpret_cast<const sockaddr_in*>(sa));
|
||||
return !::bind(m_fd, reinterpret_cast<const sockaddr*>(mapped_sa.get()), sizeof(sockaddr_in6));
|
||||
}
|
||||
|
||||
return !::bind(m_fd, sa.c_sockaddr(), sa.length());
|
||||
}
|
||||
|
||||
bool
|
||||
SocketFd::bind(const rak::socket_address& sa, unsigned int length) {
|
||||
check_valid();
|
||||
|
||||
if (m_ipv6_socket && sa.family() == rak::socket_address::pf_inet) {
|
||||
rak::socket_address_inet6 sa_mapped = sa.sa_inet()->to_mapped_address();
|
||||
return !::bind(m_fd, sa_mapped.c_sockaddr(), sizeof(sa_mapped));
|
||||
}
|
||||
|
||||
return !::bind(m_fd, sa.c_sockaddr(), length);
|
||||
}
|
||||
|
||||
bool
|
||||
SocketFd::connect(const rak::socket_address& sa) {
|
||||
check_valid();
|
||||
|
||||
if (m_ipv6_socket && sa.family() == rak::socket_address::pf_inet) {
|
||||
rak::socket_address_inet6 sa_mapped = sa.sa_inet()->to_mapped_address();
|
||||
return !::connect(m_fd, sa_mapped.c_sockaddr(), sizeof(sa_mapped)) || errno == EINPROGRESS;
|
||||
}
|
||||
|
||||
return !::connect(m_fd, sa.c_sockaddr(), sa.length()) || errno == EINPROGRESS;
|
||||
}
|
||||
|
||||
bool
|
||||
SocketFd::getsockname(rak::socket_address *sa) {
|
||||
check_valid();
|
||||
|
||||
socklen_t len = sizeof(rak::socket_address);
|
||||
if (::getsockname(m_fd, sa->c_sockaddr(), &len)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_ipv6_socket && sa->family() == rak::socket_address::af_inet6) {
|
||||
*sa = sa->sa_inet6()->normalize_address();
|
||||
}
|
||||
|
||||
return true;
|
||||
return !::bind(m_fd, sa, length);
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -227,39 +156,4 @@ SocketFd::listen(int size) {
|
||||
return !::listen(m_fd, size);
|
||||
}
|
||||
|
||||
SocketFd
|
||||
SocketFd::accept(rak::socket_address* sa) {
|
||||
check_valid();
|
||||
socklen_t len = sizeof(rak::socket_address);
|
||||
|
||||
if (sa == NULL) {
|
||||
return SocketFd(::accept(m_fd, NULL, &len));
|
||||
}
|
||||
int fd = ::accept(m_fd, sa->c_sockaddr(), &len);
|
||||
if (fd != -1 && m_ipv6_socket && sa->family() == rak::socket_address::af_inet6) {
|
||||
*sa = sa->sa_inet6()->normalize_address();
|
||||
}
|
||||
return SocketFd(fd);
|
||||
}
|
||||
|
||||
// unsigned int
|
||||
// SocketFd::get_read_queue_size() const {
|
||||
// unsigned int v;
|
||||
|
||||
// if (!is_valid() || ioctl(m_fd, SIOCINQ, &v) < 0)
|
||||
// throw internal_error("SocketFd::get_read_queue_size() could not be performed");
|
||||
|
||||
// return v;
|
||||
// }
|
||||
|
||||
// unsigned int
|
||||
// SocketFd::get_write_queue_size() const {
|
||||
// unsigned int v;
|
||||
|
||||
// if (!is_valid() || ioctl(m_fd, SIOCOUTQ, &v) < 0)
|
||||
// throw internal_error("SocketFd::get_write_queue_size() could not be performed");
|
||||
|
||||
// return v;
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
+4
-47
@@ -1,45 +1,9 @@
|
||||
// libTorrent - BitTorrent library
|
||||
// Copyright (C) 2005-2011, 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 <sundell.software@gmail.com>
|
||||
|
||||
|
||||
#ifndef RTORRENT_UTILS_SOCKET_FD_H
|
||||
#define RTORRENT_UTILS_SOCKET_FD_H
|
||||
|
||||
#include <cinttypes>
|
||||
#include <unistd.h>
|
||||
|
||||
namespace rak {
|
||||
class socket_address;
|
||||
}
|
||||
#include <sys/socket.h>
|
||||
|
||||
namespace utils {
|
||||
|
||||
@@ -51,7 +15,7 @@ public:
|
||||
explicit SocketFd(int fd) : m_fd(fd) {}
|
||||
|
||||
bool is_valid() const { return m_fd >= 0; }
|
||||
|
||||
|
||||
int get_fd() const { return m_fd; }
|
||||
void set_fd(int fd) { m_fd = fd; }
|
||||
|
||||
@@ -75,16 +39,9 @@ public:
|
||||
|
||||
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 getsockname(rak::socket_address* sa);
|
||||
bool bind_sa(const sockaddr* sa, unsigned int length);
|
||||
|
||||
bool listen(int size);
|
||||
SocketFd accept(rak::socket_address* sa);
|
||||
|
||||
// unsigned int get_read_queue_size() const;
|
||||
// unsigned int get_write_queue_size() const;
|
||||
|
||||
private:
|
||||
inline void check_valid() const;
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
#include "test/helpers/mock_function.h"
|
||||
#include "torrent/exceptions.h"
|
||||
#include "torrent/poll.h"
|
||||
#include "torrent/net/poll.h"
|
||||
|
||||
const int test_thread::test_flag_pre_stop;
|
||||
const int test_thread::test_flag_long_timeout;
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
#include "test/rpc/test_parse_options.h"
|
||||
|
||||
#include <array>
|
||||
#include <torrent/connection_manager.h>
|
||||
#include <torrent/exceptions.h>
|
||||
#include <torrent/net/network_config.h>
|
||||
#include <torrent/utils/log.h>
|
||||
#include <torrent/utils/option_strings.h>
|
||||
|
||||
@@ -178,11 +178,11 @@ TestParseOptions::test_flag_libtorrent() {
|
||||
|
||||
void
|
||||
TestParseOptions::test_flags_libtorrent() {
|
||||
FLAGS_LT_ENCRYPTION_ASSERT("", torrent::ConnectionManager::encryption_none);
|
||||
FLAGS_LT_ENCRYPTION_ASSERT("none", torrent::ConnectionManager::encryption_none);
|
||||
FLAGS_LT_ENCRYPTION_ASSERT("require_rc4", torrent::ConnectionManager::encryption_require_RC4);
|
||||
FLAGS_LT_ENCRYPTION_ASSERT("require_RC4", torrent::ConnectionManager::encryption_require_RC4);
|
||||
FLAGS_LT_ENCRYPTION_ASSERT("require_RC4 | enable_retry", torrent::ConnectionManager::encryption_require_RC4 | torrent::ConnectionManager::encryption_enable_retry);
|
||||
FLAGS_LT_ENCRYPTION_ASSERT("", torrent::net::NetworkConfig::encryption_none);
|
||||
FLAGS_LT_ENCRYPTION_ASSERT("none", torrent::net::NetworkConfig::encryption_none);
|
||||
FLAGS_LT_ENCRYPTION_ASSERT("require_rc4", torrent::net::NetworkConfig::encryption_require_RC4);
|
||||
FLAGS_LT_ENCRYPTION_ASSERT("require_RC4", torrent::net::NetworkConfig::encryption_require_RC4);
|
||||
FLAGS_LT_ENCRYPTION_ASSERT("require_RC4 | enable_retry", torrent::net::NetworkConfig::encryption_require_RC4 | torrent::net::NetworkConfig::encryption_enable_retry);
|
||||
|
||||
FLAGS_LT_ENCRYPTION_ASSERT_ERROR("require_");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user