Compare commits

...

122 Commits

Author SHA1 Message Date
rakshasa a88cab6d2e Released v0.9.0. 2024-09-29 11:06:14 +00:00
rakshasa 9a93281ded Merge branch 'stickz-session-fix' 2024-09-07 08:29:22 +00:00
rakshasa 133ce36570 Fixed goto warning. 2024-09-07 08:29:00 +00:00
rakshasa a142301d02 Merge branch 'session-fix' of github.com:stickz/rtorrent-rak into stickz-session-fix 2024-09-07 08:17:07 +00:00
rakshasa f04e512887 Merge branch 'stickz-memory-leak' 2024-09-07 08:02:55 +00:00
rakshasa d32d59315d Merge branch 'memory-leak' of github.com:stickz/rtorrent-rak into stickz-memory-leak 2024-09-07 07:54:00 +00:00
rakshasa 86e85ae485 Merge branch 'stickz-lto-fix' 2024-09-07 06:29:21 +00:00
stickz 6e9902c23b Fix critical memory leak
This commit fixes a critical memory leak with the inserting RPC commands. We must initialize the cmd_flags with the delete key, otherwise they hang around in memory forever; potentially leaking significant amounts of resources.
2024-09-06 11:16:47 -04:00
stickz d4427931a2 Fix session file data corruption
From https://github.com/jesec/rtorrent/commit/f9a875b633eb083ec82f89ebeae8678ca424e8b2

This commit ensures session files land on the disk in the event of a system crash or power outage. It prevents data corruption of rTorrent session files, which causes torrent client breakage.

Optimizations from the initial implementation include
1) Skipping unnecessary file metadata updates during the sync process.
2) Skipping variable initialization since open will assign -1 on failure.
2024-09-06 11:05:35 -04:00
stickz ea3828a17e Fix Link Time Optimizations
This commit fixes compiling rTorrent with LTO (Link Time Optimizations). We just need to rename from variables in the directory_entry structure to avoid ODR and ZLIB conflicts.
2024-09-01 08:20:01 -04:00
rakshasa 4e246a401f Remove decision structure for popcount_wrapper
The decision structure is very costly. It's significantly faster to work with long long than to use it.
2024-08-31 12:14:50 +00:00
rakshasa eacf9798e2 commit 30addc1a5e
Author: kannibalox <kannibalox@gmail.com>
Date:   Mon Jun 10 13:09:29 2024 -0400

    Use regular iterators intead of bucket-local ones

    Trying to manually predict which bucket a hashed key will land in does not
    appear to be well-defined behavior.

    Fixes #1285
2024-08-20 17:56:03 +00:00
rakshasa 892e595015 Added PKG_CHECK_EXISTS exception. 2024-08-09 13:06:14 +00:00
Jari Sundell 1da0e3476d Removed stray spaces. 2023-03-16 22:10:38 +01:00
Jari Sundell c0a5a55444 Disable delay tracker scrape on start. 2023-03-16 22:10:38 +01:00
stickz 551712f842 Fix typo in "trackers.delay_scrape" 2023-03-16 22:10:38 +01:00
stickz c7c290a86b Add "trackers.delay_scrape" command 2023-03-16 22:10:38 +01:00
stickz 2e1a499942 Don't delay scraping for newly added torrents 2023-03-16 22:10:38 +01:00
stickz c86f0d0333 Don't force the trackers to scrape when rTorrent first starts
rTorrent will do this gradually, so we can start connecting to peers right away.

This patch shaves approximately 5 minutes off the start time with thousands of torrents.
2023-03-16 22:10:38 +01:00
Aleksa Sarai 92bec88d09 utils: lockfile: avoid stack overflow for lockfile buffer
There appears to have been some change on openSUSE (likely some new
hardening flags for builds, or some glibc hardening) such that incorrect
buffer handling results in a segfault even if the buffer is never
overflowed.

Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
2023-03-10 22:22:36 +01:00
Jari Sundell d067bd802e Create FUNDING.yml 2022-09-08 05:08:17 +09:00
Jari Sundell 50924eeda0 Updated paypal link 2022-09-08 05:04:14 +09:00
Jari Sundell 1e40014482 Added rbedit to README. 2021-12-13 04:07:40 +09:00
Jari Sundell 8cafb55881 Updated ADA address. 2021-11-25 02:12:52 +09:00
Jari Sundell a6bc99bb82 Updated and cleaned up automake. (#1102) 2021-08-07 17:49:23 +09:00
Jari Sundell 52ceb39ca3 Updated release link. 2021-08-04 14:27:15 +09:00
Jari Sundell 926893ee62 Update README.md 2021-08-04 00:18:42 +09:00
Jari Sundell cf13789f8c Update README.md 2021-07-20 10:35:14 +09:00
rakshasa d15d93be88 Added ipv6 options. 2021-06-21 21:14:48 +09:00
rakshasa 582e4e4025 Added '--disable-execinfo' option to configure. 2021-06-16 23:29:01 +09:00
rakshasa 952777d75e Added commands to update choke queue. 2021-05-01 19:45:50 +09:00
rakshasa 19dbaa7442 Added missing ax_execinfo.m4 file. 2021-04-04 14:59:36 +09:00
rakshasa 3f72e27603 Replaced custom execinfo autoconf test. 2021-02-27 22:13:01 +09:00
rakshasa e267e8bc07 Fixed automake required files. 2021-02-25 00:05:27 +09:00
Jari Sundell 79765768ff Update README.md 2019-12-25 23:40:57 +09:00
Jari Sundell 8cc1d8f2c5 Optimize build by using a single makefile file. (#941) 2019-12-06 00:35:47 +09:00
Trog 3798de01a0 few missing sub-commands of network and throttle for the RPC interface (#937) 2019-12-01 14:55:23 +09:00
Jari Sundell 8ac98c6d3a New readme. 2019-10-03 13:25:35 +09:00
rakshasa 81500adc53 Remove obsolete check. 2019-09-11 01:51:47 +09:00
lps-rocks 14d7121185 Increase maximum SCGI request to 16MB (#905) 2019-08-29 00:44:09 +09:00
Jari Sundell 7659cd0ec0 Backport changes from feature-bind. 2019-08-23 23:25:24 +09:00
rakshasa f43f9e430d Merge branch 'chros73-ui_mod_status_mod' 2019-08-02 00:13:41 +09:00
chros f22475d1bf Modify throttle status bar mod to be able to display multiple values (See #6) 2019-07-27 11:22:56 +01:00
Jari Sundell b697a4608b Merge pull request #898 from Nicholi/log_append
Added log.append_file command
2019-07-26 20:08:09 +09:00
nicholi 765665fc28 When opening log files use new append parameter. Also added append_gz_file command. 2019-07-26 01:03:57 -07:00
nicholi 5f70986099 Added log.append_file. 2019-07-24 00:46:17 -07:00
rakshasa 6154d16987 Bumped to version 0.9.8. 2019-07-19 13:38:33 +02:00
rakshasa a5e8631cba Added log.close. 2019-07-17 19:41:23 +02:00
rakshasa 07dcd04357 Revert to only using ax_with_curses.m4, and upgrade it to version 16 which seems to be the last unborked version. 2019-07-13 14:36:05 +02:00
rakshasa 863de44c18 Added d.tracker_announce.force. 2019-07-11 17:46:35 +02:00
Jari Sundell 24135ed48e Merge pull request #763 from MindTooth/travis_path_fix
travis: Fix test in wrong path, and jobs parallelization
2019-07-09 21:24:12 +02:00
rakshasa 83709d28c9 Merge branch 'toff-master' 2019-07-08 21:40:02 +02:00
rakshasa 859d5a9578 Merge branch 'master' of https://github.com/toff/rtorrent into toff-master 2019-07-08 21:39:31 +02:00
rakshasa adc9b1dec5 Merge branch 'zetafunction-autoconf' 2019-07-08 20:30:09 +02:00
rakshasa 285972a20d Fixed configure.ac. (zetafunction) 2019-07-08 20:29:43 +02:00
Jari Sundell 3ec2f52db5 Merge pull request #857 from skangas/view-keys-man
Update change view keys to 0-9 in man page
2019-07-08 19:41:20 +02:00
rakshasa ac64fc3f63 Added _GNU_SOURCE to fallocate test. (neheb) 2019-07-08 19:37:17 +02:00
rakshasa b26dc42f3a Merge branch 'ffontaine-master' 2019-06-10 01:18:32 +09:00
rakshasa 6572088aec Merge branch 'master' of https://github.com/ffontaine/rtorrent into ffontaine-master 2019-06-09 23:51:22 +09:00
rakshasa 31a0ea1a2d Merge branch 'master' of github.com:rakshasa/rtorrent 2019-06-09 17:10:17 +09:00
rakshasa 2d72a0d2c0 Merge branch 'chros73-input_history_with_categories' 2019-06-09 17:09:59 +09:00
rakshasa a3a384b049 Fixed minor issues. 2019-06-09 17:09:35 +09:00
Jari Sundell f37dd0d5c2 Merge pull request #722 from g0tmi1k/config
Update rtorrent.rc
2019-06-09 16:27:53 +09:00
Jari Sundell 78c25011cd Merge pull request #824 from Irishsmurf/patch-1
Fix typo in README
2019-06-09 16:25:07 +09:00
rakshasa 35d98c91e0 Merge branch 'master' of github.com:rakshasa/rtorrent 2019-06-09 16:24:18 +09:00
rakshasa 27811db659 Merge branch 'ss23-749_ncurses_tinfo' 2019-06-09 16:24:00 +09:00
rakshasa 4e73ce6bfd Merge branch '749_ncurses_tinfo' of https://github.com/ss23/rtorrent into ss23-749_ncurses_tinfo 2019-06-09 15:43:54 +09:00
Jari Sundell 8c8e73bb72 Merge pull request #794 from waveletlet/master
Edit getsession() for 0.9 config format
2019-06-09 15:17:18 +09:00
Jari Sundell 0d5b344d2a Switch to C++11 MRT RNG for random bytes
Switching to a better RNG for generating strings will prevent the common peerID collisions the rTorrent client has been seeing for YEARS in #440 and #318.
2019-06-08 16:22:47 +09:00
Fabrice Fontaine 703cac9a42 Fix cross compilation, based on OpenWRT patch.
[Vincent: tweak the patch for version 0.13.6]
[Bernd: tweak the patch for version 0.13.7]

Signed-off-by: Gustavo Zacarias <gustavo@zacarias.com.ar>
Signed-off-by: Vicente Olivert Riera <Vincent.Riera@imgtec.com>
Signed-off-by: Bernd Kuhls <bernd.kuhls@t-online.de>
[Retrieved from:
https://git.buildroot.net/buildroot/tree/package/libtorrent/0001-Fix-cross-compilation-based-on-OpenWRT-patch.patch]
Signed-off-by: Fabrice Fontaine <fontaine.fabrice@gmail.com>
2019-04-20 21:37:26 +02:00
Stefan Kangas e6c008b2b7 Update change view keys to 0-9 in man page 2019-04-08 10:03:15 +02:00
Daniel Cheng 81de60e0ae Update global CFLAGS/CXXFLAGS/LIBS at the end of configure.ac
Changes to CFLAGS/CXXFLAGS/LIBS affect following lines in configure.ac.
As originally written, this would cause random libraries, such as
libtorrent, to be linked into the autoconf test program. Occasionally,
this would cause the things like the pkgconfig checks to fail with
mysterious linker errors (e.g. rakshasa/rtorrent#156).

Instead, only populate these global flags with the additional flags for
dependencies at the very end, before the invocation of AC_OUTPUT.
2019-01-13 23:37:36 -08:00
David K c361d6010e Fix typo in README
s/nessesary/necessary
2019-01-03 21:10:09 +00:00
Birger J. Nordølum 724dc088ca travis: Fix test in wrong path, and jobs parallelization 2018-11-14 22:05:19 +01:00
rakshasa c62fa6a756 Merge branch 'pyroscope-cmd-d_multicall_filtered' 2018-10-20 22:00:21 +09:00
rakshasa 656d735de7 Merge branch 'cmd-d_multicall_filtered' of https://github.com/pyroscope/rtorrent into pyroscope-cmd-d_multicall_filtered 2018-10-20 21:47:36 +09:00
rakshasa 408013478c Merge branch 'pyroscope-cmd-compare' 2018-10-20 21:38:39 +09:00
rakshasa fa61b8c11c Merge branch 'cmd-compare' of https://github.com/pyroscope/rtorrent into pyroscope-cmd-compare 2018-10-20 21:38:28 +09:00
rakshasa 1339a3ace9 Merge branch 'chros73-event_system_commands' 2018-10-20 21:35:35 +09:00
rakshasa 4ba128163f Merge branch 'event_system_commands' of https://github.com/chros73/rtorrent into chros73-event_system_commands 2018-10-20 21:30:39 +09:00
rakshasa 908a99751f Merge branch 'chros73-list_type_method_fix' 2018-10-20 21:22:13 +09:00
waveletlet c115640934 Edit getsession() for 0.9 config format 2018-10-18 19:39:32 -03:00
waveletlet 9043c46815 Edit getsession() for 0.9 config format 2018-10-18 19:36:49 -03:00
chros 1f418366d4 Fix 'list' type method (See #25) 2018-10-01 23:27:58 +01:00
toff 30c78c7034 Merge branch 'master' into master 2018-09-29 11:31:06 +02:00
chros 74435f6c40 Add 'event.system.startup_done/shutdown' commands/events (Closes #24) 2018-09-26 15:12:20 +01:00
Jari Sundell a4b281afa4 Merge pull request #753 from ss23/cross_compiling-execinfo
Use AC_COMPILE instead of AC_RUN to check for execinfo.h
2018-06-27 18:36:21 +09:00
Stephen Shkardoon f84670dd63 Use AC_COMPILE instead of AC_RUN to check for execinfo.h
This way enables cross compiling, since we don't need to run anything during the configure script.
2018-06-25 20:14:43 +12:00
rakshasa f0207ce654 Added "try" command that catches input_errors and logs them on rpc_events. 2018-06-23 17:01:34 +09:00
Stephen Shkardoon 9cce5a0bd1 Fix compiling if ncurses was built using --with-terminfo
Resolves #749
Patch from https://bugs.gentoo.org/658390
2018-06-20 01:50:45 +12:00
g0tmi1k 95cff549c6 Removed stop_untied at @pyroscope's request 2018-06-19 10:56:45 +01:00
g0tmi1k 92898a9831 Use session.path for rpc.socket in rtorrent.rc 2018-06-19 10:56:36 +01:00
g0tmi1k fcfbf0e79f Fix typos in rtorrent.rc 2018-06-19 10:51:35 +01:00
g0tmi1k 680b47c197 Add example rtorrent.rc
Source: https://github.com/rakshasa/rtorrent/wiki/CONFIG-Template
2018-06-19 10:48:25 +01:00
Jari Sundell 7804ed3009 Merge pull request #748 from pyroscope/d_custom_if_z-empty-val
d.custom.if_z: return default also for existing but empty value
2018-06-19 18:11:00 +09:00
pyroscope d9b39f5ac6 d.custom.if_z: return default also for existing but empty value 2018-06-18 19:41:53 +02:00
Jari Sundell 08aa287cfc Merge pull request #614 from chros73/adjustable_global_throttle_steps
Make global throttle steps adjustable
2018-06-19 00:08:32 +09:00
Jari Sundell 851d1902a0 Merge pull request #738 from pyroscope/d_custom_if_z+keys+items
add d.custom.if_z + d.custom.keys + d.custom.items
2018-06-19 00:06:23 +09:00
Jari Sundell b600ff0c0e Merge pull request #742 from pyroscope/cmd-event-view-change
add 'event.view.hide/show' commands / events
2018-06-16 18:48:10 +09:00
Jari Sundell a639461c4a Merge pull request #743 from pyroscope/fix-log-xmlrpc-close
fix: properly close the XMLRPC log, resetting the handle after close
2018-06-16 18:46:11 +09:00
Jari Sundell c1057d5ac7 Merge pull request #745 from pyroscope/cmd-value
add 'value' command / conversion op
2018-06-16 18:33:39 +09:00
pyroscope 2ac65ad7e1 add 'value' command / conversion op 2018-06-16 06:54:39 +02:00
pyroscope a4939cb9fd add 'compare' command / operator 2018-06-15 22:36:55 +02:00
pyroscope 3d88ac2cc8 fix: properly close the XMLRPC log, resetting the handle after close 2018-06-15 19:38:12 +02:00
pyroscope f37fefcc54 add 'event.view.hide/show' commands / events 2018-06-15 18:36:01 +02:00
pyroscope 885836f68b add 'd.multicall.filtered' command 2018-06-15 00:40:00 +02:00
pyroscope ca4c3bee8d add d.custom.if_z + d.custom.keys + d.custom.items 2018-06-14 20:32:28 +02:00
Jari Sundell 6c278668e4 Merge pull request #587 from pyroscope/add-position-display-in-title
add '[ X of Y ]' to title bar
2018-06-11 23:15:21 +09:00
Jari Sundell 1665437588 Merge pull request #576 from chros73/simple_math_commands
Add support for basic arithmetic operators
2018-06-11 23:06:37 +09:00
chros 6dc87e499a Fix bugs in 'math.*' commands (See #14) 2018-06-01 11:51:42 +01:00
chros 6c11a1dbb0 Fix error message in as_vector method (See #14) 2018-03-03 09:08:28 +00:00
chros 29d57e858a Make global throttle steps adjustable (Closes #17) 2017-06-06 09:54:01 +01:00
Toff 7ec9b6685b Merge pyroscope and chros73 suggestion: Command name uniformisation.
ui.console.log.tempfilter => view.temp_filter.log
2017-05-06 11:17:25 +02:00
Toff d5de8a91d1 Merge chros73 suggestions (settings to exclude views and hide info logs)
- Certain views can be excluded from subfiltering via view.temp_filter.excluded config option
    - its default value: "default,started,stopped"
    - example usage in config: view.temp_filter.excluded.set="default,started,stopped,leeching"

- Log messages can be displayed when temp filtering occured
    - disabled by default
    - can be enabled with: ui.console.log.tempfilter.set=1
2017-04-17 14:56:11 +02:00
pyroscope 4d6f6fe335 add '[ X of Y ]' to title bar 2017-04-01 12:30:10 +02:00
chros 13676f06e5 Add median command (See #14) 2017-03-11 11:40:08 +00:00
chros 6cb176ada3 Add more info to throw message in math commands (See #14) 2017-03-07 13:12:18 +00:00
chros 8b6a1ad079 Add count and average commands (See #14) 2017-03-07 12:57:31 +00:00
chros 3002c95b2c Rename couple of arithmetic commands (See #14) 2017-03-06 19:41:49 +00:00
chros 9590949fa7 Add support for basic arithmetic operators (See #14) 2017-03-06 13:06:59 +00:00
Toff 6ee61ee6b5 Merge chros73 suggestions (filter indicator, "start/stopped" view case)
- Suffix filtered view name with "(filtered)"
- Add a check to not filter "start" and "stopped" view
2017-01-08 19:45:46 +01:00
Toff e15270271d Add a temporary name filter for the main view.
By using 'F' in the main view you can enter a regex
that will be used to filter the view based on the torrent name.
To remove the filter set the input to empty.
This is adding a 'view.temp_filter' property and a 'match{}' function.
For example with Ctrl+X you could do:
command> view.temp_filter=main,"match={d.name=,.*linux.*iso}"
2016-10-31 12:19:41 +01:00
115 changed files with 4145 additions and 1793 deletions
+7
View File
@@ -0,0 +1,7 @@
;;; Directory Local Variables
;;; For more information see (info "(emacs) Directory Variables")
((c++-mode
(flycheck-clang-language-standard . "c++11")
(flycheck-gcc-language-standard . "c++11")))
+13
View File
@@ -0,0 +1,13 @@
# These are supported funding model platforms
github: [rakshasa]
patreon: rtorrent
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
custom: ['https://rakshasa.github.io/rtorrent/donate.html']
+14 -3
View File
@@ -1,5 +1,9 @@
language: cpp
env:
global:
- MAKEFLAGS="-j 12"
matrix:
include:
- compiler: clang
@@ -67,8 +71,15 @@ matrix:
# TODO: Use the same branch name if libtorrent has it.
before_install:
- git clone https://github.com/rakshasa/libtorrent.git
- cd libtorrent && ./autogen.sh && CXX="$COMPILER" ./configure && make -j12 && sudo make install
- |
pushd libtorrent \
&& (git checkout ${TRAVIS_BRANCH} || true) \
&& ./autogen.sh \
&& CXX="$COMPILER" ./configure --prefix=/usr \
&& make \
&& sudo make install \
&& popd
script:
- ./autogen.sh && CXX="$COMPILER" ./configure && make -j12
- if [ ! $SKIP_CHECK ]; then make -j12 check; fi
- ./autogen.sh && CXX="$COMPILER" ./configure && make
- if [ ! $SKIP_CHECK ]; then make check; fi
+254 -115
View File
@@ -1,81 +1,109 @@
Copyright 1994, 1995, 1996, 1999, 2000, 2001, 2002 Free Software
Installation Instructions
*************************
Copyright (C) 1994-1996, 1999-2002, 2004-2016 Free Software
Foundation, Inc.
This file is free documentation; the Free Software Foundation gives
unlimited permission to copy, distribute and modify it.
Copying and distribution of this file, with or without modification,
are permitted in any medium without royalty provided the copyright
notice and this notice are preserved. This file is offered as-is,
without warranty of any kind.
Basic Installation
==================
These are generic installation instructions.
Briefly, the shell command './configure && make && make install'
should configure, build, and install this package. The following
more-detailed instructions are generic; see the 'README' file for
instructions specific to this package. Some packages provide this
'INSTALL' file but do not implement all of the features documented
below. The lack of an optional feature in a given package is not
necessarily a bug. More recommendations for GNU packages can be found
in *note Makefile Conventions: (standards)Makefile Conventions.
The `configure' shell script attempts to guess correct values for
The 'configure' shell script attempts to guess correct values for
various system-dependent variables used during compilation. It uses
those values to create a `Makefile' in each directory of the package.
It may also create one or more `.h' files containing system-dependent
definitions. Finally, it creates a shell script `config.status' that
those values to create a 'Makefile' in each directory of the package.
It may also create one or more '.h' files containing system-dependent
definitions. Finally, it creates a shell script 'config.status' that
you can run in the future to recreate the current configuration, and a
file `config.log' containing compiler output (useful mainly for
debugging `configure').
file 'config.log' containing compiler output (useful mainly for
debugging 'configure').
It can also use an optional file (typically called `config.cache'
and enabled with `--cache-file=config.cache' or simply `-C') that saves
the results of its tests to speed up reconfiguring. (Caching is
disabled by default to prevent problems with accidental use of stale
cache files.)
It can also use an optional file (typically called 'config.cache' and
enabled with '--cache-file=config.cache' or simply '-C') that saves the
results of its tests to speed up reconfiguring. Caching is disabled by
default to prevent problems with accidental use of stale cache files.
If you need to do unusual things to compile the package, please try
to figure out how `configure' could check whether to do them, and mail
diffs or instructions to the address given in the `README' so they can
to figure out how 'configure' could check whether to do them, and mail
diffs or instructions to the address given in the 'README' so they can
be considered for the next release. If you are using the cache, and at
some point `config.cache' contains results you don't want to keep, you
some point 'config.cache' contains results you don't want to keep, you
may remove or edit it.
The file `configure.ac' (or `configure.in') is used to create
`configure' by a program called `autoconf'. You only need
`configure.ac' if you want to change it or regenerate `configure' using
a newer version of `autoconf'.
The file 'configure.ac' (or 'configure.in') is used to create
'configure' by a program called 'autoconf'. You need 'configure.ac' if
you want to change it or regenerate 'configure' using a newer version of
'autoconf'.
The simplest way to compile this package is:
The simplest way to compile this package is:
1. `cd' to the directory containing the package's source code and type
`./configure' to configure the package for your system. If you're
using `csh' on an old version of System V, you might need to type
`sh ./configure' instead to prevent `csh' from trying to execute
`configure' itself.
1. 'cd' to the directory containing the package's source code and type
'./configure' to configure the package for your system.
Running `configure' takes awhile. While running, it prints some
messages telling which features it is checking for.
Running 'configure' might take a while. While running, it prints
some messages telling which features it is checking for.
2. Type `make' to compile the package.
2. Type 'make' to compile the package.
3. Optionally, type `make check' to run any self-tests that come with
the package.
3. Optionally, type 'make check' to run any self-tests that come with
the package, generally using the just-built uninstalled binaries.
4. Type `make install' to install the programs and any data files and
documentation.
4. Type 'make install' to install the programs and any data files and
documentation. When installing into a prefix owned by root, it is
recommended that the package be configured and built as a regular
user, and only the 'make install' phase executed with root
privileges.
5. You can remove the program binaries and object files from the
source code directory by typing `make clean'. To also remove the
files that `configure' created (so you can compile the package for
a different kind of computer), type `make distclean'. There is
also a `make maintainer-clean' target, but that is intended mainly
5. Optionally, type 'make installcheck' to repeat any self-tests, but
this time using the binaries in their final installed location.
This target does not install anything. Running this target as a
regular user, particularly if the prior 'make install' required
root privileges, verifies that the installation completed
correctly.
6. You can remove the program binaries and object files from the
source code directory by typing 'make clean'. To also remove the
files that 'configure' created (so you can compile the package for
a different kind of computer), type 'make distclean'. There is
also a 'make maintainer-clean' target, but that is intended mainly
for the package's developers. If you use it, you may have to get
all sorts of other programs in order to regenerate files that came
with the distribution.
7. Often, you can also type 'make uninstall' to remove the installed
files again. In practice, not all packages have tested that
uninstallation works correctly, even though it is required by the
GNU Coding Standards.
8. Some packages, particularly those that use Automake, provide 'make
distcheck', which can by used by developers to test that all other
targets like 'make install' and 'make uninstall' work correctly.
This target is generally not run by end users.
Compilers and Options
=====================
Some systems require unusual options for compilation or linking that
the `configure' script does not know about. Run `./configure --help'
the 'configure' script does not know about. Run './configure --help'
for details on some of the pertinent environment variables.
You can give `configure' initial values for configuration parameters
by setting variables in the command line or in the environment. Here
is an example:
You can give 'configure' initial values for configuration parameters
by setting variables in the command line or in the environment. Here is
an example:
./configure CC=c89 CFLAGS=-O2 LIBS=-lposix
./configure CC=c99 CFLAGS=-g LIBS=-lposix
*Note Defining Variables::, for more details.
@@ -84,146 +112,257 @@ Compiling For Multiple Architectures
You can compile the package for more than one kind of computer at the
same time, by placing the object files for each architecture in their
own directory. To do this, you must use a version of `make' that
supports the `VPATH' variable, such as GNU `make'. `cd' to the
own directory. To do this, you can use GNU 'make'. 'cd' to the
directory where you want the object files and executables to go and run
the `configure' script. `configure' automatically checks for the
source code in the directory that `configure' is in and in `..'.
the 'configure' script. 'configure' automatically checks for the source
code in the directory that 'configure' is in and in '..'. This is known
as a "VPATH" build.
If you have to use a `make' that does not support the `VPATH'
variable, you have to compile the package for one architecture at a
time in the source code directory. After you have installed the
package for one architecture, use `make distclean' before reconfiguring
for another architecture.
With a non-GNU 'make', it is safer to compile the package for one
architecture at a time in the source code directory. After you have
installed the package for one architecture, use 'make distclean' before
reconfiguring for another architecture.
On MacOS X 10.5 and later systems, you can create libraries and
executables that work on multiple system types--known as "fat" or
"universal" binaries--by specifying multiple '-arch' options to the
compiler but only a single '-arch' option to the preprocessor. Like
this:
./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
CPP="gcc -E" CXXCPP="g++ -E"
This is not guaranteed to produce working output in all cases, you
may have to build one architecture at a time and combine the results
using the 'lipo' tool if you have problems.
Installation Names
==================
By default, `make install' will install the package's files in
`/usr/local/bin', `/usr/local/man', etc. You can specify an
installation prefix other than `/usr/local' by giving `configure' the
option `--prefix=PATH'.
By default, 'make install' installs the package's commands under
'/usr/local/bin', include files under '/usr/local/include', etc. You
can specify an installation prefix other than '/usr/local' by giving
'configure' the option '--prefix=PREFIX', where PREFIX must be an
absolute file name.
You can specify separate installation prefixes for
architecture-specific files and architecture-independent files. If you
give `configure' the option `--exec-prefix=PATH', the package will use
PATH as the prefix for installing programs and libraries.
Documentation and other data files will still use the regular prefix.
pass the option '--exec-prefix=PREFIX' to 'configure', the package uses
PREFIX as the prefix for installing programs and libraries.
Documentation and other data files still use the regular prefix.
In addition, if you use an unusual directory layout you can give
options like `--bindir=PATH' to specify different values for particular
kinds of files. Run `configure --help' for a list of the directories
you can set and what kinds of files go in them.
options like '--bindir=DIR' to specify different values for particular
kinds of files. Run 'configure --help' for a list of the directories
you can set and what kinds of files go in them. In general, the default
for these options is expressed in terms of '${prefix}', so that
specifying just '--prefix' will affect all of the other directory
specifications that were not explicitly provided.
If the package supports it, you can cause programs to be installed
with an extra prefix or suffix on their names by giving `configure' the
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
The most portable way to affect installation locations is to pass the
correct locations to 'configure'; however, many packages provide one or
both of the following shortcuts of passing variable assignments to the
'make install' command line to change installation locations without
having to reconfigure or recompile.
The first method involves providing an override variable for each
affected directory. For example, 'make install
prefix=/alternate/directory' will choose an alternate location for all
directory configuration variables that were expressed in terms of
'${prefix}'. Any directories that were specified during 'configure',
but not in terms of '${prefix}', must each be overridden at install time
for the entire installation to be relocated. The approach of makefile
variable overrides for each directory variable is required by the GNU
Coding Standards, and ideally causes no recompilation. However, some
platforms have known limitations with the semantics of shared libraries
that end up requiring recompilation when using this method, particularly
noticeable in packages that use GNU Libtool.
The second method involves providing the 'DESTDIR' variable. For
example, 'make install DESTDIR=/alternate/directory' will prepend
'/alternate/directory' before all installation names. The approach of
'DESTDIR' overrides is not required by the GNU Coding Standards, and
does not work on platforms that have drive letters. On the other hand,
it does better at avoiding recompilation issues, and works well even
when some directory options were not specified in terms of '${prefix}'
at 'configure' time.
Optional Features
=================
Some packages pay attention to `--enable-FEATURE' options to
`configure', where FEATURE indicates an optional part of the package.
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
is something like `gnu-as' or `x' (for the X Window System). The
`README' should mention any `--enable-' and `--with-' options that the
If the package supports it, you can cause programs to be installed
with an extra prefix or suffix on their names by giving 'configure' the
option '--program-prefix=PREFIX' or '--program-suffix=SUFFIX'.
Some packages pay attention to '--enable-FEATURE' options to
'configure', where FEATURE indicates an optional part of the package.
They may also pay attention to '--with-PACKAGE' options, where PACKAGE
is something like 'gnu-as' or 'x' (for the X Window System). The
'README' should mention any '--enable-' and '--with-' options that the
package recognizes.
For packages that use the X Window System, `configure' can usually
For packages that use the X Window System, 'configure' can usually
find the X include and library files automatically, but if it doesn't,
you can use the `configure' options `--x-includes=DIR' and
`--x-libraries=DIR' to specify their locations.
you can use the 'configure' options '--x-includes=DIR' and
'--x-libraries=DIR' to specify their locations.
Some packages offer the ability to configure how verbose the
execution of 'make' will be. For these packages, running './configure
--enable-silent-rules' sets the default to minimal output, which can be
overridden with 'make V=1'; while running './configure
--disable-silent-rules' sets the default to verbose, which can be
overridden with 'make V=0'.
Particular systems
==================
On HP-UX, the default C compiler is not ANSI C compatible. If GNU CC
is not installed, it is recommended to use the following options in
order to use an ANSI C compiler:
./configure CC="cc -Ae -D_XOPEN_SOURCE=500"
and if that doesn't work, install pre-built binaries of GCC for HP-UX.
HP-UX 'make' updates targets which have the same time stamps as their
prerequisites, which makes it generally unusable when shipped generated
files such as 'configure' are involved. Use GNU 'make' instead.
On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot
parse its '<wchar.h>' header file. The option '-nodtk' can be used as a
workaround. If GNU CC is not installed, it is therefore recommended to
try
./configure CC="cc"
and if that doesn't work, try
./configure CC="cc -nodtk"
On Solaris, don't put '/usr/ucb' early in your 'PATH'. This
directory contains several dysfunctional programs; working variants of
these programs are available in '/usr/bin'. So, if you need '/usr/ucb'
in your 'PATH', put it _after_ '/usr/bin'.
On Haiku, software installed for all users goes in '/boot/common',
not '/usr/local'. It is recommended to use the following options:
./configure --prefix=/boot/common
Specifying the System Type
==========================
There may be some features `configure' cannot figure out
There may be some features 'configure' cannot figure out
automatically, but needs to determine by the type of machine the package
will run on. Usually, assuming the package is built to be run on the
_same_ architectures, `configure' can figure that out, but if it prints
_same_ architectures, 'configure' can figure that out, but if it prints
a message saying it cannot guess the machine type, give it the
`--build=TYPE' option. TYPE can either be a short name for the system
type, such as `sun4', or a canonical name which has the form:
'--build=TYPE' option. TYPE can either be a short name for the system
type, such as 'sun4', or a canonical name which has the form:
CPU-COMPANY-SYSTEM
where SYSTEM can have one of these forms:
OS KERNEL-OS
OS
KERNEL-OS
See the file `config.sub' for the possible values of each field. If
`config.sub' isn't included in this package, then this package doesn't
See the file 'config.sub' for the possible values of each field. If
'config.sub' isn't included in this package, then this package doesn't
need to know the machine type.
If you are _building_ compiler tools for cross-compiling, you should
use the `--target=TYPE' option to select the type of system they will
use the option '--target=TYPE' to select the type of system they will
produce code for.
If you want to _use_ a cross compiler, that generates code for a
platform different from the build platform, you should specify the
"host" platform (i.e., that on which the generated programs will
eventually be run) with `--host=TYPE'.
eventually be run) with '--host=TYPE'.
Sharing Defaults
================
If you want to set default values for `configure' scripts to share,
you can create a site shell script called `config.site' that gives
default values for variables like `CC', `cache_file', and `prefix'.
`configure' looks for `PREFIX/share/config.site' if it exists, then
`PREFIX/etc/config.site' if it exists. Or, you can set the
`CONFIG_SITE' environment variable to the location of the site script.
A warning: not all `configure' scripts look for a site script.
If you want to set default values for 'configure' scripts to share,
you can create a site shell script called 'config.site' that gives
default values for variables like 'CC', 'cache_file', and 'prefix'.
'configure' looks for 'PREFIX/share/config.site' if it exists, then
'PREFIX/etc/config.site' if it exists. Or, you can set the
'CONFIG_SITE' environment variable to the location of the site script.
A warning: not all 'configure' scripts look for a site script.
Defining Variables
==================
Variables not defined in a site shell script can be set in the
environment passed to `configure'. However, some packages may run
environment passed to 'configure'. However, some packages may run
configure again during the build, and the customized values of these
variables may be lost. In order to avoid this problem, you should set
them in the `configure' command line, using `VAR=value'. For example:
them in the 'configure' command line, using 'VAR=value'. For example:
./configure CC=/usr/local2/bin/gcc
will cause the specified gcc to be used as the C compiler (unless it is
causes the specified 'gcc' to be used as the C compiler (unless it is
overridden in the site shell script).
`configure' Invocation
Unfortunately, this technique does not work for 'CONFIG_SHELL' due to an
Autoconf limitation. Until the limitation is lifted, you can use this
workaround:
CONFIG_SHELL=/bin/bash ./configure CONFIG_SHELL=/bin/bash
'configure' Invocation
======================
`configure' recognizes the following options to control how it
'configure' recognizes the following options to control how it
operates.
`--help'
`-h'
Print a summary of the options to `configure', and exit.
'--help'
'-h'
Print a summary of all of the options to 'configure', and exit.
`--version'
`-V'
Print the version of Autoconf used to generate the `configure'
'--help=short'
'--help=recursive'
Print a summary of the options unique to this package's
'configure', and exit. The 'short' variant lists options used only
in the top level, while the 'recursive' variant lists options also
present in any nested packages.
'--version'
'-V'
Print the version of Autoconf used to generate the 'configure'
script, and exit.
`--cache-file=FILE'
'--cache-file=FILE'
Enable the cache: use and save the results of the tests in FILE,
traditionally `config.cache'. FILE defaults to `/dev/null' to
traditionally 'config.cache'. FILE defaults to '/dev/null' to
disable caching.
`--config-cache'
`-C'
Alias for `--cache-file=config.cache'.
'--config-cache'
'-C'
Alias for '--cache-file=config.cache'.
`--quiet'
`--silent'
`-q'
'--quiet'
'--silent'
'-q'
Do not print messages saying which checks are being made. To
suppress all normal output, redirect it to `/dev/null' (any error
suppress all normal output, redirect it to '/dev/null' (any error
messages will still be shown).
`--srcdir=DIR'
'--srcdir=DIR'
Look for the package's source code in directory DIR. Usually
`configure' can determine that directory automatically.
'configure' can determine that directory automatically.
`configure' also accepts some other, not widely useful, options. Run
`configure --help' for more details.
'--prefix=DIR'
Use DIR as the installation prefix. *note Installation Names:: for
more details, including other options available for fine-tuning the
installation locations.
'--no-create'
'-n'
Run the configure checks, but stop before creating any output
files.
'configure' also accepts some other, not widely useful, options. Run
'configure --help' for more details.
-1
View File
@@ -4,7 +4,6 @@ SUBDIRS = \
test
EXTRA_DIST= \
autogen.sh \
rak/address_info.h \
rak/algorithm.h \
rak/allocators.h \
+3 -3
View File
@@ -1,8 +1,8 @@
BUILDING
Run "./autogen.sh" to generate the configure scripts if
nessesary. The man page "doc/rtorrent.1" must be generated with
"docbook2man rtorrent.1.xml" if it is missing.
Run "aclocal -I scripts && autoconf -i && autoheader && automake --add-missing"
to generate the configure scripts if necessary. The man page "doc/rtorrent.1"
must be generated with "docbook2man rtorrent.1.xml" if it is missing.
Note that rtorrent follows the development of libtorrent closely, and
thus the versions must be in sync. This should not be nessesary in the
+34
View File
@@ -0,0 +1,34 @@
[![Donate](https://rakshasa.github.io/rtorrent/donate_paypal_green.svg)](https://paypal.me/jarisundelljp)
RTorrent BitTorrent Client
========
Introduction
------------
To learn how to use rTorrent visit the [Wiki](https://github.com/rakshasa/rtorrent/wiki).
Stable
------
* [https://github.com/rakshasa/rtorrent-archive/raw/master/libtorrent-0.13.8.tar.gz](https://github.com/rakshasa/rtorrent-archive/raw/master/libtorrent-0.13.8.tar.gz)
* [https://github.com/rakshasa/rtorrent-archive/raw/master/rtorrent-0.9.8.tar.gz](https://github.com/rakshasa/rtorrent-archive/raw/master/rtorrent-0.9.8.tar.gz)
Related Projects
----------------
* [https://github.com/rakshasa/rbedit](https://github.com/rakshasa/rbedit): A dependency-free bencode editor.
Donate to rTorrent development
------------------------------
* [Paypal](https://paypal.me/jarisundellno)
* [Patreon](https://www.patreon.com/rtorrent)
* [SubscribeStar](https://www.subscribestar.com/rtorrent)
* Bitcoin: 1MpmXm5AHtdBoDaLZstJw8nupJJaeKu8V8
* Etherium: 0x9AB1e3C3d8a875e870f161b3e9287Db0E6DAfF78
* Litecoin: LdyaVR67LBnTf6mAT4QJnjSG2Zk67qxmfQ
* Cardano: addr1qytaslmqmk6dspltw06sp0zf83dh09u79j49ceh5y26zdcccgq4ph7nmx6kgmzeldauj43254ey97f3x4xw49d86aguqwfhlte
Help keep rTorrent development going by donating to its creator.
-51
View File
@@ -1,51 +0,0 @@
#! /bin/sh
echo aclocal...
(aclocal --version) < /dev/null > /dev/null 2>&1 || {
echo aclocal not found
exit 1
}
aclocal -I ./scripts -I . ${ACLOCAL_FLAGS} || exit 1
echo autoheader...
(autoheader --version) < /dev/null > /dev/null 2>&1 || {
echo autoheader not found
exit 1
}
autoheader || exit 1
echo -n "libtoolize... "
if ( (glibtoolize --version) < /dev/null > /dev/null 2>&1 ); then
echo "using glibtoolize"
glibtoolize --automake --copy --force || exit 1
elif ( (libtoolize --version) < /dev/null > /dev/null 2>&1 ) ; then
echo "using libtoolize"
libtoolize --automake --copy --force || exit 1
else
echo "libtoolize nor glibtoolize not found"
exit 1
fi
echo automake...
(automake --version) < /dev/null > /dev/null 2>&1 || {
echo automake not found
exit 1
}
automake --add-missing --copy --gnu || exit 1
echo autoconf...
(autoconf --version) < /dev/null > /dev/null 2>&1 || {
echo autoconf not found
exit 1
}
autoconf || exit 1
echo ready to configure
exit 0
Regular → Executable
+38 -32
View File
@@ -1,13 +1,18 @@
AC_INIT(rtorrent, 0.9.7, sundell.software@gmail.com)
m4_pattern_allow([PKG_CHECK_EXISTS])
AC_DEFINE(API_VERSION, 9, api version)
AC_INIT([rtorrent], [0.10.0], [sundell.software@gmail.com])
AM_INIT_AUTOMAKE
AC_CONFIG_HEADERS(config.h)
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_MACRO_DIRS([scripts])
AM_INIT_AUTOMAKE([foreign subdir-objects])
AC_DEFINE([API_VERSION], [10], [api version])
AC_PROG_RANLIB
AC_PROG_CXX
AC_PROG_LIBTOOL
AC_SYS_LARGEFILE
AX_CXX_COMPILE_STDCXX([14], [noext], [mandatory])
RAK_CHECK_CFLAGS
RAK_CHECK_CXXFLAGS
@@ -15,15 +20,8 @@ RAK_ENABLE_DEBUG
RAK_ENABLE_EXTRA_DEBUG
RAK_ENABLE_WERROR
RAK_CHECK_CXX11
RAK_CHECK_TR1_LIB
TORRENT_DISABLE_IPV6
AC_SYS_LARGEFILE
TORRENT_CHECK_EXECINFO
TORRENT_ENABLE_ARCH
TORRENT_WITH_SYSROOT
@@ -31,20 +29,27 @@ TORRENT_WITHOUT_VARIABLE_FDSET
TORRENT_WITHOUT_STATVFS
TORRENT_WITHOUT_STATFS
AC_ARG_ENABLE(execinfo,
AS_HELP_STRING([--disable-execinfo],
[disable libexecinfo [[default=enable]]]),
[
if test "$enableval" = "yes"; then
AX_EXECINFO
fi
],[
AX_EXECINFO
])
AX_PTHREAD([], AC_MSG_ERROR([requires pthread]))
AX_WITH_CURSES
if test "x$ax_cv_ncursesw" != xyes && test "x$ax_cv_ncurses" != xyes; then
AC_MSG_ERROR([requires either NcursesW or Ncurses library])
AC_MSG_ERROR([requires either NcursesW or Ncurses library])
fi
PKG_CHECK_MODULES([LIBCURL], [libcurl], , [LIBCURL_CHECK_CONFIG])
PKG_CHECK_MODULES([LIBCURL], [libcurl],, [LIBCURL_CHECK_CONFIG])
PKG_CHECK_MODULES([CPPUNIT], [cppunit],, [no_cppunit="yes"])
PKG_CHECK_MODULES([DEPENDENCIES], [libtorrent >= 0.13.7])
LIBS="$PTHREAD_LIBS $CURSES_LIB $CPPUNIT_LIBS $LIBCURL $LIBCURL_LIBS $DEPENDENCIES_LIBS $LIBS"
CFLAGS="$CFLAGS $PTHREAD_CFLAGS $CPPUNIT_CFLAGS $LIBCURL_CPPFLAGS $LIBCURL_CFLAGS $DEPENDENCIES_CFLAGS $CURSES_CFLAGS"
CXXFLAGS="$CXXFLAGS $PTHREAD_CFLAGS $CPPUNIT_CFLAGS $LIBCURL_CPPFLAGS $LIBCURL_CFLAGS $DEPENDENCIES_CFLAGS $CURSES_CFLAGS"
PKG_CHECK_MODULES([DEPENDENCIES], [libtorrent >= 0.14.0])
AC_LANG_PUSH(C++)
TORRENT_WITH_XMLRPC_C
@@ -58,19 +63,20 @@ TORRENT_CHECK_CACHELINE()
TORRENT_CHECK_POPCOUNT()
CC_ATTRIBUTE_UNUSED(
AC_DEFINE([__UNUSED], [__attribute__((unused))], [Wrapper around unused attribute]),
AC_DEFINE([__UNUSED], [], [Null-wrapper if unused attribute is unsupported])
AC_DEFINE([__UNUSED], [__attribute__((unused))], [Wrapper around unused attribute]),
AC_DEFINE([__UNUSED], [], [Null-wrapper if unused attribute is unsupported])
)
AC_OUTPUT([
Makefile
doc/Makefile
src/Makefile
src/core/Makefile
src/display/Makefile
src/input/Makefile
src/rpc/Makefile
src/ui/Makefile
src/utils/Makefile
test/Makefile
dnl Only update global build variables immediately before generating the output,
dnl to avoid affecting the global build environment for other autoconf checks.
LIBS="$PTHREAD_LIBS $CURSES_LIB $CURSES_LIBS $CPPUNIT_LIBS $LIBCURL $LIBCURL_LIBS $DEPENDENCIES_LIBS $LIBS"
CFLAGS="$CFLAGS $PTHREAD_CFLAGS $CPPUNIT_CFLAGS $LIBCURL_CPPFLAGS $LIBCURL_CFLAGS $DEPENDENCIES_CFLAGS $CURSES_CFLAGS"
CXXFLAGS="$CXXFLAGS $PTHREAD_CFLAGS $CPPUNIT_CFLAGS $LIBCURL_CPPFLAGS $LIBCURL_CFLAGS $DEPENDENCIES_CFLAGS $CURSES_CFLAGS"
AC_CONFIG_FILES([
Makefile
doc/Makefile
src/Makefile
test/Makefile
])
AC_OUTPUT
+4 -1
View File
@@ -52,7 +52,7 @@ Decrease the download throttle by 1/5/50 KB.
\fB->\fR
View download.
.TP
\fB1 - 7\fR
\fB0 - 9\fR
Change view.
.TP
\fB^S\fR
@@ -99,6 +99,9 @@ Delete the file the torrent is tied to, and clear the association.
.TP
\fBI\fR
Toggle whether torrent ignores ratio settings.
.TP
\fBF\fR
Add a temporary name based regex filter to the current view.
.SS "DOWNLOAD VIEW KEYS"
.TP
\fB->\fR
+8 -1
View File
@@ -122,7 +122,7 @@ View download.
</varlistentry>
<varlistentry>
<term>1 - 7</term>
<term>0 - 9</term>
<listitem><para>
Change view.
</para></listitem>
@@ -225,6 +225,13 @@ Toggle whether torrent ignores ratio settings.
</para></listitem>
</varlistentry>
<varlistentry>
<term>F</term>
<listitem><para>
Add a temporary name based regex filter to the current view.
</para></listitem>
</varlistentry>
</variablelist>
</refsect2>
+39 -23
View File
@@ -1,22 +1,36 @@
# This is an example resource file for rTorrent. Copy to
# ~/.rtorrent.rc and enable/modify the options as needed. Remember to
# uncomment the options you wish to enable.
#############################################################################
# This is an (old) example resource file for rTorrent.
# Copy to ~/.rtorrent.rc and enable/modify the options as needed.
# Remember to uncomment the options you wish to enable.
#
# See 'rtorrent.rc-example' for a newer, basic configuration.
#
# Sample: https://github.com/rakshasa/rtorrent/wiki/CONFIG-Template
# Complete: https://rtorrent-docs.readthedocs.io/en/latest/cmd-ref.html
# Useful: https://rtorrent-docs.readthedocs.io/en/latest/use-cases.html
# Manual: https://rtorrent-docs.readthedocs.io/en/latest/
# Convert: https://github.com/rakshasa/rtorrent/wiki/rTorrent-0.9-Comprehensive-Command-list-(WIP)
# Handbook: https://media.readthedocs.org/pdf/rtorrent-docs/latest/rtorrent-docs.pdf
# File: https://github.com/rakshasa/rtorrent/blob/master/doc/rtorrent.rc
#############################################################################
# Maximum and minimum number of peers to connect to per torrent.
#
#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.
#
#throttle.min_peers.seed.set = 10
#throttle.max_peers.seed.set = 50
# Maximum number of simultanious uploads per torrent.
# Maximum number of simultaneous uploads per torrent.
#
#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.
#
#throttle.global_down.max_rate.set_kb = 0
#throttle.global_up.max_rate.set_kb = 0
@@ -26,7 +40,7 @@
#directory.default.set = ./
# 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?
#
#session.path.set = ./session
@@ -35,18 +49,17 @@
# deleted.
#
#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 disk-space is low.
#
#schedule2 = low_diskspace,5,60,close_low_diskspace=100M
# The ip address reported to the tracker.
# The IP address reported to the tracker.
#
#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.
#
#network.bind_address.set = 127.0.0.1
@@ -60,8 +73,8 @@
#
#network.port_random.set = no
# Check hash for finished torrents. Might be usefull until the bug is
# fixed that causes lack of diskspace not to be properly reported.
# Check hash for finished torrents. Might be useful until the bug is
# fixed that causes lack of disk-space not to be properly reported.
#
#pieces.hash.on_completion.set = no
@@ -69,7 +82,7 @@
#
#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.
#
#schedule2 = ip_tick,0,1800,ip=rakshasa
#schedule2 = bind_tick,0,1800,bind=rakshasa
@@ -79,7 +92,7 @@
#
# The example value allows incoming encrypted connections, starts unencrypted
# outgoing connections but retries with encryption if they fail, preferring
# plaintext to RC4 encryption after the encrypted handshake
# plain-text to RC4 encryption after the encrypted handshake.
#
# protocol.encryption.set = allow_incoming,enable_retry,prefer_plaintext
@@ -87,26 +100,29 @@
# 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).
# The default is "off". For DHT to work, a session directory must be defined.
#
#
# dht.mode.set = auto
# UDP port to use for DHT.
# UDP port to use for DHT.
#
#dht.port.set = 6881
# Enable peer exchange (for torrents not marked private)
# Enable peer exchange (for torrents not marked private).
#
#protocol.pex.set = yes
# Set downlad list layout style. ("full", "compact")
# Set download list layout style ("full", "compact").
#
#ui.torrent_list.layout.set = "full"
# SCGI Connectivity (for alternative rtorrent interfaces, XMLRPC)
# Run rTorrent as a daemon, controlled via XMLRPC.
#
#system.daemon.set = false
# SCGI Connectivity (for alternative rtorrent interfaces, XMLRPC)
# Use a IP socket with scgi_port, or a Unix socket with scgi_local.
# schedule can be used to set permissions on the unix socket.
#
#scgi_port = 127.0.0.1:5000
#scgi_local = /home/user/rtorrent/rpc.socket
#schedule = scgi_permission,0,0,"execute.nothrow=chmod,\"g+w,o=\",/home/user/rtorrent/rpc.socket"
#network.scgi.open_port = "127.0.0.1:5000"
#network.scgi.open_local = (cat,(session.path),/rpc.sock)
#schedule2 = socket_chmod, 0, 0, "execute.nothrow=chmod,770,(cat,(session.path),/rpc.sock)"
+106
View File
@@ -0,0 +1,106 @@
#############################################################################
# A minimal rTorrent configuration that provides the basic features
# you want to have in addition to the built-in defaults.
#
# See https://github.com/rakshasa/rtorrent/wiki/CONFIG-Template
# for an up-to-date version.
#############################################################################
# Instance layout (base paths)
method.insert = cfg.basedir, private|const|string, (cat,"/home/USERNAME/rtorrent/")
method.insert = cfg.download, private|const|string, (cat,(cfg.basedir),"download/")
method.insert = cfg.logs, private|const|string, (cat,(cfg.basedir),"log/")
method.insert = cfg.logfile, private|const|string, (cat,(cfg.logs),"rtorrent-",(system.time),".log")
method.insert = cfg.session, private|const|string, (cat,(cfg.basedir),".session/")
method.insert = cfg.watch, private|const|string, (cat,(cfg.basedir),"watch/")
# Create instance directories
execute.throw = sh, -c, (cat,\
"mkdir -p \"",(cfg.download),"\" ",\
"\"",(cfg.logs),"\" ",\
"\"",(cfg.session),"\" ",\
"\"",(cfg.watch),"/load\" ",\
"\"",(cfg.watch),"/start\" ")
# Listening port for incoming peer traffic (fixed; you can also randomize it)
network.port_range.set = 50000-50000
network.port_random.set = no
# Tracker-less torrent and UDP tracker support
# (conservative settings for 'private' trackers, change for 'public')
dht.mode.set = disable
protocol.pex.set = no
trackers.use_udp.set = no
# Peer settings
throttle.max_uploads.set = 100
throttle.max_uploads.global.set = 250
throttle.min_peers.normal.set = 20
throttle.max_peers.normal.set = 60
throttle.min_peers.seed.set = 30
throttle.max_peers.seed.set = 80
trackers.numwant.set = 80
protocol.encryption.set = allow_incoming,try_outgoing,enable_retry
# Limits for file handle resources, this is optimized for
# an `ulimit` of 1024 (a common default). You MUST leave
# a ceiling of handles reserved for rTorrent's internal needs!
network.http.max_open.set = 50
network.max_open_files.set = 600
network.max_open_sockets.set = 300
# Memory resource usage (increase if you have a large number of items loaded,
# and/or the available resources to spend)
pieces.memory.max.set = 1800M
network.xmlrpc.size_limit.set = 4M
# Basic operational settings (no need to change these)
session.path.set = (cat, (cfg.session))
directory.default.set = (cat, (cfg.download))
log.execute = (cat, (cfg.logs), "execute.log")
##log.xmlrpc = (cat, (cfg.logs), "xmlrpc.log")
execute.nothrow = sh, -c, (cat, "echo >",\
(session.path), "rtorrent.pid", " ", (system.pid))
# Other operational settings (check & adapt)
encoding.add = utf8
system.umask.set = 0027
system.cwd.set = (directory.default)
network.http.dns_cache_timeout.set = 25
schedule2 = monitor_diskspace, 15, 60, ((close_low_diskspace, 1000M))
##pieces.hash.on_completion.set = no
##view.sort_current = seeding, greater=d.ratio=
##keys.layout.set = qwerty
##network.http.capath.set = "/etc/ssl/certs"
##network.http.ssl_verify_peer.set = 0
##network.http.ssl_verify_host.set = 0
# Some additional values and commands
method.insert = system.startup_time, value|const, (system.time)
method.insert = d.data_path, simple,\
"if=(d.is_multi_file),\
(cat, (d.directory), /),\
(cat, (d.directory), /, (d.name))"
method.insert = d.session_file, simple, "cat=(session.path), (d.hash), .torrent"
# Watch directories (add more as you like, but use unique schedule names)
schedule2 = watch_start, 10, 10, ((load.start_verbose, (cat, (cfg.watch), "start/*.torrent")))
schedule2 = watch_load, 11, 10, ((load.verbose, (cat, (cfg.watch), "load/*.torrent")))
# Run the rTorrent process as a daemon in the background
# (and control via XMLRPC sockets)
#system.daemon.set = true
#network.scgi.open_local = (cat,(session.path),rtorrent.sock)
#execute.nothrow = chmod,770,(cat,(session.path),rtorrent.sock)
# Logging:
# Levels = critical error warn notice info debug
# Groups = connection_* dht_* peer_* rpc_* storage_* thread_* tracker_* torrent_*
print = (cat, "Logging to ", (cfg.logfile))
log.open_file = "log", (cfg.logfile)
log.add_output = "info", "log"
##log.add_output = "tracker_debug", "log"
### END of rtorrent.rc ###
+1 -1
View File
@@ -130,7 +130,7 @@ d_stop() {
}
getsession() {
session=$(cat "$1" | grep "^[[:space:]]*session[[:space:]]*=" | sed "s/^[[:space:]]*session[[:space:]]*=[[:space:]]*//" )
session=$(cat "$1" | grep "^[[:space:]]*session.path.set[[:space:]]*=" | sed "s/^[[:space:]]*session.path.set[[:space:]]*=[[:space:]]*//" )
#session=${session/#~/`getent passwd ${user}|cut -d: -f6`}
echo $session
}
+1 -1
View File
@@ -104,7 +104,7 @@ d_stop() {
}
getsession() {
session=`cat "$1" | grep "^[[:space:]]*session[[:space:]]*=" | sed "s/^[[:space:]]*session[[:space:]]*=[[:space:]]*//" `
session=`cat "$1" | grep "^[[:space:]]*session.path.set[[:space:]]*=" | sed "s/^[[:space:]]*session.path.set[[:space:]]*=[[:space:]]*//" `
echo $session
}
+21 -4
View File
@@ -159,10 +159,7 @@ make_base(_InputIter __first, _InputIter __last, _Ftor __ftor) {
template<typename T>
inline int popcount_wrapper(T t) {
#if USE_BUILTIN_POPCOUNT
if (std::numeric_limits<T>::digits <= std::numeric_limits<unsigned int>::digits)
return __builtin_popcount(t);
else
return __builtin_popcountll(t);
return __builtin_popcountll(t);
#else
#error __builtin_popcount not found.
unsigned int count = 0;
@@ -176,6 +173,26 @@ inline int popcount_wrapper(T t) {
#endif
}
// Get the median of an unordered set of numbers of arbitrary
// type by modifing the underlying dataset
template <typename T = double, typename _InputIter>
T median(_InputIter __first, _InputIter __last) {
T __med;
unsigned int __size = __last - __first;
unsigned int __middle = __size / 2;
_InputIter __target1 = __first + __middle;
std::nth_element(__first, __target1, __last);
__med = *__target1;
if (__size % 2 == 0) {
_InputIter __target2 = std::max_element(__first, __target1);
__med = (__med + *__target2) / 2.0;
}
return __med;
}
}
#endif
+1 -1
View File
@@ -38,7 +38,7 @@
#define RAK_FILE_STAT_H
#include <string>
#include <inttypes.h>
#include <cinttypes>
#include <sys/stat.h>
namespace rak {
+1 -1
View File
@@ -38,7 +38,7 @@
#define RAK_FS_STAT_H
#include <string>
#include <inttypes.h>
#include <cinttypes>
#include <rak/error_number.h>
+1 -2
View File
@@ -53,8 +53,7 @@
#include <memory>
#include <functional>
#include lt_tr1_functional
#include lt_tr1_memory
#include <memory>
namespace rak {
+1 -1
View File
@@ -39,7 +39,7 @@
#include <cstring>
#include <stdexcept>
#include <inttypes.h>
#include <cinttypes>
namespace rak {
+1 -1
View File
@@ -37,7 +37,7 @@
#ifndef RAK_PRIORITY_QUEUE_DEFAULT_H
#define RAK_PRIORITY_QUEUE_DEFAULT_H
#include lt_tr1_functional
#include <functional>
#include <rak/allocators.h>
#include <rak/priority_queue.h>
#include <rak/timer.h>
+74 -5
View File
@@ -47,9 +47,12 @@
#ifndef RAK_SOCKET_ADDRESS_H
#define RAK_SOCKET_ADDRESS_H
#include <cinttypes>
#include <cstdint>
#include <cstring>
#include <string>
#include <stdexcept>
#include <string>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/types.h>
@@ -77,11 +80,13 @@ public:
static const int pf_local = PF_UNIX;
#endif
bool is_any() const;
bool is_valid() const;
bool is_bindable() const;
bool is_address_any() const;
// Should we need to set AF_UNSPEC?
bool is_valid_inet_class() const { return family() == af_inet || family() == af_inet6; }
void clear() { std::memset(this, 0, sizeof(socket_address)); set_family(); }
sa_family_t family() const { return m_sockaddr.sa_family; }
@@ -93,6 +98,8 @@ public:
std::string address_str() const;
bool address_c_str(char* buf, socklen_t size) const;
std::string pretty_address_str() const;
// Attemts to set it as an inet, then an inet6 address. It will
// never set anything but net addresses, no local/unix.
bool set_address_str(const std::string& a) { return set_address_c_str(a.c_str()); }
@@ -119,6 +126,7 @@ public:
// extranous bytes and ensure it does not go beyond the size of this
// struct.
void copy(const socket_address& src, size_t length);
void copy_sockaddr(const sockaddr* src);
static socket_address* cast_from(sockaddr* sa) { return reinterpret_cast<socket_address*>(sa); }
static const socket_address* cast_from(const sockaddr* sa) { return reinterpret_cast<const socket_address*>(sa); }
@@ -215,6 +223,8 @@ public:
void set_address_any() { set_port(0); set_address(in6addr_any); }
std::string pretty_address_str() const;
sa_family_t family() const { return m_sockaddr.sin6_family; }
void set_family() { m_sockaddr.sin6_family = AF_INET6; }
@@ -233,6 +243,18 @@ private:
struct sockaddr_in6 m_sockaddr;
};
inline bool
socket_address::is_any() const {
switch (family()) {
case af_inet:
return sa_inet()->is_any();
case af_inet6:
return sa_inet6()->is_any();
default:
return false;
}
}
inline bool
socket_address::is_valid() const {
switch (family()) {
@@ -317,6 +339,21 @@ socket_address::address_c_str(char* buf, socklen_t size) const {
}
}
inline std::string
socket_address::pretty_address_str() const {
switch (family()) {
case af_inet:
return sa_inet()->address_str();
case af_inet6:
return sa_inet6()->pretty_address_str();
case af_unspec:
return std::string("unspec");
default:
return std::string("invalid");
}
}
inline bool
socket_address::set_address_c_str(const char* a) {
if (sa_inet()->set_address_c_str(a)) {
@@ -348,13 +385,16 @@ socket_address::length() const {
inline void
socket_address::copy(const socket_address& src, size_t length) {
length = std::min(length, sizeof(socket_address));
// Does this get properly optimized?
std::memset(this, 0, sizeof(socket_address));
std::memcpy(this, &src, length);
}
// Should we be able to compare af_unspec?
inline void
socket_address::copy_sockaddr(const sockaddr* src) {
std::memset(this, 0, sizeof(socket_address));
std::memcpy(this, src, socket_address::cast_from(src)->length());
}
inline bool
socket_address::operator == (const socket_address& rhs) const {
@@ -456,6 +496,35 @@ socket_address_inet6::set_address_c_str(const char* a) {
return inet_pton(AF_INET6, a, &m_sockaddr.sin6_addr);
}
inline std::string
socket_address_inet6::pretty_address_str() const {
char buf[INET6_ADDRSTRLEN + 2 + 6];
if (inet_ntop(family(), &m_sockaddr.sin6_addr, buf + 1, INET6_ADDRSTRLEN) == NULL)
return std::string();
buf[0] = '[';
char* last_char = (char*)std::memchr(buf + 1, 0, INET6_ADDRSTRLEN);
// TODO: Throw exception here.
if (last_char == NULL || last_char >= buf + 1 + INET6_ADDRSTRLEN)
throw std::logic_error("inet_ntop for inet6 returned bad buffer");
*(last_char++) = ']';
if (!is_port_any()) {
if (snprintf(last_char, 7, ":%" PRIu16, port()) == -1)
return std::string("error"); // TODO: Throw here.
} else {
*last_char = '\0';
}
return std::string(buf);
}
inline socket_address
socket_address_inet6::normalize_address() const {
const uint32_t *addr32 = reinterpret_cast<const uint32_t *>(m_sockaddr.sin6_addr.s6_addr);
+54 -3
View File
@@ -39,9 +39,13 @@
#include <algorithm>
#include <cctype>
#include <climits>
#include <cstdlib>
#include <functional>
#include <iterator>
#include <locale>
#include <random>
namespace rak {
@@ -312,11 +316,13 @@ transform_hex_str(const Sequence& seq) {
template <typename Sequence>
Sequence
generate_random(size_t length) {
std::random_device rd;
std::mt19937 mt(rd());
using bytes_randomizer = std::independent_bits_engine<std::mt19937, CHAR_BIT, uint8_t>;
bytes_randomizer bytes(mt);
Sequence s;
s.reserve(length);
std::generate_n(std::back_inserter(s), length, &::random);
std::generate_n(std::back_inserter(s), length, std::ref(bytes));
return s;
}
@@ -371,6 +377,51 @@ is_all_name(const Sequence& src) {
return is_all_name(src.begin(), src.end());
}
template <typename Iterator>
std::string
sanitize(Iterator first, Iterator last) {
std::string dest;
for (; first != last; ++first) {
if (std::isprint(*first) && *first != '\r' && *first != '\n' && *first != '\t')
dest += *first;
else
dest += " ";
}
return dest;
}
template <typename Sequence>
std::string
sanitize(const Sequence& src) {
return trim(sanitize(src.begin(), src.end()));
}
template <typename Iterator>
std::string striptags(Iterator first, Iterator last) {
bool copychar = true;
std::string dest;
for (; first != last; ++first) {
if (std::isprint(*first) && *first == '<') {
copychar = false;
} else if (std::isprint(*first) && *first == '>') {
copychar = true;
continue;
}
if (copychar)
dest += *first;
}
return dest;
}
template <typename Sequence>
std::string striptags(const Sequence& src) {
return striptags(src.begin(), src.end());
}
}
#endif
+1 -1
View File
@@ -38,7 +38,7 @@
#define RAK_TIMER_H
#include <limits>
#include <inttypes.h>
#include <cinttypes>
#include <sys/time.h>
namespace rak {
Regular → Executable
+5 -6
View File
@@ -1,5 +1,5 @@
# ===========================================================================
# http://www.gnu.org/software/autoconf-archive/ax_check_zlib.html
# https://www.gnu.org/software/autoconf-archive/ax_check_zlib.html
# ===========================================================================
#
# SYNOPSIS
@@ -47,7 +47,7 @@
# Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
# with this program. If not, see <https://www.gnu.org/licenses/>.
#
# As a special exception, the respective Autoconf Macro's copyright owner
# gives unlimited permission to copy, distribute and modify the configure
@@ -62,7 +62,7 @@
# modified version of the Autoconf Macro, you may extend this special
# exception to the GPL to apply to your modified version as well.
#serial 14
#serial 16
AU_ALIAS([CHECK_ZLIB], [AX_CHECK_ZLIB])
AC_DEFUN([AX_CHECK_ZLIB],
@@ -108,11 +108,10 @@ then
LDFLAGS="$LDFLAGS -L${ZLIB_HOME}/lib"
CPPFLAGS="$CPPFLAGS -I${ZLIB_HOME}/include"
fi
AC_LANG_SAVE
AC_LANG_C
AC_LANG_PUSH([C])
AC_CHECK_LIB([z], [inflateEnd], [zlib_cv_libz=yes], [zlib_cv_libz=no])
AC_CHECK_HEADER([zlib.h], [zlib_cv_zlib_h=yes], [zlib_cv_zlib_h=no])
AC_LANG_RESTORE
AC_LANG_POP([C])
if test "$zlib_cv_libz" = "yes" && test "$zlib_cv_zlib_h" = "yes"
then
#
+962
View File
@@ -0,0 +1,962 @@
# ===========================================================================
# https://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_CXX_COMPILE_STDCXX(VERSION, [ext|noext], [mandatory|optional])
#
# DESCRIPTION
#
# Check for baseline language coverage in the compiler for the specified
# version of the C++ standard. If necessary, add switches to CXX and
# CXXCPP to enable support. VERSION may be '11' (for the C++11 standard)
# or '14' (for the C++14 standard).
#
# The second argument, if specified, indicates whether you insist on an
# extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g.
# -std=c++11). If neither is specified, you get whatever works, with
# preference for no added switch, and then for an extended mode.
#
# The third argument, if specified 'mandatory' or if left unspecified,
# indicates that baseline support for the specified C++ standard is
# required and that the macro should error out if no mode with that
# support is found. If specified 'optional', then configuration proceeds
# regardless, after defining HAVE_CXX${VERSION} if and only if a
# supporting mode is found.
#
# LICENSE
#
# Copyright (c) 2008 Benjamin Kosnik <bkoz@redhat.com>
# Copyright (c) 2012 Zack Weinberg <zackw@panix.com>
# Copyright (c) 2013 Roy Stogner <roystgnr@ices.utexas.edu>
# Copyright (c) 2014, 2015 Google Inc.; contributed by Alexey Sokolov <sokolov@google.com>
# Copyright (c) 2015 Paul Norman <penorman@mac.com>
# Copyright (c) 2015 Moritz Klammler <moritz@klammler.eu>
# Copyright (c) 2016, 2018 Krzesimir Nowak <qdlacz@gmail.com>
# Copyright (c) 2019 Enji Cooper <yaneurabeya@gmail.com>
# Copyright (c) 2020 Jason Merrill <jason@redhat.com>
#
# Copying and distribution of this file, with or without modification, are
# permitted in any medium without royalty provided the copyright notice
# and this notice are preserved. This file is offered as-is, without any
# warranty.
#serial 12
dnl This macro is based on the code from the AX_CXX_COMPILE_STDCXX_11 macro
dnl (serial version number 13).
AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl
m4_if([$1], [11], [ax_cxx_compile_alternatives="11 0x"],
[$1], [14], [ax_cxx_compile_alternatives="14 1y"],
[$1], [17], [ax_cxx_compile_alternatives="17 1z"],
[m4_fatal([invalid first argument `$1' to AX_CXX_COMPILE_STDCXX])])dnl
m4_if([$2], [], [],
[$2], [ext], [],
[$2], [noext], [],
[m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX])])dnl
m4_if([$3], [], [ax_cxx_compile_cxx$1_required=true],
[$3], [mandatory], [ax_cxx_compile_cxx$1_required=true],
[$3], [optional], [ax_cxx_compile_cxx$1_required=false],
[m4_fatal([invalid third argument `$3' to AX_CXX_COMPILE_STDCXX])])
AC_LANG_PUSH([C++])dnl
ac_success=no
m4_if([$2], [], [dnl
AC_CACHE_CHECK(whether $CXX supports C++$1 features by default,
ax_cv_cxx_compile_cxx$1,
[AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])],
[ax_cv_cxx_compile_cxx$1=yes],
[ax_cv_cxx_compile_cxx$1=no])])
if test x$ax_cv_cxx_compile_cxx$1 = xyes; then
ac_success=yes
fi])
m4_if([$2], [noext], [], [dnl
if test x$ac_success = xno; then
for alternative in ${ax_cxx_compile_alternatives}; do
switch="-std=gnu++${alternative}"
cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch])
AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch,
$cachevar,
[ac_save_CXX="$CXX"
CXX="$CXX $switch"
AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])],
[eval $cachevar=yes],
[eval $cachevar=no])
CXX="$ac_save_CXX"])
if eval test x\$$cachevar = xyes; then
CXX="$CXX $switch"
if test -n "$CXXCPP" ; then
CXXCPP="$CXXCPP $switch"
fi
ac_success=yes
break
fi
done
fi])
m4_if([$2], [ext], [], [dnl
if test x$ac_success = xno; then
dnl HP's aCC needs +std=c++11 according to:
dnl http://h21007.www2.hp.com/portal/download/files/unprot/aCxx/PDF_Release_Notes/769149-001.pdf
dnl Cray's crayCC needs "-h std=c++11"
for alternative in ${ax_cxx_compile_alternatives}; do
for switch in -std=c++${alternative} +std=c++${alternative} "-h std=c++${alternative}"; do
cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch])
AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch,
$cachevar,
[ac_save_CXX="$CXX"
CXX="$CXX $switch"
AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])],
[eval $cachevar=yes],
[eval $cachevar=no])
CXX="$ac_save_CXX"])
if eval test x\$$cachevar = xyes; then
CXX="$CXX $switch"
if test -n "$CXXCPP" ; then
CXXCPP="$CXXCPP $switch"
fi
ac_success=yes
break
fi
done
if test x$ac_success = xyes; then
break
fi
done
fi])
AC_LANG_POP([C++])
if test x$ax_cxx_compile_cxx$1_required = xtrue; then
if test x$ac_success = xno; then
AC_MSG_ERROR([*** A compiler with support for C++$1 language features is required.])
fi
fi
if test x$ac_success = xno; then
HAVE_CXX$1=0
AC_MSG_NOTICE([No compiler with C++$1 support was found])
else
HAVE_CXX$1=1
AC_DEFINE(HAVE_CXX$1,1,
[define if the compiler supports basic C++$1 syntax])
fi
AC_SUBST(HAVE_CXX$1)
])
dnl Test body for checking C++11 support
m4_define([_AX_CXX_COMPILE_STDCXX_testbody_11],
_AX_CXX_COMPILE_STDCXX_testbody_new_in_11
)
dnl Test body for checking C++14 support
m4_define([_AX_CXX_COMPILE_STDCXX_testbody_14],
_AX_CXX_COMPILE_STDCXX_testbody_new_in_11
_AX_CXX_COMPILE_STDCXX_testbody_new_in_14
)
m4_define([_AX_CXX_COMPILE_STDCXX_testbody_17],
_AX_CXX_COMPILE_STDCXX_testbody_new_in_11
_AX_CXX_COMPILE_STDCXX_testbody_new_in_14
_AX_CXX_COMPILE_STDCXX_testbody_new_in_17
)
dnl Tests for new features in C++11
m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_11], [[
// If the compiler admits that it is not ready for C++11, why torture it?
// Hopefully, this will speed up the test.
#ifndef __cplusplus
#error "This is not a C++ compiler"
#elif __cplusplus < 201103L
#error "This is not a C++11 compiler"
#else
namespace cxx11
{
namespace test_static_assert
{
template <typename T>
struct check
{
static_assert(sizeof(int) <= sizeof(T), "not big enough");
};
}
namespace test_final_override
{
struct Base
{
virtual ~Base() {}
virtual void f() {}
};
struct Derived : public Base
{
virtual ~Derived() override {}
virtual void f() override {}
};
}
namespace test_double_right_angle_brackets
{
template < typename T >
struct check {};
typedef check<void> single_type;
typedef check<check<void>> double_type;
typedef check<check<check<void>>> triple_type;
typedef check<check<check<check<void>>>> quadruple_type;
}
namespace test_decltype
{
int
f()
{
int a = 1;
decltype(a) b = 2;
return a + b;
}
}
namespace test_type_deduction
{
template < typename T1, typename T2 >
struct is_same
{
static const bool value = false;
};
template < typename T >
struct is_same<T, T>
{
static const bool value = true;
};
template < typename T1, typename T2 >
auto
add(T1 a1, T2 a2) -> decltype(a1 + a2)
{
return a1 + a2;
}
int
test(const int c, volatile int v)
{
static_assert(is_same<int, decltype(0)>::value == true, "");
static_assert(is_same<int, decltype(c)>::value == false, "");
static_assert(is_same<int, decltype(v)>::value == false, "");
auto ac = c;
auto av = v;
auto sumi = ac + av + 'x';
auto sumf = ac + av + 1.0;
static_assert(is_same<int, decltype(ac)>::value == true, "");
static_assert(is_same<int, decltype(av)>::value == true, "");
static_assert(is_same<int, decltype(sumi)>::value == true, "");
static_assert(is_same<int, decltype(sumf)>::value == false, "");
static_assert(is_same<int, decltype(add(c, v))>::value == true, "");
return (sumf > 0.0) ? sumi : add(c, v);
}
}
namespace test_noexcept
{
int f() { return 0; }
int g() noexcept { return 0; }
static_assert(noexcept(f()) == false, "");
static_assert(noexcept(g()) == true, "");
}
namespace test_constexpr
{
template < typename CharT >
unsigned long constexpr
strlen_c_r(const CharT *const s, const unsigned long acc) noexcept
{
return *s ? strlen_c_r(s + 1, acc + 1) : acc;
}
template < typename CharT >
unsigned long constexpr
strlen_c(const CharT *const s) noexcept
{
return strlen_c_r(s, 0UL);
}
static_assert(strlen_c("") == 0UL, "");
static_assert(strlen_c("1") == 1UL, "");
static_assert(strlen_c("example") == 7UL, "");
static_assert(strlen_c("another\0example") == 7UL, "");
}
namespace test_rvalue_references
{
template < int N >
struct answer
{
static constexpr int value = N;
};
answer<1> f(int&) { return answer<1>(); }
answer<2> f(const int&) { return answer<2>(); }
answer<3> f(int&&) { return answer<3>(); }
void
test()
{
int i = 0;
const int c = 0;
static_assert(decltype(f(i))::value == 1, "");
static_assert(decltype(f(c))::value == 2, "");
static_assert(decltype(f(0))::value == 3, "");
}
}
namespace test_uniform_initialization
{
struct test
{
static const int zero {};
static const int one {1};
};
static_assert(test::zero == 0, "");
static_assert(test::one == 1, "");
}
namespace test_lambdas
{
void
test1()
{
auto lambda1 = [](){};
auto lambda2 = lambda1;
lambda1();
lambda2();
}
int
test2()
{
auto a = [](int i, int j){ return i + j; }(1, 2);
auto b = []() -> int { return '0'; }();
auto c = [=](){ return a + b; }();
auto d = [&](){ return c; }();
auto e = [a, &b](int x) mutable {
const auto identity = [](int y){ return y; };
for (auto i = 0; i < a; ++i)
a += b--;
return x + identity(a + b);
}(0);
return a + b + c + d + e;
}
int
test3()
{
const auto nullary = [](){ return 0; };
const auto unary = [](int x){ return x; };
using nullary_t = decltype(nullary);
using unary_t = decltype(unary);
const auto higher1st = [](nullary_t f){ return f(); };
const auto higher2nd = [unary](nullary_t f1){
return [unary, f1](unary_t f2){ return f2(unary(f1())); };
};
return higher1st(nullary) + higher2nd(nullary)(unary);
}
}
namespace test_variadic_templates
{
template <int...>
struct sum;
template <int N0, int... N1toN>
struct sum<N0, N1toN...>
{
static constexpr auto value = N0 + sum<N1toN...>::value;
};
template <>
struct sum<>
{
static constexpr auto value = 0;
};
static_assert(sum<>::value == 0, "");
static_assert(sum<1>::value == 1, "");
static_assert(sum<23>::value == 23, "");
static_assert(sum<1, 2>::value == 3, "");
static_assert(sum<5, 5, 11>::value == 21, "");
static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, "");
}
// http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae
// Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function
// because of this.
namespace test_template_alias_sfinae
{
struct foo {};
template<typename T>
using member = typename T::member_type;
template<typename T>
void func(...) {}
template<typename T>
void func(member<T>*) {}
void test();
void test() { func<foo>(0); }
}
} // namespace cxx11
#endif // __cplusplus >= 201103L
]])
dnl Tests for new features in C++14
m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_14], [[
// If the compiler admits that it is not ready for C++14, why torture it?
// Hopefully, this will speed up the test.
#ifndef __cplusplus
#error "This is not a C++ compiler"
#elif __cplusplus < 201402L
#error "This is not a C++14 compiler"
#else
namespace cxx14
{
namespace test_polymorphic_lambdas
{
int
test()
{
const auto lambda = [](auto&&... args){
const auto istiny = [](auto x){
return (sizeof(x) == 1UL) ? 1 : 0;
};
const int aretiny[] = { istiny(args)... };
return aretiny[0];
};
return lambda(1, 1L, 1.0f, '1');
}
}
namespace test_binary_literals
{
constexpr auto ivii = 0b0000000000101010;
static_assert(ivii == 42, "wrong value");
}
namespace test_generalized_constexpr
{
template < typename CharT >
constexpr unsigned long
strlen_c(const CharT *const s) noexcept
{
auto length = 0UL;
for (auto p = s; *p; ++p)
++length;
return length;
}
static_assert(strlen_c("") == 0UL, "");
static_assert(strlen_c("x") == 1UL, "");
static_assert(strlen_c("test") == 4UL, "");
static_assert(strlen_c("another\0test") == 7UL, "");
}
namespace test_lambda_init_capture
{
int
test()
{
auto x = 0;
const auto lambda1 = [a = x](int b){ return a + b; };
const auto lambda2 = [a = lambda1(x)](){ return a; };
return lambda2();
}
}
namespace test_digit_separators
{
constexpr auto ten_million = 100'000'000;
static_assert(ten_million == 100000000, "");
}
namespace test_return_type_deduction
{
auto f(int& x) { return x; }
decltype(auto) g(int& x) { return x; }
template < typename T1, typename T2 >
struct is_same
{
static constexpr auto value = false;
};
template < typename T >
struct is_same<T, T>
{
static constexpr auto value = true;
};
int
test()
{
auto x = 0;
static_assert(is_same<int, decltype(f(x))>::value, "");
static_assert(is_same<int&, decltype(g(x))>::value, "");
return x;
}
}
} // namespace cxx14
#endif // __cplusplus >= 201402L
]])
dnl Tests for new features in C++17
m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_17], [[
// If the compiler admits that it is not ready for C++17, why torture it?
// Hopefully, this will speed up the test.
#ifndef __cplusplus
#error "This is not a C++ compiler"
#elif __cplusplus < 201703L
#error "This is not a C++17 compiler"
#else
#include <initializer_list>
#include <utility>
#include <type_traits>
namespace cxx17
{
namespace test_constexpr_lambdas
{
constexpr int foo = [](){return 42;}();
}
namespace test::nested_namespace::definitions
{
}
namespace test_fold_expression
{
template<typename... Args>
int multiply(Args... args)
{
return (args * ... * 1);
}
template<typename... Args>
bool all(Args... args)
{
return (args && ...);
}
}
namespace test_extended_static_assert
{
static_assert (true);
}
namespace test_auto_brace_init_list
{
auto foo = {5};
auto bar {5};
static_assert(std::is_same<std::initializer_list<int>, decltype(foo)>::value);
static_assert(std::is_same<int, decltype(bar)>::value);
}
namespace test_typename_in_template_template_parameter
{
template<template<typename> typename X> struct D;
}
namespace test_fallthrough_nodiscard_maybe_unused_attributes
{
int f1()
{
return 42;
}
[[nodiscard]] int f2()
{
[[maybe_unused]] auto unused = f1();
switch (f1())
{
case 17:
f1();
[[fallthrough]];
case 42:
f1();
}
return f1();
}
}
namespace test_extended_aggregate_initialization
{
struct base1
{
int b1, b2 = 42;
};
struct base2
{
base2() {
b3 = 42;
}
int b3;
};
struct derived : base1, base2
{
int d;
};
derived d1 {{1, 2}, {}, 4}; // full initialization
derived d2 {{}, {}, 4}; // value-initialized bases
}
namespace test_general_range_based_for_loop
{
struct iter
{
int i;
int& operator* ()
{
return i;
}
const int& operator* () const
{
return i;
}
iter& operator++()
{
++i;
return *this;
}
};
struct sentinel
{
int i;
};
bool operator== (const iter& i, const sentinel& s)
{
return i.i == s.i;
}
bool operator!= (const iter& i, const sentinel& s)
{
return !(i == s);
}
struct range
{
iter begin() const
{
return {0};
}
sentinel end() const
{
return {5};
}
};
void f()
{
range r {};
for (auto i : r)
{
[[maybe_unused]] auto v = i;
}
}
}
namespace test_lambda_capture_asterisk_this_by_value
{
struct t
{
int i;
int foo()
{
return [*this]()
{
return i;
}();
}
};
}
namespace test_enum_class_construction
{
enum class byte : unsigned char
{};
byte foo {42};
}
namespace test_constexpr_if
{
template <bool cond>
int f ()
{
if constexpr(cond)
{
return 13;
}
else
{
return 42;
}
}
}
namespace test_selection_statement_with_initializer
{
int f()
{
return 13;
}
int f2()
{
if (auto i = f(); i > 0)
{
return 3;
}
switch (auto i = f(); i + 4)
{
case 17:
return 2;
default:
return 1;
}
}
}
namespace test_template_argument_deduction_for_class_templates
{
template <typename T1, typename T2>
struct pair
{
pair (T1 p1, T2 p2)
: m1 {p1},
m2 {p2}
{}
T1 m1;
T2 m2;
};
void f()
{
[[maybe_unused]] auto p = pair{13, 42u};
}
}
namespace test_non_type_auto_template_parameters
{
template <auto n>
struct B
{};
B<5> b1;
B<'a'> b2;
}
namespace test_structured_bindings
{
int arr[2] = { 1, 2 };
std::pair<int, int> pr = { 1, 2 };
auto f1() -> int(&)[2]
{
return arr;
}
auto f2() -> std::pair<int, int>&
{
return pr;
}
struct S
{
int x1 : 2;
volatile double y1;
};
S f3()
{
return {};
}
auto [ x1, y1 ] = f1();
auto& [ xr1, yr1 ] = f1();
auto [ x2, y2 ] = f2();
auto& [ xr2, yr2 ] = f2();
const auto [ x3, y3 ] = f3();
}
namespace test_exception_spec_type_system
{
struct Good {};
struct Bad {};
void g1() noexcept;
void g2();
template<typename T>
Bad
f(T*, T*);
template<typename T1, typename T2>
Good
f(T1*, T2*);
static_assert (std::is_same_v<Good, decltype(f(g1, g2))>);
}
namespace test_inline_variables
{
template<class T> void f(T)
{}
template<class T> inline T g(T)
{
return T{};
}
template<> inline void f<>(int)
{}
template<> int g<>(int)
{
return 5;
}
}
} // namespace cxx17
#endif // __cplusplus < 201703L
]])
-106
View File
@@ -1,106 +0,0 @@
# ============================================================================
# http://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx_0x.html
# ============================================================================
#
# SYNOPSIS
#
# AX_CXX_COMPILE_STDCXX_0X
#
# DESCRIPTION
#
# Check for baseline language coverage in the compiler for the C++0x
# standard.
#
# LICENSE
#
# Copyright (c) 2008 Benjamin Kosnik <bkoz@redhat.com>
#
# Copying and distribution of this file, with or without modification, are
# permitted in any medium without royalty provided the copyright notice
# and this notice are preserved. This file is offered as-is, without any
# warranty.
#serial 7 (+1)
AU_ALIAS([AC_CXX_COMPILE_STDCXX_0X], [AX_CXX_COMPILE_STDCXX_0X])
AC_DEFUN([AX_CXX_COMPILE_STDCXX_0X], [
AC_CACHE_CHECK(if g++ supports C++0x features without additional flags,
ax_cv_cxx_compile_cxx0x_native,
[AC_LANG_SAVE
AC_LANG_CPLUSPLUS
AC_TRY_COMPILE([
template <typename T>
struct check
{
static_assert(sizeof(int) <= sizeof(T), "not big enough");
};
typedef check<check<bool>> right_angle_brackets;
int a;
decltype(a) b;
typedef check<int> check_type;
check_type c;
check_type&& cr = static_cast<check_type&&>(c);],,
ax_cv_cxx_compile_cxx0x_native=yes, ax_cv_cxx_compile_cxx0x_native=no)
AC_LANG_RESTORE
])
AC_CACHE_CHECK(if g++ supports C++0x features with -std=c++0x,
ax_cv_cxx_compile_cxx0x_cxx,
[AC_LANG_SAVE
AC_LANG_CPLUSPLUS
ac_save_CXXFLAGS="$CXXFLAGS"
CXXFLAGS="$CXXFLAGS -std=c++0x"
AC_TRY_COMPILE([
template <typename T>
struct check
{
static_assert(sizeof(int) <= sizeof(T), "not big enough");
};
typedef check<check<bool>> right_angle_brackets;
int a;
decltype(a) b;
typedef check<int> check_type;
check_type c;
check_type&& cr = static_cast<check_type&&>(c);],,
ax_cv_cxx_compile_cxx0x_cxx=yes, ax_cv_cxx_compile_cxx0x_cxx=no)
CXXFLAGS="$ac_save_CXXFLAGS"
AC_LANG_RESTORE
])
AC_CACHE_CHECK(if g++ supports C++0x features with -std=gnu++0x,
ax_cv_cxx_compile_cxx0x_gxx,
[AC_LANG_SAVE
AC_LANG_CPLUSPLUS
ac_save_CXXFLAGS="$CXXFLAGS"
CXXFLAGS="$CXXFLAGS -std=gnu++0x"
AC_TRY_COMPILE([
template <typename T>
struct check
{
static_assert(sizeof(int) <= sizeof(T), "not big enough");
};
typedef check<check<bool>> right_angle_brackets;
int a;
decltype(a) b;
typedef check<int> check_type;
check_type c;
check_type&& cr = static_cast<check_type&&>(c);],,
ax_cv_cxx_compile_cxx0x_gxx=yes, ax_cv_cxx_compile_cxx0x_gxx=no)
CXXFLAGS="$ac_save_CXXFLAGS"
AC_LANG_RESTORE
])
if test "$ax_cv_cxx_compile_cxx0x_cxx" = yes; then
AC_DEFINE(HAVE_STDCXX_0X,, [Define if compiler supports C++0x features.])
CXXFLAGS="$CXXFLAGS -std=c++0x"
fi
])
-147
View File
@@ -1,147 +0,0 @@
# ============================================================================
# http://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx_11.html
# ============================================================================
#
# SYNOPSIS
#
# AX_CXX_COMPILE_STDCXX_11([ext|noext],[mandatory|optional])
#
# DESCRIPTION
#
# Check for baseline language coverage in the compiler for the C++11
# standard; if necessary, add switches to CXXFLAGS to enable support.
#
# The first argument, if specified, indicates whether you insist on an
# extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g.
# -std=c++11). If neither is specified, you get whatever works, with
# preference for an extended mode.
#
# The second argument, if specified 'mandatory' or if left unspecified,
# indicates that baseline C++11 support is required and that the macro
# should error out if no mode with that support is found. If specified
# 'optional', then configuration proceeds regardless, after defining
# HAVE_CXX11 if and only if a supporting mode is found.
#
# LICENSE
#
# Copyright (c) 2008 Benjamin Kosnik <bkoz@redhat.com>
# Copyright (c) 2012 Zack Weinberg <zackw@panix.com>
# Copyright (c) 2013 Roy Stogner <roystgnr@ices.utexas.edu>
# Copyright (c) 2014 Alexey Sokolov <sokolov@google.com>
# Copyright (c) 2014 Jari Sundell <sundell.software@gmail.com>
#
# Copying and distribution of this file, with or without modification, are
# permitted in any medium without royalty provided the copyright notice
# and this notice are preserved. This file is offered as-is, without any
# warranty.
#serial 5
m4_define([_AX_CXX_COMPILE_STDCXX_11_testbody], [[
template <typename T>
struct check
{
static_assert(sizeof(int) <= sizeof(T), "not big enough");
};
struct Base {
virtual void f() {}
};
struct Child : public Base {
virtual void f() override {}
};
typedef check<check<bool>> right_angle_brackets;
int a;
decltype(a) b;
typedef check<int> check_type;
check_type c;
check_type&& cr = static_cast<check_type&&>(c);
auto d = a;
auto l = [](){};
void unused() {
l();
}
]])
AC_DEFUN([AX_CXX_COMPILE_STDCXX_11], [dnl
m4_if([$1], [], [],
[$1], [ext], [],
[$1], [noext], [],
[m4_fatal([invalid argument `$1' to AX_CXX_COMPILE_STDCXX_11])])dnl
m4_if([$2], [], [ax_cxx_compile_cxx11_required=true],
[$2], [mandatory], [ax_cxx_compile_cxx11_required=true],
[$2], [optional], [ax_cxx_compile_cxx11_required=false],
[m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX_11])])
AC_LANG_PUSH([C++])dnl
ac_success=no
AC_CACHE_CHECK(whether $CXX supports C++11 features by default,
ax_cv_cxx_compile_cxx11,
[AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])],
[ax_cv_cxx_compile_cxx11=yes],
[ax_cv_cxx_compile_cxx11=no])])
if test x$ax_cv_cxx_compile_cxx11 = xyes; then
ac_success=yes
fi
m4_if([$1], [noext], [], [dnl
if test x$ac_success = xno; then
for switch in -std=gnu++11 -std=gnu++0x; do
cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx11_$switch])
AC_CACHE_CHECK(whether $CXX supports C++11 features with $switch,
$cachevar,
[ac_save_CXXFLAGS="$CXXFLAGS"
CXXFLAGS="$CXXFLAGS $switch"
AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])],
[eval $cachevar=yes],
[eval $cachevar=no])
CXXFLAGS="$ac_save_CXXFLAGS"])
if eval test x\$$cachevar = xyes; then
CXXFLAGS="$CXXFLAGS $switch"
ac_success=yes
break
fi
done
fi])
m4_if([$1], [ext], [], [dnl
if test x$ac_success = xno; then
for switch in -std=c++11 -std=c++0x; do
cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx11_$switch])
AC_CACHE_CHECK(whether $CXX supports C++11 features with $switch,
$cachevar,
[ac_save_CXXFLAGS="$CXXFLAGS"
CXXFLAGS="$CXXFLAGS $switch"
AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])],
[eval $cachevar=yes],
[eval $cachevar=no])
CXXFLAGS="$ac_save_CXXFLAGS"])
if eval test x\$$cachevar = xyes; then
CXXFLAGS="$CXXFLAGS $switch"
ac_success=yes
break
fi
done
fi])
AC_LANG_POP([C++])
if test x$ax_cxx_compile_cxx11_required = xtrue; then
if test x$ac_success = xno; then
AC_MSG_ERROR([*** A compiler with support for C++11 language features is required.])
fi
else
if test x$ac_success = xno; then
HAVE_CXX11=0
AC_MSG_NOTICE([No compiler with C++11 support was found])
else
HAVE_CXX11=1
AC_DEFINE(HAVE_CXX11,1,
[define if the compiler supports basic C++11 syntax])
fi
AC_SUBST(HAVE_CXX11)
fi
])
+67
View File
@@ -0,0 +1,67 @@
# ===========================================================================
# https://www.gnu.org/software/autoconf-archive/ax_execinfo.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_EXECINFO([ACTION-IF-EXECINFO-H-IS-FOUND], [ACTION-IF-EXECINFO-H-IS-NOT-FOUND], [ADDITIONAL-TYPES-LIST])
#
# DESCRIPTION
#
# Checks for execinfo.h header and if the len parameter/return type can be
# found from a list, also define backtrace_size_t to that type.
#
# By default the list of types to try contains int and size_t, but should
# some yet undiscovered system use e.g. unsigned, the 3rd argument can be
# used for extensions. I'd like to hear of further suggestions.
#
# Executes ACTION-IF-EXECINFO-H-IS-FOUND when present and the execinfo.h
# header is found or ACTION-IF-EXECINFO-H-IS-NOT-FOUND in case the header
# seems unavailable.
#
# Also adds -lexecinfo to LIBS on BSD if needed.
#
# LICENSE
#
# Copyright (c) 2014 Thomas Jahns <jahns@dkrz.de>
#
# Copying and distribution of this file, with or without modification, are
# permitted in any medium without royalty provided the copyright notice
# and this notice are preserved. This file is offered as-is, without any
# warranty.
#serial 2
AC_DEFUN([AX_EXECINFO],
[AC_CHECK_HEADERS([execinfo.h])
AS_IF([test x"$ac_cv_header_execinfo_h" = xyes],
[AC_CACHE_CHECK([size parameter type for backtrace()],
[ax_cv_proto_backtrace_type],
[AC_LANG_PUSH([C])
for ax_cv_proto_backtrace_type in size_t int m4_ifnblank([$3],[$3 ])none; do
AS_IF([test "${ax_cv_proto_backtrace_type}" = none],
[ax_cv_proto_backtrace_type= ; break])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([
#include <execinfo.h>
extern
${ax_cv_proto_backtrace_type} backtrace(void **addrlist, ${ax_cv_proto_backtrace_type} len);
char **backtrace_symbols(void *const *buffer, ${ax_cv_proto_backtrace_type} size);
])],
[break])
done
AC_LANG_POP([C])])])
AS_IF([test x${ax_cv_proto_backtrace_type} != x],
[AC_DEFINE_UNQUOTED([backtrace_size_t], [$ax_cv_proto_backtrace_type],
[Defined to return type of backtrace().])])
AC_SEARCH_LIBS([backtrace],[execinfo])
AS_IF([test x"${ax_cv_proto_backtrace_type}" != x -a x"$ac_cv_header_execinfo_h" = xyes -a x"$ac_cv_search_backtrace" != xno],
[AC_DEFINE([HAVE_BACKTRACE],[1],
[Defined if backtrace() could be fully identified.])
]m4_ifnblank([$1],[$1
]),m4_ifnblank([$2],[$2
]))])
dnl
dnl Local Variables:
dnl mode: autoconf
dnl End:
dnl
Regular → Executable
+335 -122
View File
@@ -1,5 +1,5 @@
# ===========================================================================
# http://www.gnu.org/software/autoconf-archive/ax_pthread.html
# https://www.gnu.org/software/autoconf-archive/ax_pthread.html
# ===========================================================================
#
# SYNOPSIS
@@ -14,24 +14,28 @@
# flags that are needed. (The user can also force certain compiler
# flags/libs to be tested by setting these environment variables.)
#
# Also sets PTHREAD_CC to any special C compiler that is needed for
# multi-threaded programs (defaults to the value of CC otherwise). (This
# is necessary on AIX to use the special cc_r compiler alias.)
# Also sets PTHREAD_CC and PTHREAD_CXX to any special C compiler that is
# needed for multi-threaded programs (defaults to the value of CC
# respectively CXX otherwise). (This is necessary on e.g. AIX to use the
# special cc_r/CC_r compiler alias.)
#
# NOTE: You are assumed to not only compile your program with these flags,
# but also link it with them as well. e.g. you should link with
# but also to link with them as well. For example, you might link with
# $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS
# $PTHREAD_CXX $CXXFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS
#
# If you are only building threads programs, you may wish to use these
# If you are only building threaded programs, you may wish to use these
# variables in your default LIBS, CFLAGS, and CC:
#
# LIBS="$PTHREAD_LIBS $LIBS"
# CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
# CXXFLAGS="$CXXFLAGS $PTHREAD_CFLAGS"
# CC="$PTHREAD_CC"
# CXX="$PTHREAD_CXX"
#
# In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute constant
# has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to that name
# (e.g. PTHREAD_CREATE_UNDETACHED on AIX).
# has a nonstandard name, this macro defines PTHREAD_CREATE_JOINABLE to
# that name (e.g. PTHREAD_CREATE_UNDETACHED on AIX).
#
# Also HAVE_PTHREAD_PRIO_INHERIT is defined if pthread is found and the
# PTHREAD_PRIO_INHERIT symbol is defined when compiling with
@@ -55,6 +59,7 @@
#
# Copyright (c) 2008 Steven G. Johnson <stevenj@alum.mit.edu>
# Copyright (c) 2011 Daniel Richard G. <skunk@iSKUNK.ORG>
# Copyright (c) 2019 Marc Stevens <marc.stevens@cwi.nl>
#
# 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
@@ -67,7 +72,7 @@
# Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
# with this program. If not, see <https://www.gnu.org/licenses/>.
#
# As a special exception, the respective Autoconf Macro's copyright owner
# gives unlimited permission to copy, distribute and modify the configure
@@ -82,35 +87,41 @@
# modified version of the Autoconf Macro, you may extend this special
# exception to the GPL to apply to your modified version as well.
#serial 17
#serial 31
AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD])
AC_DEFUN([AX_PTHREAD], [
AC_REQUIRE([AC_CANONICAL_HOST])
AC_REQUIRE([AC_PROG_CC])
AC_REQUIRE([AC_PROG_SED])
AC_LANG_PUSH([C])
ax_pthread_ok=no
# We used to check for pthread.h first, but this fails if pthread.h
# requires special compiler flags (e.g. on True64 or Sequent).
# requires special compiler flags (e.g. on Tru64 or Sequent).
# It gets checked for in the link test anyway.
# First of all, check if the user has set any of the PTHREAD_LIBS,
# etcetera environment variables, and if threads linking works using
# them:
if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then
save_CFLAGS="$CFLAGS"
if test "x$PTHREAD_CFLAGS$PTHREAD_LIBS" != "x"; then
ax_pthread_save_CC="$CC"
ax_pthread_save_CFLAGS="$CFLAGS"
ax_pthread_save_LIBS="$LIBS"
AS_IF([test "x$PTHREAD_CC" != "x"], [CC="$PTHREAD_CC"])
AS_IF([test "x$PTHREAD_CXX" != "x"], [CXX="$PTHREAD_CXX"])
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
save_LIBS="$LIBS"
LIBS="$PTHREAD_LIBS $LIBS"
AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS])
AC_TRY_LINK_FUNC(pthread_join, ax_pthread_ok=yes)
AC_MSG_RESULT($ax_pthread_ok)
if test x"$ax_pthread_ok" = xno; then
AC_MSG_CHECKING([for pthread_join using $CC $PTHREAD_CFLAGS $PTHREAD_LIBS])
AC_LINK_IFELSE([AC_LANG_CALL([], [pthread_join])], [ax_pthread_ok=yes])
AC_MSG_RESULT([$ax_pthread_ok])
if test "x$ax_pthread_ok" = "xno"; then
PTHREAD_LIBS=""
PTHREAD_CFLAGS=""
fi
LIBS="$save_LIBS"
CFLAGS="$save_CFLAGS"
CC="$ax_pthread_save_CC"
CFLAGS="$ax_pthread_save_CFLAGS"
LIBS="$ax_pthread_save_LIBS"
fi
# We must check for the threads library under a number of different
@@ -118,12 +129,14 @@ fi
# (e.g. DEC) have both -lpthread and -lpthreads, where one of the
# libraries is broken (non-POSIX).
# Create a list of thread flags to try. Items starting with a "-" are
# C compiler flags, and other items are library names, except for "none"
# which indicates that we try without any flags at all, and "pthread-config"
# which is a program returning the flags for the Pth emulation library.
# Create a list of thread flags to try. Items with a "," contain both
# C compiler flags (before ",") and linker flags (after ","). Other items
# starting with a "-" are C compiler flags, and remaining items are
# library names, except for "none" which indicates that we try without
# any flags at all, and "pthread-config" which is a program returning
# the flags for the Pth emulation library.
ax_pthread_flags="none pthreads -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config"
ax_pthread_flags="pthreads none -Kthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config"
# The ordering *is* (sometimes) important. Some notes on the
# individual items follow:
@@ -132,68 +145,163 @@ ax_pthread_flags="none pthreads -Kthread -kthread lthread -pthread -pthreads -mt
# none: in case threads are in libc; should be tried before -Kthread and
# other compiler flags to prevent continual compiler warnings
# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads)
# -pthreads: Solaris/gcc
# -mthreads: Mingw32/gcc, Lynx/gcc
# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads), Tru64
# (Note: HP C rejects this with "bad form for `-t' option")
# -pthreads: Solaris/gcc (Note: HP C also rejects)
# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
# doesn't hurt to check since this sometimes defines pthreads too;
# also defines -D_REENTRANT)
# ... -mt is also the pthreads flag for HP/aCC
# doesn't hurt to check since this sometimes defines pthreads and
# -D_REENTRANT too), HP C (must be checked before -lpthread, which
# is present but should not be used directly; and before -mthreads,
# because the compiler interprets this as "-mt" + "-hreads")
# -mthreads: Mingw32/gcc, Lynx/gcc
# pthread: Linux, etcetera
# --thread-safe: KAI C++
# pthread-config: use pthread-config program (for GNU Pth library)
case "${host_cpu}-${host_os}" in
*solaris*)
case $host_os in
freebsd*)
# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
ax_pthread_flags="-kthread lthread $ax_pthread_flags"
;;
hpux*)
# From the cc(1) man page: "[-mt] Sets various -D flags to enable
# multi-threading and also sets -lpthread."
ax_pthread_flags="-mt -pthread pthread $ax_pthread_flags"
;;
openedition*)
# IBM z/OS requires a feature-test macro to be defined in order to
# enable POSIX threads at all, so give the user a hint if this is
# not set. (We don't define these ourselves, as they can affect
# other portions of the system API in unpredictable ways.)
AC_EGREP_CPP([AX_PTHREAD_ZOS_MISSING],
[
# if !defined(_OPEN_THREADS) && !defined(_UNIX03_THREADS)
AX_PTHREAD_ZOS_MISSING
# endif
],
[AC_MSG_WARN([IBM z/OS requires -D_OPEN_THREADS or -D_UNIX03_THREADS to enable pthreads support.])])
;;
solaris*)
# On Solaris (at least, for some versions), libc contains stubbed
# (non-functional) versions of the pthreads routines, so link-based
# tests will erroneously succeed. (We need to link with -pthreads/-mt/
# -lpthread.) (The stubs are missing pthread_cleanup_push, or rather
# a function called by this macro, so we could check for that, but
# who knows whether they'll stub that too in a future libc.) So,
# we'll just look for -pthreads and -lpthread first:
# tests will erroneously succeed. (N.B.: The stubs are missing
# pthread_cleanup_push, or rather a function called by this macro,
# so we could check for that, but who knows whether they'll stub
# that too in a future libc.) So we'll check first for the
# standard Solaris way of linking pthreads (-mt -lpthread).
ax_pthread_flags="-pthreads pthread -mt -pthread $ax_pthread_flags"
;;
*-darwin*)
ax_pthread_flags="none -pthread $ax_pthread_flags"
ax_pthread_flags="-mt,-lpthread pthread $ax_pthread_flags"
;;
esac
if test x"$ax_pthread_ok" = xno; then
for flag in $ax_pthread_flags; do
# Are we compiling with Clang?
case $flag in
AC_CACHE_CHECK([whether $CC is Clang],
[ax_cv_PTHREAD_CLANG],
[ax_cv_PTHREAD_CLANG=no
# Note that Autoconf sets GCC=yes for Clang as well as GCC
if test "x$GCC" = "xyes"; then
AC_EGREP_CPP([AX_PTHREAD_CC_IS_CLANG],
[/* Note: Clang 2.7 lacks __clang_[a-z]+__ */
# if defined(__clang__) && defined(__llvm__)
AX_PTHREAD_CC_IS_CLANG
# endif
],
[ax_cv_PTHREAD_CLANG=yes])
fi
])
ax_pthread_clang="$ax_cv_PTHREAD_CLANG"
# GCC generally uses -pthread, or -pthreads on some platforms (e.g. SPARC)
# Note that for GCC and Clang -pthread generally implies -lpthread,
# except when -nostdlib is passed.
# This is problematic using libtool to build C++ shared libraries with pthread:
# [1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=25460
# [2] https://bugzilla.redhat.com/show_bug.cgi?id=661333
# [3] https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=468555
# To solve this, first try -pthread together with -lpthread for GCC
AS_IF([test "x$GCC" = "xyes"],
[ax_pthread_flags="-pthread,-lpthread -pthread -pthreads $ax_pthread_flags"])
# Clang takes -pthread (never supported any other flag), but we'll try with -lpthread first
AS_IF([test "x$ax_pthread_clang" = "xyes"],
[ax_pthread_flags="-pthread,-lpthread -pthread"])
# The presence of a feature test macro requesting re-entrant function
# definitions is, on some systems, a strong hint that pthreads support is
# correctly enabled
case $host_os in
darwin* | hpux* | linux* | osf* | solaris*)
ax_pthread_check_macro="_REENTRANT"
;;
aix*)
ax_pthread_check_macro="_THREAD_SAFE"
;;
*)
ax_pthread_check_macro="--"
;;
esac
AS_IF([test "x$ax_pthread_check_macro" = "x--"],
[ax_pthread_check_cond=0],
[ax_pthread_check_cond="!defined($ax_pthread_check_macro)"])
if test "x$ax_pthread_ok" = "xno"; then
for ax_pthread_try_flag in $ax_pthread_flags; do
case $ax_pthread_try_flag in
none)
AC_MSG_CHECKING([whether pthreads work without any flags])
;;
*,*)
PTHREAD_CFLAGS=`echo $ax_pthread_try_flag | sed "s/^\(.*\),\(.*\)$/\1/"`
PTHREAD_LIBS=`echo $ax_pthread_try_flag | sed "s/^\(.*\),\(.*\)$/\2/"`
AC_MSG_CHECKING([whether pthreads work with "$PTHREAD_CFLAGS" and "$PTHREAD_LIBS"])
;;
-*)
AC_MSG_CHECKING([whether pthreads work with $flag])
PTHREAD_CFLAGS="$flag"
AC_MSG_CHECKING([whether pthreads work with $ax_pthread_try_flag])
PTHREAD_CFLAGS="$ax_pthread_try_flag"
;;
pthread-config)
AC_CHECK_PROG(ax_pthread_config, pthread-config, yes, no)
if test x"$ax_pthread_config" = xno; then continue; fi
AC_CHECK_PROG([ax_pthread_config], [pthread-config], [yes], [no])
AS_IF([test "x$ax_pthread_config" = "xno"], [continue])
PTHREAD_CFLAGS="`pthread-config --cflags`"
PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`"
;;
*)
AC_MSG_CHECKING([for the pthreads library -l$flag])
PTHREAD_LIBS="-l$flag"
AC_MSG_CHECKING([for the pthreads library -l$ax_pthread_try_flag])
PTHREAD_LIBS="-l$ax_pthread_try_flag"
;;
esac
save_LIBS="$LIBS"
save_CFLAGS="$CFLAGS"
LIBS="$PTHREAD_LIBS $LIBS"
ax_pthread_save_CFLAGS="$CFLAGS"
ax_pthread_save_LIBS="$LIBS"
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
LIBS="$PTHREAD_LIBS $LIBS"
# Check for various functions. We must include pthread.h,
# since some functions may be macros. (On the Sequent, we
@@ -204,8 +312,18 @@ for flag in $ax_pthread_flags; do
# pthread_cleanup_push because it is one of the few pthread
# functions on Solaris that doesn't have a non-functional libc stub.
# We try pthread_create on general principles.
AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h>
static void routine(void *a) { a = 0; }
# if $ax_pthread_check_cond
# error "$ax_pthread_check_macro must be defined"
# endif
static void *some_global = NULL;
static void routine(void *a)
{
/* To avoid any unused-parameter or
unused-but-set-parameter warning. */
some_global = a;
}
static void *start_routine(void *a) { return a; }],
[pthread_t th; pthread_attr_t attr;
pthread_create(&th, 0, start_routine, 0);
@@ -213,93 +331,188 @@ for flag in $ax_pthread_flags; do
pthread_attr_init(&attr);
pthread_cleanup_push(routine, 0);
pthread_cleanup_pop(0) /* ; */])],
[ax_pthread_ok=yes],
[])
[ax_pthread_ok=yes],
[])
LIBS="$save_LIBS"
CFLAGS="$save_CFLAGS"
CFLAGS="$ax_pthread_save_CFLAGS"
LIBS="$ax_pthread_save_LIBS"
AC_MSG_RESULT($ax_pthread_ok)
if test "x$ax_pthread_ok" = xyes; then
break;
fi
AC_MSG_RESULT([$ax_pthread_ok])
AS_IF([test "x$ax_pthread_ok" = "xyes"], [break])
PTHREAD_LIBS=""
PTHREAD_CFLAGS=""
done
fi
# Clang needs special handling, because older versions handle the -pthread
# option in a rather... idiosyncratic way
if test "x$ax_pthread_clang" = "xyes"; then
# Clang takes -pthread; it has never supported any other flag
# (Note 1: This will need to be revisited if a system that Clang
# supports has POSIX threads in a separate library. This tends not
# to be the way of modern systems, but it's conceivable.)
# (Note 2: On some systems, notably Darwin, -pthread is not needed
# to get POSIX threads support; the API is always present and
# active. We could reasonably leave PTHREAD_CFLAGS empty. But
# -pthread does define _REENTRANT, and while the Darwin headers
# ignore this macro, third-party headers might not.)
# However, older versions of Clang make a point of warning the user
# that, in an invocation where only linking and no compilation is
# taking place, the -pthread option has no effect ("argument unused
# during compilation"). They expect -pthread to be passed in only
# when source code is being compiled.
#
# Problem is, this is at odds with the way Automake and most other
# C build frameworks function, which is that the same flags used in
# compilation (CFLAGS) are also used in linking. Many systems
# supported by AX_PTHREAD require exactly this for POSIX threads
# support, and in fact it is often not straightforward to specify a
# flag that is used only in the compilation phase and not in
# linking. Such a scenario is extremely rare in practice.
#
# Even though use of the -pthread flag in linking would only print
# a warning, this can be a nuisance for well-run software projects
# that build with -Werror. So if the active version of Clang has
# this misfeature, we search for an option to squash it.
AC_CACHE_CHECK([whether Clang needs flag to prevent "argument unused" warning when linking with -pthread],
[ax_cv_PTHREAD_CLANG_NO_WARN_FLAG],
[ax_cv_PTHREAD_CLANG_NO_WARN_FLAG=unknown
# Create an alternate version of $ac_link that compiles and
# links in two steps (.c -> .o, .o -> exe) instead of one
# (.c -> exe), because the warning occurs only in the second
# step
ax_pthread_save_ac_link="$ac_link"
ax_pthread_sed='s/conftest\.\$ac_ext/conftest.$ac_objext/g'
ax_pthread_link_step=`AS_ECHO(["$ac_link"]) | sed "$ax_pthread_sed"`
ax_pthread_2step_ac_link="($ac_compile) && (echo ==== >&5) && ($ax_pthread_link_step)"
ax_pthread_save_CFLAGS="$CFLAGS"
for ax_pthread_try in '' -Qunused-arguments -Wno-unused-command-line-argument unknown; do
AS_IF([test "x$ax_pthread_try" = "xunknown"], [break])
CFLAGS="-Werror -Wunknown-warning-option $ax_pthread_try -pthread $ax_pthread_save_CFLAGS"
ac_link="$ax_pthread_save_ac_link"
AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])],
[ac_link="$ax_pthread_2step_ac_link"
AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])],
[break])
])
done
ac_link="$ax_pthread_save_ac_link"
CFLAGS="$ax_pthread_save_CFLAGS"
AS_IF([test "x$ax_pthread_try" = "x"], [ax_pthread_try=no])
ax_cv_PTHREAD_CLANG_NO_WARN_FLAG="$ax_pthread_try"
])
case "$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG" in
no | unknown) ;;
*) PTHREAD_CFLAGS="$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG $PTHREAD_CFLAGS" ;;
esac
fi # $ax_pthread_clang = yes
# Various other checks:
if test "x$ax_pthread_ok" = xyes; then
save_LIBS="$LIBS"
LIBS="$PTHREAD_LIBS $LIBS"
save_CFLAGS="$CFLAGS"
if test "x$ax_pthread_ok" = "xyes"; then
ax_pthread_save_CFLAGS="$CFLAGS"
ax_pthread_save_LIBS="$LIBS"
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
LIBS="$PTHREAD_LIBS $LIBS"
# Detect AIX lossage: JOINABLE attribute is called UNDETACHED.
AC_MSG_CHECKING([for joinable pthread attribute])
attr_name=unknown
for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do
AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h>],
[int attr = $attr; return attr /* ; */])],
[attr_name=$attr; break],
[])
done
AC_MSG_RESULT($attr_name)
if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then
AC_DEFINE_UNQUOTED(PTHREAD_CREATE_JOINABLE, $attr_name,
[Define to necessary symbol if this constant
uses a non-standard name on your system.])
fi
AC_CACHE_CHECK([for joinable pthread attribute],
[ax_cv_PTHREAD_JOINABLE_ATTR],
[ax_cv_PTHREAD_JOINABLE_ATTR=unknown
for ax_pthread_attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do
AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h>],
[int attr = $ax_pthread_attr; return attr /* ; */])],
[ax_cv_PTHREAD_JOINABLE_ATTR=$ax_pthread_attr; break],
[])
done
])
AS_IF([test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xunknown" && \
test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xPTHREAD_CREATE_JOINABLE" && \
test "x$ax_pthread_joinable_attr_defined" != "xyes"],
[AC_DEFINE_UNQUOTED([PTHREAD_CREATE_JOINABLE],
[$ax_cv_PTHREAD_JOINABLE_ATTR],
[Define to necessary symbol if this constant
uses a non-standard name on your system.])
ax_pthread_joinable_attr_defined=yes
])
AC_MSG_CHECKING([if more special flags are required for pthreads])
flag=no
case "${host_cpu}-${host_os}" in
*-aix* | *-freebsd* | *-darwin*) flag="-D_THREAD_SAFE";;
*-osf* | *-hpux*) flag="-D_REENTRANT";;
*solaris*)
if test "$GCC" = "yes"; then
flag="-D_REENTRANT"
else
flag="-mt -D_REENTRANT"
fi
;;
esac
AC_MSG_RESULT(${flag})
if test "x$flag" != xno; then
PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS"
fi
AC_CACHE_CHECK([whether more special flags are required for pthreads],
[ax_cv_PTHREAD_SPECIAL_FLAGS],
[ax_cv_PTHREAD_SPECIAL_FLAGS=no
case $host_os in
solaris*)
ax_cv_PTHREAD_SPECIAL_FLAGS="-D_POSIX_PTHREAD_SEMANTICS"
;;
esac
])
AS_IF([test "x$ax_cv_PTHREAD_SPECIAL_FLAGS" != "xno" && \
test "x$ax_pthread_special_flags_added" != "xyes"],
[PTHREAD_CFLAGS="$ax_cv_PTHREAD_SPECIAL_FLAGS $PTHREAD_CFLAGS"
ax_pthread_special_flags_added=yes])
AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT],
ax_cv_PTHREAD_PRIO_INHERIT, [
AC_LINK_IFELSE([
AC_LANG_PROGRAM([[#include <pthread.h>]], [[int i = PTHREAD_PRIO_INHERIT;]])],
[ax_cv_PTHREAD_PRIO_INHERIT=yes],
[ax_cv_PTHREAD_PRIO_INHERIT=no])
[ax_cv_PTHREAD_PRIO_INHERIT],
[AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <pthread.h>]],
[[int i = PTHREAD_PRIO_INHERIT;
return i;]])],
[ax_cv_PTHREAD_PRIO_INHERIT=yes],
[ax_cv_PTHREAD_PRIO_INHERIT=no])
])
AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes"],
AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], 1, [Have PTHREAD_PRIO_INHERIT.]))
AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes" && \
test "x$ax_pthread_prio_inherit_defined" != "xyes"],
[AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], [1], [Have PTHREAD_PRIO_INHERIT.])
ax_pthread_prio_inherit_defined=yes
])
LIBS="$save_LIBS"
CFLAGS="$save_CFLAGS"
CFLAGS="$ax_pthread_save_CFLAGS"
LIBS="$ax_pthread_save_LIBS"
# More AIX lossage: must compile with xlc_r or cc_r
if test x"$GCC" != xyes; then
AC_CHECK_PROGS(PTHREAD_CC, xlc_r cc_r, ${CC})
else
PTHREAD_CC=$CC
# More AIX lossage: compile with *_r variant
if test "x$GCC" != "xyes"; then
case $host_os in
aix*)
AS_CASE(["x/$CC"],
[x*/c89|x*/c89_128|x*/c99|x*/c99_128|x*/cc|x*/cc128|x*/xlc|x*/xlc_v6|x*/xlc128|x*/xlc128_v6],
[#handle absolute path differently from PATH based program lookup
AS_CASE(["x$CC"],
[x/*],
[
AS_IF([AS_EXECUTABLE_P([${CC}_r])],[PTHREAD_CC="${CC}_r"])
AS_IF([test "x${CXX}" != "x"], [AS_IF([AS_EXECUTABLE_P([${CXX}_r])],[PTHREAD_CXX="${CXX}_r"])])
],
[
AC_CHECK_PROGS([PTHREAD_CC],[${CC}_r],[$CC])
AS_IF([test "x${CXX}" != "x"], [AC_CHECK_PROGS([PTHREAD_CXX],[${CXX}_r],[$CXX])])
]
)
])
;;
esac
fi
else
PTHREAD_CC="$CC"
fi
AC_SUBST(PTHREAD_LIBS)
AC_SUBST(PTHREAD_CFLAGS)
AC_SUBST(PTHREAD_CC)
test -n "$PTHREAD_CC" || PTHREAD_CC="$CC"
test -n "$PTHREAD_CXX" || PTHREAD_CXX="$CXX"
AC_SUBST([PTHREAD_LIBS])
AC_SUBST([PTHREAD_CFLAGS])
AC_SUBST([PTHREAD_CC])
AC_SUBST([PTHREAD_CXX])
# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
if test x"$ax_pthread_ok" = xyes; then
ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1])
if test "x$ax_pthread_ok" = "xyes"; then
ifelse([$1],,[AC_DEFINE([HAVE_PTHREAD],[1],[Define if you have POSIX threads libraries and header files.])],[$1])
:
else
ax_pthread_ok=no
Regular → Executable
+105 -69
View File
@@ -1,5 +1,5 @@
# ===========================================================================
# http://www.gnu.org/software/autoconf-archive/ax_with_curses.html
# https://www.gnu.org/software/autoconf-archive/ax_with_curses.html
# ===========================================================================
#
# SYNOPSIS
@@ -12,7 +12,9 @@
# present, along with the associated header file. The NcursesW
# (wide-character) library is searched for first, followed by Ncurses,
# then the system-default plain Curses. The first library found is the
# one returned.
# one returned. Finding libraries will first be attempted by using
# pkg-config, and should the pkg-config files not be available, will
# fallback to combinations of known flags itself.
#
# The following options are understood: --with-ncursesw, --with-ncurses,
# --without-ncursesw, --without-ncurses. The "--with" options force the
@@ -52,23 +54,29 @@
#
# (These preprocessor symbols are discussed later in this document.)
#
# The following output variable is defined by this macro; it is precious
# and may be overridden on the ./configure command line:
# The following output variables are defined by this macro; they are
# precious and may be overridden on the ./configure command line:
#
# CURSES_LIB - library to add to xxx_LDADD
# CURSES_LIBS - library to add to xxx_LDADD
# CURSES_CFLAGS - include paths to add to xxx_CPPFLAGS
#
# The library listed in CURSES_LIB is NOT added to LIBS by default. You
# need to add CURSES_LIB to the appropriate xxx_LDADD line in your
# Makefile.am. For example:
# In previous versions of this macro, the flags CURSES_LIB and
# CURSES_CPPFLAGS were defined. These have been renamed, in keeping with
# AX_WITH_CURSES's close bigger brother, PKG_CHECK_MODULES, which should
# eventually supersede the use of AX_WITH_CURSES. Neither the library
# listed in CURSES_LIBS, nor the flags in CURSES_CFLAGS are added to LIBS,
# respectively CPPFLAGS, by default. You need to add both to the
# appropriate xxx_LDADD/xxx_CPPFLAGS line in your Makefile.am. For
# example:
#
# prog_LDADD = @CURSES_LIB@
# prog_LDADD = @CURSES_LIBS@
# prog_CPPFLAGS = @CURSES_CFLAGS@
#
# If CURSES_LIB is set on the configure command line (such as by running
# "./configure CURSES_LIB=-lmycurses"), then the only header searched for
# is <curses.h>. The user may use the CPPFLAGS precious variable to
# override the standard #include search path. If the user needs to
# specify an alternative path for a library (such as for a non-standard
# NcurseW), the user should use the LDFLAGS variable.
# If CURSES_LIBS is set on the configure command line (such as by running
# "./configure CURSES_LIBS=-lmycurses"), then the only header searched for
# is <curses.h>. If the user needs to specify an alternative path for a
# library (such as for a non-standard NcurseW), the user should use the
# LDFLAGS variable.
#
# The following shell variables may be defined by this macro:
#
@@ -88,7 +96,7 @@
#
# AX_WITH_CURSES
# if test "x$ax_cv_ncursesw" != xyes && test "x$ax_cv_ncurses" != xyes; then
# AX_MSG_ERROR([requires either NcursesW or Ncurses library])
# AC_MSG_ERROR([requires either NcursesW or Ncurses library])
# fi
#
# If any Curses library will do (but one must be present and must support
@@ -167,7 +175,7 @@
# Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
# with this program. If not, see <https://www.gnu.org/licenses/>.
#
# As a special exception, the respective Autoconf Macro's copyright owner
# gives unlimited permission to copy, distribute and modify the configure
@@ -182,11 +190,66 @@
# modified version of the Autoconf Macro, you may extend this special
# exception to the GPL to apply to your modified version as well.
#serial 13
#serial 18
# internal function to factorize common code that is used by both ncurses
# and ncursesw
AC_DEFUN([_FIND_CURSES_FLAGS], [
AC_MSG_CHECKING([for $1 via pkg-config])
AX_REQUIRE_DEFINED([PKG_CHECK_EXISTS])
_PKG_CONFIG([_ax_cv_$1_libs], [libs], [$1])
_PKG_CONFIG([_ax_cv_$1_cppflags], [cflags], [$1])
AS_IF([test "x$pkg_failed" = "xyes" || test "x$pkg_failed" = "xuntried"],[
AC_MSG_RESULT([no])
# No suitable .pc file found, have to find flags via fallback
AC_CACHE_CHECK([for $1 via fallback], [ax_cv_$1], [
AS_ECHO()
pkg_cv__ax_cv_$1_libs="-l$1"
pkg_cv__ax_cv_$1_cppflags="-D_GNU_SOURCE $CURSES_CFLAGS"
LIBS="$ax_saved_LIBS $pkg_cv__ax_cv_$1_libs"
CPPFLAGS="$ax_saved_CPPFLAGS $pkg_cv__ax_cv_$1_cppflags"
AC_MSG_CHECKING([for initscr() with $pkg_cv__ax_cv_$1_libs])
AC_LINK_IFELSE([AC_LANG_CALL([], [initscr])],
[
AC_MSG_RESULT([yes])
AC_MSG_CHECKING([for nodelay() with $pkg_cv__ax_cv_$1_libs])
AC_LINK_IFELSE([AC_LANG_CALL([], [nodelay])],[
ax_cv_$1=yes
],[
AC_MSG_RESULT([no])
m4_if(
[$1],[ncursesw],[pkg_cv__ax_cv_$1_libs="$pkg_cv__ax_cv_$1_libs -ltinfow"],
[$1],[ncurses],[pkg_cv__ax_cv_$1_libs="$pkg_cv__ax_cv_$1_libs -ltinfo"]
)
LIBS="$ax_saved_LIBS $pkg_cv__ax_cv_$1_libs"
AC_MSG_CHECKING([for nodelay() with $pkg_cv__ax_cv_$1_libs])
AC_LINK_IFELSE([AC_LANG_CALL([], [nodelay])],[
ax_cv_$1=yes
],[
ax_cv_$1=no
])
])
],[
ax_cv_$1=no
])
])
],[
AC_MSG_RESULT([yes])
# Found .pc file, using its information
LIBS="$ax_saved_LIBS $pkg_cv__ax_cv_$1_libs"
CPPFLAGS="$ax_saved_CPPFLAGS $pkg_cv__ax_cv_$1_cppflags"
ax_cv_$1=yes
])
])
AU_ALIAS([MP_WITH_CURSES], [AX_WITH_CURSES])
AC_DEFUN([AX_WITH_CURSES], [
AC_ARG_VAR([CURSES_LIB], [linker library for Curses, e.g. -lcurses])
AC_ARG_VAR([CURSES_LIBS], [linker library for Curses, e.g. -lcurses])
AC_ARG_VAR([CURSES_CFLAGS], [preprocessor flags for Curses, e.g. -I/usr/include/ncursesw])
AC_ARG_WITH([ncurses], [AS_HELP_STRING([--with-ncurses],
[force the use of Ncurses or NcursesW])],
[], [with_ncurses=check])
@@ -195,20 +258,17 @@ AC_DEFUN([AX_WITH_CURSES], [
[], [with_ncursesw=check])
ax_saved_LIBS=$LIBS
ax_saved_CPPFLAGS=$CPPFLAGS
AS_IF([test "x$with_ncurses" = xyes || test "x$with_ncursesw" = xyes],
[ax_with_plaincurses=no], [ax_with_plaincurses=check])
ax_cv_curses_which=no
# Test for NcursesW
AS_IF([test "x$CURSES_LIBS" = x && test "x$with_ncursesw" != xno], [
_FIND_CURSES_FLAGS([ncursesw])
AS_IF([test "x$CURSES_LIB" = x && test "x$with_ncursesw" != xno], [
LIBS="$ax_saved_LIBS -lncursesw"
AC_CACHE_CHECK([for NcursesW wide-character library], [ax_cv_ncursesw], [
AC_LINK_IFELSE([AC_LANG_CALL([], [initscr])],
[ax_cv_ncursesw=yes], [ax_cv_ncursesw=no])
])
AS_IF([test "x$ax_cv_ncursesw" = xno && test "x$with_ncursesw" = xyes], [
AC_MSG_ERROR([--with-ncursesw specified but could not find NcursesW library])
])
@@ -216,7 +276,8 @@ AC_DEFUN([AX_WITH_CURSES], [
AS_IF([test "x$ax_cv_ncursesw" = xyes], [
ax_cv_curses=yes
ax_cv_curses_which=ncursesw
CURSES_LIB="-lncursesw"
CURSES_LIBS="$pkg_cv__ax_cv_ncursesw_libs"
CURSES_CFLAGS="$pkg_cv__ax_cv_ncursesw_cppflags"
AC_DEFINE([HAVE_NCURSESW], [1], [Define to 1 if the NcursesW library is present])
AC_DEFINE([HAVE_CURSES], [1], [Define to 1 if a SysV or X/Open compatible Curses library is present])
@@ -316,46 +377,15 @@ AC_DEFUN([AX_WITH_CURSES], [
AS_IF([test "x$ax_cv_header_ncursesw_curses_h" = xno && test "x$ax_cv_header_ncursesw_h" = xno && test "x$ax_cv_header_ncurses_h_with_ncursesw" = xno], [
AC_MSG_WARN([could not find a working ncursesw/curses.h, ncursesw.h or ncurses.h])
])
dnl Test if we need to explicitly link against -ltinfow.
AC_CACHE_CHECK([if curses tinfo library is linked properly], [ax_cv_ncurses_compiled], [
LIBS="$ax_saved_LIBS $CURSES_LIB"
AC_LINK_IFELSE([AC_LANG_CALL([], [keypad])], [ax_cv_ncurses_compiled=yes], [ax_cv_ncurses_compiled=no])
LIBS="$ax_saved_LIBS $CURSES_LIB -ltinfo"
AC_LINK_IFELSE([AC_LANG_CALL([], [keypad])], [ax_cv_tinfo_compiled=yes], [ax_cv_tinfo_compiled=no])
LIBS="$ax_saved_LIBS $CURSES_LIB -ltinfow"
AC_LINK_IFELSE([AC_LANG_CALL([], [keypad])], [ax_cv_tinfow_compiled=yes], [ax_cv_tinfow_compiled=no])
LIBS=$ax_saved_LIBS
])
AS_IF([test "x$ax_cv_ncurses_compiled" = xno], [
AS_IF(
[test "x$ax_cv_tinfo_compiled" = xyes], [
AC_MSG_RESULT([adding libtinfo])
CURSES_LIB="$CURSES_LIB -ltinfo"
],
[test "x$ax_cv_tinfow_compiled" = xyes], [
AC_MSG_RESULT([adding libtinfow])
CURSES_LIB="$CURSES_LIB -ltinfow"
], [
AC_MSG_ERROR([no])
])
])
])
])
unset pkg_cv__ax_cv_ncursesw_libs
unset pkg_cv__ax_cv_ncursesw_cppflags
# Test for Ncurses
AS_IF([test "x$CURSES_LIBS" = x && test "x$with_ncurses" != xno && test "x$ax_cv_curses_which" = xno], [
_FIND_CURSES_FLAGS([ncurses])
AS_IF([test "x$CURSES_LIB" = x && test "x$with_ncurses" != xno && test "x$ax_cv_curses_which" = xno], [
LIBS="$ax_saved_LIBS -lncurses"
AC_CACHE_CHECK([for Ncurses library], [ax_cv_ncurses], [
AC_LINK_IFELSE([AC_LANG_CALL([], [initscr])],
[ax_cv_ncurses=yes], [ax_cv_ncurses=no])
])
AS_IF([test "x$ax_cv_ncurses" = xno && test "x$with_ncurses" = xyes], [
AC_MSG_ERROR([--with-ncurses specified but could not find Ncurses library])
])
@@ -363,7 +393,8 @@ AC_DEFUN([AX_WITH_CURSES], [
AS_IF([test "x$ax_cv_ncurses" = xyes], [
ax_cv_curses=yes
ax_cv_curses_which=ncurses
CURSES_LIB="-lncurses"
CURSES_LIBS="$pkg_cv__ax_cv_ncurses_libs"
CURSES_CFLAGS="$pkg_cv__ax_cv_ncurses_cppflags"
AC_DEFINE([HAVE_NCURSES], [1], [Define to 1 if the Ncurses library is present])
AC_DEFINE([HAVE_CURSES], [1], [Define to 1 if a SysV or X/Open compatible Curses library is present])
@@ -418,12 +449,13 @@ AC_DEFUN([AX_WITH_CURSES], [
])
])
])
unset pkg_cv__ax_cv_ncurses_libs
unset pkg_cv__ax_cv_ncurses_cppflags
# Test for plain Curses (or if CURSES_LIB was set by user)
# Test for plain Curses (or if CURSES_LIBS was set by user)
AS_IF([test "x$with_plaincurses" != xno && test "x$ax_cv_curses_which" = xno], [
AS_IF([test "x$CURSES_LIB" != x], [
LIBS="$ax_saved_LIBS $CURSES_LIB"
AS_IF([test "x$CURSES_LIBS" != x], [
LIBS="$ax_saved_LIBS $CURSES_LIBS"
], [
LIBS="$ax_saved_LIBS -lcurses"
])
@@ -436,8 +468,8 @@ AC_DEFUN([AX_WITH_CURSES], [
AS_IF([test "x$ax_cv_plaincurses" = xyes], [
ax_cv_curses=yes
ax_cv_curses_which=plaincurses
AS_IF([test "x$CURSES_LIB" = x], [
CURSES_LIB="-lcurses"
AS_IF([test "x$CURSES_LIBS" = x], [
CURSES_LIBS="-lcurses"
])
AC_DEFINE([HAVE_CURSES], [1], [Define to 1 if a SysV or X/Open compatible Curses library is present])
@@ -543,4 +575,8 @@ AC_DEFUN([AX_WITH_CURSES], [
AS_IF([test "x$ax_cv_curses_obsolete" != xyes], [ax_cv_curses_obsolete=no])
LIBS=$ax_saved_LIBS
CPPFLAGS=$ax_saved_CPPFLAGS
unset ax_saved_LIBS
unset ax_saved_CPPFLAGS
])dnl
+64 -64
View File
@@ -21,7 +21,7 @@ AC_DEFUN([TORRENT_CHECK_XFS], [
AC_DEFUN([TORRENT_WITHOUT_XFS], [
AC_ARG_WITH(xfs,
AC_HELP_STRING([--without-xfs], [do not check for XFS filesystem support]),
AS_HELP_STRING([--without-xfs],[do not check for XFS filesystem support]),
[
if test "$withval" = "yes"; then
TORRENT_CHECK_XFS
@@ -34,7 +34,7 @@ AC_DEFUN([TORRENT_WITHOUT_XFS], [
AC_DEFUN([TORRENT_WITH_XFS], [
AC_ARG_WITH(xfs,
AC_HELP_STRING([--with-xfs], [check for XFS filesystem support]),
AS_HELP_STRING([--with-xfs],[check for XFS filesystem support]),
[
if test "$withval" = "yes"; then
TORRENT_CHECK_XFS
@@ -63,7 +63,7 @@ AC_DEFUN([TORRENT_CHECK_EPOLL], [
AC_DEFUN([TORRENT_WITHOUT_EPOLL], [
AC_ARG_WITH(epoll,
AC_HELP_STRING([--without-epoll], [do not check for epoll support]),
AS_HELP_STRING([--without-epoll],[do not check for epoll support]),
[
if test "$withval" = "yes"; then
TORRENT_CHECK_EPOLL
@@ -88,6 +88,7 @@ AC_DEFUN([TORRENT_CHECK_KQUEUE], [
[
AC_DEFINE(USE_KQUEUE, 1, Use kqueue.)
AC_MSG_RESULT(yes)
TORRENT_CHECK_KQUEUE_SOCKET_ONLY
], [
AC_MSG_RESULT(no)
])
@@ -96,7 +97,7 @@ AC_DEFUN([TORRENT_CHECK_KQUEUE], [
AC_DEFUN([TORRENT_CHECK_KQUEUE_SOCKET_ONLY], [
AC_MSG_CHECKING(whether kqueue supports pipes and ptys)
AC_RUN_IFELSE([AC_LANG_SOURCE([
AC_LINK_IFELSE([AC_LANG_SOURCE([
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
@@ -133,11 +134,10 @@ AC_DEFUN([TORRENT_CHECK_KQUEUE_SOCKET_ONLY], [
AC_DEFUN([TORRENT_WITH_KQUEUE], [
AC_ARG_WITH(kqueue,
AC_HELP_STRING([--with-kqueue], [enable kqueue [[default=no]]]),
AS_HELP_STRING([--with-kqueue],[enable kqueue [[default=no]]]),
[
if test "$withval" = "yes"; then
TORRENT_CHECK_KQUEUE
TORRENT_CHECK_KQUEUE_SOCKET_ONLY
fi
])
])
@@ -145,22 +145,20 @@ AC_DEFUN([TORRENT_WITH_KQUEUE], [
AC_DEFUN([TORRENT_WITHOUT_KQUEUE], [
AC_ARG_WITH(kqueue,
AC_HELP_STRING([--without-kqueue], [do not check for kqueue support]),
AS_HELP_STRING([--without-kqueue],[do not check for kqueue support]),
[
if test "$withval" = "yes"; then
TORRENT_CHECK_KQUEUE
TORRENT_CHECK_KQUEUE_SOCKET_ONLY
fi
], [
TORRENT_CHECK_KQUEUE
TORRENT_CHECK_KQUEUE_SOCKET_ONLY
])
])
AC_DEFUN([TORRENT_WITHOUT_VARIABLE_FDSET], [
AC_ARG_WITH(variable-fdset,
AC_HELP_STRING([--without-variable-fdset], [do not use non-portable variable sized fd_set's]),
AS_HELP_STRING([--without-variable-fdset],[do not use non-portable variable sized fd_set's]),
[
if test "$withval" = "yes"; then
AC_DEFINE(USE_VARIABLE_FDSET, 1, defined when we allow the use of fd_set's of any size)
@@ -174,14 +172,13 @@ AC_DEFUN([TORRENT_WITHOUT_VARIABLE_FDSET], [
AC_DEFUN([TORRENT_CHECK_FALLOCATE], [
AC_MSG_CHECKING(for fallocate)
AC_TRY_LINK([#include <fcntl.h>
#include <linux/falloc.h>
],[ fallocate(0, FALLOC_FL_KEEP_SIZE, 0, 0); return 0;
],
[
AC_LINK_IFELSE([AC_LANG_PROGRAM([[#define _GNU_SOURCE
#include <fcntl.h>
]], [[ fallocate(0, FALLOC_FL_KEEP_SIZE, 0, 0); return 0;
]])],[
AC_DEFINE(HAVE_FALLOCATE, 1, Linux's fallocate supported.)
AC_MSG_RESULT(yes)
], [
],[
AC_MSG_RESULT(no)
])
])
@@ -190,13 +187,12 @@ AC_DEFUN([TORRENT_CHECK_FALLOCATE], [
AC_DEFUN([TORRENT_CHECK_POSIX_FALLOCATE], [
AC_MSG_CHECKING(for posix_fallocate)
AC_TRY_LINK([#include <fcntl.h>
],[ posix_fallocate(0, 0, 0);
],
[
AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <fcntl.h>
]], [[ posix_fallocate(0, 0, 0);
]])],[
AC_DEFINE(USE_POSIX_FALLOCATE, 1, posix_fallocate supported.)
AC_MSG_RESULT(yes)
], [
],[
AC_MSG_RESULT(no)
])
])
@@ -204,7 +200,7 @@ AC_DEFUN([TORRENT_CHECK_POSIX_FALLOCATE], [
AC_DEFUN([TORRENT_WITH_POSIX_FALLOCATE], [
AC_ARG_WITH(posix-fallocate,
AC_HELP_STRING([--with-posix-fallocate], [check for and use posix_fallocate to allocate files]),
AS_HELP_STRING([--with-posix-fallocate],[check for and use posix_fallocate to allocate files]),
[
if test "$withval" = "yes"; then
TORRENT_CHECK_POSIX_FALLOCATE
@@ -217,8 +213,7 @@ AC_DEFUN([TORRENT_CHECK_STATVFS], [
AC_MSG_CHECKING(for statvfs)
AC_TRY_LINK(
[
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
#if HAVE_SYS_VFS_H
#include <sys/vfs.h>
#endif
@@ -228,12 +223,11 @@ AC_DEFUN([TORRENT_CHECK_STATVFS], [
#if HAVE_SYS_STATFS_H
#include <sys/statfs.h>
#endif
],[
]], [[
struct statvfs s; fsblkcnt_t c;
statvfs("", &s);
fstatvfs(0, &s);
],
[
]])],[
AC_DEFINE(FS_STAT_FD, [fstatvfs(fd, &m_stat) == 0], Function to determine filesystem stats from fd)
AC_DEFINE(FS_STAT_FN, [statvfs(fn, &m_stat) == 0], Function to determine filesystem stats from filename)
AC_DEFINE(FS_STAT_STRUCT, [struct statvfs], Type of second argument to statfs function)
@@ -242,8 +236,7 @@ AC_DEFUN([TORRENT_CHECK_STATVFS], [
AC_DEFINE(FS_STAT_BLOCK_SIZE, [(m_stat.f_frsize)], Determine the block size)
AC_MSG_RESULT(ok)
have_stat_vfs=yes
],
[
],[
AC_MSG_RESULT(no)
have_stat_vfs=no
])
@@ -254,8 +247,7 @@ AC_DEFUN([TORRENT_CHECK_STATFS], [
AC_MSG_CHECKING(for statfs)
AC_TRY_LINK(
[
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
#if HAVE_SYS_STATFS_H
#include <sys/statfs.h>
#endif
@@ -265,12 +257,11 @@ AC_DEFUN([TORRENT_CHECK_STATFS], [
#if HAVE_SYS_MOUNT_H
#include <sys/mount.h>
#endif
],[
]], [[
struct statfs s;
statfs("", &s);
fstatfs(0, &s);
],
[
]])],[
AC_DEFINE(FS_STAT_FD, [fstatfs(fd, &m_stat) == 0], Function to determine filesystem stats from fd)
AC_DEFINE(FS_STAT_FN, [statfs(fn, &m_stat) == 0], Function to determine filesystem stats from filename)
AC_DEFINE(FS_STAT_STRUCT, [struct statfs], Type of second argument to statfs function)
@@ -279,8 +270,7 @@ AC_DEFUN([TORRENT_CHECK_STATFS], [
AC_DEFINE(FS_STAT_BLOCK_SIZE, [(m_stat.f_bsize)], Determine the block size)
AC_MSG_RESULT(ok)
have_stat_vfs=yes
],
[
],[
AC_MSG_RESULT(no)
have_stat_vfs=no
])
@@ -298,7 +288,7 @@ AC_DEFUN([TORRENT_DISABLED_STATFS], [
AC_DEFUN([TORRENT_WITHOUT_STATVFS], [
AC_ARG_WITH(statvfs,
AC_HELP_STRING([--without-statvfs], [don't try to use statvfs to find free diskspace]),
AS_HELP_STRING([--without-statvfs],[don't try to use statvfs to find free diskspace]),
[
if test "$withval" = "yes"; then
TORRENT_CHECK_STATVFS
@@ -313,7 +303,7 @@ AC_DEFUN([TORRENT_WITHOUT_STATVFS], [
AC_DEFUN([TORRENT_WITHOUT_STATFS], [
AC_ARG_WITH(statfs,
AC_HELP_STRING([--without-statfs], [don't try to use statfs to find free diskspace]),
AS_HELP_STRING([--without-statfs],[don't try to use statfs to find free diskspace]),
[
if test "$have_stat_vfs" = "no"; then
if test "$withval" = "yes"; then
@@ -335,7 +325,7 @@ AC_DEFUN([TORRENT_WITHOUT_STATFS], [
AC_DEFUN([TORRENT_WITH_ADDRESS_SPACE], [
AC_ARG_WITH(address-space,
AC_HELP_STRING([--with-address-space=MB], [change the default address space size [[default=1024mb]]]),
AS_HELP_STRING([--with-address-space=MB],[change the default address space size [[default=1024mb]]]),
[
if test ! -z $withval -a "$withval" != "yes" -a "$withval" != "no"; then
AC_DEFINE_UNQUOTED(DEFAULT_ADDRESS_SPACE_SIZE, [$withval])
@@ -356,7 +346,7 @@ AC_DEFUN([TORRENT_WITH_ADDRESS_SPACE], [
AC_DEFUN([TORRENT_WITH_FASTCGI], [
AC_ARG_WITH(fastcgi,
AC_HELP_STRING([--with-fastcgi=PATH], [enable FastCGI RPC support (DO NOT USE)]),
AS_HELP_STRING([--with-fastcgi=PATH],[enable FastCGI RPC support (DO NOT USE)]),
[
AC_MSG_CHECKING([for FastCGI (DO NOT USE)])
@@ -367,13 +357,10 @@ AC_DEFUN([TORRENT_WITH_FASTCGI], [
CXXFLAGS="$CXXFLAGS"
LIBS="$LIBS -lfcgi"
AC_TRY_LINK(
[ #include <fcgiapp.h>
],[ FCGX_Init(); ],
[
AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #include <fcgiapp.h>
]], [[ FCGX_Init(); ]])],[
AC_MSG_RESULT(ok)
],
[
],[
AC_MSG_RESULT(not found)
AC_MSG_ERROR(Could not compile FastCGI test.)
])
@@ -384,13 +371,10 @@ AC_DEFUN([TORRENT_WITH_FASTCGI], [
CXXFLAGS="$CXXFLAGS -I$withval/include"
LIBS="$LIBS -lfcgi -L$withval/lib"
AC_TRY_LINK(
[ #include <fcgiapp.h>
],[ FCGX_Init(); ],
[
AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #include <fcgiapp.h>
]], [[ FCGX_Init(); ]])],[
AC_MSG_RESULT(ok)
],
[
],[
AC_MSG_RESULT(not found)
AC_MSG_ERROR(Could not compile FastCGI test.)
])
@@ -405,7 +389,7 @@ AC_DEFUN([TORRENT_WITH_XMLRPC_C], [
AC_MSG_CHECKING(for XMLRPC-C)
AC_ARG_WITH(xmlrpc-c,
AC_HELP_STRING([--with-xmlrpc-c=PATH], [enable XMLRPC-C support]),
AS_HELP_STRING([--with-xmlrpc-c=PATH],[enable XMLRPC-C support]),
[
if test "$withval" = "no"; then
AC_MSG_RESULT(no)
@@ -421,12 +405,10 @@ AC_DEFUN([TORRENT_WITH_XMLRPC_C], [
CXXFLAGS="$CXXFLAGS `$xmlrpc_cc_prg --cflags server-util`"
LIBS="$LIBS `$xmlrpc_cc_prg server-util --libs`"
AC_TRY_LINK(
[ #include <xmlrpc-c/server.h>
],[ xmlrpc_registry_new(NULL); ],
[
AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #include <xmlrpc-c/server.h>
]], [[ xmlrpc_registry_new(NULL); ]])],[
AC_MSG_RESULT(ok)
], [
],[
AC_MSG_RESULT(failed)
AC_MSG_ERROR(Could not compile XMLRPC-C test.)
])
@@ -468,23 +450,23 @@ AC_DEFUN([TORRENT_CHECK_PTHREAD_SETNAME_NP], [
AC_MSG_CHECKING(for pthread_setname_np type)
AC_TRY_LINK([
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
#include <pthread.h>
#include <sys/types.h>
],[
]], [[
pthread_t t;
pthread_setname_np(t, "foo");
],[
]])],[
AC_DEFINE(HAS_PTHREAD_SETNAME_NP_GENERIC, 1, The function to set pthread name has a pthread_t argumet.)
AC_MSG_RESULT(generic)
],[
AC_TRY_LINK([
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
#include <pthread.h>
#include <sys/types.h>
],[
]],[[
pthread_t t;
pthread_setname_np("foo");
],[
]])],[
AC_DEFINE(HAS_PTHREAD_SETNAME_NP_DARWIN, 1, The function to set pthread name has no pthread argument.)
AC_MSG_RESULT(darwin)
],[
@@ -492,3 +474,21 @@ AC_DEFUN([TORRENT_CHECK_PTHREAD_SETNAME_NP], [
])
])
])
AC_DEFUN([TORRENT_DISABLE_PTHREAD_SETNAME_NP], [
AC_MSG_CHECKING([for pthread_setname_no])
AC_ARG_ENABLE(pthread-setname-np,
AS_HELP_STRING([--disable-pthread-setname-np],[disable pthread_setname_np]),
[
if test "$enableval" = "no"; then
AC_MSG_RESULT(disabled)
else
AC_MSG_RESULT(checking)
TORRENT_CHECK_PTHREAD_SETNAME_NP
fi
], [
TORRENT_CHECK_PTHREAD_SETNAME_NP
]
)
])
+14 -23
View File
@@ -1,6 +1,7 @@
AC_DEFUN([TORRENT_WITH_SYSROOT], [
AC_ARG_WITH(sysroot,
AC_HELP_STRING([--with-sysroot=PATH], [compile and link with a specific sysroot]),
AS_HELP_STRING([--with-sysroot=PATH],
[compile and link with a specific sysroot]),
[
AC_MSG_CHECKING(for sysroot)
@@ -22,7 +23,8 @@ AC_DEFUN([TORRENT_WITH_SYSROOT], [
AC_DEFUN([TORRENT_ENABLE_ARCH], [
AC_ARG_ENABLE(arch,
AC_HELP_STRING([--enable-arch=ARCH], [comma seprated list of architectures to compile for]),
AS_HELP_STRING([--enable-arch=ARCH],
[comma seprated list of architectures to compile for]),
[
AC_MSG_CHECKING(for target architectures)
@@ -82,7 +84,8 @@ AC_DEFUN([TORRENT_MINCORE_SIGNEDNESS], [
AC_DEFUN([TORRENT_MINCORE], [
AC_ARG_ENABLE(mincore,
AC_HELP_STRING([--disable-mincore], [disable mincore check [[default=enable]]]),
AS_HELP_STRING([--disable-mincore],
[disable mincore check [[default=enable]]]),
[
if test "$enableval" = "yes"; then
TORRENT_MINCORE_SIGNEDNESS()
@@ -150,21 +153,6 @@ dnl Need to fix this so that it uses the stuff defined by the system.
])
])
AC_DEFUN([TORRENT_CHECK_EXECINFO], [
AC_MSG_CHECKING(for execinfo.h)
AC_RUN_IFELSE([AC_LANG_SOURCE([
#include <execinfo.h>
int main() { backtrace((void**)0, 0); backtrace_symbols((char**)0, 0); return 0;}
])],
[
AC_MSG_RESULT(yes)
AC_DEFINE(USE_EXECINFO, 1, Use execinfo.h)
], [
AC_MSG_RESULT(no)
])
])
AC_DEFUN([TORRENT_CHECK_ALIGNED], [
AC_MSG_CHECKING(the byte alignment)
@@ -189,7 +177,8 @@ AC_DEFUN([TORRENT_CHECK_ALIGNED], [
AC_DEFUN([TORRENT_ENABLE_ALIGNED], [
AC_ARG_ENABLE(aligned,
AC_HELP_STRING([--enable-aligned], [enable alignment safe code [[default=check]]]),
AS_HELP_STRING([--enable-aligned],
[enable alignment safe code [[default=check]]]),
[
if test "$enableval" = "yes"; then
AC_DEFINE(USE_ALIGNED, 1, Require byte alignment)
@@ -204,7 +193,8 @@ AC_DEFUN([TORRENT_DISABLE_INSTRUMENTATION], [
AC_MSG_CHECKING([if instrumentation should be included])
AC_ARG_ENABLE(instrumentation,
AC_HELP_STRING([--disable-instrumentation], [disable instrumentation [[default=enabled]]]),
AS_HELP_STRING([--disable-instrumentation],
[disable instrumentation [[default=enabled]]]),
[
if test "$enableval" = "yes"; then
AC_DEFINE(LT_INSTRUMENTATION, 1, enable instrumentation)
@@ -221,7 +211,8 @@ AC_DEFUN([TORRENT_DISABLE_INSTRUMENTATION], [
AC_DEFUN([TORRENT_ENABLE_INTERRUPT_SOCKET], [
AC_ARG_ENABLE(interrupt-socket,
AC_HELP_STRING([--enable-interrupt-socket], [enable interrupt socket [[default=no]]]),
AS_HELP_STRING([--enable-interrupt-socket],
[enable interrupt socket [[default=no]]]),
[
if test "$enableval" = "yes"; then
AC_DEFINE(USE_INTERRUPT_SOCKET, 1, Use interrupt socket instead of pthread_kill)
@@ -230,10 +221,10 @@ AC_DEFUN([TORRENT_ENABLE_INTERRUPT_SOCKET], [
)
])
AC_DEFUN([TORRENT_DISABLE_IPV6], [
AC_ARG_ENABLE(ipv6,
AC_HELP_STRING([--enable-ipv6], [enable ipv6 [[default=no]]]),
AS_HELP_STRING([--enable-ipv6],
[enable ipv6 [[default=no]]]),
[
if test "$enableval" = "yes"; then
AC_DEFINE(RAK_USE_INET6, 1, enable ipv6 stuff)
-272
View File
@@ -1,272 +0,0 @@
#***************************************************************************
# _ _ ____ _
# Project ___| | | | _ \| |
# / __| | | | |_) | |
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
# Copyright (C) 2006, David Shaw <dshaw@jabberwocky.com>
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
# are also available at https://curl.haxx.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
# furnished to do so, under the terms of the COPYING file.
#
# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
# KIND, either express or implied.
#
###########################################################################
# LIBCURL_CHECK_CONFIG ([DEFAULT-ACTION], [MINIMUM-VERSION],
# [ACTION-IF-YES], [ACTION-IF-NO])
# ----------------------------------------------------------
# David Shaw <dshaw@jabberwocky.com> May-09-2006
#
# Checks for libcurl. DEFAULT-ACTION is the string yes or no to
# specify whether to default to --with-libcurl or --without-libcurl.
# If not supplied, DEFAULT-ACTION is yes. MINIMUM-VERSION is the
# minimum version of libcurl to accept. Pass the version as a regular
# version number like 7.10.1. If not supplied, any version is
# accepted. ACTION-IF-YES is a list of shell commands to run if
# libcurl was successfully found and passed the various tests.
# ACTION-IF-NO is a list of shell commands that are run otherwise.
# Note that using --without-libcurl does run ACTION-IF-NO.
#
# This macro #defines HAVE_LIBCURL if a working libcurl setup is
# found, and sets @LIBCURL@ and @LIBCURL_CPPFLAGS@ to the necessary
# values. Other useful defines are LIBCURL_FEATURE_xxx where xxx are
# the various features supported by libcurl, and LIBCURL_PROTOCOL_yyy
# where yyy are the various protocols supported by libcurl. Both xxx
# and yyy are capitalized. See the list of AH_TEMPLATEs at the top of
# the macro for the complete list of possible defines. Shell
# variables $libcurl_feature_xxx and $libcurl_protocol_yyy are also
# defined to 'yes' for those features and protocols that were found.
# Note that xxx and yyy keep the same capitalization as in the
# curl-config list (e.g. it's "HTTP" and not "http").
#
# Users may override the detected values by doing something like:
# LIBCURL="-lcurl" LIBCURL_CPPFLAGS="-I/usr/myinclude" ./configure
#
# For the sake of sanity, this macro assumes that any libcurl that is
# found is after version 7.7.2, the first version that included the
# curl-config script. Note that it is very important for people
# packaging binary versions of libcurl to include this script!
# Without curl-config, we can only guess what protocols are available,
# or use curl_version_info to figure it out at runtime.
AC_DEFUN([LIBCURL_CHECK_CONFIG],
[
AH_TEMPLATE([LIBCURL_FEATURE_SSL],[Defined if libcurl supports SSL])
AH_TEMPLATE([LIBCURL_FEATURE_KRB4],[Defined if libcurl supports KRB4])
AH_TEMPLATE([LIBCURL_FEATURE_IPV6],[Defined if libcurl supports IPv6])
AH_TEMPLATE([LIBCURL_FEATURE_LIBZ],[Defined if libcurl supports libz])
AH_TEMPLATE([LIBCURL_FEATURE_ASYNCHDNS],[Defined if libcurl supports AsynchDNS])
AH_TEMPLATE([LIBCURL_FEATURE_IDN],[Defined if libcurl supports IDN])
AH_TEMPLATE([LIBCURL_FEATURE_SSPI],[Defined if libcurl supports SSPI])
AH_TEMPLATE([LIBCURL_FEATURE_NTLM],[Defined if libcurl supports NTLM])
AH_TEMPLATE([LIBCURL_PROTOCOL_HTTP],[Defined if libcurl supports HTTP])
AH_TEMPLATE([LIBCURL_PROTOCOL_HTTPS],[Defined if libcurl supports HTTPS])
AH_TEMPLATE([LIBCURL_PROTOCOL_FTP],[Defined if libcurl supports FTP])
AH_TEMPLATE([LIBCURL_PROTOCOL_FTPS],[Defined if libcurl supports FTPS])
AH_TEMPLATE([LIBCURL_PROTOCOL_FILE],[Defined if libcurl supports FILE])
AH_TEMPLATE([LIBCURL_PROTOCOL_TELNET],[Defined if libcurl supports TELNET])
AH_TEMPLATE([LIBCURL_PROTOCOL_LDAP],[Defined if libcurl supports LDAP])
AH_TEMPLATE([LIBCURL_PROTOCOL_DICT],[Defined if libcurl supports DICT])
AH_TEMPLATE([LIBCURL_PROTOCOL_TFTP],[Defined if libcurl supports TFTP])
AH_TEMPLATE([LIBCURL_PROTOCOL_RTSP],[Defined if libcurl supports RTSP])
AH_TEMPLATE([LIBCURL_PROTOCOL_POP3],[Defined if libcurl supports POP3])
AH_TEMPLATE([LIBCURL_PROTOCOL_IMAP],[Defined if libcurl supports IMAP])
AH_TEMPLATE([LIBCURL_PROTOCOL_SMTP],[Defined if libcurl supports SMTP])
AC_ARG_WITH(libcurl,
AS_HELP_STRING([--with-libcurl=PREFIX],[look for the curl library in PREFIX/lib and headers in PREFIX/include]),
[_libcurl_with=$withval],[_libcurl_with=ifelse([$1],,[yes],[$1])])
if test "$_libcurl_with" != "no" ; then
AC_PROG_AWK
_libcurl_version_parse="eval $AWK '{split(\$NF,A,\".\"); X=256*256*A[[1]]+256*A[[2]]+A[[3]]; print X;}'"
_libcurl_try_link=yes
if test -d "$_libcurl_with" ; then
LIBCURL_CPPFLAGS="-I$withval/include"
_libcurl_ldflags="-L$withval/lib"
AC_PATH_PROG([_libcurl_config],[curl-config],[],
["$withval/bin"])
else
AC_PATH_PROG([_libcurl_config],[curl-config],[],[$PATH])
fi
if test x$_libcurl_config != "x" ; then
AC_CACHE_CHECK([for the version of libcurl],
[libcurl_cv_lib_curl_version],
[libcurl_cv_lib_curl_version=`$_libcurl_config --version | $AWK '{print $[]2}'`])
_libcurl_version=`echo $libcurl_cv_lib_curl_version | $_libcurl_version_parse`
_libcurl_wanted=`echo ifelse([$2],,[0],[$2]) | $_libcurl_version_parse`
if test $_libcurl_wanted -gt 0 ; then
AC_CACHE_CHECK([for libcurl >= version $2],
[libcurl_cv_lib_version_ok],
[
if test $_libcurl_version -ge $_libcurl_wanted ; then
libcurl_cv_lib_version_ok=yes
else
libcurl_cv_lib_version_ok=no
fi
])
fi
if test $_libcurl_wanted -eq 0 || test x$libcurl_cv_lib_version_ok = xyes ; then
if test x"$LIBCURL_CPPFLAGS" = "x" ; then
LIBCURL_CPPFLAGS=`$_libcurl_config --cflags`
fi
if test x"$LIBCURL" = "x" ; then
LIBCURL=`$_libcurl_config --libs`
# This is so silly, but Apple actually has a bug in their
# curl-config script. Fixed in Tiger, but there are still
# lots of Panther installs around.
case "${host}" in
powerpc-apple-darwin7*)
LIBCURL=`echo $LIBCURL | sed -e 's|-arch i386||g'`
;;
esac
fi
# All curl-config scripts support --feature
_libcurl_features=`$_libcurl_config --feature`
# Is it modern enough to have --protocols? (7.12.4)
if test $_libcurl_version -ge 461828 ; then
_libcurl_protocols=`$_libcurl_config --protocols`
fi
else
_libcurl_try_link=no
fi
unset _libcurl_wanted
fi
if test $_libcurl_try_link = yes ; then
# we didn't find curl-config, so let's see if the user-supplied
# link line (or failing that, "-lcurl") is enough.
LIBCURL=${LIBCURL-"$_libcurl_ldflags -lcurl"}
AC_CACHE_CHECK([whether libcurl is usable],
[libcurl_cv_lib_curl_usable],
[
_libcurl_save_cppflags=$CPPFLAGS
CPPFLAGS="$LIBCURL_CPPFLAGS $CPPFLAGS"
_libcurl_save_libs=$LIBS
LIBS="$LIBCURL $LIBS"
AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <curl/curl.h>]],[[
/* Try and use a few common options to force a failure if we are
missing symbols or can't link. */
int x;
curl_easy_setopt(NULL,CURLOPT_URL,NULL);
x=CURL_ERROR_SIZE;
x=CURLOPT_WRITEFUNCTION;
x=CURLOPT_WRITEDATA;
x=CURLOPT_ERRORBUFFER;
x=CURLOPT_STDERR;
x=CURLOPT_VERBOSE;
if (x) {;}
]])],libcurl_cv_lib_curl_usable=yes,libcurl_cv_lib_curl_usable=no)
CPPFLAGS=$_libcurl_save_cppflags
LIBS=$_libcurl_save_libs
unset _libcurl_save_cppflags
unset _libcurl_save_libs
])
if test $libcurl_cv_lib_curl_usable = yes ; then
# Does curl_free() exist in this version of libcurl?
# If not, fake it with free()
_libcurl_save_cppflags=$CPPFLAGS
CPPFLAGS="$CPPFLAGS $LIBCURL_CPPFLAGS"
_libcurl_save_libs=$LIBS
LIBS="$LIBS $LIBCURL"
AC_CHECK_FUNC(curl_free,,
AC_DEFINE(curl_free,free,
[Define curl_free() as free() if our version of curl lacks curl_free.]))
CPPFLAGS=$_libcurl_save_cppflags
LIBS=$_libcurl_save_libs
unset _libcurl_save_cppflags
unset _libcurl_save_libs
AC_DEFINE(HAVE_LIBCURL,1,
[Define to 1 if you have a functional curl library.])
AC_SUBST(LIBCURL_CPPFLAGS)
AC_SUBST(LIBCURL)
for _libcurl_feature in $_libcurl_features ; do
AC_DEFINE_UNQUOTED(AS_TR_CPP(libcurl_feature_$_libcurl_feature),[1])
eval AS_TR_SH(libcurl_feature_$_libcurl_feature)=yes
done
if test "x$_libcurl_protocols" = "x" ; then
# We don't have --protocols, so just assume that all
# protocols are available
_libcurl_protocols="HTTP FTP FILE TELNET LDAP DICT TFTP"
if test x$libcurl_feature_SSL = xyes ; then
_libcurl_protocols="$_libcurl_protocols HTTPS"
# FTPS wasn't standards-compliant until version
# 7.11.0 (0x070b00 == 461568)
if test $_libcurl_version -ge 461568; then
_libcurl_protocols="$_libcurl_protocols FTPS"
fi
fi
# RTSP, IMAP, POP3 and SMTP were added in
# 7.20.0 (0x071400 == 463872)
if test $_libcurl_version -ge 463872; then
_libcurl_protocols="$_libcurl_protocols RTSP IMAP POP3 SMTP"
fi
fi
for _libcurl_protocol in $_libcurl_protocols ; do
AC_DEFINE_UNQUOTED(AS_TR_CPP(libcurl_protocol_$_libcurl_protocol),[1])
eval AS_TR_SH(libcurl_protocol_$_libcurl_protocol)=yes
done
else
unset LIBCURL
unset LIBCURL_CPPFLAGS
fi
fi
unset _libcurl_try_link
unset _libcurl_version_parse
unset _libcurl_config
unset _libcurl_feature
unset _libcurl_features
unset _libcurl_protocol
unset _libcurl_protocols
unset _libcurl_version
unset _libcurl_ldflags
fi
if test x$_libcurl_with = xno || test x$libcurl_cv_lib_curl_usable != xyes ; then
# This is the IF-NO path
ifelse([$4],,:,[$4])
else
# This is the IF-YES path
ifelse([$3],,:,[$3])
fi
unset _libcurl_with
])dnl
+3 -3
View File
@@ -26,7 +26,7 @@ AC_DEFUN([RAK_CHECK_CXXFLAGS], [
AC_DEFUN([RAK_ENABLE_DEBUG], [
AC_ARG_ENABLE(debug,
AC_HELP_STRING([--enable-debug], [enable debug information [[default=yes]]]),
AS_HELP_STRING([--enable-debug],[enable debug information [[default=yes]]]),
[
if test "$enableval" = "yes"; then
CXXFLAGS="$CXXFLAGS -g -DDEBUG"
@@ -41,7 +41,7 @@ AC_DEFUN([RAK_ENABLE_DEBUG], [
AC_DEFUN([RAK_ENABLE_WERROR], [
AC_ARG_ENABLE(werror,
AC_HELP_STRING([--enable-werror], [enable the -Werror and -Wall flags [[default -Wall only]]]),
AS_HELP_STRING([--enable-werror],[enable the -Werror and -Wall flags [[default -Wall only]]]),
[
if test "$enableval" = "yes"; then
CXXFLAGS="$CXXFLAGS -Werror -Wall"
@@ -54,7 +54,7 @@ AC_DEFUN([RAK_ENABLE_WERROR], [
AC_DEFUN([RAK_ENABLE_EXTRA_DEBUG], [
AC_ARG_ENABLE(extra-debug,
AC_HELP_STRING([--enable-extra-debug], [enable extra debugging checks [[default=no]]]),
AS_HELP_STRING([--enable-extra-debug],[enable extra debugging checks [[default=no]]]),
[
if test "$enableval" = "yes"; then
AC_DEFINE(USE_EXTRA_DEBUG, 1, Enable extra debugging checks.)
-61
View File
@@ -1,61 +0,0 @@
AC_DEFUN([RAK_CHECK_CXX11], [
AC_ARG_ENABLE([c++0x],
AC_HELP_STRING([--enable-c++0x], [compile with C++0x (unsupported)]),
[
if test "$enableval" = "yes"; then
AX_CXX_COMPILE_STDCXX_0X
else
AX_CXX_COMPILE_STDCXX_11(noext)
fi
],[
AX_CXX_COMPILE_STDCXX_11(noext)
]
)
])
AC_DEFUN([RAK_CHECK_TR1_LIB], [
AC_LANG_PUSH(C++)
AC_MSG_CHECKING(should use TR1 headers)
AC_COMPILE_IFELSE([AC_LANG_SOURCE([
#include <unordered_map>
class Foo; typedef std::unordered_map<Foo*, int> Bar;
Bar b1;
])
], [
AC_MSG_RESULT(no)
AC_DEFINE(USE_TR1_LIB, 0, Define to 1 if you need to use TR1 containers.)
AC_DEFINE([lt_tr1_array], [<array>], [TR1 array])
AC_DEFINE([lt_tr1_functional], [<functional>], [TR1 functional])
AC_DEFINE([lt_tr1_memory], [<memory>], [TR1 memory])
AC_DEFINE([lt_tr1_unordered_map], [<unordered_map>], [TR1 unordered_map])
], [
AC_COMPILE_IFELSE([AC_LANG_SOURCE([
#include <tr1/unordered_map>
class Foo; typedef std::tr1::unordered_map<Foo*, int> Bar;
Bar b1;
])
], [
AC_MSG_RESULT([yes])
AC_DEFINE(USE_TR1_LIB, 1, Define to 1 if you need to use TR1 containers.)
AC_DEFINE([lt_tr1_array], [<tr1/array>], [TR1 array])
AC_DEFINE([lt_tr1_functional], [<tr1/functional>], [TR1 functional])
AC_DEFINE([lt_tr1_memory], [<tr1/memory>], [TR1 memory])
AC_DEFINE([lt_tr1_unordered_map], [<tr1/unordered_map>], [TR1 unordered_map])
], [
AC_MSG_ERROR([No support for C++11 standard library nor TR1 extensions found.])
])
])
AH_VERBATIM(lt_tr1_zzz, [
#if USE_TR1_LIB == 1
namespace std { namespace tr1 {} using namespace tr1; }
#endif
])
AC_LANG_POP(C++)
])
+38
View File
@@ -0,0 +1,38 @@
AC_DEFUN([TORRENT_CHECK_OPENSSL],
[
PKG_CHECK_MODULES(OPENSSL, libcrypto,
CXXFLAGS="$CXXFLAGS $OPENSSL_CFLAGS";
LIBS="$LIBS $OPENSSL_LIBS")
AC_DEFINE(USE_OPENSSL, 1, Using OpenSSL.)
AC_DEFINE(USE_OPENSSL_SHA, 1, Using OpenSSL's SHA1 implementation.)
]
)
AC_DEFUN([TORRENT_ARG_OPENSSL],
[
AC_ARG_ENABLE(openssl,
[ --disable-openssl Don't use OpenSSL's SHA1 implementation.],
[
if test "$enableval" = "yes"; then
TORRENT_CHECK_OPENSSL
else
AC_DEFINE(USE_NSS_SHA, 1, Using Mozilla's SHA1 implementation.)
fi
],[
TORRENT_CHECK_OPENSSL
])
]
)
AC_DEFUN([TORRENT_ARG_CYRUS_RC4],
[
AC_ARG_ENABLE(cyrus-rc4,
[ --enable-cyrus-rc4=PFX Use Cyrus RC4 implementation.],
[
CXXFLAGS="$CXXFLAGS -I${enableval}/include";
LIBS="$LIBS -lrc4 -L${enableval}/lib"
AC_DEFINE(USE_CYRUS_RC4, 1, Using Cyrus RC4 implementation.)
])
]
)
+160 -23
View File
@@ -1,14 +1,166 @@
SUBDIRS = \
core \
display \
input \
rpc \
ui \
utils
noinst_LIBRARIES = libsub_root.a
bin_PROGRAMS = rtorrent
rtorrent_LDADD = libsub_root.a @PTHREAD_LIBS@
rtorrent_SOURCES = main.cc
libsub_root_a_SOURCES = \
core/curl_get.cc \
core/curl_get.h \
core/curl_socket.cc \
core/curl_socket.h \
core/curl_stack.cc \
core/curl_stack.h \
core/dht_manager.cc \
core/dht_manager.h \
core/download.cc \
core/download.h \
core/download_factory.cc \
core/download_factory.h \
core/download_list.cc \
core/download_list.h \
core/download_slot_map.h \
core/download_store.cc \
core/download_store.h \
core/http_queue.cc \
core/http_queue.h \
core/manager.cc \
core/manager.h \
core/poll_manager.cc \
core/poll_manager.h \
core/range_map.h \
core/view.cc \
core/view.h \
core/view_manager.cc \
core/view_manager.h \
\
display/attributes.h \
display/canvas.cc \
display/canvas.h \
display/frame.cc \
display/frame.h \
display/manager.cc \
display/manager.h \
display/utils.cc \
display/utils.h \
display/text_element.h \
display/text_element_list.cc \
display/text_element_list.h \
display/text_element_string.cc \
display/text_element_string.h \
display/text_element_value.cc \
display/text_element_value.h \
display/window.cc \
display/window.h \
display/window_download_chunks_seen.cc \
display/window_download_chunks_seen.h \
display/window_download_list.cc \
display/window_download_list.h \
display/window_download_statusbar.cc \
display/window_download_statusbar.h \
display/window_download_transfer_list.cc \
display/window_download_transfer_list.h \
display/window_file_list.cc \
display/window_file_list.h \
display/window_http_queue.cc \
display/window_http_queue.h \
display/window_input.cc \
display/window_input.h \
display/window_log.cc \
display/window_log.h \
display/window_log_complete.cc \
display/window_log_complete.h \
display/window_peer_list.cc \
display/window_peer_list.h \
display/window_statusbar.cc \
display/window_statusbar.h \
display/window_string_list.cc \
display/window_string_list.h \
display/window_text.cc \
display/window_text.h \
display/window_title.cc \
display/window_title.h \
display/window_tracker_list.cc \
display/window_tracker_list.h \
\
input/bindings.cc \
input/bindings.h \
input/input_event.cc \
input/input_event.h \
input/manager.cc \
input/manager.h \
input/path_input.cc \
input/path_input.h \
input/text_input.cc \
input/text_input.h \
\
rpc/command.h \
rpc/command.cc \
rpc/command_impl.h \
rpc/command_map.cc \
rpc/command_map.h \
rpc/command_scheduler.cc \
rpc/command_scheduler.h \
rpc/command_scheduler_item.cc \
rpc/command_scheduler_item.h \
rpc/exec_file.cc \
rpc/exec_file.h \
rpc/fixed_key.h \
rpc/ip_table_list.h \
rpc/object_storage.cc \
rpc/object_storage.h \
rpc/parse.cc \
rpc/parse.h \
rpc/parse_commands.cc \
rpc/parse_commands.h \
rpc/parse_options.cc \
rpc/parse_options.h \
rpc/scgi.cc \
rpc/scgi.h \
rpc/scgi_task.cc \
rpc/scgi_task.h \
rpc/xmlrpc.h \
rpc/xmlrpc.cc \
\
ui/download.cc \
ui/download.h \
ui/download_list.cc \
ui/download_list.h \
ui/element_base.h \
ui/element_base.cc \
ui/element_chunks_seen.cc \
ui/element_chunks_seen.h \
ui/element_download_list.cc \
ui/element_download_list.h \
ui/element_file_list.cc \
ui/element_file_list.h \
ui/element_log_complete.cc \
ui/element_log_complete.h \
ui/element_menu.cc \
ui/element_menu.h \
ui/element_peer_list.cc \
ui/element_peer_list.h \
ui/element_string_list.cc \
ui/element_string_list.h \
ui/element_text.cc \
ui/element_text.h \
ui/element_tracker_list.cc \
ui/element_tracker_list.h \
ui/element_transfer_list.cc \
ui/element_transfer_list.h \
ui/root.cc \
ui/root.h \
\
utils/directory.cc \
utils/directory.h \
utils/file_status_cache.cc \
utils/file_status_cache.h \
utils/list_focus.h \
utils/lockfile.cc \
utils/lockfile.h \
utils/socket_fd.cc \
utils/socket_fd.h \
\
command_download.cc \
command_dynamic.cc \
command_events.cc \
@@ -38,19 +190,4 @@ libsub_root_a_SOURCES = \
thread_worker.cc \
thread_worker.h
bin_PROGRAMS = rtorrent
rtorrent_LDADD = \
libsub_root.a \
ui/libsub_ui.a \
core/libsub_core.a \
display/libsub_display.a \
input/libsub_input.a \
rpc/libsub_rpc.a \
utils/libsub_utils.a \
@PTHREAD_LIBS@
rtorrent_SOURCES = \
main.cc
AM_CPPFLAGS = -I$(srcdir) -I$(top_srcdir)
+44 -3
View File
@@ -140,7 +140,7 @@ apply_d_change_link(core::Download* download, const torrent::Object::list_type&
case 0:
if (symlink(target.c_str(), link.c_str()) == -1){
lt_log_print(torrent::LOG_TORRENT_WARN, "create_link failed: %s",
rak::error_number::current().c_str());
rak::error_number::current().c_str());
}
break;
@@ -274,6 +274,41 @@ retrieve_d_custom_throw(core::Download* download, const std::string& key) {
}
}
torrent::Object
retrieve_d_custom_if_z(core::Download* download, const torrent::Object::list_type& args) {
torrent::Object::list_const_iterator itr = args.begin();
if (itr == args.end())
throw torrent::bencode_error("d.custom.if_z: Missing key argument.");
const std::string& key = (itr++)->as_string();
if (key.empty())
throw torrent::bencode_error("d.custom.if_z: Empty key argument.");
if (itr == args.end())
throw torrent::bencode_error("d.custom.if_z: Missing default argument.");
try {
const std::string& val = download->bencode()->get_key("rtorrent").get_key("custom").get_key_string(key);
return val.empty() ? itr->as_string() : val;
} catch (torrent::bencode_error& e) {
return itr->as_string();
}
}
torrent::Object
retrieve_d_custom_map(core::Download* download, bool keys_only, const torrent::Object::list_type& args) {
if (args.begin() != args.end())
throw torrent::bencode_error("d.custom.keys/items takes no arguments.");
torrent::Object result = keys_only ? torrent::Object::create_list() : torrent::Object::create_map();
torrent::Object::map_type& entries = download->bencode()->get_key("rtorrent").get_key("custom").as_map();
for (torrent::Object::map_type::const_iterator itr = entries.begin(), last = entries.end(); itr != last; itr++) {
if (keys_only) result.as_list().push_back(itr->first);
else result.as_map()[itr->first] = itr->second;
}
return result;
}
torrent::Object
retrieve_d_bitfield(core::Download* download) {
const torrent::Bitfield* bitField = download->download()->file_list()->bitfield();
@@ -289,7 +324,7 @@ struct call_add_d_peer_t {
void operator() (const sockaddr* sa, int err) {
if (sa == NULL) {
lt_log_print(torrent::LOG_CONNECTION_WARN, "Could not resolve hostname for added peer.");
lt_log_print(torrent::LOG_TORRENT_WARN, "could not resolve hostname for added peer");
} else {
m_download->download()->add_peer(sa, m_port);
}
@@ -710,6 +745,9 @@ initialize_command_download() {
CMD2_DL_STRING("d.custom", std::bind(&retrieve_d_custom, std::placeholders::_1, std::placeholders::_2));
CMD2_DL_STRING("d.custom_throw", std::bind(&retrieve_d_custom_throw, std::placeholders::_1, std::placeholders::_2));
CMD2_DL_LIST ("d.custom.set", std::bind(&apply_d_custom, std::placeholders::_1, std::placeholders::_2));
CMD2_DL_LIST ("d.custom.if_z", std::bind(&retrieve_d_custom_if_z, std::placeholders::_1, std::placeholders::_2));
CMD2_DL_LIST ("d.custom.keys", std::bind(&retrieve_d_custom_map, std::placeholders::_1, true, std::placeholders::_2));
CMD2_DL_LIST ("d.custom.items", std::bind(&retrieve_d_custom_map, std::placeholders::_1, false, std::placeholders::_2));
CMD2_DL_VAR_STRING_PUBLIC("d.custom1", "rtorrent", "custom1");
CMD2_DL_VAR_STRING_PUBLIC("d.custom2", "rtorrent", "custom2");
@@ -834,7 +872,10 @@ initialize_command_download() {
CMD2_DL ("d.wanted_chunks", CMD2_ON_DATA(wanted_chunks));
CMD2_DL_V ("d.tracker_announce", std::bind(&torrent::Download::manual_request, CMD2_BIND_DL, false));
// Do not exposre d.tracker_announce.force to regular users.
CMD2_DL_V ("d.tracker_announce", std::bind(&torrent::Download::manual_request, CMD2_BIND_DL, false));
CMD2_DL_V ("d.tracker_announce.force", std::bind(&torrent::Download::manual_request, CMD2_BIND_DL, true));
CMD2_DL ("d.tracker_numwant", std::bind(&torrent::TrackerList::numwant, CMD2_BIND_TL));
CMD2_DL_VALUE_V ("d.tracker_numwant.set", std::bind(&torrent::TrackerList::set_numwant, CMD2_BIND_TL, std::placeholders::_2));
// TODO: Deprecate 'd.tracker_focus'.
+70 -81
View File
@@ -44,6 +44,30 @@
#include "control.h"
#include "command_helpers.h"
#include "rpc/parse.h"
#include "rpc/parse_options.h"
static std::vector<std::pair<const char*, int>> object_storage_flags = {
{ "multi", rpc::object_storage::flag_multi_type },
{ "simple", rpc::object_storage::flag_function_type },
{ "value", rpc::object_storage::flag_value_type },
{ "bool", rpc::object_storage::flag_bool_type },
{ "string", rpc::object_storage::flag_string_type },
{ "list", rpc::object_storage::flag_list_type },
{ "static", rpc::object_storage::flag_static },
{ "private", rpc::object_storage::flag_private },
{ "const", rpc::object_storage::flag_constant },
{ "rlookup", rpc::object_storage::flag_rlookup }
};
static int
object_storage_parse_flag(const std::string& flag) {
for (auto f : object_storage_flags)
if (f.first == flag)
return f.second;
throw torrent::input_error("unknown flag");
}
std::string
system_method_generate_command(torrent::Object::list_const_iterator first, torrent::Object::list_const_iterator last) {
@@ -122,7 +146,7 @@ system_method_insert_object(const torrent::Object::list_type& args, int flags) {
const std::string& rawKey = (itrArgs++)->as_string();
if (rawKey.empty() ||
control->object_storage()->find_local(torrent::raw_string::from_string(rawKey)) != control->object_storage()->end(0) ||
control->object_storage()->find_raw_string(torrent::raw_string::from_string(rawKey)) != control->object_storage()->end() ||
rpc::commands.has(rawKey) || rpc::commands.has(rawKey + ".set"))
throw torrent::input_error("Invalid key.");
@@ -139,20 +163,33 @@ system_method_insert_object(const torrent::Object::list_type& args, int flags) {
case rpc::object_storage::flag_function_type:
system_method_generate_command2(&value, itrArgs, args.end());
break;
case rpc::object_storage::flag_list_type:
break;
case rpc::object_storage::flag_multi_type:
break;
default:
throw torrent::input_error("Invalid type.");
}
int cmd_flags = 0;
// We must initialize this varriable to prevent a critical memory leak
int cmd_flags = rpc::CommandMap::flag_delete_key;
if (!(flags & rpc::object_storage::flag_static))
cmd_flags |= rpc::CommandMap::flag_modifiable;
if (!(flags & rpc::object_storage::flag_private))
cmd_flags |= rpc::CommandMap::flag_public_xmlrpc;
control->object_storage()->insert_str(rawKey, value, flags);
if ((flags & rpc::object_storage::mask_type) == rpc::object_storage::flag_list_type) {
torrent::Object valueList = torrent::Object::create_list();
torrent::Object::list_type& valueListType = valueList.as_list();
if ((itrArgs)->is_list())
valueListType = (itrArgs)->as_list();
control->object_storage()->insert_str(rawKey, valueList, flags);
} else {
control->object_storage()->insert_str(rawKey, value, flags);
}
if ((flags & rpc::object_storage::mask_type) == rpc::object_storage::flag_function_type ||
(flags & rpc::object_storage::mask_type) == rpc::object_storage::flag_multi_type) {
@@ -208,6 +245,13 @@ system_method_insert_object(const torrent::Object::list_type& args, int flags) {
&rpc::command_base_call_string<rpc::target_type>,
cmd_flags, NULL, NULL);
break;
case rpc::object_storage::flag_list_type:
rpc::commands.insert_slot<rpc::command_base_is_type<rpc::command_base_call_list<rpc::target_type> >::type>
(create_new_key<5>(rawKey, ".set"),
std::bind(&rpc::object_storage::set_str_list, control->object_storage(), rawKey, std::placeholders::_2),
&rpc::command_base_call_list<rpc::target_type>,
cmd_flags, NULL, NULL);
break;
case rpc::object_storage::flag_function_type:
case rpc::object_storage::flag_multi_type:
default: break;
@@ -244,91 +288,33 @@ system_method_insert(const torrent::Object::list_type& args) {
throw torrent::input_error("Invalid key.");
int flags = rpc::CommandMap::flag_delete_key | rpc::CommandMap::flag_modifiable | rpc::CommandMap::flag_public_xmlrpc;
int new_flags = rpc::parse_option_flags(itrArgs->as_string(), std::bind(&object_storage_parse_flag, std::placeholders::_1));
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 ((new_flags & rpc::object_storage::flag_private))
flags &= ~rpc::CommandMap::flag_public_xmlrpc;
if (options.find("const") != std::string::npos)
if ((new_flags & rpc::object_storage::flag_constant))
flags &= ~rpc::CommandMap::flag_modifiable;
if (options.find("multi") != std::string::npos) {
torrent::Object::list_type new_args;
new_args.push_back(rawKey);
torrent::Object::list_type new_args;
new_args.push_back(rawKey);
if ((new_flags & rpc::object_storage::flag_function_type) ||
(new_flags & rpc::object_storage::flag_multi_type)) {
new_args.push_back(system_method_generate_command(++itrArgs, args.end()));
int new_flags = rpc::object_storage::flag_multi_type;
if (options.find("static") != std::string::npos)
new_flags |= rpc::object_storage::flag_static;
if (options.find("private") != std::string::npos)
new_flags |= rpc::object_storage::flag_private;
if (options.find("const") != std::string::npos)
new_flags |= rpc::object_storage::flag_constant;
if (options.find("rlookup") != std::string::npos)
new_flags |= rpc::object_storage::flag_rlookup;
return system_method_insert_object(new_args, new_flags);
} else if (options.find("simple") != std::string::npos) {
torrent::Object::list_type new_args;
new_args.push_back(rawKey);
new_args.push_back(system_method_generate_command(++itrArgs, args.end()));
int new_flags = rpc::object_storage::flag_function_type;
if (options.find("static") != std::string::npos)
new_flags |= rpc::object_storage::flag_static;
if (options.find("private") != std::string::npos)
new_flags |= rpc::object_storage::flag_private;
if (options.find("const") != std::string::npos)
new_flags |= rpc::object_storage::flag_constant;
return system_method_insert_object(new_args, new_flags);
} else if (options.find("value") != std::string::npos ||
options.find("bool") != std::string::npos ||
options.find("string") != std::string::npos ||
options.find("list") != std::string::npos) {
torrent::Object::list_type new_args;
new_args.push_back(rawKey);
} else if ((new_flags & rpc::object_storage::flag_value_type) ||
(new_flags & rpc::object_storage::flag_bool_type) ||
(new_flags & rpc::object_storage::flag_string_type) ||
(new_flags & rpc::object_storage::flag_list_type)) {
if (++itrArgs != args.end())
new_args.insert(new_args.end(), itrArgs, args.end());
int new_flags;
if (options.find("value") != std::string::npos)
new_flags = rpc::object_storage::flag_value_type;
else if (options.find("bool") != std::string::npos)
new_flags = rpc::object_storage::flag_bool_type;
else if (options.find("string") != std::string::npos)
new_flags = rpc::object_storage::flag_string_type;
else if (options.find("list") != std::string::npos)
new_flags = rpc::object_storage::flag_list_type;
else if (options.find("simple") != std::string::npos)
new_flags = rpc::object_storage::flag_function_type;
else
throw torrent::input_error("No support for 'list' variable type.");
if (options.find("static") != std::string::npos)
new_flags |= rpc::object_storage::flag_static;
if (options.find("private") != std::string::npos)
new_flags |= rpc::object_storage::flag_private;
if (options.find("const") != std::string::npos)
new_flags |= rpc::object_storage::flag_constant;
return system_method_insert_object(new_args, new_flags);
} else {
// THROW.
throw torrent::input_error("No object type specified.");
}
return torrent::Object();
return system_method_insert_object(new_args, new_flags);
}
// method.erase <> {name}
@@ -370,11 +356,11 @@ system_method_set_function(const torrent::Object::list_type& args) {
if (args.empty())
throw torrent::input_error("Invalid argument count.");
rpc::object_storage::local_iterator itr =
control->object_storage()->find_local(torrent::raw_string::from_string(args.front().as_string()));
rpc::object_storage::iterator itr =
control->object_storage()->find_raw_string(torrent::raw_string::from_string(args.front().as_string()));
if (itr == control->object_storage()->end(0) || itr->second.flags & rpc::object_storage::flag_constant)
throw torrent::input_error("Command is not modifiable.");
if (itr == control->object_storage()->end() || itr->second.flags & rpc::object_storage::flag_constant)
throw torrent::input_error("Command is not modifiable.");
return control->object_storage()->set_str_function(args.front().as_string(),
system_method_generate_command(++args.begin(), args.end()));
@@ -442,11 +428,14 @@ cmd_catch(rpc::target_type target, const torrent::Object& args) {
void
initialize_command_dynamic() {
CMD2_VAR_BOOL ("method.use_deprecated", false);
CMD2_VAR_BOOL ("method.use_deprecated", true);
CMD2_VAR_VALUE ("method.use_intermediate", 1);
CMD2_ANY_LIST ("method.insert", std::bind(&system_method_insert, std::placeholders::_2));
CMD2_ANY_LIST ("method.insert.value", std::bind(&system_method_insert_object, std::placeholders::_2, rpc::object_storage::flag_value_type));
CMD2_ANY_LIST ("method.insert.bool", std::bind(&system_method_insert_object, std::placeholders::_2, rpc::object_storage::flag_bool_type));
CMD2_ANY_LIST ("method.insert.string", std::bind(&system_method_insert_object, std::placeholders::_2, rpc::object_storage::flag_string_type));
CMD2_ANY_LIST ("method.insert.list", std::bind(&system_method_insert_object, std::placeholders::_2, rpc::object_storage::flag_list_type));
CMD2_METHOD_INSERT("method.insert.simple", rpc::object_storage::flag_function_type);
CMD2_METHOD_INSERT("method.insert.c_simple", rpc::object_storage::flag_constant | rpc::object_storage::flag_function_type);
+37
View File
@@ -307,6 +307,42 @@ d_multicall(const torrent::Object::list_type& args) {
return resultRaw;
}
torrent::Object
d_multicall_filtered(const torrent::Object::list_type& args) {
if (args.size() < 2)
throw torrent::input_error("d.multicall.filtered requires at least 2 arguments.");
torrent::Object::list_const_iterator arg = args.begin();
// Find the given view
core::ViewManager* viewManager = control->view_manager();
core::ViewManager::iterator viewItr = viewManager->find(arg->as_string().empty() ? "default" : arg->as_string());
if (viewItr == viewManager->end())
throw torrent::input_error("Could not find view '" + arg->as_string() + "'.");
// Make a filtered copy of the current item list
core::View::base_type dlist;
(*viewItr)->filter_by(*++arg, dlist);
// Generate result by iterating over all items
torrent::Object resultRaw = torrent::Object::create_list();
torrent::Object::list_type& result = resultRaw.as_list();
++arg; // skip to first command
for (core::View::iterator item = dlist.begin(); item != dlist.end(); ++item) {
// Add empty row to result
torrent::Object::list_type& row = result.insert(result.end(), torrent::Object::create_list())->as_list();
// Call the provided commands and assemble their results
for (torrent::Object::list_const_iterator command = arg; command != args.end(); command++) {
const std::string& cmdstr = command->as_string();
row.push_back(rpc::parse_command(rpc::make_target(*item), cmdstr.c_str(), cmdstr.c_str() + cmdstr.size()).first);
}
}
return resultRaw;
}
static void
call_watch_command(const std::string& command, const std::string& path) {
rpc::commands.call_catch(command.c_str(), rpc::make_target(), path);
@@ -359,6 +395,7 @@ initialize_command_events() {
CMD2_ANY_LIST ("download_list", std::bind(&apply_download_list, std::placeholders::_2));
CMD2_ANY_LIST ("d.multicall2", std::bind(&d_multicall, std::placeholders::_2));
CMD2_ANY_LIST ("d.multicall.filtered", std::bind(&d_multicall_filtered, std::placeholders::_2));
CMD2_ANY_LIST ("directory.watch.added", std::bind(&directory_watch_added, std::placeholders::_2));
}
+42 -36
View File
@@ -1,44 +1,9 @@
// rTorrent - BitTorrent client
// Copyright (C) 2005-2011, Jari Sundell
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// In addition, as a special exception, the copyright holders give
// permission to link the code of portions of this program with the
// OpenSSL library under certain conditions as described in each
// individual source file, and distribute linked combinations
// including the two.
//
// You must obey the GNU General Public License in all respects for
// all of the code used other than OpenSSL. If you modify file(s)
// with this exception, you may extend this exception to your version
// of the file(s), but you are not obligated to do so. If you do not
// wish to do so, delete this exception statement from your version.
// If you delete this exception statement from all source files in the
// program, then also delete it here.
//
// Contact: Jari Sundell <jaris@ifi.uio.no>
//
// Skomakerveien 33
// 3185 Skoppum, NORWAY
#include "config.h"
#include <torrent/download/resource_manager.h>
#include <torrent/download/choke_group.h>
#include <torrent/download/choke_queue.h>
#include <torrent/utils/log.h>
#include <torrent/utils/option_strings.h>
#include "ui/root.h"
@@ -52,6 +17,9 @@
// For cg_d_group.
#include "core/download.h"
#define LT_LOG_SUBSYSTEM(log_fmt, ...) \
lt_log_print_subsystem(torrent::LOG_TORRENT_INFO, "choke_queue", log_fmt, __VA_ARGS__);
// A hack to allow testing of the new choke_group API without the
// working parts present.
#define USE_CHOKE_GROUP 0
@@ -122,6 +90,22 @@ apply_cg_insert(const std::string& arg) {
return torrent::Object();
}
torrent::Object
apply_cg_all_update_balance(bool is_up) {
LT_LOG_SUBSYSTEM("apply update balance: resource_manager is_up:%i", (int)is_up);
for (torrent::ResourceManager::group_iterator
itr = torrent::resource_manager()->group_begin(),
last = torrent::resource_manager()->group_end(); itr != last; itr++) {
if (is_up)
itr->up_queue()->balance();
else
itr->down_queue()->balance();
}
return torrent::Object();
}
//
// The hacked version:
//
@@ -182,6 +166,11 @@ apply_cg_list() {
return torrent::Object::from_list(result);
}
int
cg_get_can_unchoke(torrent::choke_queue* cq) {
return cq->max_unchoked_signed() - (int)cq->size_unchoked();
}
torrent::Object
apply_cg_insert(const std::string& arg) {
int64_t dummy;
@@ -214,6 +203,20 @@ apply_cg_index_of(const std::string& arg) {
return std::distance(cg_list_hack.begin(), itr);
}
torrent::Object
apply_cg_all_update_balance(bool is_up) {
LT_LOG_SUBSYSTEM("apply update balance: hack is_up:%i", (int)is_up);
for (auto itr : cg_list_hack) {
if (is_up)
itr->up_queue()->balance();
else
itr->down_queue()->balance();
}
return torrent::Object();
}
//
// End of choke group hack.
//
@@ -356,6 +359,9 @@ initialize_command_groups() {
std::bind(&torrent::choke_group::tracker_mode, CG_GROUP_AT())));
CMD2_ANY_LIST ("choke_group.tracker.mode.set", std::bind(&apply_cg_tracker_mode_set, std::placeholders::_2));
CMD2_ANY ("choke_group.all.up.update_balance", std::bind(&apply_cg_all_update_balance, true));
CMD2_ANY ("choke_group.all.down.update_balance", std::bind(&apply_cg_all_update_balance, false));
CMD2_ANY ("choke_group.up.rate", std::bind(&torrent::choke_group::up_rate, CG_GROUP_AT()));
CMD2_ANY ("choke_group.down.rate", std::bind(&torrent::choke_group::down_rate, CG_GROUP_AT()));
+2 -2
View File
@@ -286,7 +286,7 @@ ipv4_filter_parse(const char* address, int value) {
inet_ntop(AF_INET, &net_start, start_str, INET_ADDRSTRLEN);
inet_ntop(AF_INET, &net_end, end_str, INET_ADDRSTRLEN);
lt_log_print(torrent::LOG_CONNECTION_DEBUG, "Adding ip filter for %s-%s.", start_str, end_str);
lt_log_print(torrent::LOG_CONNECTION_FILTER, "Adding ip filter for %s-%s.", start_str, end_str);
}
}
@@ -355,7 +355,7 @@ apply_ipv4_filter_load(const torrent::Object::list_type& args) {
throw torrent::input_error(buffer);
}
lt_log_print(torrent::LOG_CONNECTION_INFO, "Loaded %u %s address blocks (%u kb in-memory) from '%s'.",
lt_log_print(torrent::LOG_CONNECTION_FILTER, "loaded %u %s address blocks (%u kb in-memory) from '%s'",
lineNumber,
value_name.c_str(),
torrent::PeerList::ipv4_filter()->sizeof_data() / 1024,
+1 -1
View File
@@ -195,7 +195,7 @@ file_print_list(torrent::Object::list_const_iterator first, torrent::Object::lis
fprintf(output, (const char*)" %s" + !(flags & file_print_use_space), first->as_string().c_str());
break;
case torrent::Object::TYPE_VALUE:
fprintf(output, (const char*)" %lli" + !(flags & file_print_use_space), first->as_value());
fprintf(output, (const char*)" %" PRIi64 + !(flags & file_print_use_space), first->as_value());
break;
case torrent::Object::TYPE_LIST:
file_print_list(first->as_list().begin(), first->as_list().end(), output, 0);
+10 -39
View File
@@ -1,39 +1,3 @@
// rTorrent - BitTorrent client
// Copyright (C) 2005-2011, Jari Sundell
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// In addition, as a special exception, the copyright holders give
// permission to link the code of portions of this program with the
// OpenSSL library under certain conditions as described in each
// individual source file, and distribute linked combinations
// including the two.
//
// You must obey the GNU General Public License in all respects for
// all of the code used other than OpenSSL. If you modify file(s)
// with this exception, you may extend this exception to your version
// of the file(s), but you are not obligated to do so. If you do not
// wish to do so, delete this exception statement from your version.
// If you delete this exception statement from all source files in the
// program, then also delete it here.
//
// Contact: Jari Sundell <jaris@ifi.uio.no>
//
// Skomakerveien 33
// 3185 Skoppum, NORWAY
#include "config.h"
#include <fcntl.h>
@@ -56,6 +20,7 @@
static const int log_flag_use_gz = 0x1;
static const int log_flag_append_pid = 0x2;
static const int log_flag_append_file = 0x4;
void
log_add_group_output_str(const char* group_name, const char* output_id) {
@@ -80,10 +45,12 @@ apply_log_open(int output_flags, const torrent::Object::list_type& args) {
file_name += buffer;
}
bool append = (output_flags & log_flag_append_file);
if ((output_flags & log_flag_use_gz))
torrent::log_open_gz_file_output(output_id.c_str(), file_name.c_str());
torrent::log_open_gz_file_output(output_id.c_str(), file_name.c_str(), append);
else
torrent::log_open_file_output(output_id.c_str(), file_name.c_str());
torrent::log_open_file_output(output_id.c_str(), file_name.c_str(), append);
while (itr != args.end())
log_add_group_output_str((itr++)->as_string().c_str(), output_id.c_str());
@@ -166,8 +133,12 @@ initialize_command_logging() {
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.append_file", std::bind(&apply_log_open, log_flag_append_file, std::placeholders::_2));
CMD2_ANY_LIST ("log.append_gz_file", std::bind(&apply_log_open, log_flag_append_file, std::placeholders::_2));
CMD2_ANY_LIST ("log.add_output", std::bind(&apply_log_add_output, std::placeholders::_2));
CMD2_ANY_STRING_V("log.close", std::bind(&torrent::log_close_output_str, 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));
+27 -19
View File
@@ -167,8 +167,7 @@ apply_scgi(const std::string& arg, int type) {
sa.sa_inet()->clear();
saPtr = &sa;
lt_log_print(torrent::LOG_RPC_EVENTS,
"The SCGI socket has not been bound to any address and likely poses a security risk.");
lt_log_print(torrent::LOG_RPC_EVENTS, "SCGI socket is open to any address and is a security risk");
} else if (std::sscanf(arg.c_str(), "%1023[^:]:%i%c", address, &port, &dummy) == 2 ||
std::sscanf(arg.c_str(), "[%64[^]]]:%i%c", address, &port, &dummy) == 2) { // [xx::xx]:port format
@@ -177,8 +176,7 @@ apply_scgi(const std::string& arg, int type) {
saPtr = ai->address();
lt_log_print(torrent::LOG_RPC_EVENTS,
"The SCGI socket is bound to a specific network device yet may still pose a security risk, consider using 'scgi_local'.");
lt_log_print(torrent::LOG_RPC_EVENTS, "SCGI socket is bound to an address and might be a security risk");
} else {
throw torrent::input_error("Could not parse address.");
@@ -265,7 +263,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 ("network.http.dns_cache_timeout", std::bind(&core::CurlStack::dns_timeout, httpStack));
CMD2_ANY_VALUE_V ("network.http.dns_cache_timeout.set", std::bind(&core::CurlStack::set_dns_timeout, httpStack, std::placeholders::_2));
CMD2_ANY ("network.http.current_open", std::bind(&core::CurlStack::active, httpStack));
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_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));
@@ -281,24 +279,34 @@ initialize_command_network() {
CMD2_ANY_VALUE_V ("network.receive_buffer.size.set", std::bind(&torrent::ConnectionManager::set_receive_buffer_size, cm, std::placeholders::_2));
CMD2_ANY_STRING ("network.tos.set", std::bind(&apply_tos, std::placeholders::_2));
CMD2_ANY ("network.bind_address", std::bind(&core::Manager::bind_address, control->core()));
CMD2_ANY_STRING_V("network.bind_address.set", std::bind(&core::Manager::set_bind_address, control->core(), std::placeholders::_2));
CMD2_ANY ("network.local_address", std::bind(&core::Manager::local_address, control->core()));
CMD2_ANY_STRING_V("network.local_address.set", std::bind(&core::Manager::set_local_address, control->core(), std::placeholders::_2));
CMD2_ANY ("network.proxy_address", std::bind(&core::Manager::proxy_address, control->core()));
CMD2_ANY_STRING_V("network.proxy_address.set", std::bind(&core::Manager::set_proxy_address, control->core(), std::placeholders::_2));
CMD2_ANY ("network.bind_address", std::bind(&core::Manager::bind_address, control->core()));
CMD2_ANY_STRING_V("network.bind_address.set", std::bind(&core::Manager::set_bind_address, control->core(), std::placeholders::_2));
CMD2_ANY ("network.local_address", std::bind(&core::Manager::local_address, control->core()));
CMD2_ANY_STRING_V("network.local_address.set", std::bind(&core::Manager::set_local_address, control->core(), std::placeholders::_2));
CMD2_ANY ("network.proxy_address", std::bind(&core::Manager::proxy_address, control->core()));
CMD2_ANY_STRING_V("network.proxy_address.set", std::bind(&core::Manager::set_proxy_address, control->core(), std::placeholders::_2));
CMD2_ANY ("network.max_open_files", std::bind(&torrent::FileManager::max_open_files, fileManager));
CMD2_ANY_VALUE_V ("network.max_open_files.set", std::bind(&torrent::FileManager::set_max_open_files, fileManager, std::placeholders::_2));
CMD2_ANY ("network.open_sockets", std::bind(&torrent::ConnectionManager::size, cm));
CMD2_ANY ("network.max_open_sockets", std::bind(&torrent::ConnectionManager::max_size, cm));
CMD2_ANY_VALUE_V ("network.max_open_sockets.set", std::bind(&torrent::ConnectionManager::set_max_size, cm, std::placeholders::_2));
CMD2_ANY ("network.open_files", std::bind(&torrent::FileManager::open_files, fileManager));
CMD2_ANY ("network.max_open_files", std::bind(&torrent::FileManager::max_open_files, fileManager));
CMD2_ANY_VALUE_V ("network.max_open_files.set", std::bind(&torrent::FileManager::set_max_open_files, fileManager, std::placeholders::_2));
CMD2_ANY ("network.total_handshakes", std::bind(&torrent::total_handshakes));
CMD2_ANY ("network.open_sockets", std::bind(&torrent::ConnectionManager::size, cm));
CMD2_ANY ("network.max_open_sockets", std::bind(&torrent::ConnectionManager::max_size, cm));
CMD2_ANY_VALUE_V ("network.max_open_sockets.set", std::bind(&torrent::ConnectionManager::set_max_size, cm, std::placeholders::_2));
CMD2_ANY_STRING ("network.scgi.open_port", std::bind(&apply_scgi, std::placeholders::_2, 1));
CMD2_ANY_STRING ("network.scgi.open_local", std::bind(&apply_scgi, std::placeholders::_2, 2));
CMD2_VAR_BOOL ("network.scgi.dont_route", false);
CMD2_ANY_STRING ("network.scgi.open_port", std::bind(&apply_scgi, std::placeholders::_2, 1));
CMD2_ANY_STRING ("network.scgi.open_local", std::bind(&apply_scgi, std::placeholders::_2, 2));
CMD2_VAR_BOOL ("network.scgi.dont_route", false);
CMD2_ANY_STRING ("network.xmlrpc.dialect.set", std::bind(&apply_xmlrpc_dialect, std::placeholders::_2));
CMD2_ANY ("network.xmlrpc.size_limit", std::bind(&rpc::XmlRpc::size_limit));
CMD2_ANY_VALUE_V ("network.xmlrpc.size_limit.set", std::bind(&rpc::XmlRpc::set_size_limit, std::placeholders::_2));
CMD2_ANY ("network.block.ipv4", std::bind(&torrent::ConnectionManager::is_block_ipv4, cm));
CMD2_ANY_VALUE_V ("network.block.ipv4.set", std::bind(&torrent::ConnectionManager::set_block_ipv4, cm, std::placeholders::_2));
CMD2_ANY ("network.block.ipv6", std::bind(&torrent::ConnectionManager::is_block_ipv6, cm));
CMD2_ANY_VALUE_V ("network.block.ipv6.set", std::bind(&torrent::ConnectionManager::set_block_ipv6, cm, std::placeholders::_2));
CMD2_ANY ("network.prefer.ipv6", std::bind(&torrent::ConnectionManager::is_prefer_ipv6, cm));
CMD2_ANY_VALUE_V ("network.prefer.ipv6.set", std::bind(&torrent::ConnectionManager::set_prefer_ipv6, cm, std::placeholders::_2));
}
+4 -2
View File
@@ -176,8 +176,10 @@ throttle_update(const char* variable, int64_t value) {
void
initialize_command_throttle() {
CMD2_ANY ("throttle.unchoked_uploads", std::bind(&torrent::ResourceManager::currently_upload_unchoked, torrent::resource_manager()));
CMD2_ANY ("throttle.unchoked_downloads", std::bind(&torrent::ResourceManager::currently_download_unchoked, torrent::resource_manager()));
CMD2_ANY ("throttle.unchoked_uploads", std::bind(&torrent::ResourceManager::currently_upload_unchoked, torrent::resource_manager()));
CMD2_ANY ("throttle.max_unchoked_uploads", std::bind(&torrent::ResourceManager::max_upload_unchoked, torrent::resource_manager()));
CMD2_ANY ("throttle.unchoked_downloads", std::bind(&torrent::ResourceManager::currently_download_unchoked, torrent::resource_manager()));
CMD2_ANY ("throttle.max_unchoked_downloads", std::bind(&torrent::ResourceManager::max_download_unchoked, torrent::resource_manager()));
CMD2_VAR_VALUE ("throttle.min_peers.normal", 100);
CMD2_VAR_VALUE ("throttle.max_peers.normal", 200);
+1
View File
@@ -157,6 +157,7 @@ initialize_command_tracker() {
CMD2_ANY_VALUE ("trackers.enable", std::bind(&apply_enable_trackers, int64_t(1)));
CMD2_ANY_VALUE ("trackers.disable", std::bind(&apply_enable_trackers, int64_t(0)));
CMD2_VAR_BOOL ("trackers.delay_scrape", false);
CMD2_VAR_VALUE ("trackers.numwant", -1);
CMD2_VAR_BOOL ("trackers.use_udp", true);
+309 -2
View File
@@ -39,8 +39,12 @@
#include <sys/types.h>
#include <ctime>
#include <regex>
#include <rak/algorithm.h>
#include <rak/functional.h>
#include <rak/functional_fun.h>
#include <torrent/utils/log.h>
#include "core/manager.h"
#include "core/view_manager.h"
@@ -147,6 +151,41 @@ apply_cat(rpc::target_type target, const torrent::Object& rawArgs) {
return result;
}
torrent::Object
apply_value(rpc::target_type target, const torrent::Object::list_type& args) {
if (args.size() < 1)
throw torrent::input_error("'value' takes at least a number argument!");
if (args.size() > 2)
throw torrent::input_error("'value' takes at most two arguments!");
torrent::Object::value_type val = 0;
if (args.front().is_value()) {
val = args.front().as_value();
} else {
int base = args.size() > 1 ? args.back().is_value() ?
args.back().as_value() : strtol(args.back().as_string().c_str(), NULL, 10) : 10;
char* endptr = 0;
val = strtoll(args.front().as_string().c_str(), &endptr, base);
while (*endptr == ' ' || *endptr == '\n') ++endptr;
if (*endptr)
throw torrent::input_error("Junk at end of number: " + args.front().as_string());
}
return val;
}
torrent::Object
apply_try(rpc::target_type target, const torrent::Object& args) {
try {
return rpc::call_object(args, target);
} catch (torrent::input_error& e) {
lt_log_print(torrent::LOG_RPC_EVENTS, "try command caught input_error: %s", e.what());
}
return torrent::Object();
}
// Move these boolean operators to a new file.
inline bool
@@ -282,6 +321,103 @@ torrent::Object apply_equal(rpc::target_type target, const torrent::Object::list
return result.is_value() ? result.as_value() == 0 : (int64_t)false;
}
torrent::Object
apply_compare(rpc::target_type target, const torrent::Object::list_type& args) {
if (!rpc::is_target_pair(target))
throw torrent::input_error("Can only compare a target pair.");
if (args.size() < 2)
throw torrent::input_error("Need at least order and one field.");
torrent::Object::list_const_iterator itr = args.begin();
std::string order = (itr++)->as_string();
const char* current = order.c_str();
torrent::Object result1;
torrent::Object result2;
for (torrent::Object::list_const_iterator last = args.end(); itr != last; itr++) {
std::string field = itr->as_string();
result1 = rpc::parse_command_single(rpc::get_target_left(target), field);
result2 = rpc::parse_command_single(rpc::get_target_right(target), field);
if (result1.type() != result2.type())
throw torrent::input_error(std::string("Type mismatch in compare of ") + field);
bool descending = *current == 'd' || *current == 'D' || *current == '-';
if (*current) {
if (!descending && !(*current == 'a' || *current == 'A' || *current == '+'))
throw torrent::input_error(std::string("Bad order '") + *current + "' in " + order);
++current;
}
switch (result1.type()) {
case torrent::Object::TYPE_VALUE:
if (result1.as_value() != result2.as_value())
return (int64_t) (descending ^ (result1.as_value() < result2.as_value()));
break;
case torrent::Object::TYPE_STRING:
if (result1.as_string() != result2.as_string())
return (int64_t) (descending ^ (result1.as_string() < result2.as_string()));
break;
default:
break; // treat unknown types as equal
}
}
// if all else is equal, ensure stable sort order based on memory location
return (int64_t) (target.second < target.third);
}
// Regexp based 'match' function.
// arg1: the text to match.
// arg2: the regexp pattern.
// eg: match{d.name=,.*linux.*iso}
torrent::Object apply_match(rpc::target_type target, const torrent::Object::list_type& args) {
if (args.size() != 2)
throw torrent::input_error("Wrong argument count for 'match': 2 arguments needed.");
// This really should be converted to using args flagged as
// commands, so that we can compare commands and statics values.
torrent::Object result1;
torrent::Object result2;
rpc::target_type target1 = rpc::is_target_pair(target) ? rpc::get_target_left(target) : target;
rpc::target_type target2 = rpc::is_target_pair(target) ? rpc::get_target_right(target) : target;
if (args.front().is_dict_key())
result1 = rpc::commands.call_command(args.front().as_dict_key().c_str(), args.front().as_dict_obj(), target1);
else
result1 = rpc::parse_command_single(target1, args.front().as_string());
if (args.back().is_dict_key())
result2 = rpc::commands.call_command(args.back().as_dict_key().c_str(), args.back().as_dict_obj(), target2);
else
result2 = args.back().as_string();
if (result1.type() != result2.type())
throw torrent::input_error("Type mismatch for 'match' arguments.");
std::string text = result1.as_string();
std::string pattern = result2.as_string();
std::transform(text.begin(), text.end(), text.begin(), ::tolower);
std::transform(pattern.begin(), pattern.end(), pattern.begin(), ::tolower);
bool isAMatch = false;
try {
std::regex re(pattern);
isAMatch = std::regex_match(text, re);
} catch (const std::regex_error& exc) {
control->core()->push_log_std("regex_error: " + std::string(exc.what()));
}
return isAMatch ? (int64_t)true : (int64_t)false;
}
torrent::Object
apply_to_time(const torrent::Object& rawArgs, int flags) {
std::tm *u;
@@ -519,6 +655,148 @@ apply_elapsed_greater(const torrent::Object::list_type& args) {
return (int64_t)(start_time != 0 && rak::timer::current_seconds() - start_time > rpc::convert_to_value(args.back()));
}
inline std::vector<int64_t>
as_vector(const torrent::Object::list_type& args) {
if (args.size() == 0)
throw torrent::input_error("Wrong argument count in as_vector.");
std::vector<int64_t> result;
for (torrent::Object::list_const_iterator itr = args.begin(), last = args.end(); itr != last; itr++) {
if (itr->is_value()) {
result.push_back(itr->as_value());
} else if (itr->is_string()) {
result.push_back(rpc::convert_to_value(itr->as_string()));
} else if (itr->is_list()) {
std::vector<int64_t> subResult = as_vector(itr->as_list());
result.insert(result.end(), subResult.begin(), subResult.end());
} else {
throw torrent::input_error("Wrong type supplied to as_vector.");
}
}
return result;
}
int64_t
apply_math_basic(const char* name, const std::function<int64_t(int64_t,int64_t)> op, const torrent::Object::list_type& args) {
int64_t val = 0, rhs = 0;
bool divides = !strcmp(name, "math.div") || !strcmp(name, "math.mod");
if (args.size() == 0)
throw torrent::input_error(std::string(name) + ": No arguments provided!");
for (torrent::Object::list_const_iterator itr = args.begin(), last = args.end(); itr != last; itr++) {
if (itr->is_value()) {
rhs = itr->as_value();
} else if (itr->is_string()) {
rhs = rpc::convert_to_value(itr->as_string());
} else if (itr->is_list()) {
rhs = apply_math_basic(name, op, itr->as_list());
} else {
throw torrent::input_error(std::string(name) + ": Wrong argument type");
}
if (divides && !rhs && itr != args.begin())
throw torrent::input_error(std::string(name) + ": Division by zero!");
val = itr == args.begin() ? rhs : op(val, rhs);
}
return val;
}
int64_t
apply_arith_basic(const std::function<int64_t(int64_t,int64_t)> op, const torrent::Object::list_type& args) {
if (args.size() == 0)
throw torrent::input_error("Wrong argument count in apply_arith_basic.");
int64_t val = 0;
for (torrent::Object::list_const_iterator itr = args.begin(), last = args.end(); itr != last; itr++) {
if (itr->is_value()) {
val = itr == args.begin() ? itr->as_value() : (op(val, itr->as_value()) ? val : itr->as_value());
} else if (itr->is_string()) {
int64_t cval = rpc::convert_to_value(itr->as_string());
val = itr == args.begin() ? cval : (op(val, cval) ? val : cval);
} else if (itr->is_list()) {
int64_t fval = apply_arith_basic(op, itr->as_list());
val = itr == args.begin() ? fval : (op(val, fval) ? val : fval);
} else {
throw torrent::input_error("Wrong type supplied to apply_arith_basic.");
}
}
return val;
}
int64_t
apply_arith_count(const torrent::Object::list_type& args) {
if (args.size() == 0)
throw torrent::input_error("Wrong argument count in apply_arith_count.");
int64_t val = 0;
for (torrent::Object::list_const_iterator itr = args.begin(), last = args.end(); itr != last; itr++) {
switch (itr->type()) {
case torrent::Object::TYPE_VALUE:
case torrent::Object::TYPE_STRING:
val++;
break;
case torrent::Object::TYPE_LIST:
val += apply_arith_count(itr->as_list());
break;
default:
throw torrent::input_error("Wrong type supplied to apply_arith_count.");
}
}
return val;
}
int64_t
apply_arith_other(const char* op, const torrent::Object::list_type& args) {
if (args.size() == 0)
throw torrent::input_error("Wrong argument count in apply_arith_other.");
if (strcmp(op, "average") == 0) {
return (int64_t)(apply_math_basic(op, std::plus<int64_t>(), args) / apply_arith_count(args));
} else if (strcmp(op, "median") == 0) {
std::vector<int64_t> result = as_vector(args);
return (int64_t)rak::median(result.begin(), result.end());
} else {
throw torrent::input_error("Wrong operation supplied to apply_arith_other.");
}
}
torrent::Object
cmd_status_throttle_names(bool up, const torrent::Object::list_type& args) {
if (args.size() == 0)
return torrent::Object();
std::vector<std::string> throttle_name_list;
for (torrent::Object::list_const_iterator itr = args.begin(), last = args.end(); itr != last; itr++) {
if (itr->is_string())
throttle_name_list.push_back(itr->as_string());
}
if (up)
control->ui()->set_status_throttle_up_names(throttle_name_list);
else
control->ui()->set_status_throttle_down_names(throttle_name_list);
return torrent::Object();
}
void
initialize_command_ui() {
CMD2_VAR_STRING("keys.layout", "qwerty");
@@ -528,8 +806,11 @@ initialize_command_ui() {
CMD2_ANY_L ("view.list", std::bind(&apply_view_list));
CMD2_ANY_LIST("view.set", std::bind(&apply_view_set, std::placeholders::_2));
CMD2_ANY_LIST("view.filter", std::bind(&apply_view_event, &core::ViewManager::set_filter, std::placeholders::_2));
CMD2_ANY_LIST("view.filter_on", std::bind(&apply_view_filter_on, std::placeholders::_2));
CMD2_ANY_LIST ("view.filter", std::bind(&apply_view_event, &core::ViewManager::set_filter, std::placeholders::_2));
CMD2_ANY_LIST ("view.filter_on", std::bind(&apply_view_filter_on, std::placeholders::_2));
CMD2_ANY_LIST ("view.filter.temp", std::bind(&apply_view_event, &core::ViewManager::set_filter_temp, std::placeholders::_2));
CMD2_VAR_STRING("view.filter.temp.excluded", "default,started,stopped");
CMD2_VAR_BOOL ("view.filter.temp.log", 0);
CMD2_ANY_LIST("view.sort", std::bind(&apply_view_sort, std::placeholders::_2));
CMD2_ANY_LIST("view.sort_new", std::bind(&apply_view_event, &core::ViewManager::set_sort_new, std::placeholders::_2));
@@ -555,12 +836,25 @@ initialize_command_ui() {
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 ("ui.input.history.size", std::bind(&ui::Root::get_input_history_size, control->ui()));
CMD2_ANY_VALUE_V("ui.input.history.size.set", std::bind(&ui::Root::set_input_history_size, control->ui(), std::placeholders::_2));
CMD2_ANY_V ("ui.input.history.clear", std::bind(&ui::Root::clear_input_history, control->ui()));
CMD2_VAR_VALUE ("ui.throttle.global.step.small", 5);
CMD2_VAR_VALUE ("ui.throttle.global.step.medium", 50);
CMD2_VAR_VALUE ("ui.throttle.global.step.large", 500);
CMD2_ANY_LIST ("ui.status.throttle.up.set", std::bind(&cmd_status_throttle_names, true, std::placeholders::_2));
CMD2_ANY_LIST ("ui.status.throttle.down.set", std::bind(&cmd_status_throttle_names, false, std::placeholders::_2));
// TODO: Add 'option_string' for rtorrent-specific options.
CMD2_VAR_STRING("ui.torrent_list.layout", "full");
// Move.
CMD2_ANY("print", &apply_print);
CMD2_ANY("cat", &apply_cat);
CMD2_ANY_LIST("value", &apply_value);
CMD2_ANY("try", &apply_try);
CMD2_ANY("if", std::bind(&apply_if, std::placeholders::_1, std::placeholders::_2, 0));
CMD2_ANY("not", &apply_not);
CMD2_ANY("false", &apply_false);
@@ -574,6 +868,8 @@ initialize_command_ui() {
CMD2_ANY_LIST("less", &apply_less);
CMD2_ANY_LIST("greater", &apply_greater);
CMD2_ANY_LIST("equal", &apply_equal);
CMD2_ANY_LIST("compare", &apply_compare);
CMD2_ANY_LIST("match", &apply_match);
CMD2_ANY_VALUE("convert.gm_time", std::bind(&apply_to_time, std::placeholders::_2, 0));
CMD2_ANY_VALUE("convert.gm_date", std::bind(&apply_to_time, std::placeholders::_2, 0x2));
@@ -585,6 +881,17 @@ initialize_command_ui() {
CMD2_ANY_VALUE("convert.xb", std::bind(&apply_to_xb, std::placeholders::_2));
CMD2_ANY_VALUE("convert.throttle", std::bind(&apply_to_throttle, std::placeholders::_2));
CMD2_ANY_LIST("math.add", std::bind(&apply_math_basic, "math.add", std::plus<int64_t>(), std::placeholders::_2));
CMD2_ANY_LIST("math.sub", std::bind(&apply_math_basic, "math.sub", std::minus<int64_t>(), std::placeholders::_2));
CMD2_ANY_LIST("math.mul", std::bind(&apply_math_basic, "math.mul", std::multiplies<int64_t>(), std::placeholders::_2));
CMD2_ANY_LIST("math.div", std::bind(&apply_math_basic, "math.div", std::divides<int64_t>(), std::placeholders::_2));
CMD2_ANY_LIST("math.mod", std::bind(&apply_math_basic, "math.mod", std::modulus<int64_t>(), std::placeholders::_2));
CMD2_ANY_LIST("math.min", std::bind(&apply_arith_basic, std::less<int64_t>(), std::placeholders::_2));
CMD2_ANY_LIST("math.max", std::bind(&apply_arith_basic, std::greater<int64_t>(), std::placeholders::_2));
CMD2_ANY_LIST("math.cnt", std::bind(&apply_arith_count, std::placeholders::_2));
CMD2_ANY_LIST("math.avg", std::bind(&apply_arith_other, "average", std::placeholders::_2));
CMD2_ANY_LIST("math.med", std::bind(&apply_arith_other, "median", std::placeholders::_2));
CMD2_ANY_LIST ("elapsed.less", std::bind(&apply_elapsed_less, std::placeholders::_2));
CMD2_ANY_LIST ("elapsed.greater", std::bind(&apply_elapsed_greater, std::placeholders::_2));
}
+2
View File
@@ -168,6 +168,8 @@ Control::is_shutdown_completed() {
void
Control::handle_shutdown() {
rpc::commands.call_catch("event.system.shutdown", rpc::make_target(), "shutdown", "System shutdown event action failed: ");
if (!m_shutdownQuick) {
// Temporary hack:
if (worker_thread->is_active())
+1 -1
View File
@@ -37,7 +37,7 @@
#ifndef RTORRENT_CONTROL_H
#define RTORRENT_CONTROL_H
#include <inttypes.h>
#include <cinttypes>
#include <sys/types.h>
#include <rak/timer.h>
#include <rak/priority_queue_default.h>
-33
View File
@@ -1,33 +0,0 @@
noinst_LIBRARIES = libsub_core.a
libsub_core_a_SOURCES = \
curl_get.cc \
curl_get.h \
curl_socket.cc \
curl_socket.h \
curl_stack.cc \
curl_stack.h \
dht_manager.cc \
dht_manager.h \
download.cc \
download.h \
download_factory.cc \
download_factory.h \
download_list.cc \
download_list.h \
download_slot_map.h \
download_store.cc \
download_store.h \
http_queue.cc \
http_queue.h \
manager.cc \
manager.h \
poll_manager.cc \
poll_manager.h \
range_map.h \
view.cc \
view.h \
view_manager.cc \
view_manager.h
AM_CPPFLAGS = -I$(srcdir) -I$(srcdir)/.. -I$(top_srcdir)
+8 -2
View File
@@ -38,10 +38,11 @@
#include <cstdlib>
#include <fstream>
#include <functional>
#include <sstream>
#include <stdexcept>
#include <rak/path.h>
#include lt_tr1_functional
#include <torrent/utils/log.h>
#include <torrent/utils/resume.h>
#include <torrent/object.h>
@@ -105,7 +106,8 @@ DownloadFactory::DownloadFactory(Manager* m) :
m_session(false),
m_start(false),
m_printLog(true),
m_isFile(false) {
m_isFile(false),
m_initLoad(false) {
m_taskLoad.slot() = std::bind(&DownloadFactory::receive_load, this);
m_taskCommit.slot() = std::bind(&DownloadFactory::receive_commit, this);
@@ -275,6 +277,10 @@ DownloadFactory::receive_success() {
if (!rpc::call_command_value("trackers.use_udp"))
download->enable_udp_trackers(false);
// Skip forcing trackers to scrape when rtorrent starts
if (m_initLoad && rpc::call_command_value("trackers.delay_scrape"))
download->set_resume_flags(torrent::Download::start_skip_tracker);
// Check first if we already have these values set in the session
// torrent, so that it is safe to change the values.
//
+6 -1
View File
@@ -41,10 +41,11 @@
#ifndef RTORRENT_CORE_DOWNLOAD_FACTORY_H
#define RTORRENT_CORE_DOWNLOAD_FACTORY_H
#include <functional>
#include <iosfwd>
#include <rak/priority_queue_default.h>
#include <torrent/object.h>
#include lt_tr1_functional
#include "http_queue.h"
@@ -77,6 +78,9 @@ public:
bool get_start() const { return m_start; }
void set_start(bool v) { m_start = v; }
bool get_init_load() const { return m_initLoad; }
void set_init_load(bool v) { m_initLoad = v; }
bool print_log() const { return m_printLog; }
void set_print_log(bool v) { m_printLog = v; }
@@ -105,6 +109,7 @@ private:
bool m_start;
bool m_printLog;
bool m_isFile;
bool m_initLoad;
command_list_type m_commands;
torrent::Object::map_type m_variables;
+2
View File
@@ -63,6 +63,7 @@
#include "download.h"
#include "download_list.h"
#include "download_store.h"
#include "ui/root.h"
#define DL_TRIGGER_EVENT(download, event_name) \
rpc::commands.call_catch(event_name, rpc::make_target(download), torrent::Object(), "Event '" event_name "' failed: ");
@@ -93,6 +94,7 @@ DownloadList::session_save() {
lt_log_print(torrent::LOG_ERROR, "Failed to save session torrents.");
control->dht_manager()->save_dht_cache();
control->ui()->save_input_history();
}
DownloadList::iterator
+1 -1
View File
@@ -37,9 +37,9 @@
#ifndef RTORRENT_CORE_DOWNLOAD_SLOT_MAP_H
#define RTORRENT_CORE_DOWNLOAD_SLOT_MAP_H
#include <functional>
#include <map>
#include <string>
#include lt_tr1_functional
#include "download.h"
+12 -1
View File
@@ -40,6 +40,7 @@
#include <fstream>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <rak/error_number.h>
#include <rak/path.h>
@@ -100,6 +101,7 @@ DownloadStore::set_path(const std::string& path) {
bool
DownloadStore::write_bencode(const std::string& filename, const torrent::Object& obj, uint32_t skip_mask) {
int fd;
torrent::Object tmp;
std::fstream output(filename.c_str(), std::ios::out | std::ios::trunc);
@@ -121,6 +123,15 @@ DownloadStore::write_bencode(const std::string& filename, const torrent::Object&
goto download_store_save_error;
output.close();
// Ensure that the new file is actually written to the disk
fd = ::open(filename.c_str(), O_WRONLY);
if (fd < 0)
goto download_store_save_error;
fdatasync(fd);
::close(fd);
return true;
download_store_save_error:
@@ -183,7 +194,7 @@ DownloadStore::remove(Download* d) {
// This also needs to check that it isn't a directory.
bool
not_correct_format(const utils::directory_entry& entry) {
return !DownloadStore::is_correct_format(entry.d_name);
return !DownloadStore::is_correct_format(entry.s_name);
}
utils::Directory
+2 -2
View File
@@ -37,9 +37,9 @@
#ifndef RTORRENT_CORE_HTTP_QUEUE_H
#define RTORRENT_CORE_HTTP_QUEUE_H
#include <list>
#include <functional>
#include <iosfwd>
#include lt_tr1_functional
#include <list>
namespace core {
+31 -2
View File
@@ -146,6 +146,35 @@ Manager::get_address_throttle(const sockaddr* addr) {
return m_addressThrottles.get(rak::socket_address::cast_from(addr)->sa_inet()->address_h(), torrent::ThrottlePair(NULL, NULL));
}
int64_t
Manager::retrieve_throttle_value(const torrent::Object::string_type& name, bool rate, bool up) {
ThrottleMap::iterator itr = throttles().find(name);
if (itr == throttles().end()) {
return (int64_t)-1;
} else {
torrent::Throttle* throttle = up ? itr->second.first : itr->second.second;
// check whether the actual up/down throttle exist (one of the pair can be missing)
if (throttle == NULL)
return (int64_t)-1;
int64_t throttle_max = (int64_t)throttle->max_rate();
if (rate) {
if (throttle_max > 0)
return (int64_t)throttle->rate()->rate();
else
return (int64_t)-1;
} else {
return throttle_max;
}
}
}
// Most of this should be possible to move out.
void
Manager::initialize_second() {
@@ -374,7 +403,7 @@ Manager::try_create_download_from_meta_download(torrent::Object* bencode, const
utils::Directory
path_expand_transform(std::string path, const utils::directory_entry& entry) {
return path + entry.d_name;
return path + entry.s_name;
}
// Move this somewhere better.
@@ -414,7 +443,7 @@ path_expand(std::vector<std::string>* paths, const std::string& pattern) {
// Only include filenames starting with '.' if the pattern
// starts with the same.
itr->update((r.pattern()[0] != '.') ? utils::Directory::update_hide_dot : 0);
itr->erase(std::remove_if(itr->begin(), itr->end(), rak::on(rak::mem_ref(&utils::directory_entry::d_name), std::not1(r))), itr->end());
itr->erase(std::remove_if(itr->begin(), itr->end(), rak::on(rak::mem_ref(&utils::directory_entry::s_name), std::not1(r))), itr->end());
std::transform(itr->begin(), itr->end(), std::back_inserter(nextCache), rak::bind1st(std::ptr_fun(&path_expand_transform), itr->path() + (itr->path() == "/" ? "" : "/")));
}
+8 -40
View File
@@ -1,47 +1,13 @@
// rTorrent - BitTorrent client
// Copyright (C) 2005-2011, Jari Sundell
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// In addition, as a special exception, the copyright holders give
// permission to link the code of portions of this program with the
// OpenSSL library under certain conditions as described in each
// individual source file, and distribute linked combinations
// including the two.
//
// You must obey the GNU General Public License in all respects for
// all of the code used other than OpenSSL. If you modify file(s)
// with this exception, you may extend this exception to your version
// of the file(s), but you are not obligated to do so. If you do not
// wish to do so, delete this exception statement from your version.
// If you delete this exception statement from all source files in the
// program, then also delete it here.
//
// Contact: Jari Sundell <jaris@ifi.uio.no>
//
// Skomakerveien 33
// 3185 Skoppum, NORWAY
#ifndef RTORRENT_CORE_MANAGER_H
#define RTORRENT_CORE_MANAGER_H
#include <iosfwd>
#include <memory>
#include <vector>
#include <torrent/utils/log_buffer.h>
#include <torrent/connection_manager.h>
#include <torrent/object.h>
#include "download_list.h"
#include "poll_manager.h"
@@ -85,12 +51,14 @@ public:
View* hashing_view() { return m_hashingView; }
void set_hashing_view(View* v);
torrent::log_buffer* log_important() { return m_log_important; }
torrent::log_buffer* log_complete() { return m_log_complete; }
torrent::log_buffer* log_important() { return m_log_important.get(); }
torrent::log_buffer* log_complete() { return m_log_complete.get(); }
ThrottleMap& throttles() { return m_throttles; }
torrent::ThrottlePair get_throttle(const std::string& name);
int64_t retrieve_throttle_value(const torrent::Object::string_type& name, bool rate, bool up);
// Use custom throttle for the given range of IP addresses.
void set_address_throttle(uint32_t begin, uint32_t end, torrent::ThrottlePair throttles);
torrent::ThrottlePair get_address_throttle(const sockaddr* addr);
@@ -152,8 +120,8 @@ private:
ThrottleMap m_throttles;
AddressThrottleMap m_addressThrottles;
torrent::log_buffer* m_log_important;
torrent::log_buffer* m_log_complete;
torrent::log_buffer_ptr m_log_important;
torrent::log_buffer_ptr m_log_complete;
};
// Meh, cleanup.
+24 -10
View File
@@ -89,17 +89,21 @@ struct view_downloads_compare : std::binary_function<Download*, Download*, bool>
};
struct view_downloads_filter : std::unary_function<Download*, bool> {
view_downloads_filter(const torrent::Object& cmd) : m_command(cmd) {}
view_downloads_filter(const torrent::Object& cmd, const torrent::Object& cmd2) : m_command(cmd), m_command2(cmd2) {}
bool operator () (Download* d1) const {
if (m_command.is_empty())
return this->evalCmd(m_command, d1) && this->evalCmd(m_command2, d1);
}
bool evalCmd(const torrent::Object& cmd, Download* d1) const {
if (cmd.is_empty())
return true;
try {
torrent::Object result;
if (m_command.is_dict_key()) {
// torrent::Object tmp_command = m_command;
if (cmd.is_dict_key()) {
// torrent::Object tmp_command = cmd;
// uint32_t flags = tmp_command.flags() & torrent::Object::mask_function;
// tmp_command.unset_flags(torrent::Object::mask_function);
@@ -109,10 +113,10 @@ struct view_downloads_filter : std::unary_function<Download*, bool> {
// result = rpc::commands.call_command(tmp_command.as_dict_key().c_str(), tmp_command.as_dict_obj(),
// rpc::make_target(d1));
result = rpc::commands.call_command(m_command.as_dict_key().c_str(), m_command.as_dict_obj(), rpc::make_target(d1));
result = rpc::commands.call_command(cmd.as_dict_key().c_str(), cmd.as_dict_obj(), rpc::make_target(d1));
} else {
result = rpc::parse_command_single(rpc::make_target(d1), m_command.as_string());
result = rpc::parse_command_single(rpc::make_target(d1), cmd.as_string());
}
switch (result.type()) {
@@ -136,6 +140,7 @@ struct view_downloads_filter : std::unary_function<Download*, bool> {
}
const torrent::Object& m_command;
const torrent::Object& m_command2;
};
void
@@ -262,8 +267,8 @@ View::filter() {
return;
// 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 splitFiltered = std::stable_partition(begin_filtered(), end_filtered(), view_downloads_filter(m_filter));
iterator splitVisible = std::stable_partition(begin_visible(), end_visible(), view_downloads_filter(m_filter, m_temp_filter));
iterator splitFiltered = std::stable_partition(begin_filtered(), end_filtered(), view_downloads_filter(m_filter, m_temp_filter));
base_type changed(splitVisible, splitFiltered);
iterator splitChanged = changed.begin() + std::distance(splitVisible, end_visible());
@@ -295,6 +300,16 @@ View::filter() {
emit_changed();
}
void
View::filter_by(const torrent::Object& condition, View::base_type& result) {
// std::copy_if(begin_visible(), end_visible(), result.begin(), view_downloads_filter(condition));
view_downloads_filter matches = view_downloads_filter(condition, m_temp_filter);
for (iterator itr = begin_visible(); itr != end_visible(); ++itr)
if (matches(*itr))
result.push_back(*itr);
}
void
View::filter_download(core::Download* download) {
iterator itr = std::find(base_type::begin(), base_type::end(), download);
@@ -302,8 +317,7 @@ View::filter_download(core::Download* download) {
if (itr == base_type::end())
throw torrent::internal_error("View::filter_download(...) could not find download.");
if (view_downloads_filter(m_filter)(download)) {
if (view_downloads_filter(m_filter, m_temp_filter)(download)) {
if (itr >= end_visible()) {
erase_internal(itr);
insert_visible(download);
+7 -2
View File
@@ -49,11 +49,12 @@
#ifndef RTORRENT_CORE_VIEW_DOWNLOADS_H
#define RTORRENT_CORE_VIEW_DOWNLOADS_H
#include <functional>
#include <string>
#include <vector>
#include <rak/timer.h>
#include <torrent/object.h>
#include lt_tr1_functional
#include "globals.h"
@@ -120,10 +121,13 @@ public:
// Need to explicity trigger filtering.
void filter();
void filter_by(const torrent::Object& condition, base_type& result);
void filter_download(core::Download* download);
const torrent::Object& get_filter() const { return m_filter; }
void set_filter(const torrent::Object& s) { m_filter = s; }
void set_filter(const torrent::Object& s) { m_filter = s; }
const torrent::Object& get_filter_temp() const { return m_temp_filter; }
void set_filter_temp(const torrent::Object& s) { m_temp_filter = s; }
void set_filter_on_event(const std::string& event);
void clear_filter_on();
@@ -172,6 +176,7 @@ private:
torrent::Object m_sortCurrent;
torrent::Object m_filter;
torrent::Object m_temp_filter; // Temporary view filter (eg: name based filter)
torrent::Object m_event_added;
torrent::Object m_event_removed;
+8
View File
@@ -109,6 +109,14 @@ ViewManager::set_filter(const std::string& name, const torrent::Object& cmd) {
(*viewItr)->filter();
}
void
ViewManager::set_filter_temp(const std::string& name, const torrent::Object& cmd) {
iterator viewItr = find_throw(name);
(*viewItr)->set_filter_temp(cmd);
(*viewItr)->filter();
}
void
ViewManager::set_filter_on(const std::string& name, const filter_args& args) {
iterator viewItr = find_throw(name);
+1
View File
@@ -93,6 +93,7 @@ public:
void set_sort_current(const std::string& name, const torrent::Object& cmd) { (*find_throw(name))->set_sort_current(cmd); }
void set_filter(const std::string& name, const torrent::Object& cmd);
void set_filter_temp(const std::string& name, const torrent::Object& cmd);
void set_filter_on(const std::string& name, const filter_args& args);
void set_event_added(const std::string& name, const torrent::Object& cmd) { (*find_throw(name))->set_event_added(cmd); }
-53
View File
@@ -1,53 +0,0 @@
noinst_LIBRARIES = libsub_display.a
libsub_display_a_SOURCES = \
attributes.h \
canvas.cc \
canvas.h \
frame.cc \
frame.h \
manager.cc \
manager.h \
utils.cc \
utils.h \
text_element.h \
text_element_list.cc \
text_element_list.h \
text_element_string.cc \
text_element_string.h \
text_element_value.cc \
text_element_value.h \
window.cc \
window.h \
window_download_chunks_seen.cc \
window_download_chunks_seen.h \
window_download_list.cc \
window_download_list.h \
window_download_statusbar.cc \
window_download_statusbar.h \
window_download_transfer_list.cc \
window_download_transfer_list.h \
window_file_list.cc \
window_file_list.h \
window_http_queue.cc \
window_http_queue.h \
window_input.cc \
window_input.h \
window_log.cc \
window_log.h \
window_log_complete.cc \
window_log_complete.h \
window_peer_list.cc \
window_peer_list.h \
window_statusbar.cc \
window_statusbar.h \
window_string_list.cc \
window_string_list.h \
window_text.cc \
window_text.h \
window_title.cc \
window_title.h \
window_tracker_list.cc \
window_tracker_list.h
AM_CPPFLAGS = -I$(srcdir) -I$(srcdir)/.. -I$(top_srcdir)
-36
View File
@@ -1,39 +1,3 @@
// rTorrent - BitTorrent client
// Copyright (C) 2005-2011, Jari Sundell
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// In addition, as a special exception, the copyright holders give
// permission to link the code of portions of this program with the
// OpenSSL library under certain conditions as described in each
// individual source file, and distribute linked combinations
// including the two.
//
// You must obey the GNU General Public License in all respects for
// all of the code used other than OpenSSL. If you modify file(s)
// with this exception, you may extend this exception to your version
// of the file(s), but you are not obligated to do so. If you do not
// wish to do so, delete this exception statement from your version.
// If you delete this exception statement from all source files in the
// program, then also delete it here.
//
// Contact: Jari Sundell <jaris@ifi.uio.no>
//
// Skomakerveien 33
// 3185 Skoppum, NORWAY
#ifndef RTORRENT_DISPLAY_ATTRIBUTES_H
#define RTORRENT_DISPLAY_ATTRIBUTES_H
+1 -1
View File
@@ -38,7 +38,7 @@
#include <algorithm>
#include <functional>
#include lt_tr1_functional
#include <rak/algorithm.h>
#include <torrent/exceptions.h>
+1 -1
View File
@@ -37,7 +37,7 @@
#ifndef RTORRENT_DISPLAY_FRAME_H
#define RTORRENT_DISPLAY_FRAME_H
#include <inttypes.h>
#include <cinttypes>
namespace display {
+1 -1
View File
@@ -37,8 +37,8 @@
#ifndef RTORRENT_DISPLAY_TEXT_ELEMENT_H
#define RTORRENT_DISPLAY_TEXT_ELEMENT_H
#include <cinttypes>
#include <vector>
#include <inttypes.h>
#include "display/canvas.h"
#include "rpc/command_map.h"
-1
View File
@@ -38,7 +38,6 @@
#define RTORRENT_DISPLAY_TEXT_ELEMENT_VALUE_H
#include <cstring>
#include <inttypes.h>
#include "text_element.h"
+91 -10
View File
@@ -57,6 +57,7 @@
#include "core/download.h"
#include "core/manager.h"
#include "rpc/parse_commands.h"
#include "ui/root.h"
#include "control.h"
#include "globals.h"
@@ -319,21 +320,101 @@ print_client_version(char* first, char* last, const torrent::ClientInfo& clientI
}
}
char*
print_status_throttle_limit(char* first, char* last, bool up, const ui::ThrottleNameList& throttle_names) {
char throttle_str[40];
throttle_str[0] = 0;
char* firstc = throttle_str;
char* lastc = throttle_str + 40 - 1;
for (ui::ThrottleNameList::const_iterator itr = throttle_names.begin(), laste = throttle_names.end(); itr != laste; itr++) {
if (!(*itr).empty()) {
int64_t throttle_max = control->core()->retrieve_throttle_value(*itr, false, up);
if (throttle_max > 0)
firstc = print_buffer(firstc, lastc, "|%1.0f", (double)throttle_max / 1024.0);
}
}
// Add temp buffer (chop first char first) into main buffer if temp buffer isn't empty
if (throttle_str[0] != 0)
first = print_buffer(first, last, "(%s)", &throttle_str[1]);
return first;
}
char*
print_status_throttle_rate(char* first, char* last, bool up, const ui::ThrottleNameList& throttle_names, const double& global_rate) {
double main_rate = global_rate;
char throttle_str[50];
throttle_str[0] = 0;
char* firstc = throttle_str;
char* lastc = throttle_str + 50 - 1;
for (ui::ThrottleNameList::const_iterator itr = throttle_names.begin(), laste = throttle_names.end(); itr != laste; itr++) {
if (!(*itr).empty() && (up ? torrent::up_throttle_global()->is_throttled() : torrent::down_throttle_global()->is_throttled())) {
int64_t throttle_rate_value = control->core()->retrieve_throttle_value(*itr, true, up);
if (throttle_rate_value > -1) {
double throttle_rate = (double)throttle_rate_value / 1024.0;
main_rate = main_rate - throttle_rate;
firstc = print_buffer(firstc, lastc, "|%3.1f", throttle_rate);
}
}
}
// Add temp buffer into main buffer if temp buffer isn't empty
if (throttle_str[0] != 0)
first = print_buffer(first, last, "(%3.1f%s)",
main_rate < 0.0 ? 0.0 : main_rate,
throttle_str);
return first;
}
char*
print_status_info(char* first, char* last) {
if (!torrent::up_throttle_global()->is_throttled())
ui::ThrottleNameList& throttle_up_names = control->ui()->get_status_throttle_up_names();
ui::ThrottleNameList& throttle_down_names = control->ui()->get_status_throttle_down_names();
if (!torrent::up_throttle_global()->is_throttled()) {
first = print_buffer(first, last, "[Throttle off");
else
} else {
first = print_buffer(first, last, "[Throttle %3i", torrent::up_throttle_global()->max_rate() / 1024);
if (!torrent::down_throttle_global()->is_throttled())
first = print_buffer(first, last, "/off KB]");
else
first = print_buffer(first, last, "/%3i KB]", torrent::down_throttle_global()->max_rate() / 1024);
first = print_buffer(first, last, " [Rate %5.1f/%5.1f KB]",
(double)torrent::up_rate()->rate() / 1024.0,
(double)torrent::down_rate()->rate() / 1024.0);
if (!throttle_up_names.empty())
first = print_status_throttle_limit(first, last, true, throttle_up_names);
}
if (!torrent::down_throttle_global()->is_throttled()) {
first = print_buffer(first, last, " / off KB]");
} else {
first = print_buffer(first, last, " / %3i", torrent::down_throttle_global()->max_rate() / 1024);
if (!throttle_down_names.empty())
first = print_status_throttle_limit(first, last, false, throttle_down_names);
first = print_buffer(first, last, " KB]");
}
double global_uprate = (double)torrent::up_rate()->rate() / 1024.0;
first = print_buffer(first, last, " [Rate %5.1f", global_uprate);
if (!throttle_up_names.empty())
first = print_status_throttle_rate(first, last, true, throttle_up_names, global_uprate);
double global_downrate = (double)torrent::down_rate()->rate() / 1024.0;
first = print_buffer(first, last, " / %5.1f", global_downrate);
if (!throttle_down_names.empty())
first = print_status_throttle_rate(first, last, false, throttle_down_names, global_downrate);
first = print_buffer(first, last, " KB]");
first = print_buffer(first, last, " [Port: %i]", (unsigned int)torrent::connection_manager()->listen_port());
+3
View File
@@ -80,6 +80,9 @@ char* print_client_version(char* first, char* last, const torrent::ClientI
char* print_entry_tags(char* first, char* last);
char* print_entry_file(char* first, char* last, const torrent::Entry& entry);
char* print_status_throttle_limit(char* first, char* last, bool up, const std::vector<std::string>& throttle_names);
char* print_status_throttle_rate(char* first, char* last, bool up, const std::vector<std::string>& throttle_names, const double& global_rate);
char* print_status_info(char* first, char* last);
char* print_status_extra(char* first, char* last);
+10 -1
View File
@@ -81,11 +81,20 @@ WindowDownloadList::redraw() {
if (m_view == NULL)
return;
m_canvas->print(0, 0, "%s", ("[View: " + m_view->name() + "]").c_str());
m_canvas->print(0, 0, "%s", ("[View: " + m_view->name() + (m_view->get_filter_temp().is_empty() ? "" : " (filtered)") + "]").c_str());
if (m_view->empty_visible() || m_canvas->width() < 5 || m_canvas->height() < 2)
return;
// show "X of Y"
if (m_canvas->width() > 16 + 8 + m_view->name().length()) {
int item_idx = m_view->focus() - m_view->begin_visible();
if (item_idx == int(m_view->size()))
m_canvas->print(m_canvas->width() - 16, 0, "[ none of %-5d]", m_view->size());
else
m_canvas->print(m_canvas->width() - 16, 0, "[%5d of %-5d]", item_idx + 1, m_view->size());
}
int layout_height;
const std::string layout_name = rpc::call_command_string("ui.torrent_list.layout");
+1 -1
View File
@@ -37,7 +37,7 @@
#ifndef RTORRENT_DISPLAY_WINDOW_HTTP_QUEUE_H
#define RTORRENT_DISPLAY_WINDOW_HTTP_QUEUE_H
#include lt_tr1_functional
#include <functional>
#include "window.h"
+1 -1
View File
@@ -37,7 +37,7 @@
#ifndef RTORRENT_DISPLAY_WINDOW_STATUSBAR_H
#define RTORRENT_DISPLAY_WINDOW_STATUSBAR_H
#include <inttypes.h>
#include <cstdint>
#include "window.h"
-15
View File
@@ -1,15 +0,0 @@
noinst_LIBRARIES = libsub_input.a
libsub_input_a_SOURCES = \
bindings.cc \
bindings.h \
input_event.cc \
input_event.h \
manager.cc \
manager.h \
path_input.cc \
path_input.h \
text_input.cc \
text_input.h
AM_CPPFLAGS = -I$(srcdir) -I$(srcdir)/.. -I$(top_srcdir)
+1 -1
View File
@@ -37,8 +37,8 @@
#ifndef RTORRENT_INPUT_BINDINGS_H
#define RTORRENT_INPUT_BINDINGS_H
#include <functional>
#include <map>
#include lt_tr1_functional
#include "display/attributes.h"
+2 -1
View File
@@ -37,9 +37,10 @@
#ifndef RTORRENT_INPUT_INPUT_EVENT_H
#define RTORRENT_INPUT_INPUT_EVENT_H
#include <functional>
#include <torrent/event.h>
#include <torrent/poll.h>
#include lt_tr1_functional
namespace input {
+6 -6
View File
@@ -76,11 +76,11 @@ PathInput::pressed(int key) {
struct _transform_filename {
void operator () (utils::directory_entry& entry) {
#ifdef __sun__
if (entry.d_type & S_IFDIR)
if (entry.s_type & S_IFDIR)
#else
if (entry.d_type == DT_DIR)
if (entry.s_type == DT_DIR)
#endif
entry.d_name += '/';
entry.s_name += '/';
}
};
@@ -105,7 +105,7 @@ PathInput::receive_do_complete() {
if (r.first == r.second)
return; // Show some nice colors here.
std::string base = rak::make_base<std::string>(r.first, r.second, rak::const_mem_ref(&utils::directory_entry::d_name));
std::string base = rak::make_base<std::string>(r.first, r.second, rak::const_mem_ref(&utils::directory_entry::s_name));
// Clear the path after the cursor to make this code cleaner. It's
// not really nessesary to add the complexity just because someone
@@ -142,12 +142,12 @@ PathInput::find_last_delim() {
inline bool
find_complete_compare(const utils::directory_entry& complete, const std::string& base) {
return complete.d_name.compare(0, base.size(), base);
return complete.s_name.compare(0, base.size(), base);
}
inline bool
find_complete_not_compare(const utils::directory_entry& complete, const std::string& base) {
return !complete.d_name.compare(0, base.size(), base);
return !complete.s_name.compare(0, base.size(), base);
}
PathInput::range_type
+1 -1
View File
@@ -37,8 +37,8 @@
#ifndef RTORRENT_INPUT_PATH_INPUT_H
#define RTORRENT_INPUT_PATH_INPUT_H
#include <functional>
#include <list>
#include lt_tr1_functional
#include "utils/directory.h"
#include "text_input.h"
-21
View File
@@ -47,22 +47,6 @@ TextInput::pressed(int key) {
if (m_bindings.pressed(key)) {
return true;
} else if (m_alt) {
m_alt = false;
switch (key) {
// case 'b':
// Base::insert(m_pos, "M^b");
// break;
// case 'f':
// Base::insert(m_pos, "M^f");
// break;
default:
return false;
}
} else if (key >= 0x20 && key < 0x7F) {
Base::insert(m_pos++, 1, key);
@@ -113,11 +97,6 @@ TextInput::pressed(int key) {
Base::erase(m_pos, size()-m_pos);
break;
case 0x1B:
m_alt = true;
break;
default:
return false;
}
+2 -3
View File
@@ -54,7 +54,7 @@ public:
using Base::size_type;
using Base::npos;
TextInput() : m_pos(0), m_alt(false) {}
TextInput() : m_pos(0) {}
virtual ~TextInput() {}
size_type get_pos() { return m_pos; }
@@ -62,7 +62,7 @@ public:
virtual bool pressed(int key);
void clear() { m_pos = 0; m_alt = false; Base::clear(); }
void clear() { m_pos = 0; Base::clear(); }
void slot_dirty(slot_void s) { m_slot_dirty = s; }
void mark_dirty() { if (m_slot_dirty) m_slot_dirty(); }
@@ -74,7 +74,6 @@ public:
private:
size_type m_pos;
bool m_alt;
slot_void m_slot_dirty;
Bindings m_bindings;
+22 -5
View File
@@ -53,7 +53,7 @@
#include <rak/functional.h>
#include <rak/error_number.h>
#ifdef USE_EXECINFO
#ifdef HAVE_BACKTRACE
#include <execinfo.h>
#endif
@@ -66,6 +66,7 @@
#include "display/window.h"
#include "display/manager.h"
#include "input/bindings.h"
#include "ui/root.h"
#include "rpc/command_scheduler.h"
#include "rpc/command_scheduler_item.h"
@@ -80,6 +81,9 @@
#include "thread_worker.h"
#define LT_LOG(log_fmt, ...) \
lt_log_print(torrent::LOG_SYSTEM, "system: " log_fmt, __VA_ARGS__);
void handle_sigbus(int signum, siginfo_t* sa, void* ptr);
void do_panic(int signum);
void print_help();
@@ -131,8 +135,9 @@ load_session_torrents() {
// Replace with session torrent flag.
f->set_session(true);
f->set_init_load(true);
f->slot_finished(std::bind(&rak::call_delete_func<core::DownloadFactory>, f));
f->load(entries.path() + first->d_name);
f->load(entries.path() + first->s_name);
f->commit();
}
}
@@ -145,6 +150,7 @@ load_arg_torrents(char** first, char** last) {
// Replace with session torrent flag.
f->set_start(true);
f->set_init_load(true);
f->slot_finished(std::bind(&rak::call_delete_func<core::DownloadFactory>, f));
f->load(*first);
f->commit();
@@ -249,6 +255,12 @@ main(int argc, char** argv) {
rpc::parse_command_multiple
(rpc::make_target(),
"method.insert = event.view.hide,multi|rlookup|static\n"
"method.insert = event.view.show,multi|rlookup|static\n"
"method.insert = event.system.startup_done,multi|rlookup|static\n"
"method.insert = event.system.shutdown,multi|rlookup|static\n"
"method.insert = event.download.inserted,multi|rlookup|static\n"
"method.insert = event.download.inserted_new,multi|rlookup|static\n"
"method.insert = event.download.inserted_session,multi|rlookup|static\n"
@@ -459,7 +471,10 @@ main(int argc, char** argv) {
}
}
LT_LOG("seeded srandom and srand48 (seed:%u)", random_seed);
control->initialize();
control->ui()->load_input_history();
// Load session torrents and perform scheduled tasks to ensure
// session torrents are loaded before arg torrents.
@@ -477,6 +492,8 @@ main(int argc, char** argv) {
worker_thread->start_thread();
rpc::commands.call_catch("event.system.startup_done", rpc::make_target(), "startup_done", "System startup_done event action failed: ");
torrent::thread_base::event_loop(torrent::main_thread());
control->core()->download_list()->session_save();
@@ -518,7 +535,7 @@ handle_sigbus(int signum, siginfo_t* sa, void* ptr) {
std::stringstream output;
output << "Caught SIGBUS, dumping stack:" << std::endl;
#ifdef USE_EXECINFO
#ifdef HAVE_BACKTRACE
void* stackPtrs[20];
// Print the stack and exit.
@@ -589,7 +606,7 @@ do_panic(int signum) {
output << "Caught " << SignalHandler::as_string(signum) << ", dumping stack:" << std::endl;
#ifdef USE_EXECINFO
#ifdef HAVE_BACKTRACE
void* stackPtrs[20];
// Print the stack and exit.
@@ -658,7 +675,7 @@ print_help() {
std::cout << " o View trackers" << std::endl;
std::cout << std::endl;
std::cout << "Report bugs to <sundell.software@gmail.com>." << std::endl;
std::cout << "Report bugs to <github.com/rakshasa/rtorrent>." << std::endl;
exit(0);
}
+1 -1
View File
@@ -37,9 +37,9 @@
#ifndef RTORRENT_OPTION_PARSER_H
#define RTORRENT_OPTION_PARSER_H
#include <functional>
#include <map>
#include <string>
#include lt_tr1_functional
// Throws std::runtime_error upon receiving bad input.
-30
View File
@@ -1,30 +0,0 @@
noinst_LIBRARIES = libsub_rpc.a
libsub_rpc_a_SOURCES = \
command.h \
command.cc \
command_impl.h \
command_map.cc \
command_map.h \
command_scheduler.cc \
command_scheduler.h \
command_scheduler_item.cc \
command_scheduler_item.h \
exec_file.cc \
exec_file.h \
fixed_key.h \
ip_table_list.h \
object_storage.cc \
object_storage.h \
parse.cc \
parse.h \
parse_commands.cc \
parse_commands.h \
scgi.cc \
scgi.h \
scgi_task.cc \
scgi_task.h \
xmlrpc.h \
xmlrpc.cc
AM_CPPFLAGS = -I$(srcdir) -I$(srcdir)/.. -I$(top_srcdir)
-2
View File
@@ -39,9 +39,7 @@
#include <functional>
#include <limits>
#include <inttypes.h>
#include <torrent/object.h>
#include lt_tr1_functional
#include <torrent/object.h>
#include <torrent/data/file_list_iterator.h>
+1 -1
View File
@@ -37,9 +37,9 @@
#ifndef RTORRENT_COMMAND_SCHEDULER_H
#define RTORRENT_COMMAND_SCHEDULER_H
#include <cstdint>
#include <vector>
#include <string>
#include <inttypes.h>
#include <rak/functional_fun.h>
namespace torrent {
+2 -1
View File
@@ -39,7 +39,8 @@
#include "globals.h"
#include lt_tr1_functional
#include <functional>
#include <torrent/object.h>
namespace rpc {
+28 -31
View File
@@ -61,22 +61,19 @@ const unsigned int object_storage::flag_rlookup;
const size_t object_storage::key_size;
object_storage::local_iterator
object_storage::find_local(const torrent::raw_string& key) {
std::size_t n = hash_fixed_key_type::hash(key.data(), key.size()) % bucket_count();
object_storage::iterator
object_storage::find_raw_string(const torrent::raw_string& key) {
fixed_key_type<64> k;
k.set_c_str(key.data());
for (local_iterator itr = begin(n), last = end(n); itr != last; itr++)
if (itr->first.size() == key.size() && std::memcmp(itr->first.data(), key.data(), key.size()) == 0)
return itr;
return end(bucket_count());
return find(k);
}
object_storage::local_iterator
object_storage::find_local_const(const torrent::raw_string& key, unsigned int type) {
local_iterator itr = find_local(key);
object_storage::iterator
object_storage::find_raw_string_const(const torrent::raw_string& key, unsigned int type) {
iterator itr = find_raw_string(key);
if (itr == end(bucket_count()))
if (itr == end())
throw torrent::input_error("Key not found.");
if ((type != 0 && (itr->second.flags & mask_type) != type))
@@ -85,11 +82,11 @@ object_storage::find_local_const(const torrent::raw_string& key, unsigned int ty
return itr;
}
object_storage::local_iterator
object_storage::find_local_mutable(const torrent::raw_string& key, unsigned int type) {
local_iterator itr = find_local(key);
object_storage::iterator
object_storage::find_raw_string_mutable(const torrent::raw_string& key, unsigned int type) {
iterator itr = find_raw_string(key);
if (itr == end(bucket_count()))
if (itr == end())
throw torrent::input_error("Key not found.");
if ((type != 0 && (itr->second.flags & mask_type) != type) ||
@@ -138,63 +135,63 @@ object_storage::insert(const char* key_data, uint32_t key_size, const torrent::O
bool
object_storage::has_flag(const torrent::raw_string& key, unsigned int flag) {
local_iterator itr = find_local_const(key);
iterator itr = find_raw_string_const(key);
return itr->second.flags & flag;
}
void
object_storage::enable_flag(const torrent::raw_string& key, unsigned int flag) {
local_iterator itr = find_local_mutable(key);
iterator itr = find_raw_string_mutable(key);
itr->second.flags |= (flag & (flag_constant));
}
const torrent::Object&
object_storage::get(const torrent::raw_string& key) {
local_iterator itr = find_local_const(key);
iterator itr = find_raw_string_const(key);
return itr->second.object;
}
const torrent::Object&
object_storage::set_bool(const torrent::raw_string& key, int64_t object) {
local_iterator itr = find_local_mutable(key, flag_bool_type);
iterator itr = find_raw_string_mutable(key, flag_bool_type);
return itr->second.object = !!object;
}
const torrent::Object&
object_storage::set_value(const torrent::raw_string& key, int64_t object) {
local_iterator itr = find_local_mutable(key, flag_value_type);
iterator itr = find_raw_string_mutable(key, flag_value_type);
return itr->second.object = object;
}
const torrent::Object&
object_storage::set_string(const torrent::raw_string& key, const std::string& object) {
local_iterator itr = find_local_mutable(key, flag_string_type);
iterator itr = find_raw_string_mutable(key, flag_string_type);
return itr->second.object = object;
}
const torrent::Object&
object_storage::set_list(const torrent::raw_string& key, const torrent::Object::list_type& object) {
local_iterator itr = find_local_mutable(key, flag_list_type);
iterator itr = find_raw_string_mutable(key, flag_list_type);
return itr->second.object = torrent::Object::create_list_range(object.begin(), object.end());
}
void
object_storage::list_push_back(const torrent::raw_string& key, const torrent::Object& object) {
local_iterator itr = find_local_mutable(key, flag_list_type);
iterator itr = find_raw_string_mutable(key, flag_list_type);
itr->second.object.as_list().push_back(object);
}
const torrent::Object&
object_storage::set_function(const torrent::raw_string& key, const std::string& object) {
local_iterator itr = find_local_mutable(key, flag_function_type);
iterator itr = find_raw_string_mutable(key, flag_function_type);
return itr->second.object = object;
}
torrent::Object
object_storage::call_function(const torrent::raw_string& key, target_type target, const torrent::Object& object) {
local_iterator itr = find_local_const(key);
iterator itr = find_raw_string_const(key);
switch (itr->second.flags & mask_type) {
case flag_function_type:
@@ -207,13 +204,13 @@ object_storage::call_function(const torrent::raw_string& key, target_type target
bool
object_storage::has_multi_key(const torrent::raw_string& key, const std::string& cmd_key) {
local_iterator itr = find_local_const(key, flag_multi_type);
iterator itr = find_raw_string_const(key, flag_multi_type);
return itr->second.object.has_key(cmd_key);
}
void
object_storage::erase_multi_key(const torrent::raw_string& key, const std::string& cmd_key) {
local_iterator itr = find_local_mutable(key, flag_multi_type);
iterator itr = find_raw_string_mutable(key, flag_multi_type);
itr->second.object.erase_key(cmd_key);
@@ -238,7 +235,7 @@ object_storage::set_multi_key_obj(const torrent::raw_string& key, const std::str
if (!object.is_string() && !object.is_dict_key() && !object.is_list())
throw torrent::input_error("Object is wrong type.");
local_iterator itr = find_local_mutable(key, flag_multi_type);
iterator itr = find_raw_string_mutable(key, flag_multi_type);
if (itr->second.flags & flag_rlookup) {
rlookup_iterator r_itr = m_rlookup.find(cmd_key);
@@ -259,7 +256,7 @@ object_storage::rlookup_list(const std::string& cmd_key) {
torrent::Object::list_type result;
rlookup_iterator r_itr = m_rlookup.find(cmd_key);
if (r_itr != m_rlookup.end())
std::transform(r_itr->second.begin(), r_itr->second.end(), std::back_inserter(result),
std::bind(&key_type::c_str, std::bind(rak::mem_ptr(&value_type::first), std::placeholders::_1)));
@@ -270,7 +267,7 @@ object_storage::rlookup_list(const std::string& cmd_key) {
void
object_storage::rlookup_clear(const std::string& cmd_key) {
rlookup_iterator r_itr = m_rlookup.find(cmd_key);
if (r_itr == m_rlookup.end())
return;
+16 -19
View File
@@ -42,7 +42,7 @@
#define RTORRENT_RPC_OBJECT_STORAGE_H
#include <cstring>
#include lt_tr1_unordered_map
#include <unordered_map>
#include <torrent/object.h>
#include "rak/unordered_vector.h"
@@ -79,9 +79,6 @@ public:
using base_type::size;
using base_type::empty;
using base_type::key_eq;
using base_type::bucket;
using base_type::bucket_count;
using base_type::max_bucket_count;
using base_type::load_factor;
// Verify rlookup is static / const.
@@ -89,27 +86,27 @@ public:
using base_type::clear;
using base_type::find;
using base_type::erase;
static const unsigned int flag_generic_type = 0x1;
static const unsigned int flag_bool_type = 0x2;
static const unsigned int flag_value_type = 0x3;
static const unsigned int flag_string_type = 0x4;
static const unsigned int flag_list_type = 0x5;
static const unsigned int flag_function_type = 0x6;
static const unsigned int flag_multi_type = 0x7;
static const unsigned int flag_value_type = 0x4;
static const unsigned int flag_string_type = 0x8;
static const unsigned int flag_list_type = 0x10;
static const unsigned int flag_function_type = 0x20;
static const unsigned int flag_multi_type = 0x40;
static const unsigned int mask_type = 0xf;
static const unsigned int mask_type = 0xff;
static const unsigned int flag_constant = 0x10;
static const unsigned int flag_static = 0x20;
static const unsigned int flag_private = 0x40;
static const unsigned int flag_rlookup = 0x80;
static const unsigned int flag_constant = 0x100;
static const unsigned int flag_static = 0x200;
static const unsigned int flag_private = 0x400;
static const unsigned int flag_rlookup = 0x800;
static const size_t key_size = key_type::max_size;
local_iterator find_local(const torrent::raw_string& key);
local_iterator find_local_const(const torrent::raw_string& key, unsigned int type = 0);
local_iterator find_local_mutable(const torrent::raw_string& key, unsigned int type = 0);
iterator find_raw_string(const torrent::raw_string& key);
iterator find_raw_string_const(const torrent::raw_string& key, unsigned int type = 0);
iterator find_raw_string_mutable(const torrent::raw_string& key, unsigned int type = 0);
iterator insert(const char* key_data, uint32_t key_size, const torrent::Object& object, unsigned int flags);
iterator insert_c_str(const char* key, const torrent::Object& object, unsigned int flags) { return insert(key, std::strlen(key), object, flags); }
@@ -141,7 +138,7 @@ public:
const torrent::Object& set_string(const torrent::raw_string& key, const std::string& object);
const torrent::Object& set_c_str_string(const char* str, const std::string& object) { return set_string(torrent::raw_string::from_c_str(str), object); }
const torrent::Object& set_str_string(const std::string& str, const std::string& object) { return set_string(torrent::raw_string::from_string(str), object); }
const torrent::Object& set_list(const torrent::raw_string& key, const torrent::Object::list_type& object);
const torrent::Object& set_c_str_list(const char* str, const torrent::Object::list_type& object) { return set_list(torrent::raw_string::from_c_str(str), object); }
const torrent::Object& set_str_list(const std::string& str, const torrent::Object::list_type& object) { return set_list(torrent::raw_string::from_string(str), object); }
+169
View File
@@ -0,0 +1,169 @@
// 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 "parse_options.h"
#include <algorithm>
#include <locale>
#include <torrent/exceptions.h>
namespace rpc {
int
parse_option_flag(const std::string& option, parse_option_flag_type ftor) {
auto first = option.begin();
auto last = option.end();
first = std::find_if(first, last, [](char c) { return !std::isspace(c, std::locale::classic()); });
if (first == last)
throw torrent::input_error(option);
auto next = std::find_if(first, last, [](char c) { return !std::isalnum(c, std::locale::classic()) && c != '_'; });
if (first == next)
throw torrent::input_error(option);
if (std::find_if(next, last, [](char c) { return !std::isspace(c, std::locale::classic()); }) != last)
throw torrent::input_error(option);
return ftor(std::string(first, next));
}
int
parse_option_flags(const std::string& option, parse_option_flag_type ftor, int flags) {
auto first = option.begin();
auto last = option.end();
while (first != last) {
first = std::find_if(first, last, [](char c) { return !std::isspace(c, std::locale::classic()); });
if (first == last)
break;
auto next = std::find_if(first, last, [](char c) { return !std::isalnum(c, std::locale::classic()) && c != '_'; });
if (first == next)
throw torrent::input_error(option);
int f = ftor(std::string(first, next));
if (f < 0)
flags &= f;
else
flags |= f;
first = std::find_if(next, last, [](char c) { return !std::isspace(c, std::locale::classic()); });
if (first == last)
break;
if (*first++ != '|' || first == last)
throw torrent::input_error(option);
}
return flags;
}
void
parse_option_for_each(const std::string& option, parse_option_flag_type ftor) {
auto first = option.begin();
auto last = option.end();
while (first != last) {
first = std::find_if(first, last, [](char c) { return !std::isspace(c, std::locale::classic()); });
if (first == last)
break;
auto next = std::find_if(first, last, [](char c) { return !std::isalnum(c, std::locale::classic()) && c != '_'; });
if (first == next)
throw torrent::input_error(option);
ftor(std::string(first, next));
first = std::find_if(next, last, [](char c) { return !std::isspace(c, std::locale::classic()); });
if (first == last)
break;
if (*first++ != '|' || first == last)
throw torrent::input_error(option);
}
}
std::string
parse_option_print_vector(int flags, const std::vector<std::pair<const char*, int>>& flag_list) {
std::string result;
for (auto f : flag_list) {
if (f.second < 0) {
if ((flags & f.second) != flags)
continue;
} else {
if ((flags & f.second) != f.second)
continue;
}
if (!result.empty())
result += '|';
result += f.first;
}
return result;
}
std::string
parse_option_print_flags(unsigned int flags, parse_option_rflag_type ftor) {
std::string result;
for (int i = 1; flags != 0; i <<= 1) {
if (!(flags & i))
continue;
if (!result.empty())
result += '|';
result += ftor(i);
flags &= ~i;
}
return result;
}
}
+63
View File
@@ -0,0 +1,63 @@
// rTorrent - BitTorrent client
// Copyright (C) 2005-2011, Jari Sundell
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// In addition, as a special exception, the copyright holders give
// permission to link the code of portions of this program with the
// OpenSSL library under certain conditions as described in each
// individual source file, and distribute linked combinations
// including the two.
//
// You must obey the GNU General Public License in all respects for
// all of the code used other than OpenSSL. If you modify file(s)
// with this exception, you may extend this exception to your version
// of the file(s), but you are not obligated to do so. If you do not
// wish to do so, delete this exception statement from your version.
// If you delete this exception statement from all source files in the
// program, then also delete it here.
//
// Contact: Jari Sundell <jaris@ifi.uio.no>
//
// Skomakerveien 33
// 3185 Skoppum, NORWAY
#ifndef RTORRENT_RPC_PARSE_OPTIONS_H
#define RTORRENT_RPC_PARSE_OPTIONS_H
#include <cstring>
#include <functional>
#include <string>
#include <vector>
namespace rpc {
// If a flag returned by the functor is negative it is treated as a
// negation of the flag.
typedef std::function<int (const std::string&)> parse_option_flag_type;
typedef std::function<const char* (unsigned int)> parse_option_rflag_type;
int parse_option_flag(const std::string& option, parse_option_flag_type ftor);
int parse_option_flags(const std::string& option, parse_option_flag_type ftor, int flags = int());
void parse_option_for_each(const std::string& option, parse_option_flag_type ftor);
std::string parse_option_print_vector(int flags, const std::vector<std::pair<const char*, int>>& flag_list);
std::string parse_option_print_flags(unsigned int flags, parse_option_rflag_type ftor);
}
#endif
+1 -1
View File
@@ -51,7 +51,7 @@ class SCgiTask : public torrent::Event {
public:
static const unsigned int default_buffer_size = 2047;
static const int max_header_size = 2000;
static const int max_content_size = (2 << 20);
static const int max_content_size = (2 << 23);
SCgiTask() { m_fileDesc = -1; }
+2 -1
View File
@@ -37,7 +37,8 @@
#ifndef RTORRENT_RPC_XMLRPC_H
#define RTORRENT_RPC_XMLRPC_H
#include lt_tr1_functional
#include <functional>
#include <torrent/hash_string.h>
namespace core {
+1 -1
View File
@@ -37,8 +37,8 @@
#ifndef RTORRENT_SIGNAL_HANDLER_H
#define RTORRENT_SIGNAL_HANDLER_H
#include <functional>
#include <signal.h>
#include lt_tr1_functional
class SignalHandler {
public:
+5 -4
View File
@@ -113,14 +113,15 @@ ThreadWorker::change_xmlrpc_log() {
if (scgi() == NULL)
return;
if (scgi()->log_fd() != -1)
if (scgi()->log_fd() != -1) {
::close(scgi()->log_fd());
if (m_xmlrpcLog.empty()) {
scgi()->set_log_fd(-1);
control->core()->push_log("Closed XMLRPC log.");
return;
}
if (m_xmlrpcLog.empty())
return;
scgi()->set_log_fd(open(rak::path_expand(m_xmlrpcLog).c_str(), O_WRONLY | O_APPEND | O_CREAT, 0644));
if (scgi()->log_fd() == -1) {
-33
View File
@@ -1,33 +0,0 @@
noinst_LIBRARIES = libsub_ui.a
libsub_ui_a_SOURCES = \
download.cc \
download.h \
download_list.cc \
download_list.h \
element_base.h \
element_base.cc \
element_chunks_seen.cc \
element_chunks_seen.h \
element_download_list.cc \
element_download_list.h \
element_file_list.cc \
element_file_list.h \
element_log_complete.cc \
element_log_complete.h \
element_menu.cc \
element_menu.h \
element_peer_list.cc \
element_peer_list.h \
element_string_list.cc \
element_string_list.h \
element_text.cc \
element_text.h \
element_tracker_list.cc \
element_tracker_list.h \
element_transfer_list.cc \
element_transfer_list.h \
root.cc \
root.h
AM_CPPFLAGS = -I$(srcdir) -I$(srcdir)/.. -I$(top_srcdir)
+13 -12
View File
@@ -54,6 +54,7 @@
#include "display/window_download_statusbar.h"
#include "display/text_element_string.h"
#include "rpc/parse_commands.h"
#include "control.h"
#include "download.h"
@@ -395,20 +396,20 @@ Download::bind_keys() {
const char* keys = control->ui()->get_throttle_keys();
m_bindings[keys[ 0]] = std::bind(&Download::adjust_up_throttle, this, 1);
m_bindings[keys[ 1]] = std::bind(&Download::adjust_up_throttle, this, -1);
m_bindings[keys[ 2]] = std::bind(&Download::adjust_down_throttle, this, 1);
m_bindings[keys[ 3]] = std::bind(&Download::adjust_down_throttle, this, -1);
m_bindings[keys[ 0]] = std::bind(&Download::adjust_up_throttle, this, (int) rpc::call_command_value("ui.throttle.global.step.small"));
m_bindings[keys[ 1]] = std::bind(&Download::adjust_up_throttle, this, (int) -rpc::call_command_value("ui.throttle.global.step.small"));
m_bindings[keys[ 2]] = std::bind(&Download::adjust_down_throttle, this, (int) rpc::call_command_value("ui.throttle.global.step.small"));
m_bindings[keys[ 3]] = std::bind(&Download::adjust_down_throttle, this, (int) -rpc::call_command_value("ui.throttle.global.step.small"));
m_bindings[keys[ 4]] = std::bind(&Download::adjust_up_throttle, this, 5);
m_bindings[keys[ 5]] = std::bind(&Download::adjust_up_throttle, this, -5);
m_bindings[keys[ 6]] = std::bind(&Download::adjust_down_throttle, this, 5);
m_bindings[keys[ 7]] = std::bind(&Download::adjust_down_throttle, this, -5);
m_bindings[keys[ 4]] = std::bind(&Download::adjust_up_throttle, this, (int) rpc::call_command_value("ui.throttle.global.step.medium"));
m_bindings[keys[ 5]] = std::bind(&Download::adjust_up_throttle, this, (int) -rpc::call_command_value("ui.throttle.global.step.medium"));
m_bindings[keys[ 6]] = std::bind(&Download::adjust_down_throttle, this, (int) rpc::call_command_value("ui.throttle.global.step.medium"));
m_bindings[keys[ 7]] = std::bind(&Download::adjust_down_throttle, this, (int) -rpc::call_command_value("ui.throttle.global.step.medium"));
m_bindings[keys[ 8]] = std::bind(&Download::adjust_up_throttle, this, 50);
m_bindings[keys[ 9]] = std::bind(&Download::adjust_up_throttle, this, -50);
m_bindings[keys[10]] = std::bind(&Download::adjust_down_throttle, this, 50);
m_bindings[keys[11]] = std::bind(&Download::adjust_down_throttle, this, -50);
m_bindings[keys[ 8]] = std::bind(&Download::adjust_up_throttle, this, (int) rpc::call_command_value("ui.throttle.global.step.large"));
m_bindings[keys[ 9]] = std::bind(&Download::adjust_up_throttle, this, (int) -rpc::call_command_value("ui.throttle.global.step.large"));
m_bindings[keys[10]] = std::bind(&Download::adjust_down_throttle, this, (int) rpc::call_command_value("ui.throttle.global.step.large"));
m_bindings[keys[11]] = std::bind(&Download::adjust_down_throttle, this, (int) -rpc::call_command_value("ui.throttle.global.step.large"));
}
}
+56 -2
View File
@@ -36,6 +36,8 @@
#include "config.h"
#include <sstream>
#include <rak/functional.h>
#include <rak/string_manip.h>
#include <torrent/exceptions.h>
@@ -259,6 +261,25 @@ DownloadList::receive_view_input(Input type) {
title = "command";
break;
case INPUT_FILTER:
{
// Do not allow to subfilter the defined excluded views
const std::string excluded_views = rpc::call_command_string("view.filter.temp.excluded");
std::stringstream ss(excluded_views);
std::string view_name_var;
while(ss.good()) {
std::getline(ss, view_name_var, ',');
if (current_view()->name() == rak::trim(view_name_var)) {
control->core()->push_log_std("View '" + current_view()->name() + "' can't be filtered.");
return;
}
}
title = "filter";
}
break;
default:
throw torrent::internal_error("DownloadList::receive_view_input(...) Invalid input type.");
}
@@ -274,21 +295,31 @@ DownloadList::receive_view_input(Input type) {
std::placeholders::_1,
std::placeholders::_2));
// reset ESC delay for input prompt
set_escdelay(0);
input->bindings()['\n'] = std::bind(&DownloadList::receive_exit_input, this, type);
input->bindings()[KEY_ENTER] = std::bind(&DownloadList::receive_exit_input, this, type);
input->bindings()['\x07'] = std::bind(&DownloadList::receive_exit_input, this, INPUT_NONE);
input->bindings()['\x07'] = std::bind(&DownloadList::receive_exit_input, this, INPUT_NONE); // ^G
input->bindings()['\x1B'] = std::bind(&DownloadList::receive_exit_input, this, INPUT_NONE); // ESC , ^[
control->ui()->enable_input(title, input);
control->ui()->enable_input(title, input, type);
}
void
DownloadList::receive_exit_input(Input type) {
// set back ESC delay to default
set_escdelay(1000);
input::TextInput* input = control->ui()->current_input();
// We should check that this object is the one holding the input.
if (input == NULL)
return;
if (type != INPUT_NONE && type != INPUT_EOI)
control->ui()->add_to_input_history(type, input->str());
control->ui()->disable_input();
try {
@@ -322,6 +353,28 @@ DownloadList::receive_exit_input(Input type) {
input->str());
break;
case INPUT_FILTER:
if (input->str().empty()) {
if (rpc::call_command_value("view.filter.temp.log"))
control->core()->push_log_std("Clear temporary filter on '" + current_view()->name() + "' view.");
current_view()->set_filter_temp(torrent::Object());
current_view()->filter();
current_view()->sort();
} else {
std::string pattern = input->str();
if (pattern.back() != '$')
pattern = pattern + ".*";
if (pattern.front() != '^')
pattern = ".*" + pattern;
std::transform(pattern.begin(), pattern.end(), pattern.begin(), ::tolower);
std::string temp_filter = "match={d.name=," + pattern + "}";
if (rpc::call_command_value("view.filter.temp.log"))
control->core()->push_log_std("Temporary filter on '" + current_view()->name() + "' view: " + pattern);
current_view()->set_filter_temp(temp_filter);
current_view()->filter();
}
break;
default:
throw torrent::internal_error("DownloadList::receive_exit_input(...) Invalid input type.");
}
@@ -343,6 +396,7 @@ DownloadList::setup_keys() {
m_bindings[KEY_ENTER] = std::bind(&DownloadList::receive_view_input, this, INPUT_LOAD_MODIFIED);
m_bindings['\x0F'] = std::bind(&DownloadList::receive_view_input, this, INPUT_CHANGE_DIRECTORY);
m_bindings['X' - '@'] = std::bind(&DownloadList::receive_view_input, this, INPUT_COMMAND);
m_bindings['F'] = std::bind(&DownloadList::receive_view_input, this, INPUT_FILTER);
m_uiArray[DISPLAY_LOG]->bindings()[KEY_LEFT] =
m_uiArray[DISPLAY_LOG]->bindings()['B' - '@'] =
+3 -1
View File
@@ -86,7 +86,9 @@ public:
INPUT_LOAD_DEFAULT,
INPUT_LOAD_MODIFIED,
INPUT_CHANGE_DIRECTORY,
INPUT_COMMAND
INPUT_COMMAND,
INPUT_FILTER,
INPUT_EOI
} Input;
DownloadList();

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