Compare commits

...

154 Commits

Author SHA1 Message Date
rakshasa e42ec54920 Bumped scgi listen queue to 100. 2014-05-09 18:05:30 +09:00
rakshasa 6a3234eaa7 Bumped to 0.9.4. 2014-05-09 17:54:04 +09:00
rakshasa d396c8e058 Changed rpc log types. 2014-04-25 19:55:47 +09:00
rakshasa 9548e08935 Removed debugging exceptions. 2014-04-25 17:24:42 +09:00
rakshasa ce125b1c54 Updated instrumentation plot. 2014-04-21 22:33:47 +09:00
rakshasa 82a68420f4 Fixed non-POSIX conformant included headers. 2014-04-18 22:27:13 +09:00
rakshasa d9f6f5aef4 Cleaned up CurlStack. 2014-04-18 22:16:24 +09:00
rakshasa 38f39bdb23 Added unordered curve to plot. 2014-04-10 22:32:07 +09:00
rakshasa 906683714b Updated instrumentation transfers plot script. 2014-04-10 22:00:46 +09:00
rakshasa a536fc09a0 Updated autoconf scripts. 2014-04-01 11:49:19 +02:00
rakshasa dea7c80996 Updated instrumenation transfer plot script. 2014-04-01 01:03:44 +02:00
rakshasa 3e3a84b3a0 Added 'network.listen.backlog{,.set}' commands. 2014-03-23 14:46:10 +01:00
rakshasa 866289b38a Updated email address. 2014-01-28 23:29:05 +09:00
rakshasa c9e894982f Merge branch 'master' of github.com:rakshasa/rtorrent 2013-11-28 01:53:41 +09:00
rakshasa 6b7adfd6bd Added scripts for gnuplot. 2013-11-28 01:53:20 +09:00
Jari Sundell fcd1fdb2fe Merge pull request #164 from artagnon/doc
Janitorial documentation work
2013-11-26 09:59:22 -08:00
Ramkumar Ramachandra a5d92cc940 rtorrent.1.xml: nuke deprecated stop_on_ratio
Signed-off-by: Ramkumar Ramachandra <artagnon@gmail.com>
2013-11-26 23:24:36 +05:30
Ramkumar Ramachandra 9fcef7fbd6 rtorrent.1.xml: nuke a bunch of deprecated on_* functions
Signed-off-by: Ramkumar Ramachandra <artagnon@gmail.com>
2013-11-26 23:24:36 +05:30
Ramkumar Ramachandra effdc5642d rtorrent.1.xml: document (max|min)_(uploads|downloads)
Only max_uploads was documented previously.

Signed-off-by: Ramkumar Ramachandra <artagnon@gmail.com>
2013-11-26 23:24:36 +05:30
Ramkumar Ramachandra fe5439f6a0 rtorrent.1.xml: document set_* functions for throttle
Signed-off-by: Ramkumar Ramachandra <artagnon@gmail.com>
2013-11-26 23:24:36 +05:30
Ramkumar Ramachandra 58fba68aff rtorrent.1.xml: add more DHT variables
Use TODO placeholders for the moment.

Signed-off-by: Ramkumar Ramachandra <artagnon@gmail.com>
2013-11-26 23:24:36 +05:30
Ramkumar Ramachandra 89dfa3a268 rtorrent.1.xml: clearly demarcate DHT settings
DHT stuff is clearly demarcated in the code, so let the manual also
follow along.

Signed-off-by: Ramkumar Ramachandra <artagnon@gmail.com>
2013-11-26 23:24:36 +05:30
Ramkumar Ramachandra 0d620e77db rtorrent.1.xml: remove schedule and schedule_remove
They were deprecated a long time ago.

Signed-off-by: Ramkumar Ramachandra <artagnon@gmail.com>
2013-11-26 23:24:36 +05:30
rakshasa 55b826d6cb Added brackets around configure parameters. 2013-11-22 23:20:50 +09:00
rakshasa 385b342deb Fixed typo in IPv6 option. 2013-11-22 23:03:00 +09:00
rakshasa 2e9baa1635 Added logging of some ui events. 2013-11-06 23:23:20 +09:00
rakshasa 67236d7757 Fixed an issue with input window. 2013-11-06 23:22:54 +09:00
rakshasa 66edb39863 Added 'log.open_gz_file' option. 2013-08-30 00:09:08 +09:00
rakshasa 00a349f68c Added slot_call_list. 2013-08-27 23:18:31 +09:00
rakshasa 370bae4b98 Removed all dependencies on sigc++. 2013-08-27 00:43:23 +09:00
rakshasa aa93404278 Added subdirs option to suppress warnings. 2013-08-26 23:47:31 +09:00
rakshasa aa2f784ae6 Converted sigc::signals to STL. 2013-08-26 23:15:33 +09:00
rakshasa 529eda5aab Converted sigc++ slots to std::tr1::function. 2013-08-24 00:14:25 +09:00
rakshasa 629ebcbd54 Removed deprecated signals for chunks passed/failed. 2013-08-22 03:48:54 +09:00
rakshasa d8d7861244 Removed old logging signals. 2013-08-22 03:33:48 +09:00
Jari Sundell bc4209e380 Merge pull request #128 from skydrome/automake-1.12
Fix warning on automake-1.12.4
2013-08-21 07:08:34 -07:00
rakshasa e36a0d43a4 Added missing <unistd.h> include. 2013-08-21 22:59:54 +09:00
rakshasa c3ad68156e Adding test output file gitignore. 2013-08-16 22:11:32 +09:00
rakshasa 6697806185 Use pid and ppid to XOR the seed value for random and rand48. 2013-08-16 16:29:59 +09:00
rakshasa 412a2f79b9 Removed obsolete logging facility. 2013-07-31 23:24:02 +09:00
rakshasa 0bf60679e4 Changed file permissions for log_stats.plot. 2013-07-31 06:17:13 +09:00
skydrome b113a02584 Fix warning on automake-1.12.4
warning: 'INCLUDES' is the old name for 'AM_CPPFLAGS' (or '*_CPPFLAGS')
2013-05-09 14:00:09 -04:00
rakshasa 7689059dbc Cleaned up thread code. 2013-04-03 21:16:11 +09:00
rakshasa 3b2a47a6d0 Use thread_base::interrupt for all SIGUSR1 interrupt signals and don't set a handler if it's not supported. 2013-03-03 05:00:31 +09:00
rakshasa e28692492b Fixed obsolete macro statements. 2013-02-26 17:44:42 +09:00
rakshasa 2c97841e92 Removed unused member variables. 2013-02-26 17:40:41 +09:00
rakshasa 5e6cb5da04 Merge branch 'master' of github.com:rakshasa/rtorrent 2012-10-24 14:35:59 +09:00
rakshasa cd029a67c5 Bumped version to 0.9.3. 2012-10-23 22:39:07 +09:00
Jari Sundell addc323ec8 Merge pull request #89 from ShanaTsunTsunLove/master
Typo in rtorrent.rc
2012-09-05 12:14:54 -07:00
Mateusz Kowalczyk 2217b14095 Typo in default rtorrent.rc comment 2012-08-28 12:35:10 +01:00
rakshasa 6a84facae0 Merge branch 'master' of github.com:rakshasa/rtorrent 2012-08-14 17:56:24 +09:00
rakshasa 66a116841a Removed old options. 2012-08-14 17:55:31 +09:00
rakshasa bacb6c0f72 Removed unused variables. 2012-07-23 23:54:21 +09:00
Jari Sundell 40fc8bbf80 Merge pull request #79 from nullren/master
Restore create_link and delete_link.
2012-07-10 23:21:25 -07:00
nullren 13f672ab4d using lt_log_print
replaced push_log_std with lt_log_print using LOG_TORRENT_WARN.
2012-06-27 00:19:09 -07:00
rakshasa 2967f9a224 Cleaned up old documents and scripts. 2012-06-27 15:43:32 +09:00
nullren eac7536f6a restored create_link
took away empty-body warnings from clang by restoring error messages
using push_log_std.
2012-06-23 20:21:47 -07:00
rakshasa 78f64a3e08 Use internal_error for priority queue exceptions. 2012-05-31 20:16:26 +09:00
rakshasa cf77a17399 Cleaned up command wrappers. 2012-05-22 17:19:19 +09:00
rakshasa 48733c84ec Added 'catch' command to allow safely calling commands that might fail with input_error. Note that double-brackets are required as the method needs to be called by the 'catch' command, not the parser.
catch = ((foo.bar,"bad input"))
2012-05-21 16:08:49 +09:00
rakshasa b020aa0197 Pass command target when using rpc::call_object with dict_key. 2012-05-21 16:08:18 +09:00
rakshasa 678049bc09 Fixed brackets in autoconf scripts. 2012-05-14 20:18:29 +09:00
rakshasa d0f6bb440a Fixed clang compilation issues. 2012-05-07 02:25:37 +09:00
rakshasa 8f5f383e3c For POSIX threads config script try none first to avoid adding flags when not needed. 2012-05-07 02:19:12 +09:00
rakshasa 2ca49e3485 Removed unused parse command function. 2012-05-07 01:53:39 +09:00
rakshasa 004862850d Allow command function lists for dynamically created functions. 2012-05-04 22:56:58 +09:00
rakshasa d2d09d97f8 Replace old command call functions with the new one taking torrent::Objects. 2012-05-04 22:33:26 +09:00
rakshasa fb75510c0f Allow functions and lists of functions to be passed to view.event_{added,removed}. 2012-05-04 21:31:12 +09:00
rakshasa 8d0f9b3300 Removed old hanshake log signal. 2012-05-04 05:17:11 +09:00
rakshasa 76ed90f514 Removed commented out settings for views. 2012-05-04 05:09:21 +09:00
rakshasa b79dea94b2 Wait for disowned http requests to finish to ensure stopped event gets sent to tracker on client shutdown. 2012-05-04 04:02:59 +09:00
rakshasa cf1c44ef5b Removed sigc++ dependency from ConnectionManager. 2012-05-04 04:02:59 +09:00
Jari Sundell 9df9183a0c Merge pull request #45 from SineSwiper/master
New rtorrent_fast_resume script
2012-04-27 00:41:12 -07:00
rakshasa f373b20c1b Removed old handshake logging functions. 2012-04-26 21:22:35 +09:00
rakshasa 22acdd87c3 Print backtrace for internal_error. 2012-04-25 22:23:15 +09:00
rakshasa cca1f21471 Added logging of segfault/bus signal and backtrace to LOG_CRITICAL. 2012-04-25 21:46:23 +09:00
rakshasa 4dd7582240 Bumped version to 0.9.2. 2012-04-20 16:03:55 +09:00
rakshasa 03c0a4e18c Allow tilde for 'log.open_file' path. 2012-04-18 17:32:12 +09:00
rakshasa c2b768cd6d Minor updates to choke group documentation. 2012-04-18 16:55:30 +09:00
rakshasa 63cf700593 Updated documentation for choke groups. 2012-04-16 17:06:53 +09:00
rakshasa 17201984a6 When 'throttle.max_*.global.*.set' commands are called they will automatically update the libtorrent settings, so it is no longer needed to set the throttle to force this update. 2012-04-16 00:40:47 +09:00
rakshasa 0a9e03df57 Added logging of options for created torrents. 2012-04-13 20:53:57 +09:00
rakshasa 90830dc765 Use right function argument for inotify test. 2012-04-12 18:44:42 +09:00
rakshasa d2dd143d2e Added 'throttle.update' to force 'throttle.max_{up,down}loads.global' setting to take effect. 2012-04-12 15:29:07 +09:00
rakshasa b71b44dbd6 Merge branch 'master' of github.com:rakshasa/rtorrent 2012-04-11 19:27:17 +09:00
Jari Sundell 83294e2198 Merge pull request #53 from taylorchu/master
Sigc++ header cleanup.
2012-04-11 03:26:45 -07:00
rakshasa 46862e23a9 Added ENODEV to "error_number.h". 2012-04-11 19:24:24 +09:00
taylorchu 077288407f fix build after removing sigc++ for download.cc 2012-04-10 15:42:45 -07:00
rakshasa 3fe1a734ac Differentiate scrape and normal requests in the tracker list. 2012-04-10 15:38:41 +09:00
rakshasa fdc6ee56de Removed sigc++ signal from ConnectionList. 2012-04-07 15:06:25 +09:00
rakshasa 36f8e5d349 Use TR1 slots instead of sigc++ for DownloadInfo events. 2012-04-07 03:37:37 +09:00
rakshasa 5bed4f01ad Added tracker related commands. 2012-04-04 02:49:05 +09:00
rakshasa 020de10f38 Return hex instead of binary for 'd.chunks_seen'. 2012-04-04 02:09:08 +09:00
rakshasa b28f2ea807 Added 'd.chunks_seen', which is limited to 'Download::peers_accounted()' number of peers for optimization reasons. 2012-04-01 02:22:18 +09:00
rakshasa dc817e24e4 Added inotify autoconf script. 2012-03-29 22:05:43 +09:00
rakshasa d1ff1fe77c Solaris compatibility fixes. 2012-03-26 23:18:10 +09:00
SineSwiper 47d36c0690 Add new version of rtorrent_fast_resume.pl
Add torrent_data script to peek at torrent contents
2012-03-25 16:54:02 -04:00
rakshasa bb75f06c6d Replaced std::placeholders with tr1::placholders. 2012-03-21 01:24:35 +09:00
rakshasa 04acc8a0af Converted std::bind calls to tr1::bind. 2012-03-21 01:22:25 +09:00
rakshasa f1cd0f4780 Added 'system.api_version', which will be incremented every time the API changes. (sans brainfarts) 2012-03-21 00:05:37 +09:00
rakshasa ece90f975b Initiate worker thread after initializing libtorrent to ensure logging is properly done. 2012-03-20 23:52:32 +09:00
rakshasa 2c72c31e1c Since logs are now thread-safe, allow all threads to push log messages. #43 2012-03-19 15:33:50 +09:00
rakshasa 64c66c81ae Bumped version to 0.9.1. 2012-03-16 18:01:19 +09:00
rakshasa 3ac22e4bc7 Bumped default max file size to 128Gb. 2012-03-12 21:30:43 +09:00
rakshasa 3d1b0b5971 Cleaned up old log code. 2012-03-12 20:55:29 +09:00
rakshasa 7e0d5956b5 Use new logging buffer for complete log view. 2012-03-12 20:41:19 +09:00
rakshasa a186932c03 Use log_buffer for console logs. 2012-03-12 04:09:18 +09:00
Jari Sundell 79e9990669 Merge pull request #38 from sochotnicky/master
Without this change build will fail when using gold linker
2012-03-08 06:20:45 -08:00
Stanislav Ochotnicky 31ba6341cf Fix build with gold linker
This is needed for certain optimization levels with llvm
2012-03-08 11:00:57 +01:00
rakshasa 6b71d75c33 Test against both libtinfo and libtinfow. 2012-02-27 19:54:53 +09:00
rakshasa 4ff2483f07 Fixed libtinfow detection. 2012-02-27 17:40:08 +09:00
rakshasa d8f41a28fa Added check to see if libinfow is required by ncursesw. 2012-02-27 01:22:47 +09:00
rakshasa 482a9ba09f Used AX_PTHREAD and AX_WITH_CURSES macros. 2012-02-24 16:22:17 +09:00
rakshasa 639af87e53 Use new logging API. 2012-02-21 15:37:50 +09:00
rakshasa 78abb7fed1 Reorder libraries for the unit test. 2012-02-18 02:21:17 +09:00
rakshasa 1b4d8f9626 Removed old thread test code. 2012-02-16 15:08:30 +09:00
rakshasa 4bcf7f4f5e Added 'ipv4_filter.dump'. 2012-02-15 13:14:57 +09:00
rakshasa 45d2d0bd49 Added type names to events. 2012-02-14 19:37:21 +09:00
rakshasa 7fe2fb1584 Properly initialize the main poll object. 2012-02-14 13:38:27 +09:00
rakshasa d4cbe5294d Cleaned up formating. 2012-02-14 00:55:19 +09:00
rakshasa d4a3ec0224 Add logging for IP addresses added. 2012-02-13 19:07:53 +09:00
rakshasa 4f601fda79 Use intermediate std::string to store the arguments to work around a possible bug. 2012-02-13 17:15:54 +09:00
rakshasa 8ed8ee9f81 Merge branch 'master' of github.com:rakshasa/rtorrent 2012-02-13 11:53:43 +09:00
Jari Sundell 2178422d90 Merge pull request #30 from extravagant/autoconf-2-68
Updated with AC_LANG_SOURCE directives
2012-02-12 18:45:59 -08:00
Extravagant f1852cd222 Updated with AC_LANG_SOURCE directives
Please see this informative thread on bug-autoconf:
http://www.mail-archive.com/bug-autoconf@gnu.org/msg03052.html
2012-02-12 22:23:40 +00:00
rakshasa 47125b9c38 Moved main thread object to libtorrent. 2012-02-12 21:58:16 +09:00
rakshasa 9ad22ab8ff Fixed log syntax. 2012-02-12 15:11:26 +09:00
rakshasa ba30dcd7cf Added names to threads. 2012-02-11 19:14:22 +09:00
rakshasa 4632053301 Added 'ip_tables.size_data'. 2012-02-11 18:52:46 +09:00
rakshasa 309711025b Cleaned up some code. 2012-02-11 16:17:13 +09:00
rakshasa be95b82d29 Potential fix to the issue of torrents remaining closed after final hashing. 2012-01-30 00:29:06 +09:00
rakshasa 74ea256036 Updated gitignore files. 2012-01-29 22:31:51 +09:00
Jari Sundell 222018e395 Removed obsolete 'system.hash.read_ahead', 'system.hash.interval' and 'system.hash.max_tries'. 2012-01-09 21:49:27 +09:00
Jari Sundell 18d51a60a1 Exit the autogen.sh script if one of the commands fail. 2012-01-05 13:30:47 +09:00
Jari Sundell e58f3975f1 Fixed compiler issues with clang. 2011-12-29 18:58:12 +09:00
Jari Sundell 002833f7b7 Fixed compile issues with C++03. 2011-12-27 17:26:36 +09:00
Jari Sundell 0626dcf783 C++11 fixes. 2011-12-27 16:45:19 +09:00
Jari Sundell f51b280cbf Merge branch 'master' into c++11 2011-12-27 15:50:01 +09:00
Jari Sundell 4c29d3b714 Removed extra semicolon. 2011-12-26 14:32:45 +09:00
Jari Sundell 28634f2c8c Added slot for poll creation. 2011-12-21 01:54:29 +09:00
Jari Sundell 007d83e904 Moved code from ThreadBase to torrent::thread_base. 2011-12-19 03:20:42 +09:00
Jari Sundell 5b7a2b5e95 Moved setting of PTHREAD related variables outside of the macro. 2011-12-19 03:19:54 +09:00
Jari Sundell 1c1993acef Cleaned up code. 2011-12-14 13:38:16 +09:00
Jari Sundell 1fc70a733d Merge branch 'master' into c++11
Conflicts:
	src/core/manager.cc
	src/thread_base.cc
2011-12-13 19:49:10 +09:00
Jari Sundell ee859a6137 Removed deprecated PollManager files. 2011-12-12 03:32:36 +09:00
Jari Sundell 4d1f5dce67 Fixed poll arguments. 2011-12-12 02:58:16 +09:00
Jari Sundell 6dfd2fe0cd Moved polling code to libtorrent. 2011-12-12 01:46:09 +09:00
Jari Sundell 89213982d5 Moving thread code to libtorrent. 2011-12-12 00:03:50 +09:00
Jari Sundell 2d8036e3a8 Use new API call. 2011-12-11 17:52:10 +09:00
Jari Sundell a2ad162fe3 Don't display scrape requests. 2011-12-11 15:41:05 +09:00
Jari Sundell 21944b941a Make sure we don't access freed memory if a download is erased during the erased event. 2011-12-11 12:21:24 +09:00
Jari Sundell 41d49b7c18 Merge branch 'master' into c++11
Conflicts:
	src/command_network.cc
2011-12-07 16:08:05 +09:00
Jari Sundell 9a9dcb88f7 Merge branch 'master' into c++11 2011-11-26 01:44:52 +09:00
Jari Sundell 58727fe7fd Fixed compiler issues with gcc-4.6 c++0x. 2011-11-18 17:28:50 +09:00
164 changed files with 3527 additions and 3122 deletions
+67 -7
View File
@@ -1,9 +1,69 @@
aclocal.m4
src/rtorrent
scripts/libtool.m4
scripts/ltoptions.m4
scripts/ltsugar.m4
scripts/ltversion.m4
scripts/lt~obsolete.m4
# Compiled source #
###################
*.o
*.lo
*.a
*.la
*.so
*.in
*.sub
*.pc
*.orig
*.rej
# Autoconf files #
##################
.deps
.libs
Makefile
aclocal.m4
autom4te.cache
compile
config.h
config.guess
config.status
confdefs.h
conftest.dir
configure
depcomp
install-sh
libtool
ltmain.sh
missing
stamp-h1
scripts/libtool.m4
scripts/lt*.m4
# Editor poo #
##############
.#*
\#*#
*~
# Packages #
############
# it's better to unpack these files and commit the raw source
# git has its own built in compression methods
*.gz
*.tar
*.zip
# Logs and databases #
######################
*.log
# OS generated files #
######################
.DS_Store?
ehthumbs.db
Icon?
Thumbs.db
TAGS
# rTorrent specific files
###########################
src/rtorrent
test/rtorrentTest
test-driver
test/rtorrentTest.trs
+6 -6
View File
@@ -6,7 +6,7 @@ echo aclocal...
exit 1
}
aclocal -I ./scripts -I . ${ACLOCAL_FLAGS}
aclocal -I ./scripts -I . ${ACLOCAL_FLAGS} || exit 1
echo autoheader...
(autoheader --version) < /dev/null > /dev/null 2>&1 || {
@@ -14,16 +14,16 @@ echo autoheader...
exit 1
}
autoheader
autoheader || exit 1
echo -n "libtoolize... "
if ( (glibtoolize --version) < /dev/null > /dev/null 2>&1 ); then
echo "using glibtoolize"
glibtoolize --automake --copy --force
glibtoolize --automake --copy --force || exit 1
elif ( (libtoolize --version) < /dev/null > /dev/null 2>&1 ) ; then
echo "using libtoolize"
libtoolize --automake --copy --force
libtoolize --automake --copy --force || exit 1
else
echo "libtoolize nor glibtoolize not found"
@@ -36,7 +36,7 @@ echo automake...
exit 1
}
automake --add-missing --copy --gnu
automake --add-missing --copy --gnu || exit 1
echo autoconf...
(autoconf --version) < /dev/null > /dev/null 2>&1 || {
@@ -44,7 +44,7 @@ echo autoconf...
exit 1
}
autoconf
autoconf || exit 1
echo ready to configure
+17 -11
View File
@@ -1,7 +1,9 @@
AC_INIT(rtorrent, 0.9.0, jaris@ifi.uio.no)
AC_INIT(rtorrent, 0.9.4, sundell.software@gmail.com)
AC_DEFINE(API_VERSION, 8, api version)
AM_INIT_AUTOMAKE
AM_CONFIG_HEADER(config.h)
AC_CONFIG_HEADERS(config.h)
AM_PATH_CPPUNIT(1.9.6)
AC_PROG_CXX
@@ -11,6 +13,8 @@ TORRENT_CHECK_CXXFLAGS()
TORRENT_ENABLE_DEBUG()
TORRENT_ENABLE_EXTRA_DEBUG()
TORRENT_ENABLE_WERROR()
TORRENT_ENABLE_TR1()
TORRENT_ENABLE_CXX11()
TORRENT_DISABLE_IPV6
@@ -23,23 +27,25 @@ TORRENT_ENABLE_ARCH
TORRENT_WITH_SYSROOT
TORRENT_WITHOUT_VARIABLE_FDSET()
TORRENT_WITHOUT_NCURSESW()
TORRENT_WITHOUT_STATVFS()
TORRENT_WITHOUT_STATFS()
ACX_PTHREAD(CXXFLAGS="$CXXFLAGS $PTHREAD_CFLAGS";
LIBS="$PTHREAD_LIBS $LIBS"
)
AX_PTHREAD([], AC_MSG_ERROR([requires pthread]))
AX_WITH_CURSES()
PKG_CHECK_MODULES(sigc, sigc++-2.0,
CXXFLAGS="$CXXFLAGS $sigc_CFLAGS";
LIBS="$LIBS $sigc_LIBS")
if test "x$ax_cv_ncursesw" != xyes && test "x$ax_cv_ncurses" != xyes; then
AC_MSG_ERROR([requires either NcursesW or Ncurses library])
fi
PKG_CHECK_MODULES(libcurl, libcurl >= 7.15.4,
CFLAGS="$CFLAGS $PTHREAD_CFLAGS $CURSES_CFLAGS"
CXXFLAGS="$CXXFLAGS $PTHREAD_CFLAGS $CURSES_CFLAGS"
LIBS="$PTHREAD_LIBS $CURSES_LIB $LIBS"
PKG_CHECK_MODULES([libcurl], libcurl >= 7.15.4,
CXXFLAGS="$CXXFLAGS $libcurl_CFLAGS";
LIBS="$LIBS $libcurl_LIBS")
PKG_CHECK_MODULES(libtorrent, libtorrent >= 0.13.0,
PKG_CHECK_MODULES([libtorrent], libtorrent >= 0.13.4,
CXXFLAGS="$CXXFLAGS $libtorrent_CFLAGS";
LIBS="$LIBS $libtorrent_LIBS")
-5
View File
@@ -1,7 +1,2 @@
#man_MANS = rtorrent.1
EXTRA_DIST= \
faq.xml \
rtorrent.1 \
rtorrent.1.xml \
rtorrent.rc
Regular → Executable
View File
Regular → Executable
View File
+28
View File
@@ -0,0 +1,28 @@
# Choke Groups
## Settings
choke_group.insert = "leech_fast"
Create a new group named "leech_fast", accessible by the string or
index / reverse index according to order of insertion. E.g. '-1'
refers to the last inserted choke group, while 0 refers to the first.
All commands that applies to a group requires the first argument to be
the index, reverse index or the group name.
choke_group.tracker.mode.set = -1,"aggressive"
Set the tracker mode for torrents in this group.
choke_group.up.heuristics.set = -1,"upload_leech_experimental"
choke_group.down.heuristics.set = -1,"download_leech"
Set the heuristics used when deciding on which peers to choke and
unchoke. Use "strings.choke_heuristics{,.upload,.download}" to get a
list of the available heuristics.
choke_group.up.max.set = -1,250
choke_group.down.max.set = -1,500
Set the max total number of unchoked peers for all torrents in this choke group.
+64
View File
@@ -0,0 +1,64 @@
# IP filtering
## Introduction
## Make a new ip table
ip_tables.insert_table = <table_name>
Create a new empty table with the name table\_name, with the default
value returned being $0$.
There is currently no use of the generic ip tables commands.
## Add a new address block
ip_tables.add_address = <table_name>, 10.0.0.0/8, <value>
Set <value\> for all addresses in the address block, overwriting prior
values.
## Add a new address block
ip_tables.load = <table_name>, ~/foo.txt, <value>
Set <value\> for all addresses in the file foo.txt separated by
newline, similar to add\_address.
## Get value for address
ip_tables.get = <table_name>, 10.10.10.10
Returns the value set for an address, or the address block it belongs
to. The default is $0$.
## Size of data structures
ip_tables.size_data = <table_name>
Returns the size in bytes of all data structures for this table,
excluding the root class object itself. Note that the in-memory table is
dynamically consolidated, as such memory use will always be based on
actual fragmentation.
The table is a b-tree with 1024 nodes per branch.
## IPv4 filtering table
ipv4_filter.add_address = 10.0.0.0/8, unwanted
ipv4_filter.add_address = 11.0.0.0/8, preferred
ipv4_filter.load = ~/filters.txt, unwanted
ipv4_filter.get = 10.10.10.10
ipv4_filter.size_data =
The main ip filter, currently supporting unwanted (do not allow
connections) and preferred (currently used only in private code).
## Constants
strings.ip_filter =
=>
{ "unwanted", PeerInfo::flag_unwanted },
{ "preferred", PeerInfo::flag_preferred },
Constants used by ipv4\_filter values.
+85
View File
@@ -0,0 +1,85 @@
\section{IP filtering}
\subsection{Introduction}
\subsection{Make a new ip table}
\begin{verbatim}
ip_tables.insert_table = <table_name>
\end{verbatim}
Create a new empty table with the name 'table\_name', with the default
value returned being $0$.
There is currently no use of the generic ip tables commands.
\subsection{Add a new address block}
\begin{verbatim}
ip_tables.add_address = <table_name>, 10.0.0.0/8, <value>
\end{verbatim}
Set <value> for all addresses in the address block, overwriting prior
values.
\subsection{Add a new address block}
\begin{verbatim}
ip_tables.load = <table_name>, ~/foo.txt, <value>
\end{verbatim}
Set <value> for all addresses in the file 'foo.txt' separated by
newline, similar to 'add\_address'.
\subsection{Get value for address}
\begin{verbatim}
ip_tables.get = <table_name>, 10.10.10.10
\end{verbatim}
Returns the value set for an address, or the address block it belongs
to. The default is $0$.
\subsection{Size of data structures}
\begin{verbatim}
ip_tables.size_data = <table_name>
\end{verbatim}
Returns the size in bytes of all data structures for this table,
excluding the root class object itself. Note that the in-memory table
is dynamically consolidated, as such memory use will always be based
on actual fragmentation.
The table is a b-tree with 1024 nodes per branch.
\subsection{IPv4 filtering table}
\begin{verbatim}
ipv4_filter.add_address = 10.0.0.0/8, unwanted
ipv4_filter.add_address = 11.0.0.0/8, preferred
ipv4_filter.load = ~/filters.txt, unwanted
ipv4_filter.get = 10.10.10.10
ipv4_filter.size_data =
\end{verbatim}
The main ip filter, currently supporting 'unwanted' (do not allow
connections) and 'preferred' (currently used only in private code).
\subsection{Constants}
\begin{verbatim}
strings.ip_filter =
=>
{ "unwanted", PeerInfo::flag_unwanted },
{ "preferred", PeerInfo::flag_preferred },
\end{verbatim}
Constants used by ipv4_filter values.
+50
View File
@@ -0,0 +1,50 @@
# Logging
## Opening log files
# log.open_file = "log name", "file path"
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.
## 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"
Each log handle can be added to multiple different logging events.
## Logging events
"critical"
"error"
"warn"
"notice"
"info"
"debug"
The above events receive logging events from all the sub-groups
displayed below, and each event also reciving events from the event
above in importance.
Thus some high-volume sub-group events such as “tracker\_debug” are not
part of “debug” and every “warn” event will receive events from “error”,
“critical”.
"connection_*"
"dht_*"
"peer_*"
"rpc_*"
"storage_*"
"thread_*"
"tracker_*"
"torrent_*"
All sub-groups have events from “critical” to “debug” defined.
+47 -63
View File
@@ -507,29 +507,6 @@ Enable/disable peer exchange for torrents that aren't marked private. Disabled b
</para></listitem>
</varlistentry>
<varlistentry>
<term>schedule = <replaceable>id</replaceable>,<replaceable>start</replaceable>,<replaceable>interval</replaceable>,<replaceable>command</replaceable></term>
<listitem><para>
Call <emphasis>command</emphasis> every <emphasis>interval</emphasis>
seconds, starting from <emphasis>start</emphasis>. An
<emphasis>interval</emphasis> of zero calls the task once, while a
<emphasis>start</emphasis> of zero calls it immediately. Currently
<emphasis>command</emphasis> is forwarded to the option handler.
<emphasis>start</emphasis> and <emphasis>interval</emphasis> may
optionally use a time format, <emphasis>dd:hh:mm:ss</emphasis>. F.ex to
start a task every day at <emphasis>18:00</emphasis>, use
<emphasis>18:00:00,24:00:00</emphasis>.
</para></listitem>
</varlistentry>
<varlistentry>
<term>schedule_remove = <replaceable>id</replaceable></term>
<listitem><para>
Delete <emphasis>id</emphasis> from the scheduler.
</para></listitem>
</varlistentry>
<varlistentry>
<term>start_tied =</term>
<listitem><para>
@@ -580,40 +557,6 @@ torrent::input_error exception on bad input.
</para></listitem>
</varlistentry>
<varlistentry>
<term>stop_on_ratio = <replaceable>min_ratio</replaceable></term>
<term>stop_on_ratio = <replaceable>min_ratio</replaceable>,<replaceable>min_upload</replaceable></term>
<term>stop_on_ratio = <replaceable>min_ratio</replaceable>,<replaceable>min_upload</replaceable>,<replaceable>max_ratio</replaceable></term>
<listitem><para>
Stop torrents when they reach the given upload ratio
<emphasis>min_ratio</emphasis> in percent. If the optional
<emphasis>min_upload</emphasis> is given, require a total
upload amount of this many bytes as well. If the optional
<emphasis>max_ratio</emphasis> is given, stop the torrent
when reaching this ratio regardless of the total upload
amount. Exclude certain torrent by pressing
<emphasis>Shift+I</emphasis> in the downlist list.
Use with the <emphasis>schedule</emphasis> option.
</para></listitem>
</varlistentry>
<varlistentry>
<term>on_insert = <replaceable>id</replaceable>,<replaceable>command</replaceable></term>
<term>on_erase = <replaceable>id</replaceable>,<replaceable>command</replaceable></term>
<term>on_open = <replaceable>id</replaceable>,<replaceable>command</replaceable></term>
<term>on_close = <replaceable>id</replaceable>,<replaceable>command</replaceable></term>
<term>on_start = <replaceable>id</replaceable>,<replaceable>command</replaceable></term>
<term>on_stop = <replaceable>id</replaceable>,<replaceable>command</replaceable></term>
<term>on_hash_queued = <replaceable>id</replaceable>,<replaceable>command</replaceable></term>
<term>on_hash_removed = <replaceable>id</replaceable>,<replaceable>command</replaceable></term>
<term>on_hash_done = <replaceable>id</replaceable>,<replaceable>command</replaceable></term>
<term>on_finished = <replaceable>id</replaceable>,<replaceable>command</replaceable></term>
<listitem><para>
Call a command on a download when its state changes. Only a subset of
commands are available.
</para></listitem>
</varlistentry>
</variablelist>
</refsect1>
@@ -629,6 +572,8 @@ commands are available.
<varlistentry>
<term>upload_rate = <replaceable>KB</replaceable></term>
<term>download_rate = <replaceable>KB</replaceable></term>
<term>set_upload_rate = <replaceable>TODO</replaceable></term>
<term>set_download_rate = <replaceable>TODO</replaceable></term>
<listitem><para>
Set the maximum global uploand and download rates.
</para></listitem>
@@ -653,14 +598,19 @@ Set the minimum nad maximum number of peers to allow while seeding, or
<varlistentry>
<term>max_uploads = <replaceable>value</replaceable></term>
<term>max_downloads = <replaceable>value</replaceable></term>
<term>min_uploads = <replaceable>value</replaceable></term>
<term>min_downloads = <replaceable>value</replaceable></term>
<listitem><para>
Set the maximum number of simultaneous uploads per download.
Set the maximum/minimum number of simultaneous uploads/downloads per download/upload.
</para></listitem>
</varlistentry>
<varlistentry>
<term>max_uploads_div = <replaceable>value</replaceable></term>
<term>max_downloads_div = <replaceable>value</replaceable></term>
<term>set_max_uploads_div = <replaceable>value</replaceable></term>
<term>set_max_downloads_div = <replaceable>value</replaceable></term>
<listitem><para>
Change the divider used to calculate the max upload and download slots
to use when the throttle is changed. Disable by
@@ -671,6 +621,8 @@ setting <emphasis>0</emphasis>.
<varlistentry>
<term>max_uploads_global = <replaceable>value</replaceable></term>
<term>max_downloads_global = <replaceable>value</replaceable></term>
<term>set_max_uploads_global = <replaceable>value</replaceable></term>
<term>set_max_downloads_global = <replaceable>value</replaceable></term>
<listitem><para>
Max upload and download slots allowed. Disable by
setting <emphasis>0</emphasis>.
@@ -746,6 +698,27 @@ not allow connections to UDP trackers.
</para></listitem>
</varlistentry>
<varlistentry>
<term>http_capath = <replaceable>path</replaceable></term>
<term>http_cacert = <replaceable>filename</replaceable></term>
<listitem><para>
Set the certificates to use in http requests. See Curl's
CURLOPT_CAPATH and CURLOPT_CAINFO options for further information.
</para></listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1>
<title>DHT-RELATED SETTINGS</title>
<para>
Settings related to DHT
</para>
<variablelist>
<varlistentry>
<term>dht = <replaceable>disabled|off|auto|on</replaceable></term>
<listitem><para>
@@ -779,11 +752,23 @@ The port is optional, with port 6881 being used by default.
</varlistentry>
<varlistentry>
<term>http_capath = <replaceable>path</replaceable></term>
<term>http_cacert = <replaceable>filename</replaceable></term>
<term>dht_statistics = <replaceable>TODO</replaceable></term>
<listitem><para>
Set the certificates to use in http requests. See Curl's
CURLOPT_CAPATH and CURLOPT_CAINFO options for further information.
TODO
</para></listitem>
</varlistentry>
<varlistentry>
<term>set_dht_port = <replaceable>TODO</replaceable></term>
<listitem><para>
TODO
</para></listitem>
</varlistentry>
<varlistentry>
<term>set_dht_throttle = <replaceable>TODO</replaceable></term>
<listitem><para>
TODO
</para></listitem>
</varlistentry>
@@ -791,7 +776,6 @@ CURLOPT_CAPATH and CURLOPT_CAINFO options for further information.
</refsect1>
<refsect1>
<title>USER-INTERFACE SETTINGS</title>
<para>
+49
View File
@@ -0,0 +1,49 @@
#/bin/bash
gnuplot << EOF
set terminal png size 1024,768 enhanced
set xdata time
set timefmt "%s"
set format x "%H:%M"
set y2tics
set autoscale xfix
set key autotitle columnhead
# set datafile missing '0'
set format y "%.0f"
set format y2 "%.0f"
set yrange [0:]
set y2range [0:]
set output "output_$1_transfer_requests.png"
plot \
"instrumentation_transfers.log.$1" using 1:2 title 'delegated' with lines lw 4 axis x1y1,\
"instrumentation_transfers.log.$1" using 1:3 title 'downloading' with lines lw 4 axis x1y1,\
"instrumentation_transfers.log.$1" using 1:4 title 'finished' with lines lw 4 axis x1y1,\
"instrumentation_transfers.log.$1" using 1:5 title 'skipped' with lines lw 2 axis x1y2,\
"instrumentation_transfers.log.$1" using 1:6 title 'unknown' with lines lw 2 axis x1y2,\
"instrumentation_transfers.log.$1" using 1:7 title 'unordered' with lines lw 2 axis x1y2,\
"instrumentation_transfers.log.$1" using 1:19 title 'unaccounted' with lines lw 2 axis x1y2
set output "output_$1_transfer_queues.png"
plot \
"instrumentation_transfers.log.$1" using 1:8 title 'queue added' with lines lw 2 axis x1y1,\
"instrumentation_transfers.log.$1" using 1:9 title 'queue moved' with lines lw 2 axis x1y1,\
"instrumentation_transfers.log.$1" using 1:10 title 'queue removed' with lines lw 2 axis x1y1,\
"instrumentation_transfers.log.$1" using 1:11 title 'queue total' with lines lw 4 axis x1y2,\
"instrumentation_transfers.log.$1" using 1:12 title 'unordered added' with lines lw 2 axis x1y1,\
"instrumentation_transfers.log.$1" using 1:13 title 'unordered moved' with lines lw 2 axis x1y1,\
"instrumentation_transfers.log.$1" using 1:14 title 'unordered removed' with lines lw 2 axis x1y1,\
"instrumentation_transfers.log.$1" using 1:15 title 'unordered total' with lines lw 4 axis x1y2,\
"instrumentation_transfers.log.$1" using 1:16 title 'stalled added' with lines lw 2 axis x1y1,\
"instrumentation_transfers.log.$1" using 1:17 title 'stalled moved' with lines lw 2 axis x1y1,\
"instrumentation_transfers.log.$1" using 1:18 title 'stalled removed' with lines lw 2 axis x1y1,\
"instrumentation_transfers.log.$1" using 1:19 title 'stalled total' with lines lw 4 axis x1y2,\
"instrumentation_transfers.log.$1" using 1:20 title 'choked added' with lines lw 2 axis x1y1,\
"instrumentation_transfers.log.$1" using 1:21 title 'choked moved' with lines lw 2 axis x1y1,\
"instrumentation_transfers.log.$1" using 1:22 title 'choked removed' with lines lw 2 axis x1y1,\
"instrumentation_transfers.log.$1" using 1:23 title 'choked total' with lines lw 4 axis x1y2
EOF
+30
View File
@@ -0,0 +1,30 @@
#/bin/bash
gnuplot << EOF
set terminal png size 1024,768 enhanced
set xdata time
set timefmt "%s"
set format x "%H:%M"
set y2tics
set autoscale xfix
set key autotitle columnhead
set format y "%.0f"
set format y2 "%.0f"
set output "output_$1_incore_sync.png"
plot \
"instrumentation_mincore.log.$1" using 1:6 title 'success' smooth sbezier with lines lw 4 axis x1y1,\
"instrumentation_mincore.log.$1" using 1:7 title 'failed' smooth sbezier with lines lw 4 axis x1y1,\
"instrumentation_mincore.log.$1" using 1:8 title 'not synced' smooth sbezier with lines lw 4 axis x1y2,\
"instrumentation_mincore.log.$1" using 1:9 title 'not deallocated' smooth sbezier with lines lw 4 axis x1y2
set format y "%.0g"
set output "output_$1_incore_alloc.png"
plot \
"instrumentation_mincore.log.$1" using 1:12 title 'allocations' smooth sbezier with lines lw 2 axis x1y1,\
"instrumentation_mincore.log.$1" using 1:13 title 'deallocations' smooth sbezier with lines lw 4 axis x1y1,\
"instrumentation_mincore.log.$1" using 1:10 title 'alloc failed' smooth sbezier with lines lw 2 axis x1y2
EOF
+1 -19
View File
@@ -52,7 +52,7 @@
# fixed that causes lack of diskspace not to be properly reported.
#check_hash = no
# Set whetever the client should try to connect to UDP trackers.
# Set whether the client should try to connect to UDP trackers.
#use_udp_trackers = yes
# Alternative calls to bind and ip that should handle dynamic ip's.
@@ -82,21 +82,3 @@
# Enable peer exchange (for torrents not marked private)
#
# peer_exchange = yes
#
# Do not modify the following parameters unless you know what you're doing.
#
# Hash read-ahead controls how many MB to request the kernel to read
# ahead. If the value is too low the disk may not be fully utilized,
# while if too high the kernel might not be able to keep the read
# pages in memory thus end up trashing.
#hash_read_ahead = 10
# Interval between attempts to check the hash, in milliseconds.
#hash_interval = 100
# Number of attempts to check the hash while using the mincore status,
# before forcing. Overworked systems might need lower values to get a
# decent hash checking rate.
#hash_max_tries = 10
+128
View File
@@ -0,0 +1,128 @@
#!/usr/bin/perl
# Perl script to add rTorrent fast resume data to torrent files.
#
# Usage:
# rtorrent_fast_resume.pl [base-directory] < plain.torrent > with_fast_resume.torrent
# -OR-
# rtorrent_fast_resume.pl [base-directory] plain.torrent [with_fast_resume.torrent]
use strict;
use warnings;
use Convert::Bencode_XS qw(bencode bdecode);
use File::Spec; # core module
use POSIX; # core module
$/ = undef;
$| = 1;
# Process ARGV
my $d = $ARGV[0];
if ($d and not -d $d) {
if (-f $d and -s $d and not $ARGV[2]) { # missing directory, but has file
$ARGV[2] = $ARGV[1];
$ARGV[1] = $ARGV[0];
$d = '';
}
else { die "$d is not a directory\n"; }
}
$d ||= ".";
$d .= "/" unless $d =~ m#/$#;
my ($in, $out, $msg);
my ($in_file, $out_file) = ('', '');
if ($ARGV[1]) {
$in_file = $ARGV[1];
open($in, ($ARGV[2] ? '<' : '+<'), $in_file) || die "Cannot open $in_file for input!\n";
unless ($ARGV[2]) {
$out = $in;
$out_file = $in_file;
}
}
else { $in = *STDIN; }
if ($ARGV[2]) {
$out_file = $ARGV[2];
open($out, '>', $out_file) || die "Cannot open $out_file for output!\n";
$msg = *STDOUT;
}
elsif (!$ARGV[1]) { $out = *STDOUT; }
$msg //= *STDERR;
print {$msg} "Total input torrent size: ".sprintf('%.2f', (-s $in_file) / 1024)." KB\n" if $in_file;
print {$msg} "Decoding ".($in_file || 'torrent from standard input')."...";
my $t = bdecode(scalar <$in>);
die "No info key.\n" unless ref $t eq "HASH" and exists $t->{info};
my $psize = $t->{info}{"piece length"} or die "No piece length key.\n";
print {$msg} "done\n\n";
my @files;
my $tsize = 0;
if (exists $t->{info}{files}) {
print {$msg} "Multi file torrent: $t->{info}{name}\n";
for (@{$t->{info}{files}}) {
push @files, join "/", $t->{info}{name},@{$_->{path}};
$tsize += $_->{length};
}
}
else {
print {$msg} "Single file torrent: $t->{info}{name}\n";
@files = ($t->{info}{name});
$tsize = $t->{info}{length};
}
my $chunks = int(($tsize + $psize - 1) / $psize);
print {$msg} "Total size: ".sprintf('%.2f', $tsize / 1024**2)." MB; $chunks chunks; ", scalar @files, " files.\n\n";
die "Inconsistent piece information!\n" if $chunks*20 != length $t->{info}{pieces};
print {$msg} "Adding fast resume information...";
# flags => 1+16+
my $pmod = 0;
$t->{libtorrent_resume}{bitfield} = $chunks;
foreach my $f (0..$#files) {
die "$d$files[$f] not found.\n" unless -e "$d$files[$f]";
my $mtime = (stat "$d$files[$f]")[9];
# Compute number of chunks per file
my $fsize = $t->{info}{files}[$f]{length};
my $fchunks = ($pmod ? 1 : 0);
if ($pmod >= $fsize) { ($fsize, $pmod ) = (0, $pmod-$fsize); }
else { ($pmod, $fsize) = (0, $fsize-$pmod); }
$fchunks += ceil($fsize / $psize);
$pmod ||= $psize - ($fsize % $psize);
$t->{libtorrent_resume}{files}[$f] = {
priority => 0, # Don't download; we already have the file, so don't clobber it!
mtime => $mtime,
completed => $fchunks,
};
};
$t->{libtorrent_resume}{'uncertain_pieces.timestamp'} = time;
# Some extra information to re-enforce the fact that this is a finished torrent
$d .= $t->{info}{name};
$t->{rtorrent} = {
state => 1, # started
state_changed => time,
state_counter => 1,
chunks_wanted => 0,
chunks_done => $chunks,
complete => 1,
hashing => 0, # Not hashing
directory => File::Spec->file_name_is_absolute($d) ? $d : File::Spec->rel2abs($d),
((tied_to_file => File::Spec->file_name_is_absolute($out_file) ? $out_file : File::Spec->rel2abs($out_file)) x!! $out_file),
'timestamp.finished' => 0,
'timestamp.started' => time,
};
print {$msg} "done\n";
print {$msg} "Encoding ".($out_file || 'torrent from standard output')."...";
seek($out, 0, 0); # just in case files are the same
print {$out} bencode($t);
close($in);
close($out);
print {$msg} "done\n";
exit;
+23
View File
@@ -0,0 +1,23 @@
#!/usr/bin/perl
# Perl script to read torrent data
use strict;
use warnings;
use Convert::Bencode_XS qw(bdecode);
use Data::Dumper;
$/ = undef;
$| = 1;
my $in;
my $in_file = $ARGV[0];
if ($in_file) { open($in, '<', $in_file) || die "Cannot open $in_file for input!\n"; }
else { $in = *STDIN; }
print "Total input torrent size: ".sprintf('%.2f', (-s $in_file) / 1024)." KB\n" if $in_file;
print "Decoding ".($in_file || 'torrent from standard input')."...";
my $t = bdecode(scalar <$in>);
print "done\n\n";
print Data::Dumper->new([$t], ['*Torrent'])->Indent(1)->Useqq(1)->Quotekeys(0)->Sortkeys(1)->Dump;
+1
View File
@@ -51,6 +51,7 @@ public:
static const int e_deadlk = EDEADLK;
static const int e_noent = ENOENT;
static const int e_nodev = ENODEV;
static const int e_nomem = ENOMEM;
static const int e_notdir = ENOTDIR;
static const int e_isdir = EISDIR;
+51
View File
@@ -627,6 +627,57 @@ make_mem_fun(Object* o, Ret (Object::*f)(Arg1, Arg2, Arg3)) {
return mem_fun3<Object, Ret, Arg1, Arg2, Arg3>(o, f);
}
template <typename Container>
inline void
slot_list_call(const Container& slot_list) {
if (slot_list.empty())
return;
typename Container::const_iterator first = slot_list.begin();
typename Container::const_iterator next = slot_list.begin();
while (++next != slot_list.end()) {
(*first)();
first = next;
}
(*first)();
}
template <typename Container, typename Arg1>
inline void
slot_list_call(const Container& slot_list, Arg1 arg1) {
if (slot_list.empty())
return;
typename Container::const_iterator first = slot_list.begin();
typename Container::const_iterator next = slot_list.begin();
while (++next != slot_list.end()) {
(*first)(arg1);
first = next;
}
(*first)(arg1);
}
template <typename Container, typename Arg1, typename Arg2, typename Arg3, typename Arg4>
inline void
slot_list_call(const Container& slot_list, Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4) {
if (slot_list.empty())
return;
typename Container::const_iterator first = slot_list.begin();
typename Container::const_iterator next = slot_list.begin();
while (++next != slot_list.end()) {
(*first)(arg1, arg2, arg3, arg4);
first = next;
}
(*first)(arg1, arg2, arg3, arg4);
}
}
#endif
+12 -10
View File
@@ -53,6 +53,8 @@
#include <memory>
#include <functional>
#include <tr1/functional>
#include <tr1/memory>
namespace rak {
@@ -96,13 +98,13 @@ public:
bool is_valid() const { return m_base.get() != NULL; }
void set(base_type* base) { m_base = std::auto_ptr<base_type>(base); }
void set(base_type* base) { m_base = std::tr1::shared_ptr<base_type>(base); }
base_type* release() { return m_base.release(); }
Result operator () () { return (*m_base)(); }
private:
std::auto_ptr<base_type> m_base;
std::tr1::shared_ptr<base_type> m_base;
};
template <typename Result, typename Arg1>
@@ -113,13 +115,13 @@ public:
bool is_valid() const { return m_base.get() != NULL; }
void set(base_type* base) { m_base = std::auto_ptr<base_type>(base); }
void set(base_type* base) { m_base = std::tr1::shared_ptr<base_type>(base); }
base_type* release() { return m_base.release(); }
Result operator () (Arg1 arg1) { return (*m_base)(arg1); }
private:
std::auto_ptr<base_type> m_base;
std::tr1::shared_ptr<base_type> m_base;
};
template <typename Result, typename Arg1, typename Arg2>
@@ -130,13 +132,13 @@ public:
bool is_valid() const { return m_base.get() != NULL; }
void set(base_type* base) { m_base = std::auto_ptr<base_type>(base); }
void set(base_type* base) { m_base = std::tr1::shared_ptr<base_type>(base); }
base_type* release() { return m_base.release(); }
Result operator () (Arg1 arg1, Arg2 arg2) { return (*m_base)(arg1, arg2); }
private:
std::auto_ptr<base_type> m_base;
std::tr1::shared_ptr<base_type> m_base;
};
template <typename Result, typename Arg2>
@@ -147,7 +149,7 @@ public:
bool is_valid() const { return m_base.get() != NULL; }
void set(base_type* base) { m_base = std::auto_ptr<base_type>(base); }
void set(base_type* base) { m_base = std::tr1::shared_ptr<base_type>(base); }
base_type* release() { return m_base.release(); }
Result operator () (Arg2 arg2) { return (*m_base)(arg2); }
@@ -156,7 +158,7 @@ public:
Result operator () (Discard discard, Arg2 arg2) { return (*m_base)(arg2); }
private:
std::auto_ptr<base_type> m_base;
std::tr1::shared_ptr<base_type> m_base;
};
template <typename Result, typename Arg1, typename Arg2, typename Arg3>
@@ -167,13 +169,13 @@ public:
bool is_valid() const { return m_base.get() != NULL; }
void set(base_type* base) { m_base = std::auto_ptr<base_type>(base); }
void set(base_type* base) { m_base = std::tr1::shared_ptr<base_type>(base); }
base_type* release() { return m_base.release(); }
Result operator () (Arg1 arg1, Arg2 arg2, Arg3 arg3) { return (*m_base)(arg1, arg2, arg3); }
private:
std::auto_ptr<base_type> m_base;
std::tr1::shared_ptr<base_type> m_base;
};
template <typename Result>
+24 -23
View File
@@ -37,44 +37,45 @@
#ifndef RAK_PRIORITY_QUEUE_DEFAULT_H
#define RAK_PRIORITY_QUEUE_DEFAULT_H
#include <stdexcept>
#include <tr1/functional>
#include <rak/allocators.h>
#include <rak/functional.h>
#include <rak/functional_fun.h>
#include <rak/priority_queue.h>
#include <rak/timer.h>
#include "torrent/exceptions.h"
namespace rak {
class priority_item {
public:
typedef std::tr1::function<void (void)> slot_void;
priority_item() {}
~priority_item() {
if (is_queued())
throw std::logic_error("priority_item::~priority_item() called on a queued item.");
throw torrent::internal_error("priority_item::~priority_item() called on a queued item.");
m_time = timer();
m_slot.set(NULL);
m_slot = slot_void();
}
bool is_valid() const { return m_slot.is_valid(); }
bool is_queued() const { return m_time != timer(); }
bool is_valid() const { return (bool)m_slot; }
bool is_queued() const { return m_time != timer(); }
void call() { m_slot(); }
void set_slot(function0<void>::base_type* s) { m_slot.set(s); }
const timer& time() const { return m_time; }
void clear_time() { m_time = timer(); }
void set_time(const timer& t) { m_time = t; }
slot_void& slot() { return m_slot; }
bool compare(const timer& t) const { return m_time > t; }
const timer& time() const { return m_time; }
void clear_time() { m_time = timer(); }
void set_time(const timer& t) { m_time = t; }
bool compare(const timer& t) const { return m_time > t; }
private:
priority_item(const priority_item&);
void operator = (const priority_item&);
timer m_time;
function0<void> m_slot;
slot_void m_slot;
};
struct priority_compare {
@@ -94,23 +95,23 @@ priority_queue_perform(priority_queue_default* queue, timer t) {
queue->pop();
v->clear_time();
v->call();
v->slot()();
}
}
inline void
priority_queue_insert(priority_queue_default* queue, priority_item* item, timer t) {
if (t == timer())
throw std::logic_error("priority_queue_insert(...) received a bad timer.");
throw torrent::internal_error("priority_queue_insert(...) received a bad timer.");
if (!item->is_valid())
throw std::logic_error("priority_queue_insert(...) called on an invalid item.");
throw torrent::internal_error("priority_queue_insert(...) called on an invalid item.");
if (item->is_queued())
throw std::logic_error("priority_queue_insert(...) called on an already queued item.");
throw torrent::internal_error("priority_queue_insert(...) called on an already queued item.");
if (queue->find(item) != queue->end())
throw std::logic_error("priority_queue_insert(...) item found in queue.");
throw torrent::internal_error("priority_queue_insert(...) item found in queue.");
item->set_time(t);
queue->push(item);
@@ -124,16 +125,16 @@ priority_queue_erase(priority_queue_default* queue, priority_item* item) {
// Check is_valid() after is_queued() so that it is safe to call
// erase on untouched instances.
if (!item->is_valid())
throw std::logic_error("priority_queue_erase(...) called on an invalid item.");
throw torrent::internal_error("priority_queue_erase(...) called on an invalid item.");
// Clear time before erasing to force it to the top.
item->clear_time();
if (!queue->erase(item))
throw std::logic_error("priority_queue_erase(...) could not find item in queue.");
throw torrent::internal_error("priority_queue_erase(...) could not find item in queue.");
if (queue->find(item) != queue->end())
throw std::logic_error("priority_queue_erase(...) item still in queue.");
throw torrent::internal_error("priority_queue_erase(...) item still in queue.");
}
}
+3
View File
@@ -49,6 +49,9 @@ class timer {
timer(int64_t usec = 0) : m_time(usec) {}
timer(timeval tv) : m_time((int64_t)(uint32_t)tv.tv_sec * 1000000 + (int64_t)(uint32_t)tv.tv_usec % 1000000) {}
bool is_zero() const { return m_time == 0; }
bool is_not_zero() const { return m_time != 0; }
int32_t seconds() const { return m_time / 1000000; }
int32_t seconds_ceiling() const { return (m_time + 1000000 - 1) / 1000000; }
int64_t usec() const { return m_time; }
-227
View File
@@ -1,227 +0,0 @@
dnl PGSGL: When updating, comment out port-specific part below;
dnl see the comment below with the word "PostgreSQL".
dnl
dnl Available from the GNU Autoconf Macro Archive at:
dnl http://www.gnu.org/software/ac-archive/htmldoc/acx_pthread.html
dnl
AC_DEFUN([ACX_PTHREAD], [
AC_REQUIRE([AC_CANONICAL_HOST])
AC_LANG_SAVE
AC_LANG_C
acx_pthread_ok=no
# We used to check for pthread.h first, but this fails if pthread.h
# requires special compiler flags (e.g. on True64 or Sequent).
# It gets checked for in the link test anyway.
# First of all, check if the user has set any of the PTHREAD_LIBS,
# etcetera environment variables, and if threads linking works using
# them:
if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then
save_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
save_LIBS="$LIBS"
LIBS="$PTHREAD_LIBS $LIBS"
AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS])
AC_TRY_LINK_FUNC(pthread_join, acx_pthread_ok=yes)
AC_MSG_RESULT($acx_pthread_ok)
if test x"$acx_pthread_ok" = xno; then
PTHREAD_LIBS=""
PTHREAD_CFLAGS=""
fi
LIBS="$save_LIBS"
CFLAGS="$save_CFLAGS"
fi
# We must check for the threads library under a number of different
# names; the ordering is very important because some systems
# (e.g. DEC) have both -lpthread and -lpthreads, where one of the
# libraries is broken (non-POSIX).
# Create a list of thread flags to try. Items starting with a "-" are
# C compiler flags, and other items are library names, except for "none"
# which indicates that we try without any flags at all, and "pthread-config"
# which is a program returning the flags for the Pth emulation library.
acx_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config pthreadGC2"
# The ordering *is* (sometimes) important. Some notes on the
# individual items follow:
# pthreads: AIX (must check this before -lpthread)
# none: in case threads are in libc; should be tried before -Kthread and
# other compiler flags to prevent continual compiler warnings
# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads)
# -pthreads: Solaris/gcc
# -mthreads: Mingw32/gcc, Lynx/gcc
# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
# doesn't hurt to check since this sometimes defines pthreads too;
# also defines -D_REENTRANT)
# pthread: Linux, etcetera
# --thread-safe: KAI C++
# pthread-config: use pthread-config program (for GNU Pth library)
case "${host_cpu}-${host_os}" in
*solaris*)
# On Solaris (at least, for some versions), libc contains stubbed
# (non-functional) versions of the pthreads routines, so link-based
# tests will erroneously succeed. (We need to link with -pthread or
# -lpthread.) (The stubs are missing pthread_cleanup_push, or rather
# a function called by this macro, so we could check for that, but
# who knows whether they'll stub that too in a future libc.) So,
# we'll just look for -pthreads and -lpthread first:
acx_pthread_flags="-pthread -pthreads pthread -mt $acx_pthread_flags"
;;
esac
if test x"$acx_pthread_ok" = xno; then
for flag in $acx_pthread_flags; do
tryPTHREAD_CFLAGS=""
tryPTHREAD_LIBS=""
case $flag in
none)
AC_MSG_CHECKING([whether pthreads work without any flags])
;;
-*)
AC_MSG_CHECKING([whether pthreads work with $flag])
tryPTHREAD_CFLAGS="$flag"
;;
pthread-config)
# skip this if we already have flags defined, for PostgreSQL
if test x"$PTHREAD_CFLAGS" != x -o x"$PTHREAD_LIBS" != x; then continue; fi
AC_CHECK_PROG(acx_pthread_config, pthread-config, yes, no)
if test x"$acx_pthread_config" = xno; then continue; fi
tryPTHREAD_CFLAGS="`pthread-config --cflags`"
tryPTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`"
;;
*)
AC_MSG_CHECKING([for the pthreads library -l$flag])
tryPTHREAD_LIBS="-l$flag"
;;
esac
save_LIBS="$LIBS"
save_CFLAGS="$CFLAGS"
LIBS="$tryPTHREAD_LIBS $PTHREAD_LIBS $LIBS"
CFLAGS="$CFLAGS $PTHREAD_CFLAGS $tryPTHREAD_CFLAGS"
# Check for various functions. We must include pthread.h,
# since some functions may be macros. (On the Sequent, we
# need a special flag -Kthread to make this header compile.)
# We check for pthread_join because it is in -lpthread on IRIX
# while pthread_create is in libc. We check for pthread_attr_init
# due to DEC craziness with -lpthreads. We check for
# pthread_cleanup_push because it is one of the few pthread
# functions on Solaris that doesn't have a non-functional libc stub.
# We try pthread_create on general principles.
AC_TRY_LINK([#include <pthread.h>],
[pthread_t th; pthread_join(th, 0);
pthread_attr_init(0); pthread_cleanup_push(0, 0);
pthread_create(0,0,0,0); pthread_cleanup_pop(0); ],
[acx_pthread_ok=yes], [acx_pthread_ok=no])
if test "x$acx_pthread_ok" = xyes; then
# Don't use options that are ignored by the compiler.
# We find them by checking stderror.
cat >conftest.$ac_ext <<_ACEOF
int
main (int argc, char **argv)
{
(void) argc;
(void) argv;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if test "`(eval $ac_link 2>&1 1>&5)`" = ""; then
# we continue with more flags because Linux needs -lpthread
# for libpq builds on PostgreSQL. The test above only
# tests for building binaries, not shared libraries.
PTHREAD_LIBS=" $tryPTHREAD_LIBS $PTHREAD_LIBS"
PTHREAD_CFLAGS="$PTHREAD_CFLAGS $tryPTHREAD_CFLAGS"
else acx_pthread_ok=no
fi
fi
LIBS="$save_LIBS"
CFLAGS="$save_CFLAGS"
AC_MSG_RESULT($acx_pthread_ok)
done
fi
# Various other checks:
if test "x$acx_pthread_ok" = xyes; then
save_LIBS="$LIBS"
LIBS="$PTHREAD_LIBS $LIBS"
save_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
# Detect AIX lossage: threads are created detached by default
# and the JOINABLE attribute has a nonstandard name (UNDETACHED).
AC_MSG_CHECKING([for joinable pthread attribute])
AC_TRY_LINK([#include <pthread.h>],
[int attr=PTHREAD_CREATE_JOINABLE;],
ok=PTHREAD_CREATE_JOINABLE, ok=unknown)
if test x"$ok" = xunknown; then
AC_TRY_LINK([#include <pthread.h>],
[int attr=PTHREAD_CREATE_UNDETACHED;],
ok=PTHREAD_CREATE_UNDETACHED, ok=unknown)
fi
if test x"$ok" != xPTHREAD_CREATE_JOINABLE; then
AC_DEFINE(PTHREAD_CREATE_JOINABLE, $ok,
[Define to the necessary symbol if this constant
uses a non-standard name on your system.])
fi
AC_MSG_RESULT(${ok})
if test x"$ok" = xunknown; then
AC_MSG_WARN([we do not know how to create joinable pthreads])
fi
AC_MSG_CHECKING([if more special flags are required for pthreads])
flag=no
# We always add these in PostgreSQL
# case "${host_cpu}-${host_os}" in
# *-aix* | *-freebsd* | *-darwin*) flag="-D_THREAD_SAFE";;
# *solaris* | *-osf* | *-hpux*) flag="-D_REENTRANT";;
# esac
AC_MSG_RESULT(${flag})
if test "x$flag" != xno; then
PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS"
fi
LIBS="$save_LIBS"
CFLAGS="$save_CFLAGS"
# Supporting cc_r would require a special CC in all places that
# use libpq, and that is ugly, so we don't do it. Users can still
# define their compiler as cc_r to do thread builds of everything.
# More AIX lossage: must compile with cc_r
AC_CHECK_PROG(PTHREAD_CC, cc_r, cc_r, ${CC})
else
PTHREAD_CC="$CC"
fi
AC_SUBST(PTHREAD_LIBS)
AC_SUBST(PTHREAD_CFLAGS)
AC_SUBST(PTHREAD_CC)
# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
if test x"$acx_pthread_ok" = xyes; then
ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1])
:
else
acx_pthread_ok=no
$2
fi
AC_LANG_RESTORE
])dnl ACX_PTHREAD
+14 -14
View File
@@ -3,10 +3,10 @@
AC_DEFUN([CC_ATTRIBUTE_CONSTRUCTOR], [
AC_CACHE_CHECK([if compiler supports __attribute__((constructor))],
[cc_cv_attribute_constructor],
[AC_COMPILE_IFELSE([
[AC_COMPILE_IFELSE([AC_LANG_SOURCE([
void ctor() __attribute__((constructor));
void ctor() { };
],
])],
[cc_cv_attribute_constructor=yes],
[cc_cv_attribute_constructor=no])
])
@@ -23,9 +23,9 @@ AC_DEFUN([CC_ATTRIBUTE_CONSTRUCTOR], [
AC_DEFUN([CC_ATTRIBUTE_FORMAT], [
AC_CACHE_CHECK([if compiler supports __attribute__((format(printf, n, n)))],
[cc_cv_attribute_format],
[AC_COMPILE_IFELSE([
[AC_COMPILE_IFELSE([AC_LANG_SOURCE([
void __attribute__((format(printf, 1, 2))) printflike(const char *fmt, ...) { }
],
])],
[cc_cv_attribute_format=yes],
[cc_cv_attribute_format=no])
])
@@ -42,9 +42,9 @@ AC_DEFUN([CC_ATTRIBUTE_FORMAT], [
AC_DEFUN([CC_ATTRIBUTE_INTERNAL], [
AC_CACHE_CHECK([if compiler supports __attribute__((visibility("internal")))],
[cc_cv_attribute_internal],
[AC_COMPILE_IFELSE([
[AC_COMPILE_IFELSE([AC_LANG_SOURCE([
void __attribute__((visibility("internal"))) internal_function() { }
],
])],
[cc_cv_attribute_internal=yes],
[cc_cv_attribute_internal=no])
])
@@ -66,9 +66,9 @@ AC_DEFUN([CC_ATTRIBUTE_VISIBILITY], [
AC_CACHE_CHECK([if compiler supports __attribute__((visibility("default")))],
[cc_cv_attribute_visibility],
[AC_COMPILE_IFELSE([
[AC_COMPILE_IFELSE([AC_LANG_SOURCE([
void __attribute__((visibility("default"))) visibility_function() { }
],
])],
[cc_cv_attribute_visibility=yes],
[cc_cv_attribute_visibility=no])
])
@@ -90,10 +90,10 @@ AC_DEFUN([CC_ATTRIBUTE_VISIBILITY], [
AC_DEFUN([CC_ATTRIBUTE_NONNULL], [
AC_CACHE_CHECK([if compiler supports __attribute__((nonnull()))],
[cc_cv_attribute_nonnull],
[AC_COMPILE_IFELSE([
[AC_COMPILE_IFELSE([AC_LANG_SOURCE([
void some_function(void *foo, void *bar) __attribute__((nonnull()));
void some_function(void *foo, void *bar) { }
],
])],
[cc_cv_attribute_nonnull=yes],
[cc_cv_attribute_nonnull=no])
])
@@ -110,9 +110,9 @@ AC_DEFUN([CC_ATTRIBUTE_NONNULL], [
AC_DEFUN([CC_ATTRIBUTE_UNUSED], [
AC_CACHE_CHECK([if compiler supports __attribute__((unused))],
[cc_cv_attribute_unused],
[AC_COMPILE_IFELSE([
[AC_COMPILE_IFELSE([AC_LANG_SOURCE([
void some_function(void *foo, __attribute__((unused)) void *bar);
],
])],
[cc_cv_attribute_unused=yes],
[cc_cv_attribute_unused=no])
])
@@ -129,13 +129,13 @@ AC_DEFUN([CC_ATTRIBUTE_UNUSED], [
AC_DEFUN([CC_FUNC_EXPECT], [
AC_CACHE_CHECK([if compiler has __builtin_expect function],
[cc_cv_func_expect],
[AC_COMPILE_IFELSE([
[AC_COMPILE_IFELSE([AC_LANG_SOURCE([
int some_function()
{
int a = 3;
return (int)__builtin_expect(a, 3);
}
],
])],
[cc_cv_func_expect=yes],
[cc_cv_func_expect=no])
])
+309
View File
@@ -0,0 +1,309 @@
# ===========================================================================
# http://www.gnu.org/software/autoconf-archive/ax_pthread.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
#
# DESCRIPTION
#
# This macro figures out how to build C programs using POSIX threads. It
# sets the PTHREAD_LIBS output variable to the threads library and linker
# flags, and the PTHREAD_CFLAGS output variable to any special C compiler
# flags that are needed. (The user can also force certain compiler
# flags/libs to be tested by setting these environment variables.)
#
# Also sets PTHREAD_CC to any special C compiler that is needed for
# multi-threaded programs (defaults to the value of CC otherwise). (This
# is necessary on AIX to use the special cc_r compiler alias.)
#
# NOTE: You are assumed to not only compile your program with these flags,
# but also link it with them as well. e.g. you should link with
# $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS
#
# If you are only building threads programs, you may wish to use these
# variables in your default LIBS, CFLAGS, and CC:
#
# LIBS="$PTHREAD_LIBS $LIBS"
# CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
# CC="$PTHREAD_CC"
#
# In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute constant
# has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to that name
# (e.g. PTHREAD_CREATE_UNDETACHED on AIX).
#
# Also HAVE_PTHREAD_PRIO_INHERIT is defined if pthread is found and the
# PTHREAD_PRIO_INHERIT symbol is defined when compiling with
# PTHREAD_CFLAGS.
#
# ACTION-IF-FOUND is a list of shell commands to run if a threads library
# is found, and ACTION-IF-NOT-FOUND is a list of commands to run it if it
# is not found. If ACTION-IF-FOUND is not specified, the default action
# will define HAVE_PTHREAD.
#
# Please let the authors know if this macro fails on any platform, or if
# you have any other suggestions or comments. This macro was based on work
# by SGJ on autoconf scripts for FFTW (http://www.fftw.org/) (with help
# from M. Frigo), as well as ac_pthread and hb_pthread macros posted by
# Alejandro Forero Cuervo to the autoconf macro repository. We are also
# grateful for the helpful feedback of numerous users.
#
# Updated for Autoconf 2.68 by Daniel Richard G.
#
# LICENSE
#
# Copyright (c) 2008 Steven G. Johnson <stevenj@alum.mit.edu>
# Copyright (c) 2011 Daniel Richard G. <skunk@iSKUNK.ORG>
#
# 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 3 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, see <http://www.gnu.org/licenses/>.
#
# As a special exception, the respective Autoconf Macro's copyright owner
# gives unlimited permission to copy, distribute and modify the configure
# scripts that are the output of Autoconf when processing the Macro. You
# need not follow the terms of the GNU General Public License when using
# or distributing such scripts, even though portions of the text of the
# Macro appear in them. The GNU General Public License (GPL) does govern
# all other use of the material that constitutes the Autoconf Macro.
#
# This special exception to the GPL applies to versions of the Autoconf
# Macro released by the Autoconf Archive. When you make and distribute a
# modified version of the Autoconf Macro, you may extend this special
# exception to the GPL to apply to your modified version as well.
#serial 17
AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD])
AC_DEFUN([AX_PTHREAD], [
AC_REQUIRE([AC_CANONICAL_HOST])
AC_LANG_PUSH([C])
ax_pthread_ok=no
# We used to check for pthread.h first, but this fails if pthread.h
# requires special compiler flags (e.g. on True64 or Sequent).
# It gets checked for in the link test anyway.
# First of all, check if the user has set any of the PTHREAD_LIBS,
# etcetera environment variables, and if threads linking works using
# them:
if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then
save_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
save_LIBS="$LIBS"
LIBS="$PTHREAD_LIBS $LIBS"
AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS])
AC_TRY_LINK_FUNC(pthread_join, ax_pthread_ok=yes)
AC_MSG_RESULT($ax_pthread_ok)
if test x"$ax_pthread_ok" = xno; then
PTHREAD_LIBS=""
PTHREAD_CFLAGS=""
fi
LIBS="$save_LIBS"
CFLAGS="$save_CFLAGS"
fi
# We must check for the threads library under a number of different
# names; the ordering is very important because some systems
# (e.g. DEC) have both -lpthread and -lpthreads, where one of the
# libraries is broken (non-POSIX).
# Create a list of thread flags to try. Items starting with a "-" are
# C compiler flags, and other items are library names, except for "none"
# which indicates that we try without any flags at all, and "pthread-config"
# which is a program returning the flags for the Pth emulation library.
ax_pthread_flags="none pthreads -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config"
# The ordering *is* (sometimes) important. Some notes on the
# individual items follow:
# pthreads: AIX (must check this before -lpthread)
# none: in case threads are in libc; should be tried before -Kthread and
# other compiler flags to prevent continual compiler warnings
# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads)
# -pthreads: Solaris/gcc
# -mthreads: Mingw32/gcc, Lynx/gcc
# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
# doesn't hurt to check since this sometimes defines pthreads too;
# also defines -D_REENTRANT)
# ... -mt is also the pthreads flag for HP/aCC
# pthread: Linux, etcetera
# --thread-safe: KAI C++
# pthread-config: use pthread-config program (for GNU Pth library)
case "${host_cpu}-${host_os}" in
*solaris*)
# On Solaris (at least, for some versions), libc contains stubbed
# (non-functional) versions of the pthreads routines, so link-based
# tests will erroneously succeed. (We need to link with -pthreads/-mt/
# -lpthread.) (The stubs are missing pthread_cleanup_push, or rather
# a function called by this macro, so we could check for that, but
# who knows whether they'll stub that too in a future libc.) So,
# we'll just look for -pthreads and -lpthread first:
ax_pthread_flags="-pthreads pthread -mt -pthread $ax_pthread_flags"
;;
*-darwin*)
ax_pthread_flags="none -pthread $ax_pthread_flags"
;;
esac
if test x"$ax_pthread_ok" = xno; then
for flag in $ax_pthread_flags; do
case $flag in
none)
AC_MSG_CHECKING([whether pthreads work without any flags])
;;
-*)
AC_MSG_CHECKING([whether pthreads work with $flag])
PTHREAD_CFLAGS="$flag"
;;
pthread-config)
AC_CHECK_PROG(ax_pthread_config, pthread-config, yes, no)
if test x"$ax_pthread_config" = xno; then continue; fi
PTHREAD_CFLAGS="`pthread-config --cflags`"
PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`"
;;
*)
AC_MSG_CHECKING([for the pthreads library -l$flag])
PTHREAD_LIBS="-l$flag"
;;
esac
save_LIBS="$LIBS"
save_CFLAGS="$CFLAGS"
LIBS="$PTHREAD_LIBS $LIBS"
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
# Check for various functions. We must include pthread.h,
# since some functions may be macros. (On the Sequent, we
# need a special flag -Kthread to make this header compile.)
# We check for pthread_join because it is in -lpthread on IRIX
# while pthread_create is in libc. We check for pthread_attr_init
# due to DEC craziness with -lpthreads. We check for
# pthread_cleanup_push because it is one of the few pthread
# functions on Solaris that doesn't have a non-functional libc stub.
# We try pthread_create on general principles.
AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h>
static void routine(void *a) { a = 0; }
static void *start_routine(void *a) { return a; }],
[pthread_t th; pthread_attr_t attr;
pthread_create(&th, 0, start_routine, 0);
pthread_join(th, 0);
pthread_attr_init(&attr);
pthread_cleanup_push(routine, 0);
pthread_cleanup_pop(0) /* ; */])],
[ax_pthread_ok=yes],
[])
LIBS="$save_LIBS"
CFLAGS="$save_CFLAGS"
AC_MSG_RESULT($ax_pthread_ok)
if test "x$ax_pthread_ok" = xyes; then
break;
fi
PTHREAD_LIBS=""
PTHREAD_CFLAGS=""
done
fi
# Various other checks:
if test "x$ax_pthread_ok" = xyes; then
save_LIBS="$LIBS"
LIBS="$PTHREAD_LIBS $LIBS"
save_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
# Detect AIX lossage: JOINABLE attribute is called UNDETACHED.
AC_MSG_CHECKING([for joinable pthread attribute])
attr_name=unknown
for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do
AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h>],
[int attr = $attr; return attr /* ; */])],
[attr_name=$attr; break],
[])
done
AC_MSG_RESULT($attr_name)
if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then
AC_DEFINE_UNQUOTED(PTHREAD_CREATE_JOINABLE, $attr_name,
[Define to necessary symbol if this constant
uses a non-standard name on your system.])
fi
AC_MSG_CHECKING([if more special flags are required for pthreads])
flag=no
case "${host_cpu}-${host_os}" in
*-aix* | *-freebsd* | *-darwin*) flag="-D_THREAD_SAFE";;
*-osf* | *-hpux*) flag="-D_REENTRANT";;
*solaris*)
if test "$GCC" = "yes"; then
flag="-D_REENTRANT"
else
flag="-mt -D_REENTRANT"
fi
;;
esac
AC_MSG_RESULT(${flag})
if test "x$flag" != xno; then
PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS"
fi
AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT],
ax_cv_PTHREAD_PRIO_INHERIT, [
AC_LINK_IFELSE([
AC_LANG_PROGRAM([[#include <pthread.h>]], [[int i = PTHREAD_PRIO_INHERIT;]])],
[ax_cv_PTHREAD_PRIO_INHERIT=yes],
[ax_cv_PTHREAD_PRIO_INHERIT=no])
])
AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes"],
AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], 1, [Have PTHREAD_PRIO_INHERIT.]))
LIBS="$save_LIBS"
CFLAGS="$save_CFLAGS"
# More AIX lossage: must compile with xlc_r or cc_r
if test x"$GCC" != xyes; then
AC_CHECK_PROGS(PTHREAD_CC, xlc_r cc_r, ${CC})
else
PTHREAD_CC=$CC
fi
else
PTHREAD_CC="$CC"
fi
AC_SUBST(PTHREAD_LIBS)
AC_SUBST(PTHREAD_CFLAGS)
AC_SUBST(PTHREAD_CC)
# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
if test x"$ax_pthread_ok" = xyes; then
ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1])
:
else
ax_pthread_ok=no
$2
fi
AC_LANG_POP
])dnl AX_PTHREAD
+546
View File
@@ -0,0 +1,546 @@
# ===========================================================================
# http://www.gnu.org/software/autoconf-archive/ax_with_curses.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_WITH_CURSES
#
# DESCRIPTION
#
# This macro checks whether a SysV or X/Open-compatible Curses library is
# present, along with the associated header file. The NcursesW
# (wide-character) library is searched for first, followed by Ncurses,
# then the system-default plain Curses. The first library found is the
# one returned.
#
# The following options are understood: --with-ncursesw, --with-ncurses,
# --without-ncursesw, --without-ncurses. The "--with" options force the
# macro to use that particular library, terminating with an error if not
# found. The "--without" options simply skip the check for that library.
# The effect on the search pattern is:
#
# (no options) - NcursesW, Ncurses, Curses
# --with-ncurses --with-ncursesw - NcursesW only [*]
# --without-ncurses --with-ncursesw - NcursesW only [*]
# --with-ncursesw - NcursesW only [*]
# --with-ncurses --without-ncursesw - Ncurses only [*]
# --with-ncurses - NcursesW, Ncurses [**]
# --without-ncurses --without-ncursesw - Curses only
# --without-ncursesw - Ncurses, Curses
# --without-ncurses - NcursesW, Curses
#
# [*] If the library is not found, abort the configure script.
#
# [**] If the second library (Ncurses) is not found, abort configure.
#
# The following preprocessor symbols may be defined by this macro if the
# appropriate conditions are met:
#
# HAVE_CURSES - if any SysV or X/Open Curses library found
# HAVE_CURSES_ENHANCED - if library supports X/Open Enhanced functions
# HAVE_CURSES_COLOR - if library supports color (enhanced functions)
# HAVE_CURSES_OBSOLETE - if library supports certain obsolete features
# HAVE_NCURSESW - if NcursesW (wide char) library is to be used
# HAVE_NCURSES - if the Ncurses library is to be used
#
# HAVE_CURSES_H - if <curses.h> is present and should be used
# HAVE_NCURSESW_H - if <ncursesw.h> should be used
# HAVE_NCURSES_H - if <ncurses.h> should be used
# HAVE_NCURSESW_CURSES_H - if <ncursesw/curses.h> should be used
# HAVE_NCURSES_CURSES_H - if <ncurses/curses.h> should be used
#
# (These preprocessor symbols are discussed later in this document.)
#
# The following output variable is defined by this macro; it is precious
# and may be overridden on the ./configure command line:
#
# CURSES_LIB - library to add to xxx_LDADD
#
# The library listed in CURSES_LIB is NOT added to LIBS by default. You
# need to add CURSES_LIB to the appropriate xxx_LDADD line in your
# Makefile.am. For example:
#
# prog_LDADD = @CURSES_LIB@
#
# If CURSES_LIB is set on the configure command line (such as by running
# "./configure CURSES_LIB=-lmycurses"), then the only header searched for
# is <curses.h>. The user may use the CPPFLAGS precious variable to
# override the standard #include search path. If the user needs to
# specify an alternative path for a library (such as for a non-standard
# NcurseW), the user should use the LDFLAGS variable.
#
# The following shell variables may be defined by this macro:
#
# ax_cv_curses - set to "yes" if any Curses library found
# ax_cv_curses_enhanced - set to "yes" if Enhanced functions present
# ax_cv_curses_color - set to "yes" if color functions present
# ax_cv_curses_obsolete - set to "yes" if obsolete features present
#
# ax_cv_ncursesw - set to "yes" if NcursesW library found
# ax_cv_ncurses - set to "yes" if Ncurses library found
# ax_cv_plaincurses - set to "yes" if plain Curses library found
# ax_cv_curses_which - set to "ncursesw", "ncurses", "plaincurses" or "no"
#
# These variables can be used in your configure.ac to determine the level
# of support you need from the Curses library. For example, if you must
# have either Ncurses or NcursesW, you could include:
#
# AX_WITH_CURSES
# if test "x$ax_cv_ncursesw" != xyes && test "x$ax_cv_ncurses" != xyes; then
# AX_MSG_ERROR([requires either NcursesW or Ncurses library])
# fi
#
# If any Curses library will do (but one must be present and must support
# color), you could use:
#
# AX_WITH_CURSES
# if test "x$ax_cv_curses" != xyes || test "x$ax_cv_curses_color" != xyes; then
# AC_MSG_ERROR([requires an X/Open-compatible Curses library with color])
# fi
#
# Certain preprocessor symbols and shell variables defined by this macro
# can be used to determine various features of the Curses library. In
# particular, HAVE_CURSES and ax_cv_curses are defined if the Curses
# library found conforms to the traditional SysV and/or X/Open Base Curses
# definition. Any working Curses library conforms to this level.
#
# HAVE_CURSES_ENHANCED and ax_cv_curses_enhanced are defined if the
# library supports the X/Open Enhanced Curses definition. In particular,
# the wide-character types attr_t, cchar_t and wint_t, the functions
# wattr_set() and wget_wch() and the macros WA_NORMAL and _XOPEN_CURSES
# are checked. The Ncurses library does NOT conform to this definition,
# although NcursesW does.
#
# HAVE_CURSES_COLOR and ax_cv_curses_color are defined if the library
# supports color functions and macros such as COLOR_PAIR, A_COLOR,
# COLOR_WHITE, COLOR_RED and init_pair(). These are NOT part of the
# X/Open Base Curses definition, but are part of the Enhanced set of
# functions. The Ncurses library DOES support these functions, as does
# NcursesW.
#
# HAVE_CURSES_OBSOLETE and ax_cv_curses_obsolete are defined if the
# library supports certain features present in SysV and BSD Curses but not
# defined in the X/Open definition. In particular, the functions
# getattrs(), getcurx() and getmaxx() are checked.
#
# To use the HAVE_xxx_H preprocessor symbols, insert the following into
# your system.h (or equivalent) header file:
#
# #if defined HAVE_NCURSESW_CURSES_H
# # include <ncursesw/curses.h>
# #elif defined HAVE_NCURSESW_H
# # include <ncursesw.h>
# #elif defined HAVE_NCURSES_CURSES_H
# # include <ncurses/curses.h>
# #elif defined HAVE_NCURSES_H
# # include <ncurses.h>
# #elif defined HAVE_CURSES_H
# # include <curses.h>
# #else
# # error "SysV or X/Open-compatible Curses header file required"
# #endif
#
# For previous users of this macro: you should not need to change anything
# in your configure.ac or Makefile.am, as the previous (serial 10)
# semantics are still valid. However, you should update your system.h (or
# equivalent) header file to the fragment shown above. You are encouraged
# also to make use of the extended functionality provided by this version
# of AX_WITH_CURSES, as well as in the additional macros
# AX_WITH_CURSES_PANEL, AX_WITH_CURSES_MENU and AX_WITH_CURSES_FORM.
#
# LICENSE
#
# Copyright (c) 2009 Mark Pulford <mark@kyne.com.au>
# Copyright (c) 2009 Damian Pietras <daper@daper.net>
# Copyright (c) 2012 Reuben Thomas <rrt@sc3d.org>
# Copyright (c) 2011 John Zaitseff <J.Zaitseff@zap.org.au>
#
# 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 3 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, see <http://www.gnu.org/licenses/>.
#
# As a special exception, the respective Autoconf Macro's copyright owner
# gives unlimited permission to copy, distribute and modify the configure
# scripts that are the output of Autoconf when processing the Macro. You
# need not follow the terms of the GNU General Public License when using
# or distributing such scripts, even though portions of the text of the
# Macro appear in them. The GNU General Public License (GPL) does govern
# all other use of the material that constitutes the Autoconf Macro.
#
# This special exception to the GPL applies to versions of the Autoconf
# Macro released by the Autoconf Archive. When you make and distribute a
# modified version of the Autoconf Macro, you may extend this special
# exception to the GPL to apply to your modified version as well.
#serial 13
AU_ALIAS([MP_WITH_CURSES], [AX_WITH_CURSES])
AC_DEFUN([AX_WITH_CURSES], [
AC_ARG_VAR([CURSES_LIB], [linker library for Curses, e.g. -lcurses])
AC_ARG_WITH([ncurses], [AS_HELP_STRING([--with-ncurses],
[force the use of Ncurses or NcursesW])],
[], [with_ncurses=check])
AC_ARG_WITH([ncursesw], [AS_HELP_STRING([--without-ncursesw],
[do not use NcursesW (wide character support)])],
[], [with_ncursesw=check])
ax_saved_LIBS=$LIBS
AS_IF([test "x$with_ncurses" = xyes || test "x$with_ncursesw" = xyes],
[ax_with_plaincurses=no], [ax_with_plaincurses=check])
ax_cv_curses_which=no
# Test for NcursesW
AS_IF([test "x$CURSES_LIB" = x && test "x$with_ncursesw" != xno], [
LIBS="$ax_saved_LIBS -lncursesw"
AC_CACHE_CHECK([for NcursesW wide-character library], [ax_cv_ncursesw], [
AC_LINK_IFELSE([AC_LANG_CALL([], [initscr])],
[ax_cv_ncursesw=yes], [ax_cv_ncursesw=no])
])
AS_IF([test "x$ax_cv_ncursesw" = xno && test "x$with_ncursesw" = xyes], [
AC_MSG_ERROR([--with-ncursesw specified but could not find NcursesW library])
])
AS_IF([test "x$ax_cv_ncursesw" = xyes], [
ax_cv_curses=yes
ax_cv_curses_which=ncursesw
CURSES_LIB="-lncursesw"
AC_DEFINE([HAVE_NCURSESW], [1], [Define to 1 if the NcursesW library is present])
AC_DEFINE([HAVE_CURSES], [1], [Define to 1 if a SysV or X/Open compatible Curses library is present])
AC_CACHE_CHECK([for working ncursesw/curses.h], [ax_cv_header_ncursesw_curses_h], [
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
@%:@define _XOPEN_SOURCE_EXTENDED 1
@%:@include <ncursesw/curses.h>
]], [[
chtype a = A_BOLD;
int b = KEY_LEFT;
chtype c = COLOR_PAIR(1) & A_COLOR;
attr_t d = WA_NORMAL;
cchar_t e;
wint_t f;
int g = getattrs(stdscr);
int h = getcurx(stdscr) + getmaxx(stdscr);
initscr();
init_pair(1, COLOR_WHITE, COLOR_RED);
wattr_set(stdscr, d, 0, NULL);
wget_wch(stdscr, &f);
]])],
[ax_cv_header_ncursesw_curses_h=yes],
[ax_cv_header_ncursesw_curses_h=no])
])
AS_IF([test "x$ax_cv_header_ncursesw_curses_h" = xyes], [
ax_cv_curses_enhanced=yes
ax_cv_curses_color=yes
ax_cv_curses_obsolete=yes
AC_DEFINE([HAVE_CURSES_ENHANCED], [1], [Define to 1 if library supports X/Open Enhanced functions])
AC_DEFINE([HAVE_CURSES_COLOR], [1], [Define to 1 if library supports color (enhanced functions)])
AC_DEFINE([HAVE_CURSES_OBSOLETE], [1], [Define to 1 if library supports certain obsolete features])
AC_DEFINE([HAVE_NCURSESW_CURSES_H], [1], [Define to 1 if <ncursesw/curses.h> is present])
])
AC_CACHE_CHECK([for working ncursesw.h], [ax_cv_header_ncursesw_h], [
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
@%:@define _XOPEN_SOURCE_EXTENDED 1
@%:@include <ncursesw.h>
]], [[
chtype a = A_BOLD;
int b = KEY_LEFT;
chtype c = COLOR_PAIR(1) & A_COLOR;
attr_t d = WA_NORMAL;
cchar_t e;
wint_t f;
int g = getattrs(stdscr);
int h = getcurx(stdscr) + getmaxx(stdscr);
initscr();
init_pair(1, COLOR_WHITE, COLOR_RED);
wattr_set(stdscr, d, 0, NULL);
wget_wch(stdscr, &f);
]])],
[ax_cv_header_ncursesw_h=yes],
[ax_cv_header_ncursesw_h=no])
])
AS_IF([test "x$ax_cv_header_ncursesw_h" = xyes], [
ax_cv_curses_enhanced=yes
ax_cv_curses_color=yes
ax_cv_curses_obsolete=yes
AC_DEFINE([HAVE_CURSES_ENHANCED], [1], [Define to 1 if library supports X/Open Enhanced functions])
AC_DEFINE([HAVE_CURSES_COLOR], [1], [Define to 1 if library supports color (enhanced functions)])
AC_DEFINE([HAVE_CURSES_OBSOLETE], [1], [Define to 1 if library supports certain obsolete features])
AC_DEFINE([HAVE_NCURSESW_H], [1], [Define to 1 if <ncursesw.h> is present])
])
AC_CACHE_CHECK([for working ncurses.h], [ax_cv_header_ncurses_h_with_ncursesw], [
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
@%:@define _XOPEN_SOURCE_EXTENDED 1
@%:@include <ncurses.h>
]], [[
chtype a = A_BOLD;
int b = KEY_LEFT;
chtype c = COLOR_PAIR(1) & A_COLOR;
attr_t d = WA_NORMAL;
cchar_t e;
wint_t f;
int g = getattrs(stdscr);
int h = getcurx(stdscr) + getmaxx(stdscr);
initscr();
init_pair(1, COLOR_WHITE, COLOR_RED);
wattr_set(stdscr, d, 0, NULL);
wget_wch(stdscr, &f);
]])],
[ax_cv_header_ncurses_h_with_ncursesw=yes],
[ax_cv_header_ncurses_h_with_ncursesw=no])
])
AS_IF([test "x$ax_cv_header_ncurses_h_with_ncursesw" = xyes], [
ax_cv_curses_enhanced=yes
ax_cv_curses_color=yes
ax_cv_curses_obsolete=yes
AC_DEFINE([HAVE_CURSES_ENHANCED], [1], [Define to 1 if library supports X/Open Enhanced functions])
AC_DEFINE([HAVE_CURSES_COLOR], [1], [Define to 1 if library supports color (enhanced functions)])
AC_DEFINE([HAVE_CURSES_OBSOLETE], [1], [Define to 1 if library supports certain obsolete features])
AC_DEFINE([HAVE_NCURSES_H], [1], [Define to 1 if <ncurses.h> is present])
])
AS_IF([test "x$ax_cv_header_ncursesw_curses_h" = xno && test "x$ax_cv_header_ncursesw_h" = xno && test "x$ax_cv_header_ncurses_h_with_ncursesw" = xno], [
AC_MSG_WARN([could not find a working ncursesw/curses.h, ncursesw.h or ncurses.h])
])
dnl Test if we need to explicitly link against -ltinfow.
AC_CACHE_CHECK([if curses tinfo library is linked properly], [ax_cv_ncurses_compiled], [
LIBS="$ax_saved_LIBS $CURSES_LIB"
AC_LINK_IFELSE([AC_LANG_CALL([], [keypad])], [ax_cv_ncurses_compiled=yes], [ax_cv_ncurses_compiled=no])
LIBS="$ax_saved_LIBS $CURSES_LIB -ltinfo"
AC_LINK_IFELSE([AC_LANG_CALL([], [keypad])], [ax_cv_tinfo_compiled=yes], [ax_cv_tinfo_compiled=no])
LIBS="$ax_saved_LIBS $CURSES_LIB -ltinfow"
AC_LINK_IFELSE([AC_LANG_CALL([], [keypad])], [ax_cv_tinfow_compiled=yes], [ax_cv_tinfow_compiled=no])
LIBS=$ax_saved_LIBS
])
AS_IF([test "x$ax_cv_ncurses_compiled" = xno], [
AS_IF(
[test "x$ax_cv_tinfo_compiled" = xyes], [
AC_MSG_RESULT([adding libtinfo])
CURSES_LIB="$CURSES_LIB -ltinfo"
],
[test "x$ax_cv_tinfow_compiled" = xyes], [
AC_MSG_RESULT([adding libtinfow])
CURSES_LIB="$CURSES_LIB -ltinfow"
], [
AC_MSG_ERROR([no])
])
])
])
])
# Test for Ncurses
AS_IF([test "x$CURSES_LIB" = x && test "x$with_ncurses" != xno && test "x$ax_cv_curses_which" = xno], [
LIBS="$ax_saved_LIBS -lncurses"
AC_CACHE_CHECK([for Ncurses library], [ax_cv_ncurses], [
AC_LINK_IFELSE([AC_LANG_CALL([], [initscr])],
[ax_cv_ncurses=yes], [ax_cv_ncurses=no])
])
AS_IF([test "x$ax_cv_ncurses" = xno && test "x$with_ncurses" = xyes], [
AC_MSG_ERROR([--with-ncurses specified but could not find Ncurses library])
])
AS_IF([test "x$ax_cv_ncurses" = xyes], [
ax_cv_curses=yes
ax_cv_curses_which=ncurses
CURSES_LIB="-lncurses"
AC_DEFINE([HAVE_NCURSES], [1], [Define to 1 if the Ncurses library is present])
AC_DEFINE([HAVE_CURSES], [1], [Define to 1 if a SysV or X/Open compatible Curses library is present])
AC_CACHE_CHECK([for working ncurses/curses.h], [ax_cv_header_ncurses_curses_h], [
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
@%:@include <ncurses/curses.h>
]], [[
chtype a = A_BOLD;
int b = KEY_LEFT;
chtype c = COLOR_PAIR(1) & A_COLOR;
int g = getattrs(stdscr);
int h = getcurx(stdscr) + getmaxx(stdscr);
initscr();
init_pair(1, COLOR_WHITE, COLOR_RED);
]])],
[ax_cv_header_ncurses_curses_h=yes],
[ax_cv_header_ncurses_curses_h=no])
])
AS_IF([test "x$ax_cv_header_ncurses_curses_h" = xyes], [
ax_cv_curses_color=yes
ax_cv_curses_obsolete=yes
AC_DEFINE([HAVE_CURSES_COLOR], [1], [Define to 1 if library supports color (enhanced functions)])
AC_DEFINE([HAVE_CURSES_OBSOLETE], [1], [Define to 1 if library supports certain obsolete features])
AC_DEFINE([HAVE_NCURSES_CURSES_H], [1], [Define to 1 if <ncurses/curses.h> is present])
])
AC_CACHE_CHECK([for working ncurses.h], [ax_cv_header_ncurses_h], [
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
@%:@include <ncurses.h>
]], [[
chtype a = A_BOLD;
int b = KEY_LEFT;
chtype c = COLOR_PAIR(1) & A_COLOR;
int g = getattrs(stdscr);
int h = getcurx(stdscr) + getmaxx(stdscr);
initscr();
init_pair(1, COLOR_WHITE, COLOR_RED);
]])],
[ax_cv_header_ncurses_h=yes],
[ax_cv_header_ncurses_h=no])
])
AS_IF([test "x$ax_cv_header_ncurses_h" = xyes], [
ax_cv_curses_color=yes
ax_cv_curses_obsolete=yes
AC_DEFINE([HAVE_CURSES_COLOR], [1], [Define to 1 if library supports color (enhanced functions)])
AC_DEFINE([HAVE_CURSES_OBSOLETE], [1], [Define to 1 if library supports certain obsolete features])
AC_DEFINE([HAVE_NCURSES_H], [1], [Define to 1 if <ncurses.h> is present])
])
AS_IF([test "x$ax_cv_header_ncurses_curses_h" = xno && test "x$ax_cv_header_ncurses_h" = xno], [
AC_MSG_WARN([could not find a working ncurses/curses.h or ncurses.h])
])
])
])
# Test for plain Curses (or if CURSES_LIB was set by user)
AS_IF([test "x$with_plaincurses" != xno && test "x$ax_cv_curses_which" = xno], [
AS_IF([test "x$CURSES_LIB" != x], [
LIBS="$ax_saved_LIBS $CURSES_LIB"
], [
LIBS="$ax_saved_LIBS -lcurses"
])
AC_CACHE_CHECK([for Curses library], [ax_cv_plaincurses], [
AC_LINK_IFELSE([AC_LANG_CALL([], [initscr])],
[ax_cv_plaincurses=yes], [ax_cv_plaincurses=no])
])
AS_IF([test "x$ax_cv_plaincurses" = xyes], [
ax_cv_curses=yes
ax_cv_curses_which=plaincurses
AS_IF([test "x$CURSES_LIB" = x], [
CURSES_LIB="-lcurses"
])
AC_DEFINE([HAVE_CURSES], [1], [Define to 1 if a SysV or X/Open compatible Curses library is present])
# Check for base conformance (and header file)
AC_CACHE_CHECK([for working curses.h], [ax_cv_header_curses_h], [
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
@%:@include <curses.h>
]], [[
chtype a = A_BOLD;
int b = KEY_LEFT;
initscr();
]])],
[ax_cv_header_curses_h=yes],
[ax_cv_header_curses_h=no])
])
AS_IF([test "x$ax_cv_header_curses_h" = xyes], [
AC_DEFINE([HAVE_CURSES_H], [1], [Define to 1 if <curses.h> is present])
# Check for X/Open Enhanced conformance
AC_CACHE_CHECK([for X/Open Enhanced Curses conformance], [ax_cv_plaincurses_enhanced], [
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
@%:@define _XOPEN_SOURCE_EXTENDED 1
@%:@include <curses.h>
@%:@ifndef _XOPEN_CURSES
@%:@error "this Curses library is not enhanced"
"this Curses library is not enhanced"
@%:@endif
]], [[
chtype a = A_BOLD;
int b = KEY_LEFT;
chtype c = COLOR_PAIR(1) & A_COLOR;
attr_t d = WA_NORMAL;
cchar_t e;
wint_t f;
initscr();
init_pair(1, COLOR_WHITE, COLOR_RED);
wattr_set(stdscr, d, 0, NULL);
wget_wch(stdscr, &f);
]])],
[ax_cv_plaincurses_enhanced=yes],
[ax_cv_plaincurses_enhanced=no])
])
AS_IF([test "x$ax_cv_plaincurses_enhanced" = xyes], [
ax_cv_curses_enhanced=yes
ax_cv_curses_color=yes
AC_DEFINE([HAVE_CURSES_ENHANCED], [1], [Define to 1 if library supports X/Open Enhanced functions])
AC_DEFINE([HAVE_CURSES_COLOR], [1], [Define to 1 if library supports color (enhanced functions)])
])
# Check for color functions
AC_CACHE_CHECK([for Curses color functions], [ax_cv_plaincurses_color], [
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
@%:@define _XOPEN_SOURCE_EXTENDED 1
@%:@include <curses.h>
]], [[
chtype a = A_BOLD;
int b = KEY_LEFT;
chtype c = COLOR_PAIR(1) & A_COLOR;
initscr();
init_pair(1, COLOR_WHITE, COLOR_RED);
]])],
[ax_cv_plaincurses_color=yes],
[ax_cv_plaincurses_color=no])
])
AS_IF([test "x$ax_cv_plaincurses_color" = xyes], [
ax_cv_curses_color=yes
AC_DEFINE([HAVE_CURSES_COLOR], [1], [Define to 1 if library supports color (enhanced functions)])
])
# Check for obsolete functions
AC_CACHE_CHECK([for obsolete Curses functions], [ax_cv_plaincurses_obsolete], [
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
@%:@include <curses.h>
]], [[
chtype a = A_BOLD;
int b = KEY_LEFT;
int g = getattrs(stdscr);
int h = getcurx(stdscr) + getmaxx(stdscr);
initscr();
]])],
[ax_cv_plaincurses_obsolete=yes],
[ax_cv_plaincurses_obsolete=no])
])
AS_IF([test "x$ax_cv_plaincurses_obsolete" = xyes], [
ax_cv_curses_obsolete=yes
AC_DEFINE([HAVE_CURSES_OBSOLETE], [1], [Define to 1 if library supports certain obsolete features])
])
])
AS_IF([test "x$ax_cv_header_curses_h" = xno], [
AC_MSG_WARN([could not find a working curses.h])
])
])
])
AS_IF([test "x$ax_cv_curses" != xyes], [ax_cv_curses=no])
AS_IF([test "x$ax_cv_curses_enhanced" != xyes], [ax_cv_curses_enhanced=no])
AS_IF([test "x$ax_cv_curses_color" != xyes], [ax_cv_curses_color=no])
AS_IF([test "x$ax_cv_curses_obsolete" != xyes], [ax_cv_curses_obsolete=no])
LIBS=$ax_saved_LIBS
])dnl
+127 -60
View File
@@ -1,15 +1,15 @@
AC_DEFUN([TORRENT_CHECK_XFS], [
AC_MSG_CHECKING(for XFS support)
AC_COMPILE_IFELSE(
[[#include <xfs/libxfs.h>
AC_COMPILE_IFELSE([AC_LANG_SOURCE([
#include <xfs/libxfs.h>
#include <sys/ioctl.h>
int main() {
struct xfs_flock64 l;
ioctl(0, XFS_IOC_RESVSP64, &l);
return 0;
}
]],
])],
[
AC_DEFINE(USE_XFS, 1, Use XFS filesystem stuff.)
AC_MSG_RESULT(yes)
@@ -21,9 +21,9 @@ AC_DEFUN([TORRENT_CHECK_XFS], [
AC_DEFUN([TORRENT_WITHOUT_XFS], [
AC_ARG_WITH(xfs,
[ --without-xfs Do not check for XFS filesystem support],
AC_HELP_STRING([--without-xfs], [do not check for XFS filesystem support]),
[
if test "$withval" = "yes"; then
if test "$withval" = "yes"; then
TORRENT_CHECK_XFS
fi
], [
@@ -34,7 +34,7 @@ AC_DEFUN([TORRENT_WITHOUT_XFS], [
AC_DEFUN([TORRENT_WITH_XFS], [
AC_ARG_WITH(xfs,
[ --with-xfs Check for XFS filesystem support],
AC_HELP_STRING([--with-xfs], [check for XFS filesystem support]),
[
if test "$withval" = "yes"; then
TORRENT_CHECK_XFS
@@ -46,13 +46,13 @@ AC_DEFUN([TORRENT_WITH_XFS], [
AC_DEFUN([TORRENT_CHECK_EPOLL], [
AC_MSG_CHECKING(for epoll support)
AC_COMPILE_IFELSE(
[[#include <sys/epoll.h>
AC_COMPILE_IFELSE([AC_LANG_SOURCE([
#include <sys/epoll.h>
int main() {
int fd = epoll_create(100);
return 0;
}
]],
])],
[
AC_DEFINE(USE_EPOLL, 1, Use epoll.)
AC_MSG_RESULT(yes)
@@ -63,7 +63,7 @@ AC_DEFUN([TORRENT_CHECK_EPOLL], [
AC_DEFUN([TORRENT_WITHOUT_EPOLL], [
AC_ARG_WITH(epoll,
[ --without-epoll Do not check for epoll support.],
AC_HELP_STRING([--without-epoll], [do not check for epoll support]),
[
if test "$withval" = "yes"; then
TORRENT_CHECK_EPOLL
@@ -77,14 +77,14 @@ AC_DEFUN([TORRENT_WITHOUT_EPOLL], [
AC_DEFUN([TORRENT_CHECK_KQUEUE], [
AC_MSG_CHECKING(for kqueue support)
AC_LINK_IFELSE(
[[#include <sys/time.h> /* Because OpenBSD's sys/event.h fails to compile otherwise. Yeah... */
AC_LINK_IFELSE([AC_LANG_SOURCE([
#include <sys/time.h> /* Because OpenBSD's sys/event.h fails to compile otherwise. Yeah... */
#include <sys/event.h>
int main() {
int fd = kqueue();
return 0;
}
]],
])],
[
AC_DEFINE(USE_KQUEUE, 1, Use kqueue.)
AC_MSG_RESULT(yes)
@@ -96,33 +96,33 @@ AC_DEFUN([TORRENT_CHECK_KQUEUE], [
AC_DEFUN([TORRENT_CHECK_KQUEUE_SOCKET_ONLY], [
AC_MSG_CHECKING(whether kqueue supports pipes and ptys)
AC_RUN_IFELSE(
[[#include <fcntl.h>
AC_RUN_IFELSE([AC_LANG_SOURCE([
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/event.h>
#include <sys/time.h>
int main() {
struct kevent ev[2], ev_out[2];
struct kevent ev@<:@2@:>@, ev_out@<:@2@:>@;
struct timespec ts = { 0, 0 };
int pfd[2], pty[2], kfd, n;
char buffer[9001];
int pfd@<:@2@:>@, pty@<:@2@:>@, kfd, n;
char buffer@<:@9001@:>@;
if (pipe(pfd) == -1) return 1;
if (fcntl(pfd[1], F_SETFL, O_NONBLOCK) == -1) return 2;
while ((n = write(pfd[1], buffer, sizeof(buffer))) == sizeof(buffer));
if ((pty[0]=posix_openpt(O_RDWR | O_NOCTTY)) == -1) return 3;
if ((pty[1]=grantpt(pty[0])) == -1) return 4;
EV_SET(ev+0, pfd[1], EVFILT_WRITE, EV_ADD | EV_ENABLE, 0, 0, NULL);
EV_SET(ev+1, pty[1], EVFILT_READ, EV_ADD | EV_ENABLE, 0, 0, NULL);
if (fcntl(pfd@<:@1@:>@, F_SETFL, O_NONBLOCK) == -1) return 2;
while ((n = write(pfd@<:@1@:>@, buffer, sizeof(buffer))) == sizeof(buffer));
if ((pty@<:@0@:>@=posix_openpt(O_RDWR | O_NOCTTY)) == -1) return 3;
if ((pty@<:@1@:>@=grantpt(pty@<:@0@:>@)) == -1) return 4;
EV_SET(ev+0, pfd@<:@1@:>@, EVFILT_WRITE, EV_ADD | EV_ENABLE, 0, 0, NULL);
EV_SET(ev+1, pty@<:@1@:>@, EVFILT_READ, EV_ADD | EV_ENABLE, 0, 0, NULL);
if ((kfd = kqueue()) == -1) return 5;
if ((n = kevent(kfd, ev, 2, NULL, 0, NULL)) == -1) return 6;
if (ev_out[0].flags & EV_ERROR) return 7;
if (ev_out[1].flags & EV_ERROR) return 8;
read(pfd[0], buffer, sizeof(buffer));
if (ev_out@<:@0@:>@.flags & EV_ERROR) return 7;
if (ev_out@<:@1@:>@.flags & EV_ERROR) return 8;
read(pfd@<:@0@:>@, buffer, sizeof(buffer));
if ((n = kevent(kfd, NULL, 0, ev_out, 2, &ts)) < 1) return 9;
return 0;
}
]],
])],
[
AC_MSG_RESULT(yes)
], [
@@ -133,7 +133,7 @@ AC_DEFUN([TORRENT_CHECK_KQUEUE_SOCKET_ONLY], [
AC_DEFUN([TORRENT_WITH_KQUEUE], [
AC_ARG_WITH(kqueue,
[ --with-kqueue enable kqueue. [[default=no]]],
AC_HELP_STRING([--with-kqueue], [enable kqueue [[default=no]]]),
[
if test "$withval" = "yes"; then
TORRENT_CHECK_KQUEUE
@@ -143,10 +143,24 @@ AC_DEFUN([TORRENT_WITH_KQUEUE], [
])
AC_DEFUN([TORRENT_WITHOUT_KQUEUE], [
AC_ARG_WITH(kqueue,
AC_HELP_STRING([--without-kqueue], [do not check for kqueue support]),
[
if test "$withval" = "yes"; then
TORRENT_CHECK_KQUEUE
TORRENT_CHECK_KQUEUE_SOCKET_ONLY
fi
], [
TORRENT_CHECK_KQUEUE
TORRENT_CHECK_KQUEUE_SOCKET_ONLY
])
])
AC_DEFUN([TORRENT_WITHOUT_VARIABLE_FDSET], [
AC_ARG_WITH(variable-fdset,
[ --without-variable-fdset do not use non-portable variable sized fd_set's.],
AC_HELP_STRING([--without-variable-fdset], [do not use non-portable variable sized fd_set's]),
[
if test "$withval" = "yes"; then
AC_DEFINE(USE_VARIABLE_FDSET, 1, defined when we allow the use of fd_set's of any size)
@@ -190,7 +204,7 @@ AC_DEFUN([TORRENT_CHECK_POSIX_FALLOCATE], [
AC_DEFUN([TORRENT_WITH_POSIX_FALLOCATE], [
AC_ARG_WITH(posix-fallocate,
[ --with-posix-fallocate Check for and use posix_fallocate to allocate files.],
AC_HELP_STRING([--with-posix-fallocate], [check for and use posix_fallocate to allocate files]),
[
if test "$withval" = "yes"; then
TORRENT_CHECK_POSIX_FALLOCATE
@@ -198,26 +212,6 @@ AC_DEFUN([TORRENT_WITH_POSIX_FALLOCATE], [
])
])
AC_DEFUN([TORRENT_WITHOUT_NCURSESW], [
AC_ARG_WITH(ncursesw,
[ --without-ncursesw Don't try to use wide char ncurses.],
[
if test "$withval" = "no"; then
AC_SEARCH_LIBS(add_wch, ncursesw,
AC_DEFINE(HAVE_NCURSESW, 1, defined if ncurses wide character support is available),
AC_SEARCH_LIBS(wbkgdset, ncurses curses,,echo "*** The ncurses library is required!";exit 1)
)
else
AC_SEARCH_LIBS(wbkgdset, ncurses curses,,echo "*** The ncurses library is required!";exit 1)
fi
],[
AC_SEARCH_LIBS(add_wch, ncursesw,
AC_DEFINE(HAVE_NCURSESW, 1, defined if ncurses wide character support is available),
AC_SEARCH_LIBS(wbkgdset, ncurses curses,,echo "*** The ncurses library is required!";exit 1)
)
])
])
AC_DEFUN([TORRENT_CHECK_STATVFS], [
AC_CHECK_HEADERS(sys/vfs.h sys/statvfs.h sys/statfs.h)
@@ -304,7 +298,7 @@ AC_DEFUN([TORRENT_DISABLED_STATFS], [
AC_DEFUN([TORRENT_WITHOUT_STATVFS], [
AC_ARG_WITH(statvfs,
[ --without-statvfs Don't try to use statvfs to find free diskspace.],
AC_HELP_STRING([--without-statvfs], [don't try to use statvfs to find free diskspace]),
[
if test "$withval" = "yes"; then
TORRENT_CHECK_STATVFS
@@ -319,7 +313,7 @@ AC_DEFUN([TORRENT_WITHOUT_STATVFS], [
AC_DEFUN([TORRENT_WITHOUT_STATFS], [
AC_ARG_WITH(statfs,
[ --without-statfs Don't try to use statfs to find free diskspace.],
AC_HELP_STRING([--without-statfs], [don't try to use statfs to find free diskspace]),
[
if test "$have_stat_vfs" = "no"; then
if test "$withval" = "yes"; then
@@ -341,7 +335,7 @@ AC_DEFUN([TORRENT_WITHOUT_STATFS], [
AC_DEFUN([TORRENT_WITH_ADDRESS_SPACE], [
AC_ARG_WITH(address-space,
AC_HELP_STRING([--with-address-space=MB], [Change the default address space size, default 1024 MB.]),
AC_HELP_STRING([--with-address-space=MB], [change the default address space size [[default=1024mb]]]),
[
if test ! -z $withval -a "$withval" != "yes" -a "$withval" != "no"; then
AC_DEFINE_UNQUOTED(DEFAULT_ADDRESS_SPACE_SIZE, [$withval])
@@ -364,11 +358,11 @@ AC_DEFUN([TORRENT_CHECK_TR1], [
AC_LANG_PUSH(C++)
AC_MSG_CHECKING(for TR1 support)
AC_COMPILE_IFELSE(
[[#include <tr1/unordered_map>
AC_COMPILE_IFELSE([AC_LANG_SOURCE([
#include <tr1/unordered_map>
class Foo;
typedef std::tr1::unordered_map<Foo*, int> Bar;
]],
])],
[
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_TR1, 1, Define to 1 if your C++ library supports the extensions from Technical Report 1)
@@ -381,9 +375,33 @@ AC_DEFUN([TORRENT_CHECK_TR1], [
AC_LANG_POP(C++)
])
AC_DEFUN([TORRENT_CHECK_CXX11], [
AC_LANG_PUSH(C++)
AC_MSG_CHECKING(for C++11 support)
AC_COMPILE_IFELSE([AC_LANG_SOURCE([
#include <functional>
#include <unordered_map>
class Foo;
typedef std::unordered_map<Foo*, int> Bar;
union test { Bar b1; };
])],
[
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_CXX11, 1, Define to 1 if your C++ compiler has support for C++11.)
],
[
AC_MSG_RESULT(no)
]
)
AC_LANG_POP(C++)
])
AC_DEFUN([TORRENT_WITH_FASTCGI], [
AC_ARG_WITH(fastcgi,
[ --with-fastcgi=PATH Enable FastCGI RPC support. (DO NOT USE)],
AC_HELP_STRING([--with-fastcgi=PATH], [enable FastCGI RPC support (DO NOT USE)]),
[
AC_MSG_CHECKING([for FastCGI (DO NOT USE)])
@@ -432,7 +450,7 @@ AC_DEFUN([TORRENT_WITH_XMLRPC_C], [
AC_MSG_CHECKING(for XMLRPC-C)
AC_ARG_WITH(xmlrpc-c,
[ --with-xmlrpc-c=PATH Enable XMLRPC-C support.],
AC_HELP_STRING([--with-xmlrpc-c=PATH], [enable XMLRPC-C support]),
[
if test "$withval" = "no"; then
AC_MSG_RESULT(no)
@@ -470,3 +488,52 @@ AC_DEFUN([TORRENT_WITH_XMLRPC_C], [
AC_MSG_RESULT(ignored)
])
])
AC_DEFUN([TORRENT_WITH_INOTIFY], [
AC_LANG_PUSH(C++)
AC_CHECK_HEADERS([sys/inotify.h mcheck.h])
AC_MSG_CHECKING([whether sys/inotify.h actually works])
AC_COMPILE_IFELSE([AC_LANG_SOURCE([
#include <sys/inotify.h>
int main(int,const char**) { return (-1 == inotify_init()); }])
],[
AC_DEFINE(HAVE_INOTIFY, 1, [sys/inotify.h exists and works correctly])
AC_MSG_RESULT(yes)],
[AC_MSG_RESULT(failed)]
)
AC_LANG_POP(C++)
])
AC_DEFUN([TORRENT_CHECK_PTHREAD_SETNAME_NP], [
AC_CHECK_HEADERS(pthread.h)
AC_MSG_CHECKING(for pthread_setname_np type)
AC_TRY_LINK([
#include <pthread.h>
#include <sys/types.h>
],[
pthread_t t;
pthread_setname_np(t, "foo");
],[
AC_DEFINE(HAS_PTHREAD_SETNAME_NP_GENERIC, 1, The function to set pthread name has a pthread_t argumet.)
AC_MSG_RESULT(generic)
],[
AC_TRY_LINK([
#include <pthread.h>
#include <sys/types.h>
],[
pthread_t t;
pthread_setname_np("foo");
],[
AC_DEFINE(HAS_PTHREAD_SETNAME_NP_DARWIN, 1, The function to set pthread name has no pthread argument.)
AC_MSG_RESULT(darwin)
],[
AC_MSG_RESULT(no)
])
])
])
+83 -37
View File
@@ -13,7 +13,7 @@ AC_DEFUN([TORRENT_CHECK_CXXFLAGS], [
AC_DEFUN([TORRENT_ENABLE_DEBUG], [
AC_ARG_ENABLE(debug,
[ --enable-debug enable debug information [[default=yes]]],
AC_HELP_STRING([--enable-debug], [enable debug information [[default=yes]]]),
[
if test "$enableval" = "yes"; then
CXXFLAGS="$CXXFLAGS -g -DDEBUG"
@@ -28,7 +28,7 @@ AC_DEFUN([TORRENT_ENABLE_DEBUG], [
AC_DEFUN([TORRENT_ENABLE_WERROR], [
AC_ARG_ENABLE(werror,
[ --enable-werror enable the -Werror and -Wall flag [[default=no]]],
AC_HELP_STRING([--enable-werror], [enable the -Werror and -Wall flag [[default=no]]]),
[
if test "$enableval" = "yes"; then
CXXFLAGS="$CXXFLAGS -Werror -Wall"
@@ -39,7 +39,7 @@ AC_DEFUN([TORRENT_ENABLE_WERROR], [
AC_DEFUN([TORRENT_ENABLE_EXTRA_DEBUG], [
AC_ARG_ENABLE(extra-debug,
[ --enable-extra-debug enable extra debugging checks. [[default=no]]],
AC_HELP_STRING([--enable-extra-debug], [enable extra debugging checks [[default=no]]]),
[
if test "$enableval" = "yes"; then
AC_DEFINE(USE_EXTRA_DEBUG, 1, Enable extra debugging checks.)
@@ -50,7 +50,7 @@ AC_DEFUN([TORRENT_ENABLE_EXTRA_DEBUG], [
AC_DEFUN([TORRENT_WITH_SYSROOT], [
AC_ARG_WITH(sysroot,
[ --with-sysroot=PATH compile and link with a specific sysroot.],
AC_HELP_STRING([--with-sysroot=PATH], [compile and link with a specific sysroot]),
[
AC_MSG_CHECKING(for sysroot)
@@ -72,7 +72,7 @@ AC_DEFUN([TORRENT_WITH_SYSROOT], [
AC_DEFUN([TORRENT_ENABLE_ARCH], [
AC_ARG_ENABLE(arch,
[ --enable-arch=ARCH comma seprated list of architectures to compile for.],
AC_HELP_STRING([--enable-arch=ARCH], [comma seprated list of architectures to compile for]),
[
AC_MSG_CHECKING(for target architectures)
@@ -99,11 +99,11 @@ AC_DEFUN([TORRENT_OTFD], [
AC_LANG_PUSH(C++)
AC_MSG_CHECKING(for proper overloaded template function disambiguation)
AC_COMPILE_IFELSE(
[[template <typename T> void f(T&) {}
AC_COMPILE_IFELSE([AC_LANG_SOURCE([
template <typename T> void f(T&) {}
template <typename T> void f(T*) {}
int main() { int *i = 0; f(*i); f(i); }
]],
])],
[
AC_MSG_RESULT(yes)
], [
@@ -119,24 +119,24 @@ AC_DEFUN([TORRENT_MINCORE_SIGNEDNESS], [
AC_LANG_PUSH(C++)
AC_MSG_CHECKING(signedness of mincore parameter)
AC_COMPILE_IFELSE(
[[#include <sys/types.h>
AC_COMPILE_IFELSE([AC_LANG_SOURCE([
#include <sys/types.h>
#include <sys/mman.h>
#include <unistd.h>
void f() { mincore((char*)0, 0, (unsigned char*)0); }
]],
])],
[
AC_DEFINE(USE_MINCORE, 1, Use mincore)
AC_DEFINE(USE_MINCORE_UNSIGNED, 1, use unsigned char* in mincore)
AC_MSG_RESULT(unsigned)
],
[
AC_COMPILE_IFELSE(
[[#include <sys/types.h>
AC_COMPILE_IFELSE([AC_LANG_SOURCE([
#include <sys/types.h>
#include <sys/mman.h>
#include <unistd.h>
void f() { mincore((char*)0, 0, (char*)0); }
]],
])],
[
AC_DEFINE(USE_MINCORE, 1, Use mincore)
AC_DEFINE(USE_MINCORE_UNSIGNED, 0, use char* in mincore)
@@ -152,7 +152,7 @@ AC_DEFUN([TORRENT_MINCORE_SIGNEDNESS], [
AC_DEFUN([TORRENT_MINCORE], [
AC_ARG_ENABLE(mincore,
[ --disable-mincore disable mincore check [[default=enable]]],
AC_HELP_STRING([--disable-mincore], [disable mincore check [[default=enable]]]),
[
if test "$enableval" = "yes"; then
TORRENT_MINCORE_SIGNEDNESS()
@@ -168,11 +168,11 @@ AC_DEFUN([TORRENT_MINCORE], [
AC_DEFUN([TORRENT_CHECK_MADVISE], [
AC_MSG_CHECKING(for madvise)
AC_COMPILE_IFELSE(
[[#include <sys/types.h>
#include <sys/mman.h>
void f() { static char test[1024]; madvise((void *)test, sizeof(test), MADV_NORMAL); }
]],
AC_COMPILE_IFELSE([AC_LANG_SOURCE([
#include <sys/types.h>
#include <sys/mman.h>
void f() { static char test@<:@1024@:>@; madvise((void *)test, sizeof(test), MADV_NORMAL); }
])],
[
AC_MSG_RESULT(yes)
AC_DEFINE(USE_MADVISE, 1, Use madvise)
@@ -184,10 +184,9 @@ AC_DEFUN([TORRENT_CHECK_MADVISE], [
AC_DEFUN([TORRENT_CHECK_POPCOUNT], [
AC_MSG_CHECKING(for __builtin_popcount)
AC_COMPILE_IFELSE(
[[
void f() { __builtin_popcount(0); }
]],
AC_COMPILE_IFELSE([AC_LANG_SOURCE([
int f() { return __builtin_popcount(0); }
])],
[
AC_MSG_RESULT(yes)
AC_DEFINE(USE_BUILTIN_POPCOUNT, 1, Use __builtin_popcount.)
@@ -199,12 +198,12 @@ AC_DEFUN([TORRENT_CHECK_POPCOUNT], [
AC_DEFUN([TORRENT_CHECK_CACHELINE], [
AC_MSG_CHECKING(for cacheline)
AC_COMPILE_IFELSE(
[[#include <stdlib.h>
AC_COMPILE_IFELSE([AC_LANG_SOURCE([
#include <stdlib.h>
#include <linux/cache.h>
void* vptr __cacheline_aligned;
void f() { posix_memalign(&vptr, SMP_CACHE_BYTES, 42); }
]],
])],
[
AC_MSG_RESULT(found builtin)
dnl AC_DEFINE(LT_SMP_CACHE_BYTES, SMP_CACHE_BYTES, Largest L1 cache size we know of, should work on all archs.)
@@ -224,10 +223,10 @@ dnl Need to fix this so that it uses the stuff defined by the system.
AC_DEFUN([TORRENT_CHECK_EXECINFO], [
AC_MSG_CHECKING(for execinfo.h)
AC_RUN_IFELSE(
[[#include <execinfo.h>
AC_RUN_IFELSE([AC_LANG_SOURCE([
#include <execinfo.h>
int main() { backtrace((void**)0, 0); backtrace_symbols((char**)0, 0); return 0;}
]],
])],
[
AC_MSG_RESULT(yes)
AC_DEFINE(USE_EXECINFO, 1, Use execinfo.h)
@@ -239,16 +238,16 @@ AC_DEFUN([TORRENT_CHECK_EXECINFO], [
AC_DEFUN([TORRENT_CHECK_ALIGNED], [
AC_MSG_CHECKING(the byte alignment)
AC_RUN_IFELSE(
[[#include <inttypes.h>
AC_RUN_IFELSE([AC_LANG_SOURCE([
#include <inttypes.h>
int main() {
char buf[8] = { 0, 0, 0, 0, 1, 0, 0, 0 };
char buf@<:@8@:>@ = { 0, 0, 0, 0, 1, 0, 0, 0 };
int i;
for (i = 1; i < 4; ++i)
if (*(uint32_t*)(buf + i) == 0) return -1;
return 0;
}
]],
])],
[
AC_MSG_RESULT(none needed)
], [
@@ -260,7 +259,7 @@ AC_DEFUN([TORRENT_CHECK_ALIGNED], [
AC_DEFUN([TORRENT_ENABLE_ALIGNED], [
AC_ARG_ENABLE(aligned,
[ --enable-aligned enable alignment safe code [[default=check]]],
AC_HELP_STRING([--enable-aligned], [enable alignment safe code [[default=check]]]),
[
if test "$enableval" = "yes"; then
AC_DEFINE(USE_ALIGNED, 1, Require byte alignment)
@@ -271,9 +270,40 @@ AC_DEFUN([TORRENT_ENABLE_ALIGNED], [
])
AC_DEFUN([TORRENT_DISABLE_INSTRUMENTATION], [
AC_MSG_CHECKING([if instrumentation should be included])
AC_ARG_ENABLE(instrumentation,
AC_HELP_STRING([--disable-instrumentation], [disable instrumentation [[default=enabled]]]),
[
if test "$enableval" = "yes"; then
AC_DEFINE(LT_INSTRUMENTATION, 1, enable instrumentation)
AC_MSG_RESULT(yes)
else
AC_MSG_RESULT(no)
fi
],[
AC_DEFINE(LT_INSTRUMENTATION, 1, enable instrumentation)
AC_MSG_RESULT(yes)
])
])
AC_DEFUN([TORRENT_ENABLE_INTERRUPT_SOCKET], [
AC_ARG_ENABLE(interrupt-socket,
AC_HELP_STRING([--enable-interrupt-socket], [enable interrupt socket [[default=no]]]),
[
if test "$enableval" = "yes"; then
AC_DEFINE(USE_INTERRUPT_SOCKET, 1, Use interrupt socket instead of pthread_kill)
fi
]
)
])
AC_DEFUN([TORRENT_DISABLE_IPV6], [
AC_ARG_ENABLE(ipv6,
[ --enable-ipv6 disable ipv6 [[default=no]]],
AC_HELP_STRING([--enable-ipv6], [enable ipv6 [[default=no]]]),
[
if test "$enableval" = "yes"; then
AC_DEFINE(RAK_USE_INET6, 1, enable ipv6 stuff)
@@ -283,7 +313,7 @@ AC_DEFUN([TORRENT_DISABLE_IPV6], [
AC_DEFUN([TORRENT_ENABLE_TR1], [
AC_ARG_ENABLE(std_tr1,
[ --disable-std_tr1 disable check for support for TR1 [[default=enable]]],
AC_HELP_STRING([--disable-std_tr1], [disable check for support for TR1 [[default=enable]]]),
[
if test "$enableval" = "yes"; then
TORRENT_CHECK_TR1()
@@ -295,3 +325,19 @@ AC_DEFUN([TORRENT_ENABLE_TR1], [
TORRENT_CHECK_TR1()
])
])
AC_DEFUN([TORRENT_ENABLE_CXX11], [
AC_ARG_ENABLE(std_c++11,
AC_HELP_STRING([--disable-std_c++11], [disable check for support for C++11 [[default=enable]]]),
[
if test "$enableval" = "yes"; then
TORRENT_CHECK_CXX11()
else
AC_MSG_CHECKING(for C++11 support)
AC_MSG_RESULT(disabled)
fi
],[
TORRENT_CHECK_CXX11()
]
)
])
+3 -4
View File
@@ -34,8 +34,6 @@ libsub_root_a_SOURCES = \
signal_handler.h \
thread_base.cc \
thread_base.h \
thread_main.cc \
thread_main.h \
thread_worker.cc \
thread_worker.h
@@ -48,9 +46,10 @@ rtorrent_LDADD = \
display/libsub_display.a \
input/libsub_input.a \
rpc/libsub_rpc.a \
utils/libsub_utils.a
utils/libsub_utils.a \
@PTHREAD_LIBS@
rtorrent_SOURCES = \
main.cc
INCLUDES = -I$(srcdir) -I$(top_srcdir)
AM_CPPFLAGS = -I$(srcdir) -I$(top_srcdir)
+153 -145
View File
@@ -138,10 +138,10 @@ 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)
// control->core()->push_log("create_link failed: " + std::string(rak::error_number::current().c_str()));
// control->core()->push_log("create_link failed: " + std::string(rak::error_number::current().c_str()) + " to " + target);
; // Disabled.
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());
}
break;
case 1:
@@ -150,9 +150,10 @@ apply_d_change_link(core::Download* download, const torrent::Object::list_type&
rak::error_number::clear_global();
if (!fileStat.update_link(link) || !fileStat.is_link() ||
unlink(link.c_str()) == -1)
; // control->core()->push_log("delete_link failed: " + std::string(rak::error_number::current().c_str()));
unlink(link.c_str()) == -1){
lt_log_print(torrent::LOG_TORRENT_WARN, "delete_link failed: %s",
rak::error_number::current().c_str());
}
break;
}
default:
@@ -283,15 +284,6 @@ retrieve_d_bitfield(core::Download* download) {
return torrent::Object(rak::transform_hex(bitField->begin(), bitField->end()));
}
// Just a helper function atm.
torrent::Object
cmd_d_initialize_logs(core::Download* download) {
download->info()->signal_network_log().connect(sigc::mem_fun(control->core(), &core::Manager::push_log_complete));
download->info()->signal_storage_error().connect(sigc::mem_fun(control->core(), &core::Manager::push_log_complete));
return torrent::Object();
}
struct call_add_d_peer_t {
call_add_d_peer_t(core::Download* d, int port) : m_download(d), m_port(port) { }
@@ -329,6 +321,22 @@ apply_d_add_peer(core::Download* download, const std::string& arg) {
torrent::connection_manager()->resolver()(host, (int)rak::socket_address::pf_inet, SOCK_STREAM, call_add_d_peer_t(download, port));
}
torrent::Object
d_chunks_seen(core::Download* download) {
const uint8_t* seen = download->download()->chunks_seen();
if (seen == NULL)
return std::string();
uint32_t size = download->download()->file_list()->size_chunks();
std::string result;
result.resize(size * 2);
rak::transform_hex((const char*)seen, (const char*)seen + size, result.begin());
return result;
}
torrent::Object
f_multicall(core::Download* download, const torrent::Object::list_type& args) {
if (args.empty())
@@ -348,7 +356,7 @@ f_multicall(core::Download* download, const torrent::Object::list_type& args) {
if (args.front().is_list())
std::transform(args.front().as_list().begin(), args.front().as_list().end(),
std::back_inserter(regex_list),
std::bind(&torrent::Object::as_string_c, std::placeholders::_1));
tr1::bind(&torrent::Object::as_string_c, tr1::placeholders::_1));
else if (args.front().is_string() && !args.front().as_string().empty())
regex_list.push_back(args.front().as_string());
else
@@ -357,12 +365,12 @@ f_multicall(core::Download* download, const torrent::Object::list_type& args) {
for (torrent::FileList::const_iterator itr = download->file_list()->begin(), last = download->file_list()->end(); itr != last; itr++) {
if (use_regex &&
std::find_if(regex_list.begin(), regex_list.end(),
std::bind(&rak::regex::operator(), std::placeholders::_1, (*itr)->path()->as_string())) == regex_list.end())
tr1::bind(&rak::regex::operator(), tr1::placeholders::_1, (*itr)->path()->as_string())) == regex_list.end())
continue;
torrent::Object::list_type& row = result.insert(result.end(), torrent::Object::create_list())->as_list();
for (torrent::Object::list_const_iterator cItr = ++args.begin(), cLast = args.end(); cItr != args.end(); cItr++) {
for (torrent::Object::list_const_iterator cItr = ++args.begin(); cItr != args.end(); cItr++) {
const std::string& cmd = cItr->as_string();
row.push_back(rpc::parse_command(rpc::make_target(*itr), cmd.c_str(), cmd.c_str() + cmd.size()).first);
}
@@ -387,7 +395,7 @@ t_multicall(core::Download* download, const torrent::Object::list_type& args) {
for (int itr = 0, last = download->tracker_list()->size(); itr != last; itr++) {
torrent::Object::list_type& row = result.insert(result.end(), torrent::Object::create_list())->as_list();
for (torrent::Object::list_const_iterator cItr = ++args.begin(), cLast = args.end(); cItr != args.end(); cItr++) {
for (torrent::Object::list_const_iterator cItr = ++args.begin(); cItr != args.end(); cItr++) {
const std::string& cmd = cItr->as_string();
torrent::Tracker* t = download->tracker_list()->at(itr);
@@ -415,7 +423,7 @@ p_multicall(core::Download* download, const torrent::Object::list_type& args) {
itr != last; itr++) {
torrent::Object::list_type& row = result.insert(result.end(), torrent::Object::create_list())->as_list();
for (torrent::Object::list_const_iterator cItr = ++args.begin(), cLast = args.end(); cItr != args.end(); cItr++) {
for (torrent::Object::list_const_iterator cItr = ++args.begin(); cItr != args.end(); cItr++) {
const std::string& cmd = cItr->as_string();
row.push_back(rpc::parse_command(rpc::make_target(*itr), cmd.c_str(), cmd.c_str() + cmd.size()).first);
@@ -573,52 +581,52 @@ d_list_remove(core::Download* download, const torrent::Object& rawArgs, const ch
return torrent::Object();
}
#define CMD2_ON_INFO(func) std::bind(&torrent::DownloadInfo::func, std::bind(&core::Download::info, std::placeholders::_1))
#define CMD2_ON_DATA(func) std::bind(&torrent::download_data::func, std::bind(&core::Download::data, std::placeholders::_1))
#define CMD2_ON_DL(func) std::bind(&torrent::Download::func, std::bind(&core::Download::download, std::placeholders::_1))
#define CMD2_ON_FL(func) std::bind(&torrent::FileList::func, std::bind(&core::Download::file_list, std::placeholders::_1))
#define CMD2_ON_INFO(func) tr1::bind(&torrent::DownloadInfo::func, tr1::bind(&core::Download::info, tr1::placeholders::_1))
#define CMD2_ON_DATA(func) tr1::bind(&torrent::download_data::func, tr1::bind(&core::Download::data, tr1::placeholders::_1))
#define CMD2_ON_DL(func) tr1::bind(&torrent::Download::func, tr1::bind(&core::Download::download, tr1::placeholders::_1))
#define CMD2_ON_FL(func) tr1::bind(&torrent::FileList::func, tr1::bind(&core::Download::file_list, tr1::placeholders::_1))
#define CMD2_BIND_DL std::bind(&core::Download::download, std::placeholders::_1)
#define CMD2_BIND_CL std::bind(&core::Download::connection_list, std::placeholders::_1)
#define CMD2_BIND_FL std::bind(&core::Download::file_list, std::placeholders::_1)
#define CMD2_BIND_PL std::bind(&core::Download::c_peer_list, std::placeholders::_1)
#define CMD2_BIND_TL std::bind(&core::Download::tracker_list, std::placeholders::_1)
#define CMD2_BIND_TC std::bind(&core::Download::tracker_controller, std::placeholders::_1)
#define CMD2_BIND_DL tr1::bind(&core::Download::download, tr1::placeholders::_1)
#define CMD2_BIND_CL tr1::bind(&core::Download::connection_list, tr1::placeholders::_1)
#define CMD2_BIND_FL tr1::bind(&core::Download::file_list, tr1::placeholders::_1)
#define CMD2_BIND_PL tr1::bind(&core::Download::c_peer_list, tr1::placeholders::_1)
#define CMD2_BIND_TL tr1::bind(&core::Download::tracker_list, tr1::placeholders::_1)
#define CMD2_BIND_TC tr1::bind(&core::Download::tracker_controller, tr1::placeholders::_1)
#define CMD2_BIND_INFO std::bind(&core::Download::info, std::placeholders::_1)
#define CMD2_BIND_DATA std::bind(&core::Download::data, std::placeholders::_1)
#define CMD2_BIND_INFO tr1::bind(&core::Download::info, tr1::placeholders::_1)
#define CMD2_BIND_DATA tr1::bind(&core::Download::data, tr1::placeholders::_1)
#define CMD2_DL_VAR_VALUE(key, first_key, second_key) \
CMD2_DL(key, std::bind(&download_get_variable, std::placeholders::_1, first_key, second_key)); \
CMD2_DL_VALUE_P(key ".set", std::bind(&download_set_variable_value, \
std::placeholders::_1, std::placeholders::_2, \
CMD2_DL(key, tr1::bind(&download_get_variable, tr1::placeholders::_1, first_key, second_key)); \
CMD2_DL_VALUE_P(key ".set", tr1::bind(&download_set_variable_value, \
tr1::placeholders::_1, tr1::placeholders::_2, \
first_key, second_key));
#define CMD2_DL_VAR_VALUE_PUBLIC(key, first_key, second_key) \
CMD2_DL(key, std::bind(&download_get_variable, std::placeholders::_1, first_key, second_key)); \
CMD2_DL_VALUE(key ".set", std::bind(&download_set_variable_value, \
std::placeholders::_1, std::placeholders::_2, \
CMD2_DL(key, tr1::bind(&download_get_variable, tr1::placeholders::_1, first_key, second_key)); \
CMD2_DL_VALUE(key ".set", tr1::bind(&download_set_variable_value, \
tr1::placeholders::_1, tr1::placeholders::_2, \
first_key, second_key));
#define CMD2_DL_TIMESTAMP(key, first_key, second_key) \
CMD2_DL(key, std::bind(&download_get_variable, std::placeholders::_1, first_key, second_key)); \
CMD2_DL_VALUE_P(key ".set", std::bind(&download_set_variable_value, \
std::placeholders::_1, std::placeholders::_2, \
CMD2_DL(key, tr1::bind(&download_get_variable, tr1::placeholders::_1, first_key, second_key)); \
CMD2_DL_VALUE_P(key ".set", tr1::bind(&download_set_variable_value, \
tr1::placeholders::_1, tr1::placeholders::_2, \
first_key, second_key)); \
CMD2_DL_VALUE_P(key ".set_if_z", std::bind(&download_set_variable_value_ifz, \
std::placeholders::_1, std::placeholders::_2, \
CMD2_DL_VALUE_P(key ".set_if_z", tr1::bind(&download_set_variable_value_ifz, \
tr1::placeholders::_1, tr1::placeholders::_2, \
first_key, second_key)); \
#define CMD2_DL_VAR_STRING(key, first_key, second_key) \
CMD2_DL(key, std::bind(&download_get_variable, std::placeholders::_1, first_key, second_key)); \
CMD2_DL_STRING_P(key ".set", std::bind(&download_set_variable_string, \
std::placeholders::_1, std::placeholders::_2, \
CMD2_DL(key, tr1::bind(&download_get_variable, tr1::placeholders::_1, first_key, second_key)); \
CMD2_DL_STRING_P(key ".set", tr1::bind(&download_set_variable_string, \
tr1::placeholders::_1, tr1::placeholders::_2, \
first_key, second_key));
#define CMD2_DL_VAR_STRING_PUBLIC(key, first_key, second_key) \
CMD2_DL(key, std::bind(&download_get_variable, std::placeholders::_1, first_key, second_key)); \
CMD2_DL_STRING(key ".set", std::bind(&download_set_variable_string, \
std::placeholders::_1, std::placeholders::_2, \
CMD2_DL(key, tr1::bind(&download_get_variable, tr1::placeholders::_1, first_key, second_key)); \
CMD2_DL_STRING(key ".set", tr1::bind(&download_set_variable_string, \
tr1::placeholders::_1, tr1::placeholders::_2, \
first_key, second_key));
int64_t cg_d_group(core::Download* download);
@@ -627,12 +635,12 @@ void cg_d_group_set(core::Download* download, const torrent::Objec
void
initialize_command_download() {
CMD2_DL("d.hash", std::bind(&rak::transform_hex_str<torrent::HashString>, CMD2_ON_INFO(hash)));
CMD2_DL("d.local_id", std::bind(&rak::transform_hex_str<torrent::HashString>, CMD2_ON_INFO(local_id)));
CMD2_DL("d.local_id_html", std::bind(&rak::copy_escape_html_str<torrent::HashString>, CMD2_ON_INFO(local_id)));
CMD2_DL("d.bitfield", std::bind(&retrieve_d_bitfield, std::placeholders::_1));
CMD2_DL("d.base_path", std::bind(&retrieve_d_base_path, std::placeholders::_1));
CMD2_DL("d.base_filename", std::bind(&retrieve_d_base_filename, std::placeholders::_1));
CMD2_DL("d.hash", tr1::bind(&rak::transform_hex_str<torrent::HashString>, CMD2_ON_INFO(hash)));
CMD2_DL("d.local_id", tr1::bind(&rak::transform_hex_str<torrent::HashString>, CMD2_ON_INFO(local_id)));
CMD2_DL("d.local_id_html", tr1::bind(&rak::copy_escape_html_str<torrent::HashString>, CMD2_ON_INFO(local_id)));
CMD2_DL("d.bitfield", tr1::bind(&retrieve_d_bitfield, tr1::placeholders::_1));
CMD2_DL("d.base_path", tr1::bind(&retrieve_d_base_path, tr1::placeholders::_1));
CMD2_DL("d.base_filename", tr1::bind(&retrieve_d_base_filename, tr1::placeholders::_1));
CMD2_DL("d.name", CMD2_ON_INFO(name));
CMD2_DL("d.creation_date", CMD2_ON_INFO(creation_date));
@@ -642,19 +650,19 @@ initialize_command_download() {
// Network related:
//
CMD2_DL ("d.up.rate", std::bind(&torrent::Rate::rate, CMD2_ON_INFO(up_rate)));
CMD2_DL ("d.up.total", std::bind(&torrent::Rate::total, CMD2_ON_INFO(up_rate)));
CMD2_DL ("d.down.rate", std::bind(&torrent::Rate::rate, CMD2_ON_INFO(down_rate)));
CMD2_DL ("d.down.total", std::bind(&torrent::Rate::total, CMD2_ON_INFO(down_rate)));
CMD2_DL ("d.skip.rate", std::bind(&torrent::Rate::rate, CMD2_ON_INFO(skip_rate)));
CMD2_DL ("d.skip.total", std::bind(&torrent::Rate::total, CMD2_ON_INFO(skip_rate)));
CMD2_DL ("d.up.rate", tr1::bind(&torrent::Rate::rate, CMD2_ON_INFO(up_rate)));
CMD2_DL ("d.up.total", tr1::bind(&torrent::Rate::total, CMD2_ON_INFO(up_rate)));
CMD2_DL ("d.down.rate", tr1::bind(&torrent::Rate::rate, CMD2_ON_INFO(down_rate)));
CMD2_DL ("d.down.total", tr1::bind(&torrent::Rate::total, CMD2_ON_INFO(down_rate)));
CMD2_DL ("d.skip.rate", tr1::bind(&torrent::Rate::rate, CMD2_ON_INFO(skip_rate)));
CMD2_DL ("d.skip.total", tr1::bind(&torrent::Rate::total, CMD2_ON_INFO(skip_rate)));
CMD2_DL ("d.peer_exchange", CMD2_ON_INFO(is_pex_enabled));
CMD2_DL_VALUE_V ("d.peer_exchange.set", std::bind(&torrent::Download::set_pex_enabled, CMD2_BIND_DL, std::placeholders::_2));
CMD2_DL_VALUE_V ("d.peer_exchange.set", tr1::bind(&torrent::Download::set_pex_enabled, CMD2_BIND_DL, tr1::placeholders::_2));
CMD2_DL_LIST ("d.create_link", std::bind(&apply_d_change_link, std::placeholders::_1, std::placeholders::_2, 0));
CMD2_DL_LIST ("d.delete_link", std::bind(&apply_d_change_link, std::placeholders::_1, std::placeholders::_2, 1));
CMD2_DL ("d.delete_tied", std::bind(&apply_d_delete_tied, std::placeholders::_1));
CMD2_DL_LIST ("d.create_link", tr1::bind(&apply_d_change_link, tr1::placeholders::_1, tr1::placeholders::_2, 0));
CMD2_DL_LIST ("d.delete_link", tr1::bind(&apply_d_change_link, tr1::placeholders::_1, tr1::placeholders::_2, 1));
CMD2_DL ("d.delete_tied", tr1::bind(&apply_d_delete_tied, tr1::placeholders::_1));
CMD2_FUNC_SINGLE("d.start", "d.hashing_failed.set=0 ;view.set_visible=started");
CMD2_FUNC_SINGLE("d.stop", "view.set_visible=stopped");
@@ -668,36 +676,36 @@ initialize_command_download() {
CMD2_DL ("d.is_open", CMD2_ON_INFO(is_open));
CMD2_DL ("d.is_active", CMD2_ON_INFO(is_active));
CMD2_DL ("d.is_hash_checked", std::bind(&torrent::Download::is_hash_checked, CMD2_BIND_DL));
CMD2_DL ("d.is_hash_checking", std::bind(&torrent::Download::is_hash_checking, CMD2_BIND_DL));
CMD2_DL ("d.is_multi_file", std::bind(&torrent::FileList::is_multi_file, CMD2_BIND_FL));
CMD2_DL ("d.is_hash_checked", tr1::bind(&torrent::Download::is_hash_checked, CMD2_BIND_DL));
CMD2_DL ("d.is_hash_checking", tr1::bind(&torrent::Download::is_hash_checking, CMD2_BIND_DL));
CMD2_DL ("d.is_multi_file", tr1::bind(&torrent::FileList::is_multi_file, CMD2_BIND_FL));
CMD2_DL ("d.is_private", CMD2_ON_INFO(is_private));
CMD2_DL ("d.is_pex_active", CMD2_ON_INFO(is_pex_active));
CMD2_DL ("d.is_partially_done", CMD2_ON_DATA(is_partially_done));
CMD2_DL ("d.is_not_partially_done", CMD2_ON_DATA(is_not_partially_done));
CMD2_DL_V ("d.resume", std::bind(&core::DownloadList::resume_default, control->core()->download_list(), std::placeholders::_1));
CMD2_DL_V ("d.pause", std::bind(&core::DownloadList::pause_default, control->core()->download_list(), std::placeholders::_1));
CMD2_DL_V ("d.open", std::bind(&core::DownloadList::open_throw, control->core()->download_list(), std::placeholders::_1));
CMD2_DL_V ("d.close", std::bind(&core::DownloadList::close_throw, control->core()->download_list(), std::placeholders::_1));
CMD2_DL_V ("d.close.directly", std::bind(&core::DownloadList::close_directly, control->core()->download_list(), std::placeholders::_1));
CMD2_DL_V ("d.erase", std::bind(&core::DownloadList::erase_ptr, control->core()->download_list(), std::placeholders::_1));
CMD2_DL_V ("d.check_hash", std::bind(&core::DownloadList::check_hash, control->core()->download_list(), std::placeholders::_1));
CMD2_DL_V ("d.resume", tr1::bind(&core::DownloadList::resume_default, control->core()->download_list(), tr1::placeholders::_1));
CMD2_DL_V ("d.pause", tr1::bind(&core::DownloadList::pause_default, control->core()->download_list(), tr1::placeholders::_1));
CMD2_DL_V ("d.open", tr1::bind(&core::DownloadList::open_throw, control->core()->download_list(), tr1::placeholders::_1));
CMD2_DL_V ("d.close", tr1::bind(&core::DownloadList::close_throw, control->core()->download_list(), tr1::placeholders::_1));
CMD2_DL_V ("d.close.directly", tr1::bind(&core::DownloadList::close_directly, control->core()->download_list(), tr1::placeholders::_1));
CMD2_DL_V ("d.erase", tr1::bind(&core::DownloadList::erase_ptr, control->core()->download_list(), tr1::placeholders::_1));
CMD2_DL_V ("d.check_hash", tr1::bind(&core::DownloadList::check_hash, control->core()->download_list(), tr1::placeholders::_1));
CMD2_DL ("d.save_resume", std::bind(&core::DownloadStore::save_resume, control->core()->download_store(), std::placeholders::_1));
CMD2_DL ("d.save_full_session", std::bind(&core::DownloadStore::save_full, control->core()->download_store(), std::placeholders::_1));
CMD2_DL ("d.save_resume", tr1::bind(&core::DownloadStore::save_resume, control->core()->download_store(), tr1::placeholders::_1));
CMD2_DL ("d.save_full_session", tr1::bind(&core::DownloadStore::save_full, control->core()->download_store(), tr1::placeholders::_1));
CMD2_DL_V ("d.update_priorities", CMD2_ON_DL(update_priorities));
CMD2_DL_STRING_V("add_peer", std::bind(&apply_d_add_peer, std::placeholders::_1, std::placeholders::_2));
CMD2_DL_STRING_V("add_peer", tr1::bind(&apply_d_add_peer, tr1::placeholders::_1, tr1::placeholders::_2));
//
// Custom settings:
//
CMD2_DL_STRING("d.custom", std::bind(&retrieve_d_custom, std::placeholders::_1, std::placeholders::_2));
CMD2_DL_STRING("d.custom_throw", std::bind(&retrieve_d_custom_throw, std::placeholders::_1, std::placeholders::_2));
CMD2_DL_LIST ("d.custom.set", std::bind(&apply_d_custom, std::placeholders::_1, std::placeholders::_2));
CMD2_DL_STRING("d.custom", tr1::bind(&retrieve_d_custom, tr1::placeholders::_1, tr1::placeholders::_2));
CMD2_DL_STRING("d.custom_throw", tr1::bind(&retrieve_d_custom_throw, tr1::placeholders::_1, tr1::placeholders::_2));
CMD2_DL_LIST ("d.custom.set", tr1::bind(&apply_d_custom, tr1::placeholders::_1, tr1::placeholders::_2));
CMD2_DL_VAR_STRING_PUBLIC("d.custom1", "rtorrent", "custom1");
CMD2_DL_VAR_STRING_PUBLIC("d.custom2", "rtorrent", "custom2");
@@ -742,68 +750,68 @@ initialize_command_download() {
CMD2_DL_TIMESTAMP("d.timestamp.started", "rtorrent", "timestamp.started");
CMD2_DL_TIMESTAMP("d.timestamp.finished", "rtorrent", "timestamp.finished");
CMD2_DL ("d.connection_current", std::bind(&torrent::option_as_string, torrent::OPTION_CONNECTION_TYPE, CMD2_ON_DL(connection_type)));
CMD2_DL_STRING("d.connection_current.set", std::bind(&apply_d_connection_type, std::placeholders::_1, std::placeholders::_2));
CMD2_DL ("d.connection_current", tr1::bind(&torrent::option_as_string, torrent::OPTION_CONNECTION_TYPE, CMD2_ON_DL(connection_type)));
CMD2_DL_STRING("d.connection_current.set", tr1::bind(&apply_d_connection_type, tr1::placeholders::_1, tr1::placeholders::_2));
CMD2_DL_VAR_STRING("d.connection_leech", "rtorrent", "connection_leech");
CMD2_DL_VAR_STRING("d.connection_seed", "rtorrent", "connection_seed");
CMD2_DL ("d.up.choke_heuristics", std::bind(&torrent::option_as_string, torrent::OPTION_CHOKE_HEURISTICS, CMD2_ON_DL(upload_choke_heuristic)));
CMD2_DL_STRING("d.up.choke_heuristics.set", std::bind(&apply_d_choke_heuristics, std::placeholders::_1, std::placeholders::_2, false));
CMD2_DL ("d.down.choke_heuristics", std::bind(&torrent::option_as_string, torrent::OPTION_CHOKE_HEURISTICS, CMD2_ON_DL(download_choke_heuristic)));
CMD2_DL_STRING("d.down.choke_heuristics.set", std::bind(&apply_d_choke_heuristics, std::placeholders::_1, std::placeholders::_2, true));
CMD2_DL ("d.up.choke_heuristics", tr1::bind(&torrent::option_as_string, torrent::OPTION_CHOKE_HEURISTICS, CMD2_ON_DL(upload_choke_heuristic)));
CMD2_DL_STRING("d.up.choke_heuristics.set", tr1::bind(&apply_d_choke_heuristics, tr1::placeholders::_1, tr1::placeholders::_2, false));
CMD2_DL ("d.down.choke_heuristics", tr1::bind(&torrent::option_as_string, torrent::OPTION_CHOKE_HEURISTICS, CMD2_ON_DL(download_choke_heuristic)));
CMD2_DL_STRING("d.down.choke_heuristics.set", tr1::bind(&apply_d_choke_heuristics, tr1::placeholders::_1, tr1::placeholders::_2, true));
CMD2_DL_VAR_STRING("d.up.choke_heuristics.leech", "rtorrent", "choke_heuristics.up.leech");
CMD2_DL_VAR_STRING("d.up.choke_heuristics.seed", "rtorrent", "choke_heuristics.up.seed");
CMD2_DL_VAR_STRING("d.down.choke_heuristics.leech", "rtorrent", "choke_heuristics.down.leech");
CMD2_DL_VAR_STRING("d.down.choke_heuristics.seed", "rtorrent", "choke_heuristics.down.seed");
CMD2_DL ("d.hashing_failed", std::bind(&core::Download::is_hash_failed, std::placeholders::_1));
CMD2_DL_VALUE_V ("d.hashing_failed.set", std::bind(&core::Download::set_hash_failed, std::placeholders::_1, std::placeholders::_2));
CMD2_DL ("d.hashing_failed", tr1::bind(&core::Download::is_hash_failed, tr1::placeholders::_1));
CMD2_DL_VALUE_V ("d.hashing_failed.set", tr1::bind(&core::Download::set_hash_failed, tr1::placeholders::_1, tr1::placeholders::_2));
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, std::placeholders::_1, std::placeholders::_2, "rtorrent", "views"));
CMD2_DL ("d.views.push_back_unique", std::bind(&d_list_push_back_unique, std::placeholders::_1, std::placeholders::_2, "rtorrent", "views"));
CMD2_DL ("d.views", tr1::bind(&download_get_variable, tr1::placeholders::_1, "rtorrent", "views"));
CMD2_DL ("d.views.has", tr1::bind(&d_list_has, tr1::placeholders::_1, tr1::placeholders::_2, "rtorrent", "views"));
CMD2_DL ("d.views.remove", tr1::bind(&d_list_remove, tr1::placeholders::_1, tr1::placeholders::_2, "rtorrent", "views"));
CMD2_DL ("d.views.push_back", tr1::bind(&d_list_push_back, tr1::placeholders::_1, tr1::placeholders::_2, "rtorrent", "views"));
CMD2_DL ("d.views.push_back_unique", tr1::bind(&d_list_push_back_unique, tr1::placeholders::_1, tr1::placeholders::_2, "rtorrent", "views"));
// This command really needs to be improved, so we have proper
// logging support.
CMD2_DL ("d.message", std::bind(&core::Download::message, std::placeholders::_1));
CMD2_DL_STRING_V("d.message.set", std::bind(&core::Download::set_message, std::placeholders::_1, std::placeholders::_2));
CMD2_DL ("d.message", tr1::bind(&core::Download::message, tr1::placeholders::_1));
CMD2_DL_STRING_V("d.message.set", tr1::bind(&core::Download::set_message, tr1::placeholders::_1, tr1::placeholders::_2));
CMD2_DL ("d.max_file_size", CMD2_ON_FL(max_file_size));
CMD2_DL_VALUE_V ("d.max_file_size.set", std::bind(&torrent::FileList::set_max_file_size, CMD2_BIND_FL, std::placeholders::_2));
CMD2_DL_VALUE_V ("d.max_file_size.set", tr1::bind(&torrent::FileList::set_max_file_size, CMD2_BIND_FL, tr1::placeholders::_2));
CMD2_DL ("d.peers_min", std::bind(&torrent::ConnectionList::min_size, CMD2_BIND_CL));
CMD2_DL_VALUE_V ("d.peers_min.set", std::bind(&torrent::ConnectionList::set_min_size, CMD2_BIND_CL, std::placeholders::_2));
CMD2_DL ("d.peers_max", std::bind(&torrent::ConnectionList::max_size, CMD2_BIND_CL));
CMD2_DL_VALUE_V ("d.peers_max.set", std::bind(&torrent::ConnectionList::set_max_size, CMD2_BIND_CL, std::placeholders::_2));
CMD2_DL ("d.uploads_max", std::bind(&torrent::Download::uploads_max, CMD2_BIND_DL));
CMD2_DL_VALUE_V ("d.uploads_max.set", std::bind(&torrent::Download::set_uploads_max, CMD2_BIND_DL, std::placeholders::_2));
CMD2_DL ("d.uploads_min", std::bind(&torrent::Download::uploads_min, CMD2_BIND_DL));
CMD2_DL_VALUE_V ("d.uploads_min.set", std::bind(&torrent::Download::set_uploads_min, CMD2_BIND_DL, std::placeholders::_2));
CMD2_DL ("d.downloads_max", std::bind(&torrent::Download::downloads_max, CMD2_BIND_DL));
CMD2_DL_VALUE_V ("d.downloads_max.set", std::bind(&torrent::Download::set_downloads_max, CMD2_BIND_DL, std::placeholders::_2));
CMD2_DL ("d.downloads_min", std::bind(&torrent::Download::downloads_min, CMD2_BIND_DL));
CMD2_DL_VALUE_V ("d.downloads_min.set", std::bind(&torrent::Download::set_downloads_min, CMD2_BIND_DL, std::placeholders::_2));
CMD2_DL ("d.peers_connected", std::bind(&torrent::ConnectionList::size, CMD2_BIND_CL));
CMD2_DL ("d.peers_not_connected", std::bind(&torrent::PeerList::available_list_size, CMD2_BIND_PL));
CMD2_DL ("d.peers_min", tr1::bind(&torrent::ConnectionList::min_size, CMD2_BIND_CL));
CMD2_DL_VALUE_V ("d.peers_min.set", tr1::bind(&torrent::ConnectionList::set_min_size, CMD2_BIND_CL, tr1::placeholders::_2));
CMD2_DL ("d.peers_max", tr1::bind(&torrent::ConnectionList::max_size, CMD2_BIND_CL));
CMD2_DL_VALUE_V ("d.peers_max.set", tr1::bind(&torrent::ConnectionList::set_max_size, CMD2_BIND_CL, tr1::placeholders::_2));
CMD2_DL ("d.uploads_max", tr1::bind(&torrent::Download::uploads_max, CMD2_BIND_DL));
CMD2_DL_VALUE_V ("d.uploads_max.set", tr1::bind(&torrent::Download::set_uploads_max, CMD2_BIND_DL, tr1::placeholders::_2));
CMD2_DL ("d.uploads_min", tr1::bind(&torrent::Download::uploads_min, CMD2_BIND_DL));
CMD2_DL_VALUE_V ("d.uploads_min.set", tr1::bind(&torrent::Download::set_uploads_min, CMD2_BIND_DL, tr1::placeholders::_2));
CMD2_DL ("d.downloads_max", tr1::bind(&torrent::Download::downloads_max, CMD2_BIND_DL));
CMD2_DL_VALUE_V ("d.downloads_max.set", tr1::bind(&torrent::Download::set_downloads_max, CMD2_BIND_DL, tr1::placeholders::_2));
CMD2_DL ("d.downloads_min", tr1::bind(&torrent::Download::downloads_min, CMD2_BIND_DL));
CMD2_DL_VALUE_V ("d.downloads_min.set", tr1::bind(&torrent::Download::set_downloads_min, CMD2_BIND_DL, tr1::placeholders::_2));
CMD2_DL ("d.peers_connected", tr1::bind(&torrent::ConnectionList::size, CMD2_BIND_CL));
CMD2_DL ("d.peers_not_connected", tr1::bind(&torrent::PeerList::available_list_size, CMD2_BIND_PL));
CMD2_DL ("d.peers_complete", CMD2_ON_DL(peers_complete));
CMD2_DL ("d.peers_accounted", CMD2_ON_DL(peers_accounted));
CMD2_DL_V ("d.disconnect.seeders", std::bind(&torrent::ConnectionList::erase_seeders, CMD2_BIND_CL));
CMD2_DL_V ("d.disconnect.seeders", tr1::bind(&torrent::ConnectionList::erase_seeders, CMD2_BIND_CL));
CMD2_DL ("d.accepting_seeders", CMD2_ON_INFO(is_accepting_seeders));
CMD2_DL_V ("d.accepting_seeders.enable", std::bind(&torrent::DownloadInfo::public_set_flags, CMD2_BIND_INFO, torrent::DownloadInfo::flag_accepting_seeders));
CMD2_DL_V ("d.accepting_seeders.disable", std::bind(&torrent::DownloadInfo::public_unset_flags, CMD2_BIND_INFO, torrent::DownloadInfo::flag_accepting_seeders));
CMD2_DL_V ("d.accepting_seeders.enable", tr1::bind(&torrent::DownloadInfo::public_set_flags, CMD2_BIND_INFO, torrent::DownloadInfo::flag_accepting_seeders));
CMD2_DL_V ("d.accepting_seeders.disable", tr1::bind(&torrent::DownloadInfo::public_unset_flags, CMD2_BIND_INFO, torrent::DownloadInfo::flag_accepting_seeders));
CMD2_DL ("d.throttle_name", std::bind(&download_get_variable, std::placeholders::_1, "rtorrent", "throttle_name"));
CMD2_DL_STRING_V("d.throttle_name.set", std::bind(&core::Download::set_throttle_name, std::placeholders::_1, std::placeholders::_2));
CMD2_DL ("d.throttle_name", tr1::bind(&download_get_variable, tr1::placeholders::_1, "rtorrent", "throttle_name"));
CMD2_DL_STRING_V("d.throttle_name.set", tr1::bind(&core::Download::set_throttle_name, tr1::placeholders::_1, tr1::placeholders::_2));
CMD2_DL ("d.bytes_done", CMD2_ON_DL(bytes_done));
CMD2_DL ("d.ratio", std::bind(&retrieve_d_ratio, std::placeholders::_1));
CMD2_DL ("d.ratio", tr1::bind(&retrieve_d_ratio, tr1::placeholders::_1));
CMD2_DL ("d.chunks_hashed", CMD2_ON_DL(chunks_hashed));
CMD2_DL ("d.free_diskspace", CMD2_ON_FL(free_diskspace));
@@ -814,50 +822,50 @@ initialize_command_download() {
CMD2_DL ("d.size_pex", CMD2_ON_DL(size_pex));
CMD2_DL ("d.max_size_pex", CMD2_ON_DL(max_size_pex));
CMD2_DL ("d.chunks_seen", tr1::bind(&d_chunks_seen, tr1::placeholders::_1));
CMD2_DL ("d.completed_bytes", CMD2_ON_FL(completed_bytes));
CMD2_DL ("d.completed_chunks", CMD2_ON_FL(completed_chunks));
CMD2_DL ("d.left_bytes", CMD2_ON_FL(left_bytes));
CMD2_DL ("d.wanted_chunks", CMD2_ON_DATA(wanted_chunks));
CMD2_DL_V ("d.tracker_announce", std::bind(&torrent::Download::manual_request, CMD2_BIND_DL, false));
CMD2_DL ("d.tracker_numwant", std::bind(&torrent::TrackerList::numwant, CMD2_BIND_TL));
CMD2_DL_VALUE_V ("d.tracker_numwant.set", std::bind(&torrent::TrackerList::set_numwant, CMD2_BIND_TL, std::placeholders::_2));
CMD2_DL_V ("d.tracker_announce", tr1::bind(&torrent::Download::manual_request, CMD2_BIND_DL, false));
CMD2_DL ("d.tracker_numwant", tr1::bind(&torrent::TrackerList::numwant, CMD2_BIND_TL));
CMD2_DL_VALUE_V ("d.tracker_numwant.set", tr1::bind(&torrent::TrackerList::set_numwant, CMD2_BIND_TL, tr1::placeholders::_2));
// TODO: Deprecate 'd.tracker_focus'.
CMD2_DL ("d.tracker_focus", std::bind(&core::Download::tracker_list_size, std::placeholders::_1));
CMD2_DL ("d.tracker_size", std::bind(&core::Download::tracker_list_size, std::placeholders::_1));
CMD2_DL ("d.tracker_focus", tr1::bind(&core::Download::tracker_list_size, tr1::placeholders::_1));
CMD2_DL ("d.tracker_size", tr1::bind(&core::Download::tracker_list_size, tr1::placeholders::_1));
CMD2_DL_LIST ("d.tracker.insert", std::bind(&download_tracker_insert, std::placeholders::_1, std::placeholders::_2));
CMD2_DL_VALUE_V ("d.tracker.send_scrape", std::bind(&torrent::TrackerController::scrape_request, CMD2_BIND_TC, std::placeholders::_2));
CMD2_DL_LIST ("d.tracker.insert", tr1::bind(&download_tracker_insert, tr1::placeholders::_1, tr1::placeholders::_2));
CMD2_DL_VALUE_V ("d.tracker.send_scrape", tr1::bind(&torrent::TrackerController::scrape_request, CMD2_BIND_TC, tr1::placeholders::_2));
CMD2_DL ("d.directory", CMD2_ON_FL(root_dir));
CMD2_DL_STRING_V("d.directory.set", std::bind(&apply_d_directory, std::placeholders::_1, std::placeholders::_2));
CMD2_DL_STRING_V("d.directory.set", tr1::bind(&apply_d_directory, tr1::placeholders::_1, tr1::placeholders::_2));
CMD2_DL ("d.directory_base", CMD2_ON_FL(root_dir));
CMD2_DL_STRING_V("d.directory_base.set", std::bind(&core::Download::set_root_directory, std::placeholders::_1, std::placeholders::_2));
CMD2_DL_STRING_V("d.directory_base.set", tr1::bind(&core::Download::set_root_directory, tr1::placeholders::_1, tr1::placeholders::_2));
CMD2_DL ("d.priority", std::bind(&core::Download::priority, std::placeholders::_1));
CMD2_DL ("d.priority_str", std::bind(&retrieve_d_priority_str, std::placeholders::_1));
CMD2_DL_VALUE_V ("d.priority.set", std::bind(&core::Download::set_priority, std::placeholders::_1, std::placeholders::_2));
CMD2_DL ("d.priority", tr1::bind(&core::Download::priority, tr1::placeholders::_1));
CMD2_DL ("d.priority_str", tr1::bind(&retrieve_d_priority_str, tr1::placeholders::_1));
CMD2_DL_VALUE_V ("d.priority.set", tr1::bind(&core::Download::set_priority, tr1::placeholders::_1, tr1::placeholders::_2));
// CMD2_DL ("d.group", std::bind(&torrent::resource_manager_entry::group,
// std::bind(&torrent::ResourceManager::entry_at, torrent::resource_manager(),
// std::bind(&core::Download::main, std::placeholders::_1))));
// CMD2_DL ("d.group", tr1::bind(&torrent::resource_manager_entry::group,
// tr1::bind(&torrent::ResourceManager::entry_at, torrent::resource_manager(),
// tr1::bind(&core::Download::main, tr1::placeholders::_1))));
// CMD2_DL_V ("d.group.set", std::bind(&torrent::ResourceManager::set_group,
// CMD2_DL_V ("d.group.set", tr1::bind(&torrent::ResourceManager::set_group,
// torrent::resource_manager(),
// std::bind(&torrent::ResourceManager::find_throw, torrent::resource_manager(),
// std::bind(&core::Download::main, std::placeholders::_1)),
// tr1::bind(&torrent::ResourceManager::find_throw, torrent::resource_manager(),
// tr1::bind(&core::Download::main, tr1::placeholders::_1)),
// CG_GROUP_INDEX()));
CMD2_DL ("d.group", std::bind(&cg_d_group, std::placeholders::_1));;
CMD2_DL ("d.group.name", std::bind(&cg_d_group, std::placeholders::_1));;
CMD2_DL_V ("d.group.set", std::bind(&cg_d_group_set, std::placeholders::_1, std::placeholders::_2));
CMD2_DL ("d.group", tr1::bind(&cg_d_group, tr1::placeholders::_1));
CMD2_DL ("d.group.name", tr1::bind(&cg_d_group, tr1::placeholders::_1));
CMD2_DL_V ("d.group.set", tr1::bind(&cg_d_group_set, tr1::placeholders::_1, tr1::placeholders::_2));
CMD2_DL ("d.initialize_logs", std::bind(&cmd_d_initialize_logs, std::placeholders::_1));
CMD2_DL_LIST ("f.multicall", tr1::bind(&f_multicall, tr1::placeholders::_1, tr1::placeholders::_2));
CMD2_DL_LIST ("p.multicall", tr1::bind(&p_multicall, tr1::placeholders::_1, tr1::placeholders::_2));
CMD2_DL_LIST ("t.multicall", tr1::bind(&t_multicall, tr1::placeholders::_1, tr1::placeholders::_2));
CMD2_DL_LIST ("f.multicall", std::bind(&f_multicall, std::placeholders::_1, std::placeholders::_2));
CMD2_DL_LIST ("p.multicall", std::bind(&p_multicall, std::placeholders::_1, std::placeholders::_2));
CMD2_DL_LIST ("t.multicall", std::bind(&t_multicall, std::placeholders::_1, std::placeholders::_2));
CMD2_ANY_LIST ("p.call_target", std::bind(&p_call_target, std::placeholders::_2));
CMD2_ANY_LIST ("p.call_target", tr1::bind(&p_call_target, tr1::placeholders::_2));
}
+42 -29
View File
@@ -37,6 +37,7 @@
#include "config.h"
#include <algorithm>
#include <torrent/utils/log.h>
#include "globals.h"
#include "control.h"
@@ -150,22 +151,22 @@ system_method_insert_object(const torrent::Object::list_type& args, int flags) {
if (!(flags & rpc::object_storage::flag_private))
cmd_flags |= rpc::CommandMap::flag_public_xmlrpc;
rpc::object_storage::iterator obj_itr = control->object_storage()->insert_str(rawKey, value, flags);
control->object_storage()->insert_str(rawKey, value, flags);
if ((flags & rpc::object_storage::mask_type) == rpc::object_storage::flag_function_type ||
(flags & rpc::object_storage::mask_type) == rpc::object_storage::flag_multi_type) {
rpc::commands.insert_slot<rpc::command_base_is_type<rpc::command_base_call<rpc::target_type> >::type>
(create_new_key<0>(rawKey, ""),
std::bind(&rpc::object_storage::call_function_str, control->object_storage(),
rawKey, std::placeholders::_1, std::placeholders::_2),
(create_new_key(rawKey),
tr1::bind(&rpc::object_storage::call_function_str, control->object_storage(),
rawKey, tr1::placeholders::_1, tr1::placeholders::_2),
&rpc::command_base_call<rpc::target_type>,
cmd_flags, NULL, NULL);
} else {
rpc::commands.insert_slot<rpc::command_base_is_type<rpc::command_base_call<rpc::target_type> >::type>
(create_new_key<0>(rawKey, ""),
std::bind(&rpc::object_storage::get_str, control->object_storage(), rawKey),
(create_new_key(rawKey),
tr1::bind(&rpc::object_storage::get_str, control->object_storage(), rawKey),
&rpc::command_base_call<rpc::target_type>,
cmd_flags, NULL, NULL);
}
@@ -174,7 +175,7 @@ system_method_insert_object(const torrent::Object::list_type& args, int flags) {
// if (flags & rpc::object_storage::flag_rlookup) {
// rpc::commands.insert_slot<rpc::command_base_is_type<rpc::command_base_call_string<rpc::target_type> >::type>
// (create_new_key<9>(rawKey, ".rlookup"),
// std::bind(&rpc::object_storage::rlookup_obj_list, control->object_storage(), rawKey),
// tr1::bind(&rpc::object_storage::rlookup_obj_list, control->object_storage(), rawKey),
// &rpc::command_base_call_string<rpc::target_type>,
// cmd_flags, NULL, NULL);
// }
@@ -188,21 +189,21 @@ system_method_insert_object(const torrent::Object::list_type& args, int flags) {
case rpc::object_storage::flag_bool_type:
rpc::commands.insert_slot<rpc::command_base_is_type<rpc::command_base_call_value<rpc::target_type> >::type>
(create_new_key<5>(rawKey, ".set"),
std::bind(&rpc::object_storage::set_str_bool, control->object_storage(), rawKey, std::placeholders::_2),
tr1::bind(&rpc::object_storage::set_str_bool, control->object_storage(), rawKey, tr1::placeholders::_2),
&rpc::command_base_call_value<rpc::target_type>,
cmd_flags, NULL, NULL);
break;
case rpc::object_storage::flag_value_type:
rpc::commands.insert_slot<rpc::command_base_is_type<rpc::command_base_call_value<rpc::target_type> >::type>
(create_new_key<5>(rawKey, ".set"),
std::bind(&rpc::object_storage::set_str_value, control->object_storage(), rawKey, std::placeholders::_2),
tr1::bind(&rpc::object_storage::set_str_value, control->object_storage(), rawKey, tr1::placeholders::_2),
&rpc::command_base_call_value<rpc::target_type>,
cmd_flags, NULL, NULL);
break;
case rpc::object_storage::flag_string_type:
rpc::commands.insert_slot<rpc::command_base_is_type<rpc::command_base_call_string<rpc::target_type> >::type>
(create_new_key<5>(rawKey, ".set"),
std::bind(&rpc::object_storage::set_str_string, control->object_storage(), rawKey, std::placeholders::_2),
tr1::bind(&rpc::object_storage::set_str_string, control->object_storage(), rawKey, tr1::placeholders::_2),
&rpc::command_base_call_string<rpc::target_type>,
cmd_flags, NULL, NULL);
break;
@@ -354,7 +355,7 @@ system_method_redirect(const torrent::Object::list_type& args) {
std::string new_key = torrent::object_create_string(args.front());
std::string dest_key = torrent::object_create_string(args.back());
rpc::commands.create_redirect(create_new_key<0>(new_key, ""), create_new_key<0>(dest_key, ""),
rpc::commands.create_redirect(create_new_key(new_key), create_new_key(dest_key),
rpc::CommandMap::flag_public_xmlrpc | rpc::CommandMap::flag_delete_key | rpc::CommandMap::flag_modifiable);
return torrent::Object();
@@ -401,7 +402,7 @@ system_method_set_key(const torrent::Object::list_type& args) {
return torrent::Object();
}
if (itrArgs->is_dict_key())
if (itrArgs->is_dict_key() || itrArgs->is_list())
control->object_storage()->set_str_multi_key_obj(key.c_str(), cmd_key, *itrArgs);
else
control->object_storage()->set_str_multi_key(key, cmd_key, system_method_generate_command(itrArgs, args.end()));
@@ -422,37 +423,49 @@ system_method_list_keys(const torrent::Object::string_type& args) {
return rawResult;
}
torrent::Object
cmd_catch(rpc::target_type target, const torrent::Object& args) {
try {
return rpc::call_object(args, target);
} catch (torrent::input_error& e) {
lt_log_print(torrent::LOG_WARN, "Caught exception: '%s'.", e.what());
return torrent::Object();
}
}
#define CMD2_METHOD_INSERT(key, flags) \
CMD2_ANY_LIST(key, std::bind(&system_method_insert_object, std::placeholders::_2, flags));
CMD2_ANY_LIST(key, tr1::bind(&system_method_insert_object, tr1::placeholders::_2, flags));
void
initialize_command_dynamic() {
CMD2_VAR_BOOL ("method.use_deprecated", true);
CMD2_VAR_VALUE ("method.use_intermediate", 1);
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));
CMD2_ANY_LIST ("method.insert", tr1::bind(&system_method_insert, tr1::placeholders::_2));
CMD2_ANY_LIST ("method.insert.value", tr1::bind(&system_method_insert_object, tr1::placeholders::_2, rpc::object_storage::flag_value_type));
CMD2_METHOD_INSERT("method.insert.simple", rpc::object_storage::flag_function_type);
CMD2_METHOD_INSERT("method.insert.c_simple", rpc::object_storage::flag_constant | rpc::object_storage::flag_function_type);
CMD2_METHOD_INSERT("method.insert.s_c_simple", rpc::object_storage::flag_static |
rpc::object_storage::flag_constant |rpc::object_storage::flag_function_type);
CMD2_ANY_STRING ("method.erase", std::bind(&system_method_erase, std::placeholders::_2));
CMD2_ANY_LIST ("method.redirect", std::bind(&system_method_redirect, std::placeholders::_2));
CMD2_ANY_STRING ("method.get", std::bind(&rpc::object_storage::get_str, control->object_storage(),
std::placeholders::_2));
CMD2_ANY_LIST ("method.set", std::bind(&system_method_set_function, std::placeholders::_2));
CMD2_ANY_STRING ("method.erase", tr1::bind(&system_method_erase, tr1::placeholders::_2));
CMD2_ANY_LIST ("method.redirect", tr1::bind(&system_method_redirect, tr1::placeholders::_2));
CMD2_ANY_STRING ("method.get", tr1::bind(&rpc::object_storage::get_str, control->object_storage(),
tr1::placeholders::_2));
CMD2_ANY_LIST ("method.set", tr1::bind(&system_method_set_function, tr1::placeholders::_2));
CMD2_ANY_STRING ("method.const", std::bind(&rpc::object_storage::has_flag_str, control->object_storage(),
std::placeholders::_2, rpc::object_storage::flag_constant));
CMD2_ANY_STRING_V("method.const.enable", std::bind(&rpc::object_storage::enable_flag_str, control->object_storage(),
std::placeholders::_2, rpc::object_storage::flag_constant));
CMD2_ANY_STRING ("method.const", tr1::bind(&rpc::object_storage::has_flag_str, control->object_storage(),
tr1::placeholders::_2, rpc::object_storage::flag_constant));
CMD2_ANY_STRING_V("method.const.enable", tr1::bind(&rpc::object_storage::enable_flag_str, control->object_storage(),
tr1::placeholders::_2, rpc::object_storage::flag_constant));
CMD2_ANY_LIST ("method.has_key", std::bind(&system_method_has_key, std::placeholders::_2));
CMD2_ANY_LIST ("method.set_key", std::bind(&system_method_set_key, std::placeholders::_2));
CMD2_ANY_STRING ("method.list_keys", std::bind(&system_method_list_keys, std::placeholders::_2));
CMD2_ANY_LIST ("method.has_key", tr1::bind(&system_method_has_key, tr1::placeholders::_2));
CMD2_ANY_LIST ("method.set_key", tr1::bind(&system_method_set_key, tr1::placeholders::_2));
CMD2_ANY_STRING ("method.list_keys", tr1::bind(&system_method_list_keys, tr1::placeholders::_2));
CMD2_ANY_STRING ("method.rlookup", std::bind(&rpc::object_storage::rlookup_obj_list, control->object_storage(), std::placeholders::_2));
CMD2_ANY_STRING_V("method.rlookup.clear", std::bind(&rpc::object_storage::rlookup_clear, control->object_storage(), std::placeholders::_2));
CMD2_ANY_STRING ("method.rlookup", tr1::bind(&rpc::object_storage::rlookup_obj_list, control->object_storage(), tr1::placeholders::_2));
CMD2_ANY_STRING_V("method.rlookup.clear", tr1::bind(&rpc::object_storage::rlookup_clear, control->object_storage(), tr1::placeholders::_2));
CMD2_ANY ("catch", tr1::bind(&cmd_catch, tr1::placeholders::_1, tr1::placeholders::_2));
}
+20 -30
View File
@@ -41,7 +41,6 @@
#include <rak/file_stat.h>
#include <rak/path.h>
#include <rak/string_manip.h>
#include <sigc++/adaptors/bind.h>
#include <torrent/rate.h>
#include <torrent/hash_string.h>
#include <torrent/utils/log.h>
@@ -297,7 +296,7 @@ d_multicall(const torrent::Object::list_type& args) {
for (core::Download** vItr = dlist; vItr != dlist + dlist_size; vItr++) {
torrent::Object::list_type& row = result.insert(result.end(), torrent::Object::create_list())->as_list();
for (torrent::Object::list_const_iterator cItr = ++args.begin(), cLast = args.end(); cItr != args.end(); cItr++) {
for (torrent::Object::list_const_iterator cItr = ++args.begin(); cItr != args.end(); cItr++) {
const std::string& cmd = cItr->as_string();
row.push_back(rpc::parse_command(rpc::make_target(*vItr), cmd.c_str(), cmd.c_str() + cmd.size()).first);
}
@@ -306,42 +305,33 @@ d_multicall(const torrent::Object::list_type& args) {
return resultRaw;
}
torrent::Object
test_thread_locking() {
worker_thread->queue_item(&ThreadWorker::start_log_counter);
return torrent::Object();
}
void
initialize_command_events() {
CMD2_ANY("test.thread_locking", std::bind(&test_thread_locking));
CMD2_ANY_STRING ("on_ratio", tr1::bind(&apply_on_ratio, tr1::placeholders::_2));
CMD2_ANY_STRING ("on_ratio", std::bind(&apply_on_ratio, std::placeholders::_2));
CMD2_ANY ("start_tied", tr1::bind(&apply_start_tied));
CMD2_ANY ("stop_untied", tr1::bind(&apply_stop_untied));
CMD2_ANY ("close_untied", tr1::bind(&apply_close_untied));
CMD2_ANY ("remove_untied", tr1::bind(&apply_remove_untied));
CMD2_ANY ("start_tied", std::bind(&apply_start_tied));
CMD2_ANY ("stop_untied", std::bind(&apply_stop_untied));
CMD2_ANY ("close_untied", std::bind(&apply_close_untied));
CMD2_ANY ("remove_untied", std::bind(&apply_remove_untied));
CMD2_ANY_LIST ("schedule2", tr1::bind(&apply_schedule, tr1::placeholders::_2));
CMD2_ANY_STRING_V("schedule_remove2", tr1::bind(&rpc::CommandScheduler::erase_str, control->command_scheduler(), tr1::placeholders::_2));
CMD2_ANY_LIST ("schedule2", std::bind(&apply_schedule, std::placeholders::_2));
CMD2_ANY_STRING_V("schedule_remove2", std::bind(&rpc::CommandScheduler::erase_str, control->command_scheduler(), std::placeholders::_2));
CMD2_ANY_STRING_V("import", tr1::bind(&apply_import, tr1::placeholders::_2));
CMD2_ANY_STRING_V("try_import", tr1::bind(&apply_try_import, tr1::placeholders::_2));
CMD2_ANY_STRING_V("import", std::bind(&apply_import, std::placeholders::_2));
CMD2_ANY_STRING_V("try_import", std::bind(&apply_try_import, std::placeholders::_2));
CMD2_ANY_LIST ("load.normal", std::bind(&apply_load, std::placeholders::_2, core::Manager::create_quiet | core::Manager::create_tied));
CMD2_ANY_LIST ("load.verbose", std::bind(&apply_load, std::placeholders::_2, core::Manager::create_tied));
CMD2_ANY_LIST ("load.start", std::bind(&apply_load, std::placeholders::_2,
CMD2_ANY_LIST ("load.normal", tr1::bind(&apply_load, tr1::placeholders::_2, core::Manager::create_quiet | core::Manager::create_tied));
CMD2_ANY_LIST ("load.verbose", tr1::bind(&apply_load, tr1::placeholders::_2, core::Manager::create_tied));
CMD2_ANY_LIST ("load.start", tr1::bind(&apply_load, tr1::placeholders::_2,
core::Manager::create_quiet | core::Manager::create_tied | core::Manager::create_start));
CMD2_ANY_LIST ("load.start_verbose", std::bind(&apply_load, std::placeholders::_2, core::Manager::create_tied | core::Manager::create_start));
CMD2_ANY_LIST ("load.raw", std::bind(&apply_load, std::placeholders::_2, core::Manager::create_quiet | core::Manager::create_raw_data));
CMD2_ANY_LIST ("load.raw_verbose", std::bind(&apply_load, std::placeholders::_2, core::Manager::create_raw_data));
CMD2_ANY_LIST ("load.raw_start", std::bind(&apply_load, std::placeholders::_2,
CMD2_ANY_LIST ("load.start_verbose", tr1::bind(&apply_load, tr1::placeholders::_2, core::Manager::create_tied | core::Manager::create_start));
CMD2_ANY_LIST ("load.raw", tr1::bind(&apply_load, tr1::placeholders::_2, core::Manager::create_quiet | core::Manager::create_raw_data));
CMD2_ANY_LIST ("load.raw_verbose", tr1::bind(&apply_load, tr1::placeholders::_2, core::Manager::create_raw_data));
CMD2_ANY_LIST ("load.raw_start", tr1::bind(&apply_load, tr1::placeholders::_2,
core::Manager::create_quiet | core::Manager::create_start | core::Manager::create_raw_data));
CMD2_ANY_VALUE ("close_low_diskspace", std::bind(&apply_close_low_diskspace, std::placeholders::_2));
CMD2_ANY_VALUE ("close_low_diskspace", tr1::bind(&apply_close_low_diskspace, tr1::placeholders::_2));
CMD2_ANY_LIST ("download_list", std::bind(&apply_download_list, std::placeholders::_2));
CMD2_ANY_LIST ("d.multicall2", std::bind(&d_multicall, std::placeholders::_2));
CMD2_ANY_LIST ("download_list", tr1::bind(&apply_download_list, tr1::placeholders::_2));
CMD2_ANY_LIST ("d.multicall2", tr1::bind(&d_multicall, tr1::placeholders::_2));
}
+31 -31
View File
@@ -100,45 +100,45 @@ apply_fi_filename_last(torrent::FileListIterator* itr) {
void
initialize_command_file() {
CMD2_FILE("f.is_created", std::bind(&torrent::File::is_created, std::placeholders::_1));
CMD2_FILE("f.is_open", std::bind(&torrent::File::is_open, std::placeholders::_1));
CMD2_FILE("f.is_created", tr1::bind(&torrent::File::is_created, tr1::placeholders::_1));
CMD2_FILE("f.is_open", tr1::bind(&torrent::File::is_open, tr1::placeholders::_1));
CMD2_FILE("f.is_create_queued", std::bind(&torrent::File::is_create_queued, std::placeholders::_1));
CMD2_FILE("f.is_resize_queued", std::bind(&torrent::File::is_resize_queued, std::placeholders::_1));
CMD2_FILE("f.is_create_queued", tr1::bind(&torrent::File::is_create_queued, tr1::placeholders::_1));
CMD2_FILE("f.is_resize_queued", tr1::bind(&torrent::File::is_resize_queued, tr1::placeholders::_1));
CMD2_FILE_VALUE_V("f.set_create_queued", std::bind(&torrent::File::set_flags, std::placeholders::_1, torrent::File::flag_create_queued));
CMD2_FILE_VALUE_V("f.set_resize_queued", std::bind(&torrent::File::set_flags, std::placeholders::_1, torrent::File::flag_resize_queued));
CMD2_FILE_VALUE_V("f.unset_create_queued", std::bind(&torrent::File::unset_flags, std::placeholders::_1, torrent::File::flag_create_queued));
CMD2_FILE_VALUE_V("f.unset_resize_queued", std::bind(&torrent::File::unset_flags, std::placeholders::_1, torrent::File::flag_resize_queued));
CMD2_FILE_VALUE_V("f.set_create_queued", tr1::bind(&torrent::File::set_flags, tr1::placeholders::_1, torrent::File::flag_create_queued));
CMD2_FILE_VALUE_V("f.set_resize_queued", tr1::bind(&torrent::File::set_flags, tr1::placeholders::_1, torrent::File::flag_resize_queued));
CMD2_FILE_VALUE_V("f.unset_create_queued", tr1::bind(&torrent::File::unset_flags, tr1::placeholders::_1, torrent::File::flag_create_queued));
CMD2_FILE_VALUE_V("f.unset_resize_queued", tr1::bind(&torrent::File::unset_flags, tr1::placeholders::_1, torrent::File::flag_resize_queued));
CMD2_FILE ("f.prioritize_first", std::bind(&torrent::File::has_flags, std::placeholders::_1, torrent::File::flag_prioritize_first));
CMD2_FILE_V("f.prioritize_first.enable", std::bind(&torrent::File::set_flags, std::placeholders::_1, torrent::File::flag_prioritize_first));
CMD2_FILE_V("f.prioritize_first.disable", std::bind(&torrent::File::unset_flags, std::placeholders::_1, torrent::File::flag_prioritize_first));
CMD2_FILE ("f.prioritize_last", std::bind(&torrent::File::has_flags, std::placeholders::_1, torrent::File::flag_prioritize_last));
CMD2_FILE_V("f.prioritize_last.enable", std::bind(&torrent::File::set_flags, std::placeholders::_1, torrent::File::flag_prioritize_last));
CMD2_FILE_V("f.prioritize_last.disable", std::bind(&torrent::File::unset_flags, std::placeholders::_1, torrent::File::flag_prioritize_last));
CMD2_FILE ("f.prioritize_first", tr1::bind(&torrent::File::has_flags, tr1::placeholders::_1, torrent::File::flag_prioritize_first));
CMD2_FILE_V("f.prioritize_first.enable", tr1::bind(&torrent::File::set_flags, tr1::placeholders::_1, torrent::File::flag_prioritize_first));
CMD2_FILE_V("f.prioritize_first.disable", tr1::bind(&torrent::File::unset_flags, tr1::placeholders::_1, torrent::File::flag_prioritize_first));
CMD2_FILE ("f.prioritize_last", tr1::bind(&torrent::File::has_flags, tr1::placeholders::_1, torrent::File::flag_prioritize_last));
CMD2_FILE_V("f.prioritize_last.enable", tr1::bind(&torrent::File::set_flags, tr1::placeholders::_1, torrent::File::flag_prioritize_last));
CMD2_FILE_V("f.prioritize_last.disable", tr1::bind(&torrent::File::unset_flags, tr1::placeholders::_1, torrent::File::flag_prioritize_last));
CMD2_FILE("f.size_bytes", std::bind(&torrent::File::size_bytes, std::placeholders::_1));
CMD2_FILE("f.size_chunks", std::bind(&torrent::File::size_chunks, std::placeholders::_1));
CMD2_FILE("f.completed_chunks", std::bind(&torrent::File::completed_chunks, std::placeholders::_1));
CMD2_FILE("f.size_bytes", tr1::bind(&torrent::File::size_bytes, tr1::placeholders::_1));
CMD2_FILE("f.size_chunks", tr1::bind(&torrent::File::size_chunks, tr1::placeholders::_1));
CMD2_FILE("f.completed_chunks", tr1::bind(&torrent::File::completed_chunks, tr1::placeholders::_1));
CMD2_FILE("f.offset", std::bind(&torrent::File::offset, std::placeholders::_1));
CMD2_FILE("f.range_first", std::bind(&torrent::File::range_first, std::placeholders::_1));
CMD2_FILE("f.range_second", std::bind(&torrent::File::range_second, std::placeholders::_1));
CMD2_FILE("f.offset", tr1::bind(&torrent::File::offset, tr1::placeholders::_1));
CMD2_FILE("f.range_first", tr1::bind(&torrent::File::range_first, tr1::placeholders::_1));
CMD2_FILE("f.range_second", tr1::bind(&torrent::File::range_second, tr1::placeholders::_1));
CMD2_FILE("f.priority", std::bind(&torrent::File::priority, std::placeholders::_1));
CMD2_FILE_VALUE_V("f.priority.set", std::bind(&apply_f_set_priority, std::placeholders::_1, std::placeholders::_2));
CMD2_FILE("f.priority", tr1::bind(&torrent::File::priority, tr1::placeholders::_1));
CMD2_FILE_VALUE_V("f.priority.set", tr1::bind(&apply_f_set_priority, tr1::placeholders::_1, tr1::placeholders::_2));
CMD2_FILE("f.path", std::bind(&apply_f_path, std::placeholders::_1));
CMD2_FILE("f.path_components", std::bind(&apply_f_path_components, std::placeholders::_1));
CMD2_FILE("f.path_depth", std::bind(&apply_f_path_depth, std::placeholders::_1));
CMD2_FILE("f.frozen_path", std::bind(&torrent::File::frozen_path, std::placeholders::_1));
CMD2_FILE("f.path", tr1::bind(&apply_f_path, tr1::placeholders::_1));
CMD2_FILE("f.path_components", tr1::bind(&apply_f_path_components, tr1::placeholders::_1));
CMD2_FILE("f.path_depth", tr1::bind(&apply_f_path_depth, tr1::placeholders::_1));
CMD2_FILE("f.frozen_path", tr1::bind(&torrent::File::frozen_path, tr1::placeholders::_1));
CMD2_FILE("f.match_depth_prev", std::bind(&torrent::File::match_depth_prev, std::placeholders::_1));
CMD2_FILE("f.match_depth_next", std::bind(&torrent::File::match_depth_next, std::placeholders::_1));
CMD2_FILE("f.match_depth_prev", tr1::bind(&torrent::File::match_depth_prev, tr1::placeholders::_1));
CMD2_FILE("f.match_depth_next", tr1::bind(&torrent::File::match_depth_next, tr1::placeholders::_1));
CMD2_FILE("f.last_touched", std::bind(&torrent::File::last_touched, std::placeholders::_1));
CMD2_FILE("f.last_touched", tr1::bind(&torrent::File::last_touched, tr1::placeholders::_1));
CMD2_FILEITR("fi.filename_last", std::bind(&apply_fi_filename_last, std::placeholders::_1));
CMD2_FILEITR("fi.is_file", std::bind(&torrent::FileListIterator::is_file, std::placeholders::_1));
CMD2_FILEITR("fi.filename_last", tr1::bind(&apply_fi_filename_last, tr1::placeholders::_1));
CMD2_FILEITR("fi.is_file", tr1::bind(&torrent::FileListIterator::is_file, tr1::placeholders::_1));
}
+36 -36
View File
@@ -264,8 +264,8 @@ apply_cg_tracker_mode_set(const torrent::Object::list_type& args) {
return torrent::Object();
}
#define CG_GROUP_AT() std::bind(&cg_get_group, std::placeholders::_2)
#define CHOKE_GROUP(direction) std::bind(direction, CG_GROUP_AT())
#define CG_GROUP_AT() tr1::bind(&cg_get_group, tr1::placeholders::_2)
#define CHOKE_GROUP(direction) tr1::bind(direction, CG_GROUP_AT())
/*
@@ -336,54 +336,54 @@ options.
void
initialize_command_groups() {
// Move somewhere else?
CMD2_ANY ("strings.choke_heuristics", std::bind(&torrent::option_list_strings, torrent::OPTION_CHOKE_HEURISTICS));
CMD2_ANY ("strings.choke_heuristics.upload", std::bind(&torrent::option_list_strings, torrent::OPTION_CHOKE_HEURISTICS_UPLOAD));
CMD2_ANY ("strings.choke_heuristics.download", std::bind(&torrent::option_list_strings, torrent::OPTION_CHOKE_HEURISTICS_DOWNLOAD));
CMD2_ANY ("strings.tracker_mode", std::bind(&torrent::option_list_strings, torrent::OPTION_TRACKER_MODE));
CMD2_ANY ("strings.choke_heuristics", tr1::bind(&torrent::option_list_strings, torrent::OPTION_CHOKE_HEURISTICS));
CMD2_ANY ("strings.choke_heuristics.upload", tr1::bind(&torrent::option_list_strings, torrent::OPTION_CHOKE_HEURISTICS_UPLOAD));
CMD2_ANY ("strings.choke_heuristics.download", tr1::bind(&torrent::option_list_strings, torrent::OPTION_CHOKE_HEURISTICS_DOWNLOAD));
CMD2_ANY ("strings.tracker_mode", tr1::bind(&torrent::option_list_strings, torrent::OPTION_TRACKER_MODE));
CMD2_ANY ("choke_group.list", std::bind(&apply_cg_list));
CMD2_ANY_STRING ("choke_group.insert", std::bind(&apply_cg_insert, std::placeholders::_2));
CMD2_ANY ("choke_group.list", tr1::bind(&apply_cg_list));
CMD2_ANY_STRING ("choke_group.insert", tr1::bind(&apply_cg_insert, tr1::placeholders::_2));
#if USE_CHOKE_GROUP
CMD2_ANY ("choke_group.size", std::bind(&torrent::ResourceManager::group_size, torrent::resource_manager()));
CMD2_ANY_STRING ("choke_group.index_of", std::bind(&torrent::ResourceManager::group_index_of, torrent::resource_manager(), std::placeholders::_2));
CMD2_ANY ("choke_group.size", tr1::bind(&torrent::ResourceManager::group_size, torrent::resource_manager()));
CMD2_ANY_STRING ("choke_group.index_of", tr1::bind(&torrent::ResourceManager::group_index_of, torrent::resource_manager(), tr1::placeholders::_2));
#else
apply_cg_insert("default");
CMD2_ANY ("choke_group.size", std::bind(&std::vector<torrent::choke_group*>::size, cg_list_hack));
CMD2_ANY_STRING ("choke_group.index_of", std::bind(&apply_cg_index_of, std::placeholders::_2));
CMD2_ANY ("choke_group.size", tr1::bind(&std::vector<torrent::choke_group*>::size, cg_list_hack));
CMD2_ANY_STRING ("choke_group.index_of", tr1::bind(&apply_cg_index_of, tr1::placeholders::_2));
#endif
// Commands specific for a group. Supports as the first argument the
// name, the index or a negative index.
CMD2_ANY ("choke_group.general.size", std::bind(&torrent::choke_group::size, CG_GROUP_AT()));
CMD2_ANY ("choke_group.general.size", tr1::bind(&torrent::choke_group::size, CG_GROUP_AT()));
CMD2_ANY ("choke_group.tracker.mode", std::bind(&torrent::option_as_string, torrent::OPTION_TRACKER_MODE,
std::bind(&torrent::choke_group::tracker_mode, CG_GROUP_AT())));
CMD2_ANY_LIST ("choke_group.tracker.mode.set", std::bind(&apply_cg_tracker_mode_set, std::placeholders::_2));
CMD2_ANY ("choke_group.tracker.mode", tr1::bind(&torrent::option_as_string, torrent::OPTION_TRACKER_MODE,
tr1::bind(&torrent::choke_group::tracker_mode, CG_GROUP_AT())));
CMD2_ANY_LIST ("choke_group.tracker.mode.set", tr1::bind(&apply_cg_tracker_mode_set, tr1::placeholders::_2));
CMD2_ANY ("choke_group.up.rate", std::bind(&torrent::choke_group::up_rate, CG_GROUP_AT()));
CMD2_ANY ("choke_group.down.rate", std::bind(&torrent::choke_group::down_rate, CG_GROUP_AT()));
CMD2_ANY ("choke_group.up.rate", tr1::bind(&torrent::choke_group::up_rate, CG_GROUP_AT()));
CMD2_ANY ("choke_group.down.rate", tr1::bind(&torrent::choke_group::down_rate, CG_GROUP_AT()));
CMD2_ANY ("choke_group.up.max.unlimited", std::bind(&torrent::choke_queue::is_unlimited, CHOKE_GROUP(&torrent::choke_group::up_queue)));
CMD2_ANY ("choke_group.up.max", std::bind(&torrent::choke_queue::max_unchoked_signed, CHOKE_GROUP(&torrent::choke_group::up_queue)));
CMD2_ANY_LIST ("choke_group.up.max.set", std::bind(&apply_cg_max_set, std::placeholders::_2, true));
CMD2_ANY ("choke_group.up.max.unlimited", tr1::bind(&torrent::choke_queue::is_unlimited, CHOKE_GROUP(&torrent::choke_group::up_queue)));
CMD2_ANY ("choke_group.up.max", tr1::bind(&torrent::choke_queue::max_unchoked_signed, CHOKE_GROUP(&torrent::choke_group::up_queue)));
CMD2_ANY_LIST ("choke_group.up.max.set", tr1::bind(&apply_cg_max_set, tr1::placeholders::_2, true));
CMD2_ANY ("choke_group.up.total", std::bind(&torrent::choke_queue::size_total, CHOKE_GROUP(&torrent::choke_group::up_queue)));
CMD2_ANY ("choke_group.up.queued", std::bind(&torrent::choke_queue::size_queued, CHOKE_GROUP(&torrent::choke_group::up_queue)));
CMD2_ANY ("choke_group.up.unchoked", std::bind(&torrent::choke_queue::size_unchoked, CHOKE_GROUP(&torrent::choke_group::up_queue)));
CMD2_ANY ("choke_group.up.heuristics", std::bind(&torrent::option_as_string, torrent::OPTION_CHOKE_HEURISTICS,
std::bind(&torrent::choke_queue::heuristics, CHOKE_GROUP(&torrent::choke_group::up_queue))));
CMD2_ANY_LIST ("choke_group.up.heuristics.set", std::bind(&apply_cg_heuristics_set, std::placeholders::_2, true));
CMD2_ANY ("choke_group.up.total", tr1::bind(&torrent::choke_queue::size_total, CHOKE_GROUP(&torrent::choke_group::up_queue)));
CMD2_ANY ("choke_group.up.queued", tr1::bind(&torrent::choke_queue::size_queued, CHOKE_GROUP(&torrent::choke_group::up_queue)));
CMD2_ANY ("choke_group.up.unchoked", tr1::bind(&torrent::choke_queue::size_unchoked, CHOKE_GROUP(&torrent::choke_group::up_queue)));
CMD2_ANY ("choke_group.up.heuristics", tr1::bind(&torrent::option_as_string, torrent::OPTION_CHOKE_HEURISTICS,
tr1::bind(&torrent::choke_queue::heuristics, CHOKE_GROUP(&torrent::choke_group::up_queue))));
CMD2_ANY_LIST ("choke_group.up.heuristics.set", tr1::bind(&apply_cg_heuristics_set, tr1::placeholders::_2, true));
CMD2_ANY ("choke_group.down.max.unlimited", std::bind(&torrent::choke_queue::is_unlimited, CHOKE_GROUP(&torrent::choke_group::down_queue)));
CMD2_ANY ("choke_group.down.max", std::bind(&torrent::choke_queue::max_unchoked_signed, CHOKE_GROUP(&torrent::choke_group::down_queue)));
CMD2_ANY_LIST ("choke_group.down.max.set", std::bind(&apply_cg_max_set, std::placeholders::_2, false));
CMD2_ANY ("choke_group.down.max.unlimited", tr1::bind(&torrent::choke_queue::is_unlimited, CHOKE_GROUP(&torrent::choke_group::down_queue)));
CMD2_ANY ("choke_group.down.max", tr1::bind(&torrent::choke_queue::max_unchoked_signed, CHOKE_GROUP(&torrent::choke_group::down_queue)));
CMD2_ANY_LIST ("choke_group.down.max.set", tr1::bind(&apply_cg_max_set, tr1::placeholders::_2, false));
CMD2_ANY ("choke_group.down.total", std::bind(&torrent::choke_queue::size_total, CHOKE_GROUP(&torrent::choke_group::down_queue)));
CMD2_ANY ("choke_group.down.queued", std::bind(&torrent::choke_queue::size_queued, CHOKE_GROUP(&torrent::choke_group::down_queue)));
CMD2_ANY ("choke_group.down.unchoked", std::bind(&torrent::choke_queue::size_unchoked, CHOKE_GROUP(&torrent::choke_group::down_queue)));
CMD2_ANY ("choke_group.down.heuristics", std::bind(&torrent::option_as_string, torrent::OPTION_CHOKE_HEURISTICS,
std::bind(&torrent::choke_queue::heuristics, CHOKE_GROUP(&torrent::choke_group::down_queue))));
CMD2_ANY_LIST ("choke_group.down.heuristics.set", std::bind(&apply_cg_heuristics_set, std::placeholders::_2, false));
CMD2_ANY ("choke_group.down.total", tr1::bind(&torrent::choke_queue::size_total, CHOKE_GROUP(&torrent::choke_group::down_queue)));
CMD2_ANY ("choke_group.down.queued", tr1::bind(&torrent::choke_queue::size_queued, CHOKE_GROUP(&torrent::choke_group::down_queue)));
CMD2_ANY ("choke_group.down.unchoked", tr1::bind(&torrent::choke_queue::size_unchoked, CHOKE_GROUP(&torrent::choke_group::down_queue)));
CMD2_ANY ("choke_group.down.heuristics", tr1::bind(&torrent::option_as_string, torrent::OPTION_CHOKE_HEURISTICS,
tr1::bind(&torrent::choke_queue::heuristics, CHOKE_GROUP(&torrent::choke_group::down_queue))));
CMD2_ANY_LIST ("choke_group.down.heuristics.set", tr1::bind(&apply_cg_heuristics_set, tr1::placeholders::_2, false));
}
+33 -20
View File
@@ -41,6 +41,8 @@
#include "rpc/parse_commands.h"
#include "rpc/object_storage.h"
namespace tr1 { using namespace std::tr1; }
void initialize_commands();
//
@@ -98,43 +100,43 @@ void initialize_commands();
#define CMD2_VAR_BOOL(key, value) \
control->object_storage()->insert_c_str(key, int64_t(value), rpc::object_storage::flag_bool_type); \
CMD2_ANY(key, std::bind(&rpc::object_storage::get, control->object_storage(), \
CMD2_ANY(key, tr1::bind(&rpc::object_storage::get, control->object_storage(), \
torrent::raw_string::from_c_str(key))); \
CMD2_ANY_VALUE(key ".set", std::bind(&rpc::object_storage::set_bool, control->object_storage(), \
torrent::raw_string::from_c_str(key), std::placeholders::_2));
CMD2_ANY_VALUE(key ".set", tr1::bind(&rpc::object_storage::set_bool, control->object_storage(), \
torrent::raw_string::from_c_str(key), tr1::placeholders::_2));
#define CMD2_VAR_VALUE(key, value) \
control->object_storage()->insert_c_str(key, int64_t(value), rpc::object_storage::flag_value_type); \
CMD2_ANY(key, std::bind(&rpc::object_storage::get, control->object_storage(), \
CMD2_ANY(key, tr1::bind(&rpc::object_storage::get, control->object_storage(), \
torrent::raw_string::from_c_str(key))); \
CMD2_ANY_VALUE(key ".set", std::bind(&rpc::object_storage::set_value, control->object_storage(), \
torrent::raw_string::from_c_str(key), std::placeholders::_2));
CMD2_ANY_VALUE(key ".set", tr1::bind(&rpc::object_storage::set_value, control->object_storage(), \
torrent::raw_string::from_c_str(key), tr1::placeholders::_2));
#define CMD2_VAR_STRING(key, value) \
control->object_storage()->insert_c_str(key, value, rpc::object_storage::flag_string_type); \
CMD2_ANY(key, std::bind(&rpc::object_storage::get, control->object_storage(), \
CMD2_ANY(key, tr1::bind(&rpc::object_storage::get, control->object_storage(), \
torrent::raw_string::from_c_str(key))); \
CMD2_ANY_STRING(key ".set", std::bind(&rpc::object_storage::set_string, control->object_storage(), \
torrent::raw_string::from_c_str(key), std::placeholders::_2));
CMD2_ANY_STRING(key ".set", tr1::bind(&rpc::object_storage::set_string, control->object_storage(), \
torrent::raw_string::from_c_str(key), tr1::placeholders::_2));
#define CMD2_VAR_C_STRING(key, value) \
control->object_storage()->insert_c_str(key, value, rpc::object_storage::flag_string_type); \
CMD2_ANY(key, std::bind(&rpc::object_storage::get, control->object_storage(), \
CMD2_ANY(key, tr1::bind(&rpc::object_storage::get, control->object_storage(), \
torrent::raw_string::from_c_str(key)));
#define CMD2_VAR_LIST(key) \
control->object_storage()->insert_c_str(key, torrent::Object::create_list(), rpc::object_storage::flag_list_type); \
CMD2_ANY(key, std::bind(&rpc::object_storage::get, control->object_storage(), \
CMD2_ANY(key, tr1::bind(&rpc::object_storage::get, control->object_storage(), \
torrent::raw_string::from_c_str(key))); \
CMD2_ANY_LIST(key ".set", std::bind(&rpc::object_storage::set_list, control->object_storage(), \
torrent::raw_string::from_c_str(key), std::placeholders::_2)); \
CMD2_ANY_VOID(key ".push_back", std::bind(&rpc::object_storage::list_push_back, control->object_storage(), \
torrent::raw_string::from_c_str(key), std::placeholders::_2));
CMD2_ANY_LIST(key ".set", tr1::bind(&rpc::object_storage::set_list, control->object_storage(), \
torrent::raw_string::from_c_str(key), tr1::placeholders::_2)); \
CMD2_ANY_VOID(key ".push_back", tr1::bind(&rpc::object_storage::list_push_back, control->object_storage(), \
torrent::raw_string::from_c_str(key), tr1::placeholders::_2));
#define CMD2_FUNC_SINGLE(key, cmds) \
CMD2_ANY(key, std::bind(&rpc::command_function_call, torrent::raw_string::from_c_str(cmds), \
std::placeholders::_1, std::placeholders::_2));
#define CMD2_FUNC_SINGLE(key, cmds) \
CMD2_ANY(key, tr1::bind(&rpc::command_function_call_object, torrent::Object(torrent::raw_string::from_c_str(cmds)), \
tr1::placeholders::_1, tr1::placeholders::_2));
#define CMD2_REDIRECT(from_key, to_key) \
rpc::commands.create_redirect(from_key, to_key, rpc::CommandMap::flag_public_xmlrpc | rpc::CommandMap::flag_dont_delete);
@@ -148,11 +150,11 @@ void initialize_commands();
rpc::commands.create_redirect(from_key, to_key, rpc::CommandMap::flag_public_xmlrpc | rpc::CommandMap::flag_tracker_target | rpc::CommandMap::flag_dont_delete);
#define CMD2_REDIRECT_GENERIC_STR(from_key, to_key) \
rpc::commands.create_redirect(create_new_key<0>(from_key, ""), create_new_key<0>(to_key, ""), \
rpc::commands.create_redirect(create_new_key(from_key), create_new_key(to_key), \
rpc::CommandMap::flag_public_xmlrpc | rpc::CommandMap::flag_no_target | rpc::CommandMap::flag_delete_key);
#define CMD2_REDIRECT_GENERIC_STR_NO_EXPORT(from_key, to_key) \
rpc::commands.create_redirect(create_new_key<0>(from_key, ""), create_new_key<0>(to_key, ""), \
rpc::commands.create_redirect(create_new_key(from_key), create_new_key(to_key), \
rpc::CommandMap::flag_no_target | rpc::CommandMap::flag_delete_key);
//
@@ -175,7 +177,11 @@ struct object_convert_type<Functor, void> {
template <typename Arg1>
torrent::Object operator () (Arg1& arg1) { m_slot(arg1); return torrent::Object(); }
template <typename Arg1, typename Arg2>
torrent::Object operator () (const Arg1& arg1) { m_slot(arg1); return torrent::Object(); }
template <typename Arg1, typename Arg2>
torrent::Object operator () (Arg1& arg1, Arg2& arg2) { m_slot(arg1, arg2); return torrent::Object(); }
template <typename Arg1, typename Arg2>
torrent::Object operator () (const Arg1& arg1, const Arg2& arg2) { m_slot(arg1, arg2); return torrent::Object(); }
Functor m_slot;
};
@@ -197,4 +203,11 @@ create_new_key(const std::string& key, const char postfix[postfix_size]) {
return buffer;
}
inline const char*
create_new_key(const std::string& key) {
char *buffer = new char[key.size() + 1];
std::memcpy(buffer, key.c_str(), key.size() + 1);
return buffer;
}
#endif
+73 -23
View File
@@ -75,6 +75,9 @@ ipv4_filter_parse(const char* address, int value) {
if (values_read < 7)
block = 8 * (values_read / 2);
lt_log_print(torrent::LOG_CONNECTION_DEBUG, "Adding ip filter for %u.%u.%u.%u/%u.",
ip_values[0], ip_values[1], ip_values[2], ip_values[3], block);
torrent::PeerList::ipv4_filter()->insert((ip_values[0] << 24) + (ip_values[1] << 16) + (ip_values[2] << 8) + ip_values[3],
rpc::ipv4_table::mask_bits - block, value);
}
@@ -88,6 +91,16 @@ apply_ip_tables_insert_table(const std::string& args) {
return torrent::Object();
}
torrent::Object
apply_ip_tables_size_data(const std::string& args) {
rpc::ip_table_list::const_iterator itr = ip_tables.find(args);
if (itr != ip_tables.end())
throw torrent::input_error("IP table does not exist.");
return itr->table.sizeof_data();
}
torrent::Object
apply_ip_tables_get(const torrent::Object::list_type& args) {
if (args.size() != 2)
@@ -187,30 +200,23 @@ apply_ipv4_filter_load(const torrent::Object::list_type& args) {
if (args.size() != 2)
throw torrent::input_error("Incorrect number of arguments.");
torrent::Object::list_const_iterator args_itr = args.begin();
std::string filename = args.front().as_string();
std::string value_name = args.back().as_string();
int value = torrent::option_find_string(torrent::OPTION_IP_FILTER, value_name.c_str());
std::fstream file(rak::path_expand(args.front().as_string()).c_str(), std::ios::in);
std::fstream file(rak::path_expand(filename).c_str(), std::ios::in);
if (!file.is_open())
throw torrent::input_error("Could not open ip filter file: " + args.front().as_string());
throw torrent::input_error("Could not open ip filter file: " + filename);
int value = torrent::option_find_string(torrent::OPTION_IP_FILTER, args.back().as_string().c_str());
char buffer[4096];
unsigned int lineNumber = 0;
char buffer[4096];
try {
while (file.good() && !file.getline(buffer, 4096).fail()) {
if (file.gcount() == 0)
throw torrent::internal_error("parse_command_file(...) file.gcount() == 0.");
int lineLength = file.gcount() - 1;
// In case we are at the end of the file and the last character is
// not a line feed, we'll just increase the read character count so
// that the last would also be included in option line.
if (file.eof() && file.get() != '\n')
lineLength++;
lineNumber++;
if (buffer[0] == '\0' || buffer[0] == '#')
@@ -220,28 +226,72 @@ apply_ipv4_filter_load(const torrent::Object::list_type& args) {
}
} catch (torrent::input_error& e) {
snprintf(buffer, 2048, "Error in ip filter file: %s:%u: %s", args.front().as_string().c_str(), lineNumber, e.what());
snprintf(buffer, 2048, "Error in ip filter file: %s:%u: %s", filename.c_str(), lineNumber, e.what());
throw torrent::input_error(buffer);
}
lt_log_print(torrent::LOG_CONNECTION_INFO, "Loaded %u %s address blocks (%u kb in-memory) from '%s'.",
lineNumber,
args.back().as_string().c_str(),
value_name.c_str(),
torrent::PeerList::ipv4_filter()->sizeof_data() / 1024,
args.front().as_string().c_str());
filename.c_str());
return torrent::Object();
}
static void
append_table(torrent::ipv4_table::base_type* extent, torrent::Object::list_type& result) {
torrent::ipv4_table::table_type::iterator first = extent->table.begin();
torrent::ipv4_table::table_type::iterator last = extent->table.end();
while (first != last) {
if (first->first != NULL) {
// Do something more here?...
append_table(first->first, result);
} else if (first->second != 0) {
uint32_t position = extent->partition_pos(first);
char buffer[256];
snprintf(buffer, 256, "%u.%u.%u.%u/%u %s",
(position >> 24) & 0xff,
(position >> 16) & 0xff,
(position >> 8) & 0xff,
(position >> 0) & 0xff,
extent->mask_bits,
torrent::option_as_string(torrent::OPTION_IP_FILTER, first->second));
result.push_back((std::string)buffer);
}
first++;
}
}
torrent::Object
apply_ipv4_filter_dump() {
torrent::Object raw_result = torrent::Object::create_list();
torrent::Object::list_type& result = raw_result.as_list();
append_table(torrent::PeerList::ipv4_filter()->data(), result);
return raw_result;
}
void
initialize_command_ip() {
CMD2_ANY_STRING ("ip_tables.insert_table", std::bind(&apply_ip_tables_insert_table, std::placeholders::_2));
CMD2_ANY_LIST ("ip_tables.get", std::bind(&apply_ip_tables_get, std::placeholders::_2));
CMD2_ANY_LIST ("ip_tables.add_address", std::bind(&apply_ip_tables_add_address, std::placeholders::_2));
CMD2_ANY ("strings.ip_filter", tr1::bind(&torrent::option_list_strings, torrent::OPTION_IP_FILTER));
CMD2_ANY ("strings.ip_tos", tr1::bind(&torrent::option_list_strings, torrent::OPTION_IP_TOS));
CMD2_ANY ("ipv4_filter.size_data", std::bind(&apply_ipv4_filter_size_data));
CMD2_ANY_STRING ("ipv4_filter.get", std::bind(&apply_ipv4_filter_get, std::placeholders::_2));
CMD2_ANY_LIST ("ipv4_filter.add_address", std::bind(&apply_ipv4_filter_add_address, std::placeholders::_2));
CMD2_ANY_LIST ("ipv4_filter.load", std::bind(&apply_ipv4_filter_load, std::placeholders::_2));
CMD2_ANY_STRING ("ip_tables.insert_table", tr1::bind(&apply_ip_tables_insert_table, tr1::placeholders::_2));
CMD2_ANY_STRING ("ip_tables.size_data", tr1::bind(&apply_ip_tables_size_data, tr1::placeholders::_2));
CMD2_ANY_LIST ("ip_tables.get", tr1::bind(&apply_ip_tables_get, tr1::placeholders::_2));
CMD2_ANY_LIST ("ip_tables.add_address", tr1::bind(&apply_ip_tables_add_address, tr1::placeholders::_2));
CMD2_ANY ("ipv4_filter.size_data", tr1::bind(&apply_ipv4_filter_size_data));
CMD2_ANY_STRING ("ipv4_filter.get", tr1::bind(&apply_ipv4_filter_get, tr1::placeholders::_2));
CMD2_ANY_LIST ("ipv4_filter.add_address", tr1::bind(&apply_ipv4_filter_add_address, tr1::placeholders::_2));
CMD2_ANY_LIST ("ipv4_filter.load", tr1::bind(&apply_ipv4_filter_load, tr1::placeholders::_2));
CMD2_ANY_LIST ("ipv4_filter.dump", tr1::bind(&apply_ipv4_filter_dump));
}
+68 -78
View File
@@ -49,7 +49,6 @@
#include <torrent/data/file_manager.h>
#include <torrent/data/chunk_utils.h>
#include <torrent/utils/log.h>
#include <torrent/utils/log_files.h>
#include <torrent/utils/option_strings.h>
#include "core/download.h"
@@ -116,27 +115,6 @@ apply_log(const torrent::Object::string_type& arg, int logType) {
return torrent::Object();
}
torrent::Object
apply_log_libtorrent(const torrent::Object::list_type& args) {
if (args.empty() || args.size() > 2)
throw torrent::input_error("Invalid argument count.");
torrent::log_file* log_file = torrent::find_log_file(args.front().as_string().c_str());
if (log_file == NULL)
throw torrent::input_error("Invalid log name.");
if (args.size() == 1) {
log_file->close();
return torrent::Object();
}
if (!log_file->open_file(args.back().as_string().c_str()))
throw torrent::input_error("Could not open log file.");
return torrent::Object();
}
torrent::Object
system_hostname() {
char buffer[1024];
@@ -263,10 +241,10 @@ file_print_list(torrent::Object::list_const_iterator first, torrent::Object::lis
while (first != last) {
switch (first->type()) {
case torrent::Object::TYPE_STRING:
fprintf(output, " %s" + !(flags & file_print_use_space), first->as_string().c_str());
fprintf(output, (const char*)" %s" + !(flags & file_print_use_space), first->as_string().c_str());
break;
case torrent::Object::TYPE_VALUE:
fprintf(output, " %lli" + !(flags & file_print_use_space), first->as_value());
fprintf(output, (const char*)" %lli" + !(flags & file_print_use_space), first->as_value());
break;
case torrent::Object::TYPE_LIST:
file_print_list(first->as_list().begin(), first->as_list().end(), output, 0);
@@ -304,7 +282,18 @@ apply_log_open_file(const torrent::Object::list_type& args) {
if (args.size() != 2)
throw torrent::input_error("Invalid number of arguments.");
torrent::log_open_file_output(args.front().as_string().c_str(), args.back().as_string().c_str());
torrent::log_open_file_output(args.front().as_string().c_str(),
rak::path_expand(args.back().as_string()).c_str());
return torrent::Object();
}
torrent::Object
apply_log_open_gz_file(const torrent::Object::list_type& args) {
if (args.size() != 2)
throw torrent::input_error("Invalid number of arguments.");
torrent::log_open_gz_file_output(args.front().as_string().c_str(),
rak::path_expand(args.back().as_string()).c_str());
return torrent::Object();
}
@@ -325,64 +314,65 @@ initialize_command_local() {
core::DownloadList* dList = control->core()->download_list();
core::DownloadStore* dStore = control->core()->download_store();
CMD2_ANY ("system.hostname", std::bind(&system_hostname));
CMD2_ANY ("system.pid", std::bind(&getpid));
CMD2_ANY ("system.hostname", tr1::bind(&system_hostname));
CMD2_ANY ("system.pid", tr1::bind(&getpid));
CMD2_VAR_C_STRING("system.api_version", (int64_t)API_VERSION);
CMD2_VAR_C_STRING("system.client_version", PACKAGE_VERSION);
CMD2_VAR_C_STRING("system.library_version", torrent::version());
CMD2_VAR_VALUE ("system.file.allocate", 0);
CMD2_VAR_VALUE ("system.file.max_size", (int64_t)64 << 30);
CMD2_VAR_VALUE ("system.file.max_size", (int64_t)128 << 30);
CMD2_VAR_VALUE ("system.file.split_size", -1);
CMD2_VAR_STRING ("system.file.split_suffix", ".part");
CMD2_ANY ("system.file_status_cache.size", std::bind(&utils::FileStatusCache::size,
CMD2_ANY ("system.file_status_cache.size", tr1::bind(&utils::FileStatusCache::size,
(utils::FileStatusCache::base_type*)control->core()->file_status_cache()));
CMD2_ANY_V ("system.file_status_cache.prune", std::bind(&utils::FileStatusCache::prune, control->core()->file_status_cache()));
CMD2_ANY_V ("system.file_status_cache.prune", tr1::bind(&utils::FileStatusCache::prune, control->core()->file_status_cache()));
CMD2_VAR_BOOL ("file.prioritize_toc", 0);
CMD2_VAR_LIST ("file.prioritize_toc.first");
CMD2_VAR_LIST ("file.prioritize_toc.last");
CMD2_ANY ("system.files.opened_counter", std::bind(&FM_t::files_opened_counter, fileManager));
CMD2_ANY ("system.files.closed_counter", std::bind(&FM_t::files_closed_counter, fileManager));
CMD2_ANY ("system.files.failed_counter", std::bind(&FM_t::files_failed_counter, fileManager));
CMD2_ANY ("system.files.opened_counter", tr1::bind(&FM_t::files_opened_counter, fileManager));
CMD2_ANY ("system.files.closed_counter", tr1::bind(&FM_t::files_closed_counter, fileManager));
CMD2_ANY ("system.files.failed_counter", tr1::bind(&FM_t::files_failed_counter, fileManager));
CMD2_ANY ("system.time", std::bind(&rak::timer::seconds, &cachedTime));
CMD2_ANY ("system.time_seconds", std::bind(&rak::timer::current_seconds));
CMD2_ANY ("system.time_usec", std::bind(&rak::timer::current_usec));
CMD2_ANY ("system.time", tr1::bind(&rak::timer::seconds, &cachedTime));
CMD2_ANY ("system.time_seconds", tr1::bind(&rak::timer::current_seconds));
CMD2_ANY ("system.time_usec", tr1::bind(&rak::timer::current_usec));
CMD2_ANY_VALUE_V ("system.umask.set", std::bind(&umask, std::placeholders::_2));
CMD2_ANY_VALUE_V ("system.umask.set", tr1::bind(&umask, tr1::placeholders::_2));
CMD2_ANY ("system.cwd", std::bind(&system_get_cwd));
CMD2_ANY_STRING ("system.cwd.set", std::bind(&system_set_cwd, std::placeholders::_2));
CMD2_ANY ("system.cwd", tr1::bind(&system_get_cwd));
CMD2_ANY_STRING ("system.cwd.set", tr1::bind(&system_set_cwd, tr1::placeholders::_2));
CMD2_ANY ("pieces.sync.always_safe", std::bind(&CM_t::safe_sync, chunkManager));
CMD2_ANY_VALUE_V ("pieces.sync.always_safe.set", std::bind(&CM_t::set_safe_sync, chunkManager, std::placeholders::_2));
CMD2_ANY ("pieces.sync.safe_free_diskspace", std::bind(&CM_t::safe_free_diskspace, chunkManager));
CMD2_ANY ("pieces.sync.timeout", std::bind(&CM_t::timeout_sync, chunkManager));
CMD2_ANY_VALUE_V ("pieces.sync.timeout.set", std::bind(&CM_t::set_timeout_sync, chunkManager, std::placeholders::_2));
CMD2_ANY ("pieces.sync.timeout_safe", std::bind(&CM_t::timeout_safe_sync, chunkManager));
CMD2_ANY_VALUE_V ("pieces.sync.timeout_safe.set", std::bind(&CM_t::set_timeout_safe_sync, chunkManager, std::placeholders::_2));
CMD2_ANY ("pieces.sync.queue_size", std::bind(&CM_t::sync_queue_size, chunkManager));
CMD2_ANY ("pieces.sync.always_safe", tr1::bind(&CM_t::safe_sync, chunkManager));
CMD2_ANY_VALUE_V ("pieces.sync.always_safe.set", tr1::bind(&CM_t::set_safe_sync, chunkManager, tr1::placeholders::_2));
CMD2_ANY ("pieces.sync.safe_free_diskspace", tr1::bind(&CM_t::safe_free_diskspace, chunkManager));
CMD2_ANY ("pieces.sync.timeout", tr1::bind(&CM_t::timeout_sync, chunkManager));
CMD2_ANY_VALUE_V ("pieces.sync.timeout.set", tr1::bind(&CM_t::set_timeout_sync, chunkManager, tr1::placeholders::_2));
CMD2_ANY ("pieces.sync.timeout_safe", tr1::bind(&CM_t::timeout_safe_sync, chunkManager));
CMD2_ANY_VALUE_V ("pieces.sync.timeout_safe.set", tr1::bind(&CM_t::set_timeout_safe_sync, chunkManager, tr1::placeholders::_2));
CMD2_ANY ("pieces.sync.queue_size", tr1::bind(&CM_t::sync_queue_size, chunkManager));
CMD2_ANY ("pieces.preload.type", std::bind(&CM_t::preload_type, chunkManager));
CMD2_ANY_VALUE_V ("pieces.preload.type.set", std::bind(&CM_t::set_preload_type, chunkManager, std::placeholders::_2));
CMD2_ANY ("pieces.preload.min_size", std::bind(&CM_t::preload_min_size, chunkManager));
CMD2_ANY_VALUE_V ("pieces.preload.min_size.set", std::bind(&CM_t::set_preload_min_size, chunkManager, std::placeholders::_2));
CMD2_ANY ("pieces.preload.min_rate", std::bind(&CM_t::preload_required_rate, chunkManager));
CMD2_ANY_VALUE_V ("pieces.preload.min_rate.set", std::bind(&CM_t::set_preload_required_rate, chunkManager, std::placeholders::_2));
CMD2_ANY ("pieces.preload.type", tr1::bind(&CM_t::preload_type, chunkManager));
CMD2_ANY_VALUE_V ("pieces.preload.type.set", tr1::bind(&CM_t::set_preload_type, chunkManager, tr1::placeholders::_2));
CMD2_ANY ("pieces.preload.min_size", tr1::bind(&CM_t::preload_min_size, chunkManager));
CMD2_ANY_VALUE_V ("pieces.preload.min_size.set", tr1::bind(&CM_t::set_preload_min_size, chunkManager, tr1::placeholders::_2));
CMD2_ANY ("pieces.preload.min_rate", tr1::bind(&CM_t::preload_required_rate, chunkManager));
CMD2_ANY_VALUE_V ("pieces.preload.min_rate.set", tr1::bind(&CM_t::set_preload_required_rate, chunkManager, tr1::placeholders::_2));
CMD2_ANY ("pieces.memory.current", std::bind(&CM_t::memory_usage, chunkManager));
CMD2_ANY ("pieces.memory.sync_queue", std::bind(&CM_t::sync_queue_memory_usage, chunkManager));
CMD2_ANY ("pieces.memory.block_count", std::bind(&CM_t::memory_block_count, chunkManager));
CMD2_ANY ("pieces.memory.max", std::bind(&CM_t::max_memory_usage, chunkManager));
CMD2_ANY_VALUE_V ("pieces.memory.max.set", std::bind(&CM_t::set_max_memory_usage, chunkManager, std::placeholders::_2));
CMD2_ANY ("pieces.stats_preloaded", std::bind(&CM_t::stats_preloaded, chunkManager));
CMD2_ANY ("pieces.stats_not_preloaded", std::bind(&CM_t::stats_not_preloaded, chunkManager));
CMD2_ANY ("pieces.memory.current", tr1::bind(&CM_t::memory_usage, chunkManager));
CMD2_ANY ("pieces.memory.sync_queue", tr1::bind(&CM_t::sync_queue_memory_usage, chunkManager));
CMD2_ANY ("pieces.memory.block_count", tr1::bind(&CM_t::memory_block_count, chunkManager));
CMD2_ANY ("pieces.memory.max", tr1::bind(&CM_t::max_memory_usage, chunkManager));
CMD2_ANY_VALUE_V ("pieces.memory.max.set", tr1::bind(&CM_t::set_max_memory_usage, chunkManager, tr1::placeholders::_2));
CMD2_ANY ("pieces.stats_preloaded", tr1::bind(&CM_t::stats_preloaded, chunkManager));
CMD2_ANY ("pieces.stats_not_preloaded", tr1::bind(&CM_t::stats_not_preloaded, chunkManager));
CMD2_ANY ("pieces.stats.total_size", std::bind(&apply_pieces_stats_total_size));
CMD2_ANY ("pieces.stats.total_size", tr1::bind(&apply_pieces_stats_total_size));
CMD2_ANY ("pieces.hash.queue_size", std::bind(&torrent::hash_queue_size));
CMD2_ANY ("pieces.hash.queue_size", tr1::bind(&torrent::hash_queue_size));
CMD2_VAR_BOOL ("pieces.hash.on_completion", true);
CMD2_VAR_STRING ("directory.default", "./");
@@ -391,13 +381,13 @@ initialize_command_local() {
CMD2_VAR_BOOL ("session.use_lock", true);
CMD2_VAR_BOOL ("session.on_completion", true);
CMD2_ANY ("session.path", std::bind(&core::DownloadStore::path, dStore));
CMD2_ANY_STRING_V("session.path.set", std::bind(&core::DownloadStore::set_path, dStore, std::placeholders::_2));
CMD2_ANY ("session.path", tr1::bind(&core::DownloadStore::path, dStore));
CMD2_ANY_STRING_V("session.path.set", tr1::bind(&core::DownloadStore::set_path, dStore, tr1::placeholders::_2));
CMD2_ANY_V ("session.save", std::bind(&core::DownloadList::session_save, dList));
CMD2_ANY_V ("session.save", tr1::bind(&core::DownloadList::session_save, dList));
#define CMD2_EXECUTE(key, flags) \
CMD2_ANY(key, std::bind(&rpc::ExecFile::execute_object, &rpc::execFile, std::placeholders::_2, flags));
CMD2_ANY(key, tr1::bind(&rpc::ExecFile::execute_object, &rpc::execFile, tr1::placeholders::_2, flags));
CMD2_EXECUTE ("execute2", rpc::ExecFile::flag_expand_tilde | rpc::ExecFile::flag_throw);
CMD2_EXECUTE ("execute.throw", rpc::ExecFile::flag_expand_tilde | rpc::ExecFile::flag_throw);
@@ -411,25 +401,25 @@ initialize_command_local() {
CMD2_EXECUTE ("execute.capture", rpc::ExecFile::flag_throw | rpc::ExecFile::flag_expand_tilde | rpc::ExecFile::flag_capture);
CMD2_EXECUTE ("execute.capture_nothrow", rpc::ExecFile::flag_expand_tilde | rpc::ExecFile::flag_capture);
CMD2_ANY_LIST ("log.open_file", std::bind(&apply_log_open_file, std::placeholders::_2));
CMD2_ANY_LIST ("log.add_output", std::bind(&apply_log_add_output, std::placeholders::_2));
CMD2_ANY_LIST ("log.open_file", tr1::bind(&apply_log_open_file, tr1::placeholders::_2));
CMD2_ANY_LIST ("log.open_gz_file", tr1::bind(&apply_log_open_gz_file, tr1::placeholders::_2));
CMD2_ANY_LIST ("log.add_output", tr1::bind(&apply_log_add_output, tr1::placeholders::_2));
CMD2_ANY_STRING ("log.execute", std::bind(&apply_log, std::placeholders::_2, 0));
CMD2_ANY_STRING ("log.vmmap.dump", std::bind(&log_vmmap_dump, std::placeholders::_2));
CMD2_ANY_STRING_V("log.xmlrpc", std::bind(&ThreadWorker::set_xmlrpc_log, worker_thread, std::placeholders::_2));
CMD2_ANY_LIST ("log.libtorrent", std::bind(&apply_log_libtorrent, std::placeholders::_2));
CMD2_ANY_STRING ("log.execute", tr1::bind(&apply_log, tr1::placeholders::_2, 0));
CMD2_ANY_STRING ("log.vmmap.dump", tr1::bind(&log_vmmap_dump, tr1::placeholders::_2));
CMD2_ANY_STRING_V("log.xmlrpc", tr1::bind(&ThreadWorker::set_xmlrpc_log, worker_thread, tr1::placeholders::_2));
CMD2_ANY_LIST ("file.append", std::bind(&cmd_file_append, std::placeholders::_2));
CMD2_ANY_LIST ("file.append", tr1::bind(&cmd_file_append, tr1::placeholders::_2));
// TODO: Convert to new command types:
*rpc::command_base::argument(0) = "placeholder.0";
*rpc::command_base::argument(1) = "placeholder.1";
*rpc::command_base::argument(2) = "placeholder.2";
*rpc::command_base::argument(3) = "placeholder.3";
CMD2_ANY_P("argument.0", std::bind(&rpc::command_base::argument_ref, 0));
CMD2_ANY_P("argument.1", std::bind(&rpc::command_base::argument_ref, 1));
CMD2_ANY_P("argument.2", std::bind(&rpc::command_base::argument_ref, 2));
CMD2_ANY_P("argument.3", std::bind(&rpc::command_base::argument_ref, 3));
CMD2_ANY_P("argument.0", tr1::bind(&rpc::command_base::argument_ref, 0));
CMD2_ANY_P("argument.1", tr1::bind(&rpc::command_base::argument_ref, 1));
CMD2_ANY_P("argument.2", tr1::bind(&rpc::command_base::argument_ref, 2));
CMD2_ANY_P("argument.3", tr1::bind(&rpc::command_base::argument_ref, 3));
CMD2_ANY_LIST ("group.insert", std::bind(&group_insert, std::placeholders::_2));
CMD2_ANY_LIST ("group.insert", tr1::bind(&group_insert, tr1::placeholders::_2));
}
+52 -59
View File
@@ -62,6 +62,8 @@
#include "control.h"
#include "command_helpers.h"
namespace tr1 { using namespace std::tr1; }
torrent::Object
apply_encryption(const torrent::Object::list_type& args) {
uint32_t options_mask = torrent::ConnectionManager::encryption_none;
@@ -92,8 +94,6 @@ apply_tos(const torrent::Object::string_type& arg) {
return torrent::Object();
}
torrent::Object apply_hash_read_ahead(int arg) { torrent::set_hash_read_ahead(arg << 20); return torrent::Object(); }
torrent::Object apply_hash_interval(int arg) { torrent::set_hash_interval(arg * 1000); return torrent::Object(); }
torrent::Object apply_encoding_list(const std::string& arg) { torrent::encoding_list()->push_back(arg); return torrent::Object(); }
torrent::File*
@@ -126,10 +126,10 @@ xmlrpc_find_peer(core::Download* download, const torrent::HashString& hash) {
void
initialize_xmlrpc() {
rpc::xmlrpc.initialize();
rpc::xmlrpc.set_slot_find_download(rak::mem_fn(control->core()->download_list(), &core::DownloadList::find_hex_ptr));
rpc::xmlrpc.set_slot_find_file(rak::ptr_fn(&xmlrpc_find_file));
rpc::xmlrpc.set_slot_find_tracker(rak::ptr_fn(&xmlrpc_find_tracker));
rpc::xmlrpc.set_slot_find_peer(rak::ptr_fn(&xmlrpc_find_peer));
rpc::xmlrpc.slot_find_download() = tr1::bind(&core::DownloadList::find_hex_ptr, control->core()->download_list(), tr1::placeholders::_1);
rpc::xmlrpc.slot_find_file() = tr1::bind(&xmlrpc_find_file, tr1::placeholders::_1, tr1::placeholders::_2);
rpc::xmlrpc.slot_find_tracker() = tr1::bind(&xmlrpc_find_tracker, tr1::placeholders::_1, tr1::placeholders::_2);
rpc::xmlrpc.slot_find_peer() = tr1::bind(&xmlrpc_find_peer, tr1::placeholders::_1, tr1::placeholders::_2);
unsigned int count = 0;
@@ -140,7 +140,7 @@ initialize_xmlrpc() {
rpc::xmlrpc.insert_command(itr->first, itr->second.m_parm, itr->second.m_doc);
}
lt_log_print(torrent::LOG_RPC_INFO, "XMLRPC initialized with %u functions.", count);
lt_log_print(torrent::LOG_RPC_EVENTS, "XMLRPC initialized with %u functions.", count);
}
torrent::Object
@@ -169,7 +169,8 @@ apply_scgi(const std::string& arg, int type) {
sa.sa_inet()->clear();
saPtr = &sa;
lt_log_print(torrent::LOG_RPC_WARN, "The SCGI socket has not been bound to any address and likely poses a security risk.");
lt_log_print(torrent::LOG_RPC_EVENTS,
"The SCGI socket has not been bound to any address and likely poses a security risk.");
} else if (std::sscanf(arg.c_str(), "%1023[^:]:%i%c", address, &port, &dummy) == 2) {
if ((err = rak::address_info::get_address_info(address, PF_INET, SOCK_STREAM, &ai)) != 0)
@@ -177,7 +178,8 @@ apply_scgi(const std::string& arg, int type) {
saPtr = ai->address();
lt_log_print(torrent::LOG_RPC_WARN, "The SCGI socket is bound to a specific network device yet may still pose a security risk, consider using 'scgi_local'.");
lt_log_print(torrent::LOG_RPC_EVENTS,
"The SCGI socket is bound to a specific network device yet may still pose a security risk, consider using 'scgi_local'.");
} else {
throw torrent::input_error("Could not parse address.");
@@ -236,25 +238,23 @@ initialize_command_network() {
torrent::FileManager* fileManager = torrent::file_manager();
core::CurlStack* httpStack = control->core()->http_stack();
CMD2_ANY ("strings.connection_type", std::bind(&torrent::option_list_strings, torrent::OPTION_CONNECTION_TYPE));
CMD2_ANY ("strings.encryption", std::bind(&torrent::option_list_strings, torrent::OPTION_ENCRYPTION));
CMD2_ANY ("strings.ip_filter", std::bind(&torrent::option_list_strings, torrent::OPTION_IP_FILTER));
CMD2_ANY ("strings.ip_tos", std::bind(&torrent::option_list_strings, torrent::OPTION_IP_TOS));
CMD2_ANY ("strings.connection_type", tr1::bind(&torrent::option_list_strings, torrent::OPTION_CONNECTION_TYPE));
CMD2_ANY ("strings.encryption", tr1::bind(&torrent::option_list_strings, torrent::OPTION_ENCRYPTION));
CMD2_VAR_BOOL ("log.handshake", false);
// CMD2_ANY_STRING ("encoding_list", std::bind(&apply_encoding_list, std::placeholders::_2));
CMD2_ANY_STRING ("encoding.add", std::bind(&apply_encoding_list, std::placeholders::_2));
// CMD2_ANY_STRING ("encoding_list", tr1::bind(&apply_encoding_list, tr1::placeholders::_2));
CMD2_ANY_STRING ("encoding.add", tr1::bind(&apply_encoding_list, tr1::placeholders::_2));
// Isn't port_open used?
CMD2_VAR_BOOL ("network.port_open", true);
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.port", tr1::bind(&torrent::ConnectionManager::listen_port, cm));
CMD2_ANY ("network.listen.backlog", tr1::bind(&torrent::ConnectionManager::listen_backlog, cm));
CMD2_ANY_VALUE_V ("network.listen.backlog.set", tr1::bind(&torrent::ConnectionManager::set_listen_backlog, cm, tr1::placeholders::_2));
CMD2_VAR_BOOL ("protocol.pex", true);
CMD2_ANY_LIST ("protocol.encryption.set", std::bind(&apply_encryption, std::placeholders::_2));
CMD2_ANY_LIST ("protocol.encryption.set", tr1::bind(&apply_encryption, tr1::placeholders::_2));
CMD2_VAR_STRING ("protocol.connection.leech", "leech");
CMD2_VAR_STRING ("protocol.connection.seed", "seed");
@@ -264,50 +264,43 @@ initialize_command_network() {
CMD2_VAR_STRING ("protocol.choke_heuristics.down.leech", "download_leech");
CMD2_VAR_STRING ("protocol.choke_heuristics.down.seed", "download_leech");
CMD2_ANY ("network.http.capath", std::bind(&core::CurlStack::http_capath, httpStack));
CMD2_ANY_STRING_V("network.http.capath.set", std::bind(&core::CurlStack::set_http_capath, httpStack, std::placeholders::_2));
CMD2_ANY ("network.http.cacert", std::bind(&core::CurlStack::http_cacert, httpStack));
CMD2_ANY_STRING_V("network.http.cacert.set", std::bind(&core::CurlStack::set_http_cacert, httpStack, std::placeholders::_2));
CMD2_ANY ("network.http.proxy_address", std::bind(&core::CurlStack::http_proxy, httpStack));
CMD2_ANY_STRING_V("network.http.proxy_address.set", std::bind(&core::CurlStack::set_http_proxy, httpStack, std::placeholders::_2));
CMD2_ANY ("network.http.max_open", std::bind(&core::CurlStack::max_active, httpStack));
CMD2_ANY_VALUE_V ("network.http.max_open.set", std::bind(&core::CurlStack::set_max_active, httpStack, std::placeholders::_2));
CMD2_ANY ("network.http.ssl_verify_peer", std::bind(&core::CurlStack::ssl_verify_peer, httpStack));
CMD2_ANY_VALUE_V ("network.http.ssl_verify_peer.set", std::bind(&core::CurlStack::set_ssl_verify_peer, httpStack, std::placeholders::_2));
CMD2_ANY ("network.http.dns_cache_timeout", std::bind(&core::CurlStack::dns_timeout, httpStack));
CMD2_ANY_VALUE_V ("network.http.dns_cache_timeout.set", std::bind(&core::CurlStack::set_dns_timeout, httpStack, std::placeholders::_2));
CMD2_ANY ("network.http.capath", tr1::bind(&core::CurlStack::http_capath, httpStack));
CMD2_ANY_STRING_V("network.http.capath.set", tr1::bind(&core::CurlStack::set_http_capath, httpStack, tr1::placeholders::_2));
CMD2_ANY ("network.http.cacert", tr1::bind(&core::CurlStack::http_cacert, httpStack));
CMD2_ANY_STRING_V("network.http.cacert.set", tr1::bind(&core::CurlStack::set_http_cacert, httpStack, tr1::placeholders::_2));
CMD2_ANY ("network.http.proxy_address", tr1::bind(&core::CurlStack::http_proxy, httpStack));
CMD2_ANY_STRING_V("network.http.proxy_address.set", tr1::bind(&core::CurlStack::set_http_proxy, httpStack, tr1::placeholders::_2));
CMD2_ANY ("network.http.max_open", tr1::bind(&core::CurlStack::max_active, httpStack));
CMD2_ANY_VALUE_V ("network.http.max_open.set", tr1::bind(&core::CurlStack::set_max_active, httpStack, tr1::placeholders::_2));
CMD2_ANY ("network.http.ssl_verify_peer", tr1::bind(&core::CurlStack::ssl_verify_peer, httpStack));
CMD2_ANY_VALUE_V ("network.http.ssl_verify_peer.set", tr1::bind(&core::CurlStack::set_ssl_verify_peer, httpStack, tr1::placeholders::_2));
CMD2_ANY ("network.http.dns_cache_timeout", tr1::bind(&core::CurlStack::dns_timeout, httpStack));
CMD2_ANY_VALUE_V ("network.http.dns_cache_timeout.set", tr1::bind(&core::CurlStack::set_dns_timeout, httpStack, tr1::placeholders::_2));
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", tr1::bind(&torrent::ConnectionManager::send_buffer_size, cm));
CMD2_ANY_VALUE_V ("network.send_buffer.size.set", tr1::bind(&torrent::ConnectionManager::set_send_buffer_size, cm, tr1::placeholders::_2));
CMD2_ANY ("network.receive_buffer.size", tr1::bind(&torrent::ConnectionManager::receive_buffer_size, cm));
CMD2_ANY_VALUE_V ("network.receive_buffer.size.set", tr1::bind(&torrent::ConnectionManager::set_receive_buffer_size, cm, tr1::placeholders::_2));
CMD2_ANY_STRING ("network.tos.set", tr1::bind(&apply_tos, tr1::placeholders::_2));
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", tr1::bind(&core::Manager::bind_address, control->core()));
CMD2_ANY_STRING_V("network.bind_address.set", tr1::bind(&core::Manager::set_bind_address, control->core(), tr1::placeholders::_2));
CMD2_ANY ("network.local_address", tr1::bind(&core::Manager::local_address, control->core()));
CMD2_ANY_STRING_V("network.local_address.set", tr1::bind(&core::Manager::set_local_address, control->core(), tr1::placeholders::_2));
CMD2_ANY ("network.proxy_address", tr1::bind(&core::Manager::proxy_address, control->core()));
CMD2_ANY_STRING_V("network.proxy_address.set", tr1::bind(&core::Manager::set_proxy_address, control->core(), tr1::placeholders::_2));
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.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.max_open_files", tr1::bind(&torrent::FileManager::max_open_files, fileManager));
CMD2_ANY_VALUE_V ("network.max_open_files.set", tr1::bind(&torrent::FileManager::set_max_open_files, fileManager, tr1::placeholders::_2));
CMD2_ANY ("network.open_sockets", tr1::bind(&torrent::ConnectionManager::size, cm));
CMD2_ANY ("network.max_open_sockets", tr1::bind(&torrent::ConnectionManager::max_size, cm));
CMD2_ANY_VALUE_V ("network.max_open_sockets.set", tr1::bind(&torrent::ConnectionManager::set_max_size, cm, tr1::placeholders::_2));
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_ANY_STRING ("network.scgi.open_port", tr1::bind(&apply_scgi, tr1::placeholders::_2, 1));
CMD2_ANY_STRING ("network.scgi.open_local", tr1::bind(&apply_scgi, tr1::placeholders::_2, 2));
CMD2_VAR_BOOL ("network.scgi.dont_route", false);
CMD2_ANY_STRING ("network.xmlrpc.dialect.set", std::bind(&apply_xmlrpc_dialect, std::placeholders::_2));
CMD2_ANY ("network.xmlrpc.size_limit", std::bind(&rpc::XmlRpc::size_limit));
CMD2_ANY_VALUE_V ("network.xmlrpc.size_limit.set", std::bind(&rpc::XmlRpc::set_size_limit, std::placeholders::_2));
CMD2_ANY ("system.hash.read_ahead", std::bind(&torrent::hash_read_ahead));
CMD2_ANY_VALUE_V ("system.hash.read_ahead.set", std::bind(&apply_hash_read_ahead, std::placeholders::_2));
CMD2_ANY ("system.hash.interval", std::bind(&torrent::hash_interval));
CMD2_ANY_VALUE_V ("system.hash.interval.set", std::bind(&apply_hash_interval, std::placeholders::_2));
CMD2_ANY ("system.hash.max_tries", std::bind(&torrent::hash_max_tries));
CMD2_ANY_VALUE_V ("system.hash.max_tries.set", std::bind(&torrent::set_hash_max_tries, std::placeholders::_2));
CMD2_ANY_STRING ("network.xmlrpc.dialect.set", tr1::bind(&apply_xmlrpc_dialect, tr1::placeholders::_2));
CMD2_ANY ("network.xmlrpc.size_limit", tr1::bind(&rpc::XmlRpc::size_limit));
CMD2_ANY_VALUE_V ("network.xmlrpc.size_limit.set", tr1::bind(&rpc::XmlRpc::set_size_limit, tr1::placeholders::_2));
}
+25 -25
View File
@@ -97,37 +97,37 @@ retrieve_p_completed_percent(torrent::Peer* peer) {
void
initialize_command_peer() {
CMD2_PEER("p.id", std::bind(&retrieve_p_id, std::placeholders::_1));
CMD2_PEER("p.id_html", std::bind(&retrieve_p_id_html, std::placeholders::_1));
CMD2_PEER("p.client_version", std::bind(&retrieve_p_client_version, std::placeholders::_1));
CMD2_PEER("p.id", tr1::bind(&retrieve_p_id, tr1::placeholders::_1));
CMD2_PEER("p.id_html", tr1::bind(&retrieve_p_id_html, tr1::placeholders::_1));
CMD2_PEER("p.client_version", tr1::bind(&retrieve_p_client_version, tr1::placeholders::_1));
CMD2_PEER("p.options_str", std::bind(&retrieve_p_options_str, std::placeholders::_1));
CMD2_PEER("p.options_str", tr1::bind(&retrieve_p_options_str, tr1::placeholders::_1));
CMD2_PEER("p.is_encrypted", std::bind(&torrent::Peer::is_encrypted, std::placeholders::_1));
CMD2_PEER("p.is_incoming", std::bind(&torrent::Peer::is_incoming, std::placeholders::_1));
CMD2_PEER("p.is_obfuscated", std::bind(&torrent::Peer::is_obfuscated, std::placeholders::_1));
CMD2_PEER("p.is_snubbed", std::bind(&torrent::Peer::is_snubbed, std::placeholders::_1));
CMD2_PEER("p.is_encrypted", tr1::bind(&torrent::Peer::is_encrypted, tr1::placeholders::_1));
CMD2_PEER("p.is_incoming", tr1::bind(&torrent::Peer::is_incoming, tr1::placeholders::_1));
CMD2_PEER("p.is_obfuscated", tr1::bind(&torrent::Peer::is_obfuscated, tr1::placeholders::_1));
CMD2_PEER("p.is_snubbed", tr1::bind(&torrent::Peer::is_snubbed, tr1::placeholders::_1));
CMD2_PEER("p.is_unwanted", std::bind(&torrent::PeerInfo::is_unwanted, std::bind(&torrent::Peer::peer_info, std::placeholders::_1)));
CMD2_PEER("p.is_preferred", std::bind(&torrent::PeerInfo::is_preferred, std::bind(&torrent::Peer::peer_info, std::placeholders::_1)));
CMD2_PEER("p.is_unwanted", tr1::bind(&torrent::PeerInfo::is_unwanted, tr1::bind(&torrent::Peer::peer_info, tr1::placeholders::_1)));
CMD2_PEER("p.is_preferred", tr1::bind(&torrent::PeerInfo::is_preferred, tr1::bind(&torrent::Peer::peer_info, tr1::placeholders::_1)));
CMD2_PEER("p.address", std::bind(&retrieve_p_address, std::placeholders::_1));
CMD2_PEER("p.port", std::bind(&retrieve_p_port, std::placeholders::_1));
CMD2_PEER("p.address", tr1::bind(&retrieve_p_address, tr1::placeholders::_1));
CMD2_PEER("p.port", tr1::bind(&retrieve_p_port, tr1::placeholders::_1));
CMD2_PEER("p.completed_percent", std::bind(&retrieve_p_completed_percent, std::placeholders::_1));
CMD2_PEER("p.completed_percent", tr1::bind(&retrieve_p_completed_percent, tr1::placeholders::_1));
CMD2_PEER("p.up_rate", std::bind(&torrent::Rate::rate, std::bind(&torrent::Peer::up_rate, std::placeholders::_1)));
CMD2_PEER("p.up_total", std::bind(&torrent::Rate::total, std::bind(&torrent::Peer::up_rate, std::placeholders::_1)));
CMD2_PEER("p.down_rate", std::bind(&torrent::Rate::rate, std::bind(&torrent::Peer::down_rate, std::placeholders::_1)));
CMD2_PEER("p.down_total", std::bind(&torrent::Rate::total, std::bind(&torrent::Peer::down_rate, std::placeholders::_1)));
CMD2_PEER("p.peer_rate", std::bind(&torrent::Rate::rate, std::bind(&torrent::Peer::peer_rate, std::placeholders::_1)));
CMD2_PEER("p.peer_total", std::bind(&torrent::Rate::total, std::bind(&torrent::Peer::peer_rate, std::placeholders::_1)));
CMD2_PEER("p.up_rate", tr1::bind(&torrent::Rate::rate, tr1::bind(&torrent::Peer::up_rate, tr1::placeholders::_1)));
CMD2_PEER("p.up_total", tr1::bind(&torrent::Rate::total, tr1::bind(&torrent::Peer::up_rate, tr1::placeholders::_1)));
CMD2_PEER("p.down_rate", tr1::bind(&torrent::Rate::rate, tr1::bind(&torrent::Peer::down_rate, tr1::placeholders::_1)));
CMD2_PEER("p.down_total", tr1::bind(&torrent::Rate::total, tr1::bind(&torrent::Peer::down_rate, tr1::placeholders::_1)));
CMD2_PEER("p.peer_rate", tr1::bind(&torrent::Rate::rate, tr1::bind(&torrent::Peer::peer_rate, tr1::placeholders::_1)));
CMD2_PEER("p.peer_total", tr1::bind(&torrent::Rate::total, tr1::bind(&torrent::Peer::peer_rate, tr1::placeholders::_1)));
CMD2_PEER ("p.snubbed", std::bind(&torrent::Peer::is_snubbed, std::placeholders::_1));
CMD2_PEER_VALUE_V("p.snubbed.set", std::bind(&torrent::Peer::set_snubbed, std::placeholders::_1, std::placeholders::_2));
CMD2_PEER ("p.banned", std::bind(&torrent::Peer::is_banned, std::placeholders::_1));
CMD2_PEER_VALUE_V("p.banned.set", std::bind(&torrent::Peer::set_banned, std::placeholders::_1, std::placeholders::_2));
CMD2_PEER ("p.snubbed", tr1::bind(&torrent::Peer::is_snubbed, tr1::placeholders::_1));
CMD2_PEER_VALUE_V("p.snubbed.set", tr1::bind(&torrent::Peer::set_snubbed, tr1::placeholders::_1, tr1::placeholders::_2));
CMD2_PEER ("p.banned", tr1::bind(&torrent::Peer::is_banned, tr1::placeholders::_1));
CMD2_PEER_VALUE_V("p.banned.set", tr1::bind(&torrent::Peer::set_banned, tr1::placeholders::_1, tr1::placeholders::_2));
CMD2_PEER_V("p.disconnect", std::bind(&torrent::Peer::disconnect, std::placeholders::_1, 0));
CMD2_PEER_V("p.disconnect_delayed", std::bind(&torrent::Peer::disconnect, std::placeholders::_1, torrent::ConnectionList::disconnect_delayed));
CMD2_PEER_V("p.disconnect", tr1::bind(&torrent::Peer::disconnect, tr1::placeholders::_1, 0));
CMD2_PEER_V("p.disconnect_delayed", tr1::bind(&torrent::Peer::disconnect, tr1::placeholders::_1, torrent::ConnectionList::disconnect_delayed));
}
+3 -3
View File
@@ -115,7 +115,7 @@ void
initialize_command_scheduler() {
CMD2_VAR_VALUE("scheduler.max_active", int64_t(-1));
CMD2_DL("scheduler.simple.added", std::bind(&cmd_scheduler_simple_added, std::placeholders::_1));
CMD2_DL("scheduler.simple.removed", std::bind(&cmd_scheduler_simple_removed, std::placeholders::_1));
CMD2_DL("scheduler.simple.update", std::bind(&cmd_scheduler_simple_update, std::placeholders::_1));
CMD2_DL("scheduler.simple.added", tr1::bind(&cmd_scheduler_simple_added, tr1::placeholders::_1));
CMD2_DL("scheduler.simple.removed", tr1::bind(&cmd_scheduler_simple_removed, tr1::placeholders::_1));
CMD2_DL("scheduler.simple.update", tr1::bind(&cmd_scheduler_simple_update, tr1::placeholders::_1));
}
+43 -24
View File
@@ -89,7 +89,7 @@ parse_address_range(const torrent::Object::list_type& args, torrent::Object::lis
// convert to [begin, end) making sure the end doesn't overflow
// (this precludes 255.255.255.255 from ever matching, but that's not a real IP anyway)
return std::make_pair<uint32_t, uint32_t>(begin, std::max(end, end + 1));
return std::make_pair((uint32_t)begin, (uint32_t)std::max(end, end + 1));
}
torrent::Object
@@ -162,10 +162,19 @@ apply_address_throttle(const torrent::Object::list_type& args) {
return torrent::Object();
}
torrent::Object
throttle_update(const char* variable, int64_t value) {
rpc::commands.call_command(variable, value);
control->ui()->adjust_up_throttle(0);
control->ui()->adjust_down_throttle(0);
return torrent::Object();
}
void
initialize_command_throttle() {
CMD2_ANY ("throttle.unchoked_uploads", std::bind(&torrent::ResourceManager::currently_upload_unchoked, torrent::resource_manager()));
CMD2_ANY ("throttle.unchoked_downloads", std::bind(&torrent::ResourceManager::currently_download_unchoked, torrent::resource_manager()));
CMD2_ANY ("throttle.unchoked_uploads", tr1::bind(&torrent::ResourceManager::currently_upload_unchoked, torrent::resource_manager()));
CMD2_ANY ("throttle.unchoked_downloads", tr1::bind(&torrent::ResourceManager::currently_download_unchoked, torrent::resource_manager()));
CMD2_VAR_VALUE ("throttle.min_peers.normal", 100);
CMD2_VAR_VALUE ("throttle.max_peers.normal", 200);
@@ -177,31 +186,41 @@ initialize_command_throttle() {
CMD2_VAR_VALUE ("throttle.min_downloads", 0);
CMD2_VAR_VALUE ("throttle.max_downloads", 50);
CMD2_VAR_VALUE ("throttle.max_uploads.div", 1);
CMD2_VAR_VALUE ("throttle.max_uploads.global", 0);
CMD2_VAR_VALUE ("throttle.max_downloads.div", 1);
CMD2_VAR_VALUE ("throttle.max_downloads.global", 0);
CMD2_VAR_VALUE ("throttle.max_uploads.div._val", 1);
CMD2_VAR_VALUE ("throttle.max_uploads.global._val", 0);
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_ANY_VALUE ("throttle.max_uploads.div.set", tr1::bind(&throttle_update, "throttle.max_uploads.div._val.set", tr1::placeholders::_2));
CMD2_ANY_VALUE ("throttle.max_uploads.global.set", tr1::bind(&throttle_update, "throttle.max_uploads.global._val.set", tr1::placeholders::_2));
CMD2_ANY_VALUE ("throttle.max_downloads.div.set", tr1::bind(&throttle_update, "throttle.max_downloads.div._val.set", tr1::placeholders::_2));
CMD2_ANY_VALUE ("throttle.max_downloads.global.set", tr1::bind(&throttle_update, "throttle.max_downloads.global._val.set", tr1::placeholders::_2));
// TODO: Move the logic into some libtorrent function.
CMD2_ANY ("throttle.global_up.rate", std::bind(&torrent::Rate::rate, torrent::up_rate()));
CMD2_ANY ("throttle.global_up.total", std::bind(&torrent::Rate::total, torrent::up_rate()));
CMD2_ANY ("throttle.global_up.max_rate", std::bind(&torrent::Throttle::max_rate, torrent::up_throttle_global()));
CMD2_ANY_VALUE_V ("throttle.global_up.max_rate.set", std::bind(&ui::Root::set_up_throttle_i64, control->ui(), std::placeholders::_2));
CMD2_ANY_VALUE_KB("throttle.global_up.max_rate.set_kb", std::bind(&ui::Root::set_up_throttle_i64, control->ui(), std::placeholders::_2));
CMD2_ANY ("throttle.global_down.rate", std::bind(&torrent::Rate::rate, torrent::down_rate()));
CMD2_ANY ("throttle.global_down.total", std::bind(&torrent::Rate::total, torrent::down_rate()));
CMD2_ANY ("throttle.global_down.max_rate", std::bind(&torrent::Throttle::max_rate, torrent::down_throttle_global()));
CMD2_ANY_VALUE_V ("throttle.global_down.max_rate.set", std::bind(&ui::Root::set_down_throttle_i64, control->ui(), std::placeholders::_2));
CMD2_ANY_VALUE_KB("throttle.global_down.max_rate.set_kb", std::bind(&ui::Root::set_down_throttle_i64, control->ui(), std::placeholders::_2));
CMD2_ANY ("throttle.global_up.rate", tr1::bind(&torrent::Rate::rate, torrent::up_rate()));
CMD2_ANY ("throttle.global_up.total", tr1::bind(&torrent::Rate::total, torrent::up_rate()));
CMD2_ANY ("throttle.global_up.max_rate", tr1::bind(&torrent::Throttle::max_rate, torrent::up_throttle_global()));
CMD2_ANY_VALUE_V ("throttle.global_up.max_rate.set", tr1::bind(&ui::Root::set_up_throttle_i64, control->ui(), tr1::placeholders::_2));
CMD2_ANY_VALUE_KB("throttle.global_up.max_rate.set_kb", tr1::bind(&ui::Root::set_up_throttle_i64, control->ui(), tr1::placeholders::_2));
CMD2_ANY ("throttle.global_down.rate", tr1::bind(&torrent::Rate::rate, torrent::down_rate()));
CMD2_ANY ("throttle.global_down.total", tr1::bind(&torrent::Rate::total, torrent::down_rate()));
CMD2_ANY ("throttle.global_down.max_rate", tr1::bind(&torrent::Throttle::max_rate, torrent::down_throttle_global()));
CMD2_ANY_VALUE_V ("throttle.global_down.max_rate.set", tr1::bind(&ui::Root::set_down_throttle_i64, control->ui(), tr1::placeholders::_2));
CMD2_ANY_VALUE_KB("throttle.global_down.max_rate.set_kb", tr1::bind(&ui::Root::set_down_throttle_i64, control->ui(), tr1::placeholders::_2));
// Temporary names, need to change this to accept real rates rather
// than kB.
CMD2_ANY_LIST ("throttle.up", std::bind(&apply_throttle, std::placeholders::_2, true));
CMD2_ANY_LIST ("throttle.down", std::bind(&apply_throttle, std::placeholders::_2, false));
CMD2_ANY_LIST ("throttle.ip", std::bind(&apply_address_throttle, std::placeholders::_2));
CMD2_ANY_LIST ("throttle.up", tr1::bind(&apply_throttle, tr1::placeholders::_2, true));
CMD2_ANY_LIST ("throttle.down", tr1::bind(&apply_throttle, tr1::placeholders::_2, false));
CMD2_ANY_LIST ("throttle.ip", tr1::bind(&apply_address_throttle, tr1::placeholders::_2));
CMD2_ANY_STRING ("throttle.up.max", std::bind(&retrieve_throttle_info, std::placeholders::_2, throttle_info_up | throttle_info_max));
CMD2_ANY_STRING ("throttle.up.rate", std::bind(&retrieve_throttle_info, std::placeholders::_2, throttle_info_up | throttle_info_rate));
CMD2_ANY_STRING ("throttle.down.max", std::bind(&retrieve_throttle_info, std::placeholders::_2, throttle_info_down | throttle_info_max));
CMD2_ANY_STRING ("throttle.down.rate", std::bind(&retrieve_throttle_info, std::placeholders::_2, throttle_info_down | throttle_info_rate));
CMD2_ANY_STRING ("throttle.up.max", tr1::bind(&retrieve_throttle_info, tr1::placeholders::_2, throttle_info_up | throttle_info_max));
CMD2_ANY_STRING ("throttle.up.rate", tr1::bind(&retrieve_throttle_info, tr1::placeholders::_2, throttle_info_up | throttle_info_rate));
CMD2_ANY_STRING ("throttle.down.max", tr1::bind(&retrieve_throttle_info, tr1::placeholders::_2, throttle_info_down | throttle_info_max));
CMD2_ANY_STRING ("throttle.down.rate", tr1::bind(&retrieve_throttle_info, tr1::placeholders::_2, throttle_info_down | throttle_info_rate));
}
+41 -30
View File
@@ -111,48 +111,59 @@ apply_enable_trackers(int64_t arg) {
void
initialize_command_tracker() {
CMD2_TRACKER ("t.is_open", std::bind(&torrent::Tracker::is_busy, std::placeholders::_1));
CMD2_TRACKER ("t.is_enabled", std::bind(&torrent::Tracker::is_enabled, std::placeholders::_1));
CMD2_TRACKER_VALUE_V("t.is_enabled.set", std::bind(&tracker_set_enabled, std::placeholders::_1, std::placeholders::_2));
CMD2_TRACKER_V ("t.enable", std::bind(&torrent::Tracker::enable, std::placeholders::_1));
CMD2_TRACKER_V ("t.disable", std::bind(&torrent::Tracker::disable, std::placeholders::_1));
CMD2_TRACKER ("t.is_open", tr1::bind(&torrent::Tracker::is_busy, tr1::placeholders::_1));
CMD2_TRACKER ("t.is_enabled", tr1::bind(&torrent::Tracker::is_enabled, tr1::placeholders::_1));
CMD2_TRACKER ("t.is_usable", tr1::bind(&torrent::Tracker::is_usable, tr1::placeholders::_1));
CMD2_TRACKER ("t.is_busy", tr1::bind(&torrent::Tracker::is_busy, tr1::placeholders::_1));
CMD2_TRACKER ("t.is_extra_tracker", tr1::bind(&torrent::Tracker::is_extra_tracker, tr1::placeholders::_1));
CMD2_TRACKER ("t.can_scrape", tr1::bind(&torrent::Tracker::can_scrape, tr1::placeholders::_1));
CMD2_TRACKER ("t.url", std::bind(&torrent::Tracker::url, std::placeholders::_1));
CMD2_TRACKER ("t.group", std::bind(&torrent::Tracker::group, std::placeholders::_1));
CMD2_TRACKER ("t.type", std::bind(&torrent::Tracker::type, std::placeholders::_1));
CMD2_TRACKER ("t.id", std::bind(&torrent::Tracker::tracker_id, std::placeholders::_1));
CMD2_TRACKER_V ("t.enable", tr1::bind(&torrent::Tracker::enable, tr1::placeholders::_1));
CMD2_TRACKER_V ("t.disable", tr1::bind(&torrent::Tracker::disable, tr1::placeholders::_1));
CMD2_TRACKER ("t.latest_event", std::bind(&torrent::Tracker::latest_event, std::placeholders::_1));
CMD2_TRACKER ("t.latest_new_peers", std::bind(&torrent::Tracker::latest_new_peers, std::placeholders::_1));
CMD2_TRACKER ("t.latest_sum_peers", std::bind(&torrent::Tracker::latest_sum_peers, std::placeholders::_1));
CMD2_TRACKER_VALUE_V("t.is_enabled.set", tr1::bind(&tracker_set_enabled, tr1::placeholders::_1, tr1::placeholders::_2));
CMD2_TRACKER ("t.url", tr1::bind(&torrent::Tracker::url, tr1::placeholders::_1));
CMD2_TRACKER ("t.group", tr1::bind(&torrent::Tracker::group, tr1::placeholders::_1));
CMD2_TRACKER ("t.type", tr1::bind(&torrent::Tracker::type, tr1::placeholders::_1));
CMD2_TRACKER ("t.id", tr1::bind(&torrent::Tracker::tracker_id, tr1::placeholders::_1));
CMD2_TRACKER ("t.latest_event", tr1::bind(&torrent::Tracker::latest_event, tr1::placeholders::_1));
CMD2_TRACKER ("t.latest_new_peers", tr1::bind(&torrent::Tracker::latest_new_peers, tr1::placeholders::_1));
CMD2_TRACKER ("t.latest_sum_peers", tr1::bind(&torrent::Tracker::latest_sum_peers, tr1::placeholders::_1));
// Time since last connection, connection attempt.
CMD2_TRACKER ("t.normal_interval", std::bind(&torrent::Tracker::normal_interval, std::placeholders::_1));
CMD2_TRACKER ("t.min_interval", std::bind(&torrent::Tracker::min_interval, std::placeholders::_1));
CMD2_TRACKER ("t.normal_interval", tr1::bind(&torrent::Tracker::normal_interval, tr1::placeholders::_1));
CMD2_TRACKER ("t.min_interval", tr1::bind(&torrent::Tracker::min_interval, tr1::placeholders::_1));
CMD2_TRACKER ("t.success_time_last", std::bind(&torrent::Tracker::success_time_last, std::placeholders::_1));
CMD2_TRACKER ("t.success_counter", std::bind(&torrent::Tracker::success_counter, std::placeholders::_1));
CMD2_TRACKER ("t.activity_time_next", tr1::bind(&torrent::Tracker::activity_time_next, tr1::placeholders::_1));
CMD2_TRACKER ("t.activity_time_last", tr1::bind(&torrent::Tracker::activity_time_last, tr1::placeholders::_1));
CMD2_TRACKER ("t.failed_time_last", std::bind(&torrent::Tracker::failed_time_last, std::placeholders::_1));
CMD2_TRACKER ("t.failed_counter", std::bind(&torrent::Tracker::failed_counter, std::placeholders::_1));
CMD2_TRACKER ("t.success_time_next", tr1::bind(&torrent::Tracker::success_time_next, tr1::placeholders::_1));
CMD2_TRACKER ("t.success_time_last", tr1::bind(&torrent::Tracker::success_time_last, tr1::placeholders::_1));
CMD2_TRACKER ("t.success_counter", tr1::bind(&torrent::Tracker::success_counter, tr1::placeholders::_1));
CMD2_TRACKER ("t.scrape_time_last", std::bind(&torrent::Tracker::scrape_time_last, std::placeholders::_1));
CMD2_TRACKER ("t.scrape_counter", std::bind(&torrent::Tracker::scrape_counter, std::placeholders::_1));
CMD2_TRACKER ("t.failed_time_next", tr1::bind(&torrent::Tracker::failed_time_next, tr1::placeholders::_1));
CMD2_TRACKER ("t.failed_time_last", tr1::bind(&torrent::Tracker::failed_time_last, tr1::placeholders::_1));
CMD2_TRACKER ("t.failed_counter", tr1::bind(&torrent::Tracker::failed_counter, tr1::placeholders::_1));
CMD2_TRACKER ("t.scrape_complete", std::bind(&torrent::Tracker::scrape_complete, std::placeholders::_1));
CMD2_TRACKER ("t.scrape_incomplete", std::bind(&torrent::Tracker::scrape_incomplete, std::placeholders::_1));
CMD2_TRACKER ("t.scrape_downloaded", std::bind(&torrent::Tracker::scrape_downloaded, std::placeholders::_1));
CMD2_TRACKER ("t.scrape_time_last", tr1::bind(&torrent::Tracker::scrape_time_last, tr1::placeholders::_1));
CMD2_TRACKER ("t.scrape_counter", tr1::bind(&torrent::Tracker::scrape_counter, tr1::placeholders::_1));
CMD2_ANY_VALUE ("trackers.enable", std::bind(&apply_enable_trackers, int64_t(1)));
CMD2_ANY_VALUE ("trackers.disable", std::bind(&apply_enable_trackers, int64_t(0)));
CMD2_TRACKER ("t.scrape_complete", tr1::bind(&torrent::Tracker::scrape_complete, tr1::placeholders::_1));
CMD2_TRACKER ("t.scrape_incomplete", tr1::bind(&torrent::Tracker::scrape_incomplete, tr1::placeholders::_1));
CMD2_TRACKER ("t.scrape_downloaded", tr1::bind(&torrent::Tracker::scrape_downloaded, tr1::placeholders::_1));
CMD2_ANY_VALUE ("trackers.enable", tr1::bind(&apply_enable_trackers, int64_t(1)));
CMD2_ANY_VALUE ("trackers.disable", tr1::bind(&apply_enable_trackers, int64_t(0)));
CMD2_VAR_VALUE ("trackers.numwant", -1);
CMD2_VAR_BOOL ("trackers.use_udp", true);
CMD2_ANY_STRING_V ("dht.mode.set", std::bind(&core::DhtManager::set_mode, control->dht_manager(), std::placeholders::_2));
CMD2_ANY_STRING_V ("dht.mode.set", tr1::bind(&core::DhtManager::set_mode, control->dht_manager(), tr1::placeholders::_2));
CMD2_VAR_VALUE ("dht.port", int64_t(6881));
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_STRING ("dht.add_node", tr1::bind(&apply_dht_add_node, tr1::placeholders::_2));
CMD2_ANY ("dht.statistics", tr1::bind(&core::DhtManager::dht_statistics, control->dht_manager()));
CMD2_ANY ("dht.throttle.name", tr1::bind(&core::DhtManager::throttle_name, control->dht_manager()));
CMD2_ANY_STRING_V ("dht.throttle.name.set", tr1::bind(&core::DhtManager::set_throttle_name, control->dht_manager(), tr1::placeholders::_2));
}
+36 -59
View File
@@ -41,7 +41,6 @@
#include <ctime>
#include <rak/functional.h>
#include <rak/functional_fun.h>
#include <sigc++/adaptors/bind.h>
#include "core/manager.h"
#include "core/view_manager.h"
@@ -53,8 +52,7 @@
#include "control.h"
#include "command_helpers.h"
typedef void (core::ViewManager::*view_cfilter_slot)(const std::string&, const torrent::Object&);
typedef void (core::ViewManager::*view_event_slot)(const std::string&, const std::string&);
typedef void (core::ViewManager::*view_event_slot)(const std::string&, const torrent::Object&);
torrent::Object
apply_view_filter_on(const torrent::Object::list_type& args) {
@@ -76,33 +74,12 @@ apply_view_filter_on(const torrent::Object::list_type& args) {
return torrent::Object();
}
torrent::Object
apply_view_cfilter(view_cfilter_slot viewFilterSlot, const torrent::Object::list_type& args) {
if (args.size() != 2)
throw torrent::input_error("Too few arguments.");
const std::string& name = args.front().as_string();
if (name.empty())
throw torrent::input_error("First argument must be a string.");
(control->view_manager()->*viewFilterSlot)(name, args.back());
return torrent::Object();
}
torrent::Object
apply_view_event(view_event_slot viewFilterSlot, const torrent::Object::list_type& args) {
if (args.size() != 2)
throw torrent::input_error("Too few arguments.");
const std::string& name = args.front().as_string();
if (name.empty())
throw torrent::input_error("First argument must be a string.");
(control->view_manager()->*viewFilterSlot)(name, args.back().as_string());
throw torrent::input_error("Wrong argument count.");
(control->view_manager()->*viewFilterSlot)(args.front().as_string(), args.back());
return torrent::Object();
}
@@ -472,7 +449,7 @@ torrent::Object
cmd_view_persistent(const torrent::Object::string_type& args) {
core::View* view = *control->view_manager()->find_throw(args);
if (!view->get_filter().is_empty() || !view->get_event_added().empty() || !view->get_event_removed().empty())
if (!view->get_filter().is_empty() || !view->event_added().is_empty() || !view->event_removed().is_empty())
throw torrent::input_error("Cannot set modified views as persitent.");
view->set_filter("d.views.has=" + args);
@@ -541,41 +518,41 @@ void
initialize_command_ui() {
CMD2_VAR_STRING("keys.layout", "qwerty");
CMD2_ANY_STRING("view.add", object_convert_void(std::bind(&core::ViewManager::insert_throw, control->view_manager(), std::placeholders::_2)));
CMD2_ANY_STRING("view.add", object_convert_void(tr1::bind(&core::ViewManager::insert_throw, control->view_manager(), tr1::placeholders::_2)));
CMD2_ANY_L ("view.list", std::bind(&apply_view_list));
CMD2_ANY_LIST("view.set", std::bind(&apply_view_set, std::placeholders::_2));
CMD2_ANY_L ("view.list", tr1::bind(&apply_view_list));
CMD2_ANY_LIST("view.set", tr1::bind(&apply_view_set, tr1::placeholders::_2));
CMD2_ANY_LIST("view.filter", std::bind(&apply_view_cfilter, &core::ViewManager::set_filter, std::placeholders::_2));
CMD2_ANY_LIST("view.filter_on", std::bind(&apply_view_filter_on, std::placeholders::_2));
CMD2_ANY_LIST("view.filter", tr1::bind(&apply_view_event, &core::ViewManager::set_filter, tr1::placeholders::_2));
CMD2_ANY_LIST("view.filter_on", tr1::bind(&apply_view_filter_on, tr1::placeholders::_2));
CMD2_ANY_LIST("view.sort", std::bind(&apply_view_sort, std::placeholders::_2));
CMD2_ANY_LIST("view.sort_new", std::bind(&apply_view_cfilter, &core::ViewManager::set_sort_new, std::placeholders::_2));
CMD2_ANY_LIST("view.sort_current", std::bind(&apply_view_cfilter, &core::ViewManager::set_sort_current, std::placeholders::_2));
CMD2_ANY_LIST("view.sort", tr1::bind(&apply_view_sort, tr1::placeholders::_2));
CMD2_ANY_LIST("view.sort_new", tr1::bind(&apply_view_event, &core::ViewManager::set_sort_new, tr1::placeholders::_2));
CMD2_ANY_LIST("view.sort_current", tr1::bind(&apply_view_event, &core::ViewManager::set_sort_current, tr1::placeholders::_2));
CMD2_ANY_LIST("view.event_added", std::bind(&apply_view_event, &core::ViewManager::set_event_added, std::placeholders::_2));
CMD2_ANY_LIST("view.event_removed", std::bind(&apply_view_event, &core::ViewManager::set_event_removed, std::placeholders::_2));
CMD2_ANY_LIST("view.event_added", tr1::bind(&apply_view_event, &core::ViewManager::set_event_added, tr1::placeholders::_2));
CMD2_ANY_LIST("view.event_removed", tr1::bind(&apply_view_event, &core::ViewManager::set_event_removed, tr1::placeholders::_2));
// Cleanup and add . to view.
CMD2_ANY_STRING("view.size", std::bind(&cmd_view_size, std::placeholders::_2));
CMD2_ANY_STRING("view.size_not_visible", std::bind(&cmd_view_size_not_visible, std::placeholders::_2));
CMD2_ANY_STRING("view.persistent", std::bind(&cmd_view_persistent, std::placeholders::_2));
CMD2_ANY_STRING("view.size", tr1::bind(&cmd_view_size, tr1::placeholders::_2));
CMD2_ANY_STRING("view.size_not_visible", tr1::bind(&cmd_view_size_not_visible, tr1::placeholders::_2));
CMD2_ANY_STRING("view.persistent", tr1::bind(&cmd_view_persistent, tr1::placeholders::_2));
CMD2_ANY_STRING_V("view.filter_all", std::bind(&core::View::filter, std::bind(&core::ViewManager::find_ptr_throw, control->view_manager(), std::placeholders::_2)));
CMD2_ANY_STRING_V("view.filter_all", tr1::bind(&core::View::filter, tr1::bind(&core::ViewManager::find_ptr_throw, control->view_manager(), tr1::placeholders::_2)));
CMD2_DL_STRING ("view.filter_download", std::bind(&cmd_view_filter_download, std::placeholders::_1, std::placeholders::_2));
CMD2_DL_STRING ("view.set_visible", std::bind(&cmd_view_set_visible, std::placeholders::_1, std::placeholders::_2));
CMD2_DL_STRING ("view.set_not_visible", std::bind(&cmd_view_set_not_visible, std::placeholders::_1, std::placeholders::_2));
CMD2_DL_STRING ("view.filter_download", tr1::bind(&cmd_view_filter_download, tr1::placeholders::_1, tr1::placeholders::_2));
CMD2_DL_STRING ("view.set_visible", tr1::bind(&cmd_view_set_visible, tr1::placeholders::_1, tr1::placeholders::_2));
CMD2_DL_STRING ("view.set_not_visible", tr1::bind(&cmd_view_set_not_visible, tr1::placeholders::_1, tr1::placeholders::_2));
// Commands that affect the default rtorrent UI.
CMD2_DL ("ui.unfocus_download", std::bind(&cmd_ui_unfocus_download, std::placeholders::_1));
CMD2_ANY_STRING("ui.current_view.set", std::bind(&cmd_ui_set_view, std::placeholders::_2));
CMD2_DL ("ui.unfocus_download", tr1::bind(&cmd_ui_unfocus_download, tr1::placeholders::_1));
CMD2_ANY_STRING("ui.current_view.set", tr1::bind(&cmd_ui_set_view, tr1::placeholders::_2));
// Move.
CMD2_ANY("print", &apply_print);
CMD2_ANY("cat", &apply_cat);
CMD2_ANY("if", std::bind(&apply_if, std::placeholders::_1, std::placeholders::_2, 0));
CMD2_ANY("if", tr1::bind(&apply_if, tr1::placeholders::_1, tr1::placeholders::_2, 0));
CMD2_ANY("not", &apply_not);
CMD2_ANY("false", &apply_false);
CMD2_ANY("and", &apply_and);
@@ -583,22 +560,22 @@ initialize_command_ui() {
// A temporary command for handling stuff until we get proper
// support for seperation of commands and literals.
CMD2_ANY("branch", std::bind(&apply_if, std::placeholders::_1, std::placeholders::_2, 1));
CMD2_ANY("branch", tr1::bind(&apply_if, tr1::placeholders::_1, tr1::placeholders::_2, 1));
CMD2_ANY_LIST("less", &apply_less);
CMD2_ANY_LIST("greater", &apply_greater);
CMD2_ANY_LIST("equal", &apply_equal);
CMD2_ANY_VALUE("convert.gm_time", std::bind(&apply_to_time, std::placeholders::_2, 0));
CMD2_ANY_VALUE("convert.gm_date", std::bind(&apply_to_time, std::placeholders::_2, 0x2));
CMD2_ANY_VALUE("convert.time", std::bind(&apply_to_time, std::placeholders::_2, 0x1));
CMD2_ANY_VALUE("convert.date", std::bind(&apply_to_time, std::placeholders::_2, 0x1 | 0x2));
CMD2_ANY_VALUE("convert.elapsed_time", std::bind(&apply_to_elapsed_time, std::placeholders::_2));
CMD2_ANY_VALUE("convert.kb", std::bind(&apply_to_kb, std::placeholders::_2));
CMD2_ANY_VALUE("convert.mb", std::bind(&apply_to_mb, std::placeholders::_2));
CMD2_ANY_VALUE("convert.xb", std::bind(&apply_to_xb, std::placeholders::_2));
CMD2_ANY_VALUE("convert.throttle", std::bind(&apply_to_throttle, std::placeholders::_2));
CMD2_ANY_VALUE("convert.gm_time", tr1::bind(&apply_to_time, tr1::placeholders::_2, 0));
CMD2_ANY_VALUE("convert.gm_date", tr1::bind(&apply_to_time, tr1::placeholders::_2, 0x2));
CMD2_ANY_VALUE("convert.time", tr1::bind(&apply_to_time, tr1::placeholders::_2, 0x1));
CMD2_ANY_VALUE("convert.date", tr1::bind(&apply_to_time, tr1::placeholders::_2, 0x1 | 0x2));
CMD2_ANY_VALUE("convert.elapsed_time", tr1::bind(&apply_to_elapsed_time, tr1::placeholders::_2));
CMD2_ANY_VALUE("convert.kb", tr1::bind(&apply_to_kb, tr1::placeholders::_2));
CMD2_ANY_VALUE("convert.mb", tr1::bind(&apply_to_mb, tr1::placeholders::_2));
CMD2_ANY_VALUE("convert.xb", tr1::bind(&apply_to_xb, tr1::placeholders::_2));
CMD2_ANY_VALUE("convert.throttle", tr1::bind(&apply_to_throttle, tr1::placeholders::_2));
CMD2_ANY_LIST ("elapsed.less", std::bind(&apply_elapsed_less, std::placeholders::_2));
CMD2_ANY_LIST ("elapsed.greater", std::bind(&apply_elapsed_greater, std::placeholders::_2));
CMD2_ANY_LIST ("elapsed.less", tr1::bind(&apply_elapsed_less, tr1::placeholders::_2));
CMD2_ANY_LIST ("elapsed.greater", tr1::bind(&apply_elapsed_greater, tr1::placeholders::_2));
}
+15 -5
View File
@@ -44,6 +44,7 @@
#include "core/download_store.h"
#include "core/view_manager.h"
#include "core/dht_manager.h"
#include "core/http_queue.h"
#include "display/canvas.h"
#include "display/window.h"
@@ -75,9 +76,9 @@ Control::Control() :
m_viewManager = new core::ViewManager();
m_dhtManager = new core::DhtManager();
m_inputStdin->slot_pressed(sigc::mem_fun(m_input, &input::Manager::pressed));
m_inputStdin->slot_pressed(std::tr1::bind(&input::Manager::pressed, m_input, std::tr1::placeholders::_1));
m_taskShutdown.set_slot(rak::mem_fn(this, &Control::handle_shutdown));
m_taskShutdown.slot() = std::tr1::bind(&Control::handle_shutdown, this);
m_commandScheduler->set_slot_error_message(rak::mem_fn(m_core, &core::Manager::push_log_std));
}
@@ -114,7 +115,7 @@ Control::initialize() {
m_ui->init(this);
m_inputStdin->insert(main_thread->poll());
m_inputStdin->insert(torrent::main_thread()->poll());
}
void
@@ -124,7 +125,7 @@ Control::cleanup() {
priority_queue_erase(&taskScheduler, &m_taskShutdown);
m_inputStdin->remove(main_thread->poll());
m_inputStdin->remove(torrent::main_thread()->poll());
m_core->download_store()->disable();
@@ -146,7 +147,16 @@ Control::cleanup_exception() {
bool
Control::is_shutdown_completed() {
return m_shutdownQuick && !worker_thread->is_active() && torrent::is_inactive();
if (!m_shutdownQuick || worker_thread->is_active())
return false;
// Tracker requests can be disowned, so wait for these to
// finish. The edge case of torrent http downloads may delay
// shutdown.
if (!core()->http_stack()->empty() || !core()->http_queue()->empty())
return false;
return torrent::is_inactive();
}
void
-1
View File
@@ -90,7 +90,6 @@ public:
core::ViewManager* view_manager() { return m_viewManager; }
core::DhtManager* dht_manager() { return m_dhtManager; }
ui::Root* ui() { return m_ui; }
display::Manager* display() { return m_display; }
input::Manager* input() { return m_input; }
+1 -9
View File
@@ -20,22 +20,14 @@ libsub_core_a_SOURCES = \
download_store.h \
http_queue.cc \
http_queue.h \
log.cc \
log.h \
manager.cc \
manager.h \
poll_manager.cc \
poll_manager.h \
poll_manager_epoll.cc \
poll_manager_epoll.h \
poll_manager_kqueue.cc \
poll_manager_kqueue.h \
poll_manager_select.cc \
poll_manager_select.h \
range_map.h \
view.cc \
view.h \
view_manager.cc \
view_manager.h
INCLUDES = -I$(srcdir) -I$(srcdir)/.. -I$(top_srcdir)
AM_CPPFLAGS = -I$(srcdir) -I$(srcdir)/.. -I$(top_srcdir)
+1 -1
View File
@@ -82,7 +82,7 @@ CurlGet::start() {
// Normally libcurl should handle the timeout. But sometimes that doesn't
// work right so we do a fallback timeout that just aborts the transfer.
m_taskTimeout.set_slot(rak::mem_fn(this, &CurlGet::receive_timeout));
m_taskTimeout.slot() = std::tr1::bind(&CurlGet::receive_timeout, this);
priority_queue_erase(&taskScheduler, &m_taskTimeout);
priority_queue_insert(&taskScheduler, &m_taskTimeout, cachedTime + rak::timer::from_seconds(m_timeout + 5));
}
-1
View File
@@ -40,7 +40,6 @@
#include <iosfwd>
#include <string>
#include <curl/curl.h>
#include <sigc++/signal.h>
#include <torrent/http.h>
#include "rak/priority_queue_default.h"
+8 -7
View File
@@ -41,6 +41,7 @@
#include <torrent/poll.h>
#include <torrent/exceptions.h>
#include <torrent/utils/thread_base.h>
#include "control.h"
@@ -69,22 +70,22 @@ CurlSocket::receive_socket(void* easy_handle, curl_socket_t fd, int what, void*
if (socket == NULL) {
socket = stack->new_socket(fd);
main_thread->poll()->open(socket);
torrent::main_thread()->poll()->open(socket);
// No interface for libcurl to signal when it's interested in error events.
// Assume that hence it must always be interested in them.
main_thread->poll()->insert_error(socket);
torrent::main_thread()->poll()->insert_error(socket);
}
if (what == CURL_POLL_NONE || what == CURL_POLL_OUT)
main_thread->poll()->remove_read(socket);
torrent::main_thread()->poll()->remove_read(socket);
else
main_thread->poll()->insert_read(socket);
torrent::main_thread()->poll()->insert_read(socket);
if (what == CURL_POLL_NONE || what == CURL_POLL_IN)
main_thread->poll()->remove_write(socket);
torrent::main_thread()->poll()->remove_write(socket);
else
main_thread->poll()->insert_write(socket);
torrent::main_thread()->poll()->insert_write(socket);
return 0;
}
@@ -99,7 +100,7 @@ CurlSocket::close() {
if (m_fileDesc == -1)
throw torrent::internal_error("CurlSocket::close() m_fileDesc == -1.");
main_thread->poll()->closed(this);
torrent::main_thread()->poll()->closed(this);
m_fileDesc = -1;
}
+3 -1
View File
@@ -50,6 +50,8 @@ public:
CurlSocket(int fd, CurlStack* stack) : m_stack(stack) { m_fileDesc = fd; }
~CurlSocket();
const char* type_name() const { return "curl"; }
void close();
static int receive_socket(void* easy_handle, curl_socket_t fd, int what, void* userp, void* socketp);
@@ -62,7 +64,7 @@ private:
virtual void event_write();
virtual void event_error();
CurlStack* m_stack;
CurlStack* m_stack;
};
}
+29 -17
View File
@@ -38,7 +38,6 @@
#include <algorithm>
#include <curl/multi.h>
#include <sigc++/adaptors/bind.h>
#include <torrent/exceptions.h>
#include "rak/functional.h"
@@ -46,8 +45,6 @@
#include "curl_socket.h"
#include "curl_stack.h"
namespace std { using namespace tr1; }
namespace core {
CurlStack::CurlStack() :
@@ -57,7 +54,7 @@ CurlStack::CurlStack() :
m_ssl_verify_peer(true),
m_dns_timeout(60) {
m_taskTimeout.set_slot(rak::mem_fn(this, &CurlStack::receive_timeout));
m_taskTimeout.slot() = std::tr1::bind(&CurlStack::receive_timeout, this);
#if (LIBCURL_VERSION_NUM >= 0x071000)
curl_multi_setopt((CURLM*)m_handle, CURLMOPT_TIMERDATA, this);
@@ -94,29 +91,27 @@ CurlStack::receive_action(CurlSocket* socket, int events) {
do {
int count;
#if (LIBCURL_VERSION_NUM >= 0x071003)
code = curl_multi_socket_action((CURLM*)m_handle, socket != NULL ? socket->file_descriptor() : CURL_SOCKET_TIMEOUT, events, &count);
code = curl_multi_socket_action((CURLM*)m_handle,
socket != NULL ? socket->file_descriptor() : CURL_SOCKET_TIMEOUT,
events,
&count);
#else
code = curl_multi_socket((CURLM*)m_handle, socket != NULL ? socket->file_descriptor() : CURL_SOCKET_TIMEOUT, &count);
code = curl_multi_socket((CURLM*)m_handle,
socket != NULL ? socket->file_descriptor() : CURL_SOCKET_TIMEOUT,
&count);
#endif
if (code > 0)
throw torrent::internal_error("Error calling curl_multi_socket_action.");
// Socket might be removed when cleaning handles below, future calls should not use it.
// Socket might be removed when cleaning handles below, future
// calls should not use it.
socket = NULL;
events = 0;
if ((unsigned int)count != size()) {
// Done with some handles.
int t;
CURLMsg* msg;
while ((msg = curl_multi_info_read((CURLM*)m_handle, &t)) != NULL) {
if (msg->msg != CURLMSG_DONE)
throw torrent::internal_error("CurlStack::receive_action() msg->msg != CURLMSG_DONE.");
transfer_done(msg->easy_handle, msg->data.result == CURLE_OK ? NULL : curl_easy_strerror(msg->data.result));
}
while (process_done_handle())
; // Do nothing.
if (empty())
priority_queue_erase(&taskScheduler, &m_taskTimeout);
@@ -125,6 +120,23 @@ CurlStack::receive_action(CurlSocket* socket, int events) {
} while (code == CURLM_CALL_MULTI_PERFORM);
}
bool
CurlStack::process_done_handle() {
int remaining_msgs = 0;
CURLMsg* msg = curl_multi_info_read((CURLM*)m_handle, &remaining_msgs);
if (msg == NULL)
return false;
if (msg->msg != CURLMSG_DONE)
throw torrent::internal_error("CurlStack::receive_action() msg->msg != CURLMSG_DONE.");
transfer_done(msg->easy_handle,
msg->data.result == CURLE_OK ? NULL : curl_easy_strerror(msg->data.result));
return remaining_msgs != 0;
}
void
CurlStack::transfer_done(void* handle, const char* msg) {
iterator itr = std::find_if(begin(), end(), rak::equal(handle, std::mem_fun(&CurlGet::handle)));
+2 -1
View File
@@ -39,7 +39,6 @@
#include <deque>
#include <string>
#include <sigc++/functors/slot.h>
#include "rak/priority_queue_default.h"
@@ -126,6 +125,8 @@ class CurlStack : std::deque<CurlGet*> {
void receive_timeout();
bool process_done_handle();
void* m_handle;
unsigned int m_active;
+4 -4
View File
@@ -114,7 +114,7 @@ DhtManager::start_dht() {
torrent::dht_manager()->start(port);
torrent::dht_manager()->reset_statistics();
m_updateTimeout.set_slot(rak::mem_fn(this, &DhtManager::update));
m_updateTimeout.slot() = std::tr1::bind(&DhtManager::update, this);
priority_queue_insert(&taskScheduler, &m_updateTimeout, (cachedTime + rak::timer::from_seconds(60)).round_seconds());
m_dhtPrevCycle = 0;
@@ -197,7 +197,7 @@ DhtManager::update() {
break;
if (itr == end) {
m_stopTimeout.set_slot(rak::mem_fn(this, &DhtManager::stop_dht));
m_stopTimeout.slot() = std::tr1::bind(&DhtManager::stop_dht, this);
priority_queue_insert(&taskScheduler, &m_stopTimeout, (cachedTime + rak::timer::from_seconds(15 * 60)).round_seconds());
}
}
@@ -248,7 +248,7 @@ DhtManager::log_statistics(bool force) {
if (m_dhtPrevCycle == 1) {
char buffer[128];
snprintf(buffer, sizeof(buffer), "DHT bootstrap complete, have %d nodes in %d buckets.", stats.num_nodes, stats.num_buckets);
control->core()->get_log_complete().push_front(buffer);
control->core()->push_log_complete(buffer);
m_dhtPrevCycle = stats.cycle;
return false;
};
@@ -271,7 +271,7 @@ DhtManager::log_statistics(bool force) {
stats.max_peers,
stats.num_trackers);
control->core()->get_log_complete().push_front(buffer);
control->core()->push_log_complete(buffer);
m_dhtPrevCycle = stats.cycle;
m_dhtPrevQueriesSent = stats.queries_sent;
+3 -23
View File
@@ -36,9 +36,7 @@
#include "config.h"
#include <sigc++/adaptors/bind.h>
#include <sigc++/adaptors/hide.h>
#include <sigc++/signal.h>
#include <list>
#include <rak/file_stat.h>
#include <rak/functional.h>
#include <rak/path.h>
@@ -61,25 +59,17 @@ Download::Download(download_type d) :
m_download(d),
m_hashFailed(false),
m_chunksFailed(0),
m_resumeFlags(~uint32_t()),
m_group(0) {
m_connTrackerSucceeded = m_download.info()->signal_tracker_success().connect(sigc::bind(sigc::mem_fun(*this, &Download::receive_tracker_msg), ""));
m_connTrackerFailed = m_download.info()->signal_tracker_failed().connect(sigc::mem_fun(*this, &Download::receive_tracker_msg));
m_connStorageError = m_download.info()->signal_storage_error().connect(sigc::mem_fun(*this, &Download::receive_storage_error));
m_download.info()->signal_chunk_failed().connect(sigc::mem_fun(*this, &Download::receive_chunk_failed));
m_download.info()->signal_tracker_success().push_back(tr1::bind(&Download::receive_tracker_msg, this, ""));
m_download.info()->signal_tracker_failed().push_back(tr1::bind(&Download::receive_tracker_msg, this, tr1::placeholders::_1));
}
Download::~Download() {
if (!m_download.is_valid())
return;
m_connTrackerSucceeded.disconnect();
m_connTrackerFailed.disconnect();
m_connStorageError.disconnect();
m_download = download_type();
}
@@ -125,11 +115,6 @@ Download::receive_tracker_msg(std::string msg) {
m_message = "Tracker: [" + msg + "]";
}
void
Download::receive_storage_error(std::string msg) {
m_message = "Storage error: [" + msg + "]";
}
float
Download::distributed_copies() const {
const uint8_t* avail = m_download.chunks_seen();
@@ -154,11 +139,6 @@ Download::distributed_copies() const {
return minAvail + 1 - bitfield->is_all_set() - (float)num / m_download.file_list()->size_chunks();
}
void
Download::receive_chunk_failed(__UNUSED uint32_t idx) {
m_chunksFailed++;
}
void
Download::set_throttle_name(const std::string& throttleName) {
if (m_download.info()->is_active())
-13
View File
@@ -37,7 +37,6 @@
#ifndef RTORRENT_CORE_DOWNLOAD_H
#define RTORRENT_CORE_DOWNLOAD_H
#include <sigc++/connection.h>
#include <torrent/download.h>
#include <torrent/download_info.h>
#include <torrent/hash_string.h>
@@ -114,8 +113,6 @@ public:
const std::string& message() const { return m_message; }
void set_message(const std::string& msg) { m_message = msg; }
uint32_t chunks_failed() const { return m_chunksFailed; }
void enable_udp_trackers(bool state);
uint32_t priority();
@@ -141,24 +138,14 @@ private:
void operator () (const Download&);
void receive_tracker_msg(std::string msg);
void receive_storage_error(std::string msg);
void receive_chunk_failed(uint32_t idx);
// Store the FileList instance so we can use slots etc on it.
download_type m_download;
bool m_hashFailed;
std::string m_message;
uint32_t m_chunksFailed;
uint32_t m_resumeFlags;
sigc::connection m_connTrackerSucceeded;
sigc::connection m_connTrackerFailed;
sigc::connection m_connStorageError;
unsigned int m_group;
};
+56 -29
View File
@@ -41,6 +41,8 @@
#include <sstream>
#include <stdexcept>
#include <rak/path.h>
#include <tr1/functional>
#include <torrent/utils/log.h>
#include <torrent/utils/resume.h>
#include <torrent/object.h>
#include <torrent/object_stream.h>
@@ -105,14 +107,14 @@ DownloadFactory::DownloadFactory(Manager* m) :
m_printLog(true),
m_isFile(false) {
m_taskLoad.set_slot(rak::mem_fn(this, &DownloadFactory::receive_load));
m_taskCommit.set_slot(rak::mem_fn(this, &DownloadFactory::receive_commit));
m_taskLoad.slot() = std::tr1::bind(&DownloadFactory::receive_load, this);
m_taskCommit.slot() = std::tr1::bind(&DownloadFactory::receive_commit, this);
// m_variables["connection_leech"] = rpc::call_command_void("protocol.connection.leech");
// m_variables["connection_seed"] = rpc::call_command_void("protocol.connection.seed");
// m_variables["connection_leech"] = rpc::call_command("protocol.connection.leech");
// m_variables["connection_seed"] = rpc::call_command("protocol.connection.seed");
m_variables["connection_leech"] = std::string();
m_variables["connection_seed"] = std::string();
m_variables["directory"] = rpc::call_command_void("directory.default");
m_variables["directory"] = rpc::call_command("directory.default");
m_variables["tied_to_file"] = torrent::Object((int64_t)false);
}
@@ -156,8 +158,8 @@ DownloadFactory::receive_load() {
m_stream = new std::stringstream;
HttpQueue::iterator itr = m_manager->http_queue()->insert(m_uri, m_stream);
(*itr)->signal_done().push_front(std::bind(&DownloadFactory::receive_loaded, this));
(*itr)->signal_failed().push_front(std::bind(&DownloadFactory::receive_failed, this, std::placeholders::_1));
(*itr)->signal_done().push_front(std::tr1::bind(&DownloadFactory::receive_loaded, this));
(*itr)->signal_failed().push_front(std::tr1::bind(&DownloadFactory::receive_failed, this, std::tr1::placeholders::_1));
m_variables["tied_to_file"] = (int64_t)false;
@@ -214,7 +216,7 @@ DownloadFactory::receive_success() {
if (download == NULL) {
// core::Manager should already have added the error message to
// the log.
m_slotFinished();
m_slot_finished();
return;
}
@@ -253,21 +255,21 @@ DownloadFactory::receive_success() {
if (!rtorrent->has_key_string("custom4")) rtorrent->insert_key("custom4", std::string());
if (!rtorrent->has_key_string("custom5")) rtorrent->insert_key("custom5", std::string());
rpc::call_command("d.uploads_min.set", rpc::call_command_void("throttle.min_uploads"), rpc::make_target(download));
rpc::call_command("d.uploads_max.set", rpc::call_command_void("throttle.max_uploads"), rpc::make_target(download));
rpc::call_command("d.downloads_min.set", rpc::call_command_void("throttle.min_downloads"), rpc::make_target(download));
rpc::call_command("d.downloads_max.set", rpc::call_command_void("throttle.max_downloads"), rpc::make_target(download));
rpc::call_command("d.peers_min.set", rpc::call_command_void("throttle.min_peers.normal"), rpc::make_target(download));
rpc::call_command("d.peers_max.set", rpc::call_command_void("throttle.max_peers.normal"), rpc::make_target(download));
rpc::call_command("d.tracker_numwant.set", rpc::call_command_void("trackers.numwant"), rpc::make_target(download));
rpc::call_command("d.max_file_size.set", rpc::call_command_void("system.file.max_size"), rpc::make_target(download));
rpc::call_command("d.uploads_min.set", rpc::call_command("throttle.min_uploads"), rpc::make_target(download));
rpc::call_command("d.uploads_max.set", rpc::call_command("throttle.max_uploads"), rpc::make_target(download));
rpc::call_command("d.downloads_min.set", rpc::call_command("throttle.min_downloads"), rpc::make_target(download));
rpc::call_command("d.downloads_max.set", rpc::call_command("throttle.max_downloads"), rpc::make_target(download));
rpc::call_command("d.peers_min.set", rpc::call_command("throttle.min_peers.normal"), rpc::make_target(download));
rpc::call_command("d.peers_max.set", rpc::call_command("throttle.max_peers.normal"), rpc::make_target(download));
rpc::call_command("d.tracker_numwant.set", rpc::call_command("trackers.numwant"), rpc::make_target(download));
rpc::call_command("d.max_file_size.set", rpc::call_command("system.file.max_size"), rpc::make_target(download));
if (rpc::call_command_value("d.complete", rpc::make_target(download)) != 0) {
if (rpc::call_command_value("throttle.min_peers.seed") >= 0)
rpc::call_command("d.peers_min.set", rpc::call_command_void("throttle.min_peers.seed"), rpc::make_target(download));
rpc::call_command("d.peers_min.set", rpc::call_command("throttle.min_peers.seed"), rpc::make_target(download));
if (rpc::call_command_value("throttle.max_peers.seed") >= 0)
rpc::call_command("d.peers_max.set", rpc::call_command_void("throttle.max_peers.seed"), rpc::make_target(download));
rpc::call_command("d.peers_max.set", rpc::call_command("throttle.max_peers.seed"), rpc::make_target(download));
}
if (!rpc::call_command_value("trackers.use_udp"))
@@ -302,7 +304,7 @@ DownloadFactory::receive_success() {
// ATM doesn't really ever get here.
delete download;
m_slotFinished();
m_slot_finished();
return;
}
@@ -310,6 +312,9 @@ DownloadFactory::receive_success() {
torrent::HashString infohash = download->info()->hash();
try {
if (torrent::log_groups[torrent::LOG_TORRENT_DEBUG].valid())
log_created(download, rtorrent);
std::for_each(m_commands.begin(), m_commands.end(),
rak::bind2nd(std::ptr_fun(&rpc::parse_command_multiple_std), rpc::make_target(download)));
@@ -325,10 +330,8 @@ DownloadFactory::receive_success() {
} catch (torrent::input_error& e) {
std::string msg = "Command on torrent creation failed: " + std::string(e.what());
if (m_printLog) {
m_manager->get_log_important().push_front(msg);
m_manager->get_log_complete().push_front(msg);
}
if (m_printLog)
m_manager->push_log_std(msg);
if (m_manager->download_list()->find(infohash) != m_manager->download_list()->end()) {
// Should stop it, mark it bad. Perhaps even delete it?
@@ -338,18 +341,42 @@ DownloadFactory::receive_success() {
}
}
m_slotFinished();
m_slot_finished();
}
void
DownloadFactory::log_created(Download* download, torrent::Object* rtorrent) {
std::stringstream dump;
dump << "info_hash = " << torrent::hash_string_to_hex_str(download->info()->hash()) << std::endl;
dump << "session = " << (m_session ? "true" : "false") << std::endl;
if (download->download()->info()->is_meta_download())
dump << "magnet = true" << std::endl;
if (!rtorrent->has_key_string("directory"))
dump << "directory = \"" << (m_variables["directory"].is_string() ? m_variables["directory"].as_string() : std::string()) << '"' << std::endl;
else
dump << "directory_base = \"" << (rtorrent->get_key("directory").is_string() ? rtorrent->get_key("directory").as_string() : std::string()) << '"' << std::endl;
dump << "---COMMANDS---" << std::endl;
for (command_list_type::const_iterator itr = m_commands.begin(); itr != m_commands.end(); itr++) {
dump << *itr << std::endl;
}
std::string dump_str = dump.str();
lt_log_print_dump(torrent::LOG_TORRENT_DEBUG, dump_str.c_str(), dump_str.size(), "Creating new download:");
}
void
DownloadFactory::receive_failed(const std::string& msg) {
// Add message to log.
if (m_printLog) {
m_manager->get_log_important().push_front(msg + ": \"" + m_uri + "\"");
m_manager->get_log_complete().push_front(msg + ": \"" + m_uri + "\"");
}
if (m_printLog)
m_manager->push_log_std(msg + ": \"" + m_uri + "\"");
m_slotFinished();
m_slot_finished();
}
void
+6 -4
View File
@@ -42,9 +42,9 @@
#define RTORRENT_CORE_DOWNLOAD_FACTORY_H
#include <iosfwd>
#include <sigc++/functors/slot.h>
#include <rak/priority_queue_default.h>
#include <torrent/object.h>
#include <tr1/functional>
#include "http_queue.h"
@@ -54,7 +54,7 @@ class Manager;
class DownloadFactory {
public:
typedef sigc::slot<void> Slot;
typedef std::tr1::function<void ()> slot_void;
typedef std::vector<std::string> command_list_type;
// Do not destroy this object while it is in a HttpQueue.
@@ -80,7 +80,7 @@ public:
bool print_log() const { return m_printLog; }
void set_print_log(bool v) { m_printLog = v; }
void slot_finished(Slot s) { m_slotFinished = s; }
void slot_finished(slot_void s) { m_slot_finished = s; }
private:
void receive_load();
@@ -89,6 +89,8 @@ private:
void receive_success();
void receive_failed(const std::string& msg);
void log_created(Download* download, torrent::Object* rtorrent);
void initialize_rtorrent(Download* download, torrent::Object* rtorrent);
Manager* m_manager;
@@ -107,7 +109,7 @@ private:
command_list_type m_commands;
torrent::Object::map_type m_variables;
Slot m_slotFinished;
slot_void m_slot_finished;
rak::priority_item m_taskLoad;
rak::priority_item m_taskCommit;
};
+55 -29
View File
@@ -39,7 +39,6 @@
#include <algorithm>
#include <fstream>
#include <iostream>
#include <sigc++/adaptors/bind.h>
#include <rak/functional.h>
#include <rak/string_manip.h>
#include <torrent/data/file.h>
@@ -178,9 +177,11 @@ DownloadList::iterator
DownloadList::insert(Download* download) {
iterator itr = base_type::insert(end(), download);
lt_log_print_info(torrent::LOG_TORRENT_INFO, download->info(), "download_list", "Inserting download.");
try {
(*itr)->data()->slot_initial_hash() = std::bind(&DownloadList::hash_done, this, download);
(*itr)->data()->slot_download_done() = std::bind(&DownloadList::received_finished, this, download);
(*itr)->data()->slot_initial_hash() = tr1::bind(&DownloadList::hash_done, this, download);
(*itr)->data()->slot_download_done() = tr1::bind(&DownloadList::received_finished, this, download);
// This needs to be separated into two different calls to ensure
// the download remains in the view.
@@ -208,6 +209,8 @@ DownloadList::erase(iterator itr) {
if (itr == end())
throw torrent::internal_error("DownloadList::erase(...) could not find download.");
lt_log_print_info(torrent::LOG_TORRENT_INFO, (*itr)->info(), "download_list", "Erasing download.");
// Makes sure close doesn't restart hashing of this download.
(*itr)->set_hash_failed(true);
@@ -242,6 +245,8 @@ void
DownloadList::open_throw(Download* download) {
check_contains(download);
lt_log_print_info(torrent::LOG_TORRENT_INFO, download->info(), "download_list", "Opening download.");
if (download->download()->info()->is_open())
return;
@@ -257,7 +262,6 @@ DownloadList::open_throw(Download* download) {
void
DownloadList::close(Download* download) {
try {
close_throw(download);
} catch (torrent::local_error& e) {
@@ -267,6 +271,8 @@ DownloadList::close(Download* download) {
void
DownloadList::close_directly(Download* download) {
lt_log_print_info(torrent::LOG_TORRENT_INFO, download->info(), "download_list", "Closing download directly.");
if (download->download()->info()->is_active()) {
download->download()->stop(torrent::Download::stop_skip_tracker);
@@ -280,6 +286,7 @@ DownloadList::close_directly(Download* download) {
void
DownloadList::close_quick(Download* download) {
lt_log_print_info(torrent::LOG_TORRENT_INFO, download->info(), "download_list", "Closing download quickly.");
close(download);
// Make sure we cancel any tracker requests. This should rather be
@@ -293,6 +300,8 @@ void
DownloadList::close_throw(Download* download) {
check_contains(download);
lt_log_print_info(torrent::LOG_TORRENT_INFO, download->info(), "download_list", "Closing download with throw.");
// When pause gets called it will clear the initial hash check state
// and set hash failed. This should ensure hashing doesn't restart
// until resume gets called.
@@ -324,6 +333,8 @@ void
DownloadList::resume(Download* download, int flags) {
check_contains(download);
lt_log_print_info(torrent::LOG_TORRENT_INFO, download->info(), "download_list", "Resuming download: flags:%0x.", flags);
try {
if (download->download()->info()->is_active())
@@ -361,26 +372,26 @@ DownloadList::resume(Download* download, int flags) {
rpc::call_command("d.state_counter.set", rpc::call_command_value("d.state_counter", rpc::make_target(download)) + 1, rpc::make_target(download));
if (download->is_done()) {
torrent::Object conn_current = rpc::call_command_void("d.connection_seed", rpc::make_target(download));
torrent::Object choke_up = rpc::call_command_void("d.up.choke_heuristics.seed", rpc::make_target(download));
torrent::Object choke_down = rpc::call_command_void("d.down.choke_heuristics.seed", rpc::make_target(download));
torrent::Object conn_current = rpc::call_command("d.connection_seed", torrent::Object(), rpc::make_target(download));
torrent::Object choke_up = rpc::call_command("d.up.choke_heuristics.seed", torrent::Object(), rpc::make_target(download));
torrent::Object choke_down = rpc::call_command("d.down.choke_heuristics.seed", torrent::Object(), rpc::make_target(download));
if (conn_current.is_string_empty()) conn_current = rpc::call_command_void("protocol.connection.seed", rpc::make_target(download));
if (choke_up.is_string_empty()) choke_up = rpc::call_command_void("protocol.choke_heuristics.up.seed", rpc::make_target(download));
if (choke_down.is_string_empty()) choke_down = rpc::call_command_void("protocol.choke_heuristics.down.seed", rpc::make_target(download));
if (conn_current.is_string_empty()) conn_current = rpc::call_command("protocol.connection.seed", torrent::Object(), rpc::make_target(download));
if (choke_up.is_string_empty()) choke_up = rpc::call_command("protocol.choke_heuristics.up.seed", torrent::Object(), rpc::make_target(download));
if (choke_down.is_string_empty()) choke_down = rpc::call_command("protocol.choke_heuristics.down.seed", torrent::Object(), rpc::make_target(download));
rpc::call_command("d.connection_current.set", conn_current, rpc::make_target(download));
rpc::call_command("d.up.choke_heuristics.set", choke_up, rpc::make_target(download));
rpc::call_command("d.down.choke_heuristics.set", choke_down, rpc::make_target(download));
} else {
torrent::Object conn_current = rpc::call_command_void("d.connection_leech", rpc::make_target(download));
torrent::Object choke_up = rpc::call_command_void("d.up.choke_heuristics.leech", rpc::make_target(download));
torrent::Object choke_down = rpc::call_command_void("d.down.choke_heuristics.leech", rpc::make_target(download));
torrent::Object conn_current = rpc::call_command("d.connection_leech", torrent::Object(), rpc::make_target(download));
torrent::Object choke_up = rpc::call_command("d.up.choke_heuristics.leech", torrent::Object(), rpc::make_target(download));
torrent::Object choke_down = rpc::call_command("d.down.choke_heuristics.leech", torrent::Object(), rpc::make_target(download));
if (conn_current.is_string_empty()) conn_current = rpc::call_command_void("protocol.connection.leech", rpc::make_target(download));
if (choke_up.is_string_empty()) choke_up = rpc::call_command_void("protocol.choke_heuristics.up.leech", rpc::make_target(download));
if (choke_down.is_string_empty()) choke_down = rpc::call_command_void("protocol.choke_heuristics.down.leech", rpc::make_target(download));
if (conn_current.is_string_empty()) conn_current = rpc::call_command("protocol.connection.leech", torrent::Object(), rpc::make_target(download));
if (choke_up.is_string_empty()) choke_up = rpc::call_command("protocol.choke_heuristics.up.leech", torrent::Object(), rpc::make_target(download));
if (choke_down.is_string_empty()) choke_down = rpc::call_command("protocol.choke_heuristics.down.leech", torrent::Object(), rpc::make_target(download));
rpc::call_command("d.connection_current.set", conn_current, rpc::make_target(download));
rpc::call_command("d.up.choke_heuristics.set", choke_up, rpc::make_target(download));
@@ -417,6 +428,8 @@ void
DownloadList::pause(Download* download, int flags) {
check_contains(download);
lt_log_print_info(torrent::LOG_TORRENT_INFO, download->info(), "download_list", "Pausing download: flags:%0x.", flags);
try {
download->set_resume_flags(~uint32_t());
@@ -448,8 +461,8 @@ DownloadList::pause(Download* download, int flags) {
// If initial seeding is complete, don't try it again when restarting.
if (download->is_done() &&
rpc::call_command_void("d.connection_current", rpc::make_target(download)).as_string() == "initial_seed")
rpc::call_command("d.connection_seed.set", rpc::call_command_void("d.connection_current", rpc::make_target(download)), rpc::make_target(download));
rpc::call_command("d.connection_current", torrent::Object(), rpc::make_target(download)).as_string() == "initial_seed")
rpc::call_command("d.connection_seed.set", rpc::call_command("d.connection_current", torrent::Object(), rpc::make_target(download)), rpc::make_target(download));
// Save the state after all the slots, etc have been called so we
// include the modifications they may make.
@@ -464,8 +477,9 @@ void
DownloadList::check_hash(Download* download) {
check_contains(download);
try {
lt_log_print_info(torrent::LOG_TORRENT_INFO, download->info(), "download_list", "Checking hash.");
try {
if (rpc::call_command_value("d.hashing", rpc::make_target(download)) != Download::variable_hashing_stopped)
return;
@@ -480,6 +494,8 @@ void
DownloadList::hash_done(Download* download) {
check_contains(download);
lt_log_print_info(torrent::LOG_TORRENT_INFO, download->info(), "download_list", "Hash done.");
if (download->is_hash_checking() || download->is_active())
throw torrent::internal_error("DownloadList::hash_done(...) download in invalid state.");
@@ -554,6 +570,8 @@ void
DownloadList::hash_queue(Download* download, int type) {
check_contains(download);
lt_log_print_info(torrent::LOG_TORRENT_INFO, download->info(), "download_list", "Hash queue.");
if (rpc::call_command_value("d.hashing", rpc::make_target(download)) != Download::variable_hashing_stopped)
throw torrent::internal_error("DownloadList::hash_queue(...) hashing already queued.");
@@ -583,6 +601,8 @@ void
DownloadList::received_finished(Download* download) {
check_contains(download);
lt_log_print_info(torrent::LOG_TORRENT_INFO, download->info(), "download_list", "Received finished.");
if (rpc::call_command_value("pieces.hash.on_completion"))
// Set some 'checking_finished_thingie' variable to make hash_done
// trigger correctly, also so it can bork on missing data.
@@ -596,19 +616,21 @@ void
DownloadList::confirm_finished(Download* download) {
check_contains(download);
lt_log_print_info(torrent::LOG_TORRENT_INFO, download->info(), "download_list", "Confirming finished.");
if (download->download()->info()->is_meta_download())
return process_meta_download(download);
rpc::call_command("d.complete.set", (int64_t)1, rpc::make_target(download));
// Clean up these settings:
torrent::Object conn_current = rpc::call_command_void("d.connection_seed", rpc::make_target(download));
torrent::Object choke_up = rpc::call_command_void("d.up.choke_heuristics.seed", rpc::make_target(download));
torrent::Object choke_down = rpc::call_command_void("d.down.choke_heuristics.seed", rpc::make_target(download));
torrent::Object conn_current = rpc::call_command("d.connection_seed", torrent::Object(), rpc::make_target(download));
torrent::Object choke_up = rpc::call_command("d.up.choke_heuristics.seed", torrent::Object(), rpc::make_target(download));
torrent::Object choke_down = rpc::call_command("d.down.choke_heuristics.seed", torrent::Object(), rpc::make_target(download));
if (conn_current.is_string_empty()) conn_current = rpc::call_command_void("protocol.connection.seed", rpc::make_target(download));
if (choke_up.is_string_empty()) choke_up = rpc::call_command_void("protocol.choke_heuristics.up.seed", rpc::make_target(download));
if (choke_down.is_string_empty()) choke_down = rpc::call_command_void("protocol.choke_heuristics.down.seed", rpc::make_target(download));
if (conn_current.is_string_empty()) conn_current = rpc::call_command("protocol.connection.seed", torrent::Object(), rpc::make_target(download));
if (choke_up.is_string_empty()) choke_up = rpc::call_command("protocol.choke_heuristics.up.seed", torrent::Object(), rpc::make_target(download));
if (choke_down.is_string_empty()) choke_down = rpc::call_command("protocol.choke_heuristics.down.seed", torrent::Object(), rpc::make_target(download));
rpc::call_command("d.connection_current.set", conn_current, rpc::make_target(download));
rpc::call_command("d.up.choke_heuristics.set", choke_up, rpc::make_target(download));
@@ -618,11 +640,11 @@ DownloadList::confirm_finished(Download* download) {
if (rpc::call_command_value("d.peers_min", rpc::make_target(download)) == rpc::call_command_value("throttle.min_peers.normal") &&
rpc::call_command_value("throttle.min_peers.seed") >= 0)
rpc::call_command("d.peers_min.set", rpc::call_command_void("throttle.min_peers.seed"), rpc::make_target(download));
rpc::call_command("d.peers_min.set", rpc::call_command("throttle.min_peers.seed"), rpc::make_target(download));
if (rpc::call_command_value("d.peers_max", rpc::make_target(download)) == rpc::call_command_value("throttle.max_peers.normal") &&
rpc::call_command_value("throttle.max_peers.seed") >= 0)
rpc::call_command("d.peers_max.set", rpc::call_command_void("throttle.max_peers.seed"), rpc::make_target(download));
rpc::call_command("d.peers_max.set", rpc::call_command("throttle.max_peers.seed"), rpc::make_target(download));
// Do this before the slots are called in case one of them closes
// the download.
@@ -642,6 +664,9 @@ DownloadList::confirm_finished(Download* download) {
DL_TRIGGER_EVENT(download, "event.download.finished");
if (find(infohash) == end())
return;
// if (download->resume_flags() != ~uint32_t())
// throw torrent::internal_error("DownloadList::confirm_finished(...) download->resume_flags() != ~uint32_t().");
@@ -655,8 +680,7 @@ DownloadList::confirm_finished(Download* download) {
// being hashed.
download->set_resume_flags(~uint32_t());
if (find(infohash) != end() &&
!download->is_active() && rpc::call_command_value("d.state", rpc::make_target(download)) == 1)
if (!download->is_active() && rpc::call_command_value("d.state", rpc::make_target(download)) == 1)
resume(download,
torrent::Download::start_no_create |
torrent::Download::start_skip_tracker |
@@ -665,6 +689,8 @@ DownloadList::confirm_finished(Download* download) {
void
DownloadList::process_meta_download(Download* download) {
lt_log_print_info(torrent::LOG_TORRENT_INFO, download->info(), "download_list", "Processing meta download.");
rpc::call_command("d.stop", torrent::Object(), rpc::make_target(download));
rpc::call_command("d.close", torrent::Object(), rpc::make_target(download));
+6 -6
View File
@@ -39,19 +39,19 @@
#include <map>
#include <string>
#include <sigc++/functors/slot.h>
#include <tr1/functional>
#include "download.h"
namespace core {
class DownloadSlotMap : public std::map<std::string, sigc::slot1<void, Download*> > {
class DownloadSlotMap : public std::map<std::string, std::tr1::function<void (Download*)> > {
public:
typedef sigc::slot1<void, Download*> SlotDownload;
typedef std::map<std::string, SlotDownload> Base;
typedef std::tr1::function<void (Download*)> slot_download;
typedef std::map<std::string, slot_download> Base;
void insert(const std::string& key, SlotDownload s) { Base::operator[](key) = s; }
void erase(const std::string& key) { Base::erase(key); }
void insert(const std::string& key, slot_download s) { Base::operator[](key) = s; }
void erase(const std::string& key) { Base::erase(key); }
void for_each(Download* d);
};
+15 -16
View File
@@ -38,45 +38,44 @@
#include <memory>
#include <sstream>
#include <sigc++/adaptors/bind.h>
#include <sigc++/adaptors/hide.h>
#include <torrent/http.h>
#include "rak/functional.h"
#include "http_queue.h"
#include "curl_get.h"
namespace std { using namespace tr1; }
namespace core {
HttpQueue::iterator
HttpQueue::insert(const std::string& url, std::iostream* s) {
std::auto_ptr<CurlGet> h(m_slotFactory());
std::auto_ptr<CurlGet> h(m_slot_factory());
h->set_url(url);
h->set_stream(s);
h->set_timeout(5 * 60);
iterator itr = Base::insert(end(), h.get());
iterator signal_itr = base_type::insert(end(), h.get());
h->signal_done().push_back(std::bind(&HttpQueue::erase, this, itr));
h->signal_failed().push_back(std::bind(&HttpQueue::erase, this, itr));
h->signal_done().push_back(std::tr1::bind(&HttpQueue::erase, this, signal_itr));
h->signal_failed().push_back(std::tr1::bind(&HttpQueue::erase, this, signal_itr));
(*itr)->start();
(*signal_itr)->start();
h.release();
m_signalInsert.emit(*itr);
return itr;
for (signal_curl_get::iterator itr = m_signal_insert.begin(), last = m_signal_insert.end(); itr != last; itr++)
(*itr)(*signal_itr);
return signal_itr;
}
void
HttpQueue::erase(iterator itr) {
m_signalErase.emit(*itr);
HttpQueue::erase(iterator signal_itr) {
for (signal_curl_get::iterator itr = m_signal_erase.begin(), last = m_signal_erase.end(); itr != last; itr++)
(*itr)(*signal_itr);
delete *itr;
Base::erase(itr);
delete *signal_itr;
base_type::erase(signal_itr);
}
void
@@ -84,7 +83,7 @@ HttpQueue::clear() {
while (!empty())
erase(begin());
Base::clear();
base_type::clear();
}
}
+21 -20
View File
@@ -39,7 +39,7 @@
#include <list>
#include <iosfwd>
#include <sigc++/signal.h>
#include <tr1/functional>
namespace core {
@@ -47,22 +47,23 @@ class CurlGet;
class HttpQueue : private std::list<CurlGet*> {
public:
typedef std::list<CurlGet*> Base;
typedef sigc::signal1<void, CurlGet*> SignalHttp;
typedef sigc::slot0<CurlGet*> SlotFactory;
typedef std::list<CurlGet*> base_type;
typedef std::tr1::function<CurlGet* ()> slot_factory;
typedef std::tr1::function<void (CurlGet*)> slot_curl_get;
typedef std::list<slot_curl_get> signal_curl_get;
using Base::iterator;
using Base::const_iterator;
using Base::reverse_iterator;
using Base::const_reverse_iterator;
using base_type::iterator;
using base_type::const_iterator;
using base_type::reverse_iterator;
using base_type::const_reverse_iterator;
using Base::begin;
using Base::end;
using Base::rbegin;
using Base::rend;
using base_type::begin;
using base_type::end;
using base_type::rbegin;
using base_type::rend;
using Base::empty;
using Base::size;
using base_type::empty;
using base_type::size;
HttpQueue() {}
~HttpQueue() { clear(); }
@@ -77,15 +78,15 @@ public:
void clear();
void slot_factory(SlotFactory s) { m_slotFactory = s; }
void set_slot_factory(slot_factory s) { m_slot_factory = s; }
SignalHttp& signal_insert() { return m_signalInsert; }
SignalHttp& signal_erase() { return m_signalErase; }
signal_curl_get& signal_insert() { return m_signal_insert; }
signal_curl_get& signal_erase() { return m_signal_erase; }
private:
SlotFactory m_slotFactory;
SignalHttp m_signalInsert;
SignalHttp m_signalErase;
slot_factory m_slot_factory;
signal_curl_get m_signal_insert;
signal_curl_get m_signal_erase;
};
}
-65
View File
@@ -1,65 +0,0 @@
// 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 <jaris@ifi.uio.no>
//
// Skomakerveien 33
// 3185 Skoppum, NORWAY
#include "config.h"
#include <algorithm>
#include <rak/functional.h>
#include "globals.h"
#include "log.h"
namespace core {
void
Log::push_front(const std::string& msg) {
if (!m_enabled)
return;
Base::push_front(Type(cachedTime, msg));
if (size() > 50)
Base::pop_back();
m_signalUpdate.emit();
}
Log::iterator
Log::find_older(rak::timer t) {
return std::find_if(begin(), end(), rak::on(rak::mem_ref(&Type::first), std::bind2nd(std::less_equal<rak::timer>(), t)));
}
}
-88
View File
@@ -1,88 +0,0 @@
// 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 <jaris@ifi.uio.no>
//
// Skomakerveien 33
// 3185 Skoppum, NORWAY
#ifndef RTORRENT_CORE_LOG_H
#define RTORRENT_CORE_LOG_H
#include <deque>
#include <string>
#include <sigc++/signal.h>
#include <rak/timer.h>
namespace core {
class Log : private std::deque<std::pair<rak::timer, std::string> > {
public:
typedef std::pair<rak::timer, std::string> Type;
typedef std::deque<Type> Base;
typedef sigc::signal0<void> Signal;
using Base::iterator;
using Base::const_iterator;
using Base::reverse_iterator;
using Base::const_reverse_iterator;
using Base::begin;
using Base::end;
using Base::rbegin;
using Base::rend;
using Base::empty;
using Base::size;
Log() : m_enabled(true) {}
bool is_enabled() const { return m_enabled; }
void enable() { m_enabled = true; }
void disable() { m_enabled = false; }
void push_front(const std::string& msg);
iterator find_older(rak::timer t);
Signal& signal_update() { return m_signalUpdate; }
private:
bool m_enabled;
Signal m_signalUpdate;
};
}
#endif
+16 -81
View File
@@ -47,8 +47,6 @@
#include <rak/regex.h>
#include <rak/path.h>
#include <rak/string_manip.h>
#include <sigc++/adaptors/bind.h>
#include <sigc++/adaptors/hide.h>
#include <torrent/utils/resume.h>
#include <torrent/object.h>
#include <torrent/connection_manager.h>
@@ -71,83 +69,21 @@
#include "download_store.h"
#include "http_queue.h"
#include "manager.h"
#include "poll_manager_epoll.h"
#include "poll_manager_kqueue.h"
#include "poll_manager_select.h"
#include "poll_manager.h"
#include "view.h"
namespace std { using namespace tr1; }
namespace core {
void
Manager::handshake_log(const sockaddr* sa, int msg, int err, const torrent::HashString* hash) {
if (!rpc::call_command_value("log.handshake"))
return;
std::string peer;
std::string download;
const rak::socket_address* socketAddress = rak::socket_address::cast_from(sa);
if (socketAddress->is_valid()) {
char port[6];
snprintf(port, sizeof(port), "%d", socketAddress->port());
peer = socketAddress->address_str() + ":" + port;
} else {
peer = "(unknown)";
}
// torrent::Download d = torrent::download_find(hash);
// if (d.is_valid())
// download = ": " + d.name();
// else
download = "";
switch (msg) {
case torrent::ConnectionManager::handshake_incoming:
m_logComplete.push_front("Incoming connection from " + peer + download);
break;
case torrent::ConnectionManager::handshake_outgoing:
m_logComplete.push_front("Outgoing connection to " + peer + download);
break;
case torrent::ConnectionManager::handshake_outgoing_encrypted:
m_logComplete.push_front("Outgoing encrypted connection to " + peer + download);
break;
case torrent::ConnectionManager::handshake_outgoing_proxy:
m_logComplete.push_front("Outgoing proxy connection to " + peer + download);
break;
case torrent::ConnectionManager::handshake_success:
m_logComplete.push_front("Successful handshake: " + peer + download);
break;
case torrent::ConnectionManager::handshake_dropped:
m_logComplete.push_front("Dropped handshake: " + peer + " - " + torrent::strerror(err) + download);
break;
case torrent::ConnectionManager::handshake_failed:
m_logComplete.push_front("Handshake failed: " + peer + " - " + torrent::strerror(err) + download);
break;
case torrent::ConnectionManager::handshake_retry_plaintext:
m_logComplete.push_front("Trying again without encryption: " + peer + download);
break;
case torrent::ConnectionManager::handshake_retry_encrypted:
m_logComplete.push_front("Trying again encrypted: " + peer + download);
break;
default:
m_logComplete.push_front("Unknown handshake message for " + peer + download);
break;
}
}
void
Manager::push_log(const char* msg) {
m_logImportant.push_front(msg);
m_logComplete.push_front(msg);
m_log_important->lock_and_push_log(msg, strlen(msg), 0);
m_log_complete->lock_and_push_log(msg, strlen(msg), 0);
}
Manager::Manager() :
m_hashingView(NULL)
// m_pollManager(NULL) {
m_hashingView(NULL),
m_log_important(torrent::log_open_log_buffer("important")),
m_log_complete(torrent::log_open_log_buffer("complete"))
{
m_downloadStore = new DownloadStore();
m_downloadList = new DownloadList();
@@ -164,6 +100,8 @@ Manager::~Manager() {
torrent::Throttle::destroy_throttle(m_throttles["NULL"].first);
delete m_downloadList;
// TODO: Clean up logs objects.
delete m_downloadStore;
delete m_httpQueue;
delete m_fileStatusCache;
@@ -175,7 +113,7 @@ Manager::set_hashing_view(View* v) {
throw torrent::internal_error("Manager::set_hashing_view(...) received NULL or is already set.");
m_hashingView = v;
v->signal_changed().connect(sigc::mem_fun(this, &Manager::receive_hashing_changed));
m_hashingView->signal_changed().push_back(std::tr1::bind(&Manager::receive_hashing_changed, this));
}
torrent::ThrottlePair
@@ -195,7 +133,7 @@ Manager::get_throttle(const std::string& name) {
void
Manager::set_address_throttle(uint32_t begin, uint32_t end, torrent::ThrottlePair throttles) {
m_addressThrottles.set_merge(begin, end, throttles);
torrent::connection_manager()->set_address_throttle(sigc::mem_fun(control->core(), &core::Manager::get_address_throttle));
torrent::connection_manager()->address_throttle() = tr1::bind(&core::Manager::get_address_throttle, control->core(), tr1::placeholders::_1);
}
torrent::ThrottlePair
@@ -206,12 +144,10 @@ Manager::get_address_throttle(const sockaddr* addr) {
// Most of this should be possible to move out.
void
Manager::initialize_second() {
torrent::Http::set_factory(std::bind(&CurlStack::new_object, m_httpStack));
m_httpQueue->slot_factory(sigc::mem_fun(m_httpStack, &CurlStack::new_object));
torrent::Http::slot_factory() = std::tr1::bind(&CurlStack::new_object, m_httpStack);
m_httpQueue->set_slot_factory(std::tr1::bind(&CurlStack::new_object, m_httpStack));
CurlStack::global_init();
torrent::connection_manager()->set_signal_handshake_log(sigc::mem_fun(this, &Manager::handshake_log));
}
void
@@ -247,7 +183,7 @@ Manager::listen_open() {
return;
int portFirst, portLast;
torrent::Object portRange = rpc::call_command_void("network.port_range");
torrent::Object portRange = rpc::call_command("network.port_range");
if (portRange.is_string()) {
if (std::sscanf(portRange.as_string().c_str(), "%i-%i", &portFirst, &portLast) != 2)
@@ -373,8 +309,7 @@ Manager::set_proxy_address(const std::string& addr) {
void
Manager::receive_http_failed(std::string msg) {
m_logImportant.push_front("Http download error: \"" + msg + "\"");
m_logComplete.push_front("Http download error: \"" + msg + "\"");
push_log_std("Http download error: \"" + msg + "\"");
}
void
@@ -395,7 +330,7 @@ Manager::try_create_download(const std::string& uri, int flags, const command_li
f->set_start(flags & create_start);
f->set_print_log(!(flags & create_quiet));
f->slot_finished(sigc::bind(sigc::ptr_fun(&rak::call_delete_func<core::DownloadFactory>), f));
f->slot_finished(std::tr1::bind(&rak::call_delete_func<core::DownloadFactory>, f));
if (flags & create_raw_data)
f->load_raw_data(uri);
@@ -419,7 +354,7 @@ Manager::try_create_download_from_meta_download(torrent::Object* bencode, const
f->set_start(meta.get_key_value("start"));
f->set_print_log(meta.get_key_value("print_log"));
f->slot_finished(sigc::bind(sigc::ptr_fun(&rak::call_delete_func<core::DownloadFactory>), f));
f->slot_finished(std::tr1::bind(&rak::call_delete_func<core::DownloadFactory>, f));
// Bit of a waste to create the bencode repesentation here
// only to have the DownloadFactory decode it.
+9 -9
View File
@@ -40,12 +40,12 @@
#include <iosfwd>
#include <vector>
#include <torrent/utils/log_buffer.h>
#include <torrent/connection_manager.h>
#include "download_list.h"
#include "poll_manager.h"
#include "range_map.h"
#include "log.h"
namespace torrent {
class Bencode;
@@ -69,8 +69,8 @@ public:
typedef DownloadList::iterator DListItr;
typedef utils::FileStatusCache FileStatusCache;
typedef sigc::slot1<void, DownloadList::iterator> SlotReady;
typedef sigc::slot0<void> SlotFailed;
// typedef std::tr1::function<void (DownloadList::iterator)> slot_ready;
// typedef std::tr1::function<void ()> slot_void;
Manager();
~Manager();
@@ -85,8 +85,8 @@ public:
View* hashing_view() { return m_hashingView; }
void set_hashing_view(View* v);
Log& get_log_important() { return m_logImportant; }
Log& get_log_complete() { return m_logComplete; }
torrent::log_buffer* log_important() { return m_log_important; }
torrent::log_buffer* log_complete() { return m_log_complete; }
ThrottleMap& throttles() { return m_throttles; }
torrent::ThrottlePair get_throttle(const std::string& name);
@@ -113,8 +113,8 @@ public:
void shutdown(bool force);
void push_log(const char* msg);
void push_log_std(const std::string& msg) { m_logImportant.push_front(msg); m_logComplete.push_front(msg); }
void push_log_complete(const std::string& msg) { m_logComplete.push_front(msg); }
void push_log_std(const std::string& msg) { m_log_important->lock_and_push_log(msg.c_str(), msg.size(), 0); m_log_complete->lock_and_push_log(msg.c_str(), msg.size(), 0); }
void push_log_complete(const std::string& msg) { m_log_complete->lock_and_push_log(msg.c_str(), msg.size(), 0); }
void handshake_log(const sockaddr* sa, int msg, int err, const torrent::HashString* hash);
@@ -152,8 +152,8 @@ private:
ThrottleMap m_throttles;
AddressThrottleMap m_addressThrottles;
Log m_logImportant;
Log m_logComplete;
torrent::log_buffer* m_log_important;
torrent::log_buffer* m_log_complete;
};
// Meh, cleanup.
+28 -46
View File
@@ -38,72 +38,54 @@
#include <stdexcept>
#include <unistd.h>
#include <rak/error_number.h>
#include <torrent/exceptions.h>
#include <torrent/poll_epoll.h>
#include <torrent/poll_kqueue.h>
#include <torrent/poll_select.h>
#include "globals.h"
#include "control.h"
#include "manager.h"
#include "poll_manager.h"
#include "poll_manager_epoll.h"
#include "poll_manager_kqueue.h"
#include "poll_manager_select.h"
namespace core {
PollManager::PollManager(torrent::Poll* poll) :
m_poll(poll) {
if (m_poll == NULL)
throw std::logic_error("PollManager::PollManager(...) received poll == NULL");
}
PollManager::~PollManager() {
delete m_poll;
}
PollManager*
PollManager::create_poll_manager() {
PollManager* pollManager = NULL;
Log* log = &control->core()->get_log_important();
const char* poll = getenv("RTORRENT_POLL");
torrent::Poll*
create_poll() {
const char* poll_name = getenv("RTORRENT_POLL");
int maxOpen = sysconf(_SC_OPEN_MAX);
if (poll != NULL) {
if (!strcmp(poll, "epoll"))
pollManager = PollManagerEPoll::create(maxOpen);
else if (!strcmp(poll, "kqueue"))
pollManager = PollManagerKQueue::create(maxOpen);
else if (!strcmp(poll, "select"))
pollManager = PollManagerSelect::create(maxOpen);
torrent::Poll* poll = NULL;
if (pollManager == NULL)
log->push_front(std::string("Cannot enable '") + poll + "' based polling.");
if (poll_name != NULL) {
if (!strcmp(poll_name, "epoll"))
poll = torrent::PollEPoll::create(maxOpen);
else if (!strcmp(poll_name, "kqueue"))
poll = torrent::PollKQueue::create(maxOpen);
else if (!strcmp(poll_name, "select"))
poll = torrent::PollSelect::create(maxOpen);
if (poll == NULL)
control->core()->push_log_std(std::string("Cannot enable '") + poll_name + "' based polling.");
}
if (pollManager != NULL)
log->push_front(std::string("Using '") + poll + "' based polling.");
if (poll != NULL)
control->core()->push_log_std(std::string("Using '") + poll_name + "' based polling.");
else if ((pollManager = PollManagerEPoll::create(maxOpen)) != NULL)
log->push_front("Using 'epoll' based polling.");
else if ((poll = torrent::PollEPoll::create(maxOpen)) != NULL)
control->core()->push_log_std("Using 'epoll' based polling.");
else if ((pollManager = PollManagerKQueue::create(maxOpen)) != NULL)
log->push_front("Using 'kqueue' based polling.");
else if ((poll = torrent::PollKQueue::create(maxOpen)) != NULL)
control->core()->push_log_std("Using 'kqueue' based polling.");
else if ((pollManager = PollManagerSelect::create(maxOpen)) != NULL)
log->push_front("Using 'select' based polling.");
else if ((poll = torrent::PollSelect::create(maxOpen)) != NULL)
control->core()->push_log_std("Using 'select' based polling.");
else
throw std::runtime_error("Could not create any PollManager.");
throw torrent::internal_error("Could not create any Poll object.");
return pollManager;
}
void
PollManager::check_error() {
if (rak::error_number::current().value() != rak::error_number::e_intr)
throw std::runtime_error("Poll::work(): " + std::string(rak::error_number::current().c_str()));
return poll;
}
}
+5 -31
View File
@@ -37,41 +37,15 @@
#ifndef RTORRENT_CORE_POLL_MANAGER_H
#define RTORRENT_CORE_POLL_MANAGER_H
#include <rak/timer.h>
#include <sigc++/signal.h>
#include <torrent/poll.h>
#include "curl_stack.h"
namespace torrent {
class Poll;
}
namespace core {
// CurlStack really should be somewhere else, but that won't happen
// until they add an epoll friendly API.
class PollManager {
public:
typedef sigc::signal0<void> Signal;
PollManager(torrent::Poll* poll);
virtual ~PollManager();
unsigned int get_open_max() const { return m_poll->open_max(); }
torrent::Poll* get_torrent_poll() { return m_poll; }
virtual void poll(rak::timer timeout) = 0;
virtual void poll_simple(rak::timer timeout) = 0;
static PollManager* create_poll_manager();
protected:
PollManager(const PollManager&);
void operator = (const PollManager&);
void check_error();
torrent::Poll* m_poll;
};
torrent::Poll* create_poll();
}
-98
View File
@@ -1,98 +0,0 @@
// 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 <jaris@ifi.uio.no>
//
// Skomakerveien 33
// 3185 Skoppum, NORWAY
#include "config.h"
#include <cstring>
#include <stdexcept>
#include <unistd.h>
#include <sys/time.h>
#include <torrent/poll_epoll.h>
#include <torrent/torrent.h>
#include "poll_manager_epoll.h"
#include "thread_base.h"
namespace core {
PollManagerEPoll*
PollManagerEPoll::create(int maxOpenSockets) {
torrent::PollEPoll* p = torrent::PollEPoll::create(maxOpenSockets);
if (p == NULL)
return NULL;
else
return new PollManagerEPoll(p);
}
PollManagerEPoll::~PollManagerEPoll() {
}
void
PollManagerEPoll::poll(rak::timer timeout) {
// Add 1ms to ensure we don't idle loop due to the lack of
// resolution.
torrent::perform();
timeout = std::min(timeout, rak::timer(torrent::next_timeout())) + 1000;
ThreadBase::release_global_lock();
ThreadBase::entering_main_polling();
int status = static_cast<torrent::PollEPoll*>(m_poll)->poll((timeout.usec() + 999) / 1000);
ThreadBase::leaving_main_polling();
ThreadBase::acquire_global_lock();
if (status == -1)
return check_error();
torrent::perform();
static_cast<torrent::PollEPoll*>(m_poll)->perform();
}
void
PollManagerEPoll::poll_simple(rak::timer timeout) {
// Add 1ms to ensure we don't idle loop due to the lack of
// resolution.
timeout = timeout + 1000;
if (static_cast<torrent::PollEPoll*>(m_poll)->poll((timeout.usec() + 999) / 1000) == -1)
return check_error();
static_cast<torrent::PollEPoll*>(m_poll)->perform();
}
}
-64
View File
@@ -1,64 +0,0 @@
// 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 <jaris@ifi.uio.no>
//
// Skomakerveien 33
// 3185 Skoppum, NORWAY
#ifndef RTORRENT_CORE_POLL_MANAGER_EPOLL_H
#define RTORRENT_CORE_POLL_MANAGER_EPOLL_H
#include "poll_manager.h"
namespace torrent {
class PollEPoll;
}
namespace core {
class PollManagerEPoll : public PollManager {
public:
static PollManagerEPoll* create(int maxOpenSockets);
~PollManagerEPoll();
torrent::Poll* get_torrent_poll();
void poll(rak::timer timeout);
void poll_simple(rak::timer timeout);
private:
PollManagerEPoll(torrent::Poll* p) : PollManager(p) {}
};
}
#endif
-99
View File
@@ -1,99 +0,0 @@
// 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 <jaris@ifi.uio.no>
//
// Skomakerveien 33
// 3185 Skoppum, NORWAY
#include "config.h"
#include <cstring>
#include <stdexcept>
#include <unistd.h>
#include <sys/time.h>
#include <torrent/exceptions.h>
#include <torrent/poll_kqueue.h>
#include <torrent/torrent.h>
#include "poll_manager_kqueue.h"
#include "thread_base.h"
namespace core {
PollManagerKQueue*
PollManagerKQueue::create(int maxOpenSockets) {
torrent::PollKQueue* p = torrent::PollKQueue::create(maxOpenSockets);
if (p == NULL)
return NULL;
else
return new PollManagerKQueue(p);
}
PollManagerKQueue::~PollManagerKQueue() {
}
void
PollManagerKQueue::poll(rak::timer timeout) {
// Add 1ms to ensure we don't idle loop due to the lack of
// resolution.
torrent::perform();
timeout = std::min(timeout, rak::timer(torrent::next_timeout())) + 1000;
ThreadBase::release_global_lock();
ThreadBase::entering_main_polling();
int status = static_cast<torrent::PollKQueue*>(m_poll)->poll((timeout.usec() + 999) / 1000);
ThreadBase::leaving_main_polling();
ThreadBase::acquire_global_lock();
if (status == -1)
return check_error();
torrent::perform();
static_cast<torrent::PollKQueue*>(m_poll)->perform();
}
void
PollManagerKQueue::poll_simple(rak::timer timeout) {
// Add 1ms to ensure we don't idle loop due to the lack of
// resolution.
timeout = std::min(timeout, rak::timer(torrent::next_timeout())) + 1000;
if (static_cast<torrent::PollKQueue*>(m_poll)->poll((timeout.usec() + 999) / 1000) == -1)
return check_error();
static_cast<torrent::PollKQueue*>(m_poll)->perform();
}
}
-64
View File
@@ -1,64 +0,0 @@
// 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 <jaris@ifi.uio.no>
//
// Skomakerveien 33
// 3185 Skoppum, NORWAY
#ifndef RTORRENT_CORE_POLL_MANAGER_KQUEUE_H
#define RTORRENT_CORE_POLL_MANAGER_KQUEUE_H
#include "poll_manager.h"
namespace torrent {
class PollKQueue;
}
namespace core {
class PollManagerKQueue : public PollManager {
public:
static PollManagerKQueue* create(int maxOpenSockets);
~PollManagerKQueue();
torrent::Poll* get_torrent_poll();
void poll(rak::timer timeout);
void poll_simple(rak::timer timeout);
private:
PollManagerKQueue(torrent::Poll* p) : PollManager(p) {}
};
}
#endif
-127
View File
@@ -1,127 +0,0 @@
// 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 <jaris@ifi.uio.no>
//
// Skomakerveien 33
// 3185 Skoppum, NORWAY
#include "config.h"
#include <cstring>
#include <stdexcept>
#include <unistd.h>
#include <sys/time.h>
#include <rak/allocators.h>
#include <torrent/exceptions.h>
#include <torrent/poll_select.h>
#include <torrent/torrent.h>
#include "poll_manager_select.h"
#include "thread_base.h"
namespace core {
PollManagerSelect::PollManagerSelect(torrent::Poll* p) : PollManager(p) {
#if defined USE_VARIABLE_FDSET
m_setSize = (m_poll->open_max() + 7) / 8;
char* buffer = rak::cacheline_allocator<char>::alloc_size(3 * m_setSize);
std::memset(buffer, 0, 3 * m_setSize);
m_readSet = (fd_set*)buffer;
m_writeSet = (fd_set*)(buffer += m_setSize);
m_errorSet = (fd_set*)(buffer += m_setSize);
#else
#error Only variable fdset supported atm.
#endif
}
PollManagerSelect*
PollManagerSelect::create(int maxOpenSockets) {
torrent::PollSelect* p = torrent::PollSelect::create(maxOpenSockets);
if (p == NULL)
return NULL;
return new PollManagerSelect(p);
}
PollManagerSelect::~PollManagerSelect() {
free(m_readSet);
}
void
PollManagerSelect::poll(rak::timer timeout) {
torrent::perform();
timeout = std::min(timeout, rak::timer(torrent::next_timeout())) + 1000;
std::memset(m_readSet, 0, m_setSize);
std::memset(m_writeSet, 0, m_setSize);
std::memset(m_errorSet, 0, m_setSize);
unsigned int maxFd = static_cast<torrent::PollSelect*>(m_poll)->fdset(m_readSet, m_writeSet, m_errorSet);
timeval t = timeout.tval();
ThreadBase::entering_main_polling();
ThreadBase::release_global_lock();
int status = select(maxFd + 1, m_readSet, m_writeSet, m_errorSet, &t);
ThreadBase::leaving_main_polling();
ThreadBase::acquire_global_lock();
if (status == -1)
return check_error();
torrent::perform();
static_cast<torrent::PollSelect*>(m_poll)->perform(m_readSet, m_writeSet, m_errorSet);
}
void
PollManagerSelect::poll_simple(rak::timer timeout) {
torrent::PollSelect* currentPoll = static_cast<torrent::PollSelect*>(m_poll);
timeout = timeout + 1000;
std::memset(m_readSet, 0, 3 * m_setSize);
unsigned int maxFd = currentPoll->fdset(m_readSet, m_writeSet, m_errorSet);
timeval t = timeout.tval();
if (select(maxFd + 1, m_readSet, m_writeSet, m_errorSet, &t) == -1)
return check_error();
currentPoll->perform(m_readSet, m_writeSet, m_errorSet);
}
}
-67
View File
@@ -1,67 +0,0 @@
// 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 <jaris@ifi.uio.no>
//
// Skomakerveien 33
// 3185 Skoppum, NORWAY
#ifndef RTORRENT_CORE_POLL_MANAGER_SELECT_H
#define RTORRENT_CORE_POLL_MANAGER_SELECT_H
#include "poll_manager.h"
namespace torrent {
class PollSelect;
}
namespace core {
class lt_cacheline_aligned PollManagerSelect : public PollManager {
public:
static PollManagerSelect* create(int maxOpenSockets);
~PollManagerSelect();
void poll(rak::timer timeout);
void poll_simple(rak::timer timeout);
private:
PollManagerSelect(torrent::Poll* p);
unsigned int m_setSize;
fd_set* m_readSet;
fd_set* m_writeSet;
fd_set* m_errorSet;
};
}
#endif
+19 -12
View File
@@ -40,7 +40,6 @@
#include <functional>
#include <rak/functional.h>
#include <rak/functional_fun.h>
#include <sigc++/adaptors/bind.h>
#include <torrent/download.h>
#include <torrent/exceptions.h>
@@ -139,12 +138,18 @@ struct view_downloads_filter : std::unary_function<Download*, bool> {
const torrent::Object& m_command;
};
inline void
void
View::emit_changed() {
priority_queue_erase(&taskScheduler, &m_delayChanged);
priority_queue_insert(&taskScheduler, &m_delayChanged, cachedTime);
}
void
View::emit_changed_now() {
for (signal_void::iterator itr = m_signal_changed.begin(), last = m_signal_changed.end(); itr != last; itr++)
(*itr)();
}
View::~View() {
if (m_name.empty())
return;
@@ -172,7 +177,7 @@ View::initialize(const std::string& name) {
m_focus = 0;
set_last_changed(rak::timer());
m_delayChanged.set_slot(rak::mem_fn(&m_signalChanged, &signal_type::operator()));
m_delayChanged.slot() = std::tr1::bind(&View::emit_changed_now, this);
}
void
@@ -184,7 +189,7 @@ View::erase(Download* download) {
} else {
erase_internal(itr);
rpc::parse_command_multiple_d_nothrow(download, m_eventRemoved);
rpc::call_object_nothrow(m_event_removed, rpc::make_target(download));
}
}
@@ -200,7 +205,7 @@ View::set_visible(Download* download) {
base_type::erase(itr);
insert_visible(download);
rpc::parse_command_multiple_d_nothrow(download, m_eventAdded);
rpc::call_object_nothrow(m_event_added, rpc::make_target(download));
}
void
@@ -218,7 +223,7 @@ View::set_not_visible(Download* download) {
base_type::erase(itr);
base_type::push_back(download);
rpc::parse_command_multiple_d_nothrow(download, m_eventRemoved);
rpc::call_object_nothrow(m_event_removed, rpc::make_target(download));
}
void
@@ -275,11 +280,13 @@ View::filter() {
// done by using a base_type* member variable, and making sure we
// set the elements to NULL as we trigger commands on them. Or
// perhaps always clear them, thus not throwing anything.
if (!m_eventRemoved.empty())
std::for_each(changed.begin(), splitChanged, rak::bind2nd(std::ptr_fun(&rpc::parse_command_multiple_d_nothrow), m_eventRemoved));
if (!m_event_removed.is_empty())
std::for_each(changed.begin(), splitChanged,
tr1::bind(&rpc::call_object_d_nothrow, m_event_removed, tr1::placeholders::_1));
if (!m_eventAdded.empty())
std::for_each(splitChanged, changed.end(), rak::bind2nd(std::ptr_fun(&rpc::parse_command_multiple_d_nothrow), m_eventAdded));
if (!m_event_added.is_empty())
std::for_each(changed.begin(), splitChanged,
tr1::bind(&rpc::call_object_d_nothrow, m_event_added, tr1::placeholders::_1));
emit_changed();
}
@@ -297,7 +304,7 @@ View::filter_download(core::Download* download) {
erase_internal(itr);
insert_visible(download);
rpc::parse_command_multiple_d_nothrow(download, m_eventAdded);
rpc::call_object_nothrow(m_event_added, rpc::make_target(download));
} else {
// This makes sure the download is sorted even if it is
@@ -315,7 +322,7 @@ View::filter_download(core::Download* download) {
erase_internal(itr);
base_type::push_back(download);
rpc::parse_command_multiple_d_nothrow(download, m_eventRemoved);
rpc::call_object_nothrow(m_event_removed, rpc::make_target(download));
}
emit_changed();
+15 -14
View File
@@ -49,12 +49,11 @@
#ifndef RTORRENT_CORE_VIEW_DOWNLOADS_H
#define RTORRENT_CORE_VIEW_DOWNLOADS_H
#include <memory>
#include <string>
#include <vector>
#include <rak/timer.h>
#include <sigc++/signal.h>
#include <torrent/object.h>
#include <tr1/functional>
#include "globals.h"
@@ -64,8 +63,9 @@ class Download;
class View : private std::vector<Download*> {
public:
typedef std::vector<Download*> base_type;
typedef sigc::signal0<void> signal_type;
typedef std::vector<Download*> base_type;
typedef std::tr1::function<void ()> slot_void;
typedef std::list<slot_void> signal_void;
using base_type::iterator;
using base_type::const_iterator;
@@ -102,7 +102,7 @@ public:
iterator focus() { return begin() + m_focus; }
const_iterator focus() const { return begin() + m_focus; }
void set_focus(iterator itr) { m_focus = position(itr); m_signalChanged.emit(); }
void set_focus(iterator itr) { m_focus = position(itr); emit_changed(); }
void insert(Download* download) { base_type::push_back(download); }
void erase(Download* download);
@@ -128,10 +128,10 @@ public:
void clear_filter_on();
const std::string& get_event_added() const { return m_eventAdded; }
const std::string& get_event_removed() const { return m_eventRemoved; }
void set_event_added(const std::string& cmd) { m_eventAdded = cmd; }
void set_event_removed(const std::string& cmd) { m_eventRemoved = cmd; }
const torrent::Object& event_added() const { return m_event_added; }
const torrent::Object& event_removed() const { return m_event_removed; }
void set_event_added(const torrent::Object& cmd) { m_event_added = cmd; }
void set_event_removed(const torrent::Object& cmd) { m_event_removed = cmd; }
// The time of the last change to the view, semantics of this is
// user-dependent. Used by f.ex. ViewManager to decide if it should
@@ -144,7 +144,7 @@ public:
// Don't connect any slots until after initialize else it get's
// triggered when adding the Download's in DownloadList.
signal_type& signal_changed() { return m_signalChanged; }
signal_void& signal_changed() { return m_signal_changed; }
private:
View(const View&);
@@ -155,7 +155,8 @@ private:
inline void insert_visible(Download* d);
inline void erase_internal(iterator itr);
inline void emit_changed();
void emit_changed();
void emit_changed_now();
size_type position(const_iterator itr) const { return itr - begin(); }
@@ -172,12 +173,12 @@ private:
torrent::Object m_filter;
std::string m_eventAdded;
std::string m_eventRemoved;
torrent::Object m_event_added;
torrent::Object m_event_removed;
rak::timer m_lastChanged;
signal_type m_signalChanged;
signal_void m_signal_changed;
rak::priority_item m_delayChanged;
};
+2 -5
View File
@@ -95,11 +95,8 @@ public:
void set_filter(const std::string& name, const torrent::Object& cmd);
void set_filter_on(const std::string& name, const filter_args& args);
void set_event_added(const std::string& name, const std::string& cmd) { (*find_throw(name))->set_event_added(cmd); }
void set_event_removed(const std::string& name, const std::string& cmd) { (*find_throw(name))->set_event_removed(cmd); }
private:
DownloadList* m_list;
void set_event_added(const std::string& name, const torrent::Object& cmd) { (*find_throw(name))->set_event_added(cmd); }
void set_event_removed(const std::string& name, const torrent::Object& cmd) { (*find_throw(name))->set_event_removed(cmd); }
};
}
+1 -1
View File
@@ -50,4 +50,4 @@ libsub_display_a_SOURCES = \
window_tracker_list.cc \
window_tracker_list.h
INCLUDES = -I$(srcdir) -I$(srcdir)/.. -I$(top_srcdir)
AM_CPPFLAGS = -I$(srcdir) -I$(srcdir)/.. -I$(top_srcdir)
+13
View File
@@ -39,7 +39,20 @@
#include <string>
#include <vector>
#if defined(HAVE_NCURSESW_CURSES_H)
#include <ncursesw/curses.h>
#elif defined(HAVE_NCURSESW_H)
#include <ncursesw.h>
#elif defined(HAVE_NCURSES_CURSES_H)
#include <ncurses/curses.h>
#elif defined(HAVE_NCURSES_H)
#include <ncurses.h>
#elif defined(HAVE_CURSES_H)
#include <curses.h>
#else
#error "SysV or X/Open-compatible Curses header file required"
#endif
// Let us hail the creators of curses for being idiots. The only
// clever move they made was in the naming.
+1 -1
View File
@@ -38,7 +38,7 @@
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/termios.h>
#include <termios.h>
#include <torrent/exceptions.h>
#include "canvas.h"
+3 -3
View File
@@ -62,10 +62,10 @@ public:
static void resize_term(int x, int y) { resizeterm(y, x); }
static void resize_term(std::pair<int, int> dim) { resizeterm(dim.second, dim.first); }
unsigned int get_x() { int x, y; getyx(m_window, y, x); return x; }
unsigned int get_x() { int x, __UNUSED y; getyx(m_window, y, x); return x; }
unsigned int get_y() { int x, y; getyx(m_window, y, x); return y; }
unsigned int width() { int x, y; getmaxyx(m_window, y, x); return x; }
unsigned int width() { int x, __UNUSED y; getmaxyx(m_window, y, x); return x; }
unsigned int height() { int x, y; getmaxyx(m_window, y, x); return y; }
void move(unsigned int x, unsigned int y) { wmove(m_window, y, x); }
@@ -101,7 +101,7 @@ public:
static void initialize();
static void cleanup();
static int get_screen_width() { int x, y; getmaxyx(stdscr, y, x); return x; }
static int get_screen_width() { int x, __UNUSED y; getmaxyx(stdscr, y, x); return x; }
static int get_screen_height() { int x, y; getmaxyx(stdscr, y, x); return y; }
static std::pair<int, int> term_size();
+1 -1
View File
@@ -50,7 +50,7 @@ namespace display {
Manager::Manager() :
m_forceRedraw(false) {
m_taskUpdate.set_slot(rak::mem_fn(this, &Manager::receive_update));
m_taskUpdate.slot() = std::tr1::bind(&Manager::receive_update, this);
}
Manager::~Manager() {
+1 -1
View File
@@ -112,7 +112,7 @@ TextElementValueBase::print(char* first, char* last, Canvas::attributes_list* at
if (u == NULL)
return first;
first += std::min<ptrdiff_t>(std::max(snprintf(first, last - first + 1, "%02u/%02u/%04u", u->tm_mday, (u->tm_mon + 1), (1900 + u->tm_year)), 0), last - first + 1);;
first += std::min<ptrdiff_t>(std::max(snprintf(first, last - first + 1, "%02u/%02u/%04u", u->tm_mday, (u->tm_mon + 1), (1900 + u->tm_year)), 0), last - first + 1);
} else if (m_flags & flag_time) {
time_t t = val;
+2 -2
View File
@@ -195,10 +195,10 @@ print_download_status(char* first, char* last, core::Download* d) {
first = print_buffer(first, last, "Checking hash [%2i%%]",
(d->download()->chunks_hashed() * 100) / d->download()->file_list()->size_chunks());
} else if (d->tracker_list()->has_active()) {
} else if (d->tracker_list()->has_active_not_scrape()) {
torrent::TrackerList::iterator itr =
std::find_if(d->tracker_list()->begin(), d->tracker_list()->end(),
std::mem_fun(&torrent::Tracker::is_busy));
std::mem_fun(&torrent::Tracker::is_busy_not_scrape));
char status[128];
(*itr)->get_status(status, sizeof(status));
+1 -1
View File
@@ -59,7 +59,7 @@ Window::Window(Canvas* canvas, int flags, extent_type minWidth, extent_type minH
m_maxWidth(maxWidth),
m_maxHeight(maxHeight) {
m_taskUpdate.set_slot(rak::mem_fn(this, &Window::redraw));
m_taskUpdate.slot() = std::tr1::bind(&Window::redraw, this);
}
Window::~Window() {
+16 -8
View File
@@ -48,18 +48,27 @@
namespace display {
WindowDownloadList::WindowDownloadList() :
Window(new Canvas, 0, 120, 1, extent_full, extent_full),
m_view(NULL) {
}
WindowDownloadList::~WindowDownloadList() {
m_connChanged.disconnect();
if (m_view != NULL)
m_view->signal_changed().erase(m_changed_itr);
m_view = NULL;
}
void
WindowDownloadList::set_view(core::View* l) {
if (m_view != NULL)
m_view->signal_changed().erase(m_changed_itr);
m_view = l;
m_connChanged.disconnect();
if (m_view != NULL)
m_connChanged = m_view->signal_changed().connect(sigc::mem_fun(*this, &Window::mark_dirty));
m_changed_itr = m_view->signal_changed().insert(m_view->signal_changed().begin(), std::tr1::bind(&Window::mark_dirty, this));
}
void
@@ -93,16 +102,15 @@ WindowDownloadList::redraw() {
while (range.first != range.second) {
char buffer[m_canvas->width() + 1];
char* position;
char* last = buffer + m_canvas->width() - 2 + 1;
position = print_download_title(buffer, last, *range.first);
print_download_title(buffer, last, *range.first);
m_canvas->print(0, pos++, "%c %s", range.first == m_view->focus() ? '*' : ' ', buffer);
position = print_download_info(buffer, last, *range.first);
print_download_info(buffer, last, *range.first);
m_canvas->print(0, pos++, "%c %s", range.first == m_view->focus() ? '*' : ' ', buffer);
position = print_download_status(buffer, last, *range.first);
print_download_status(buffer, last, *range.first);
m_canvas->print(0, pos++, "%c %s", range.first == m_view->focus() ? '*' : ' ', buffer);
++range.first;
+5 -10
View File
@@ -37,23 +37,18 @@
#ifndef RTORRENT_DISPLAY_WINDOW_DOWNLOAD_LIST_H
#define RTORRENT_DISPLAY_WINDOW_DOWNLOAD_LIST_H
#include <sigc++/connection.h>
#include "window.h"
#include "core/download_list.h"
namespace core {
class View;
}
#include "core/view.h"
namespace display {
class WindowDownloadList : public Window {
public:
WindowDownloadList() :
Window(new Canvas, 0, 120, 1, extent_full, extent_full),
m_view(NULL) {}
typedef core::View::signal_void::iterator signal_void_itr;
WindowDownloadList();
~WindowDownloadList();
virtual void redraw();
@@ -63,7 +58,7 @@ public:
private:
core::View* m_view;
sigc::connection m_connChanged;
signal_void_itr m_changed_itr;
};
}
+19 -20
View File
@@ -37,6 +37,7 @@
#include "config.h"
#include <torrent/rate.h>
#include <torrent/data/transfer_list.h>
#include <torrent/tracker_controller.h>
#include <torrent/tracker_list.h>
#include <torrent/peer/connection_list.h>
@@ -63,33 +64,31 @@ WindowDownloadStatusbar::redraw() {
m_canvas->erase();
char buffer[m_canvas->width()];
char* position;
char* last = buffer + m_canvas->width() - 2;
position = print_download_info(buffer, last, m_download);
print_download_info(buffer, last, m_download);
m_canvas->print(0, 0, "%s", buffer);
position = buffer + std::min<ptrdiff_t>(std::max(snprintf(buffer, last - buffer, "Peers: %i(%i) Min/Max: %i/%i Slots: U:%i/%i D:%i/%i U/I/C/A: %i/%i/%i/%i Unchoked: %u/%u Failed: %i",
(int)m_download->download()->connection_list()->size(),
(int)m_download->download()->peer_list()->available_list_size(),
(int)m_download->download()->connection_list()->min_size(),
(int)m_download->download()->connection_list()->max_size(),
(int)m_download->download()->uploads_min(),
(int)m_download->download()->uploads_max(),
(int)m_download->download()->downloads_min(),
(int)m_download->download()->downloads_max(),
(int)m_download->download()->peers_currently_unchoked(),
(int)m_download->download()->peers_currently_interested(),
(int)m_download->download()->peers_complete(),
(int)m_download->download()->peers_accounted(),
(int)m_download->info()->upload_unchoked(),
(int)m_download->info()->download_unchoked(),
(int)m_download->chunks_failed()),
0), last - buffer);
snprintf(buffer, last - buffer, "Peers: %i(%i) Min/Max: %i/%i Slots: U:%i/%i D:%i/%i U/I/C/A: %i/%i/%i/%i Unchoked: %u/%u Failed: %i",
(int)m_download->download()->connection_list()->size(),
(int)m_download->download()->peer_list()->available_list_size(),
(int)m_download->download()->connection_list()->min_size(),
(int)m_download->download()->connection_list()->max_size(),
(int)m_download->download()->uploads_min(),
(int)m_download->download()->uploads_max(),
(int)m_download->download()->downloads_min(),
(int)m_download->download()->downloads_max(),
(int)m_download->download()->peers_currently_unchoked(),
(int)m_download->download()->peers_currently_interested(),
(int)m_download->download()->peers_complete(),
(int)m_download->download()->peers_accounted(),
(int)m_download->info()->upload_unchoked(),
(int)m_download->info()->download_unchoked(),
(int)m_download->download()->transfer_list()->failed_count());
m_canvas->print(0, 1, "%s", buffer);
position = print_download_status(buffer, last, m_download);
print_download_status(buffer, last, m_download);
m_canvas->print(0, 2, "[%c:%i] %s",
m_download->tracker_list()->has_active() ? 'C' : ' ',
(int)(m_download->download()->tracker_controller()->seconds_to_next_timeout()),
+1 -2
View File
@@ -50,8 +50,7 @@ namespace display {
WindowDownloadTransferList::WindowDownloadTransferList(core::Download* d, unsigned int *focus) :
Window(new Canvas, 0, 0, 0, extent_full, extent_full),
m_download(d),
m_focus(focus) {
m_download(d) {
}
void
@@ -71,8 +71,6 @@ private:
char key_id(torrent::BlockTransfer::key_type key);
core::Download* m_download;
unsigned int* m_focus;
assigned_vector m_assigned;
};
+1 -1
View File
@@ -123,7 +123,7 @@ WindowFileList::redraw() {
if (fl->size_files() == 0 || m_canvas->height() < 2)
return;
iterator entries[m_canvas->height() - 1];
std::vector<iterator> entries(m_canvas->height() - 1);
unsigned int last = 0;
+8 -2
View File
@@ -52,8 +52,14 @@ WindowHttpQueue::WindowHttpQueue(core::HttpQueue* q) :
m_queue(q) {
set_active(false);
m_connInsert = m_queue->signal_insert().connect(sigc::mem_fun(*this, &WindowHttpQueue::receive_insert));
m_connErase = m_queue->signal_erase().connect(sigc::mem_fun(*this, &WindowHttpQueue::receive_erase));
m_connInsert = m_queue->signal_insert().insert(m_queue->signal_insert().end(),
std::tr1::bind(&WindowHttpQueue::receive_insert,
this,
std::tr1::placeholders::_1));
m_connErase = m_queue->signal_erase().insert(m_queue->signal_insert().end(),
std::tr1::bind(&WindowHttpQueue::receive_erase,
this,
std::tr1::placeholders::_1));
}
void
+7 -5
View File
@@ -37,7 +37,7 @@
#ifndef RTORRENT_DISPLAY_WINDOW_HTTP_QUEUE_H
#define RTORRENT_DISPLAY_WINDOW_HTTP_QUEUE_H
#include <sigc++/connection.h>
#include <tr1/functional>
#include "window.h"
@@ -50,8 +50,10 @@ namespace display {
class WindowHttpQueue : public Window {
public:
typedef std::tr1::function<void (core::CurlGet*)> slot_curl_get;
typedef std::list<slot_curl_get> signal_curl_get;
WindowHttpQueue(core::HttpQueue* q);
~WindowHttpQueue() { m_connInsert.disconnect(); m_connErase.disconnect(); }
virtual void redraw();
@@ -76,10 +78,10 @@ private:
static std::string create_name(core::CurlGet* h);
core::HttpQueue* m_queue;
sigc::connection m_connInsert;
sigc::connection m_connErase;
Container m_container;
signal_curl_get::iterator m_connInsert;
signal_curl_get::iterator m_connErase;
};
}
+18 -12
View File
@@ -37,6 +37,8 @@
#include "config.h"
#include <ctime>
#include <torrent/torrent.h>
#include <torrent/utils/thread_base.h>
#include "canvas.h"
#include "utils.h"
@@ -44,24 +46,25 @@
namespace display {
WindowLog::WindowLog(core::Log* l) :
WindowLog::WindowLog(torrent::log_buffer* l) :
Window(new Canvas, 0, 0, 0, extent_full, extent_static),
m_log(l) {
m_taskUpdate.set_slot(rak::mem_fn(this, &WindowLog::receive_update)),
m_taskUpdate.slot() = std::tr1::bind(&WindowLog::receive_update, this);
// We're trying out scheduled tasks instead.
m_connUpdate = l->signal_update().connect(sigc::mem_fun(*this, &WindowLog::receive_update));
unsigned int signal_index = torrent::main_thread()->signal_bitfield()->add_signal(std::tr1::bind(&WindowLog::receive_update, this));
m_log->lock_and_set_update_slot(std::tr1::bind(&torrent::thread_base::send_event_signal, torrent::main_thread(), signal_index, false));
}
WindowLog::~WindowLog() {
priority_queue_erase(&taskScheduler, &m_taskUpdate);
m_connUpdate.disconnect();
}
WindowLog::iterator
WindowLog::find_older() {
return m_log->find_older(cachedTime - rak::timer::from_seconds(60));
return m_log->find_older(cachedTime.seconds() - 60);
// return m_log->begin();
}
void
@@ -70,11 +73,13 @@ WindowLog::redraw() {
int pos = m_canvas->height();
for (core::Log::iterator itr = m_log->begin(), last = find_older(); itr != last && pos > 0; ++itr, --pos) {
char buffer[16];
print_hhmmss_local(buffer, buffer + 16, static_cast<time_t>(itr->first.seconds()));
for (iterator itr = m_log->end(), last = find_older(); itr != last && pos > 0; --pos) {
itr--;
m_canvas->print(0, pos - 1, "(%s) %s", buffer, itr->second.c_str());
char buffer[16];
print_hhmmss_local(buffer, buffer + 16, static_cast<time_t>(itr->timestamp));
m_canvas->print(0, pos - 1, "(%s) %s", buffer, itr->message.c_str());
}
}
@@ -86,11 +91,12 @@ WindowLog::receive_update() {
return;
iterator itr = find_older();
extent_type height = std::min(std::distance(m_log->begin(), itr), (std::iterator_traits<iterator>::difference_type)10);
extent_type height = std::min(std::distance(itr, (iterator)m_log->end()), (std::iterator_traits<iterator>::difference_type)10);
if (height != m_maxHeight) {
m_minHeight = height != 0 ? 1 : 0;
m_maxHeight = height;
mark_dirty();
m_slotAdjust();
} else {
@@ -100,7 +106,7 @@ WindowLog::receive_update() {
priority_queue_erase(&taskScheduler, &m_taskUpdate);
if (height != 0)
priority_queue_insert(&taskScheduler, &m_taskUpdate, (cachedTime + rak::timer::from_seconds(30)).round_seconds());
priority_queue_insert(&taskScheduler, &m_taskUpdate, (cachedTime + rak::timer::from_seconds(5)).round_seconds());
}
}
+5 -9
View File
@@ -37,9 +37,7 @@
#ifndef RTORRENT_DISPLAY_WINDOW_LOG_H
#define RTORRENT_DISPLAY_WINDOW_LOG_H
#include <sigc++/connection.h>
#include "core/log.h"
#include <torrent/utils/log_buffer.h>
#include "window.h"
@@ -47,9 +45,9 @@ namespace display {
class WindowLog : public Window {
public:
typedef core::Log::iterator iterator;
typedef torrent::log_buffer::const_iterator iterator;
WindowLog(core::Log* l);
WindowLog(torrent::log_buffer* l);
~WindowLog();
virtual void redraw();
@@ -59,10 +57,8 @@ public:
private:
inline iterator find_older();
core::Log* m_log;
sigc::connection m_connUpdate;
rak::priority_item m_taskUpdate;
torrent::log_buffer* m_log;
rak::priority_item m_taskUpdate;
};
}
+9 -16
View File
@@ -44,21 +44,17 @@
namespace display {
WindowLogComplete::WindowLogComplete(core::Log* l) :
WindowLogComplete::WindowLogComplete(torrent::log_buffer* l) :
Window(new Canvas, 0, 30, 1, extent_full, extent_full),
m_log(l) {
// We're trying out scheduled tasks instead.
m_connUpdate = l->signal_update().connect(sigc::mem_fun(*this, &WindowLogComplete::receive_update));
}
WindowLogComplete::~WindowLogComplete() {
m_connUpdate.disconnect();
}
WindowLogComplete::iterator
WindowLogComplete::find_older() {
return m_log->find_older(cachedTime - rak::timer::from_seconds(60));
return m_log->find_older(cachedTime.seconds() - 60);
}
void
@@ -70,28 +66,25 @@ WindowLogComplete::redraw() {
int pos = m_canvas->height();
for (core::Log::iterator itr = m_log->begin(), last = m_log->end(); itr != last && pos > 0; ++itr) {
for (iterator itr = m_log->end(), last = m_log->begin(); itr != last && pos > 0; ) {
itr--;
char buffer[16];
// Use an arbitrary min width of 60 for allowing multiple
// lines. This should ensure we don't mess up the display when the
// screen is shrunk too much.
unsigned int timeWidth = 3 + print_hhmmss_local(buffer, buffer + 16, static_cast<time_t>(itr->first.seconds())) - buffer;
unsigned int timeWidth = 3 + print_hhmmss_local(buffer, buffer + 16, static_cast<time_t>(itr->timestamp)) - buffer;
unsigned int logWidth = m_canvas->width() > 60 ? (m_canvas->width() - timeWidth) : (60 - timeWidth);
unsigned int logHeight = (itr->second.size() + logWidth - 1) / logWidth;
unsigned int logHeight = (itr->message.size() + logWidth - 1) / logWidth;
for (unsigned int j = logHeight; j > 0 && pos > 0; --j, --pos)
if (j == 1)
m_canvas->print(0, pos - 1, "(%s) %s", buffer, itr->second.substr(0, m_canvas->width() - timeWidth).c_str());
m_canvas->print(0, pos - 1, "(%s) %s", buffer, itr->message.substr(0, m_canvas->width() - timeWidth).c_str());
else
m_canvas->print(timeWidth, pos - 1, "%s", itr->second.substr(logWidth * (j - 1), m_canvas->width() - timeWidth).c_str());
m_canvas->print(timeWidth, pos - 1, "%s", itr->message.substr(logWidth * (j - 1), m_canvas->width() - timeWidth).c_str());
}
}
void
WindowLogComplete::receive_update() {
mark_dirty();
}
}
+4 -9
View File
@@ -37,9 +37,7 @@
#ifndef RTORRENT_DISPLAY_WINDOW_LOG_COMPLETE_H
#define RTORRENT_DISPLAY_WINDOW_LOG_COMPLETE_H
#include <sigc++/connection.h>
#include "core/log.h"
#include <torrent/utils/log_buffer.h>
#include "window.h"
@@ -47,20 +45,17 @@ namespace display {
class WindowLogComplete : public Window {
public:
typedef core::Log::iterator iterator;
typedef torrent::log_buffer::const_iterator iterator;
WindowLogComplete(core::Log* l);
WindowLogComplete(torrent::log_buffer* l);
~WindowLogComplete();
virtual void redraw();
void receive_update();
private:
inline iterator find_older();
core::Log* m_log;
sigc::connection m_connUpdate;
torrent::log_buffer* m_log;
};
}
+12 -2
View File
@@ -89,9 +89,18 @@ WindowTrackerList::redraw() {
m_canvas->print(4, pos++, "%s",
tracker->url().c_str());
if (pos < m_canvas->height())
if (pos < m_canvas->height()) {
const char* state;
if (tracker->is_busy_not_scrape())
state = "req ";
else if (tracker->is_busy())
state = "scr ";
else
state = " ";
m_canvas->print(0, pos++, "%s Id: %s Counters: %uf / %us (%u) %s S/L/D: %u/%u/%u (%u/%u)",
tracker->is_busy() ? "req " : " ",
state,
rak::copy_escape_html(tracker->tracker_id()).c_str(),
tracker->failed_counter(),
tracker->success_counter(),
@@ -102,6 +111,7 @@ WindowTrackerList::redraw() {
tracker->scrape_downloaded(),
tracker->latest_new_peers(),
tracker->latest_sum_peers());
}
if (range.first == *m_focus) {
m_canvas->set_attr(4, pos - 2, m_canvas->width(), is_focused() ? A_REVERSE : A_BOLD, COLOR_PAIR(0));
+1 -3
View File
@@ -43,6 +43,4 @@ rak::timer cachedTime;
rpc::ip_table_list ip_tables;
Control* control = NULL;
//__thread ThreadBase* main_thread = NULL;
ThreadMain* main_thread = NULL;
ThreadWorker* worker_thread = NULL;
ThreadWorker* worker_thread = NULL;
-3
View File
@@ -41,7 +41,6 @@
#include <rak/priority_queue_default.h>
#include "thread_base.h"
#include "thread_main.h"
#include "thread_worker.h"
#include "rpc/ip_table_list.h"
@@ -57,8 +56,6 @@ extern rak::timer cachedTime;
extern rpc::ip_table_list ip_tables;
extern Control* control;
// extern __thread ThreadBase* main_thread; // Only use for worker threads for now.
extern ThreadMain* main_thread;
extern ThreadWorker* worker_thread;
#endif
+1 -1
View File
@@ -12,4 +12,4 @@ libsub_input_a_SOURCES = \
text_input.cc \
text_input.h
INCLUDES = -I$(srcdir) -I$(srcdir)/.. -I$(top_srcdir)
AM_CPPFLAGS = -I$(srcdir) -I$(srcdir)/.. -I$(top_srcdir)

Some files were not shown because too many files have changed in this diff Show More