mirror of
https://github.com/rakshasa/rtorrent.git
synced 2026-08-06 10:12:30 +00:00
Compare commits
102 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| cf1ba60b67 | |||
| b283f51cad | |||
| 301926172a | |||
| 78a0fb3e85 | |||
| 145ad4fe0f | |||
| ae5f37dbf0 | |||
| 368a629804 | |||
| 3d2fb6afbc | |||
| e42ec54920 | |||
| 6a3234eaa7 | |||
| d396c8e058 | |||
| 9548e08935 | |||
| ce125b1c54 | |||
| 82a68420f4 | |||
| d9f6f5aef4 | |||
| 38f39bdb23 | |||
| 906683714b | |||
| a536fc09a0 | |||
| dea7c80996 | |||
| 3e3a84b3a0 | |||
| 866289b38a | |||
| c9e894982f | |||
| 6b7adfd6bd | |||
| fcd1fdb2fe | |||
| a5d92cc940 | |||
| 9fcef7fbd6 | |||
| effdc5642d | |||
| fe5439f6a0 | |||
| 58fba68aff | |||
| 89dfa3a268 | |||
| 0d620e77db | |||
| 55b826d6cb | |||
| 385b342deb | |||
| 2e9baa1635 | |||
| 67236d7757 | |||
| 66edb39863 | |||
| 00a349f68c | |||
| 370bae4b98 | |||
| aa93404278 | |||
| aa2f784ae6 | |||
| 529eda5aab | |||
| 629ebcbd54 | |||
| d8d7861244 | |||
| bc4209e380 | |||
| e36a0d43a4 | |||
| c3ad68156e | |||
| 6697806185 | |||
| 412a2f79b9 | |||
| 0bf60679e4 | |||
| b113a02584 | |||
| 7689059dbc | |||
| 3b2a47a6d0 | |||
| e28692492b | |||
| 2c97841e92 | |||
| 5e6cb5da04 | |||
| cd029a67c5 | |||
| addc323ec8 | |||
| 2217b14095 | |||
| 6a84facae0 | |||
| 66a116841a | |||
| bacb6c0f72 | |||
| 40fc8bbf80 | |||
| 13f672ab4d | |||
| 2967f9a224 | |||
| eac7536f6a | |||
| 78f64a3e08 | |||
| cf77a17399 | |||
| 48733c84ec | |||
| b020aa0197 | |||
| 678049bc09 | |||
| d0f6bb440a | |||
| 8f5f383e3c | |||
| 2ca49e3485 | |||
| 004862850d | |||
| d2d09d97f8 | |||
| fb75510c0f | |||
| 8d0f9b3300 | |||
| 76ed90f514 | |||
| b79dea94b2 | |||
| cf1c44ef5b | |||
| 9df9183a0c | |||
| f373b20c1b | |||
| 22acdd87c3 | |||
| cca1f21471 | |||
| 4dd7582240 | |||
| 03c0a4e18c | |||
| c2b768cd6d | |||
| 63cf700593 | |||
| 17201984a6 | |||
| 0a9e03df57 | |||
| 90830dc765 | |||
| d2dd143d2e | |||
| b71b44dbd6 | |||
| 83294e2198 | |||
| 46862e23a9 | |||
| 077288407f | |||
| 3fe1a734ac | |||
| fdc6ee56de | |||
| 36f8e5d349 | |||
| 5bed4f01ad | |||
| 020de10f38 | |||
| 47d36c0690 |
@@ -19,6 +19,7 @@
|
||||
Makefile
|
||||
aclocal.m4
|
||||
autom4te.cache
|
||||
compile
|
||||
config.h
|
||||
config.guess
|
||||
config.status
|
||||
@@ -64,3 +65,5 @@ TAGS
|
||||
###########################
|
||||
src/rtorrent
|
||||
test/rtorrentTest
|
||||
test-driver
|
||||
test/rtorrentTest.trs
|
||||
|
||||
+5
-9
@@ -1,9 +1,9 @@
|
||||
AC_INIT(rtorrent, 0.9.1, jaris@ifi.uio.no)
|
||||
AC_INIT(rtorrent, 0.9.6, sundell.software@gmail.com)
|
||||
|
||||
AC_DEFINE(API_VERSION, 3, api version)
|
||||
AC_DEFINE(API_VERSION, 9, api version)
|
||||
|
||||
AM_INIT_AUTOMAKE
|
||||
AM_CONFIG_HEADER(config.h)
|
||||
AC_CONFIG_HEADERS(config.h)
|
||||
AM_PATH_CPPUNIT(1.9.6)
|
||||
|
||||
AC_PROG_CXX
|
||||
@@ -41,15 +41,11 @@ CFLAGS="$CFLAGS $PTHREAD_CFLAGS $CURSES_CFLAGS"
|
||||
CXXFLAGS="$CXXFLAGS $PTHREAD_CFLAGS $CURSES_CFLAGS"
|
||||
LIBS="$PTHREAD_LIBS $CURSES_LIB $LIBS"
|
||||
|
||||
PKG_CHECK_MODULES(sigc, sigc++-2.0,
|
||||
CXXFLAGS="$CXXFLAGS $sigc_CFLAGS";
|
||||
LIBS="$LIBS $sigc_LIBS")
|
||||
|
||||
PKG_CHECK_MODULES(libcurl, libcurl >= 7.15.4,
|
||||
PKG_CHECK_MODULES([libcurl], libcurl >= 7.15.4,
|
||||
CXXFLAGS="$CXXFLAGS $libcurl_CFLAGS";
|
||||
LIBS="$LIBS $libcurl_LIBS")
|
||||
|
||||
PKG_CHECK_MODULES(libtorrent, libtorrent >= 0.13.1,
|
||||
PKG_CHECK_MODULES([libtorrent], libtorrent >= 0.13.6,
|
||||
CXXFLAGS="$CXXFLAGS $libtorrent_CFLAGS";
|
||||
LIBS="$LIBS $libtorrent_LIBS")
|
||||
|
||||
|
||||
@@ -1,7 +1,2 @@
|
||||
#man_MANS = rtorrent.1
|
||||
|
||||
EXTRA_DIST= \
|
||||
faq.xml \
|
||||
rtorrent.1 \
|
||||
rtorrent.1.xml \
|
||||
rtorrent.rc
|
||||
|
||||
Regular → Executable
Regular → Executable
@@ -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.
|
||||
@@ -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.
|
||||
@@ -1,4 +1,4 @@
|
||||
\section(IP filtering}
|
||||
\section{IP filtering}
|
||||
|
||||
\subsection{Introduction}
|
||||
|
||||
|
||||
@@ -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.
|
||||
@@ -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>
|
||||
Executable
+49
@@ -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
|
||||
Executable
+30
@@ -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
@@ -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
|
||||
|
||||
Executable
+128
@@ -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;
|
||||
Executable
+23
@@ -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;
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -37,12 +37,13 @@
|
||||
#ifndef RAK_PRIORITY_QUEUE_DEFAULT_H
|
||||
#define RAK_PRIORITY_QUEUE_DEFAULT_H
|
||||
|
||||
#include <stdexcept>
|
||||
#include <tr1/functional>
|
||||
#include <rak/allocators.h>
|
||||
#include <rak/priority_queue.h>
|
||||
#include <rak/timer.h>
|
||||
|
||||
#include "torrent/exceptions.h"
|
||||
|
||||
namespace rak {
|
||||
|
||||
class priority_item {
|
||||
@@ -52,7 +53,7 @@ public:
|
||||
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 = slot_void();
|
||||
@@ -101,16 +102,16 @@ priority_queue_perform(priority_queue_default* queue, timer t) {
|
||||
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.");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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; }
|
||||
|
||||
@@ -123,7 +123,7 @@ fi
|
||||
# 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="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config"
|
||||
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:
|
||||
@@ -160,7 +160,7 @@ case "${host_cpu}-${host_os}" in
|
||||
;;
|
||||
|
||||
*-darwin*)
|
||||
ax_pthread_flags="-pthread $ax_pthread_flags"
|
||||
ax_pthread_flags="none -pthread $ax_pthread_flags"
|
||||
;;
|
||||
esac
|
||||
|
||||
|
||||
+56
-27
@@ -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
|
||||
@@ -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
|
||||
@@ -103,22 +103,22 @@ AC_DEFUN([TORRENT_CHECK_KQUEUE_SOCKET_ONLY], [
|
||||
#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;
|
||||
}
|
||||
@@ -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
|
||||
@@ -145,7 +145,7 @@ AC_DEFUN([TORRENT_WITH_KQUEUE], [
|
||||
|
||||
AC_DEFUN([TORRENT_WITHOUT_KQUEUE], [
|
||||
AC_ARG_WITH(kqueue,
|
||||
[ --without-kqueue Do not check for kqueue support.],
|
||||
AC_HELP_STRING([--without-kqueue], [do not check for kqueue support]),
|
||||
[
|
||||
if test "$withval" = "yes"; then
|
||||
TORRENT_CHECK_KQUEUE
|
||||
@@ -160,8 +160,7 @@ AC_DEFUN([TORRENT_WITHOUT_KQUEUE], [
|
||||
|
||||
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)
|
||||
@@ -205,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
|
||||
@@ -299,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
|
||||
@@ -314,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
|
||||
@@ -336,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])
|
||||
@@ -402,7 +401,7 @@ AC_DEFUN([TORRENT_CHECK_CXX11], [
|
||||
|
||||
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)])
|
||||
|
||||
@@ -451,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)
|
||||
@@ -499,7 +498,7 @@ AC_DEFUN([TORRENT_WITH_INOTIFY], [
|
||||
|
||||
AC_COMPILE_IFELSE([AC_LANG_SOURCE([
|
||||
#include <sys/inotify.h>
|
||||
int main(int,const char*) { return (-1 == inotify_init()); }])
|
||||
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)],
|
||||
@@ -508,3 +507,33 @@ AC_DEFUN([TORRENT_WITH_INOTIFY], [
|
||||
|
||||
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)
|
||||
])
|
||||
])
|
||||
])
|
||||
|
||||
+46
-14
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
@@ -170,8 +170,8 @@ AC_DEFUN([TORRENT_CHECK_MADVISE], [
|
||||
|
||||
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); }
|
||||
#include <sys/mman.h>
|
||||
void f() { static char test@<:@1024@:>@; madvise((void *)test, sizeof(test), MADV_NORMAL); }
|
||||
])],
|
||||
[
|
||||
AC_MSG_RESULT(yes)
|
||||
@@ -241,7 +241,7 @@ AC_DEFUN([TORRENT_CHECK_ALIGNED], [
|
||||
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;
|
||||
@@ -259,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)
|
||||
@@ -270,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)
|
||||
@@ -282,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()
|
||||
@@ -297,7 +328,7 @@ AC_DEFUN([TORRENT_ENABLE_TR1], [
|
||||
|
||||
AC_DEFUN([TORRENT_ENABLE_CXX11], [
|
||||
AC_ARG_ENABLE(std_c++11,
|
||||
[ --disable-std_c++11 disable check for support for C++11 [[default=enable]]],
|
||||
AC_HELP_STRING([--disable-std_c++11], [disable check for support for C++11 [[default=enable]]]),
|
||||
[
|
||||
if test "$enableval" = "yes"; then
|
||||
TORRENT_CHECK_CXX11()
|
||||
@@ -307,5 +338,6 @@ AC_DEFUN([TORRENT_ENABLE_CXX11], [
|
||||
fi
|
||||
],[
|
||||
TORRENT_CHECK_CXX11()
|
||||
])
|
||||
]
|
||||
)
|
||||
])
|
||||
|
||||
+2
-1
@@ -18,6 +18,7 @@ libsub_root_a_SOURCES = \
|
||||
command_helpers.h \
|
||||
command_groups.cc \
|
||||
command_local.cc \
|
||||
command_logging.cc \
|
||||
command_network.cc \
|
||||
command_peer.cc \
|
||||
command_throttle.cc \
|
||||
@@ -52,4 +53,4 @@ rtorrent_LDADD = \
|
||||
rtorrent_SOURCES = \
|
||||
main.cc
|
||||
|
||||
INCLUDES = -I$(srcdir) -I$(top_srcdir)
|
||||
AM_CPPFLAGS = -I$(srcdir) -I$(top_srcdir)
|
||||
|
||||
+15
-18
@@ -138,9 +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);
|
||||
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:
|
||||
@@ -149,8 +150,9 @@ 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;
|
||||
}
|
||||
@@ -282,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) { }
|
||||
|
||||
@@ -334,8 +327,14 @@ d_chunks_seen(core::Download* download) {
|
||||
|
||||
if (seen == NULL)
|
||||
return std::string();
|
||||
else
|
||||
return std::string((const char*)seen, download->download()->file_list()->size_chunks());
|
||||
|
||||
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
|
||||
@@ -864,8 +863,6 @@ initialize_command_download() {
|
||||
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", tr1::bind(&cmd_d_initialize_logs, tr1::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));
|
||||
|
||||
+14
-1
@@ -37,6 +37,7 @@
|
||||
#include "config.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <torrent/utils/log.h>
|
||||
|
||||
#include "globals.h"
|
||||
#include "control.h"
|
||||
@@ -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,6 +423,16 @@ 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, tr1::bind(&system_method_insert_object, tr1::placeholders::_2, flags));
|
||||
|
||||
@@ -455,4 +466,6 @@ initialize_command_dynamic() {
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -49,6 +49,7 @@ void initialize_command_file();
|
||||
void initialize_command_ip();
|
||||
void initialize_command_peer();
|
||||
void initialize_command_local();
|
||||
void initialize_command_logging();
|
||||
void initialize_command_network();
|
||||
void initialize_command_groups();
|
||||
void initialize_command_throttle();
|
||||
@@ -63,6 +64,7 @@ initialize_commands() {
|
||||
initialize_command_network();
|
||||
initialize_command_groups();
|
||||
initialize_command_local();
|
||||
initialize_command_logging();
|
||||
initialize_command_ui();
|
||||
initialize_command_download();
|
||||
initialize_command_file();
|
||||
|
||||
@@ -135,7 +135,7 @@ void initialize_commands();
|
||||
torrent::raw_string::from_c_str(key), tr1::placeholders::_2));
|
||||
|
||||
#define CMD2_FUNC_SINGLE(key, cmds) \
|
||||
CMD2_ANY(key, tr1::bind(&rpc::command_function_call, torrent::raw_string::from_c_str(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) \
|
||||
|
||||
@@ -245,9 +245,6 @@ append_table(torrent::ipv4_table::base_type* extent, torrent::Object::list_type&
|
||||
torrent::ipv4_table::table_type::iterator first = extent->table.begin();
|
||||
torrent::ipv4_table::table_type::iterator last = extent->table.end();
|
||||
|
||||
int current_value = 0;
|
||||
uint32_t range_first = 0;
|
||||
|
||||
while (first != last) {
|
||||
if (first->first != NULL) {
|
||||
// Do something more here?...
|
||||
@@ -266,9 +263,6 @@ append_table(torrent::ipv4_table::base_type* extent, torrent::Object::list_type&
|
||||
torrent::option_as_string(torrent::OPTION_IP_FILTER, first->second));
|
||||
|
||||
result.push_back((std::string)buffer);
|
||||
|
||||
range_first = position;
|
||||
current_value = first->second;
|
||||
}
|
||||
|
||||
first++;
|
||||
|
||||
+3
-110
@@ -48,8 +48,6 @@
|
||||
#include <torrent/chunk_manager.h>
|
||||
#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"
|
||||
@@ -80,63 +78,6 @@ apply_pieces_stats_total_size() {
|
||||
return size;
|
||||
}
|
||||
|
||||
torrent::Object
|
||||
apply_log(const torrent::Object::string_type& arg, int logType) {
|
||||
if (rpc::execFile.log_fd() != -1) {
|
||||
switch (logType) {
|
||||
case 0: ::close(rpc::execFile.log_fd()); rpc::execFile.set_log_fd(-1); break;
|
||||
case 1:
|
||||
// if (control->scgi()) {
|
||||
// ::close(control->scgi()->log_fd());
|
||||
// control->scgi()->set_log_fd(-1);
|
||||
// }
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!arg.empty()) {
|
||||
int logFd = open(rak::path_expand(arg).c_str(), O_WRONLY | O_APPEND | O_CREAT, 0644);
|
||||
|
||||
if (logFd < 0)
|
||||
throw torrent::input_error("Could not open execute log file.");
|
||||
|
||||
switch (logType) {
|
||||
case 0: rpc::execFile.set_log_fd(logFd); break;
|
||||
// case 1: if (control->scgi()) control->scgi()->set_log_fd(logFd); break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
control->core()->push_log("Opened log file.");
|
||||
|
||||
} else {
|
||||
control->core()->push_log("Closed log file.");
|
||||
}
|
||||
|
||||
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];
|
||||
@@ -234,27 +175,6 @@ group_insert(const torrent::Object::list_type& args) {
|
||||
return name;
|
||||
}
|
||||
|
||||
torrent::Object
|
||||
log_vmmap_dump(const std::string& str) {
|
||||
core::DownloadList* d_list = control->core()->download_list();
|
||||
std::vector<torrent::vm_mapping> all_mappings;
|
||||
|
||||
for (core::DownloadList::iterator itr = d_list->begin(), last = d_list->end(); itr != last; itr++) {
|
||||
std::vector<torrent::vm_mapping> tmp_mappings = torrent::chunk_list_mapping((*itr)->download());
|
||||
|
||||
all_mappings.insert(all_mappings.end(), tmp_mappings.begin(), tmp_mappings.end());
|
||||
}
|
||||
|
||||
FILE* log_file = fopen(str.c_str(), "w");
|
||||
|
||||
for (std::vector<torrent::vm_mapping>::iterator itr = all_mappings.begin(), last = all_mappings.end(); itr != last; itr++) {
|
||||
fprintf(log_file, "%8p-%8p [%5llxk]\n", itr->ptr, (char*)itr->ptr + itr->length, (long long unsigned int)(itr->length / 1024));
|
||||
}
|
||||
|
||||
fclose(log_file);
|
||||
return torrent::Object();
|
||||
}
|
||||
|
||||
static const int file_print_use_space = 0x1;
|
||||
static const int file_print_delim_space = 0x2;
|
||||
|
||||
@@ -263,10 +183,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);
|
||||
@@ -299,25 +219,6 @@ cmd_file_append(const torrent::Object::list_type& args) {
|
||||
return torrent::Object();
|
||||
}
|
||||
|
||||
torrent::Object
|
||||
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());
|
||||
return torrent::Object();
|
||||
}
|
||||
|
||||
torrent::Object
|
||||
apply_log_add_output(const torrent::Object::list_type& args) {
|
||||
if (args.size() != 2)
|
||||
throw torrent::input_error("Invalid number of arguments.");
|
||||
|
||||
torrent::log_add_group_output(torrent::option_find_string(torrent::OPTION_LOG_GROUP, args.front().as_string().c_str()),
|
||||
args.back().as_string().c_str());
|
||||
return torrent::Object();
|
||||
}
|
||||
|
||||
void
|
||||
initialize_command_local() {
|
||||
torrent::ChunkManager* chunkManager = torrent::chunk_manager();
|
||||
@@ -337,7 +238,7 @@ initialize_command_local() {
|
||||
CMD2_VAR_STRING ("system.file.split_suffix", ".part");
|
||||
|
||||
CMD2_ANY ("system.file_status_cache.size", tr1::bind(&utils::FileStatusCache::size,
|
||||
(utils::FileStatusCache::base_type*)control->core()->file_status_cache()));
|
||||
(utils::FileStatusCache::base_type*)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);
|
||||
@@ -412,14 +313,6 @@ 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", tr1::bind(&apply_log_open_file, tr1::placeholders::_2));
|
||||
CMD2_ANY_LIST ("log.add_output", tr1::bind(&apply_log_add_output, tr1::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 ("log.libtorrent", tr1::bind(&apply_log_libtorrent, tr1::placeholders::_2));
|
||||
|
||||
CMD2_ANY_LIST ("file.append", tr1::bind(&cmd_file_append, tr1::placeholders::_2));
|
||||
|
||||
// TODO: Convert to new command types:
|
||||
|
||||
@@ -0,0 +1,175 @@
|
||||
// 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 <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <torrent/data/chunk_utils.h>
|
||||
#include <torrent/object.h>
|
||||
#include <torrent/utils/log.h>
|
||||
#include <torrent/utils/option_strings.h>
|
||||
|
||||
#include "core/download.h"
|
||||
#include "core/download_list.h"
|
||||
#include "core/manager.h"
|
||||
#include "rak/path.h"
|
||||
#include "rpc/parse_commands.h"
|
||||
|
||||
#include "globals.h"
|
||||
#include "control.h"
|
||||
#include "command_helpers.h"
|
||||
|
||||
static const int log_flag_use_gz = 0x1;
|
||||
static const int log_flag_append_pid = 0x2;
|
||||
|
||||
void
|
||||
log_add_group_output_str(const char* group_name, const char* output_id) {
|
||||
int log_group = torrent::option_find_string(torrent::OPTION_LOG_GROUP, group_name);
|
||||
torrent::log_add_group_output(log_group, output_id);
|
||||
}
|
||||
|
||||
torrent::Object
|
||||
apply_log_open(int output_flags, const torrent::Object::list_type& args) {
|
||||
if (args.size() < 2)
|
||||
throw torrent::input_error("Invalid number of arguments.");
|
||||
|
||||
torrent::Object::list_const_iterator itr = args.begin();
|
||||
|
||||
std::string output_id = (itr++)->as_string();
|
||||
std::string file_name = rak::path_expand((itr++)->as_string());
|
||||
|
||||
if ((output_flags & log_flag_append_pid)) {
|
||||
char buffer[32];
|
||||
snprintf(buffer, 32, ".%li", (long)getpid());
|
||||
|
||||
file_name += buffer;
|
||||
}
|
||||
|
||||
if ((output_flags & log_flag_use_gz))
|
||||
torrent::log_open_gz_file_output(output_id.c_str(), file_name.c_str());
|
||||
else
|
||||
torrent::log_open_file_output(output_id.c_str(), file_name.c_str());
|
||||
|
||||
while (itr != args.end())
|
||||
log_add_group_output_str((itr++)->as_string().c_str(), output_id.c_str());
|
||||
|
||||
return torrent::Object();
|
||||
}
|
||||
|
||||
torrent::Object
|
||||
apply_log_add_output(const torrent::Object::list_type& args) {
|
||||
if (args.size() != 2)
|
||||
throw torrent::input_error("Invalid number of arguments.");
|
||||
|
||||
log_add_group_output_str(args.front().as_string().c_str(),
|
||||
args.back().as_string().c_str());
|
||||
|
||||
return torrent::Object();
|
||||
}
|
||||
|
||||
// TODO: Deprecated.
|
||||
torrent::Object
|
||||
apply_log(const torrent::Object::string_type& arg, int logType) {
|
||||
if (rpc::execFile.log_fd() != -1) {
|
||||
switch (logType) {
|
||||
case 0: ::close(rpc::execFile.log_fd()); rpc::execFile.set_log_fd(-1); break;
|
||||
case 1:
|
||||
// if (control->scgi()) {
|
||||
// ::close(control->scgi()->log_fd());
|
||||
// control->scgi()->set_log_fd(-1);
|
||||
// }
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!arg.empty()) {
|
||||
int logFd = open(rak::path_expand(arg).c_str(), O_WRONLY | O_APPEND | O_CREAT, 0644);
|
||||
|
||||
if (logFd < 0)
|
||||
throw torrent::input_error("Could not open execute log file.");
|
||||
|
||||
switch (logType) {
|
||||
case 0: rpc::execFile.set_log_fd(logFd); break;
|
||||
// case 1: if (control->scgi()) control->scgi()->set_log_fd(logFd); break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
control->core()->push_log("Opened log file.");
|
||||
|
||||
} else {
|
||||
control->core()->push_log("Closed log file.");
|
||||
}
|
||||
|
||||
return torrent::Object();
|
||||
}
|
||||
|
||||
torrent::Object
|
||||
log_vmmap_dump(const std::string& str) {
|
||||
core::DownloadList* d_list = control->core()->download_list();
|
||||
std::vector<torrent::vm_mapping> all_mappings;
|
||||
|
||||
for (core::DownloadList::iterator itr = d_list->begin(), last = d_list->end(); itr != last; itr++) {
|
||||
std::vector<torrent::vm_mapping> tmp_mappings = torrent::chunk_list_mapping((*itr)->download());
|
||||
|
||||
all_mappings.insert(all_mappings.end(), tmp_mappings.begin(), tmp_mappings.end());
|
||||
}
|
||||
|
||||
FILE* log_file = fopen(str.c_str(), "w");
|
||||
|
||||
for (std::vector<torrent::vm_mapping>::iterator itr = all_mappings.begin(), last = all_mappings.end(); itr != last; itr++) {
|
||||
fprintf(log_file, "%8p-%8p [%5llxk]\n", itr->ptr, (char*)itr->ptr + itr->length, (long long unsigned int)(itr->length / 1024));
|
||||
}
|
||||
|
||||
fclose(log_file);
|
||||
return torrent::Object();
|
||||
}
|
||||
|
||||
void
|
||||
initialize_command_logging() {
|
||||
CMD2_ANY_LIST ("log.open_file", tr1::bind(&apply_log_open, 0, tr1::placeholders::_2));
|
||||
CMD2_ANY_LIST ("log.open_gz_file", tr1::bind(&apply_log_open, log_flag_use_gz, tr1::placeholders::_2));
|
||||
CMD2_ANY_LIST ("log.open_file_pid", tr1::bind(&apply_log_open, log_flag_append_pid, tr1::placeholders::_2));
|
||||
CMD2_ANY_LIST ("log.open_gz_file_pid", tr1::bind(&apply_log_open, log_flag_append_pid | log_flag_use_gz, tr1::placeholders::_2));
|
||||
|
||||
CMD2_ANY_LIST ("log.add_output", tr1::bind(&apply_log_add_output, tr1::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));
|
||||
}
|
||||
@@ -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.");
|
||||
@@ -239,8 +241,6 @@ initialize_command_network() {
|
||||
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", tr1::bind(&apply_encoding_list, tr1::placeholders::_2));
|
||||
CMD2_ANY_STRING ("encoding.add", tr1::bind(&apply_encoding_list, tr1::placeholders::_2));
|
||||
|
||||
@@ -249,7 +249,9 @@ initialize_command_network() {
|
||||
CMD2_VAR_BOOL ("network.port_random", true);
|
||||
CMD2_VAR_STRING ("network.port_range", "6881-6999");
|
||||
|
||||
CMD2_ANY ("network.listen.port", tr1::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", tr1::bind(&apply_encryption, tr1::placeholders::_2));
|
||||
|
||||
+23
-4
@@ -162,6 +162,15 @@ 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", tr1::bind(&torrent::ResourceManager::currently_upload_unchoked, torrent::resource_manager()));
|
||||
@@ -177,10 +186,20 @@ 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", tr1::bind(&torrent::Rate::rate, torrent::up_rate()));
|
||||
|
||||
+12
-1
@@ -113,10 +113,16 @@ void
|
||||
initialize_command_tracker() {
|
||||
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_VALUE_V("t.is_enabled.set", tr1::bind(&tracker_set_enabled, tr1::placeholders::_1, tr1::placeholders::_2));
|
||||
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_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_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));
|
||||
@@ -131,9 +137,14 @@ initialize_command_tracker() {
|
||||
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.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.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.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));
|
||||
|
||||
|
||||
+7
-30
@@ -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);
|
||||
@@ -546,12 +523,12 @@ initialize_command_ui() {
|
||||
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", tr1::bind(&apply_view_cfilter, &core::ViewManager::set_filter, tr1::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", tr1::bind(&apply_view_sort, tr1::placeholders::_2));
|
||||
CMD2_ANY_LIST("view.sort_new", tr1::bind(&apply_view_cfilter, &core::ViewManager::set_sort_new, tr1::placeholders::_2));
|
||||
CMD2_ANY_LIST("view.sort_current", tr1::bind(&apply_view_cfilter, &core::ViewManager::set_sort_current, 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", 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));
|
||||
|
||||
+12
-2
@@ -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,7 +76,7 @@ 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.slot() = std::tr1::bind(&Control::handle_shutdown, this);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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; }
|
||||
|
||||
@@ -30,4 +30,4 @@ libsub_core_a_SOURCES = \
|
||||
view_manager.cc \
|
||||
view_manager.h
|
||||
|
||||
INCLUDES = -I$(srcdir) -I$(srcdir)/.. -I$(top_srcdir)
|
||||
AM_CPPFLAGS = -I$(srcdir) -I$(srcdir)/.. -I$(top_srcdir)
|
||||
|
||||
@@ -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"
|
||||
|
||||
+28
-14
@@ -38,7 +38,6 @@
|
||||
|
||||
#include <algorithm>
|
||||
#include <curl/multi.h>
|
||||
#include <sigc++/adaptors/bind.h>
|
||||
#include <torrent/exceptions.h>
|
||||
|
||||
#include "rak/functional.h"
|
||||
@@ -92,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);
|
||||
@@ -123,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)));
|
||||
|
||||
@@ -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;
|
||||
|
||||
+3
-23
@@ -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())
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
#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>
|
||||
@@ -109,11 +110,11 @@ DownloadFactory::DownloadFactory(Manager* m) :
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -215,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;
|
||||
}
|
||||
|
||||
@@ -254,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"))
|
||||
@@ -303,7 +304,7 @@ DownloadFactory::receive_success() {
|
||||
// ATM doesn't really ever get here.
|
||||
delete download;
|
||||
|
||||
m_slotFinished();
|
||||
m_slot_finished();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -311,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)));
|
||||
|
||||
@@ -337,7 +341,33 @@ 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
|
||||
@@ -346,7 +376,7 @@ DownloadFactory::receive_failed(const std::string& msg) {
|
||||
if (m_printLog)
|
||||
m_manager->push_log_std(msg + ": \"" + m_uri + "\"");
|
||||
|
||||
m_slotFinished();
|
||||
m_slot_finished();
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
+22
-23
@@ -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>
|
||||
@@ -373,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));
|
||||
@@ -462,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.
|
||||
@@ -625,13 +624,13 @@ DownloadList::confirm_finished(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));
|
||||
@@ -641,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.
|
||||
|
||||
@@ -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
-14
@@ -38,8 +38,6 @@
|
||||
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
#include <sigc++/adaptors/bind.h>
|
||||
#include <sigc++/adaptors/hide.h>
|
||||
#include <torrent/http.h>
|
||||
|
||||
#include "rak/functional.h"
|
||||
@@ -50,31 +48,34 @@ 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::tr1::bind(&HttpQueue::erase, this, itr));
|
||||
h->signal_failed().push_back(std::tr1::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
|
||||
@@ -82,7 +83,7 @@ HttpQueue::clear() {
|
||||
while (!empty())
|
||||
erase(begin());
|
||||
|
||||
Base::clear();
|
||||
base_type::clear();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+21
-20
@@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
+6
-69
@@ -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>
|
||||
@@ -76,65 +74,6 @@
|
||||
|
||||
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:
|
||||
push_log_complete("Incoming connection from " + peer + download);
|
||||
break;
|
||||
case torrent::ConnectionManager::handshake_outgoing:
|
||||
push_log_complete("Outgoing connection to " + peer + download);
|
||||
break;
|
||||
case torrent::ConnectionManager::handshake_outgoing_encrypted:
|
||||
push_log_complete("Outgoing encrypted connection to " + peer + download);
|
||||
break;
|
||||
case torrent::ConnectionManager::handshake_outgoing_proxy:
|
||||
push_log_complete("Outgoing proxy connection to " + peer + download);
|
||||
break;
|
||||
case torrent::ConnectionManager::handshake_success:
|
||||
push_log_complete("Successful handshake: " + peer + download);
|
||||
break;
|
||||
case torrent::ConnectionManager::handshake_dropped:
|
||||
push_log_complete("Dropped handshake: " + peer + " - " + torrent::strerror(err) + download);
|
||||
break;
|
||||
case torrent::ConnectionManager::handshake_failed:
|
||||
push_log_complete("Handshake failed: " + peer + " - " + torrent::strerror(err) + download);
|
||||
break;
|
||||
case torrent::ConnectionManager::handshake_retry_plaintext:
|
||||
push_log_complete("Trying again without encryption: " + peer + download);
|
||||
break;
|
||||
case torrent::ConnectionManager::handshake_retry_encrypted:
|
||||
push_log_complete("Trying again encrypted: " + peer + download);
|
||||
break;
|
||||
default:
|
||||
push_log_complete("Unknown handshake message for " + peer + download);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Manager::push_log(const char* msg) {
|
||||
m_log_important->lock_and_push_log(msg, strlen(msg), 0);
|
||||
@@ -174,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
|
||||
@@ -194,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,11 +145,9 @@ Manager::get_address_throttle(const sockaddr* addr) {
|
||||
void
|
||||
Manager::initialize_second() {
|
||||
torrent::Http::slot_factory() = std::tr1::bind(&CurlStack::new_object, m_httpStack);
|
||||
m_httpQueue->slot_factory(sigc::mem_fun(m_httpStack, &CurlStack::new_object));
|
||||
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
|
||||
@@ -246,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)
|
||||
@@ -393,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);
|
||||
@@ -417,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.
|
||||
|
||||
+2
-2
@@ -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();
|
||||
|
||||
+19
-12
@@ -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.slot() = std::tr1::bind(&signal_type::operator(), &m_signalChanged);
|
||||
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
-13
@@ -52,8 +52,8 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <rak/timer.h>
|
||||
#include <sigc++/signal.h>
|
||||
#include <torrent/object.h>
|
||||
#include <tr1/functional>
|
||||
|
||||
#include "globals.h"
|
||||
|
||||
@@ -63,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;
|
||||
@@ -101,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);
|
||||
@@ -127,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
|
||||
@@ -143,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&);
|
||||
@@ -154,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(); }
|
||||
|
||||
@@ -171,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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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); }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
@@ -83,7 +84,7 @@ WindowDownloadStatusbar::redraw() {
|
||||
(int)m_download->download()->peers_accounted(),
|
||||
(int)m_download->info()->upload_unchoked(),
|
||||
(int)m_download->info()->download_unchoked(),
|
||||
(int)m_download->chunks_failed());
|
||||
(int)m_download->download()->transfer_list()->failed_count());
|
||||
|
||||
m_canvas->print(0, 1, "%s", buffer);
|
||||
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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
-1
@@ -43,4 +43,4 @@ rak::timer cachedTime;
|
||||
rpc::ip_table_list ip_tables;
|
||||
|
||||
Control* control = NULL;
|
||||
ThreadWorker* worker_thread = NULL;
|
||||
ThreadWorker* worker_thread = NULL;
|
||||
|
||||
@@ -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)
|
||||
|
||||
+16
-16
@@ -38,31 +38,31 @@
|
||||
#define RTORRENT_INPUT_BINDINGS_H
|
||||
|
||||
#include <map>
|
||||
#include <sigc++/functors/slot.h>
|
||||
#include <tr1/functional>
|
||||
|
||||
#include "display/attributes.h"
|
||||
|
||||
namespace input {
|
||||
|
||||
class Bindings : private std::map<int, sigc::slot0<void> > {
|
||||
class Bindings : private std::map<int, std::tr1::function<void ()> > {
|
||||
public:
|
||||
typedef sigc::slot0<void> Slot;
|
||||
typedef std::map<int, Slot > Base;
|
||||
typedef std::tr1::function<void ()> slot_void;
|
||||
typedef std::map<int, slot_void> base_type;
|
||||
|
||||
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::find;
|
||||
using base_type::begin;
|
||||
using base_type::end;
|
||||
using base_type::rbegin;
|
||||
using base_type::rend;
|
||||
using base_type::find;
|
||||
|
||||
using Base::erase;
|
||||
using base_type::erase;
|
||||
|
||||
using Base::operator[];
|
||||
using base_type::operator[];
|
||||
|
||||
Bindings() : m_enabled(true) {}
|
||||
|
||||
@@ -71,7 +71,7 @@ public:
|
||||
|
||||
bool pressed(int key);
|
||||
|
||||
void ignore(int key) { (*this)[key] = Slot(); }
|
||||
void ignore(int key) { (*this)[key] = slot_void(); }
|
||||
|
||||
private:
|
||||
bool m_enabled;
|
||||
|
||||
@@ -37,15 +37,15 @@
|
||||
#ifndef RTORRENT_INPUT_INPUT_EVENT_H
|
||||
#define RTORRENT_INPUT_INPUT_EVENT_H
|
||||
|
||||
#include <sigc++/functors/slot.h>
|
||||
#include <torrent/event.h>
|
||||
#include <torrent/poll.h>
|
||||
#include <tr1/functional>
|
||||
|
||||
namespace input {
|
||||
|
||||
class InputEvent : public torrent::Event {
|
||||
public:
|
||||
typedef sigc::slot<void, int> SlotInt;
|
||||
typedef std::tr1::function<void (int)> slot_int;
|
||||
|
||||
InputEvent(int fd) { m_fileDesc = fd; }
|
||||
|
||||
@@ -56,10 +56,10 @@ public:
|
||||
void event_write();
|
||||
void event_error();
|
||||
|
||||
void slot_pressed(SlotInt s) { m_slotPressed = s; }
|
||||
void slot_pressed(slot_int s) { m_slotPressed = s; }
|
||||
|
||||
private:
|
||||
SlotInt m_slotPressed;
|
||||
slot_int m_slotPressed;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
+16
-17
@@ -41,14 +41,10 @@
|
||||
#include <rak/functional.h>
|
||||
#include <rak/path.h>
|
||||
|
||||
#include <dirent.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#ifdef __sun__
|
||||
#include <dirent.h>
|
||||
#include <sys/stat.h>
|
||||
#else
|
||||
#include <sys/dir.h>
|
||||
#endif
|
||||
#include <torrent/utils/log.h>
|
||||
|
||||
#include "path_input.h"
|
||||
|
||||
@@ -67,7 +63,8 @@ PathInput::pressed(int key) {
|
||||
return TextInput::pressed(key);
|
||||
|
||||
} else if (m_showNext) {
|
||||
m_signalShowNext.emit();
|
||||
for (signal_void::iterator itr = m_signal_show_next.begin(), last = m_signal_show_next.end(); itr != last; itr++)
|
||||
(*itr)();
|
||||
|
||||
} else {
|
||||
receive_do_complete();
|
||||
@@ -78,17 +75,15 @@ PathInput::pressed(int key) {
|
||||
|
||||
struct _transform_filename {
|
||||
void operator () (utils::directory_entry& entry) {
|
||||
#ifdef __sun__
|
||||
if (entry.d_type & S_IFDIR)
|
||||
#else
|
||||
if (entry.d_type == DT_DIR)
|
||||
#endif
|
||||
entry.d_name += '/';
|
||||
}
|
||||
};
|
||||
|
||||
void
|
||||
PathInput::receive_do_complete() {
|
||||
lt_log_print(torrent::LOG_UI_EVENTS, "path_input: received completion");
|
||||
|
||||
size_type dirEnd = find_last_delim();
|
||||
|
||||
utils::Directory dir(dirEnd != 0 ? str().substr(0, dirEnd) : "./");
|
||||
@@ -101,7 +96,7 @@ PathInput::receive_do_complete() {
|
||||
|
||||
std::for_each(dir.begin(), dir.end(), _transform_filename());
|
||||
|
||||
Range r = find_incomplete(dir, str().substr(dirEnd, get_pos()));
|
||||
range_type r = find_incomplete(dir, str().substr(dirEnd, get_pos()));
|
||||
|
||||
if (r.first == r.second)
|
||||
return; // Show some nice colors here.
|
||||
@@ -121,8 +116,12 @@ PathInput::receive_do_complete() {
|
||||
// Only emit if there are more than one option.
|
||||
m_showNext = ++utils::Directory::iterator(r.first) != r.second;
|
||||
|
||||
if (m_showNext)
|
||||
m_signalShowRange.emit(r.first, r.second);
|
||||
if (m_showNext) {
|
||||
lt_log_print(torrent::LOG_UI_EVENTS, "path_input: show next page");
|
||||
|
||||
for (signal_itr_itr::iterator itr = m_signal_show_range.begin(), last = m_signal_show_range.end(); itr != last; itr++)
|
||||
(*itr)(r.first, r.second);
|
||||
}
|
||||
}
|
||||
|
||||
PathInput::size_type
|
||||
@@ -147,9 +146,9 @@ find_complete_not_compare(const utils::directory_entry& complete, const std::str
|
||||
return !complete.d_name.compare(0, base.size(), base);
|
||||
}
|
||||
|
||||
PathInput::Range
|
||||
PathInput::range_type
|
||||
PathInput::find_incomplete(utils::Directory& d, const std::string& f) {
|
||||
Range r;
|
||||
range_type r;
|
||||
|
||||
r.first = std::find_if(d.begin(), d.end(), rak::bind2nd(std::ptr_fun(&find_complete_not_compare), f));
|
||||
r.second = std::find_if(r.first, d.end(), rak::bind2nd(std::ptr_fun(&find_complete_compare), f));
|
||||
|
||||
+14
-9
@@ -37,7 +37,8 @@
|
||||
#ifndef RTORRENT_INPUT_PATH_INPUT_H
|
||||
#define RTORRENT_INPUT_PATH_INPUT_H
|
||||
|
||||
#include <sigc++/signal.h>
|
||||
#include <list>
|
||||
#include <tr1/functional>
|
||||
|
||||
#include "utils/directory.h"
|
||||
#include "text_input.h"
|
||||
@@ -46,15 +47,19 @@ namespace input {
|
||||
|
||||
class PathInput : public TextInput {
|
||||
public:
|
||||
typedef std::pair<utils::Directory::iterator, utils::Directory::iterator> Range;
|
||||
typedef sigc::signal0<void> Signal;
|
||||
typedef sigc::signal2<void, utils::Directory::iterator, utils::Directory::iterator> SignalShowRange;
|
||||
typedef utils::Directory::iterator directory_itr;
|
||||
typedef std::pair<directory_itr, directory_itr> range_type;
|
||||
|
||||
typedef std::tr1::function<void ()> slot_void;
|
||||
typedef std::tr1::function<void (directory_itr, directory_itr)> slot_itr_itr;
|
||||
typedef std::list<slot_void> signal_void;
|
||||
typedef std::list<slot_itr_itr> signal_itr_itr;
|
||||
|
||||
PathInput();
|
||||
virtual ~PathInput() {}
|
||||
|
||||
Signal& signal_show_next() { return m_signalShowNext; }
|
||||
SignalShowRange& signal_show_range() { return m_signalShowRange; }
|
||||
signal_void& signal_show_next() { return m_signal_show_next; }
|
||||
signal_itr_itr& signal_show_range() { return m_signal_show_range; }
|
||||
|
||||
virtual bool pressed(int key);
|
||||
|
||||
@@ -62,12 +67,12 @@ private:
|
||||
void receive_do_complete();
|
||||
|
||||
size_type find_last_delim();
|
||||
Range find_incomplete(utils::Directory& d, const std::string& f);
|
||||
range_type find_incomplete(utils::Directory& d, const std::string& f);
|
||||
|
||||
bool m_showNext;
|
||||
|
||||
Signal m_signalShowNext;
|
||||
SignalShowRange m_signalShowRange;
|
||||
signal_void m_signal_show_next;
|
||||
signal_itr_itr m_signal_show_range;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -123,7 +123,7 @@ TextInput::pressed(int key) {
|
||||
}
|
||||
}
|
||||
|
||||
m_slotDirty();
|
||||
mark_dirty();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -45,8 +45,8 @@ namespace input {
|
||||
|
||||
class TextInput : private std::string {
|
||||
public:
|
||||
typedef std::string Base;
|
||||
typedef sigc::slot0<void> SlotDirty;
|
||||
typedef std::string Base;
|
||||
typedef std::tr1::function<void ()> slot_void;
|
||||
|
||||
using Base::c_str;
|
||||
using Base::empty;
|
||||
@@ -64,8 +64,8 @@ public:
|
||||
|
||||
void clear() { m_pos = 0; m_alt = false; Base::clear(); }
|
||||
|
||||
void slot_dirty(SlotDirty s) { m_slotDirty = s; }
|
||||
void mark_dirty() { m_slotDirty(); }
|
||||
void slot_dirty(slot_void s) { m_slot_dirty = s; }
|
||||
void mark_dirty() { if (m_slot_dirty) m_slot_dirty(); }
|
||||
|
||||
std::string& str() { return *this; }
|
||||
|
||||
@@ -75,7 +75,7 @@ private:
|
||||
size_type m_pos;
|
||||
|
||||
bool m_alt;
|
||||
SlotDirty m_slotDirty;
|
||||
slot_void m_slot_dirty;
|
||||
|
||||
Bindings m_bindings;
|
||||
};
|
||||
|
||||
+88
-93
@@ -40,9 +40,10 @@
|
||||
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <inttypes.h>
|
||||
#include <sigc++/adaptors/bind.h>
|
||||
#include <unistd.h>
|
||||
#include <torrent/http.h>
|
||||
#include <torrent/torrent.h>
|
||||
#include <torrent/exceptions.h>
|
||||
@@ -85,6 +86,7 @@ void print_help();
|
||||
void initialize_commands();
|
||||
|
||||
void do_nothing() {}
|
||||
void do_nothing_str(const std::string&) {}
|
||||
|
||||
int
|
||||
parse_options(Control* c, int argc, char** argv) {
|
||||
@@ -92,20 +94,20 @@ parse_options(Control* c, int argc, char** argv) {
|
||||
OptionParser optionParser;
|
||||
|
||||
// Converted.
|
||||
optionParser.insert_flag('h', sigc::ptr_fun(&print_help));
|
||||
optionParser.insert_flag('n', OptionParser::Slot());
|
||||
optionParser.insert_flag('D', OptionParser::Slot());
|
||||
optionParser.insert_flag('I', OptionParser::Slot());
|
||||
optionParser.insert_flag('K', OptionParser::Slot());
|
||||
optionParser.insert_flag('h', std::tr1::bind(&print_help));
|
||||
optionParser.insert_flag('n', std::tr1::bind(&do_nothing_str, std::tr1::placeholders::_1));
|
||||
optionParser.insert_flag('D', std::tr1::bind(&do_nothing_str, std::tr1::placeholders::_1));
|
||||
optionParser.insert_flag('I', std::tr1::bind(&do_nothing_str, std::tr1::placeholders::_1));
|
||||
optionParser.insert_flag('K', std::tr1::bind(&do_nothing_str, std::tr1::placeholders::_1));
|
||||
|
||||
optionParser.insert_option('b', sigc::bind<0>(sigc::ptr_fun(&rpc::call_command_set_string), "network.bind_address.set"));
|
||||
optionParser.insert_option('d', sigc::bind<0>(sigc::ptr_fun(&rpc::call_command_set_string), "directory.default.set"));
|
||||
optionParser.insert_option('i', sigc::bind<0>(sigc::ptr_fun(&rpc::call_command_set_string), "ip"));
|
||||
optionParser.insert_option('p', sigc::bind<0>(sigc::ptr_fun(&rpc::call_command_set_string), "network.port_range.set"));
|
||||
optionParser.insert_option('s', sigc::bind<0>(sigc::ptr_fun(&rpc::call_command_set_string), "session"));
|
||||
optionParser.insert_option('b', std::tr1::bind(&rpc::call_command_set_string, "network.bind_address.set", std::tr1::placeholders::_1));
|
||||
optionParser.insert_option('d', std::tr1::bind(&rpc::call_command_set_string, "directory.default.set", std::tr1::placeholders::_1));
|
||||
optionParser.insert_option('i', std::tr1::bind(&rpc::call_command_set_string, "ip", std::tr1::placeholders::_1));
|
||||
optionParser.insert_option('p', std::tr1::bind(&rpc::call_command_set_string, "network.port_range.set", std::tr1::placeholders::_1));
|
||||
optionParser.insert_option('s', std::tr1::bind(&rpc::call_command_set_string, "session", std::tr1::placeholders::_1));
|
||||
|
||||
optionParser.insert_option('O', sigc::ptr_fun(&rpc::parse_command_single_std));
|
||||
optionParser.insert_option_list('o', sigc::ptr_fun(&rpc::call_command_set_std_string));
|
||||
optionParser.insert_option('O', std::tr1::bind(&rpc::parse_command_single_std, std::tr1::placeholders::_1));
|
||||
optionParser.insert_option_list('o', std::tr1::bind(&rpc::call_command_set_std_string, std::tr1::placeholders::_1, std::tr1::placeholders::_2));
|
||||
|
||||
return optionParser.process(argc, argv);
|
||||
|
||||
@@ -129,7 +131,7 @@ load_session_torrents(Control* c) {
|
||||
|
||||
// Replace with session torrent flag.
|
||||
f->set_session(true);
|
||||
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));
|
||||
f->load(entries.path() + first->d_name);
|
||||
f->commit();
|
||||
}
|
||||
@@ -143,7 +145,7 @@ load_arg_torrents(Control* c, char** first, char** last) {
|
||||
|
||||
// Replace with session torrent flag.
|
||||
f->set_start(true);
|
||||
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));
|
||||
f->load(*first);
|
||||
f->commit();
|
||||
}
|
||||
@@ -188,22 +190,28 @@ main(int argc, char** argv) {
|
||||
|
||||
control = new Control;
|
||||
|
||||
srandom(cachedTime.usec());
|
||||
srand48(cachedTime.usec());
|
||||
srandom(cachedTime.usec() ^ (getpid() << 16) ^ getppid());
|
||||
srand48(cachedTime.usec() ^ (getpid() << 16) ^ getppid());
|
||||
|
||||
SignalHandler::set_ignore(SIGPIPE);
|
||||
SignalHandler::set_handler(SIGINT, sigc::mem_fun(control, &Control::receive_normal_shutdown));
|
||||
SignalHandler::set_handler(SIGTERM, sigc::mem_fun(control, &Control::receive_quick_shutdown));
|
||||
SignalHandler::set_handler(SIGWINCH, sigc::mem_fun(control->display(), &display::Manager::force_redraw));
|
||||
SignalHandler::set_handler(SIGSEGV, sigc::bind(sigc::ptr_fun(&do_panic), SIGSEGV));
|
||||
SignalHandler::set_handler(SIGILL, sigc::bind(sigc::ptr_fun(&do_panic), SIGILL));
|
||||
SignalHandler::set_handler(SIGFPE, sigc::bind(sigc::ptr_fun(&do_panic), SIGFPE));
|
||||
SignalHandler::set_handler(SIGINT, std::tr1::bind(&Control::receive_normal_shutdown, control));
|
||||
SignalHandler::set_handler(SIGTERM, std::tr1::bind(&Control::receive_quick_shutdown, control));
|
||||
SignalHandler::set_handler(SIGWINCH, std::tr1::bind(&display::Manager::force_redraw, control->display()));
|
||||
SignalHandler::set_handler(SIGSEGV, std::tr1::bind(&do_panic, SIGSEGV));
|
||||
SignalHandler::set_handler(SIGILL, std::tr1::bind(&do_panic, SIGILL));
|
||||
SignalHandler::set_handler(SIGFPE, std::tr1::bind(&do_panic, SIGFPE));
|
||||
|
||||
SignalHandler::set_sigaction_handler(SIGBUS, &handle_sigbus);
|
||||
|
||||
// SIGUSR1 is used for interrupting polling, forcing that thread
|
||||
// to process new non-socket events.
|
||||
SignalHandler::set_handler(SIGUSR1, sigc::ptr_fun(&do_nothing));
|
||||
// SIGUSR1 is used for interrupting polling, forcing the target
|
||||
// thread to process new non-socket events.
|
||||
//
|
||||
// LibTorrent uses sockets for this purpose on Solaris and other
|
||||
// platforms that do not properly pass signals to the target
|
||||
// threads. Use '--enable-interrupt-socket' when configuring
|
||||
// LibTorrent to enable this workaround.
|
||||
if (torrent::thread_base::should_handle_sigusr1())
|
||||
SignalHandler::set_handler(SIGUSR1, std::tr1::bind(&do_nothing));
|
||||
|
||||
torrent::log_add_group_output(torrent::LOG_NOTICE, "important");
|
||||
torrent::log_add_group_output(torrent::LOG_INFO, "complete");
|
||||
@@ -238,15 +246,6 @@ main(int argc, char** argv) {
|
||||
|
||||
rpc::parse_command_multiple
|
||||
(rpc::make_target(),
|
||||
// "method.insert = test.value,value\n"
|
||||
// "method.insert = test.value2,value,6\n"
|
||||
|
||||
// "method.insert = test.string,string,6\n"
|
||||
// "method.insert = test.bool,bool,true\n"
|
||||
|
||||
// "method.insert.simple = test.method.simple,((print,simple_test_,$argument.0=))\n"
|
||||
// "method.insert.simple = test.method.double,((print,simple_test_,$argument.0=)),\"print=simple_test_,$argument.1=\"\n"
|
||||
|
||||
"method.insert = event.download.inserted,multi|rlookup|static\n"
|
||||
"method.insert = event.download.inserted_new,multi|rlookup|static\n"
|
||||
"method.insert = event.download.inserted_session,multi|rlookup|static\n"
|
||||
@@ -263,10 +262,9 @@ main(int argc, char** argv) {
|
||||
"method.insert = event.download.hash_removed,multi|rlookup|static\n"
|
||||
"method.insert = event.download.hash_queued,multi|rlookup|static\n"
|
||||
|
||||
"method.set_key = event.download.inserted, 1_connect_logs, ((d.initialize_logs))\n"
|
||||
"method.set_key = event.download.inserted, 1_send_scrape, ((d.tracker.send_scrape,30))\n"
|
||||
"method.set_key = event.download.inserted_new, 1_prepare, \"branch=d.state=,view.set_visible=started,view.set_visible=stopped ;d.save_full_session=\"\n"
|
||||
"method.set_key = event.download.inserted_session, 1_prepare, \"branch=d.state=,view.set_visible=started,view.set_visible=stopped\"\n"
|
||||
"method.set_key = event.download.inserted_new, 1_prepare, {(branch,((d.state)),((view.set_visible,started)),((view.set_visible,stopped)) ),(d.save_full_session)}\n"
|
||||
"method.set_key = event.download.inserted_session, 1_prepare, {(branch,((d.state)),((view.set_visible,started)),((view.set_visible,stopped)) )}\n"
|
||||
|
||||
"method.set_key = event.download.inserted, 1_prioritize_toc, \"branch=file.prioritize_toc=,{\\\"f.multicall=(file.prioritize_toc.first),f.prioritize_first.enable=\\\",\\\"f.multicall=(file.prioritize_toc.last),f.prioritize_last.enable=\\\",d.update_priorities=}\"\n"
|
||||
|
||||
@@ -292,7 +290,7 @@ main(int argc, char** argv) {
|
||||
|
||||
"group.insert = seeding,seeding\n"
|
||||
|
||||
"session.name.set = \"$cat=$system.hostname=,:,$system.pid=\"\n"
|
||||
"session.name.set = (cat,(system.hostname),:,(system.pid))\n"
|
||||
|
||||
// Currently not doing any sorting on main.
|
||||
"view.add = main\n"
|
||||
@@ -307,46 +305,36 @@ main(int argc, char** argv) {
|
||||
|
||||
"view.add = started\n"
|
||||
"view.filter = started,((false))\n"
|
||||
"view.event_added = started,\"view.set_not_visible=stopped ;d.state.set=1 ;scheduler.simple.added=\"\n"
|
||||
"view.event_removed = started,\"view.set_visible=stopped ;scheduler.simple.removed=\"\n"
|
||||
"view.event_added = started,{(view.set_not_visible,stopped),(d.state.set,1),(scheduler.simple.added)}\n"
|
||||
"view.event_removed = started,{(view.set_visible,stopped),(scheduler.simple.removed)}\n"
|
||||
|
||||
"view.add = stopped\n"
|
||||
"view.filter = stopped,((false))\n"
|
||||
"view.event_added = stopped,\"d.state.set=0 ;view.set_not_visible=started\"\n"
|
||||
"view.event_removed = stopped,view.set_visible=started\n"
|
||||
"view.event_added = stopped,{(d.state.set,0),(view.set_not_visible,started)}\n"
|
||||
"view.event_removed = stopped,((view.set_visible,started))\n"
|
||||
|
||||
"view.add = complete\n"
|
||||
"view.filter = complete,((d.complete))\n"
|
||||
"view.filter_on = complete,event.download.hash_done,event.download.hash_failed,event.download.hash_final_failed,event.download.finished\n"
|
||||
// "view.sort_new = complete,((less,((d.state_changed))))\n"
|
||||
// "view.sort_current = complete,((less,((d.state_changed))))\n"
|
||||
|
||||
"view.add = incomplete\n"
|
||||
"view.filter = incomplete,((not,((d.complete))))\n"
|
||||
"view.filter_on = incomplete,event.download.hash_done,event.download.hash_failed,"
|
||||
"event.download.hash_final_failed,event.download.finished\n"
|
||||
// "view.sort_new = incomplete,((less,((d.state_changed))))\n"
|
||||
// "view.sort_current = incomplete,((less,((d.state_changed))))\n"
|
||||
|
||||
// The hashing view does not include stopped torrents.
|
||||
"view.add = hashing\n"
|
||||
"view.filter = hashing,((d.hashing))\n"
|
||||
"view.filter_on = hashing,event.download.hash_queued,event.download.hash_removed,"
|
||||
"event.download.hash_done,event.download.hash_failed,event.download.hash_final_failed,event.download.finished\n"
|
||||
// "view.sort_new = hashing,less=d.state_changed=\n"
|
||||
// "view.sort_current = hashing,less=d.state_changed=\n"
|
||||
|
||||
"view.add = seeding\n"
|
||||
"view.filter = seeding,((and,((d.state)),((d.complete))))\n"
|
||||
"view.filter_on = seeding,event.download.resumed,event.download.paused,event.download.finished\n"
|
||||
// "view.sort_new = seeding,((less,((d.state_changed))))\n"
|
||||
// "view.sort_current = seeding,((less,((d.state_changed))))\n"
|
||||
"view.filter_on = seeding,event.download.resumed,event.download.paused,event.download.finished\n"
|
||||
|
||||
"view.add = leeching\n"
|
||||
"view.filter = leeching,((and,((d.state)),((not,((d.complete))))))\n"
|
||||
"view.filter_on = leeching,event.download.resumed,event.download.paused,event.download.finished\n"
|
||||
// "view.sort_new = leeching,((less,((d.state_changed))))\n"
|
||||
// "view.sort_current = leeching,((less,((d.state_changed))))\n"
|
||||
"view.filter_on = leeching,event.download.resumed,event.download.paused,event.download.finished\n"
|
||||
|
||||
"schedule2 = view.main,10,10,((view.sort,main,20))\n"
|
||||
"schedule2 = view.name,10,10,((view.sort,name,20))\n"
|
||||
@@ -447,9 +435,6 @@ main(int argc, char** argv) {
|
||||
|
||||
CMD2_REDIRECT ("session_save", "session.save");
|
||||
|
||||
CMD2_REDIRECT ("get_handshake_log", "log.handshake");
|
||||
CMD2_REDIRECT_GENERIC("set_handshake_log", "log.handshake.set");
|
||||
|
||||
CMD2_REDIRECT ("get_name", "session.name");
|
||||
CMD2_REDIRECT_GENERIC("set_name", "session.name.set");
|
||||
|
||||
@@ -874,10 +859,20 @@ main(int argc, char** argv) {
|
||||
control->core()->download_list()->session_save();
|
||||
control->cleanup();
|
||||
|
||||
} catch (torrent::internal_error& e) {
|
||||
control->cleanup_exception();
|
||||
|
||||
std::cout << "Caught internal_error: " << e.what() << std::endl
|
||||
<< e.backtrace();
|
||||
lt_log_print_dump(torrent::LOG_CRITICAL, e.backtrace().c_str(), e.backtrace().size(),
|
||||
"Caught internal_error: '%s'.", e.what());
|
||||
return -1;
|
||||
|
||||
} catch (std::exception& e) {
|
||||
control->cleanup_exception();
|
||||
|
||||
std::cout << "rtorrent: " << e.what() << std::endl;
|
||||
lt_log_print(torrent::LOG_CRITICAL, "Caught exception: '%s'.", e.what());
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -897,9 +892,8 @@ handle_sigbus(int signum, siginfo_t* sa, void* ptr) {
|
||||
SignalHandler::set_default(signum);
|
||||
display::Canvas::cleanup();
|
||||
|
||||
// Use printf here instead...
|
||||
|
||||
printf("Caught SIGBUS, dumping stack:\n");
|
||||
std::stringstream output;
|
||||
output << "Caught SIGBUS, dumping stack:" << std::endl;
|
||||
|
||||
#ifdef USE_EXECINFO
|
||||
void* stackPtrs[20];
|
||||
@@ -909,13 +903,12 @@ handle_sigbus(int signum, siginfo_t* sa, void* ptr) {
|
||||
char** stackStrings = backtrace_symbols(stackPtrs, stackSize);
|
||||
|
||||
for (int i = 0; i < stackSize; ++i)
|
||||
printf("%i %s\n", i, stackStrings[i]);
|
||||
output << stackStrings[i] << std::endl;
|
||||
|
||||
#else
|
||||
printf("Stack dump not enabled.\n");
|
||||
output << "Stack dump not enabled." << std::endl;
|
||||
#endif
|
||||
|
||||
printf("\nError: %s\n", rak::error_number(sa->si_errno).c_str());
|
||||
output << std::endl << "Error: " << rak::error_number(sa->si_errno).c_str() << std::endl;
|
||||
|
||||
const char* signal_reason;
|
||||
|
||||
@@ -932,23 +925,31 @@ handle_sigbus(int signum, siginfo_t* sa, void* ptr) {
|
||||
break;
|
||||
};
|
||||
|
||||
printf("Signal code '%i': %s\n", sa->si_code, signal_reason);
|
||||
printf("Fault address: %p.\n\n", sa->si_addr);
|
||||
output << "Signal code '" << sa->si_code << "': " << signal_reason << std::endl;
|
||||
output << "Fault address: " << sa->si_addr << std::endl;
|
||||
|
||||
// New code for finding the location of the SIGBUS signal, and using
|
||||
// that to figure out how to recover.
|
||||
torrent::chunk_info_result result = torrent::chunk_list_address_info(sa->si_addr);
|
||||
|
||||
if (!result.download.is_valid()) {
|
||||
printf("The fault address is not part of any chunk.\n");
|
||||
std::abort();
|
||||
output << "The fault address is not part of any chunk." << std::endl;
|
||||
goto handle_sigbus_exit;
|
||||
}
|
||||
|
||||
printf("Torrent name: '%s'.\n", result.download.info()->name().c_str());
|
||||
printf("File name: '%s'.\n", result.file_path);
|
||||
printf("File offset: %" PRIu64 ".\n", result.file_offset);
|
||||
printf("Chunk index: %u.\n", result.chunk_index);
|
||||
printf("Chunk offset: %u.\n", result.chunk_offset);
|
||||
output << "Torrent name: " << result.download.info()->name().c_str() << std::endl;
|
||||
output << "File name: " << result.file_path << std::endl;
|
||||
output << "File offset: " << result.file_offset << std::endl;
|
||||
output << "Chunk index: " << result.chunk_index << std::endl;
|
||||
output << "Chunk offset: " << result.chunk_offset << std::endl;
|
||||
|
||||
handle_sigbus_exit:
|
||||
std::cout << output.rdbuf();
|
||||
|
||||
if (lt_log_is_valid(torrent::LOG_CRITICAL)) {
|
||||
std::string dump = output.str();
|
||||
lt_log_print_dump(torrent::LOG_CRITICAL, dump.c_str(), dump.size(), "Caught signal: '%s'.", signal_reason);
|
||||
}
|
||||
|
||||
torrent::log_cleanup();
|
||||
std::abort();
|
||||
@@ -961,9 +962,9 @@ do_panic(int signum) {
|
||||
SignalHandler::set_default(signum);
|
||||
display::Canvas::cleanup();
|
||||
|
||||
// Use printf here instead...
|
||||
std::stringstream output;
|
||||
|
||||
std::cout << "Caught " << SignalHandler::as_string(signum) << ", dumping stack:" << std::endl;
|
||||
output << "Caught " << SignalHandler::as_string(signum) << ", dumping stack:" << std::endl;
|
||||
|
||||
#ifdef USE_EXECINFO
|
||||
void* stackPtrs[20];
|
||||
@@ -973,27 +974,21 @@ do_panic(int signum) {
|
||||
char** stackStrings = backtrace_symbols(stackPtrs, stackSize);
|
||||
|
||||
for (int i = 0; i < stackSize; ++i)
|
||||
std::cout << i << ' ' << stackStrings[i] << std::endl;
|
||||
output << stackStrings[i] << std::endl;
|
||||
|
||||
#else
|
||||
std::cout << "Stack dump not enabled." << std::endl;
|
||||
output << "Stack dump not enabled." << std::endl;
|
||||
#endif
|
||||
|
||||
// Dumping virtual memory map information to file:
|
||||
// char dump_path[256];
|
||||
// snprintf(dump_path, 256, "./rtorrent.map.%u", getpid());
|
||||
|
||||
// int dump_fd = open(dump_path, O_RDWR | O_CREAT);
|
||||
|
||||
// if (dump_fd == -1) {
|
||||
// printf("Could not create vmmap dump file '%s'.", dump_path);
|
||||
// goto do_panic_exit;
|
||||
// }
|
||||
|
||||
// do_panic_exit:
|
||||
|
||||
if (signum == SIGBUS)
|
||||
std::cout << "A bus error probably means you ran out of diskspace." << std::endl;
|
||||
output << "A bus error probably means you ran out of diskspace." << std::endl;
|
||||
|
||||
std::cout << output.rdbuf();
|
||||
|
||||
if (lt_log_is_valid(torrent::LOG_CRITICAL)) {
|
||||
std::string dump = output.str();
|
||||
lt_log_print_dump(torrent::LOG_CRITICAL, dump.c_str(), dump.size(), "Caught signal: '%s.", strsignal(signum));
|
||||
}
|
||||
|
||||
torrent::log_cleanup();
|
||||
std::abort();
|
||||
@@ -1038,7 +1033,7 @@ print_help() {
|
||||
std::cout << " o View trackers" << std::endl;
|
||||
std::cout << std::endl;
|
||||
|
||||
std::cout << "Report bugs to <jaris@ifi.uio.no>." << std::endl;
|
||||
std::cout << "Report bugs to <sundell.software@gmail.com>." << std::endl;
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
+9
-11
@@ -43,32 +43,30 @@
|
||||
#include <getopt.h>
|
||||
#include <stdexcept>
|
||||
#include <unistd.h>
|
||||
#include <sigc++/adaptors/bind.h>
|
||||
#include <sigc++/adaptors/hide.h>
|
||||
|
||||
#include "option_parser.h"
|
||||
|
||||
void
|
||||
OptionParser::insert_flag(char c, Slot s) {
|
||||
m_container[c].m_slot = sigc::hide(s);
|
||||
OptionParser::insert_flag(char c, slot_string s) {
|
||||
m_container[c].m_slot = s;
|
||||
m_container[c].m_useOption = false;
|
||||
}
|
||||
|
||||
void
|
||||
OptionParser::insert_option(char c, SlotString s) {
|
||||
OptionParser::insert_option(char c, slot_string s) {
|
||||
m_container[c].m_slot = s;
|
||||
m_container[c].m_useOption = true;
|
||||
}
|
||||
|
||||
void
|
||||
OptionParser::insert_option_list(char c, SlotStringPair s) {
|
||||
m_container[c].m_slot = sigc::bind<0>(sigc::ptr_fun(&OptionParser::call_option_list), s);
|
||||
OptionParser::insert_option_list(char c, slot_string_pair s) {
|
||||
m_container[c].m_slot = std::tr1::bind(&OptionParser::call_option_list, s, std::tr1::placeholders::_1);
|
||||
m_container[c].m_useOption = true;
|
||||
}
|
||||
|
||||
void
|
||||
OptionParser::insert_int_pair(char c, SlotIntPair s) {
|
||||
m_container[c].m_slot = sigc::bind<0>(sigc::ptr_fun(&OptionParser::call_int_pair), s);
|
||||
OptionParser::insert_int_pair(char c, slot_int_pair s) {
|
||||
m_container[c].m_slot = std::tr1::bind(&OptionParser::call_int_pair, s, std::tr1::placeholders::_1);
|
||||
m_container[c].m_useOption = true;
|
||||
}
|
||||
|
||||
@@ -118,7 +116,7 @@ OptionParser::call(char c, const std::string& arg) {
|
||||
}
|
||||
|
||||
void
|
||||
OptionParser::call_option_list(SlotStringPair slot, const std::string& arg) {
|
||||
OptionParser::call_option_list(slot_string_pair slot, const std::string& arg) {
|
||||
std::string::const_iterator itr = arg.begin();
|
||||
|
||||
while (itr != arg.end()) {
|
||||
@@ -138,7 +136,7 @@ OptionParser::call_option_list(SlotStringPair slot, const std::string& arg) {
|
||||
}
|
||||
|
||||
void
|
||||
OptionParser::call_int_pair(SlotIntPair slot, const std::string& arg) {
|
||||
OptionParser::call_int_pair(slot_int_pair slot, const std::string& arg) {
|
||||
int a, b;
|
||||
|
||||
if (std::sscanf(arg.c_str(), "%u-%u", &a, &b) != 2)
|
||||
|
||||
+11
-12
@@ -39,21 +39,20 @@
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <sigc++/functors/slot.h>
|
||||
#include <tr1/functional>
|
||||
|
||||
// Throws std::runtime_error upon receiving bad input.
|
||||
|
||||
class OptionParser {
|
||||
public:
|
||||
typedef sigc::slot0<void> Slot;
|
||||
typedef sigc::slot1<void, const std::string&> SlotString;
|
||||
typedef sigc::slot2<void, const std::string&, const std::string&> SlotStringPair;
|
||||
typedef sigc::slot2<void, int, int> SlotIntPair;
|
||||
typedef std::tr1::function<void (const std::string&)> slot_string;
|
||||
typedef std::tr1::function<void (const std::string&, const std::string&)> slot_string_pair;
|
||||
typedef std::tr1::function<void (int, int)> slot_int_pair;
|
||||
|
||||
void insert_flag(char c, Slot s);
|
||||
void insert_option(char c, SlotString s);
|
||||
void insert_option_list(char c, SlotStringPair s);
|
||||
void insert_int_pair(char c, SlotIntPair s);
|
||||
void insert_flag(char c, slot_string s);
|
||||
void insert_option(char c, slot_string s);
|
||||
void insert_option_list(char c, slot_string_pair s);
|
||||
void insert_int_pair(char c, slot_int_pair s);
|
||||
|
||||
// Returns the index of the first non-option argument.
|
||||
int process(int argc, char** argv);
|
||||
@@ -64,12 +63,12 @@ private:
|
||||
std::string create_optstring();
|
||||
|
||||
void call(char c, const std::string& arg);
|
||||
static void call_option_list(SlotStringPair slot, const std::string& arg);
|
||||
static void call_int_pair(SlotIntPair slot, const std::string& arg);
|
||||
static void call_option_list(slot_string_pair slot, const std::string& arg);
|
||||
static void call_int_pair(slot_int_pair slot, const std::string& arg);
|
||||
|
||||
// Use pair instead?
|
||||
struct Node {
|
||||
SlotString m_slot;
|
||||
slot_string m_slot;
|
||||
bool m_useOption;
|
||||
};
|
||||
|
||||
|
||||
+1
-1
@@ -27,4 +27,4 @@ libsub_rpc_a_SOURCES = \
|
||||
xmlrpc.h \
|
||||
xmlrpc.cc
|
||||
|
||||
INCLUDES = -I$(srcdir) -I$(srcdir)/.. -I$(top_srcdir)
|
||||
AM_CPPFLAGS = -I$(srcdir) -I$(srcdir)/.. -I$(top_srcdir)
|
||||
|
||||
@@ -97,24 +97,7 @@ CommandScheduler::call_item(value_type item) {
|
||||
// removed.
|
||||
|
||||
try {
|
||||
if (item->command().is_string()) {
|
||||
rpc::parse_command_multiple_std(item->command().as_string());
|
||||
|
||||
} else if (item->command().is_dict_key()) {
|
||||
// This can/should be optimized...
|
||||
torrent::Object tmp_command = item->command();
|
||||
|
||||
// Unquote the root function object so 'parse_command_execute'
|
||||
// doesn't end up calling it.
|
||||
//
|
||||
// TODO: Only call this if mask_function is set?
|
||||
uint32_t flags = tmp_command.flags() & torrent::Object::mask_function;
|
||||
tmp_command.unset_flags(torrent::Object::mask_function);
|
||||
tmp_command.set_flags((flags >> 1) & torrent::Object::mask_function);
|
||||
|
||||
rpc::parse_command_execute(rpc::make_target(), &tmp_command);
|
||||
rpc::commands.call_command(tmp_command.as_dict_key().c_str(), tmp_command.as_dict_obj());
|
||||
}
|
||||
rpc::call_object(item->command());
|
||||
|
||||
} catch (torrent::input_error& e) {
|
||||
if (m_slotErrorMessage.is_valid())
|
||||
|
||||
@@ -181,9 +181,8 @@ object_storage::call_function(const torrent::raw_string& key, target_type target
|
||||
|
||||
switch (itr->second.flags & mask_type) {
|
||||
case flag_function_type:
|
||||
return command_function_call_object(itr->second.object, target, object);
|
||||
case flag_multi_type:
|
||||
return command_function_multi_call(itr->second.object.as_map(), target, object);
|
||||
return command_function_call_object(itr->second.object, target, object);
|
||||
default:
|
||||
throw torrent::input_error("Key not found or wrong type.");
|
||||
}
|
||||
@@ -219,7 +218,7 @@ object_storage::erase_multi_key(const torrent::raw_string& key, const std::strin
|
||||
|
||||
void
|
||||
object_storage::set_multi_key_obj(const torrent::raw_string& key, const std::string& cmd_key, const torrent::Object& object) {
|
||||
if (!object.is_string() && !object.is_dict_key())
|
||||
if (!object.is_string() && !object.is_dict_key() && !object.is_list())
|
||||
throw torrent::input_error("Object is wrong type.");
|
||||
|
||||
local_iterator itr = find_local_mutable(key, flag_multi_type);
|
||||
|
||||
+42
-99
@@ -181,11 +181,6 @@ parse_command_multiple(target_type target, const char* first, const char* last)
|
||||
return result.first;
|
||||
}
|
||||
|
||||
parse_command_type
|
||||
parse_command_object(target_type target, const torrent::Object& object) {
|
||||
return parse_command(target, object.as_string().c_str(), object.as_string().c_str() + object.as_string().size());
|
||||
}
|
||||
|
||||
bool
|
||||
parse_command_file(const std::string& path) {
|
||||
std::fstream file(rak::path_expand(path).c_str(), std::ios::in);
|
||||
@@ -239,35 +234,55 @@ parse_command_file(const std::string& path) {
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
torrent::Object
|
||||
call_object(const torrent::Object& command, target_type target) {
|
||||
switch (command.type()) {
|
||||
case torrent::Object::TYPE_RAW_STRING:
|
||||
return parse_command_multiple(target, command.as_raw_string().begin(), command.as_raw_string().end());
|
||||
case torrent::Object::TYPE_STRING:
|
||||
return parse_command_multiple(target, command.as_string().c_str(), command.as_string().c_str() + command.as_string().size());
|
||||
|
||||
// Temp until it can be moved somewhere better...
|
||||
const torrent::Object
|
||||
command_function_call(const torrent::raw_string& cmd, target_type target, const torrent::Object& args) {
|
||||
rpc::command_base::stack_type stack;
|
||||
torrent::Object* last_stack;
|
||||
case torrent::Object::TYPE_LIST:
|
||||
{
|
||||
torrent::Object result;
|
||||
|
||||
if (args.is_list())
|
||||
last_stack = rpc::command_base::push_stack(args.as_list(), &stack);
|
||||
else if (args.type() != torrent::Object::TYPE_NONE)
|
||||
last_stack = rpc::command_base::push_stack(&args, &args + 1, &stack);
|
||||
else
|
||||
last_stack = rpc::command_base::push_stack(NULL, NULL, &stack);
|
||||
for (torrent::Object::list_const_iterator itr = command.as_list().begin(), last = command.as_list().end(); itr != last; itr++)
|
||||
result = call_object(*itr, target);
|
||||
|
||||
try {
|
||||
torrent::Object result = parse_command_multiple(target, cmd.begin(), cmd.end());
|
||||
|
||||
rpc::command_base::pop_stack(&stack, last_stack);
|
||||
return result;
|
||||
}
|
||||
case torrent::Object::TYPE_MAP:
|
||||
{
|
||||
for (torrent::Object::map_const_iterator itr = command.as_map().begin(), last = command.as_map().end(); itr != last; itr++)
|
||||
call_object(itr->second, target);
|
||||
|
||||
} catch (torrent::bencode_error& e) {
|
||||
rpc::command_base::pop_stack(&stack, last_stack);
|
||||
throw e;
|
||||
return torrent::Object();
|
||||
}
|
||||
case torrent::Object::TYPE_DICT_KEY:
|
||||
{
|
||||
// This can/should be optimized...
|
||||
torrent::Object tmp_command = command;
|
||||
|
||||
// Unquote the root function object so 'parse_command_execute'
|
||||
// doesn't end up calling it.
|
||||
//
|
||||
// TODO: Only call this if mask_function is set?
|
||||
uint32_t flags = tmp_command.flags() & torrent::Object::mask_function;
|
||||
tmp_command.unset_flags(torrent::Object::mask_function);
|
||||
tmp_command.set_flags((flags >> 1) & torrent::Object::mask_function);
|
||||
|
||||
parse_command_execute(target, &tmp_command);
|
||||
return commands.call_command(tmp_command.as_dict_key().c_str(), tmp_command.as_dict_obj(), target);
|
||||
}
|
||||
default:
|
||||
return torrent::Object();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
const torrent::Object
|
||||
command_function_call_object(const torrent::Object& cmd, target_type target, const torrent::Object& args) {
|
||||
rpc::command_base::stack_type stack;
|
||||
@@ -281,34 +296,7 @@ command_function_call_object(const torrent::Object& cmd, target_type target, con
|
||||
last_stack = rpc::command_base::push_stack(NULL, NULL, &stack);
|
||||
|
||||
try {
|
||||
torrent::Object result;
|
||||
|
||||
if (cmd.is_string()) {
|
||||
result = parse_command_multiple(target, cmd.as_string().c_str(), cmd.as_string().c_str() + cmd.as_string().size());
|
||||
|
||||
} else if (cmd.is_list()){
|
||||
for (torrent::Object::list_const_iterator first = cmd.as_list().begin(), last = cmd.as_list().end(); first != last; first++) {
|
||||
torrent::Object tmp_cmd = *first;
|
||||
|
||||
rpc::parse_command_execute(target, &tmp_cmd);
|
||||
result = rpc::commands.call_command(tmp_cmd.as_dict_key().c_str(), tmp_cmd.as_dict_obj());
|
||||
}
|
||||
|
||||
} else {
|
||||
torrent::Object tmp_command = cmd;
|
||||
|
||||
// Unquote the root function object so 'parse_command_execute'
|
||||
// doesn't end up calling it.
|
||||
//
|
||||
// TODO: Only call this if mask_function is set?
|
||||
uint32_t flags = tmp_command.flags() & torrent::Object::mask_function;
|
||||
tmp_command.unset_flags(torrent::Object::mask_function);
|
||||
tmp_command.set_flags((flags >> 1) & torrent::Object::mask_function);
|
||||
|
||||
rpc::parse_command_execute(target, &tmp_command);
|
||||
rpc::commands.call_command(tmp_command.as_dict_key().c_str(), tmp_command.as_dict_obj(), target);
|
||||
}
|
||||
|
||||
torrent::Object result = call_object(cmd, target);
|
||||
rpc::command_base::pop_stack(&stack, last_stack);
|
||||
return result;
|
||||
|
||||
@@ -318,49 +306,4 @@ command_function_call_object(const torrent::Object& cmd, target_type target, con
|
||||
}
|
||||
}
|
||||
|
||||
const torrent::Object
|
||||
command_function_multi_call(const torrent::Object::map_type& cmd, target_type target, const torrent::Object& args) {
|
||||
rpc::command_base::stack_type stack;
|
||||
torrent::Object* last_stack;
|
||||
|
||||
if (args.is_list())
|
||||
last_stack = rpc::command_base::push_stack(args.as_list(), &stack);
|
||||
else if (args.type() != torrent::Object::TYPE_NONE)
|
||||
last_stack = rpc::command_base::push_stack(&args, &args + 1, &stack);
|
||||
else
|
||||
last_stack = rpc::command_base::push_stack(NULL, NULL, &stack);
|
||||
|
||||
try {
|
||||
for (torrent::Object::map_const_iterator itr = cmd.begin(), last = cmd.end(); itr != last; itr++) {
|
||||
if (itr->second.is_dict_key()) {
|
||||
// This can/should be optimized...
|
||||
torrent::Object tmp_command = itr->second;
|
||||
|
||||
// Unquote the root function object so 'parse_command_execute'
|
||||
// doesn't end up calling it.
|
||||
//
|
||||
// TODO: Only call this if mask_function is set?
|
||||
uint32_t flags = tmp_command.flags() & torrent::Object::mask_function;
|
||||
tmp_command.unset_flags(torrent::Object::mask_function);
|
||||
tmp_command.set_flags((flags >> 1) & torrent::Object::mask_function);
|
||||
|
||||
rpc::parse_command_execute(target, &tmp_command);
|
||||
rpc::commands.call_command(tmp_command.as_dict_key().c_str(), tmp_command.as_dict_obj(), target);
|
||||
continue;
|
||||
}
|
||||
|
||||
const std::string& cmd_str = itr->second.as_string();
|
||||
parse_command_multiple(target, cmd_str.c_str(), cmd_str.c_str() + cmd_str.size());
|
||||
}
|
||||
|
||||
} catch (torrent::bencode_error& e) {
|
||||
rpc::command_base::pop_stack(&stack, last_stack);
|
||||
throw e;
|
||||
}
|
||||
|
||||
rpc::command_base::pop_stack(&stack, last_stack);
|
||||
return torrent::Object();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
+15
-17
@@ -64,9 +64,6 @@ torrent::Object parse_command_multiple(target_type target, const char* fi
|
||||
|
||||
void parse_command_execute(target_type target, torrent::Object* object);
|
||||
|
||||
// Make this take care of lists too.
|
||||
parse_command_type parse_command_object(target_type target, const torrent::Object& object);
|
||||
|
||||
inline torrent::Object parse_command_single(target_type target, const char* first) { return parse_command(target, first, first + std::strlen(first)).first; }
|
||||
inline torrent::Object parse_command_multiple(target_type target, const char* first) { return parse_command_multiple(target, first, first + std::strlen(first)); }
|
||||
|
||||
@@ -98,19 +95,13 @@ parse_command_multiple_d_nothrow(core::Download* download, const std::string& cm
|
||||
}
|
||||
}
|
||||
|
||||
inline torrent::Object call_command (const char* key, const torrent::Object& obj, target_type target = make_target()) { return commands.call_command(key, obj, target); }
|
||||
inline torrent::Object call_command_void (const char* key, target_type target = make_target()) { return commands.call_command(key, torrent::Object(), target); }
|
||||
inline torrent::Object call_command (const char* key, const torrent::Object& obj = torrent::Object(), target_type target = make_target()) { return commands.call_command(key, obj, target); }
|
||||
inline std::string call_command_string(const char* key, target_type target = make_target()) { return commands.call_command(key, torrent::Object(), target).as_string(); }
|
||||
inline int64_t call_command_value (const char* key, target_type target = make_target()) { return commands.call_command(key, torrent::Object(), target).as_value(); }
|
||||
|
||||
inline void call_command_set_string(const char* key, const std::string& arg) { commands.call_command(key, torrent::Object(arg)); }
|
||||
inline void call_command_set_std_string(const std::string& key, const std::string& arg) { commands.call_command(key.c_str(), torrent::Object(arg)); }
|
||||
|
||||
inline void call_command_d_v_void(const char* key, core::Download* download) { commands.call_command_d(key, download, torrent::Object()); }
|
||||
|
||||
inline void call_command_set_value(const char* key, int64_t arg, target_type target = make_target()) { commands.call_command(key, torrent::Object(arg), target); }
|
||||
inline void call_command_d_set_string(const char* key, core::Download* download, const std::string& arg) { commands.call_command_d(key, download, torrent::Object(arg)); }
|
||||
inline void call_command_d_set_std_string(const std::string& key, core::Download* download, const std::string& arg) { commands.call_command_d(key.c_str(), download, torrent::Object(arg)); }
|
||||
inline void call_command_set_value(const char* key, int64_t arg, target_type target = make_target()) { commands.call_command(key, torrent::Object(arg), target); }
|
||||
|
||||
inline torrent::Object
|
||||
call_command_d_range(const char* key, core::Download* download, torrent::Object::list_const_iterator first, torrent::Object::list_const_iterator last) {
|
||||
@@ -124,21 +115,28 @@ call_command_d_range(const char* key, core::Download* download, torrent::Object:
|
||||
return commands.call_command_d(key, download, rawArgs);
|
||||
}
|
||||
|
||||
torrent::Object call_object(const torrent::Object& command, target_type target = make_target());
|
||||
|
||||
inline torrent::Object
|
||||
call_object_nothrow(const torrent::Object& command, target_type target = make_target()) {
|
||||
try { return call_object(command, target); } catch (torrent::input_error& e) { return torrent::Object(); }
|
||||
}
|
||||
|
||||
inline torrent::Object
|
||||
call_object_d_nothrow(const torrent::Object& command, core::Download* download) {
|
||||
try { return call_object(command, make_target(download)); } catch (torrent::input_error& e) { return torrent::Object(); }
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
// Temp until it can be moved somewhere better...
|
||||
const torrent::Object
|
||||
command_function_call(const torrent::raw_string& cmd, target_type target, const torrent::Object& args);
|
||||
const torrent::Object
|
||||
command_function_call_object(const torrent::Object& cmd, target_type target, const torrent::Object& args);
|
||||
const torrent::Object
|
||||
command_function_multi_call(const torrent::Object::map_type& cmd, target_type target, const torrent::Object& args);
|
||||
|
||||
inline const torrent::Object
|
||||
command_function_call_str(const std::string& cmd, target_type target, const torrent::Object& args) {
|
||||
return command_function_call(torrent::raw_string::from_string(cmd), target, args);
|
||||
return command_function_call_object(torrent::Object(cmd), target, args);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+3
-3
@@ -169,12 +169,12 @@ SCgi::receive_call(SCgiTask* task, const char* buffer, uint32_t length) {
|
||||
slot_write slotWrite;
|
||||
slotWrite.set(rak::mem_fn(task, &SCgiTask::receive_write));
|
||||
|
||||
ThreadBase::acquire_global_lock();
|
||||
ThreadBase::interrupt_main_polling();
|
||||
torrent::thread_base::acquire_global_lock();
|
||||
torrent::main_thread()->interrupt();
|
||||
|
||||
bool result = xmlrpc.process(buffer, length, slotWrite);
|
||||
|
||||
ThreadBase::release_global_lock();
|
||||
torrent::thread_base::release_global_lock();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
+1
-1
@@ -53,7 +53,7 @@ class lt_cacheline_aligned SCgi : public torrent::Event {
|
||||
public:
|
||||
typedef rak::function2<bool, const char*, uint32_t> slot_write;
|
||||
|
||||
static const int max_tasks = 30;
|
||||
static const int max_tasks = 100;
|
||||
|
||||
// Global lock:
|
||||
SCgi() : m_logFd(-1) {}
|
||||
|
||||
@@ -185,7 +185,7 @@ SCgiTask::event_read() {
|
||||
result = write(m_parent->log_fd(), "\n---\n", sizeof("\n---\n"));
|
||||
}
|
||||
|
||||
lt_log_print_dump(torrent::LOG_RPC_DEBUG, m_body, m_bufferSize - std::distance(m_buffer, m_body), "scgi", "RPC read.", 0);
|
||||
lt_log_print_dump(torrent::LOG_RPC_DUMP, m_body, m_bufferSize - std::distance(m_buffer, m_body), "scgi", "RPC read.", 0);
|
||||
|
||||
// Close if the call failed, else stay open to write back data.
|
||||
if (!m_parent->receive_call(this, m_body, m_bufferSize - std::distance(m_buffer, m_body)))
|
||||
@@ -246,7 +246,7 @@ SCgiTask::receive_write(const char* buffer, uint32_t length) {
|
||||
result = write(m_parent->log_fd(), "\n---\n", sizeof("\n---\n"));
|
||||
}
|
||||
|
||||
lt_log_print_dump(torrent::LOG_RPC_DEBUG, m_buffer, m_bufferSize, "scgi", "RPC write.", 0);
|
||||
lt_log_print_dump(torrent::LOG_RPC_DUMP, m_buffer, m_bufferSize, "scgi", "RPC write.", 0);
|
||||
|
||||
event_write();
|
||||
return true;
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
//extern "C" void (*signal (int sig, void (*disp)(int)))(int);
|
||||
#endif
|
||||
|
||||
SignalHandler::Slot SignalHandler::m_handlers[HIGHEST_SIGNAL];
|
||||
SignalHandler::slot_void SignalHandler::m_handlers[HIGHEST_SIGNAL];
|
||||
|
||||
void
|
||||
SignalHandler::set_default(unsigned int signum) {
|
||||
@@ -54,7 +54,7 @@ SignalHandler::set_default(unsigned int signum) {
|
||||
throw std::logic_error("SignalHandler::set_default(...) received invalid signal value.");
|
||||
|
||||
signal(signum, SIG_DFL);
|
||||
m_handlers[signum].disconnect();
|
||||
m_handlers[signum] = slot_void();
|
||||
}
|
||||
|
||||
void
|
||||
@@ -63,15 +63,15 @@ SignalHandler::set_ignore(unsigned int signum) {
|
||||
throw std::logic_error("SignalHandler::set_ignore(...) received invalid signal value.");
|
||||
|
||||
signal(signum, SIG_IGN);
|
||||
m_handlers[signum].disconnect();
|
||||
m_handlers[signum] = slot_void();
|
||||
}
|
||||
|
||||
void
|
||||
SignalHandler::set_handler(unsigned int signum, Slot slot) {
|
||||
SignalHandler::set_handler(unsigned int signum, slot_void slot) {
|
||||
if (signum > HIGHEST_SIGNAL)
|
||||
throw std::logic_error("SignalHandler::set_handler(...) received invalid signal value.");
|
||||
|
||||
if (slot.empty())
|
||||
if (!slot)
|
||||
throw std::logic_error("SignalHandler::set_handler(...) received an empty slot.");
|
||||
|
||||
signal(signum, &SignalHandler::caught);
|
||||
@@ -98,7 +98,7 @@ SignalHandler::caught(int signum) {
|
||||
if ((unsigned)signum > HIGHEST_SIGNAL)
|
||||
throw std::logic_error("SignalHandler::caught(...) received invalid signal from the kernel, bork bork bork.");
|
||||
|
||||
if (m_handlers[signum].empty())
|
||||
if (!m_handlers[signum])
|
||||
throw std::logic_error("SignalHandler::caught(...) received a signal we don't have a handler for.");
|
||||
|
||||
m_handlers[signum]();
|
||||
|
||||
@@ -37,12 +37,12 @@
|
||||
#ifndef RTORRENT_SIGNAL_HANDLER_H
|
||||
#define RTORRENT_SIGNAL_HANDLER_H
|
||||
|
||||
#include <sys/signal.h>
|
||||
#include <sigc++/functors/slot.h>
|
||||
#include <signal.h>
|
||||
#include <tr1/functional>
|
||||
|
||||
class SignalHandler {
|
||||
public:
|
||||
typedef sigc::slot0<void> Slot;
|
||||
typedef std::tr1::function<void ()> slot_void;
|
||||
|
||||
// typedef void (*handler_slot)(int, siginfo_t *info, ucontext_t *uap);
|
||||
typedef void (*handler_slot)(int, siginfo_t*, void*);
|
||||
@@ -56,7 +56,7 @@ public:
|
||||
|
||||
static void set_default(unsigned int signum);
|
||||
static void set_ignore(unsigned int signum);
|
||||
static void set_handler(unsigned int signum, Slot slot);
|
||||
static void set_handler(unsigned int signum, slot_void slot);
|
||||
|
||||
static void set_sigaction_handler(unsigned int signum, handler_slot slot);
|
||||
|
||||
@@ -65,7 +65,7 @@ public:
|
||||
private:
|
||||
static void caught(int signum);
|
||||
|
||||
static Slot m_handlers[HIGHEST_SIGNAL];
|
||||
static slot_void m_handlers[HIGHEST_SIGNAL];
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
+1
-16
@@ -160,20 +160,5 @@ ThreadBase::queue_item(thread_base_func newFunc) {
|
||||
|
||||
// Make it also restart inactive threads?
|
||||
if (m_state == STATE_ACTIVE)
|
||||
pthread_kill(m_thread, SIGUSR1);
|
||||
}
|
||||
|
||||
void
|
||||
ThreadBase::interrupt_main_polling() {
|
||||
int sleep_length = 0;
|
||||
|
||||
while (ThreadBase::is_main_polling()) {
|
||||
pthread_kill(torrent::main_thread()->pthread(), SIGUSR1);
|
||||
|
||||
if (!ThreadBase::is_main_polling())
|
||||
return;
|
||||
|
||||
usleep(sleep_length);
|
||||
sleep_length = std::min(sleep_length + 50, 1000);
|
||||
}
|
||||
interrupt();
|
||||
}
|
||||
|
||||
@@ -66,14 +66,6 @@ public:
|
||||
|
||||
void queue_item(thread_base_func newFunc);
|
||||
|
||||
// Only call this when global lock has been acquired, as it checks
|
||||
// ThreadBase::is_main_polling() which is only guaranteed to remain
|
||||
// 'false' if global lock keeps main thread from entering polling
|
||||
// again.
|
||||
//
|
||||
// Move to libtorrent some day.
|
||||
static void interrupt_main_polling();
|
||||
|
||||
protected:
|
||||
int64_t next_timeout_usec();
|
||||
|
||||
|
||||
+1
-1
@@ -30,4 +30,4 @@ libsub_ui_a_SOURCES = \
|
||||
root.cc \
|
||||
root.h
|
||||
|
||||
INCLUDES = -I$(srcdir) -I$(srcdir)/.. -I$(top_srcdir)
|
||||
AM_CPPFLAGS = -I$(srcdir) -I$(srcdir)/.. -I$(top_srcdir)
|
||||
|
||||
+51
-52
@@ -36,7 +36,6 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <sigc++/adaptors/bind.h>
|
||||
#include <rak/functional.h>
|
||||
#include <rak/string_manip.h>
|
||||
#include <torrent/exceptions.h>
|
||||
@@ -85,13 +84,13 @@ Download::Download(core::Download* d) :
|
||||
m_uiArray[DISPLAY_CHUNKS_SEEN] = new ElementChunksSeen(d);
|
||||
m_uiArray[DISPLAY_TRANSFER_LIST] = new ElementTransferList(d);
|
||||
|
||||
m_uiArray[DISPLAY_MENU]->slot_exit(sigc::mem_fun(&m_slotExit, &slot_type::operator()));
|
||||
m_uiArray[DISPLAY_PEER_LIST]->slot_exit(sigc::bind(sigc::mem_fun(this, &Download::activate_display_menu), DISPLAY_PEER_LIST));
|
||||
m_uiArray[DISPLAY_INFO]->slot_exit(sigc::bind(sigc::mem_fun(this, &Download::activate_display_menu), DISPLAY_INFO));
|
||||
m_uiArray[DISPLAY_FILE_LIST]->slot_exit(sigc::bind(sigc::mem_fun(this, &Download::activate_display_menu), DISPLAY_FILE_LIST));
|
||||
m_uiArray[DISPLAY_TRACKER_LIST]->slot_exit(sigc::bind(sigc::mem_fun(this, &Download::activate_display_menu), DISPLAY_TRACKER_LIST));
|
||||
m_uiArray[DISPLAY_CHUNKS_SEEN]->slot_exit(sigc::bind(sigc::mem_fun(this, &Download::activate_display_menu), DISPLAY_CHUNKS_SEEN));
|
||||
m_uiArray[DISPLAY_TRANSFER_LIST]->slot_exit(sigc::bind(sigc::mem_fun(this, &Download::activate_display_menu), DISPLAY_TRANSFER_LIST));
|
||||
m_uiArray[DISPLAY_MENU]->slot_exit(std::tr1::bind(&slot_type::operator(), &m_slot_exit));
|
||||
m_uiArray[DISPLAY_PEER_LIST]->slot_exit(std::tr1::bind(&Download::activate_display_menu, this, DISPLAY_PEER_LIST));
|
||||
m_uiArray[DISPLAY_INFO]->slot_exit(std::tr1::bind(&Download::activate_display_menu, this, DISPLAY_INFO));
|
||||
m_uiArray[DISPLAY_FILE_LIST]->slot_exit(std::tr1::bind(&Download::activate_display_menu, this, DISPLAY_FILE_LIST));
|
||||
m_uiArray[DISPLAY_TRACKER_LIST]->slot_exit(std::tr1::bind(&Download::activate_display_menu, this, DISPLAY_TRACKER_LIST));
|
||||
m_uiArray[DISPLAY_CHUNKS_SEEN]->slot_exit(std::tr1::bind(&Download::activate_display_menu, this, DISPLAY_CHUNKS_SEEN));
|
||||
m_uiArray[DISPLAY_TRANSFER_LIST]->slot_exit(std::tr1::bind(&Download::activate_display_menu, this, DISPLAY_TRANSFER_LIST));
|
||||
|
||||
bind_keys();
|
||||
}
|
||||
@@ -110,30 +109,30 @@ Download::create_menu() {
|
||||
ElementMenu* element = new ElementMenu;
|
||||
|
||||
element->push_back("Peer list",
|
||||
sigc::bind(sigc::mem_fun(this, &Download::activate_display_focus), DISPLAY_PEER_LIST),
|
||||
sigc::bind(sigc::mem_fun(this, &Download::activate_display_menu), DISPLAY_PEER_LIST));
|
||||
std::tr1::bind(&Download::activate_display_focus, this, DISPLAY_PEER_LIST),
|
||||
std::tr1::bind(&Download::activate_display_menu, this, DISPLAY_PEER_LIST));
|
||||
element->push_back("Info",
|
||||
sigc::bind(sigc::mem_fun(this, &Download::activate_display_focus), DISPLAY_INFO),
|
||||
sigc::bind(sigc::mem_fun(this, &Download::activate_display_menu), DISPLAY_INFO));
|
||||
std::tr1::bind(&Download::activate_display_focus, this, DISPLAY_INFO),
|
||||
std::tr1::bind(&Download::activate_display_menu, this, DISPLAY_INFO));
|
||||
element->push_back("File list",
|
||||
sigc::bind(sigc::mem_fun(this, &Download::activate_display_focus), DISPLAY_FILE_LIST),
|
||||
sigc::bind(sigc::mem_fun(this, &Download::activate_display_menu), DISPLAY_FILE_LIST));
|
||||
std::tr1::bind(&Download::activate_display_focus, this, DISPLAY_FILE_LIST),
|
||||
std::tr1::bind(&Download::activate_display_menu, this, DISPLAY_FILE_LIST));
|
||||
element->push_back("Tracker list",
|
||||
sigc::bind(sigc::mem_fun(this, &Download::activate_display_focus), DISPLAY_TRACKER_LIST),
|
||||
sigc::bind(sigc::mem_fun(this, &Download::activate_display_menu), DISPLAY_TRACKER_LIST));
|
||||
std::tr1::bind(&Download::activate_display_focus, this, DISPLAY_TRACKER_LIST),
|
||||
std::tr1::bind(&Download::activate_display_menu, this, DISPLAY_TRACKER_LIST));
|
||||
element->push_back("Chunks seen",
|
||||
sigc::bind(sigc::mem_fun(this, &Download::activate_display_focus), DISPLAY_CHUNKS_SEEN),
|
||||
sigc::bind(sigc::mem_fun(this, &Download::activate_display_menu), DISPLAY_CHUNKS_SEEN));
|
||||
std::tr1::bind(&Download::activate_display_focus, this, DISPLAY_CHUNKS_SEEN),
|
||||
std::tr1::bind(&Download::activate_display_menu, this, DISPLAY_CHUNKS_SEEN));
|
||||
element->push_back("Transfer list",
|
||||
sigc::bind(sigc::mem_fun(this, &Download::activate_display_focus), DISPLAY_TRANSFER_LIST),
|
||||
sigc::bind(sigc::mem_fun(this, &Download::activate_display_menu), DISPLAY_TRANSFER_LIST));
|
||||
std::tr1::bind(&Download::activate_display_focus, this, DISPLAY_TRANSFER_LIST),
|
||||
std::tr1::bind(&Download::activate_display_menu, this, DISPLAY_TRANSFER_LIST));
|
||||
|
||||
element->set_entry(0, false);
|
||||
|
||||
m_bindings['p'] = sigc::bind(sigc::mem_fun(element, &ElementMenu::set_entry_trigger), 0);
|
||||
m_bindings['o'] = sigc::bind(sigc::mem_fun(element, &ElementMenu::set_entry_trigger), 1);
|
||||
m_bindings['i'] = sigc::bind(sigc::mem_fun(element, &ElementMenu::set_entry_trigger), 2);
|
||||
m_bindings['u'] = sigc::bind(sigc::mem_fun(element, &ElementMenu::set_entry_trigger), 3);
|
||||
m_bindings['p'] = std::tr1::bind(&ElementMenu::set_entry_trigger, element, 0);
|
||||
m_bindings['o'] = std::tr1::bind(&ElementMenu::set_entry_trigger, element, 1);
|
||||
m_bindings['i'] = std::tr1::bind(&ElementMenu::set_entry_trigger, element, 2);
|
||||
m_bindings['u'] = std::tr1::bind(&ElementMenu::set_entry_trigger, element, 3);
|
||||
|
||||
return element;
|
||||
}
|
||||
@@ -376,40 +375,40 @@ Download::adjust_up_throttle(int throttle) {
|
||||
|
||||
void
|
||||
Download::bind_keys() {
|
||||
m_bindings['1'] = sigc::bind(sigc::mem_fun(this, &Download::receive_min_uploads), -1);
|
||||
m_bindings['2'] = sigc::bind(sigc::mem_fun(this, &Download::receive_min_uploads), 1);
|
||||
m_bindings['3'] = sigc::bind(sigc::mem_fun(this, &Download::receive_max_uploads), -1);
|
||||
m_bindings['4'] = sigc::bind(sigc::mem_fun(this, &Download::receive_max_uploads), 1);
|
||||
m_bindings['!'] = sigc::bind(sigc::mem_fun(this, &Download::receive_min_downloads), -1);
|
||||
m_bindings['@'] = sigc::bind(sigc::mem_fun(this, &Download::receive_min_downloads), 1);
|
||||
m_bindings['#'] = sigc::bind(sigc::mem_fun(this, &Download::receive_max_downloads), -1);
|
||||
m_bindings['$'] = sigc::bind(sigc::mem_fun(this, &Download::receive_max_downloads), 1);
|
||||
m_bindings['5'] = sigc::bind(sigc::mem_fun(this, &Download::receive_min_peers), -5);
|
||||
m_bindings['6'] = sigc::bind(sigc::mem_fun(this, &Download::receive_min_peers), 5);
|
||||
m_bindings['7'] = sigc::bind(sigc::mem_fun(this, &Download::receive_max_peers), -5);
|
||||
m_bindings['8'] = sigc::bind(sigc::mem_fun(this, &Download::receive_max_peers), 5);
|
||||
m_bindings['+'] = sigc::mem_fun(this, &Download::receive_next_priority);
|
||||
m_bindings['-'] = sigc::mem_fun(this, &Download::receive_prev_priority);
|
||||
m_bindings['1'] = std::tr1::bind(&Download::receive_min_uploads, this, -1);
|
||||
m_bindings['2'] = std::tr1::bind(&Download::receive_min_uploads, this, 1);
|
||||
m_bindings['3'] = std::tr1::bind(&Download::receive_max_uploads, this, -1);
|
||||
m_bindings['4'] = std::tr1::bind(&Download::receive_max_uploads, this, 1);
|
||||
m_bindings['!'] = std::tr1::bind(&Download::receive_min_downloads, this, -1);
|
||||
m_bindings['@'] = std::tr1::bind(&Download::receive_min_downloads, this, 1);
|
||||
m_bindings['#'] = std::tr1::bind(&Download::receive_max_downloads, this, -1);
|
||||
m_bindings['$'] = std::tr1::bind(&Download::receive_max_downloads, this, 1);
|
||||
m_bindings['5'] = std::tr1::bind(&Download::receive_min_peers, this, -5);
|
||||
m_bindings['6'] = std::tr1::bind(&Download::receive_min_peers, this, 5);
|
||||
m_bindings['7'] = std::tr1::bind(&Download::receive_max_peers, this, -5);
|
||||
m_bindings['8'] = std::tr1::bind(&Download::receive_max_peers, this, 5);
|
||||
m_bindings['+'] = std::tr1::bind(&Download::receive_next_priority, this);
|
||||
m_bindings['-'] = std::tr1::bind(&Download::receive_prev_priority, this);
|
||||
|
||||
m_bindings['t'] = sigc::bind(sigc::mem_fun(m_download->download(), &torrent::Download::manual_request), false);
|
||||
m_bindings['T'] = sigc::bind(sigc::mem_fun(m_download->download(), &torrent::Download::manual_request), true);
|
||||
m_bindings['t'] = std::tr1::bind(&torrent::Download::manual_request, m_download->download(), false);
|
||||
m_bindings['T'] = std::tr1::bind(&torrent::Download::manual_request, m_download->download(), true);
|
||||
|
||||
const char* keys = control->ui()->get_throttle_keys();
|
||||
|
||||
m_bindings[keys[ 0]] = sigc::bind(sigc::mem_fun(this, &Download::adjust_up_throttle), 1);
|
||||
m_bindings[keys[ 1]] = sigc::bind(sigc::mem_fun(this, &Download::adjust_up_throttle), -1);
|
||||
m_bindings[keys[ 2]] = sigc::bind(sigc::mem_fun(this, &Download::adjust_down_throttle), 1);
|
||||
m_bindings[keys[ 3]] = sigc::bind(sigc::mem_fun(this, &Download::adjust_down_throttle), -1);
|
||||
m_bindings[keys[ 0]] = std::tr1::bind(&Download::adjust_up_throttle, this, 1);
|
||||
m_bindings[keys[ 1]] = std::tr1::bind(&Download::adjust_up_throttle, this, -1);
|
||||
m_bindings[keys[ 2]] = std::tr1::bind(&Download::adjust_down_throttle, this, 1);
|
||||
m_bindings[keys[ 3]] = std::tr1::bind(&Download::adjust_down_throttle, this, -1);
|
||||
|
||||
m_bindings[keys[ 4]] = sigc::bind(sigc::mem_fun(this, &Download::adjust_up_throttle), 5);
|
||||
m_bindings[keys[ 5]] = sigc::bind(sigc::mem_fun(this, &Download::adjust_up_throttle), -5);
|
||||
m_bindings[keys[ 6]] = sigc::bind(sigc::mem_fun(this, &Download::adjust_down_throttle), 5);
|
||||
m_bindings[keys[ 7]] = sigc::bind(sigc::mem_fun(this, &Download::adjust_down_throttle), -5);
|
||||
m_bindings[keys[ 4]] = std::tr1::bind(&Download::adjust_up_throttle, this, 5);
|
||||
m_bindings[keys[ 5]] = std::tr1::bind(&Download::adjust_up_throttle, this, -5);
|
||||
m_bindings[keys[ 6]] = std::tr1::bind(&Download::adjust_down_throttle, this, 5);
|
||||
m_bindings[keys[ 7]] = std::tr1::bind(&Download::adjust_down_throttle, this, -5);
|
||||
|
||||
m_bindings[keys[ 8]] = sigc::bind(sigc::mem_fun(this, &Download::adjust_up_throttle), 50);
|
||||
m_bindings[keys[ 9]] = sigc::bind(sigc::mem_fun(this, &Download::adjust_up_throttle), -50);
|
||||
m_bindings[keys[10]] = sigc::bind(sigc::mem_fun(this, &Download::adjust_down_throttle), 50);
|
||||
m_bindings[keys[11]] = sigc::bind(sigc::mem_fun(this, &Download::adjust_down_throttle), -50);
|
||||
m_bindings[keys[ 8]] = std::tr1::bind(&Download::adjust_up_throttle, this, 50);
|
||||
m_bindings[keys[ 9]] = std::tr1::bind(&Download::adjust_up_throttle, this, -50);
|
||||
m_bindings[keys[10]] = std::tr1::bind(&Download::adjust_down_throttle, this, 50);
|
||||
m_bindings[keys[11]] = std::tr1::bind(&Download::adjust_down_throttle, this, -50);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -39,7 +39,6 @@
|
||||
|
||||
#include <list>
|
||||
#include <torrent/peer/peer.h>
|
||||
#include <sigc++/connection.h>
|
||||
|
||||
#include "display/manager.h"
|
||||
#include "utils/list_focus.h"
|
||||
|
||||
+20
-19
@@ -38,8 +38,6 @@
|
||||
|
||||
#include <rak/functional.h>
|
||||
#include <rak/string_manip.h>
|
||||
#include <sigc++/adaptors/bind.h>
|
||||
#include <sigc++/adaptors/hide.h>
|
||||
#include <torrent/exceptions.h>
|
||||
#include <torrent/torrent.h>
|
||||
#include <torrent/utils/log.h>
|
||||
@@ -193,7 +191,7 @@ DownloadList::activate_display(Display displayType) {
|
||||
Download* download = new Download(*current_view()->focus());
|
||||
|
||||
download->activate(m_frame);
|
||||
download->slot_exit(sigc::bind(sigc::mem_fun(*this, &DownloadList::activate_display), DISPLAY_DOWNLOAD_LIST));
|
||||
download->slot_exit(std::tr1::bind(&DownloadList::activate_display, this, DISPLAY_DOWNLOAD_LIST));
|
||||
|
||||
m_uiArray[DISPLAY_DOWNLOAD] = download;
|
||||
break;
|
||||
@@ -270,15 +268,18 @@ DownloadList::receive_view_input(Input type) {
|
||||
|
||||
ElementStringList* esl = dynamic_cast<ElementStringList*>(m_uiArray[DISPLAY_STRING_LIST]);
|
||||
|
||||
input->signal_show_next().connect(sigc::bind(sigc::mem_fun(*this, &DownloadList::activate_display), DISPLAY_STRING_LIST));
|
||||
input->signal_show_next().connect(sigc::mem_fun(*esl, &ElementStringList::next_screen));
|
||||
input->signal_show_next().push_back(std::tr1::bind(&DownloadList::activate_display, this, DISPLAY_STRING_LIST));
|
||||
input->signal_show_next().push_back(std::tr1::bind(&ElementStringList::next_screen, esl));
|
||||
|
||||
input->signal_show_range().connect(sigc::hide(sigc::hide(sigc::bind(sigc::mem_fun(*this, &DownloadList::activate_display), DISPLAY_STRING_LIST))));
|
||||
input->signal_show_range().connect(sigc::mem_fun(*esl, &ElementStringList::set_range_dirent<utils::Directory::iterator>));
|
||||
input->signal_show_range().push_back(std::tr1::bind(&DownloadList::activate_display, this, DISPLAY_STRING_LIST));
|
||||
input->signal_show_range().push_back(std::tr1::bind(&ElementStringList::set_range_dirent<utils::Directory::iterator>,
|
||||
esl,
|
||||
std::tr1::placeholders::_1,
|
||||
std::tr1::placeholders::_2));
|
||||
|
||||
input->bindings()['\n'] = sigc::bind(sigc::mem_fun(*this, &DownloadList::receive_exit_input), type);
|
||||
input->bindings()[KEY_ENTER] = sigc::bind(sigc::mem_fun(*this, &DownloadList::receive_exit_input), type);
|
||||
input->bindings()['\x07'] = sigc::bind(sigc::mem_fun(*this, &DownloadList::receive_exit_input), INPUT_NONE);
|
||||
input->bindings()['\n'] = std::tr1::bind(&DownloadList::receive_exit_input, this, type);
|
||||
input->bindings()[KEY_ENTER] = std::tr1::bind(&DownloadList::receive_exit_input, this, type);
|
||||
input->bindings()['\x07'] = std::tr1::bind(&DownloadList::receive_exit_input, this, INPUT_NONE);
|
||||
|
||||
control->ui()->enable_input(title, input);
|
||||
}
|
||||
@@ -339,20 +340,20 @@ DownloadList::receive_exit_input(Input type) {
|
||||
|
||||
void
|
||||
DownloadList::setup_keys() {
|
||||
m_bindings['\x7f'] = sigc::bind(sigc::mem_fun(*this, &DownloadList::receive_view_input), INPUT_LOAD_DEFAULT);
|
||||
m_bindings[KEY_BACKSPACE] = sigc::bind(sigc::mem_fun(*this, &DownloadList::receive_view_input), INPUT_LOAD_DEFAULT);
|
||||
m_bindings['\n'] = sigc::bind(sigc::mem_fun(*this, &DownloadList::receive_view_input), INPUT_LOAD_MODIFIED);
|
||||
m_bindings[KEY_ENTER] = sigc::bind(sigc::mem_fun(*this, &DownloadList::receive_view_input), INPUT_LOAD_MODIFIED);
|
||||
m_bindings['\x0F'] = sigc::bind(sigc::mem_fun(*this, &DownloadList::receive_view_input), INPUT_CHANGE_DIRECTORY);
|
||||
m_bindings['X' - '@'] = sigc::bind(sigc::mem_fun(*this, &DownloadList::receive_view_input), INPUT_COMMAND);
|
||||
m_bindings['\x7f'] = std::tr1::bind(&DownloadList::receive_view_input, this, INPUT_LOAD_DEFAULT);
|
||||
m_bindings[KEY_BACKSPACE] = std::tr1::bind(&DownloadList::receive_view_input, this, INPUT_LOAD_DEFAULT);
|
||||
m_bindings['\n'] = std::tr1::bind(&DownloadList::receive_view_input, this, INPUT_LOAD_MODIFIED);
|
||||
m_bindings[KEY_ENTER] = std::tr1::bind(&DownloadList::receive_view_input, this, INPUT_LOAD_MODIFIED);
|
||||
m_bindings['\x0F'] = std::tr1::bind(&DownloadList::receive_view_input, this, INPUT_CHANGE_DIRECTORY);
|
||||
m_bindings['X' - '@'] = std::tr1::bind(&DownloadList::receive_view_input, this, INPUT_COMMAND);
|
||||
|
||||
m_uiArray[DISPLAY_LOG]->bindings()[KEY_LEFT] =
|
||||
m_uiArray[DISPLAY_LOG]->bindings()['B' - '@'] =
|
||||
m_uiArray[DISPLAY_LOG]->bindings()[' '] = sigc::bind(sigc::mem_fun(*this, &DownloadList::activate_display), DISPLAY_DOWNLOAD_LIST);
|
||||
m_uiArray[DISPLAY_LOG]->bindings()[' '] = std::tr1::bind(&DownloadList::activate_display, this, DISPLAY_DOWNLOAD_LIST);
|
||||
|
||||
m_uiArray[DISPLAY_DOWNLOAD_LIST]->bindings()[KEY_RIGHT] =
|
||||
m_uiArray[DISPLAY_DOWNLOAD_LIST]->bindings()['F' - '@'] = sigc::bind(sigc::mem_fun(*this, &DownloadList::activate_display), DISPLAY_DOWNLOAD);
|
||||
m_uiArray[DISPLAY_DOWNLOAD_LIST]->bindings()['l'] = sigc::bind(sigc::mem_fun(*this, &DownloadList::activate_display), DISPLAY_LOG);
|
||||
m_uiArray[DISPLAY_DOWNLOAD_LIST]->bindings()['F' - '@'] = std::tr1::bind(&DownloadList::activate_display, this, DISPLAY_DOWNLOAD);
|
||||
m_uiArray[DISPLAY_DOWNLOAD_LIST]->bindings()['l'] = std::tr1::bind(&DownloadList::activate_display, this, DISPLAY_LOG);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -37,12 +37,9 @@
|
||||
#ifndef RTORRENT_UI_DOWNLOAD_LIST_H
|
||||
#define RTORRENT_UI_DOWNLOAD_LIST_H
|
||||
|
||||
#include <sigc++/functors/slot.h>
|
||||
|
||||
#include "display/manager.h"
|
||||
|
||||
#include "element_base.h"
|
||||
#include "globals.h"
|
||||
#include "display/manager.h"
|
||||
|
||||
class Control;
|
||||
|
||||
@@ -74,7 +71,7 @@ public:
|
||||
typedef display::WindowLog WLog;
|
||||
typedef display::WindowLogComplete WLogComplete;
|
||||
|
||||
typedef sigc::slot1<void, const std::string&> SlotOpenUri;
|
||||
typedef std::tr1::function<void (const std::string&)> slot_string;
|
||||
|
||||
typedef enum {
|
||||
DISPLAY_DOWNLOAD,
|
||||
@@ -103,7 +100,7 @@ public:
|
||||
core::View* current_view();
|
||||
void set_current_view(const std::string& name);
|
||||
|
||||
void slot_open_uri(SlotOpenUri s) { m_slotOpenUri = s; }
|
||||
void slot_open_uri(slot_string s) { m_slot_open_uri = s; }
|
||||
|
||||
void unfocus_download(core::Download* d);
|
||||
|
||||
@@ -122,7 +119,7 @@ private:
|
||||
ElementBase* m_uiArray[DISPLAY_MAX_SIZE];
|
||||
WLog* m_windowLog;
|
||||
|
||||
SlotOpenUri m_slotOpenUri;
|
||||
slot_string m_slot_open_uri;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ namespace ui {
|
||||
|
||||
class ElementBase {
|
||||
public:
|
||||
typedef sigc::slot0<void> slot_type;
|
||||
typedef std::tr1::function<void ()> slot_type;
|
||||
|
||||
ElementBase() : m_frame(NULL), m_focus(false) {}
|
||||
virtual ~ElementBase() {}
|
||||
@@ -60,7 +60,7 @@ public:
|
||||
virtual void activate(display::Frame* frame, bool focus = true) = 0;
|
||||
virtual void disable() = 0;
|
||||
|
||||
void slot_exit(const slot_type& s) { m_slotExit = s; }
|
||||
void slot_exit(const slot_type& s) { m_slot_exit = s; }
|
||||
|
||||
void mark_dirty();
|
||||
|
||||
@@ -69,7 +69,7 @@ protected:
|
||||
bool m_focus;
|
||||
|
||||
input::Bindings m_bindings;
|
||||
slot_type m_slotExit;
|
||||
slot_type m_slot_exit;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -52,12 +52,12 @@ ElementChunksSeen::ElementChunksSeen(core::Download* d) :
|
||||
m_window(NULL),
|
||||
m_focus(0) {
|
||||
|
||||
m_bindings[KEY_LEFT] = m_bindings['B' - '@'] = sigc::mem_fun(&m_slotExit, &slot_type::operator());
|
||||
m_bindings[KEY_LEFT] = m_bindings['B' - '@'] = std::tr1::bind(&slot_type::operator(), &m_slot_exit);
|
||||
|
||||
m_bindings[KEY_DOWN] = m_bindings['N' - '@'] = sigc::mem_fun(*this, &ElementChunksSeen::receive_next);
|
||||
m_bindings[KEY_UP] = m_bindings['P' - '@'] = sigc::mem_fun(*this, &ElementChunksSeen::receive_prev);
|
||||
m_bindings[KEY_NPAGE] = sigc::mem_fun(*this, &ElementChunksSeen::receive_pagenext);
|
||||
m_bindings[KEY_PPAGE] = sigc::mem_fun(*this, &ElementChunksSeen::receive_pageprev);
|
||||
m_bindings[KEY_DOWN] = m_bindings['N' - '@'] = std::tr1::bind(&ElementChunksSeen::receive_next, this);
|
||||
m_bindings[KEY_UP] = m_bindings['P' - '@'] = std::tr1::bind(&ElementChunksSeen::receive_prev, this);
|
||||
m_bindings[KEY_NPAGE] = std::tr1::bind(&ElementChunksSeen::receive_pagenext, this);
|
||||
m_bindings[KEY_PPAGE] = std::tr1::bind(&ElementChunksSeen::receive_pageprev, this);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -36,7 +36,6 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <sigc++/adaptors/bind.h>
|
||||
#include <torrent/exceptions.h>
|
||||
#include <torrent/object.h>
|
||||
#include <torrent/utils/log.h>
|
||||
@@ -64,41 +63,42 @@ ElementDownloadList::ElementDownloadList() :
|
||||
if (m_view == NULL)
|
||||
throw torrent::internal_error("View \"main\" must be present to initialize the main display.");
|
||||
|
||||
m_bindings['\x13'] = sigc::bind(sigc::mem_fun(*this, &ElementDownloadList::receive_command), "d.start=");
|
||||
m_bindings['\x04'] = sigc::bind(sigc::mem_fun(*this, &ElementDownloadList::receive_command), "branch=d.state=,d.stop=,d.erase=");
|
||||
m_bindings['\x0B'] = sigc::bind(sigc::mem_fun(*this, &ElementDownloadList::receive_command), "d.ignore_commands.set=1; d.stop=; d.close=");
|
||||
m_bindings['\x12'] = sigc::bind(sigc::mem_fun(*this, &ElementDownloadList::receive_command), "d.complete.set=0; d.check_hash=");
|
||||
m_bindings['\x05'] = sigc::bind(sigc::mem_fun(*this, &ElementDownloadList::receive_command),
|
||||
"f.multicall=,f.set_create_queued=0,f.set_resize_queued=0; print=\"Queued create/resize of files in torrent.\"");
|
||||
m_bindings['\x13'] = std::tr1::bind(&ElementDownloadList::receive_command, this, "d.start=");
|
||||
m_bindings['\x04'] = std::tr1::bind(&ElementDownloadList::receive_command, this, "branch=d.state=,d.stop=,d.erase=");
|
||||
m_bindings['\x0B'] = std::tr1::bind(&ElementDownloadList::receive_command, this, "d.ignore_commands.set=1; d.stop=; d.close=");
|
||||
m_bindings['\x12'] = std::tr1::bind(&ElementDownloadList::receive_command, this, "d.complete.set=0; d.check_hash=");
|
||||
m_bindings['\x05'] = std::tr1::bind(&ElementDownloadList::receive_command, this,
|
||||
"f.multicall=,f.set_create_queued=0,f.set_resize_queued=0; print=\"Queued create/resize of files in torrent.\"");
|
||||
|
||||
m_bindings['+'] = sigc::mem_fun(*this, &ElementDownloadList::receive_next_priority);
|
||||
m_bindings['-'] = sigc::mem_fun(*this, &ElementDownloadList::receive_prev_priority);
|
||||
m_bindings['T'-'@']= sigc::mem_fun(*this, &ElementDownloadList::receive_cycle_throttle);
|
||||
m_bindings['I'] = sigc::bind(sigc::mem_fun(*this, &ElementDownloadList::receive_command),
|
||||
m_bindings['+'] = std::tr1::bind(&ElementDownloadList::receive_next_priority, this);
|
||||
m_bindings['-'] = std::tr1::bind(&ElementDownloadList::receive_prev_priority, this);
|
||||
m_bindings['T'-'@']= std::tr1::bind(&ElementDownloadList::receive_cycle_throttle, this);
|
||||
m_bindings['I'] = std::tr1::bind(&ElementDownloadList::receive_command, this,
|
||||
"branch=d.ignore_commands=,"
|
||||
"{d.ignore_commands.set=0, print=\"Torrent set to heed commands.\"},"
|
||||
"{d.ignore_commands.set=1, print=\"Torrent set to ignore commands.\"}");
|
||||
m_bindings['B'-'@']= sigc::bind(sigc::mem_fun(*this, &ElementDownloadList::receive_command),
|
||||
m_bindings['B'-'@']= std::tr1::bind(&ElementDownloadList::receive_command, this,
|
||||
"branch=d.is_active=,"
|
||||
"{print=\"Cannot enable initial seeding on an active download.\"},"
|
||||
"{d.connection_seed.set=initial_seed, print=\"Enabled initial seeding for the selected download.\"}");
|
||||
|
||||
m_bindings['U'] = sigc::bind(sigc::mem_fun(*this, &ElementDownloadList::receive_command), "d.delete_tied=; print=\"Cleared tied to file association for the selected download.\"");
|
||||
m_bindings['U'] = std::tr1::bind(&ElementDownloadList::receive_command, this,
|
||||
"d.delete_tied=; print=\"Cleared tied to file association for the selected download.\"");
|
||||
|
||||
// These should also be commands.
|
||||
m_bindings['1'] = sigc::bind(sigc::mem_fun(*this, &ElementDownloadList::receive_change_view), "main");
|
||||
m_bindings['2'] = sigc::bind(sigc::mem_fun(*this, &ElementDownloadList::receive_change_view), "name");
|
||||
m_bindings['3'] = sigc::bind(sigc::mem_fun(*this, &ElementDownloadList::receive_change_view), "started");
|
||||
m_bindings['4'] = sigc::bind(sigc::mem_fun(*this, &ElementDownloadList::receive_change_view), "stopped");
|
||||
m_bindings['5'] = sigc::bind(sigc::mem_fun(*this, &ElementDownloadList::receive_change_view), "complete");
|
||||
m_bindings['6'] = sigc::bind(sigc::mem_fun(*this, &ElementDownloadList::receive_change_view), "incomplete");
|
||||
m_bindings['7'] = sigc::bind(sigc::mem_fun(*this, &ElementDownloadList::receive_change_view), "hashing");
|
||||
m_bindings['8'] = sigc::bind(sigc::mem_fun(*this, &ElementDownloadList::receive_change_view), "seeding");
|
||||
m_bindings['9'] = sigc::bind(sigc::mem_fun(*this, &ElementDownloadList::receive_change_view), "leeching");
|
||||
m_bindings['0'] = sigc::bind(sigc::mem_fun(*this, &ElementDownloadList::receive_change_view), "active");
|
||||
m_bindings['1'] = std::tr1::bind(&ElementDownloadList::receive_change_view, this, "main");
|
||||
m_bindings['2'] = std::tr1::bind(&ElementDownloadList::receive_change_view, this, "name");
|
||||
m_bindings['3'] = std::tr1::bind(&ElementDownloadList::receive_change_view, this, "started");
|
||||
m_bindings['4'] = std::tr1::bind(&ElementDownloadList::receive_change_view, this, "stopped");
|
||||
m_bindings['5'] = std::tr1::bind(&ElementDownloadList::receive_change_view, this, "complete");
|
||||
m_bindings['6'] = std::tr1::bind(&ElementDownloadList::receive_change_view, this, "incomplete");
|
||||
m_bindings['7'] = std::tr1::bind(&ElementDownloadList::receive_change_view, this, "hashing");
|
||||
m_bindings['8'] = std::tr1::bind(&ElementDownloadList::receive_change_view, this, "seeding");
|
||||
m_bindings['9'] = std::tr1::bind(&ElementDownloadList::receive_change_view, this, "leeching");
|
||||
m_bindings['0'] = std::tr1::bind(&ElementDownloadList::receive_change_view, this, "active");
|
||||
|
||||
m_bindings[KEY_UP] = m_bindings['P' - '@'] = sigc::mem_fun(*this, &ElementDownloadList::receive_prev);
|
||||
m_bindings[KEY_DOWN] = m_bindings['N' - '@'] = sigc::mem_fun(*this, &ElementDownloadList::receive_next);
|
||||
m_bindings[KEY_UP] = m_bindings['P' - '@'] = std::tr1::bind(&ElementDownloadList::receive_prev, this);
|
||||
m_bindings[KEY_DOWN] = m_bindings['N' - '@'] = std::tr1::bind(&ElementDownloadList::receive_next, this);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
+10
-11
@@ -36,7 +36,6 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <sigc++/adaptors/bind.h>
|
||||
#include <rak/algorithm.h>
|
||||
#include <torrent/exceptions.h>
|
||||
#include <torrent/data/file.h>
|
||||
@@ -64,17 +63,17 @@ ElementFileList::ElementFileList(core::Download* d) :
|
||||
m_selected(iterator(d->download()->file_list()->begin())),
|
||||
m_collapsed(false) {
|
||||
|
||||
m_bindings[KEY_LEFT] = m_bindings['B' - '@'] = sigc::mem_fun(&m_slotExit, &slot_type::operator());
|
||||
m_bindings[KEY_RIGHT] = m_bindings['F' - '@'] = sigc::mem_fun(*this, &ElementFileList::receive_select);
|
||||
m_bindings[KEY_LEFT] = m_bindings['B' - '@'] = std::tr1::bind(&slot_type::operator(), &m_slot_exit);
|
||||
m_bindings[KEY_RIGHT] = m_bindings['F' - '@'] = std::tr1::bind(&ElementFileList::receive_select, this);
|
||||
|
||||
m_bindings[' '] = sigc::mem_fun(*this, &ElementFileList::receive_priority);
|
||||
m_bindings['*'] = sigc::mem_fun(*this, &ElementFileList::receive_change_all);
|
||||
m_bindings['/'] = sigc::mem_fun(*this, &ElementFileList::receive_collapse);
|
||||
m_bindings[KEY_NPAGE] = sigc::mem_fun(*this, &ElementFileList::receive_pagenext);
|
||||
m_bindings[KEY_PPAGE] = sigc::mem_fun(*this, &ElementFileList::receive_pageprev);
|
||||
m_bindings[' '] = std::tr1::bind(&ElementFileList::receive_priority, this);
|
||||
m_bindings['*'] = std::tr1::bind(&ElementFileList::receive_change_all, this);
|
||||
m_bindings['/'] = std::tr1::bind(&ElementFileList::receive_collapse, this);
|
||||
m_bindings[KEY_NPAGE] = std::tr1::bind(&ElementFileList::receive_pagenext, this);
|
||||
m_bindings[KEY_PPAGE] = std::tr1::bind(&ElementFileList::receive_pageprev, this);
|
||||
|
||||
m_bindings[KEY_DOWN] = m_bindings['N' - '@'] = sigc::mem_fun(*this, &ElementFileList::receive_next);
|
||||
m_bindings[KEY_UP] = m_bindings['P' - '@'] = sigc::mem_fun(*this, &ElementFileList::receive_prev);
|
||||
m_bindings[KEY_DOWN] = m_bindings['N' - '@'] = std::tr1::bind(&ElementFileList::receive_next, this);
|
||||
m_bindings[KEY_UP] = m_bindings['P' - '@'] = std::tr1::bind(&ElementFileList::receive_prev, this);
|
||||
}
|
||||
|
||||
inline ElementText*
|
||||
@@ -118,7 +117,7 @@ ElementFileList::activate(display::Frame* frame, bool focus) {
|
||||
m_window->set_focused(focus);
|
||||
|
||||
m_elementInfo = element_file_list_create_info();
|
||||
m_elementInfo->slot_exit(sigc::bind(sigc::mem_fun(this, &ElementFileList::activate_display), DISPLAY_LIST));
|
||||
m_elementInfo->slot_exit(std::tr1::bind(&ElementFileList::activate_display, this, DISPLAY_LIST));
|
||||
m_elementInfo->set_target(rpc::make_target(&m_selected));
|
||||
|
||||
m_frame = frame;
|
||||
|
||||
@@ -72,11 +72,11 @@ ElementMenu::ElementMenu() :
|
||||
m_entry(entry_invalid) {
|
||||
|
||||
// Move bindings into a function that defines default bindings.
|
||||
m_bindings[KEY_LEFT] = m_bindings['B' - '@'] = sigc::mem_fun(&m_slotExit, &slot_type::operator());
|
||||
m_bindings[KEY_RIGHT] = m_bindings['F' - '@'] = sigc::mem_fun(this, &ElementMenu::entry_select);
|
||||
m_bindings[KEY_LEFT] = m_bindings['B' - '@'] = std::tr1::bind(&slot_type::operator(), &m_slot_exit);
|
||||
m_bindings[KEY_RIGHT] = m_bindings['F' - '@'] = std::tr1::bind(&ElementMenu::entry_select, this);
|
||||
|
||||
m_bindings[KEY_UP] = m_bindings['P' - '@'] = sigc::mem_fun(this, &ElementMenu::entry_prev);
|
||||
m_bindings[KEY_DOWN] = m_bindings['N' - '@'] = sigc::mem_fun(this, &ElementMenu::entry_next);
|
||||
m_bindings[KEY_UP] = m_bindings['P' - '@'] = std::tr1::bind(&ElementMenu::entry_prev, this);
|
||||
m_bindings[KEY_DOWN] = m_bindings['N' - '@'] = std::tr1::bind(&ElementMenu::entry_next, this);
|
||||
}
|
||||
|
||||
ElementMenu::~ElementMenu() {
|
||||
|
||||
@@ -37,8 +37,6 @@
|
||||
#ifndef RTORRENT_UI_ELEMENT_MENU_H
|
||||
#define RTORRENT_UI_ELEMENT_MENU_H
|
||||
|
||||
#include <sigc++/functors/slot.h>
|
||||
|
||||
#include "core/download.h"
|
||||
|
||||
#include "element_base.h"
|
||||
@@ -53,14 +51,13 @@ namespace ui {
|
||||
struct ElementMenuEntry {
|
||||
display::TextElementStringBase* m_element;
|
||||
|
||||
sigc::slot0<void> m_slotFocus;
|
||||
sigc::slot0<void> m_slotSelect;
|
||||
std::tr1::function<void ()> m_slotFocus;
|
||||
std::tr1::function<void ()> m_slotSelect;
|
||||
};
|
||||
|
||||
class ElementMenu : public ElementBase, public std::vector<ElementMenuEntry> {
|
||||
public:
|
||||
typedef std::vector<ElementMenuEntry> base_type;
|
||||
typedef sigc::slot0<void> slot_type;
|
||||
|
||||
typedef display::WindowText WindowText;
|
||||
|
||||
|
||||
+18
-13
@@ -36,7 +36,6 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <sigc++/adaptors/bind.h>
|
||||
#include <torrent/exceptions.h>
|
||||
#include <torrent/rate.h>
|
||||
#include <torrent/hash_string.h>
|
||||
@@ -65,27 +64,33 @@ ElementPeerList::ElementPeerList(core::Download* d) :
|
||||
std::for_each(m_download->download()->connection_list()->begin(), m_download->download()->connection_list()->end(),
|
||||
rak::bind1st(std::mem_fun<void,PList,PList::const_reference>(&PList::push_back), &m_list));
|
||||
|
||||
m_connPeerConnected = m_download->download()->connection_list()->signal_connected().connect(sigc::mem_fun(*this, &ElementPeerList::receive_peer_connected));
|
||||
m_connPeerDisconnected = m_download->download()->connection_list()->signal_disconnected().connect(sigc::mem_fun(*this, &ElementPeerList::receive_peer_disconnected));
|
||||
torrent::ConnectionList* connection_list = m_download->download()->connection_list();
|
||||
|
||||
m_peer_connected = connection_list->signal_connected().insert(connection_list->signal_connected().end(),
|
||||
tr1::bind(&ElementPeerList::receive_peer_connected, this, tr1::placeholders::_1));
|
||||
m_peer_disconnected = connection_list->signal_disconnected().insert(connection_list->signal_disconnected().end(),
|
||||
tr1::bind(&ElementPeerList::receive_peer_disconnected, this, tr1::placeholders::_1));
|
||||
|
||||
m_windowList = new display::WindowPeerList(m_download, &m_list, &m_listItr);
|
||||
m_elementInfo = create_info();
|
||||
|
||||
m_elementInfo->slot_exit(sigc::bind(sigc::mem_fun(this, &ElementPeerList::activate_display), DISPLAY_LIST));
|
||||
m_elementInfo->slot_exit(std::tr1::bind(&ElementPeerList::activate_display, this, DISPLAY_LIST));
|
||||
|
||||
m_bindings['k'] = sigc::mem_fun(this, &ElementPeerList::receive_disconnect_peer);
|
||||
m_bindings['*'] = sigc::mem_fun(this, &ElementPeerList::receive_snub_peer);
|
||||
m_bindings['B'] = sigc::mem_fun(this, &ElementPeerList::receive_ban_peer);
|
||||
m_bindings[KEY_LEFT] = m_bindings['B' - '@'] = sigc::mem_fun(&m_slotExit, &slot_type::operator());
|
||||
m_bindings[KEY_RIGHT] = m_bindings['F' - '@'] = sigc::bind(sigc::mem_fun(this, &ElementPeerList::activate_display), DISPLAY_INFO);
|
||||
m_bindings['k'] = std::tr1::bind(&ElementPeerList::receive_disconnect_peer, this);
|
||||
m_bindings['*'] = std::tr1::bind(&ElementPeerList::receive_snub_peer, this);
|
||||
m_bindings['B'] = std::tr1::bind(&ElementPeerList::receive_ban_peer, this);
|
||||
m_bindings[KEY_LEFT] = m_bindings['B' - '@'] = std::tr1::bind(&slot_type::operator(), &m_slot_exit);
|
||||
m_bindings[KEY_RIGHT] = m_bindings['F' - '@'] = std::tr1::bind(&ElementPeerList::activate_display, this, DISPLAY_INFO);
|
||||
|
||||
m_bindings[KEY_UP] = m_bindings['P' - '@'] = sigc::mem_fun(this, &ElementPeerList::receive_prev);
|
||||
m_bindings[KEY_DOWN] = m_bindings['N' - '@'] = sigc::mem_fun(this, &ElementPeerList::receive_next);
|
||||
m_bindings[KEY_UP] = m_bindings['P' - '@'] = std::tr1::bind(&ElementPeerList::receive_prev, this);
|
||||
m_bindings[KEY_DOWN] = m_bindings['N' - '@'] = std::tr1::bind(&ElementPeerList::receive_next, this);
|
||||
}
|
||||
|
||||
ElementPeerList::~ElementPeerList() {
|
||||
m_connPeerConnected.disconnect();
|
||||
m_connPeerDisconnected.disconnect();
|
||||
torrent::ConnectionList* connection_list = m_download->download()->connection_list();
|
||||
|
||||
connection_list->signal_connected().erase(m_peer_connected);
|
||||
connection_list->signal_disconnected().erase(m_peer_disconnected);
|
||||
|
||||
delete m_windowList;
|
||||
delete m_elementInfo;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user