mirror of
https://github.com/rakshasa/rtorrent.git
synced 2026-10-14 21:26:17 +00:00
Merge branch 'master' into ipv6
This commit is contained in:
+20
@@ -0,0 +1,20 @@
|
|||||||
|
language: cpp
|
||||||
|
compiler:
|
||||||
|
- gcc
|
||||||
|
- clang
|
||||||
|
|
||||||
|
before_install:
|
||||||
|
- sudo add-apt-repository --yes ppa:ubuntu-toolchain-r/test
|
||||||
|
- sudo apt-get update -qq
|
||||||
|
- sudo apt-get build-dep rtorrent libtorrent-dev
|
||||||
|
|
||||||
|
- if [ "$CXX" = "g++" ]; then sudo apt-get install -qq g++-4.7; fi
|
||||||
|
- if [ "$CXX" = "g++" ]; then export CXX="g++-4.7" CC="gcc-4.7"; fi
|
||||||
|
|
||||||
|
# prevent `macro `AM_PATH_CPPUNIT' not found in library` in `autogen.sh`
|
||||||
|
- sudo apt-get install libcppunit-dev
|
||||||
|
|
||||||
|
- git clone https://github.com/rakshasa/libtorrent.git && cd libtorrent && ./autogen.sh && ./configure && make -j12 && sudo make install && cd ..
|
||||||
|
|
||||||
|
# Figure out how to fix the issue running 'make check'.
|
||||||
|
script: ./autogen.sh && ./configure && make -j12 && sudo make install
|
||||||
+5
-4
@@ -1,6 +1,6 @@
|
|||||||
AC_INIT(rtorrent, 0.9.4, sundell.software@gmail.com)
|
AC_INIT(rtorrent, 0.9.6, sundell.software@gmail.com)
|
||||||
|
|
||||||
AC_DEFINE(API_VERSION, 8, api version)
|
AC_DEFINE(API_VERSION, 9, api version)
|
||||||
|
|
||||||
AM_INIT_AUTOMAKE
|
AM_INIT_AUTOMAKE
|
||||||
AC_CONFIG_HEADERS(config.h)
|
AC_CONFIG_HEADERS(config.h)
|
||||||
@@ -44,9 +44,10 @@ PKG_CHECK_MODULES([libcurl], libcurl >= 7.15.4,
|
|||||||
CXXFLAGS="$CXXFLAGS $libcurl_CFLAGS";
|
CXXFLAGS="$CXXFLAGS $libcurl_CFLAGS";
|
||||||
LIBS="$LIBS $libcurl_LIBS")
|
LIBS="$LIBS $libcurl_LIBS")
|
||||||
|
|
||||||
PKG_CHECK_MODULES([libtorrent], libtorrent >= 0.13.4,
|
PKG_CHECK_MODULES([libtorrent], libtorrent >= 0.13.6,
|
||||||
CXXFLAGS="$CXXFLAGS $libtorrent_CFLAGS";
|
CXXFLAGS="$CXXFLAGS $libtorrent_CFLAGS";
|
||||||
LIBS="$LIBS $libtorrent_LIBS")
|
LIBS="$LIBS $libtorrent_LIBS",
|
||||||
|
[AC_MSG_ERROR([libtorrent >= 0.13.6 not found. Install from https://github.com/rakshasa/libtorrent.git])])
|
||||||
|
|
||||||
AC_LANG_PUSH(C++)
|
AC_LANG_PUSH(C++)
|
||||||
TORRENT_WITH_XMLRPC_C
|
TORRENT_WITH_XMLRPC_C
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#/bin/bash
|
#/bin/bash
|
||||||
gnuplot << EOF
|
gnuplot << EOF
|
||||||
|
|
||||||
set terminal png size 1024,768 enhanced
|
set terminal png size 1024 * 1, 768 enhanced
|
||||||
set xdata time
|
set xdata time
|
||||||
set timefmt "%s"
|
set timefmt "%s"
|
||||||
set format x "%H:%M"
|
set format x "%H:%M"
|
||||||
@@ -14,17 +14,17 @@ set format y2 "%.0f"
|
|||||||
|
|
||||||
set output "output_$1_incore_sync.png"
|
set output "output_$1_incore_sync.png"
|
||||||
plot \
|
plot \
|
||||||
"instrumentation_mincore.log.$1" using 1:6 title 'success' smooth sbezier with lines lw 4 axis x1y1,\
|
"instrumentation_mincore.log.$1" using 1:6 title 'success' 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:7 title 'failed' 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:8 title 'not synced' with lines lw 4 axis x1y2,\
|
||||||
"instrumentation_mincore.log.$1" using 1:9 title 'not deallocated' smooth sbezier with lines lw 4 axis x1y2
|
"instrumentation_mincore.log.$1" using 1:9 title 'not deallocated' with lines lw 4 axis x1y2
|
||||||
|
|
||||||
set format y "%.0g"
|
set format y "%.0g"
|
||||||
|
|
||||||
set output "output_$1_incore_alloc.png"
|
set output "output_$1_incore_alloc.png"
|
||||||
plot \
|
plot \
|
||||||
"instrumentation_mincore.log.$1" using 1:12 title 'allocations' smooth sbezier with lines lw 2 axis x1y1,\
|
"instrumentation_mincore.log.$1" using 1:12 title 'allocations' 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:13 title 'deallocations' with lines lw 4 axis x1y1,\
|
||||||
"instrumentation_mincore.log.$1" using 1:10 title 'alloc failed' smooth sbezier with lines lw 2 axis x1y2
|
"instrumentation_mincore.log.$1" using 1:10 title 'alloc failed' with lines lw 2 axis x1y2
|
||||||
|
|
||||||
EOF
|
EOF
|
||||||
+46
-27
@@ -3,61 +3,76 @@
|
|||||||
# uncomment the options you wish to enable.
|
# uncomment the options you wish to enable.
|
||||||
|
|
||||||
# Maximum and minimum number of peers to connect to per torrent.
|
# Maximum and minimum number of peers to connect to per torrent.
|
||||||
#min_peers = 40
|
#
|
||||||
#max_peers = 100
|
#throttle.min_peers.normal.set = 40
|
||||||
|
#throttle.max_peers.normal.set = 100
|
||||||
|
|
||||||
# Same as above but for seeding completed torrents (-1 = same as downloading)
|
# Same as above but for seeding completed torrents (-1 = same as downloading)
|
||||||
#min_peers_seed = 10
|
#
|
||||||
#max_peers_seed = 50
|
#throttle.min_peers.seed.set = 10
|
||||||
|
#throttle.max_peers.seed.set = 50
|
||||||
|
|
||||||
# Maximum number of simultanious uploads per torrent.
|
# Maximum number of simultanious uploads per torrent.
|
||||||
#max_uploads = 15
|
#
|
||||||
|
#throttle.max_uploads.set = 15
|
||||||
|
|
||||||
# Global upload and download rate in KiB. "0" for unlimited.
|
# Global upload and download rate in KiB. "0" for unlimited.
|
||||||
#download_rate = 0
|
#
|
||||||
#upload_rate = 0
|
#throttle.global_down.max_rate.set_kb = 0
|
||||||
|
#throttle.global_up.max_rate.set_kb = 0
|
||||||
|
|
||||||
# Default directory to save the downloaded torrents.
|
# Default directory to save the downloaded torrents.
|
||||||
#directory = ./
|
#
|
||||||
|
#directory.default.set = ./
|
||||||
|
|
||||||
# Default session directory. Make sure you don't run multiple instance
|
# Default session directory. Make sure you don't run multiple instance
|
||||||
# of rtorrent using the same session directory. Perhaps using a
|
# of rtorrent using the same session directory. Perhaps using a
|
||||||
# relative path?
|
# relative path?
|
||||||
#session = ./session
|
#
|
||||||
|
#session.path.set = ./session
|
||||||
|
|
||||||
# Watch a directory for new torrents, and stop those that have been
|
# Watch a directory for new torrents, and stop those that have been
|
||||||
# deleted.
|
# deleted.
|
||||||
#schedule = watch_directory,5,5,load_start=./watch/*.torrent
|
#
|
||||||
#schedule = untied_directory,5,5,stop_untied=
|
#schedule2 = watch_directory,5,5,load.start=./watch/*.torrent
|
||||||
|
#schedule2 = untied_directory,5,5,stop_untied=
|
||||||
|
|
||||||
# Close torrents when diskspace is low.
|
# Close torrents when diskspace is low.
|
||||||
#schedule = low_diskspace,5,60,close_low_diskspace=100M
|
#
|
||||||
|
#schedule2 = low_diskspace,5,60,close_low_diskspace=100M
|
||||||
|
|
||||||
# The ip address reported to the tracker.
|
# The ip address reported to the tracker.
|
||||||
#ip = 127.0.0.1
|
#
|
||||||
#ip = rakshasa.no
|
#network.local_address.set = 127.0.0.1
|
||||||
|
#network.local_address.set = rakshasa.no
|
||||||
|
|
||||||
# The ip address the listening socket and outgoing connections is
|
# The ip address the listening socket and outgoing connections is
|
||||||
# bound to.
|
# bound to.
|
||||||
#bind = 127.0.0.1
|
#
|
||||||
#bind = rakshasa.no
|
#network.bind_address.set = 127.0.0.1
|
||||||
|
#network.bind_address.set = rakshasa.no
|
||||||
|
|
||||||
# Port range to use for listening.
|
# Port range to use for listening.
|
||||||
#port_range = 6890-6999
|
#
|
||||||
|
#network.port_range.set = 6890-6999
|
||||||
|
|
||||||
# Start opening ports at a random position within the port range.
|
# Start opening ports at a random position within the port range.
|
||||||
#port_random = no
|
#
|
||||||
|
#network.port_random.set = no
|
||||||
|
|
||||||
# Check hash for finished torrents. Might be usefull until the bug is
|
# Check hash for finished torrents. Might be usefull until the bug is
|
||||||
# fixed that causes lack of diskspace not to be properly reported.
|
# fixed that causes lack of diskspace not to be properly reported.
|
||||||
#check_hash = no
|
#
|
||||||
|
#pieces.hash.on_completion.set = no
|
||||||
|
|
||||||
# Set whether the client should try to connect to UDP trackers.
|
# Set whether the client should try to connect to UDP trackers.
|
||||||
#use_udp_trackers = yes
|
#
|
||||||
|
#trackers.use_udp.set = yes
|
||||||
|
|
||||||
# Alternative calls to bind and ip that should handle dynamic ip's.
|
# Alternative calls to bind and ip that should handle dynamic ip's.
|
||||||
#schedule = ip_tick,0,1800,ip=rakshasa
|
#
|
||||||
#schedule = bind_tick,0,1800,bind=rakshasa
|
#schedule2 = ip_tick,0,1800,ip=rakshasa
|
||||||
|
#schedule2 = bind_tick,0,1800,bind=rakshasa
|
||||||
|
|
||||||
# Encryption options, set to none (default) or any combination of the following:
|
# Encryption options, set to none (default) or any combination of the following:
|
||||||
# allow_incoming, try_outgoing, require, require_RC4, enable_retry, prefer_plaintext
|
# allow_incoming, try_outgoing, require, require_RC4, enable_retry, prefer_plaintext
|
||||||
@@ -66,19 +81,23 @@
|
|||||||
# outgoing connections but retries with encryption if they fail, preferring
|
# outgoing connections but retries with encryption if they fail, preferring
|
||||||
# plaintext to RC4 encryption after the encrypted handshake
|
# plaintext to RC4 encryption after the encrypted handshake
|
||||||
#
|
#
|
||||||
# encryption = allow_incoming,enable_retry,prefer_plaintext
|
# protocol.encryption.set = allow_incoming,enable_retry,prefer_plaintext
|
||||||
|
|
||||||
# Enable DHT support for trackerless torrents or when all trackers are down.
|
# Enable DHT support for trackerless torrents or when all trackers are down.
|
||||||
# May be set to "disable" (completely disable DHT), "off" (do not start DHT),
|
# May be set to "disable" (completely disable DHT), "off" (do not start DHT),
|
||||||
# "auto" (start and stop DHT as needed), or "on" (start DHT immediately).
|
# "auto" (start and stop DHT as needed), or "on" (start DHT immediately).
|
||||||
# The default is "off". For DHT to work, a session directory must be defined.
|
# The default is "off". For DHT to work, a session directory must be defined.
|
||||||
#
|
#
|
||||||
# dht = auto
|
# dht.mode.set = auto
|
||||||
|
|
||||||
# UDP port to use for DHT.
|
# UDP port to use for DHT.
|
||||||
#
|
#
|
||||||
# dht_port = 6881
|
#dht.port.set = 6881
|
||||||
|
|
||||||
# Enable peer exchange (for torrents not marked private)
|
# Enable peer exchange (for torrents not marked private)
|
||||||
#
|
#
|
||||||
# peer_exchange = yes
|
#protocol.pex.set = yes
|
||||||
|
|
||||||
|
# Set downlad list layout style. ("full", "compact")
|
||||||
|
#
|
||||||
|
#torrent_list_layout = "full"
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ foreach my $f (0..$#files) {
|
|||||||
my $mtime = (stat "$d$files[$f]")[9];
|
my $mtime = (stat "$d$files[$f]")[9];
|
||||||
|
|
||||||
# Compute number of chunks per file
|
# Compute number of chunks per file
|
||||||
my $fsize = $t->{info}{files}[$f]{length};
|
my $fsize = (exists $t->{info}{files}) ? $t->{info}{files}[$f]{length} : 1;
|
||||||
my $fchunks = ($pmod ? 1 : 0);
|
my $fchunks = ($pmod ? 1 : 0);
|
||||||
if ($pmod >= $fsize) { ($fsize, $pmod ) = (0, $pmod-$fsize); }
|
if ($pmod >= $fsize) { ($fsize, $pmod ) = (0, $pmod-$fsize); }
|
||||||
else { ($pmod, $fsize) = (0, $fsize-$pmod); }
|
else { ($pmod, $fsize) = (0, $fsize-$pmod); }
|
||||||
@@ -101,7 +101,10 @@ foreach my $f (0..$#files) {
|
|||||||
$t->{libtorrent_resume}{'uncertain_pieces.timestamp'} = time;
|
$t->{libtorrent_resume}{'uncertain_pieces.timestamp'} = time;
|
||||||
|
|
||||||
# Some extra information to re-enforce the fact that this is a finished torrent
|
# Some extra information to re-enforce the fact that this is a finished torrent
|
||||||
$d .= $t->{info}{name};
|
if (exists $t->{info}{files}) {
|
||||||
|
$d .= $t->{info}{name};
|
||||||
|
}
|
||||||
|
|
||||||
$t->{rtorrent} = {
|
$t->{rtorrent} = {
|
||||||
state => 1, # started
|
state => 1, # started
|
||||||
state_changed => time,
|
state_changed => time,
|
||||||
|
|||||||
Executable
+164
@@ -0,0 +1,164 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
#############
|
||||||
|
###<Notes>###
|
||||||
|
#############
|
||||||
|
# This script depends on screen.
|
||||||
|
# For the stop function to work, you must set an
|
||||||
|
# explicit session directory using absolute paths (no, ~ is not absolute) in your rtorrent.rc.
|
||||||
|
# If you typically just start rtorrent with just "rtorrent" on the
|
||||||
|
# command line, all you need to change is the "user" option.
|
||||||
|
# Attach to the screen session as your user with
|
||||||
|
# "screen -dr rtorrent". Change "rtorrent" with srnname option.
|
||||||
|
# Licensed under the GPLv2 by lostnihilist: lostnihilist _at_ gmail _dot_ com
|
||||||
|
##############
|
||||||
|
###</Notes>###
|
||||||
|
##############
|
||||||
|
|
||||||
|
#######################
|
||||||
|
##Start Configuration##
|
||||||
|
#######################
|
||||||
|
# You can specify your configuration in a different file
|
||||||
|
# (so that it is saved with upgrades, saved in your home directory,
|
||||||
|
# or whatever reason you want to)
|
||||||
|
# by commenting out/deleting the configuration lines and placing them
|
||||||
|
# in a text file (say /home/user/.rtorrent.init.conf) exactly as you would
|
||||||
|
# have written them here (you can leave the comments if you desire
|
||||||
|
# and then uncommenting the following line correcting the path/filename
|
||||||
|
# for the one you used. note the space after the ".".
|
||||||
|
# . /etc/rtorrent.init.conf
|
||||||
|
|
||||||
|
|
||||||
|
#Do not put a space on either side of the equal signs e.g.
|
||||||
|
# user = user
|
||||||
|
# will not work
|
||||||
|
# system user to run as (can only use one)
|
||||||
|
user="user"
|
||||||
|
|
||||||
|
# system user to run as # not implemented, see d_start for beginning implementation
|
||||||
|
# group=$(id -ng "$user")
|
||||||
|
|
||||||
|
# the full path to the filename where you store your rtorrent configuration
|
||||||
|
# must keep parentheses around the entire statement, quotations around each config file
|
||||||
|
config=("$(su -c 'echo $HOME' $user)/.rtorrent.rc")
|
||||||
|
# Examples:
|
||||||
|
# config=("/home/user/.rtorrent.rc")
|
||||||
|
# config=("/home/user/.rtorrent.rc" "/mnt/some/drive/.rtorrent2.rc")
|
||||||
|
# config=("/home/user/.rtorrent.rc"
|
||||||
|
# "/mnt/some/drive/.rtorrent2.rc"
|
||||||
|
# "/mnt/another/drive/.rtorrent3.rc")
|
||||||
|
|
||||||
|
# set of options to run with each instance, separated by a new line
|
||||||
|
# must keep parentheses around the entire statement
|
||||||
|
#if no special options, specify with: ""
|
||||||
|
options=("")
|
||||||
|
# Examples:
|
||||||
|
# starts one instance, sourcing both .rtorrent.rc and .rtorrent2.rc
|
||||||
|
# options=("-o import=~/.rtorrent2.rc")
|
||||||
|
# starts two instances, ignoring .rtorrent.rc for both, and using
|
||||||
|
# .rtorrent2.rc for the first, and .rtorrent3.rc for the second
|
||||||
|
# we do not check for valid options
|
||||||
|
# options=("-n -o import=~/.rtorrent2.rc" "-n -o import=~/rtorrent3.rc")
|
||||||
|
|
||||||
|
# default directory for screen, needs to be an absolute path
|
||||||
|
base=$(su -c 'echo $HOME' $user)
|
||||||
|
|
||||||
|
# name of screen session
|
||||||
|
srnname="rtorrent"
|
||||||
|
|
||||||
|
# file to log to (makes for easier debugging if something goes wrong)
|
||||||
|
logfile="/var/log/rtorrentInit.log"
|
||||||
|
#######################
|
||||||
|
###END CONFIGURATION###
|
||||||
|
#######################
|
||||||
|
|
||||||
|
PATH=/usr/bin:/usr/local/bin:/usr/local/sbin:/sbin:/bin:/usr/sbin
|
||||||
|
DESC="rtorrent"
|
||||||
|
NAME=rtorrent
|
||||||
|
DAEMON=$NAME
|
||||||
|
SCRIPTNAME=/etc/init.d/$NAME
|
||||||
|
|
||||||
|
checkcnfg() {
|
||||||
|
exists=0
|
||||||
|
for i in `echo "$PATH" | tr ':' '\n'` ; do
|
||||||
|
if [ -f $i/$NAME ] ; then
|
||||||
|
exists=1
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
if [ $exists -eq 0 ] ; then
|
||||||
|
echo "cannot find $NAME binary in PATH: $PATH" | tee -a "$logfile" >&2
|
||||||
|
exit 3
|
||||||
|
fi
|
||||||
|
for (( i=0 ; i < ${#config[@]} ; i++ )) ; do
|
||||||
|
if ! [ -r "${config[i]}" ] ; then
|
||||||
|
echo "cannot find readable config ${config[i]}. check that it is there and permissions are appropriate" | tee -a "$logfile" >&2
|
||||||
|
exit 3
|
||||||
|
fi
|
||||||
|
session=$(getsession "${config[i]}")
|
||||||
|
if ! [ -d "${session}" ] ; then
|
||||||
|
echo "cannot find readable session directory ${session} from config ${config[i]}. check permissions" | tee -a "$logfile" >&2
|
||||||
|
exit 3
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
d_start() {
|
||||||
|
[ -d "${base}" ] && cd "${base}"
|
||||||
|
stty stop undef && stty start undef
|
||||||
|
su -c "screen -S "${srnname}" -X screen rtorrent ${options} 2>&1 1>/dev/null" ${user} | tee -a "$logfile" >&2
|
||||||
|
# this works for the screen command, but starting rtorrent below adopts screen session gid
|
||||||
|
# even if it is not the screen session we started (e.g. running under an undesirable gid
|
||||||
|
#su -c "screen -ls | grep -sq "\.${srnname}[[:space:]]" " ${user} || su -c "sg \"$group\" -c \"screen -fn -dm -S ${srnname} 2>&1 1>/dev/null\"" ${user} | tee -a "$logfile" >&2
|
||||||
|
for (( i=0 ; i < ${#options[@]} ; i++ )) ; do
|
||||||
|
sleep 3
|
||||||
|
su -c "screen -S "${srnname}" -X screen rtorrent ${options[i]} 2>&1 1>/dev/null" ${user} | tee -a "$logfile" >&2
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
d_stop() {
|
||||||
|
for (( i=0 ; i < ${#config[@]} ; i++ )) ; do
|
||||||
|
session=$(getsession "${config[i]}")
|
||||||
|
if ! [ -s ${session}/rtorrent.lock ] ; then
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
pid=$(cat ${session}/rtorrent.lock | awk -F: '{print($2)}' | sed "s/[^0-9]//g")
|
||||||
|
# make sure the pid doesn't belong to another process
|
||||||
|
if ps -A | grep -sq ${pid}.*rtorrent ; then
|
||||||
|
kill -s INT ${pid}
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
getsession() {
|
||||||
|
session=$(cat "$1" | grep "^[[:space:]]*session[[:space:]]*=" | sed "s/^[[:space:]]*session[[:space:]]*=[[:space:]]*//" )
|
||||||
|
#session=${session/#~/`getent passwd ${user}|cut -d: -f6`}
|
||||||
|
echo $session
|
||||||
|
}
|
||||||
|
|
||||||
|
checkcnfg
|
||||||
|
|
||||||
|
case "$1" in
|
||||||
|
start)
|
||||||
|
echo -n "Starting $DESC: $NAME"
|
||||||
|
d_start
|
||||||
|
echo "."
|
||||||
|
;;
|
||||||
|
stop)
|
||||||
|
echo -n "Stopping $DESC: $NAME"
|
||||||
|
d_stop
|
||||||
|
echo "."
|
||||||
|
;;
|
||||||
|
restart|force-reload)
|
||||||
|
echo -n "Restarting $DESC: $NAME"
|
||||||
|
d_stop
|
||||||
|
sleep 1
|
||||||
|
d_start
|
||||||
|
echo "."
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Usage: $SCRIPTNAME {start|stop|restart|force-reload}" >&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
exit 0
|
||||||
Executable
+137
@@ -0,0 +1,137 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
#############
|
||||||
|
###<Notes>###
|
||||||
|
#############
|
||||||
|
# This script depends on screen.
|
||||||
|
# For the stop function to work, you must set an
|
||||||
|
# explicit session directory using ABSOLUTE paths (no, ~ is not absolute) in your rtorrent.rc.
|
||||||
|
# If you typically just start rtorrent with just "rtorrent" on the
|
||||||
|
# command line, all you need to change is the "user" option.
|
||||||
|
# Attach to the screen session as your user with
|
||||||
|
# "screen -dr rtorrent". Change "rtorrent" with srnname option.
|
||||||
|
# Licensed under the GPLv2 by lostnihilist: lostnihilist _at_ gmail _dot_ com
|
||||||
|
##############
|
||||||
|
###</Notes>###
|
||||||
|
##############
|
||||||
|
|
||||||
|
#######################
|
||||||
|
##Start Configuration##
|
||||||
|
#######################
|
||||||
|
# You can specify your configuration in a different file
|
||||||
|
# (so that it is saved with upgrades, saved in your home directory,
|
||||||
|
# or whateve reason you want to)
|
||||||
|
# by commenting out/deleting the configuration lines and placing them
|
||||||
|
# in a text file (say /home/user/.rtorrent.init.conf) exactly as you would
|
||||||
|
# have written them here (you can leave the comments if you desire
|
||||||
|
# and then uncommenting the following line correcting the path/filename
|
||||||
|
# for the one you used. note the space after the ".".
|
||||||
|
# . /etc/rtorrent.init.conf
|
||||||
|
|
||||||
|
#Do not put a space on either side of the equal signs e.g.
|
||||||
|
# user = user
|
||||||
|
# will not work
|
||||||
|
# system user to run as
|
||||||
|
user="user"
|
||||||
|
|
||||||
|
# the system group to run as, not implemented, see d_start for beginning implementation
|
||||||
|
# group=`id -ng "$user"`
|
||||||
|
|
||||||
|
# the full path to the filename where you store your rtorrent configuration
|
||||||
|
config="`su -c 'echo $HOME' $user`/.rtorrent.rc"
|
||||||
|
|
||||||
|
# set of options to run with
|
||||||
|
options=""
|
||||||
|
|
||||||
|
# default directory for screen, needs to be an absolute path
|
||||||
|
base="`su -c 'echo $HOME' $user`"
|
||||||
|
|
||||||
|
# name of screen session
|
||||||
|
srnname="rtorrent"
|
||||||
|
|
||||||
|
# file to log to (makes for easier debugging if something goes wrong)
|
||||||
|
logfile="/var/log/rtorrentInit.log"
|
||||||
|
#######################
|
||||||
|
###END CONFIGURATION###
|
||||||
|
#######################
|
||||||
|
PATH=/usr/bin:/usr/local/bin:/usr/local/sbin:/sbin:/bin:/usr/sbin
|
||||||
|
DESC="rtorrent"
|
||||||
|
NAME=rtorrent
|
||||||
|
DAEMON=$NAME
|
||||||
|
SCRIPTNAME=/etc/init.d/$NAME
|
||||||
|
|
||||||
|
checkcnfg() {
|
||||||
|
exists=0
|
||||||
|
for i in `echo "$PATH" | tr ':' '\n'` ; do
|
||||||
|
if [ -f $i/$NAME ] ; then
|
||||||
|
exists=1
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
if [ $exists -eq 0 ] ; then
|
||||||
|
echo "cannot find rtorrent binary in PATH $PATH" | tee -a "$logfile" >&2
|
||||||
|
exit 3
|
||||||
|
fi
|
||||||
|
if ! [ -r "${config}" ] ; then
|
||||||
|
echo "cannot find readable config ${config}. check that it is there and permissions are appropriate" | tee -a "$logfile" >&2
|
||||||
|
exit 3
|
||||||
|
fi
|
||||||
|
session=`getsession "$config"`
|
||||||
|
if ! [ -d "${session}" ] ; then
|
||||||
|
echo "cannot find readable session directory ${session} from config ${config}. check permissions" | tee -a "$logfile" >&2
|
||||||
|
exit 3
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
d_start() {
|
||||||
|
[ -d "${base}" ] && cd "${base}"
|
||||||
|
stty stop undef && stty start undef
|
||||||
|
su -c "screen -ls | grep -sq "\.${srnname}[[:space:]]" " ${user} || su -c "screen -dm -S ${srnname} 2>&1 1>/dev/null" ${user} | tee -a "$logfile" >&2
|
||||||
|
# this works for the screen command, but starting rtorrent below adopts screen session gid
|
||||||
|
# even if it is not the screen session we started (e.g. running under an undesirable gid
|
||||||
|
#su -c "screen -ls | grep -sq "\.${srnname}[[:space:]]" " ${user} || su -c "sg \"$group\" -c \"screen -fn -dm -S ${srnname} 2>&1 1>/dev/null\"" ${user} | tee -a "$logfile" >&2
|
||||||
|
su -c "screen -S "${srnname}" -X screen rtorrent ${options} 2>&1 1>/dev/null" ${user} | tee -a "$logfile" >&2
|
||||||
|
}
|
||||||
|
|
||||||
|
d_stop() {
|
||||||
|
session=`getsession "$config"`
|
||||||
|
if ! [ -s ${session}/rtorrent.lock ] ; then
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
pid=`cat ${session}/rtorrent.lock | awk -F: '{print($2)}' | sed "s/[^0-9]//g"`
|
||||||
|
if ps -A | grep -sq ${pid}.*rtorrent ; then # make sure the pid doesn't belong to another process
|
||||||
|
kill -s INT ${pid}
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
getsession() {
|
||||||
|
session=`cat "$1" | grep "^[[:space:]]*session[[:space:]]*=" | sed "s/^[[:space:]]*session[[:space:]]*=[[:space:]]*//" `
|
||||||
|
echo $session
|
||||||
|
}
|
||||||
|
|
||||||
|
checkcnfg
|
||||||
|
|
||||||
|
case "$1" in
|
||||||
|
start)
|
||||||
|
echo -n "Starting $DESC: $NAME"
|
||||||
|
d_start
|
||||||
|
echo "."
|
||||||
|
;;
|
||||||
|
stop)
|
||||||
|
echo -n "Stopping $DESC: $NAME"
|
||||||
|
d_stop
|
||||||
|
echo "."
|
||||||
|
;;
|
||||||
|
restart|force-reload)
|
||||||
|
echo -n "Restarting $DESC: $NAME"
|
||||||
|
d_stop
|
||||||
|
sleep 1
|
||||||
|
d_start
|
||||||
|
echo "."
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Usage: $SCRIPTNAME {start|stop|restart|force-reload}" >&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
exit 0
|
||||||
Executable
+166
@@ -0,0 +1,166 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
### BEGIN INIT INFO
|
||||||
|
# Provides: rtorrent_autostart
|
||||||
|
# Required-Start: $local_fs $remote_fs $network $syslog $netdaemons
|
||||||
|
# Required-Stop: $local_fs $remote_fs
|
||||||
|
# Default-Start: 2 3 4 5
|
||||||
|
# Default-Stop: 0 1 6
|
||||||
|
# Short-Description: rtorrent script using tmux
|
||||||
|
# Description: rtorrent script using tmux
|
||||||
|
### END INIT INFO
|
||||||
|
|
||||||
|
#############
|
||||||
|
###<Notes>###
|
||||||
|
#############
|
||||||
|
# This script depends on tmux and is based on 'rtorrentInitScreen.sh' script
|
||||||
|
# with the following enhancements:
|
||||||
|
# - init script 'start' option can be called without breaking anything
|
||||||
|
# - init script 'status' option can be used in scripts to determine whether rtorrent is running or not
|
||||||
|
# - auto removes damaged/stuck 'rtorrent.lock' file if necessary
|
||||||
|
# - saves session (just in case) before stopping with 'rtxmlrp' if it exists
|
||||||
|
# - provides examples how to script tmux windows
|
||||||
|
#
|
||||||
|
# For the stop function to work, you must set an explicit session directory
|
||||||
|
# using ABSOLUTE paths (no, ~ is not absolute) in your rtorrent.rc and with
|
||||||
|
# "sessiondir" option.
|
||||||
|
# If you typically just start rtorrent with just "rtorrent" on the
|
||||||
|
# command line, all you need to change is the "user" and "sessiondir" option.
|
||||||
|
# Attach to the tmux session as your user with
|
||||||
|
# "tmux -2u new-session -A -s rtorrent". Change "rtorrent" with "tmuxname" option.
|
||||||
|
# Licensed under the GPLv2 by lostnihilist: lostnihilist _at_ gmail _dot_ com
|
||||||
|
##############
|
||||||
|
###</Notes>###
|
||||||
|
##############
|
||||||
|
|
||||||
|
#######################
|
||||||
|
##Start Configuration##
|
||||||
|
#######################
|
||||||
|
# You can specify your configuration in a different file.
|
||||||
|
# (so that it is saved with upgrades, saved in your home directory,
|
||||||
|
# or whatever reason you want to)
|
||||||
|
# by commenting out/deleting the configuration lines and placing them
|
||||||
|
# in a text file (say /home/user/.rtorrent.init.conf) exactly as you would
|
||||||
|
# have written them here (you can leave the comments if you desire
|
||||||
|
# and then uncommenting the following line correcting the path/filename.
|
||||||
|
# for the one you used. note the space after the ".".
|
||||||
|
# . /etc/rtorrent.init.conf
|
||||||
|
|
||||||
|
# system user to run as
|
||||||
|
user="username"
|
||||||
|
|
||||||
|
# default directory for tmux, needs to be an absolute path
|
||||||
|
base=$(su -c 'echo $HOME' $user)
|
||||||
|
|
||||||
|
# the full path to the filename where you store your rtorrent configuration
|
||||||
|
config="$base/.rtorrent.rc"
|
||||||
|
|
||||||
|
# the full path to the session directory of rtorrent
|
||||||
|
sessiondir="/mnt/Torrents/.rtorrent/.session"
|
||||||
|
|
||||||
|
# options to pass to rtorrent; e.g. don't read config from $HOME but load alternate
|
||||||
|
#options="-n -O import=$config"
|
||||||
|
options=""
|
||||||
|
|
||||||
|
# name of tmux session
|
||||||
|
tmuxname="rtorrent"
|
||||||
|
|
||||||
|
# name of window in tmux session
|
||||||
|
tmuxwindowname="rT"
|
||||||
|
#######################
|
||||||
|
###END CONFIGURATION###
|
||||||
|
#######################
|
||||||
|
PATH=/usr/bin:/usr/local/bin:/usr/local/sbin:/sbin:/bin:/usr/sbin
|
||||||
|
NAME=rtorrent
|
||||||
|
DAEMON=$NAME
|
||||||
|
SCRIPTNAME=/etc/init.d/$NAME
|
||||||
|
RTXMLRPCBIN="$base/bin/rtxmlrpc"
|
||||||
|
|
||||||
|
|
||||||
|
checkcnfg() {
|
||||||
|
if [ -z "$(which $DAEMON)" ] ; then
|
||||||
|
echo "Cannot find $DAEMON binary in PATH: $PATH"
|
||||||
|
exit 3
|
||||||
|
fi
|
||||||
|
if ! [ -r "$config" ] ; then
|
||||||
|
echo "Cannot find readable config $config. Check that it is there and permissions are appropriate"
|
||||||
|
exit 3
|
||||||
|
fi
|
||||||
|
if ! [ -d "$sessiondir" ] ; then
|
||||||
|
echo "Cannot find readable session directory $sessiondir from config $config. Check permissions"
|
||||||
|
exit 3
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status() {
|
||||||
|
if [ -e "${sessiondir}/rtorrent.lock" ] ; then
|
||||||
|
pid=`cat ${sessiondir}/rtorrent.lock | awk -F: '{print($2)}' | sed "s/[^0-9]//g"`
|
||||||
|
# make sure the pid isn't empty and doesn't belong to another process : this will match lines containing rtorrent, which grep '[r]torrent' does not!
|
||||||
|
# if there is no process as the 'pid' suggests then delete the stuck "rtorrent.lock" file (to be able to start rtorrent)
|
||||||
|
[[ -n "$pid" ]] && ps aux | grep -sq ${pid}.*[r]torrent && echo -e ${pid} || rm -f "${sessiondir}/rtorrent.lock"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
d_start() {
|
||||||
|
[ -d "$base" ] && cd "$base"
|
||||||
|
# if STDIN is a terminal (we are using interactive mode)
|
||||||
|
[ -t 0 ] && stty stop undef && stty start undef
|
||||||
|
# start the default 2 tmux window (bash and mc) if there isn't tmux session called "tmuxname" option (rtorrent)
|
||||||
|
if ! su -c "tmux ls | grep -sq ${tmuxname}: " $user ; then
|
||||||
|
# 1st window (0): split it into 3 panes, display 'date' in the last one
|
||||||
|
su -c "tmux -2u new-session -d -s ${tmuxname} -n 'shell1'" $user
|
||||||
|
su -c "tmux -2u split-window -v -t ${tmuxname}:0 'bash'" $user
|
||||||
|
su -c "tmux -2u split-window -h -t ${tmuxname}:0 'date; bash'" $user
|
||||||
|
# 2nd window (1): start 'mc' if it exists
|
||||||
|
su -c "tmux -2u new-window -t ${tmuxname}:1 -n 'mc1' 'command which mc && mc ~/; bash'" $user
|
||||||
|
fi
|
||||||
|
# start rtorrent always in the 3rd tmux window (2) if it's not running and leave shell behind to be able to see reason of a crash
|
||||||
|
if [ "$(status)" == "" ]; then
|
||||||
|
su -c "tmux -2u list-panes -t ${tmuxname}:2 &>/dev/null && tmux -2u respawn-pane -t ${tmuxname}:2 -k \"${DAEMON} ${options}; bash\" || tmux -2u new-window -t ${tmuxname}:2 -n ${tmuxwindowname} \"${DAEMON} ${options}; bash\"" $user
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
d_stop() {
|
||||||
|
pid=$(status)
|
||||||
|
if [ "$pid" != "" ]; then
|
||||||
|
# save session before stopping explicitly (just in case) if rtxmlrpc util exists then wait for 5 seconds to be able to complete it
|
||||||
|
[ -L "$RTXMLRPCBIN" ] && "$RTXMLRPCBIN" session.save &>/dev/null && sleep 5
|
||||||
|
# INT (2, Interrupt from keyboard): normal shutdown
|
||||||
|
kill -s INT $pid
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
checkcnfg
|
||||||
|
|
||||||
|
|
||||||
|
case "$1" in
|
||||||
|
start)
|
||||||
|
echo -n "Starting $tmuxwindowname: $NAME"
|
||||||
|
d_start
|
||||||
|
echo "."
|
||||||
|
;;
|
||||||
|
stop)
|
||||||
|
echo -n "Stopping $tmuxwindowname: $NAME"
|
||||||
|
d_stop
|
||||||
|
echo "."
|
||||||
|
;;
|
||||||
|
restart|force-reload)
|
||||||
|
echo -n "Restarting $tmuxwindowname: $NAME"
|
||||||
|
d_stop
|
||||||
|
sleep 1
|
||||||
|
d_start
|
||||||
|
echo "."
|
||||||
|
;;
|
||||||
|
status)
|
||||||
|
status
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Usage: $SCRIPTNAME {start|stop|restart|force-reload|status}" >&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
exit 0
|
||||||
@@ -18,6 +18,7 @@ libsub_root_a_SOURCES = \
|
|||||||
command_helpers.h \
|
command_helpers.h \
|
||||||
command_groups.cc \
|
command_groups.cc \
|
||||||
command_local.cc \
|
command_local.cc \
|
||||||
|
command_logging.cc \
|
||||||
command_network.cc \
|
command_network.cc \
|
||||||
command_peer.cc \
|
command_peer.cc \
|
||||||
command_throttle.cc \
|
command_throttle.cc \
|
||||||
|
|||||||
@@ -686,6 +686,7 @@ initialize_command_download() {
|
|||||||
CMD2_DL ("d.is_pex_active", CMD2_ON_INFO(is_pex_active));
|
CMD2_DL ("d.is_pex_active", CMD2_ON_INFO(is_pex_active));
|
||||||
CMD2_DL ("d.is_partially_done", CMD2_ON_DATA(is_partially_done));
|
CMD2_DL ("d.is_partially_done", CMD2_ON_DATA(is_partially_done));
|
||||||
CMD2_DL ("d.is_not_partially_done", CMD2_ON_DATA(is_not_partially_done));
|
CMD2_DL ("d.is_not_partially_done", CMD2_ON_DATA(is_not_partially_done));
|
||||||
|
CMD2_DL ("d.is_meta", CMD2_ON_INFO(is_meta_download));
|
||||||
|
|
||||||
CMD2_DL_V ("d.resume", std::bind(&core::DownloadList::resume_default, control->core()->download_list(), std::placeholders::_1));
|
CMD2_DL_V ("d.resume", std::bind(&core::DownloadList::resume_default, control->core()->download_list(), std::placeholders::_1));
|
||||||
CMD2_DL_V ("d.pause", std::bind(&core::DownloadList::pause_default, control->core()->download_list(), std::placeholders::_1));
|
CMD2_DL_V ("d.pause", std::bind(&core::DownloadList::pause_default, control->core()->download_list(), std::placeholders::_1));
|
||||||
|
|||||||
@@ -247,6 +247,10 @@ system_method_insert(const torrent::Object::list_type& args) {
|
|||||||
|
|
||||||
const std::string& options = itrArgs->as_string();
|
const std::string& options = itrArgs->as_string();
|
||||||
|
|
||||||
|
// TODO: Replace find with a method that does '|' separated search
|
||||||
|
// for all valid options, and then cross-checks that unmixable ones
|
||||||
|
// aren't in there. Use a bitfield.
|
||||||
|
|
||||||
if (options.find("private") != std::string::npos)
|
if (options.find("private") != std::string::npos)
|
||||||
flags &= ~rpc::CommandMap::flag_public_xmlrpc;
|
flags &= ~rpc::CommandMap::flag_public_xmlrpc;
|
||||||
if (options.find("const") != std::string::npos)
|
if (options.find("const") != std::string::npos)
|
||||||
@@ -289,8 +293,7 @@ system_method_insert(const torrent::Object::list_type& args) {
|
|||||||
} else if (options.find("value") != std::string::npos ||
|
} else if (options.find("value") != std::string::npos ||
|
||||||
options.find("bool") != std::string::npos ||
|
options.find("bool") != std::string::npos ||
|
||||||
options.find("string") != std::string::npos ||
|
options.find("string") != std::string::npos ||
|
||||||
options.find("list") != std::string::npos ||
|
options.find("list") != std::string::npos) {
|
||||||
options.find("simple") != std::string::npos) {
|
|
||||||
torrent::Object::list_type new_args;
|
torrent::Object::list_type new_args;
|
||||||
new_args.push_back(rawKey);
|
new_args.push_back(rawKey);
|
||||||
|
|
||||||
|
|||||||
@@ -353,6 +353,7 @@ initialize_command_events() {
|
|||||||
CMD2_ANY_LIST ("load.raw_verbose", std::bind(&apply_load, std::placeholders::_2, core::Manager::create_raw_data));
|
CMD2_ANY_LIST ("load.raw_verbose", std::bind(&apply_load, std::placeholders::_2, core::Manager::create_raw_data));
|
||||||
CMD2_ANY_LIST ("load.raw_start", std::bind(&apply_load, std::placeholders::_2,
|
CMD2_ANY_LIST ("load.raw_start", std::bind(&apply_load, std::placeholders::_2,
|
||||||
core::Manager::create_quiet | core::Manager::create_start | core::Manager::create_raw_data));
|
core::Manager::create_quiet | core::Manager::create_start | core::Manager::create_raw_data));
|
||||||
|
CMD2_ANY_LIST ("load.raw_start_verbose", std::bind(&apply_load, std::placeholders::_2, core::Manager::create_start | core::Manager::create_raw_data));
|
||||||
|
|
||||||
CMD2_ANY_VALUE ("close_low_diskspace", std::bind(&apply_close_low_diskspace, std::placeholders::_2));
|
CMD2_ANY_VALUE ("close_low_diskspace", std::bind(&apply_close_low_diskspace, std::placeholders::_2));
|
||||||
|
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ void initialize_command_file();
|
|||||||
void initialize_command_ip();
|
void initialize_command_ip();
|
||||||
void initialize_command_peer();
|
void initialize_command_peer();
|
||||||
void initialize_command_local();
|
void initialize_command_local();
|
||||||
|
void initialize_command_logging();
|
||||||
void initialize_command_network();
|
void initialize_command_network();
|
||||||
void initialize_command_groups();
|
void initialize_command_groups();
|
||||||
void initialize_command_throttle();
|
void initialize_command_throttle();
|
||||||
@@ -63,6 +64,7 @@ initialize_commands() {
|
|||||||
initialize_command_network();
|
initialize_command_network();
|
||||||
initialize_command_groups();
|
initialize_command_groups();
|
||||||
initialize_command_local();
|
initialize_command_local();
|
||||||
|
initialize_command_logging();
|
||||||
initialize_command_ui();
|
initialize_command_ui();
|
||||||
initialize_command_download();
|
initialize_command_download();
|
||||||
initialize_command_file();
|
initialize_command_file();
|
||||||
|
|||||||
+18
-101
@@ -5,12 +5,12 @@
|
|||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation; either version 2 of the License, or
|
// the Free Software Foundation; either version 2 of the License, or
|
||||||
// (at your option) any later version.
|
// (at your option) any later version.
|
||||||
//
|
//
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License for more details.
|
// GNU General Public License for more details.
|
||||||
//
|
//
|
||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with this program; if not, write to the Free Software
|
// along with this program; if not, write to the Free Software
|
||||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
@@ -48,7 +48,6 @@
|
|||||||
#include <torrent/chunk_manager.h>
|
#include <torrent/chunk_manager.h>
|
||||||
#include <torrent/data/file_manager.h>
|
#include <torrent/data/file_manager.h>
|
||||||
#include <torrent/data/chunk_utils.h>
|
#include <torrent/data/chunk_utils.h>
|
||||||
#include <torrent/utils/log.h>
|
|
||||||
#include <torrent/utils/option_strings.h>
|
#include <torrent/utils/option_strings.h>
|
||||||
|
|
||||||
#include "core/download.h"
|
#include "core/download.h"
|
||||||
@@ -80,39 +79,12 @@ apply_pieces_stats_total_size() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
torrent::Object
|
torrent::Object
|
||||||
apply_log(const torrent::Object::string_type& arg, int logType) {
|
system_env(const torrent::Object::string_type& arg) {
|
||||||
if (rpc::execFile.log_fd() != -1) {
|
if (arg.empty())
|
||||||
switch (logType) {
|
throw torrent::input_error("system.env: Missing variable name.");
|
||||||
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()) {
|
char* val = getenv(arg.c_str());
|
||||||
int logFd = open(rak::path_expand(arg).c_str(), O_WRONLY | O_APPEND | O_CREAT, 0644);
|
return std::string(val ? val : "");
|
||||||
|
|
||||||
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
|
torrent::Object
|
||||||
@@ -163,7 +135,7 @@ check_name(const std::string& str) {
|
|||||||
throw torrent::input_error("Non-alphanumeric characters found.");
|
throw torrent::input_error("Non-alphanumeric characters found.");
|
||||||
|
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
torrent::Object
|
torrent::Object
|
||||||
group_insert(const torrent::Object::list_type& args) {
|
group_insert(const torrent::Object::list_type& args) {
|
||||||
@@ -186,7 +158,7 @@ group_insert(const torrent::Object::list_type& args) {
|
|||||||
|
|
||||||
if (rpc::call_command_value("method.use_intermediate") == 1) {
|
if (rpc::call_command_value("method.use_intermediate") == 1) {
|
||||||
// Deprecated in 0.7.0:
|
// Deprecated in 0.7.0:
|
||||||
|
|
||||||
CMD2_REDIRECT_GENERIC_STR("group." + name + ".view", "group2." + name + ".view");
|
CMD2_REDIRECT_GENERIC_STR("group." + name + ".view", "group2." + name + ".view");
|
||||||
CMD2_REDIRECT_GENERIC_STR("group." + name + ".view.set", "group2." + name + ".view.set");
|
CMD2_REDIRECT_GENERIC_STR("group." + name + ".view.set", "group2." + name + ".view.set");
|
||||||
CMD2_REDIRECT_GENERIC_STR("group." + name + ".ratio.min", "group2." + name + ".ratio.min");
|
CMD2_REDIRECT_GENERIC_STR("group." + name + ".ratio.min", "group2." + name + ".ratio.min");
|
||||||
@@ -198,7 +170,7 @@ group_insert(const torrent::Object::list_type& args) {
|
|||||||
|
|
||||||
} if (rpc::call_command_value("method.use_intermediate") == 2) {
|
} if (rpc::call_command_value("method.use_intermediate") == 2) {
|
||||||
// Deprecated in 0.7.0:
|
// Deprecated in 0.7.0:
|
||||||
|
|
||||||
CMD2_REDIRECT_GENERIC_STR_NO_EXPORT("group." + name + ".view", "group2." + name + ".view");
|
CMD2_REDIRECT_GENERIC_STR_NO_EXPORT("group." + name + ".view", "group2." + name + ".view");
|
||||||
CMD2_REDIRECT_GENERIC_STR_NO_EXPORT("group." + name + ".view.set", "group2." + name + ".view.set");
|
CMD2_REDIRECT_GENERIC_STR_NO_EXPORT("group." + name + ".view.set", "group2." + name + ".view.set");
|
||||||
CMD2_REDIRECT_GENERIC_STR_NO_EXPORT("group." + name + ".ratio.min", "group2." + name + ".ratio.min");
|
CMD2_REDIRECT_GENERIC_STR_NO_EXPORT("group." + name + ".ratio.min", "group2." + name + ".ratio.min");
|
||||||
@@ -212,27 +184,6 @@ group_insert(const torrent::Object::list_type& args) {
|
|||||||
return name;
|
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_use_space = 0x1;
|
||||||
static const int file_print_delim_space = 0x2;
|
static const int file_print_delim_space = 0x2;
|
||||||
|
|
||||||
@@ -264,9 +215,9 @@ torrent::Object
|
|||||||
cmd_file_append(const torrent::Object::list_type& args) {
|
cmd_file_append(const torrent::Object::list_type& args) {
|
||||||
if (args.empty())
|
if (args.empty())
|
||||||
throw torrent::input_error("Invalid number of arguments.");
|
throw torrent::input_error("Invalid number of arguments.");
|
||||||
|
|
||||||
FILE* output = fopen(args.front().as_string().c_str(), "a");
|
FILE* output = fopen(args.front().as_string().c_str(), "a");
|
||||||
|
|
||||||
if (output == NULL)
|
if (output == NULL)
|
||||||
throw torrent::input_error("Could not append to file '" + args.front().as_string() + "': " + rak::error_number::current().c_str());
|
throw torrent::input_error("Could not append to file '" + args.front().as_string() + "': " + rak::error_number::current().c_str());
|
||||||
|
|
||||||
@@ -277,36 +228,6 @@ cmd_file_append(const torrent::Object::list_type& args) {
|
|||||||
return torrent::Object();
|
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(),
|
|
||||||
rak::path_expand(args.back().as_string()).c_str());
|
|
||||||
return torrent::Object();
|
|
||||||
}
|
|
||||||
|
|
||||||
torrent::Object
|
|
||||||
apply_log_open_gz_file(const torrent::Object::list_type& args) {
|
|
||||||
if (args.size() != 2)
|
|
||||||
throw torrent::input_error("Invalid number of arguments.");
|
|
||||||
|
|
||||||
torrent::log_open_gz_file_output(args.front().as_string().c_str(),
|
|
||||||
rak::path_expand(args.back().as_string()).c_str());
|
|
||||||
return torrent::Object();
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
void
|
||||||
initialize_command_local() {
|
initialize_command_local() {
|
||||||
torrent::ChunkManager* chunkManager = torrent::chunk_manager();
|
torrent::ChunkManager* chunkManager = torrent::chunk_manager();
|
||||||
@@ -321,12 +242,12 @@ initialize_command_local() {
|
|||||||
CMD2_VAR_C_STRING("system.client_version", PACKAGE_VERSION);
|
CMD2_VAR_C_STRING("system.client_version", PACKAGE_VERSION);
|
||||||
CMD2_VAR_C_STRING("system.library_version", torrent::version());
|
CMD2_VAR_C_STRING("system.library_version", torrent::version());
|
||||||
CMD2_VAR_VALUE ("system.file.allocate", 0);
|
CMD2_VAR_VALUE ("system.file.allocate", 0);
|
||||||
CMD2_VAR_VALUE ("system.file.max_size", (int64_t)128 << 30);
|
CMD2_VAR_VALUE ("system.file.max_size", (int64_t)512 << 30);
|
||||||
CMD2_VAR_VALUE ("system.file.split_size", -1);
|
CMD2_VAR_VALUE ("system.file.split_size", -1);
|
||||||
CMD2_VAR_STRING ("system.file.split_suffix", ".part");
|
CMD2_VAR_STRING ("system.file.split_suffix", ".part");
|
||||||
|
|
||||||
CMD2_ANY ("system.file_status_cache.size", std::bind(&utils::FileStatusCache::size,
|
CMD2_ANY ("system.file_status_cache.size", std::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", std::bind(&utils::FileStatusCache::prune, control->core()->file_status_cache()));
|
CMD2_ANY_V ("system.file_status_cache.prune", std::bind(&utils::FileStatusCache::prune, control->core()->file_status_cache()));
|
||||||
|
|
||||||
CMD2_VAR_BOOL ("file.prioritize_toc", 0);
|
CMD2_VAR_BOOL ("file.prioritize_toc", 0);
|
||||||
@@ -337,12 +258,16 @@ initialize_command_local() {
|
|||||||
CMD2_ANY ("system.files.closed_counter", std::bind(&FM_t::files_closed_counter, fileManager));
|
CMD2_ANY ("system.files.closed_counter", std::bind(&FM_t::files_closed_counter, fileManager));
|
||||||
CMD2_ANY ("system.files.failed_counter", std::bind(&FM_t::files_failed_counter, fileManager));
|
CMD2_ANY ("system.files.failed_counter", std::bind(&FM_t::files_failed_counter, fileManager));
|
||||||
|
|
||||||
|
CMD2_ANY_STRING ("system.env", std::bind(&system_env, std::placeholders::_2));
|
||||||
|
|
||||||
CMD2_ANY ("system.time", std::bind(&rak::timer::seconds, &cachedTime));
|
CMD2_ANY ("system.time", std::bind(&rak::timer::seconds, &cachedTime));
|
||||||
CMD2_ANY ("system.time_seconds", std::bind(&rak::timer::current_seconds));
|
CMD2_ANY ("system.time_seconds", std::bind(&rak::timer::current_seconds));
|
||||||
CMD2_ANY ("system.time_usec", std::bind(&rak::timer::current_usec));
|
CMD2_ANY ("system.time_usec", std::bind(&rak::timer::current_usec));
|
||||||
|
|
||||||
CMD2_ANY_VALUE_V ("system.umask.set", std::bind(&umask, std::placeholders::_2));
|
CMD2_ANY_VALUE_V ("system.umask.set", std::bind(&umask, std::placeholders::_2));
|
||||||
|
|
||||||
|
CMD2_VAR_BOOL ("system.daemon", false);
|
||||||
|
|
||||||
CMD2_ANY ("system.cwd", std::bind(&system_get_cwd));
|
CMD2_ANY ("system.cwd", std::bind(&system_get_cwd));
|
||||||
CMD2_ANY_STRING ("system.cwd.set", std::bind(&system_set_cwd, std::placeholders::_2));
|
CMD2_ANY_STRING ("system.cwd.set", std::bind(&system_set_cwd, std::placeholders::_2));
|
||||||
|
|
||||||
@@ -401,14 +326,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", 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_EXECUTE ("execute.capture_nothrow", rpc::ExecFile::flag_expand_tilde | rpc::ExecFile::flag_capture);
|
||||||
|
|
||||||
CMD2_ANY_LIST ("log.open_file", std::bind(&apply_log_open_file, std::placeholders::_2));
|
|
||||||
CMD2_ANY_LIST ("log.open_gz_file", std::bind(&apply_log_open_gz_file, std::placeholders::_2));
|
|
||||||
CMD2_ANY_LIST ("log.add_output", std::bind(&apply_log_add_output, std::placeholders::_2));
|
|
||||||
|
|
||||||
CMD2_ANY_STRING ("log.execute", std::bind(&apply_log, std::placeholders::_2, 0));
|
|
||||||
CMD2_ANY_STRING ("log.vmmap.dump", std::bind(&log_vmmap_dump, std::placeholders::_2));
|
|
||||||
CMD2_ANY_STRING_V("log.xmlrpc", std::bind(&ThreadWorker::set_xmlrpc_log, worker_thread, std::placeholders::_2));
|
|
||||||
|
|
||||||
CMD2_ANY_LIST ("file.append", std::bind(&cmd_file_append, std::placeholders::_2));
|
CMD2_ANY_LIST ("file.append", std::bind(&cmd_file_append, std::placeholders::_2));
|
||||||
|
|
||||||
// TODO: Convert to new command types:
|
// 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", std::bind(&apply_log_open, 0, std::placeholders::_2));
|
||||||
|
CMD2_ANY_LIST ("log.open_gz_file", std::bind(&apply_log_open, log_flag_use_gz, std::placeholders::_2));
|
||||||
|
CMD2_ANY_LIST ("log.open_file_pid", std::bind(&apply_log_open, log_flag_append_pid, std::placeholders::_2));
|
||||||
|
CMD2_ANY_LIST ("log.open_gz_file_pid", std::bind(&apply_log_open, log_flag_append_pid | log_flag_use_gz, std::placeholders::_2));
|
||||||
|
|
||||||
|
CMD2_ANY_LIST ("log.add_output", std::bind(&apply_log_add_output, std::placeholders::_2));
|
||||||
|
|
||||||
|
CMD2_ANY_STRING ("log.execute", std::bind(&apply_log, std::placeholders::_2, 0));
|
||||||
|
CMD2_ANY_STRING ("log.vmmap.dump", std::bind(&log_vmmap_dump, std::placeholders::_2));
|
||||||
|
CMD2_ANY_STRING_V("log.xmlrpc", std::bind(&ThreadWorker::set_xmlrpc_log, worker_thread, std::placeholders::_2));
|
||||||
|
}
|
||||||
@@ -265,6 +265,7 @@ initialize_command_network() {
|
|||||||
CMD2_ANY_STRING_V("network.http.capath.set", std::bind(&core::CurlStack::set_http_capath, httpStack, std::placeholders::_2));
|
CMD2_ANY_STRING_V("network.http.capath.set", std::bind(&core::CurlStack::set_http_capath, httpStack, std::placeholders::_2));
|
||||||
CMD2_ANY ("network.http.dns_cache_timeout", std::bind(&core::CurlStack::dns_timeout, httpStack));
|
CMD2_ANY ("network.http.dns_cache_timeout", std::bind(&core::CurlStack::dns_timeout, httpStack));
|
||||||
CMD2_ANY_VALUE_V ("network.http.dns_cache_timeout.set", std::bind(&core::CurlStack::set_dns_timeout, httpStack, std::placeholders::_2));
|
CMD2_ANY_VALUE_V ("network.http.dns_cache_timeout.set", std::bind(&core::CurlStack::set_dns_timeout, httpStack, std::placeholders::_2));
|
||||||
|
CMD2_ANY ("network.http.current_open", std::bind(&core::CurlStack::active, httpStack));
|
||||||
CMD2_ANY ("network.http.max_open", std::bind(&core::CurlStack::max_active, httpStack));
|
CMD2_ANY ("network.http.max_open", std::bind(&core::CurlStack::max_active, httpStack));
|
||||||
CMD2_ANY_VALUE_V ("network.http.max_open.set", std::bind(&core::CurlStack::set_max_active, httpStack, std::placeholders::_2));
|
CMD2_ANY_VALUE_V ("network.http.max_open.set", std::bind(&core::CurlStack::set_max_active, httpStack, std::placeholders::_2));
|
||||||
CMD2_ANY ("network.http.proxy_address", std::bind(&core::CurlStack::http_proxy, httpStack));
|
CMD2_ANY ("network.http.proxy_address", std::bind(&core::CurlStack::http_proxy, httpStack));
|
||||||
|
|||||||
@@ -466,6 +466,11 @@ cmd_ui_set_view(const torrent::Object::string_type& args) {
|
|||||||
return torrent::Object();
|
return torrent::Object();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
torrent::Object
|
||||||
|
cmd_ui_current_view() {
|
||||||
|
return control->ui()->download_list()->current_view()->name();
|
||||||
|
}
|
||||||
|
|
||||||
torrent::Object
|
torrent::Object
|
||||||
cmd_ui_unfocus_download(core::Download* download) {
|
cmd_ui_unfocus_download(core::Download* download) {
|
||||||
control->ui()->download_list()->unfocus_download(download);
|
control->ui()->download_list()->unfocus_download(download);
|
||||||
@@ -547,8 +552,12 @@ initialize_command_ui() {
|
|||||||
|
|
||||||
// Commands that affect the default rtorrent UI.
|
// Commands that affect the default rtorrent UI.
|
||||||
CMD2_DL ("ui.unfocus_download", std::bind(&cmd_ui_unfocus_download, std::placeholders::_1));
|
CMD2_DL ("ui.unfocus_download", std::bind(&cmd_ui_unfocus_download, std::placeholders::_1));
|
||||||
|
CMD2_ANY ("ui.current_view", std::bind(&cmd_ui_current_view));
|
||||||
CMD2_ANY_STRING("ui.current_view.set", std::bind(&cmd_ui_set_view, std::placeholders::_2));
|
CMD2_ANY_STRING("ui.current_view.set", std::bind(&cmd_ui_set_view, std::placeholders::_2));
|
||||||
|
|
||||||
|
// TODO: Add 'option_string' for rtorrent-specific options.
|
||||||
|
CMD2_VAR_STRING("ui.torrent_list.layout", "full");
|
||||||
|
|
||||||
// Move.
|
// Move.
|
||||||
CMD2_ANY("print", &apply_print);
|
CMD2_ANY("print", &apply_print);
|
||||||
CMD2_ANY("cat", &apply_cat);
|
CMD2_ANY("cat", &apply_cat);
|
||||||
|
|||||||
+9
-5
@@ -5,12 +5,12 @@
|
|||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation; either version 2 of the License, or
|
// the Free Software Foundation; either version 2 of the License, or
|
||||||
// (at your option) any later version.
|
// (at your option) any later version.
|
||||||
//
|
//
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License for more details.
|
// GNU General Public License for more details.
|
||||||
//
|
//
|
||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with this program; if not, write to the Free Software
|
// along with this program; if not, write to the Free Software
|
||||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
@@ -118,7 +118,9 @@ Control::initialize() {
|
|||||||
|
|
||||||
m_ui->init(this);
|
m_ui->init(this);
|
||||||
|
|
||||||
m_inputStdin->insert(torrent::main_thread()->poll());
|
if(!display::Canvas::daemon()) {
|
||||||
|
m_inputStdin->insert(torrent::main_thread()->poll());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -128,13 +130,15 @@ Control::cleanup() {
|
|||||||
|
|
||||||
priority_queue_erase(&taskScheduler, &m_taskShutdown);
|
priority_queue_erase(&taskScheduler, &m_taskShutdown);
|
||||||
|
|
||||||
m_inputStdin->remove(torrent::main_thread()->poll());
|
if(!display::Canvas::daemon()) {
|
||||||
|
m_inputStdin->remove(torrent::main_thread()->poll());
|
||||||
|
}
|
||||||
|
|
||||||
m_core->download_store()->disable();
|
m_core->download_store()->disable();
|
||||||
|
|
||||||
m_ui->cleanup();
|
m_ui->cleanup();
|
||||||
m_core->cleanup();
|
m_core->cleanup();
|
||||||
|
|
||||||
display::Canvas::erase_std();
|
display::Canvas::erase_std();
|
||||||
display::Canvas::refresh_std();
|
display::Canvas::refresh_std();
|
||||||
display::Canvas::do_update();
|
display::Canvas::do_update();
|
||||||
|
|||||||
@@ -418,6 +418,9 @@ DownloadFactory::initialize_rtorrent(Download* download, torrent::Object* rtorre
|
|||||||
if (rtorrent->has_key_value("total_uploaded"))
|
if (rtorrent->has_key_value("total_uploaded"))
|
||||||
download->info()->mutable_up_rate()->set_total(rtorrent->get_key_value("total_uploaded"));
|
download->info()->mutable_up_rate()->set_total(rtorrent->get_key_value("total_uploaded"));
|
||||||
|
|
||||||
|
if (rtorrent->has_key_value("total_downloaded"))
|
||||||
|
download->info()->mutable_down_rate()->set_total(rtorrent->get_key_value("total_downloaded"));
|
||||||
|
|
||||||
if (rtorrent->has_key_value("chunks_done") && rtorrent->has_key_value("chunks_wanted"))
|
if (rtorrent->has_key_value("chunks_done") && rtorrent->has_key_value("chunks_wanted"))
|
||||||
download->download()->set_chunks_done(rtorrent->get_key_value("chunks_done"), rtorrent->get_key_value("chunks_wanted"));
|
download->download()->set_chunks_done(rtorrent->get_key_value("chunks_done"), rtorrent->get_key_value("chunks_wanted"));
|
||||||
|
|
||||||
|
|||||||
@@ -140,6 +140,7 @@ DownloadStore::save(Download* d, int flags) {
|
|||||||
rtorrent_base->insert_key("chunks_done", d->download()->file_list()->completed_chunks());
|
rtorrent_base->insert_key("chunks_done", d->download()->file_list()->completed_chunks());
|
||||||
rtorrent_base->insert_key("chunks_wanted", d->download()->data()->wanted_chunks());
|
rtorrent_base->insert_key("chunks_wanted", d->download()->data()->wanted_chunks());
|
||||||
rtorrent_base->insert_key("total_uploaded", d->info()->up_rate()->total());
|
rtorrent_base->insert_key("total_uploaded", d->info()->up_rate()->total());
|
||||||
|
rtorrent_base->insert_key("total_downloaded", d->info()->down_rate()->total());
|
||||||
|
|
||||||
// Don't save for completed torrents when we've cleared the uncertain_pieces.
|
// Don't save for completed torrents when we've cleared the uncertain_pieces.
|
||||||
torrent::resume_save_progress(*d->download(), *resume_base);
|
torrent::resume_save_progress(*d->download(), *resume_base);
|
||||||
|
|||||||
@@ -257,6 +257,10 @@ View::sort() {
|
|||||||
|
|
||||||
void
|
void
|
||||||
View::filter() {
|
View::filter() {
|
||||||
|
// Do NOT allow filter STARTED and STOPPED views: they are special
|
||||||
|
if (m_name == "started" || m_name == "stopped")
|
||||||
|
return;
|
||||||
|
|
||||||
// Parition the list in two steps so we know which elements changed.
|
// Parition the list in two steps so we know which elements changed.
|
||||||
iterator splitVisible = std::stable_partition(begin_visible(), end_visible(), view_downloads_filter(m_filter));
|
iterator splitVisible = std::stable_partition(begin_visible(), end_visible(), view_downloads_filter(m_filter));
|
||||||
iterator splitFiltered = std::stable_partition(begin_filtered(), end_filtered(), view_downloads_filter(m_filter));
|
iterator splitFiltered = std::stable_partition(begin_filtered(), end_filtered(), view_downloads_filter(m_filter));
|
||||||
|
|||||||
+56
-40
@@ -5,12 +5,12 @@
|
|||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation; either version 2 of the License, or
|
// the Free Software Foundation; either version 2 of the License, or
|
||||||
// (at your option) any later version.
|
// (at your option) any later version.
|
||||||
//
|
//
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License for more details.
|
// GNU General Public License for more details.
|
||||||
//
|
//
|
||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with this program; if not, write to the Free Software
|
// along with this program; if not, write to the Free Software
|
||||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
@@ -41,90 +41,106 @@
|
|||||||
#include <termios.h>
|
#include <termios.h>
|
||||||
#include <torrent/exceptions.h>
|
#include <torrent/exceptions.h>
|
||||||
|
|
||||||
|
#include "rpc/parse_commands.h"
|
||||||
|
|
||||||
#include "canvas.h"
|
#include "canvas.h"
|
||||||
|
|
||||||
namespace display {
|
namespace display {
|
||||||
|
|
||||||
bool Canvas::m_isInitialized = false;
|
bool Canvas::m_isInitialized = false;
|
||||||
|
bool Canvas::m_isDaemon = false;
|
||||||
|
|
||||||
Canvas::Canvas(int x, int y, int width, int height) :
|
Canvas::Canvas(int x, int y, int width, int height) {
|
||||||
m_window(newwin(height, width, y, x)) {
|
if (!m_isDaemon) {
|
||||||
|
m_window = newwin(height, width, y, x);
|
||||||
|
|
||||||
if (m_window == NULL)
|
if (m_window == NULL)
|
||||||
throw torrent::internal_error("Could not allocate ncurses canvas.");
|
throw torrent::internal_error("Could not allocate ncurses canvas.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Canvas::resize(int x, int y, int w, int h) {
|
Canvas::resize(int x, int y, int w, int h) {
|
||||||
wresize(m_window, h, w);
|
if (!m_isDaemon) {
|
||||||
mvwin(m_window, y, x);
|
wresize(m_window, h, w);
|
||||||
|
mvwin(m_window, y, x);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Canvas::print_attributes(unsigned int x, unsigned int y, const char* first, const char* last, const attributes_list* attributes) {
|
Canvas::print_attributes(unsigned int x, unsigned int y, const char* first, const char* last, const attributes_list* attributes) {
|
||||||
move(x, y);
|
if (!m_isDaemon) {
|
||||||
|
move(x, y);
|
||||||
|
|
||||||
attr_t org_attr;
|
attr_t org_attr;
|
||||||
short org_pair;
|
short org_pair;
|
||||||
wattr_get(m_window, &org_attr, &org_pair, NULL);
|
wattr_get(m_window, &org_attr, &org_pair, NULL);
|
||||||
|
|
||||||
attributes_list::const_iterator attrItr = attributes->begin();
|
attributes_list::const_iterator attrItr = attributes->begin();
|
||||||
wattr_set(m_window, Attributes::a_normal, Attributes::color_default, NULL);
|
wattr_set(m_window, Attributes::a_normal, Attributes::color_default, NULL);
|
||||||
|
|
||||||
while (first != last) {
|
while (first != last) {
|
||||||
const char* next = last;
|
const char* next = last;
|
||||||
|
|
||||||
if (attrItr != attributes->end()) {
|
if (attrItr != attributes->end()) {
|
||||||
next = attrItr->position();
|
next = attrItr->position();
|
||||||
|
|
||||||
if (first >= next) {
|
if (first >= next) {
|
||||||
wattr_set(m_window, attrItr->attributes(), attrItr->colors(), NULL);
|
wattr_set(m_window, attrItr->attributes(), attrItr->colors(), NULL);
|
||||||
++attrItr;
|
++attrItr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
print("%.*s", next - first, first);
|
||||||
|
first = next;
|
||||||
}
|
}
|
||||||
|
|
||||||
print("%.*s", next - first, first);
|
// Reset the color.
|
||||||
first = next;
|
wattr_set(m_window, org_attr, org_pair, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset the color.
|
|
||||||
wattr_set(m_window, org_attr, org_pair, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Canvas::initialize() {
|
Canvas::initialize() {
|
||||||
if (m_isInitialized)
|
if (m_isInitialized)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
m_isDaemon = rpc::call_command_value("system.daemon");
|
||||||
|
|
||||||
m_isInitialized = true;
|
m_isInitialized = true;
|
||||||
|
|
||||||
initscr();
|
if (!m_isDaemon) {
|
||||||
raw();
|
initscr();
|
||||||
noecho();
|
raw();
|
||||||
nodelay(stdscr, TRUE);
|
noecho();
|
||||||
keypad(stdscr, TRUE);
|
nodelay(stdscr, TRUE);
|
||||||
curs_set(0);
|
keypad(stdscr, TRUE);
|
||||||
|
curs_set(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Canvas::cleanup() {
|
Canvas::cleanup() {
|
||||||
if (!m_isInitialized)
|
if (!m_isInitialized)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_isInitialized = false;
|
m_isInitialized = false;
|
||||||
|
|
||||||
noraw();
|
if (!m_isDaemon) {
|
||||||
endwin();
|
noraw();
|
||||||
|
endwin();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<int, int>
|
std::pair<int, int>
|
||||||
Canvas::term_size() {
|
Canvas::term_size() {
|
||||||
struct winsize ws;
|
struct winsize ws;
|
||||||
|
|
||||||
if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) == 0)
|
if (!m_isDaemon) {
|
||||||
return std::pair<int, int>(ws.ws_col, ws.ws_row);
|
if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) == 0)
|
||||||
else
|
return std::pair<int, int>(ws.ws_col, ws.ws_row);
|
||||||
return std::pair<int, int>(80, 24);
|
}
|
||||||
|
return std::pair<int, int>(80, 24);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+41
-34
@@ -5,12 +5,12 @@
|
|||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation; either version 2 of the License, or
|
// the Free Software Foundation; either version 2 of the License, or
|
||||||
// (at your option) any later version.
|
// (at your option) any later version.
|
||||||
//
|
//
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License for more details.
|
// GNU General Public License for more details.
|
||||||
//
|
//
|
||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with this program; if not, write to the Free Software
|
// along with this program; if not, write to the Free Software
|
||||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
@@ -49,37 +49,37 @@ public:
|
|||||||
typedef std::vector<Attributes> attributes_list;
|
typedef std::vector<Attributes> attributes_list;
|
||||||
|
|
||||||
Canvas(int x = 0, int y = 0, int width = 0, int height = 0);
|
Canvas(int x = 0, int y = 0, int width = 0, int height = 0);
|
||||||
~Canvas() { delwin(m_window); }
|
~Canvas() { if (!m_isDaemon) { delwin(m_window); } }
|
||||||
|
|
||||||
void refresh() { wnoutrefresh(m_window); }
|
void refresh() { if (!m_isDaemon) { wnoutrefresh(m_window); } }
|
||||||
static void refresh_std() { wnoutrefresh(stdscr); }
|
static void refresh_std() { if (!m_isDaemon) { wnoutrefresh(stdscr); } }
|
||||||
void redraw() { redrawwin(m_window); }
|
void redraw() { if (!m_isDaemon) { redrawwin(m_window); } }
|
||||||
static void redraw_std() { redrawwin(stdscr); }
|
static void redraw_std() { if (!m_isDaemon) { redrawwin(stdscr); } }
|
||||||
|
|
||||||
void resize(int w, int h) { wresize(m_window, h, w); }
|
void resize(int w, int h) { if (!m_isDaemon) { wresize(m_window, h, w); } }
|
||||||
void resize(int x, int y, int w, int h);
|
void resize(int x, int y, int w, int h);
|
||||||
|
|
||||||
static void resize_term(int x, int y) { resizeterm(y, x); }
|
static void resize_term(int x, int y) { if (!m_isDaemon) { resizeterm(y, x); } }
|
||||||
static void resize_term(std::pair<int, int> dim) { resizeterm(dim.second, dim.first); }
|
static void resize_term(std::pair<int, int> dim) { if (!m_isDaemon) { resizeterm(dim.second, dim.first); } }
|
||||||
|
|
||||||
unsigned int get_x() { int x, __UNUSED y; getyx(m_window, y, x); return x; }
|
unsigned int get_x() { int x, __UNUSED y; if (!m_isDaemon) { getyx(m_window, y, x); } else { x=1; } return x; }
|
||||||
unsigned int get_y() { int x, y; getyx(m_window, y, x); return y; }
|
unsigned int get_y() { int x, y; if (!m_isDaemon) { getyx(m_window, y, x); } else { y=1; } return y; }
|
||||||
|
|
||||||
unsigned int width() { int x, __UNUSED y; getmaxyx(m_window, y, x); return x; }
|
unsigned int width() { int x, __UNUSED y; if (!m_isDaemon) { getmaxyx(m_window, y, x); } else { x=80; } return x; }
|
||||||
unsigned int height() { int x, y; getmaxyx(m_window, y, x); return y; }
|
unsigned int height() { int x, y; if (!m_isDaemon) { getmaxyx(m_window, y, x); } else { y=24; } return y; }
|
||||||
|
|
||||||
void move(unsigned int x, unsigned int y) { wmove(m_window, y, x); }
|
void move(unsigned int x, unsigned int y) { if (!m_isDaemon) { wmove(m_window, y, x); } }
|
||||||
|
|
||||||
chtype get_background() { return getbkgd(m_window); }
|
chtype get_background() { chtype bg=0; if (!m_isDaemon) { bg=getbkgd(m_window); } return bg; }
|
||||||
void set_background(chtype c) { return wbkgdset(m_window, c); }
|
void set_background(chtype c) { if (!m_isDaemon) { return wbkgdset(m_window, c); } }
|
||||||
|
|
||||||
void erase() { werase(m_window); }
|
void erase() { if (!m_isDaemon) { werase(m_window); } }
|
||||||
static void erase_std() { werase(stdscr); }
|
static void erase_std() { if (!m_isDaemon) { werase(stdscr); } }
|
||||||
|
|
||||||
void print_border(chtype ls, chtype rs,
|
void print_border(chtype ls, chtype rs,
|
||||||
chtype ts, chtype bs,
|
chtype ts, chtype bs,
|
||||||
chtype tl, chtype tr,
|
chtype tl, chtype tr,
|
||||||
chtype bl, chtype br) { wborder(m_window, ls, rs, ts, bs, tl, tr, bl, br); }
|
chtype bl, chtype br) { if (!m_isDaemon) { wborder(m_window, ls, rs, ts, bs, tl, tr, bl, br); } }
|
||||||
|
|
||||||
// The format string is non-const, but that will not be a problem
|
// The format string is non-const, but that will not be a problem
|
||||||
// since the string shall always be a C string choosen at
|
// since the string shall always be a C string choosen at
|
||||||
@@ -90,29 +90,32 @@ public:
|
|||||||
|
|
||||||
void print_attributes(unsigned int x, unsigned int y, const char* first, const char* last, const attributes_list* attributes);
|
void print_attributes(unsigned int x, unsigned int y, const char* first, const char* last, const attributes_list* attributes);
|
||||||
|
|
||||||
void print_char(const chtype ch) { waddch(m_window, ch); }
|
void print_char(const chtype ch) { if (!m_isDaemon) { waddch(m_window, ch); } }
|
||||||
void print_char(unsigned int x, unsigned int y, const chtype ch) { mvwaddch(m_window, y, x, ch); }
|
void print_char(unsigned int x, unsigned int y, const chtype ch) { if (!m_isDaemon) { mvwaddch(m_window, y, x, ch); } }
|
||||||
|
|
||||||
void set_attr(unsigned int x, unsigned int y, unsigned int n, int attr, int color) { mvwchgat(m_window, y, x, n, attr, color, NULL); }
|
void set_attr(unsigned int x, unsigned int y, unsigned int n, int attr, int color) { if (!m_isDaemon) { mvwchgat(m_window, y, x, n, attr, color, NULL); } }
|
||||||
|
|
||||||
void set_default_attributes(int attr) { (void)wattrset(m_window, attr); }
|
void set_default_attributes(int attr) { if (!m_isDaemon) { (void)wattrset(m_window, attr); } }
|
||||||
|
|
||||||
// Initialize stdscr.
|
// Initialize stdscr.
|
||||||
static void initialize();
|
static void initialize();
|
||||||
static void cleanup();
|
static void cleanup();
|
||||||
|
|
||||||
static int get_screen_width() { int x, __UNUSED y; getmaxyx(stdscr, y, x); return x; }
|
static int get_screen_width() { int x, __UNUSED y; if (!m_isDaemon) { getmaxyx(stdscr, y, x); } else { x=80; } return x; }
|
||||||
static int get_screen_height() { int x, y; getmaxyx(stdscr, y, x); return y; }
|
static int get_screen_height() { int x, y; if (!m_isDaemon) { getmaxyx(stdscr, y, x); } else { y=24;} return y; }
|
||||||
|
|
||||||
static std::pair<int, int> term_size();
|
static std::pair<int, int> term_size();
|
||||||
|
|
||||||
static void do_update() { doupdate(); }
|
static void do_update() { if (!m_isDaemon) { doupdate(); } }
|
||||||
|
|
||||||
|
static bool daemon() { return m_isDaemon; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Canvas(const Canvas&);
|
Canvas(const Canvas&);
|
||||||
void operator = (const Canvas&);
|
void operator = (const Canvas&);
|
||||||
|
|
||||||
static bool m_isInitialized;
|
static bool m_isInitialized;
|
||||||
|
static bool m_isDaemon;
|
||||||
|
|
||||||
WINDOW* m_window;
|
WINDOW* m_window;
|
||||||
};
|
};
|
||||||
@@ -121,19 +124,23 @@ inline void
|
|||||||
Canvas::print(const char* str, ...) {
|
Canvas::print(const char* str, ...) {
|
||||||
va_list arglist;
|
va_list arglist;
|
||||||
|
|
||||||
va_start(arglist, str);
|
if (!m_isDaemon) {
|
||||||
vw_printw(m_window, const_cast<char*>(str), arglist);
|
va_start(arglist, str);
|
||||||
va_end(arglist);
|
vw_printw(m_window, const_cast<char*>(str), arglist);
|
||||||
|
va_end(arglist);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void
|
inline void
|
||||||
Canvas::print(unsigned int x, unsigned int y, const char* str, ...) {
|
Canvas::print(unsigned int x, unsigned int y, const char* str, ...) {
|
||||||
va_list arglist;
|
va_list arglist;
|
||||||
|
|
||||||
va_start(arglist, str);
|
if (!m_isDaemon) {
|
||||||
wmove(m_window, y, x);
|
va_start(arglist, str);
|
||||||
vw_printw(m_window, const_cast<char*>(str), arglist);
|
wmove(m_window, y, x);
|
||||||
va_end(arglist);
|
vw_printw(m_window, const_cast<char*>(str), arglist);
|
||||||
|
va_end(arglist);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+64
-2
@@ -133,7 +133,7 @@ print_download_title(char* first, char* last, core::Download* d) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
char*
|
char*
|
||||||
print_download_info(char* first, char* last, core::Download* d) {
|
print_download_info_full(char* first, char* last, core::Download* d) {
|
||||||
if (!d->download()->info()->is_open())
|
if (!d->download()->info()->is_open())
|
||||||
first = print_buffer(first, last, "[CLOSED] ");
|
first = print_buffer(first, last, "[CLOSED] ");
|
||||||
else if (!d->download()->info()->is_active())
|
else if (!d->download()->info()->is_active())
|
||||||
@@ -177,7 +177,7 @@ print_download_info(char* first, char* last, core::Download* d) {
|
|||||||
first = print_buffer(first, last , "]");
|
first = print_buffer(first, last , "]");
|
||||||
|
|
||||||
if (first > last)
|
if (first > last)
|
||||||
throw torrent::internal_error("print_download_info(...) wrote past end of the buffer.");
|
throw torrent::internal_error("print_download_info_full(...) wrote past end of the buffer.");
|
||||||
|
|
||||||
return first;
|
return first;
|
||||||
}
|
}
|
||||||
@@ -218,6 +218,68 @@ print_download_status(char* first, char* last, core::Download* d) {
|
|||||||
return first;
|
return first;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char*
|
||||||
|
print_download_column_compact(char* first, char* last) {
|
||||||
|
first = print_buffer(first, last, " %-64.64s", "Name");
|
||||||
|
first = print_buffer(first, last, "| Status | Downloaded | Size | Done | Up Rate | Down Rate | Uploaded | ETA | Ratio| Misc ");
|
||||||
|
|
||||||
|
if (first > last)
|
||||||
|
throw torrent::internal_error("print_download_column_compact(...) wrote past end of the buffer.");
|
||||||
|
|
||||||
|
return first;
|
||||||
|
}
|
||||||
|
|
||||||
|
char*
|
||||||
|
print_download_info_compact(char* first, char* last, core::Download* d) {
|
||||||
|
first = print_buffer(first, last, " %-64.64s", d->info()->name().c_str());
|
||||||
|
first = print_buffer(first, last, "|");
|
||||||
|
|
||||||
|
if (!d->download()->info()->is_open())
|
||||||
|
first = print_buffer(first, last, " CLOSED ");
|
||||||
|
else if (!d->download()->info()->is_active())
|
||||||
|
first = print_buffer(first, last, " OPEN ");
|
||||||
|
else
|
||||||
|
first = print_buffer(first, last, " ");
|
||||||
|
|
||||||
|
first = print_buffer(first, last, "| %7.1f MB ", (double)d->download()->bytes_done() / (double)(1 << 20));
|
||||||
|
first = print_buffer(first, last, "| %7.1f MB ", (double)d->download()->file_list()->size_bytes() / (double)(1 << 20));
|
||||||
|
first = print_buffer(first, last, "|");
|
||||||
|
|
||||||
|
if (d->is_done())
|
||||||
|
first = print_buffer(first, last, " 100%% ");
|
||||||
|
else if (d->is_open())
|
||||||
|
first = print_buffer(first, last, " %2u%% ",(d->download()->file_list()->completed_chunks() * 100) / d->download()->file_list()->size_chunks());
|
||||||
|
else
|
||||||
|
first = print_buffer(first, last, " ");
|
||||||
|
|
||||||
|
first = print_buffer(first, last, "| %6.1f KB ", (double)d->info()->up_rate()->rate() / (1 << 10));
|
||||||
|
first = print_buffer(first, last, "| %6.1f KB ", (double)d->info()->down_rate()->rate() / (1 << 10));
|
||||||
|
first = print_buffer(first, last, "| %7.1f MB ", (double)d->info()->up_rate()->total() / (1 << 20));
|
||||||
|
first = print_buffer(first, last, "| ");
|
||||||
|
|
||||||
|
if (d->download()->info()->is_active() && !d->is_done())
|
||||||
|
first = print_download_time_left(first, last, d);
|
||||||
|
else
|
||||||
|
first = print_buffer(first, last, " ");
|
||||||
|
|
||||||
|
first = print_buffer(first, last, "| %4.2f ", (double)rpc::call_command_value("d.ratio", rpc::make_target(d)) / 1000.0);
|
||||||
|
first = print_buffer(first, last, "| %c%c",
|
||||||
|
rpc::call_command_string("d.tied_to_file", rpc::make_target(d)).empty() ? ' ' : 'T',
|
||||||
|
rpc::call_command_value("d.ignore_commands", rpc::make_target(d)) == 0 ? ' ' : 'I',
|
||||||
|
(double)rpc::call_command_value("d.ratio", rpc::make_target(d)) / 1000.0);
|
||||||
|
|
||||||
|
if (d->priority() != 2)
|
||||||
|
first = print_buffer(first, last, " %s", rpc::call_command_string("d.priority_str", rpc::make_target(d)).c_str());
|
||||||
|
|
||||||
|
if (!d->bencode()->get_key("rtorrent").get_key_string("throttle_name").empty())
|
||||||
|
first = print_buffer(first, last , " %s", rpc::call_command_string("d.throttle_name", rpc::make_target(d)).c_str());
|
||||||
|
|
||||||
|
if (first > last)
|
||||||
|
throw torrent::internal_error("print_download_info_compact(...) wrote past end of the buffer.");
|
||||||
|
|
||||||
|
return first;
|
||||||
|
}
|
||||||
|
|
||||||
char*
|
char*
|
||||||
print_download_time_left(char* first, char* last, core::Download* d) {
|
print_download_time_left(char* first, char* last, core::Download* d) {
|
||||||
uint32_t rate = d->info()->down_rate()->rate();
|
uint32_t rate = d->info()->down_rate()->rate();
|
||||||
|
|||||||
+5
-1
@@ -66,8 +66,12 @@ char* print_ddhhmm(char* first, char* last, time_t t);
|
|||||||
char* print_ddmmyyyy(char* first, char* last, time_t t);
|
char* print_ddmmyyyy(char* first, char* last, time_t t);
|
||||||
|
|
||||||
char* print_download_title(char* first, char* last, core::Download* d);
|
char* print_download_title(char* first, char* last, core::Download* d);
|
||||||
char* print_download_info(char* first, char* last, core::Download* d);
|
char* print_download_info_full(char* first, char* last, core::Download* d);
|
||||||
char* print_download_status(char* first, char* last, core::Download* d);
|
char* print_download_status(char* first, char* last, core::Download* d);
|
||||||
|
|
||||||
|
char* print_download_column_compact(char* first, char* last);
|
||||||
|
char* print_download_info_compact(char* first, char* last, core::Download* d);
|
||||||
|
|
||||||
char* print_download_time_left(char* first, char* last, core::Download* d);
|
char* print_download_time_left(char* first, char* last, core::Download* d);
|
||||||
char* print_download_percentage_done(char* first, char* last, core::Download* d);
|
char* print_download_percentage_done(char* first, char* last, core::Download* d);
|
||||||
|
|
||||||
|
|||||||
@@ -40,6 +40,7 @@
|
|||||||
|
|
||||||
#include "core/download.h"
|
#include "core/download.h"
|
||||||
#include "core/view.h"
|
#include "core/view.h"
|
||||||
|
#include "rpc/parse_commands.h"
|
||||||
|
|
||||||
#include "canvas.h"
|
#include "canvas.h"
|
||||||
#include "globals.h"
|
#include "globals.h"
|
||||||
@@ -85,12 +86,24 @@ WindowDownloadList::redraw() {
|
|||||||
if (m_view->empty_visible() || m_canvas->width() < 5 || m_canvas->height() < 2)
|
if (m_view->empty_visible() || m_canvas->width() < 5 || m_canvas->height() < 2)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
int layout_height;
|
||||||
|
const std::string layout_name = rpc::call_command_string("ui.torrent_list.layout");
|
||||||
|
|
||||||
|
if (layout_name == "full") {
|
||||||
|
layout_height = 3;
|
||||||
|
} else if (layout_name == "compact") {
|
||||||
|
layout_height = 1;
|
||||||
|
} else {
|
||||||
|
m_canvas->print(0, 0, "INVALID ui.torrent_list.layout '%s'", layout_name.c_str());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
typedef std::pair<core::View::iterator, core::View::iterator> Range;
|
typedef std::pair<core::View::iterator, core::View::iterator> Range;
|
||||||
|
|
||||||
Range range = rak::advance_bidirectional(m_view->begin_visible(),
|
Range range = rak::advance_bidirectional(m_view->begin_visible(),
|
||||||
m_view->focus() != m_view->end_visible() ? m_view->focus() : m_view->begin_visible(),
|
m_view->focus() != m_view->end_visible() ? m_view->focus() : m_view->begin_visible(),
|
||||||
m_view->end_visible(),
|
m_view->end_visible(),
|
||||||
m_canvas->height() / 3);
|
m_canvas->height() / layout_height);
|
||||||
|
|
||||||
// Make sure we properly fill out the last lines so it looks like
|
// Make sure we properly fill out the last lines so it looks like
|
||||||
// there are more torrents, yet don't hide it if we got the last one
|
// there are more torrents, yet don't hide it if we got the last one
|
||||||
@@ -99,22 +112,38 @@ WindowDownloadList::redraw() {
|
|||||||
++range.second;
|
++range.second;
|
||||||
|
|
||||||
int pos = 1;
|
int pos = 1;
|
||||||
|
char buffer[m_canvas->width() + 1];
|
||||||
|
char* last = buffer + m_canvas->width() - 2 + 1;
|
||||||
|
|
||||||
while (range.first != range.second) {
|
// Add a proper 'column info' method.
|
||||||
char buffer[m_canvas->width() + 1];
|
if (layout_name == "compact") {
|
||||||
char* last = buffer + m_canvas->width() - 2 + 1;
|
print_download_column_compact(buffer, last);
|
||||||
|
|
||||||
print_download_title(buffer, last, *range.first);
|
m_canvas->set_default_attributes(A_BOLD);
|
||||||
m_canvas->print(0, pos++, "%c %s", range.first == m_view->focus() ? '*' : ' ', buffer);
|
m_canvas->print(0, pos++, " %s", buffer);
|
||||||
|
}
|
||||||
print_download_info(buffer, last, *range.first);
|
|
||||||
m_canvas->print(0, pos++, "%c %s", range.first == m_view->focus() ? '*' : ' ', buffer);
|
|
||||||
|
|
||||||
print_download_status(buffer, last, *range.first);
|
if (layout_name == "full") {
|
||||||
m_canvas->print(0, pos++, "%c %s", range.first == m_view->focus() ? '*' : ' ', buffer);
|
while (range.first != range.second) {
|
||||||
|
print_download_title(buffer, last, *range.first);
|
||||||
|
m_canvas->print(0, pos++, "%c %s", range.first == m_view->focus() ? '*' : ' ', buffer);
|
||||||
|
print_download_info_full(buffer, last, *range.first);
|
||||||
|
m_canvas->print(0, pos++, "%c %s", range.first == m_view->focus() ? '*' : ' ', buffer);
|
||||||
|
print_download_status(buffer, last, *range.first);
|
||||||
|
m_canvas->print(0, pos++, "%c %s", range.first == m_view->focus() ? '*' : ' ', buffer);
|
||||||
|
|
||||||
++range.first;
|
range.first++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
while (range.first != range.second) {
|
||||||
|
print_download_info_compact(buffer, last, *range.first);
|
||||||
|
m_canvas->set_default_attributes(range.first == m_view->focus() ? A_REVERSE : A_NORMAL);
|
||||||
|
m_canvas->print(0, pos++, "%c %s", range.first == m_view->focus() ? '*' : ' ', buffer);
|
||||||
|
|
||||||
|
range.first++;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ WindowDownloadStatusbar::redraw() {
|
|||||||
char buffer[m_canvas->width()];
|
char buffer[m_canvas->width()];
|
||||||
char* last = buffer + m_canvas->width() - 2;
|
char* last = buffer + m_canvas->width() - 2;
|
||||||
|
|
||||||
print_download_info(buffer, last, m_download);
|
print_download_info_full(buffer, last, m_download);
|
||||||
m_canvas->print(0, 0, "%s", buffer);
|
m_canvas->print(0, 0, "%s", buffer);
|
||||||
|
|
||||||
snprintf(buffer, last - buffer, "Peers: %i(%i) Min/Max: %i/%i Slots: U:%i/%i D:%i/%i U/I/C/A: %i/%i/%i/%i Unchoked: %u/%u Failed: %i",
|
snprintf(buffer, last - buffer, "Peers: %i(%i) Min/Max: %i/%i Slots: U:%i/%i D:%i/%i U/I/C/A: %i/%i/%i/%i Unchoked: %u/%u Failed: %i",
|
||||||
|
|||||||
@@ -75,7 +75,11 @@ PathInput::pressed(int key) {
|
|||||||
|
|
||||||
struct _transform_filename {
|
struct _transform_filename {
|
||||||
void operator () (utils::directory_entry& entry) {
|
void operator () (utils::directory_entry& entry) {
|
||||||
|
#ifdef __sun__
|
||||||
|
if (entry.d_type & S_IFDIR)
|
||||||
|
#else
|
||||||
if (entry.d_type == DT_DIR)
|
if (entry.d_type == DT_DIR)
|
||||||
|
#endif
|
||||||
entry.d_name += '/';
|
entry.d_name += '/';
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
+21
-399
@@ -190,8 +190,10 @@ main(int argc, char** argv) {
|
|||||||
|
|
||||||
control = new Control;
|
control = new Control;
|
||||||
|
|
||||||
srandom(cachedTime.usec() ^ (getpid() << 16) ^ getppid());
|
unsigned int random_seed = cachedTime.seconds() ^ cachedTime.usec() ^ (getpid() << 16) ^ getppid();
|
||||||
srand48(cachedTime.usec() ^ (getpid() << 16) ^ getppid());
|
|
||||||
|
srandom(random_seed);
|
||||||
|
srand48(random_seed);
|
||||||
|
|
||||||
SignalHandler::set_ignore(SIGPIPE);
|
SignalHandler::set_ignore(SIGPIPE);
|
||||||
SignalHandler::set_handler(SIGINT, std::bind(&Control::receive_normal_shutdown, control));
|
SignalHandler::set_handler(SIGINT, std::bind(&Control::receive_normal_shutdown, control));
|
||||||
@@ -231,7 +233,7 @@ main(int argc, char** argv) {
|
|||||||
|
|
||||||
if (OptionParser::has_flag('D', argc, argv)) {
|
if (OptionParser::has_flag('D', argc, argv)) {
|
||||||
rpc::call_command_set_value("method.use_deprecated.set", true);
|
rpc::call_command_set_value("method.use_deprecated.set", true);
|
||||||
lt_log_print(torrent::LOG_WARN, "Disabled deprecated commands.");
|
lt_log_print(torrent::LOG_WARN, "Enabled deprecated commands.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (OptionParser::has_flag('I', argc, argv)) {
|
if (OptionParser::has_flag('I', argc, argv)) {
|
||||||
@@ -414,6 +416,8 @@ main(int argc, char** argv) {
|
|||||||
CMD2_REDIRECT_GENERIC("to_xb", "convert.xb");
|
CMD2_REDIRECT_GENERIC("to_xb", "convert.xb");
|
||||||
CMD2_REDIRECT_GENERIC("to_throttle", "convert.throttle");
|
CMD2_REDIRECT_GENERIC("to_throttle", "convert.throttle");
|
||||||
|
|
||||||
|
CMD2_REDIRECT ("torrent_list_layout", "ui.torrent_list.layout.set");
|
||||||
|
|
||||||
// Deprecated commands. Don't use these anymore.
|
// Deprecated commands. Don't use these anymore.
|
||||||
|
|
||||||
if (rpc::call_command_value("method.use_intermediate") == 1) {
|
if (rpc::call_command_value("method.use_intermediate") == 1) {
|
||||||
@@ -432,408 +436,25 @@ main(int argc, char** argv) {
|
|||||||
|
|
||||||
#if LT_SLIM_VERSION != 1
|
#if LT_SLIM_VERSION != 1
|
||||||
if (rpc::call_command_value("method.use_deprecated")) {
|
if (rpc::call_command_value("method.use_deprecated")) {
|
||||||
// Deprecated in 0.7.0:
|
|
||||||
|
|
||||||
CMD2_REDIRECT_GENERIC("system.method.insert", "method.insert");
|
|
||||||
CMD2_REDIRECT_GENERIC("system.method.erase", "method.erase");
|
|
||||||
CMD2_REDIRECT_GENERIC("system.method.get", "method.get");
|
|
||||||
CMD2_REDIRECT_GENERIC("system.method.set", "method.set");
|
|
||||||
CMD2_REDIRECT_GENERIC("system.method.list_keys", "method.list_keys");
|
|
||||||
CMD2_REDIRECT_GENERIC("system.method.has_key", "method.has_key");
|
|
||||||
CMD2_REDIRECT_GENERIC("system.method.set_key", "method.set_key");
|
|
||||||
|
|
||||||
CMD2_REDIRECT ("get_directory", "directory.default");
|
|
||||||
CMD2_REDIRECT_GENERIC("set_directory", "directory.default.set");
|
|
||||||
|
|
||||||
CMD2_REDIRECT ("get_session", "session.path");
|
|
||||||
CMD2_REDIRECT_GENERIC("set_session", "session.path.set");
|
|
||||||
|
|
||||||
CMD2_REDIRECT ("session_save", "session.save");
|
|
||||||
|
|
||||||
CMD2_REDIRECT ("get_name", "session.name");
|
|
||||||
CMD2_REDIRECT_GENERIC("set_name", "session.name.set");
|
|
||||||
|
|
||||||
CMD2_REDIRECT ("system.file_allocate", "system.file.allocate");
|
|
||||||
CMD2_REDIRECT ("system.file_allocate.set", "system.file.allocate.set");
|
|
||||||
CMD2_REDIRECT ("get_max_file_size", "system.file.max_size");
|
|
||||||
CMD2_REDIRECT_GENERIC("set_max_file_size", "system.file.max_size.set");
|
|
||||||
CMD2_REDIRECT ("get_split_file_size", "system.file.split_size");
|
|
||||||
CMD2_REDIRECT_GENERIC("set_split_file_size", "system.file.split_size.set");
|
|
||||||
CMD2_REDIRECT ("get_split_suffix", "system.file.split_suffix");
|
|
||||||
CMD2_REDIRECT_GENERIC("set_split_suffix", "system.file.split_suffix.set");
|
|
||||||
|
|
||||||
CMD2_REDIRECT ("get_timeout_sync", "pieces.sync.timeout");
|
|
||||||
CMD2_REDIRECT_GENERIC("set_timeout_sync", "pieces.sync.timeout.set");
|
|
||||||
CMD2_REDIRECT ("get_timeout_safe_sync", "pieces.sync.timeout_safe");
|
|
||||||
CMD2_REDIRECT_GENERIC("set_timeout_safe_sync", "pieces.sync.timeout_safe.set");
|
|
||||||
|
|
||||||
CMD2_REDIRECT_GENERIC("get_preload_type", "pieces.preload.type");
|
|
||||||
CMD2_REDIRECT_GENERIC("get_preload_min_size", "pieces.preload.min_size");
|
|
||||||
CMD2_REDIRECT_GENERIC("get_preload_required_rate", "pieces.preload.min_rate");
|
|
||||||
CMD2_REDIRECT_GENERIC("set_preload_type", "pieces.preload.type.set");
|
|
||||||
CMD2_REDIRECT_GENERIC("set_preload_min_size", "pieces.preload.min_size.set");
|
|
||||||
CMD2_REDIRECT_GENERIC("set_preload_required_rate", "pieces.preload.min_rate.set");
|
|
||||||
CMD2_REDIRECT_GENERIC("get_stats_preloaded", "pieces.stats_preloaded");
|
|
||||||
CMD2_REDIRECT_GENERIC("get_stats_not_preloaded", "pieces.stats_not_preloaded");
|
|
||||||
|
|
||||||
CMD2_REDIRECT_GENERIC("get_safe_sync", "pieces.sync.always_safe");
|
|
||||||
CMD2_REDIRECT_GENERIC("set_safe_sync", "pieces.sync.always_safe.set");
|
|
||||||
|
|
||||||
CMD2_REDIRECT ("get_memory_usage", "pieces.memory.current");
|
|
||||||
CMD2_REDIRECT_GENERIC("get_max_memory_usage", "pieces.memory.max");
|
|
||||||
CMD2_REDIRECT_GENERIC("set_max_memory_usage", "pieces.memory.max.set");
|
|
||||||
|
|
||||||
CMD2_REDIRECT_GENERIC("load", "load.normal");
|
|
||||||
CMD2_REDIRECT_GENERIC("load_verbose", "load.verbose");
|
|
||||||
CMD2_REDIRECT_GENERIC("load_start", "load.start");
|
|
||||||
CMD2_REDIRECT_GENERIC("load_start_verbose", "load.start_verbose");
|
|
||||||
|
|
||||||
CMD2_REDIRECT_GENERIC("load_raw", "load.raw");
|
|
||||||
CMD2_REDIRECT_GENERIC("load_raw_start", "load.raw_start");
|
|
||||||
CMD2_REDIRECT_GENERIC("load_raw_verbose", "load.raw_verbose");
|
|
||||||
|
|
||||||
CMD2_REDIRECT_GENERIC("get_connection_leech", "protocol.connection.leech");
|
|
||||||
CMD2_REDIRECT_GENERIC("get_connection_seed", "protocol.connection.seed");
|
|
||||||
CMD2_REDIRECT_GENERIC("set_connection_leech", "protocol.connection.leech.set");
|
|
||||||
CMD2_REDIRECT_GENERIC("set_connection_seed", "protocol.connection.seed.set");
|
|
||||||
|
|
||||||
//
|
|
||||||
// Throttle:
|
|
||||||
//
|
|
||||||
|
|
||||||
CMD2_REDIRECT_GENERIC("throttle_up", "throttle.up");
|
|
||||||
CMD2_REDIRECT_GENERIC("throttle_down", "throttle.down");
|
|
||||||
CMD2_REDIRECT_GENERIC("throttle_ip", "throttle.ip");
|
|
||||||
|
|
||||||
CMD2_REDIRECT_GENERIC("get_throttle_up_max", "throttle.up.max");
|
|
||||||
CMD2_REDIRECT_GENERIC("get_throttle_up_rate", "throttle.up.rate");
|
|
||||||
CMD2_REDIRECT_GENERIC("get_throttle_down_max", "throttle.down.max");
|
|
||||||
CMD2_REDIRECT_GENERIC("get_throttle_down_rate", "throttle.down.rate");
|
|
||||||
|
|
||||||
CMD2_REDIRECT_GENERIC("set_min_peers", "throttle.min_peers.normal.set");
|
|
||||||
CMD2_REDIRECT_GENERIC("set_max_peers", "throttle.max_peers.normal.set");
|
|
||||||
CMD2_REDIRECT_GENERIC("set_min_peers_seed", "throttle.min_peers.seed.set");
|
|
||||||
CMD2_REDIRECT_GENERIC("set_max_peers_seed", "throttle.max_peers.seed.set");
|
|
||||||
|
|
||||||
CMD2_REDIRECT_GENERIC("set_max_uploads", "throttle.max_uploads.set");
|
|
||||||
|
|
||||||
CMD2_REDIRECT_GENERIC("set_max_uploads_div", "throttle.max_uploads.div.set");
|
|
||||||
CMD2_REDIRECT_GENERIC("set_max_uploads_global", "throttle.max_uploads.global.set");
|
|
||||||
CMD2_REDIRECT_GENERIC("set_max_downloads_div", "throttle.max_downloads.div.set");
|
|
||||||
CMD2_REDIRECT_GENERIC("set_max_downloads_global", "throttle.max_downloads.global.set");
|
|
||||||
|
|
||||||
CMD2_REDIRECT ("get_min_peers", "throttle.min_peers.normal");
|
|
||||||
CMD2_REDIRECT ("get_max_peers", "throttle.max_peers.normal");
|
|
||||||
CMD2_REDIRECT ("get_min_peers_seed", "throttle.min_peers.seed");
|
|
||||||
CMD2_REDIRECT ("get_max_peers_seed", "throttle.max_peers.seed");
|
|
||||||
|
|
||||||
CMD2_REDIRECT ("get_max_uploads", "throttle.max_uploads");
|
|
||||||
|
|
||||||
CMD2_REDIRECT ("get_max_uploads_div", "throttle.max_uploads.div");
|
|
||||||
CMD2_REDIRECT ("get_max_uploads_global", "throttle.max_uploads.global");
|
|
||||||
CMD2_REDIRECT ("get_max_downloads_div", "throttle.max_downloads.div");
|
|
||||||
CMD2_REDIRECT ("get_max_downloads_global", "throttle.max_downloads.global");
|
|
||||||
|
|
||||||
CMD2_REDIRECT ("get_up_rate", "throttle.global_up.rate");
|
|
||||||
CMD2_REDIRECT ("get_up_total", "throttle.global_up.total");
|
|
||||||
CMD2_REDIRECT ("get_upload_rate", "throttle.global_up.max_rate");
|
|
||||||
CMD2_REDIRECT_GENERIC("set_upload_rate", "throttle.global_up.max_rate.set");
|
|
||||||
CMD2_REDIRECT ("get_down_rate", "throttle.global_down.rate");
|
|
||||||
CMD2_REDIRECT ("get_down_total", "throttle.global_down.total");
|
|
||||||
CMD2_REDIRECT ("get_download_rate", "throttle.global_down.max_rate");
|
|
||||||
CMD2_REDIRECT_GENERIC("set_download_rate", "throttle.global_down.max_rate.set");
|
|
||||||
|
|
||||||
//
|
|
||||||
// Network:
|
|
||||||
//
|
|
||||||
|
|
||||||
CMD2_REDIRECT ("get_send_buffer_size", "network.send_buffer.size");
|
|
||||||
CMD2_REDIRECT_GENERIC("set_send_buffer_size", "network.send_buffer.size.set");
|
|
||||||
CMD2_REDIRECT ("get_receive_buffer_size", "network.receive_buffer.size");
|
|
||||||
CMD2_REDIRECT_GENERIC("set_receive_buffer_size", "network.receive_buffer.size.set");
|
|
||||||
|
|
||||||
CMD2_REDIRECT_GENERIC("set_bind", "network.bind_address.set");
|
|
||||||
CMD2_REDIRECT ("get_bind", "network.bind_address");
|
|
||||||
|
|
||||||
CMD2_REDIRECT_GENERIC("set_ip", "network.local_address.set");
|
|
||||||
CMD2_REDIRECT ("get_ip", "network.local_address");
|
|
||||||
|
|
||||||
CMD2_REDIRECT ("get_port_range", "network.port_range");
|
|
||||||
CMD2_REDIRECT_GENERIC("set_port_range", "network.port_range.set");
|
|
||||||
|
|
||||||
CMD2_REDIRECT ("get_port_random", "network.port_random");
|
|
||||||
CMD2_REDIRECT_GENERIC("set_port_random", "network.port_random.set");
|
|
||||||
|
|
||||||
CMD2_REDIRECT ("port_open", "network.port_open.set");
|
|
||||||
CMD2_REDIRECT ("get_port_open", "network.port_open");
|
|
||||||
CMD2_REDIRECT_GENERIC("set_port_open", "network.port_open.set");
|
|
||||||
|
|
||||||
CMD2_REDIRECT_GENERIC("set_proxy_address", "network.proxy_address.set");
|
|
||||||
CMD2_REDIRECT ("get_proxy_address", "network.proxy_address");
|
|
||||||
|
|
||||||
CMD2_REDIRECT_GENERIC("set_scgi_dont_route", "network.scgi.dont_route.set");
|
|
||||||
CMD2_REDIRECT ("get_scgi_dont_route", "network.scgi.dont_route");
|
|
||||||
|
|
||||||
CMD2_REDIRECT ("get_max_open_sockets", "network.max_open_sockets");
|
|
||||||
|
|
||||||
CMD2_REDIRECT ("get_max_open_files", "network.max_open_files");
|
|
||||||
CMD2_REDIRECT_GENERIC("set_max_open_files", "network.max_open_files.set");
|
|
||||||
|
|
||||||
//
|
|
||||||
// XMLRPC stuff:
|
|
||||||
//
|
|
||||||
|
|
||||||
CMD2_REDIRECT_GENERIC("xmlrpc_dialect", "network.xmlrpc.dialect.set");
|
|
||||||
CMD2_REDIRECT_GENERIC("set_xmlrpc_dialect", "network.xmlrpc.dialect.set");
|
|
||||||
|
|
||||||
CMD2_REDIRECT_GENERIC("xmlrpc_size_limit", "network.xmlrpc.size_limit.set");
|
|
||||||
CMD2_REDIRECT ("get_xmlrpc_size_limit", "network.xmlrpc.size_limit");
|
|
||||||
CMD2_REDIRECT_GENERIC("set_xmlrpc_size_limit", "network.xmlrpc.size_limit.set");
|
|
||||||
|
|
||||||
//
|
|
||||||
// HTTP stuff:
|
|
||||||
//
|
|
||||||
|
|
||||||
CMD2_REDIRECT_GENERIC("http_capath", "network.http.capath.set");
|
|
||||||
CMD2_REDIRECT ("get_http_capath", "network.http.capath");
|
|
||||||
CMD2_REDIRECT_GENERIC("set_http_capath", "network.http.capath.set");
|
|
||||||
|
|
||||||
CMD2_REDIRECT_GENERIC("http_cacert", "network.http.cacert.set");
|
|
||||||
CMD2_REDIRECT ("get_http_cacert", "network.http.cacert");
|
|
||||||
CMD2_REDIRECT_GENERIC("set_http_cacert", "network.http.cacert.set");
|
|
||||||
|
|
||||||
CMD2_REDIRECT ("get_max_open_http", "network.http.max_open");
|
|
||||||
CMD2_REDIRECT_GENERIC("set_max_open_http", "network.http.max_open.set");
|
|
||||||
|
|
||||||
CMD2_REDIRECT_GENERIC("http_proxy", "network.http.proxy_address.set");
|
|
||||||
CMD2_REDIRECT ("get_http_proxy", "network.http.proxy_address");
|
|
||||||
CMD2_REDIRECT_GENERIC("set_http_proxy", "network.http.proxy_address.set");
|
|
||||||
|
|
||||||
CMD2_REDIRECT ("peer_exchange", "protocol.pex.set");
|
|
||||||
CMD2_REDIRECT ("get_peer_exchange", "protocol.pex");
|
|
||||||
CMD2_REDIRECT_GENERIC("set_peer_exchange", "protocol.pex.set");
|
|
||||||
|
|
||||||
//
|
|
||||||
// Trackers:
|
|
||||||
//
|
|
||||||
|
|
||||||
CMD2_REDIRECT ("tracker_numwant", "trackers.numwant.set");
|
|
||||||
CMD2_REDIRECT ("get_tracker_numwant", "trackers.numwant");
|
|
||||||
CMD2_REDIRECT_GENERIC("set_tracker_numwant", "trackers.numwant.set");
|
|
||||||
|
|
||||||
CMD2_REDIRECT ("use_udp_trackers", "trackers.use_udp.set");
|
|
||||||
CMD2_REDIRECT ("get_use_udp_trackers", "trackers.use_udp");
|
|
||||||
CMD2_REDIRECT_GENERIC("set_use_udp_trackers", "trackers.use_udp.set");
|
|
||||||
|
|
||||||
//
|
|
||||||
// DHT stuff
|
|
||||||
//
|
|
||||||
|
|
||||||
CMD2_REDIRECT ("dht_add_node", "dht.add_node");
|
|
||||||
CMD2_REDIRECT ("dht_statistics", "dht.statistics");
|
|
||||||
CMD2_REDIRECT ("get_dht_port", "dht.port");
|
|
||||||
CMD2_REDIRECT_GENERIC("set_dht_port", "dht.port.set");
|
|
||||||
CMD2_REDIRECT ("get_dht_throttle", "dht.throttle.name");
|
|
||||||
CMD2_REDIRECT_GENERIC("set_dht_throttle", "dht.throttle.name.set");
|
|
||||||
|
|
||||||
//
|
|
||||||
// Various system stuff:
|
|
||||||
//
|
|
||||||
|
|
||||||
CMD2_REDIRECT ("get_session_lock", "session.use_lock");
|
|
||||||
CMD2_REDIRECT_GENERIC("set_session_lock", "session.use_lock.set");
|
|
||||||
CMD2_REDIRECT ("get_session_on_completion", "session.on_completion");
|
|
||||||
CMD2_REDIRECT_GENERIC("set_session_on_completion", "session.on_completion.set");
|
|
||||||
|
|
||||||
CMD2_REDIRECT ("get_check_hash", "pieces.hash.on_completion");
|
|
||||||
CMD2_REDIRECT_GENERIC("set_check_hash", "pieces.hash.on_completion.set");
|
|
||||||
|
|
||||||
//
|
|
||||||
// Download:
|
|
||||||
//
|
|
||||||
|
|
||||||
CMD2_REDIRECT ("d.get_hash", "d.hash");
|
|
||||||
CMD2_REDIRECT ("d.get_local_id", "d.local_id");
|
|
||||||
CMD2_REDIRECT ("d.get_local_id_html", "d.local_id_html");
|
|
||||||
CMD2_REDIRECT ("d.get_bitfield", "d.bitfield");
|
|
||||||
CMD2_REDIRECT ("d.get_base_path", "d.base_path");
|
|
||||||
CMD2_REDIRECT ("d.get_base_filename", "d.base_filename");
|
|
||||||
|
|
||||||
CMD2_REDIRECT ("d.get_name", "d.name");
|
|
||||||
CMD2_REDIRECT ("d.get_creation_date", "d.creation_date");
|
|
||||||
|
|
||||||
CMD2_REDIRECT ("d.get_peer_exchange", "d.peer_exchange");
|
|
||||||
|
|
||||||
CMD2_REDIRECT ("d.get_up_rate", "d.up.rate");
|
|
||||||
CMD2_REDIRECT ("d.get_up_total", "d.up.total");
|
|
||||||
CMD2_REDIRECT ("d.get_down_rate", "d.down.rate");
|
|
||||||
CMD2_REDIRECT ("d.get_down_total", "d.down.total");
|
|
||||||
CMD2_REDIRECT ("d.get_skip_rate", "d.skip.rate");
|
|
||||||
CMD2_REDIRECT ("d.get_skip_total", "d.skip.total");
|
|
||||||
|
|
||||||
//
|
|
||||||
CMD2_REDIRECT ("d.get_bytes_done", "d.bytes_done");
|
|
||||||
CMD2_REDIRECT ("d.get_chunk_size", "d.chunk_size");
|
|
||||||
CMD2_REDIRECT ("d.get_chunks_hashed", "d.chunks_hashed");
|
|
||||||
CMD2_REDIRECT ("d.get_complete", "d.complete");
|
|
||||||
CMD2_REDIRECT ("d.get_completed_bytes", "d.completed_bytes");
|
|
||||||
CMD2_REDIRECT ("d.get_completed_chunks", "d.completed_chunks");
|
|
||||||
CMD2_REDIRECT ("d.get_connection_current", "d.connection_current");
|
|
||||||
CMD2_REDIRECT ("d.get_connection_leech", "d.connection_leech");
|
|
||||||
CMD2_REDIRECT ("d.get_connection_seed", "d.connection_seed");
|
|
||||||
CMD2_REDIRECT ("d.get_custom", "d.custom");
|
|
||||||
CMD2_REDIRECT ("d.get_custom1", "d.custom1");
|
|
||||||
CMD2_REDIRECT ("d.get_custom2", "d.custom2");
|
|
||||||
CMD2_REDIRECT ("d.get_custom3", "d.custom3");
|
|
||||||
CMD2_REDIRECT ("d.get_custom4", "d.custom4");
|
|
||||||
CMD2_REDIRECT ("d.get_custom5", "d.custom5");
|
|
||||||
CMD2_REDIRECT ("d.get_custom_throw", "d.custom_throw");
|
|
||||||
CMD2_REDIRECT ("d.get_directory", "d.directory");
|
|
||||||
CMD2_REDIRECT ("d.get_directory_base", "d.directory_base");
|
|
||||||
CMD2_REDIRECT ("d.get_free_diskspace", "d.free_diskspace");
|
|
||||||
CMD2_REDIRECT ("d.get_hashing", "d.hashing");
|
|
||||||
CMD2_REDIRECT ("d.get_hashing_failed", "d.hashing_failed");
|
|
||||||
CMD2_REDIRECT ("d.get_ignore_commands", "d.ignore_commands");
|
|
||||||
CMD2_REDIRECT ("d.get_left_bytes", "d.left_bytes");
|
|
||||||
CMD2_REDIRECT ("d.get_loaded_file", "d.loaded_file");
|
|
||||||
CMD2_REDIRECT ("d.get_max_file_size", "d.max_file_size");
|
|
||||||
CMD2_REDIRECT ("d.get_max_size_pex", "d.max_size_pex");
|
|
||||||
CMD2_REDIRECT ("d.get_message", "d.message");
|
|
||||||
CMD2_REDIRECT ("d.get_mode", "d.mode");
|
|
||||||
CMD2_REDIRECT ("d.get_peers_accounted", "d.peers_accounted");
|
|
||||||
CMD2_REDIRECT ("d.get_peers_complete", "d.peers_complete");
|
|
||||||
CMD2_REDIRECT ("d.get_peers_connected", "d.peers_connected");
|
|
||||||
CMD2_REDIRECT ("d.get_peers_max", "d.peers_max");
|
|
||||||
CMD2_REDIRECT ("d.get_peers_min", "d.peers_min");
|
|
||||||
CMD2_REDIRECT ("d.get_peers_not_connected", "d.peers_not_connected");
|
|
||||||
CMD2_REDIRECT ("d.get_priority", "d.priority");
|
|
||||||
CMD2_REDIRECT ("d.get_priority_str", "d.priority_str");
|
|
||||||
CMD2_REDIRECT ("d.get_ratio", "d.ratio");
|
|
||||||
CMD2_REDIRECT ("d.get_size_bytes", "d.size_bytes");
|
|
||||||
CMD2_REDIRECT ("d.get_size_chunks", "d.size_chunks");
|
|
||||||
CMD2_REDIRECT ("d.get_size_files", "d.size_files");
|
|
||||||
CMD2_REDIRECT ("d.get_size_pex", "d.size_pex");
|
|
||||||
CMD2_REDIRECT ("d.get_state", "d.state");
|
|
||||||
CMD2_REDIRECT ("d.get_state_changed", "d.state_changed");
|
|
||||||
CMD2_REDIRECT ("d.get_state_counter", "d.state_counter");
|
|
||||||
CMD2_REDIRECT ("d.get_throttle_name", "d.throttle_name");
|
|
||||||
CMD2_REDIRECT ("d.get_tied_to_file", "d.tied_to_file");
|
|
||||||
CMD2_REDIRECT ("d.get_tracker_focus", "d.tracker_focus");
|
|
||||||
CMD2_REDIRECT ("d.get_tracker_numwant", "d.tracker_numwant");
|
|
||||||
CMD2_REDIRECT ("d.get_tracker_size", "d.tracker_size");
|
|
||||||
CMD2_REDIRECT ("d.get_uploads_max", "d.uploads_max");
|
|
||||||
|
|
||||||
CMD2_REDIRECT ("d.set_connection_current", "d.connection_current.set");
|
|
||||||
CMD2_REDIRECT ("d.set_custom", "d.custom.set");
|
|
||||||
CMD2_REDIRECT ("d.set_custom1", "d.custom1.set");
|
|
||||||
CMD2_REDIRECT ("d.set_custom2", "d.custom2.set");
|
|
||||||
CMD2_REDIRECT ("d.set_custom3", "d.custom3.set");
|
|
||||||
CMD2_REDIRECT ("d.set_custom4", "d.custom4.set");
|
|
||||||
CMD2_REDIRECT ("d.set_custom5", "d.custom5.set");
|
|
||||||
CMD2_REDIRECT ("d.set_directory", "d.directory.set");
|
|
||||||
CMD2_REDIRECT ("d.set_directory_base", "d.directory_base.set");
|
|
||||||
CMD2_REDIRECT ("d.set_hashing_failed", "d.hashing_failed.set");
|
|
||||||
CMD2_REDIRECT ("d.set_ignore_commands", "d.ignore_commands.set");
|
|
||||||
CMD2_REDIRECT ("d.set_max_file_size", "d.max_file_size.set");
|
|
||||||
CMD2_REDIRECT ("d.set_message", "d.message.set");
|
|
||||||
CMD2_REDIRECT ("d.set_peers_max", "d.peers_max.set");
|
|
||||||
CMD2_REDIRECT ("d.set_peers_min", "d.peers_min.set");
|
|
||||||
CMD2_REDIRECT ("d.set_priority", "d.priority.set");
|
|
||||||
CMD2_REDIRECT ("d.set_throttle_name", "d.throttle_name.set");
|
|
||||||
CMD2_REDIRECT ("d.set_tied_to_file", "d.tied_to_file.set");
|
|
||||||
CMD2_REDIRECT ("d.set_tracker_numwant", "d.tracker_numwant.set");
|
|
||||||
CMD2_REDIRECT ("d.set_uploads_max", "d.uploads_max.set");
|
|
||||||
|
|
||||||
CMD2_REDIRECT ("create_link", "d.create_link");
|
|
||||||
CMD2_REDIRECT ("delete_link", "d.delete_link");
|
|
||||||
CMD2_REDIRECT ("delete_tied", "d.delete_tied");
|
|
||||||
|
|
||||||
//
|
|
||||||
// Tracker:
|
|
||||||
//
|
|
||||||
|
|
||||||
CMD2_REDIRECT_TRACKER("t.get_group", "t.group");
|
|
||||||
CMD2_REDIRECT_TRACKER("t.get_id", "t.id");
|
|
||||||
CMD2_REDIRECT_TRACKER("t.get_min_interval", "t.min_interval");
|
|
||||||
CMD2_REDIRECT_TRACKER("t.get_normal_interval", "t.normal_interval");
|
|
||||||
CMD2_REDIRECT_TRACKER("t.get_scrape_complete", "t.scrape_complete");
|
|
||||||
CMD2_REDIRECT_TRACKER("t.get_scrape_downloaded", "t.scrape_downloaded");
|
|
||||||
CMD2_REDIRECT_TRACKER("t.get_scrape_incomplete", "t.scrape_incomplete");
|
|
||||||
CMD2_REDIRECT_TRACKER("t.get_scrape_time_last", "t.scrape_time_last");
|
|
||||||
CMD2_REDIRECT_TRACKER("t.get_type", "t.type");
|
|
||||||
CMD2_REDIRECT_TRACKER("t.get_url", "t.url");
|
|
||||||
CMD2_REDIRECT_TRACKER("t.set_enabled", "t.is_enabled.set");
|
|
||||||
|
|
||||||
//
|
|
||||||
// File:
|
|
||||||
//
|
|
||||||
|
|
||||||
CMD2_REDIRECT_FILE ("f.get_completed_chunks", "f.completed_chunks");
|
|
||||||
CMD2_REDIRECT_FILE ("f.get_frozen_path", "f.frozen_path");
|
|
||||||
CMD2_REDIRECT_FILE ("f.get_last_touched", "f.last_touched");
|
|
||||||
CMD2_REDIRECT_FILE ("f.get_match_depth_next", "f.match_depth_next");
|
|
||||||
CMD2_REDIRECT_FILE ("f.get_match_depth_prev", "f.match_depth_prev");
|
|
||||||
CMD2_REDIRECT_FILE ("f.get_offset", "f.offset");
|
|
||||||
CMD2_REDIRECT_FILE ("f.get_path", "f.path");
|
|
||||||
CMD2_REDIRECT_FILE ("f.get_path_components", "f.path_components");
|
|
||||||
CMD2_REDIRECT_FILE ("f.get_path_depth", "f.path_depth");
|
|
||||||
CMD2_REDIRECT_FILE ("f.get_priority", "f.priority");
|
|
||||||
CMD2_REDIRECT_FILE ("f.get_range_first", "f.range_first");
|
|
||||||
CMD2_REDIRECT_FILE ("f.get_range_second", "f.range_second");
|
|
||||||
CMD2_REDIRECT_FILE ("f.get_size_bytes", "f.size_bytes");
|
|
||||||
CMD2_REDIRECT_FILE ("f.get_size_chunks", "f.size_chunks");
|
|
||||||
CMD2_REDIRECT_FILE ("f.set_priority", "f.priority.set");
|
|
||||||
CMD2_REDIRECT_FILE ("fi.get_filename_last", "fi.filename_last");
|
|
||||||
|
|
||||||
//
|
|
||||||
// Peer:
|
|
||||||
//
|
|
||||||
|
|
||||||
CMD2_REDIRECT ("p.get_address", "p.address");
|
|
||||||
CMD2_REDIRECT ("p.get_client_version", "p.client_version");
|
|
||||||
CMD2_REDIRECT ("p.get_completed_percent", "p.completed_percent");
|
|
||||||
CMD2_REDIRECT ("p.get_down_rate", "p.down_rate");
|
|
||||||
CMD2_REDIRECT ("p.get_down_total", "p.down_total");
|
|
||||||
CMD2_REDIRECT ("p.get_id", "p.id");
|
|
||||||
CMD2_REDIRECT ("p.get_id_html", "p.id_html");
|
|
||||||
CMD2_REDIRECT ("p.get_options_str", "p.options_str");
|
|
||||||
CMD2_REDIRECT ("p.get_peer_rate", "p.peer_rate");
|
|
||||||
CMD2_REDIRECT ("p.get_peer_total", "p.peer_total");
|
|
||||||
CMD2_REDIRECT ("p.get_port", "p.port");
|
|
||||||
CMD2_REDIRECT ("p.get_up_rate", "p.up_rate");
|
|
||||||
CMD2_REDIRECT ("p.get_up_total", "p.up_total");
|
|
||||||
|
|
||||||
//
|
|
||||||
// View:
|
|
||||||
//
|
|
||||||
|
|
||||||
CMD2_REDIRECT_GENERIC("view_add", "view.add");
|
|
||||||
CMD2_REDIRECT_GENERIC("view_filter", "view.filter");
|
|
||||||
CMD2_REDIRECT_GENERIC("view_filter_on", "view.filter_on");
|
|
||||||
CMD2_REDIRECT_GENERIC("view_list", "view.list");
|
|
||||||
CMD2_REDIRECT_GENERIC("view_set", "view.set");
|
|
||||||
CMD2_REDIRECT_GENERIC("view_sort", "view.sort");
|
|
||||||
CMD2_REDIRECT_GENERIC("view_sort_current", "view.sort_current");
|
|
||||||
CMD2_REDIRECT_GENERIC("view_sort_new", "view.sort_new");
|
|
||||||
|
|
||||||
// Rename these to avoid conflicts with old style.
|
|
||||||
CMD2_REDIRECT_GENERIC("d.multicall", "d.multicall2");
|
|
||||||
|
|
||||||
CMD2_REDIRECT_GENERIC("execute_throw", "execute.throw");
|
|
||||||
CMD2_REDIRECT_GENERIC("execute_nothrow", "execute.nothrow");
|
|
||||||
CMD2_REDIRECT_GENERIC("execute_raw", "execute.raw");
|
|
||||||
CMD2_REDIRECT_GENERIC("execute_raw_nothrow", "execute.raw_nothrow");
|
|
||||||
CMD2_REDIRECT_GENERIC("execute_capture", "execute.capture");
|
|
||||||
CMD2_REDIRECT_GENERIC("execute_capture_nothrow", "execute.capture_nothrow");
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int firstArg = parse_options(control, argc, argv);
|
int firstArg = parse_options(control, argc, argv);
|
||||||
|
|
||||||
if (OptionParser::has_flag('n', argc, argv)) {
|
if (OptionParser::has_flag('n', argc, argv)) {
|
||||||
lt_log_print(torrent::LOG_WARN, "Ignoring ~/.rtorrent.rc.");
|
lt_log_print(torrent::LOG_WARN, "Ignoring rtorrent.rc.");
|
||||||
} else {
|
} else {
|
||||||
rpc::parse_command_single(rpc::make_target(), "try_import = ~/.rtorrent.rc");
|
char* config_dir = std::getenv("XDG_CONFIG_HOME");
|
||||||
|
char* home_dir = std::getenv("HOME");
|
||||||
|
|
||||||
|
if (config_dir != NULL && config_dir[0] == '/' &&
|
||||||
|
access((std::string(config_dir) + "/rtorrent/rtorrent.rc").c_str(), F_OK) != -1) {
|
||||||
|
rpc::parse_command_single(rpc::make_target(), "try_import = " + std::string(config_dir) + "/rtorrent/rtorrent.rc");
|
||||||
|
} else if (home_dir != NULL && access((std::string(home_dir) + "/.config/rtorrent/rtorrent.rc").c_str(), F_OK) != -1) {
|
||||||
|
rpc::parse_command_single(rpc::make_target(), "try_import = ~/.config/rtorrent/rtorrent.rc");
|
||||||
|
} else {
|
||||||
|
rpc::parse_command_single(rpc::make_target(), "try_import = ~/.rtorrent.rc");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
control->initialize();
|
control->initialize();
|
||||||
@@ -1004,7 +625,7 @@ print_help() {
|
|||||||
std::cout << "Usage: rtorrent [OPTIONS]... [FILE]... [URL]..." << std::endl;
|
std::cout << "Usage: rtorrent [OPTIONS]... [FILE]... [URL]..." << std::endl;
|
||||||
std::cout << " -D Enable deprecated commands" << std::endl;
|
std::cout << " -D Enable deprecated commands" << std::endl;
|
||||||
std::cout << " -h Display this very helpful text" << std::endl;
|
std::cout << " -h Display this very helpful text" << std::endl;
|
||||||
std::cout << " -n Don't try to load ~/.rtorrent.rc on startup" << std::endl;
|
std::cout << " -n Don't try to load rtorrent.rc on startup" << std::endl;
|
||||||
std::cout << " -b <a.b.c.d> Bind the listening socket to this IP" << std::endl;
|
std::cout << " -b <a.b.c.d> Bind the listening socket to this IP" << std::endl;
|
||||||
std::cout << " -i <a.b.c.d> Change the IP that is sent to the tracker" << std::endl;
|
std::cout << " -i <a.b.c.d> Change the IP that is sent to the tracker" << std::endl;
|
||||||
std::cout << " -p <int>-<int> Set port range for incoming connections" << std::endl;
|
std::cout << " -p <int>-<int> Set port range for incoming connections" << std::endl;
|
||||||
@@ -1017,6 +638,7 @@ print_help() {
|
|||||||
std::cout << " ^s Start torrent" << std::endl;
|
std::cout << " ^s Start torrent" << std::endl;
|
||||||
std::cout << " ^d Stop torrent or delete a stopped torrent" << std::endl;
|
std::cout << " ^d Stop torrent or delete a stopped torrent" << std::endl;
|
||||||
std::cout << " ^r Manually initiate hash checking" << std::endl;
|
std::cout << " ^r Manually initiate hash checking" << std::endl;
|
||||||
|
std::cout << " ^o Change the destination directory of the download. The torrent must be closed." << std::endl;
|
||||||
std::cout << " ^q Initiate shutdown or skip shutdown process" << std::endl;
|
std::cout << " ^q Initiate shutdown or skip shutdown process" << std::endl;
|
||||||
std::cout << " a,s,d,z,x,c Adjust upload throttle" << std::endl;
|
std::cout << " a,s,d,z,x,c Adjust upload throttle" << std::endl;
|
||||||
std::cout << " A,S,D,Z,X,C Adjust download throttle" << std::endl;
|
std::cout << " A,S,D,Z,X,C Adjust download throttle" << std::endl;
|
||||||
|
|||||||
+1
-1
@@ -77,7 +77,7 @@ command_base_call_value_base(command_base* rawCommand, target_type target, const
|
|||||||
return command_base::_call<typename command_value_function<T>::type, T>(rawCommand, target, val);
|
return command_base::_call<typename command_value_function<T>::type, T>(rawCommand, target, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
return command_base::_call<typename command_value_function<T>::type, T>(rawCommand, target, arg.as_value());
|
return command_base::_call<typename command_value_function<T>::type, T>(rawCommand, target, unit * arg.as_value());
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> const torrent::Object
|
template <typename T> const torrent::Object
|
||||||
|
|||||||
+1
-1
@@ -194,7 +194,7 @@ Download::create_info() {
|
|||||||
element->push_column("Upload:", te_command("cat=$convert.kb=$d.up.rate=,\" KB / \",$convert.xb=$d.up.total="));
|
element->push_column("Upload:", te_command("cat=$convert.kb=$d.up.rate=,\" KB / \",$convert.xb=$d.up.total="));
|
||||||
element->push_column("Download:", te_command("cat=$convert.kb=$d.down.rate=,\" KB / \",$convert.xb=$d.down.total="));
|
element->push_column("Download:", te_command("cat=$convert.kb=$d.down.rate=,\" KB / \",$convert.xb=$d.down.total="));
|
||||||
element->push_column("Skipped:", te_command("cat=$convert.kb=$d.skip.rate=,\" KB / \",$convert.xb=$d.skip.total="));
|
element->push_column("Skipped:", te_command("cat=$convert.kb=$d.skip.rate=,\" KB / \",$convert.xb=$d.skip.total="));
|
||||||
element->push_column("Preload:", te_command("cat=$pieces.preload.type=,\" / \",$pieces.stats_preloaded=,\" / \",$pieces.stats_preloaded="));
|
element->push_column("Preload:", te_command("cat=$pieces.preload.type=,\" / \",$pieces.stats_preloaded=,\" / \",$pieces.stats_not_preloaded="));
|
||||||
|
|
||||||
element->set_column_width(element->column_width() + 1);
|
element->set_column_width(element->column_width() + 1);
|
||||||
|
|
||||||
|
|||||||
@@ -99,6 +99,8 @@ ElementDownloadList::ElementDownloadList() :
|
|||||||
|
|
||||||
m_bindings[KEY_UP] = m_bindings['P' - '@'] = std::bind(&ElementDownloadList::receive_prev, this);
|
m_bindings[KEY_UP] = m_bindings['P' - '@'] = std::bind(&ElementDownloadList::receive_prev, this);
|
||||||
m_bindings[KEY_DOWN] = m_bindings['N' - '@'] = std::bind(&ElementDownloadList::receive_next, this);
|
m_bindings[KEY_DOWN] = m_bindings['N' - '@'] = std::bind(&ElementDownloadList::receive_next, this);
|
||||||
|
|
||||||
|
m_bindings['L'] = std::bind(&ElementDownloadList::toggle_layout, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -221,4 +223,14 @@ ElementDownloadList::receive_change_view(const std::string& name) {
|
|||||||
set_view(*itr);
|
set_view(*itr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ElementDownloadList::toggle_layout() {
|
||||||
|
const std::string layout_name = rpc::call_command_string("ui.torrent_list.layout");
|
||||||
|
|
||||||
|
if (layout_name == "full") {
|
||||||
|
rpc::call_command("ui.torrent_list.layout.set", "compact");
|
||||||
|
} else if (layout_name == "compact") {
|
||||||
|
rpc::call_command("ui.torrent_list.layout.set", "full");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -77,6 +77,8 @@ public:
|
|||||||
|
|
||||||
void receive_change_view(const std::string& name);
|
void receive_change_view(const std::string& name);
|
||||||
|
|
||||||
|
void toggle_layout();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
WDownloadList* m_window;
|
WDownloadList* m_window;
|
||||||
core::View* m_view;
|
core::View* m_view;
|
||||||
|
|||||||
@@ -118,8 +118,8 @@ ElementPeerList::create_info() {
|
|||||||
element->push_back("");
|
element->push_back("");
|
||||||
element->push_column("Snubbed:", te_command("if=$p.is_snubbed=,yes,no"));
|
element->push_column("Snubbed:", te_command("if=$p.is_snubbed=,yes,no"));
|
||||||
element->push_column("Done:", te_command("p.completed_percent="));
|
element->push_column("Done:", te_command("p.completed_percent="));
|
||||||
element->push_column("Rate:", te_command("cat=$convert.kb=$p.up_rate=,\\ KB\\ ,$convert.kb=$p.down_rate=,\\ KB"));
|
element->push_column("Rate:", te_command("cat=$convert.xb=$p.up_rate=,\\ ,$convert.xb=$p.down_rate="));
|
||||||
element->push_column("Total:", te_command("cat=$convert.kb=$p.up_total=,\\ KB\\ ,$convert.kb=$p.down_total=,\\ KB"));
|
element->push_column("Total:", te_command("cat=$convert.xb=$p.up_total=,\\ ,$convert.xb=$p.down_total="));
|
||||||
|
|
||||||
element->set_column_width(element->column_width() + 1);
|
element->set_column_width(element->column_width() + 1);
|
||||||
element->set_error_handler(new display::TextElementCString("No peer selected."));
|
element->set_error_handler(new display::TextElementCString("No peer selected."));
|
||||||
|
|||||||
Reference in New Issue
Block a user