revert
|
@ -1,26 +0,0 @@
|
|||
|
||||
Written by Arvid Norberg. Copyright (c) 2003-2007
|
||||
|
||||
Lots of testing, suggestions and contributions by:
|
||||
Massaroddel
|
||||
Tianhao Qiu.
|
||||
|
||||
Contributions by:
|
||||
Shyam
|
||||
Magnus Jonsson
|
||||
Daniel Wallin
|
||||
Cory Nelson
|
||||
Stas Khirman
|
||||
Ryan Norton
|
||||
Andrew Resch
|
||||
|
||||
Building and maintainance of the autotools scripts:
|
||||
Michael Wojciechowski
|
||||
Peter Koeleman
|
||||
|
||||
Thanks to Reimond Retz for bugfixes, suggestions and testing
|
||||
|
||||
Thanks to University of UmeŒ for providing development and test hardware.
|
||||
|
||||
Project is hosted by sourceforge.
|
||||
|
|
@ -1,302 +0,0 @@
|
|||
cmake_minimum_required(VERSION 2.6)
|
||||
project(libtorrent)
|
||||
|
||||
set(sources
|
||||
web_connection_base
|
||||
alert
|
||||
allocator
|
||||
assert
|
||||
bandwidth_limit
|
||||
bandwidth_manager
|
||||
bandwidth_queue_entry
|
||||
connection_queue
|
||||
create_torrent
|
||||
disk_buffer_holder
|
||||
entry
|
||||
error_code
|
||||
file_storage
|
||||
lazy_bdecode
|
||||
escape_string
|
||||
file
|
||||
gzip
|
||||
http_connection
|
||||
http_stream
|
||||
http_parser
|
||||
i2p_stream
|
||||
identify_client
|
||||
ip_filter
|
||||
peer_connection
|
||||
bt_peer_connection
|
||||
web_peer_connection
|
||||
http_seed_connection
|
||||
instantiate_connection
|
||||
natpmp
|
||||
packet_buffer
|
||||
piece_picker
|
||||
policy
|
||||
puff
|
||||
session
|
||||
session_impl
|
||||
settings
|
||||
socket_io
|
||||
socket_type
|
||||
socks5_stream
|
||||
stat
|
||||
storage
|
||||
thread
|
||||
time
|
||||
torrent
|
||||
torrent_handle
|
||||
torrent_info
|
||||
tracker_manager
|
||||
http_tracker_connection
|
||||
udp_tracker_connection
|
||||
udp_socket
|
||||
upnp
|
||||
logger
|
||||
file_pool
|
||||
lsd
|
||||
disk_io_thread
|
||||
enum_net
|
||||
broadcast_socket
|
||||
magnet_uri
|
||||
parse_url
|
||||
ConvertUTF
|
||||
|
||||
# -- extensions --
|
||||
metadata_transfer
|
||||
ut_pex
|
||||
ut_metadata
|
||||
smart_ban
|
||||
lt_trackers
|
||||
)
|
||||
|
||||
# -- kademlia --
|
||||
set(kademlia_sources
|
||||
dht_tracker
|
||||
node
|
||||
refresh
|
||||
rpc_manager
|
||||
find_data
|
||||
node_id
|
||||
routing_table
|
||||
traversal_algorithm
|
||||
)
|
||||
|
||||
set(includes include)
|
||||
|
||||
option(shared "build libtorrent as a shared library" ON)
|
||||
option(tcmalloc "link against google performance tools tcmalloc" OFF)
|
||||
option(pool-allocators "Uses a pool allocator for disk and piece buffers" ON)
|
||||
option(encryption "link against openssl and enable encryption" ON)
|
||||
option(geoip "link against LGPL GeoIP code from Maxmind, to enable geoip database support" OFF)
|
||||
option(dht "enable support for Mainline DHT" ON)
|
||||
option(resolve-countries "enable support for resolving countries from peer IPs" ON)
|
||||
option(unicode "enable unicode support" ON)
|
||||
option(deprecated-functions "enable deprecated functions for backwards compatibility" ON)
|
||||
option(exceptions "build with exception support" ON)
|
||||
option(logging "build with logging" OFF)
|
||||
option(verbose-logging "build with verbose logging" OFF)
|
||||
option(build_tests "build tests" OFF)
|
||||
option(build_examples "build examples" OFF)
|
||||
|
||||
set(CMAKE_CONFIGURATION_TYPES Debug Release RelWithDebInfo)
|
||||
|
||||
if (NOT CMAKE_BUILD_TYPE)
|
||||
set(CMAKE_BUILD_TYPE Release FORCE)
|
||||
endif (NOT CMAKE_BUILD_TYPE)
|
||||
|
||||
# add_definitions() doesn't seem to let you say wich build type to apply it to
|
||||
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DTORRENT_DEBUG")
|
||||
|
||||
set(CMAKE_C_FLAGS_RELWITHDEBINFO "-Os -g")
|
||||
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO}")
|
||||
|
||||
if (encryption)
|
||||
list(APPEND sources pe_crypto)
|
||||
endif (encryption)
|
||||
|
||||
if (logging)
|
||||
add_definitions(-DTORRENT_LOGGING)
|
||||
endif (logging)
|
||||
if (verbose-logging)
|
||||
add_definitions(-DTORRENT_VERBOSE_LOGGING)
|
||||
endif (verbose-logging)
|
||||
|
||||
foreach(s ${sources})
|
||||
list(APPEND sources2 src/${s})
|
||||
endforeach(s)
|
||||
|
||||
if (dht)
|
||||
foreach(s ${kademlia_sources})
|
||||
list(APPEND sources2 src/kademlia/${s})
|
||||
endforeach(s)
|
||||
else (dht)
|
||||
add_definitions(-DTORRENT_DISABLE_DHT)
|
||||
endif (dht)
|
||||
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fvisibility=hidden")
|
||||
|
||||
if (shared)
|
||||
add_library(torrent-rasterbar SHARED ${sources2})
|
||||
else (shared)
|
||||
add_library(torrent-rasterbar STATIC ${sources2})
|
||||
endif (shared)
|
||||
|
||||
FIND_PACKAGE( Boost 1.34 COMPONENTS filesystem)
|
||||
if (NOT Boost_VERSION LESS 103500)
|
||||
FIND_PACKAGE( Boost 1.35 COMPONENTS filesystem system)
|
||||
endif (NOT Boost_VERSION LESS 103500)
|
||||
include_directories(${Boost_INCLUDE_DIR})
|
||||
target_link_libraries(torrent-rasterbar ${Boost_LIBRARIES})
|
||||
|
||||
# this works around a bug in asio in boost-1.39
|
||||
add_definitions(-DBOOST_ASIO_HASH_MAP_BUCKETS=1021)
|
||||
|
||||
if (WIN32)
|
||||
target_link_libraries(torrent-rasterbar wsock32 ws2_32)
|
||||
endif (WIN32)
|
||||
|
||||
if (encryption)
|
||||
add_definitions(-DTORRENT_USE_OPENSSL)
|
||||
if (WIN32)
|
||||
target_link_libraries(torrent-rasterbar ssleay32 libeay32 advapi32 user32 shell32 gdi32)
|
||||
else (WIN32)
|
||||
target_link_libraries(torrent-rasterbar crypto ssl)
|
||||
endif (WIN32)
|
||||
else (encryption)
|
||||
add_definitions(-DTORRENT_DISABLE_ENCRYPTION)
|
||||
list(APPEND sources sha1)
|
||||
endif (encryption)
|
||||
|
||||
if (NOT pool-allocators)
|
||||
add_definitions(-DTORRENT_DISABLE_POOL_ALLOCATOR)
|
||||
endif (NOT pool-allocators)
|
||||
|
||||
if (NOT geoip)
|
||||
add_definitions(-DTORRENT_DISABLE_GEO_IP)
|
||||
endif (NOT geoip)
|
||||
|
||||
if (NOT resolve-countries)
|
||||
add_definitions(-DTORRENT_DISABLE_RESOLVE_COUNTRIES)
|
||||
endif (NOT resolve-countries)
|
||||
|
||||
if (unicode)
|
||||
add_definitions(-DUNICODE -D_UNICODE)
|
||||
endif (unicode)
|
||||
|
||||
if (NOT deprecated-functions)
|
||||
add_definitions(-DTORRENT_NO_DEPRECATE)
|
||||
endif (NOT deprecated-functions)
|
||||
|
||||
if (exceptions)
|
||||
add_definitions(-fexceptions)
|
||||
else (exceptions)
|
||||
add_definitions(-fno-exceptions)
|
||||
endif (exceptions)
|
||||
|
||||
if (MSVC)
|
||||
# disable bogus deprecation warnings on msvc8
|
||||
add_definitions(-D_SCL_SECURE_NO_DEPRECATE -D_CRT_SECURE_NO_DEPRECATE)
|
||||
# these compiler settings just makes the compiler standard conforming
|
||||
add_definitions(/Zc:wchar_t /Zc:forScope)
|
||||
|
||||
# <toolset>msvc,<variant>release:<linkflags>/OPT:ICF=5
|
||||
# <toolset>msvc,<variant>release:<linkflags>/OPT:REF
|
||||
endif(MSVC)
|
||||
|
||||
add_definitions(-D_FILE_OFFSET_BITS=64)
|
||||
add_definitions(-DBOOST_DISABLE_EXCEPTION)
|
||||
add_definitions(-DBOOST_ASIO_ENABLE_CANCELIO)
|
||||
|
||||
if (tcmalloc)
|
||||
target_link_libraries(torrent-rasterbar tcmalloc)
|
||||
endif (tcmalloc)
|
||||
|
||||
target_link_libraries(torrent-rasterbar z)
|
||||
include_directories(${includes})
|
||||
|
||||
set_target_properties(torrent-rasterbar PROPERTIES
|
||||
SOVERSION 1
|
||||
VERSION 1)
|
||||
|
||||
set (VERSION "0.16.0")
|
||||
|
||||
get_property (COMPILETIME_OPTIONS_LIST
|
||||
DIRECTORY ${CMAKE_CURRENT_SOURCE_DIRECTORY}
|
||||
PROPERTY COMPILE_DEFINITIONS
|
||||
)
|
||||
foreach (s ${COMPILETIME_OPTIONS_LIST})
|
||||
set (COMPILETIME_OPTIONS "${COMPILETIME_OPTIONS} -D${s}")
|
||||
endforeach (s)
|
||||
|
||||
configure_file(libtorrent-rasterbar-cmake.pc.in libtorrent-rasterbar.pc)
|
||||
|
||||
string (COMPARE EQUAL ${CMAKE_SIZEOF_VOID_P} "8" IS64BITS)
|
||||
|
||||
if (IS64BITS AND RESPECTLIB64)
|
||||
set (LIBDIR "lib64")
|
||||
else (IS64BITS AND RESPECTLIB64)
|
||||
set (LIBDIR "lib")
|
||||
endif (IS64BITS AND RESPECTLIB64)
|
||||
|
||||
install(TARGETS torrent-rasterbar DESTINATION ${LIBDIR} CONFIGURATIONS release)
|
||||
install(DIRECTORY include/libtorrent
|
||||
DESTINATION include
|
||||
PATTERN ".svn" EXCLUDE)
|
||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libtorrent-rasterbar.pc DESTINATION ${LIBDIR}/pkgconfig)
|
||||
|
||||
# === build examples ===
|
||||
if(build_examples)
|
||||
set(examples client_test dump_torrent simple_client enum_if make_torrent)
|
||||
|
||||
foreach(s ${examples})
|
||||
add_executable(${s} examples/${s}.cpp)
|
||||
target_link_libraries(${s} torrent-rasterbar)
|
||||
endforeach(s)
|
||||
|
||||
FIND_PACKAGE( Boost 1.34 COMPONENTS program_options regex)
|
||||
target_link_libraries(client_test ${Boost_LIBRARIES})
|
||||
include_directories(${Boost_INCLUDE_DIR})
|
||||
endif(build_examples)
|
||||
# === build tests ===
|
||||
if(build_tests)
|
||||
set(tests
|
||||
test_auto_unchoke
|
||||
test_http_connection
|
||||
test_buffer
|
||||
test_storage
|
||||
test_torrent
|
||||
test_dht
|
||||
test_transfer
|
||||
test_piece_picker
|
||||
test_fast_extension
|
||||
test_pe_crypto
|
||||
test_bencoding
|
||||
test_bdecode_performance
|
||||
test_primitives
|
||||
test_ip_filter
|
||||
test_hasher
|
||||
test_metadata_extension
|
||||
test_swarm
|
||||
test_lsd
|
||||
test_pex
|
||||
test_web_seed
|
||||
test_bandwidth_limiter
|
||||
)
|
||||
|
||||
add_library(test_common STATIC test/main.cpp test/setup_transfer.cpp)
|
||||
enable_testing()
|
||||
|
||||
foreach(s ${tests})
|
||||
add_executable(${s} test/${s}.cpp)
|
||||
target_link_libraries(${s} torrent-rasterbar test_common)
|
||||
add_test(${s} ${s})
|
||||
endforeach(s)
|
||||
|
||||
add_executable(test_upnp test/test_upnp.cpp)
|
||||
target_link_libraries(test_upnp torrent-rasterbar)
|
||||
|
||||
add_executable(test_natpmp test/test_natpmp.cpp)
|
||||
target_link_libraries(test_natpmp torrent-rasterbar)
|
||||
endif(build_tests)
|
|
@ -1,28 +0,0 @@
|
|||
Copyright (c) 2003 - 2007, Arvid Norberg
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of Rasterbar Software nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
|
@ -1,772 +0,0 @@
|
|||
* support DHT name lookup
|
||||
* optimized memory usage of torrent_info and file_storage, forcing some API changes
|
||||
around file_storage and file_entry
|
||||
* support trackerid tracker extension
|
||||
* graceful peer disconnect mode which finishes transactions before disconnecting peers
|
||||
* support chunked encoding for web seeds
|
||||
* uTP protocol support
|
||||
* resistance towards certain flood attacks
|
||||
* support chunked encoding for web seeds (only for BEP 19, web seeds)
|
||||
* optimized session startup time
|
||||
* support SSL for web seeds, through all proxies
|
||||
* support extending web seeds with custom authorization and extra headers
|
||||
* settings that are not changed from the default values are not saved
|
||||
in the session state
|
||||
* made seeding choking algorithm configurable
|
||||
* deprecated setters for max connections, max half-open, upload and download
|
||||
rates and unchoke slots. These are now set through session_settings
|
||||
* added functions to query an individual peer's upload and download limit
|
||||
* full support for BEP 21 (event=paused)
|
||||
* added share-mode feature for improving share ratios
|
||||
* merged all proxy settings into a single one
|
||||
* improved SOCKS5 support by proxying hostname lookups
|
||||
* improved support for multi-homed clients
|
||||
* added feature to not count downloaded bytes from web seeds in stats
|
||||
* added alert for incoming local service discovery messages
|
||||
* added option to set file priorities when adding torrents
|
||||
* removed the session mutex for improved performance
|
||||
* added upload and download activity timer stats for torrents
|
||||
* made the reuse-address flag configurable on the listen socket
|
||||
* moved UDP trackers over to use a single socket
|
||||
* added feature to make asserts log to a file instead of breaking the process
|
||||
(production asserts)
|
||||
* optimized disk I/O cache clearing
|
||||
* added feature to ask a torrent if it needs to save its resume data or not
|
||||
* added setting to ignore file modification time when loading resume files
|
||||
* support more fine-grained torrent states between which peer sources it
|
||||
announces to
|
||||
* supports calculating sha1 file-hashes when creating torrents
|
||||
* made the send_buffer_watermark performance warning more meaningful
|
||||
* supports complete_ago extension
|
||||
* dropped zlib as a dependency and builds using puff.c instead
|
||||
* made the default cache size depend on available physical RAM
|
||||
* added flags to torrent::status() that can filter which values are calculated
|
||||
* support 'explicit read cache' which keeps a specific set of pieces
|
||||
in the read cache, without implicitly caching other pieces
|
||||
* support sending suggest messages based on what's in the read cache
|
||||
* clear sparse flag on files that complete on windows
|
||||
* support retry-after header for web seeds
|
||||
* replaced boost.filesystem with custom functions
|
||||
* replaced dependency on boost.thread by asio's internal thread primitives
|
||||
* added support for i2p torrents
|
||||
* cleaned up usage of MAX_PATH and related macros
|
||||
* made it possible to build libtorrent without RTTI support
|
||||
* added support to build with libgcrypt and a shipped version of libtommath
|
||||
* optimized DHT routing table memory usage
|
||||
* optimized disk cache to work with large caches
|
||||
* support variable number of optimistic unchoke slots and to dynamically
|
||||
adjust based on the total number of unchoke slots
|
||||
* support for BitTyrant choker algorithm
|
||||
* support for automatically start torrents when they receive an
|
||||
incoming connection
|
||||
* added more detailed instrumentation of the disk I/O thread
|
||||
|
||||
* limit number of torrents tracked by DHT
|
||||
* fixed bug when allow_multiple_connections_per_ip was enabled
|
||||
* potential WOW64 fix for unbuffered I/O (windows)
|
||||
* expose set_alert_queue_size_limit to python binding
|
||||
* support dht nodes in magnet links
|
||||
* support 100 Continue HTTP responses
|
||||
* changed default choker behavior to use 8 unchoke slots (instead of being rate based)
|
||||
* fixed error reporting issue in disk I/O thread
|
||||
* fixed file allocation issues on linux
|
||||
* fixed filename encoding and decoding issue on platforms using iconv
|
||||
* reports redundant downloads to tracker, fixed downloaded calculation to
|
||||
be more stable when not including redundant. Improved redundant data accounting
|
||||
to be more accurate
|
||||
* fixed bugs in http seed connection and added unit test for it
|
||||
* fixed error reporting when fallocate fails
|
||||
* deprecate support for separate proxies for separate kinds of connections
|
||||
|
||||
0.15.4 release
|
||||
|
||||
* fixed piece picker issue triggered by hash failure and timed out requests to the piece
|
||||
* fixed optimistic unchoke issue when setting per torrent unchoke limits
|
||||
* fixed UPnP shutdown issue
|
||||
* fixed UPnP DeletePortmapping issue
|
||||
* fixed NAT-PMP issue when adding the same mapping multiple times
|
||||
* no peers from tracker when stopping is no longer an error
|
||||
* improved web seed retry behavior
|
||||
* fixed announce issue
|
||||
|
||||
0.15.3 release
|
||||
|
||||
* fixed announce bug where event=completed would not be sent if it violated the
|
||||
min-announce of the tracker
|
||||
* fixed limitation in rate limiter
|
||||
* fixed build error with boost 1.44
|
||||
|
||||
0.15.2 release
|
||||
|
||||
* updated compiler to msvc 2008 for python binding
|
||||
* restored default fail_limit to unlimited on all trackers
|
||||
* fixed rate limit bug for DHT
|
||||
* fixed SOCKS5 bug for routing UDP packets
|
||||
* fixed bug on windows when verifying resume data for a torrent where
|
||||
one of its directories had been removed
|
||||
* fixed race condition in peer-list with DHT
|
||||
* fix force-reannounce and tracker retry issue
|
||||
|
||||
0.15.1 release
|
||||
|
||||
* fixed rare crash when purging the peer list
|
||||
* fixed race condition around m_abort in session_impl
|
||||
* fixed bug in web_peer_connection which could cause a hang when downloading
|
||||
from web servers
|
||||
* fixed bug in metadata extensions combined with encryption
|
||||
* refactored socket reading code to not use async. operations unnecessarily
|
||||
* some timer optimizations
|
||||
* removed the reuse-address flag on the listen socket
|
||||
* fixed bug where local peer discovery and DHT wouldn't be announced to without trackers
|
||||
* fixed bug in bdecoder when decoding invalid messages
|
||||
* added build warning when building with UNICODE but the standard library
|
||||
doesn't provide std::wstring
|
||||
* fixed add_node python binding
|
||||
* fixed issue where trackers wouldn't tried immediately when the previous one failed
|
||||
* fixed synchronization issue between download queue and piece picker
|
||||
* fixed bug in udp tracker scrape response parsing
|
||||
* fixed bug in the disk thread that could get triggered under heavy load
|
||||
* fixed bug in add_piece() that would trigger asserts
|
||||
* fixed vs 2010 build
|
||||
* recognizes more clients in identify_client()
|
||||
* fixed bug where trackers wouldn't be retried if they failed
|
||||
* slight performance fix in disk elevator algorithm
|
||||
* fixed potential issue where a piece could be checked twice
|
||||
* fixed build issue on windows related to GetCompressedSize()
|
||||
* fixed deadlock when starting torrents with certain invalid tracker URLs
|
||||
* fixed iterator bug in disk I/O thread
|
||||
* fixed FIEMAP support on linux
|
||||
* fixed strict aliasing warning on gcc
|
||||
* fixed inconsistency when creating torrents with symlinks
|
||||
* properly detect windows version to initialize half-open connection limit
|
||||
* fixed bug in url encoder where $ would not be encoded
|
||||
|
||||
0.15 release
|
||||
|
||||
* introduced a session state save mechanism. load_state() and save_state().
|
||||
this saves all session settings and state (except torrents)
|
||||
* deprecated dht_state functions and merged it with the session state
|
||||
* added support for multiple trackers in magnet links
|
||||
* added support for explicitly flushing the disk cache
|
||||
* added torrent priority to affect bandwidth allocation for its peers
|
||||
* reduced the number of floating point operations (to better support
|
||||
systems without FPU)
|
||||
* added new alert when individual files complete
|
||||
* added support for storing symbolic links in .torrent files
|
||||
* added support for uTorrent interpretation of multi-tracker torrents
|
||||
* handle torrents with duplicate filenames
|
||||
* piece timeouts are adjusted to download rate limits
|
||||
* encodes urls in torrent files that needs to be encoded
|
||||
* fixed not passing &supportcrypto=1 when encryption is disabled
|
||||
* introduced an upload mode, which torrents are switched into when
|
||||
it hits a disk write error, instead of stopping the torrent.
|
||||
this lets libtorrent keep uploading the parts it has when it
|
||||
encounters a disk-full error for instance
|
||||
* improved disk error handling and expanded use of error_code in
|
||||
error reporting. added a bandwidth state, bw_disk, when waiting
|
||||
for the disk io thread to catch up writing buffers
|
||||
* improved read cache memory efficiency
|
||||
* added another cache flush algorithm to write the largest
|
||||
contiguous blocks instead of the least recently used
|
||||
* introduced a mechanism to be lighter on the disk when checking torrents
|
||||
* applied temporary memory storage optimization to when checking
|
||||
a torrent as well
|
||||
* removed hash_for_slot() from storage_interface. It is now implemented
|
||||
by using the readv() function from the storage implementation
|
||||
* improved IPv6 support by announcing twice when necessary
|
||||
* added feature to set a separate global rate limit for local peers
|
||||
* added preset settings for low memory environments and seed machines
|
||||
min_memory_usage() and high_performance_seeder()
|
||||
* optimized overall memory usage for DHT nodes and requests, peer
|
||||
entries and disk buffers
|
||||
* change in API for block_info in partial_piece_info, instead of
|
||||
accessing 'peer', call 'peer()'
|
||||
* added support for fully automatic unchoker (no need to specify
|
||||
number of upload slots). This is on by default
|
||||
* added support for changing socket buffer sizes through
|
||||
session_settings
|
||||
* added support for merkle hash tree torrents (.merkle.torrent)
|
||||
* added 'seed mode', which assumes that all files are complete
|
||||
and checks hashes lazily, as blocks are requested
|
||||
* added new extension for file attributes (executable and hidden)
|
||||
* added support for unbuffered I/O for aligned files
|
||||
* added workaround for sparse file issue on Windows Vista
|
||||
* added new lt_trackers extension to exchange trackers between
|
||||
peers
|
||||
* added support for BEP 17 http seeds
|
||||
* added read_piece() to read pieces from torrent storage
|
||||
* added option for udp tracker preference
|
||||
* added super seeding
|
||||
* added add_piece() function to inject data from external sources
|
||||
* add_tracker() function added to torrent_handle
|
||||
* if there is no working tracker, current_tracker is the
|
||||
tracker that is currently being tried
|
||||
* torrents that are checking can now be paused, which will
|
||||
pause the checking
|
||||
* introduced another torrent state, checking_resume_data, which
|
||||
the torrent is in when it's first added, and is comparing
|
||||
the files on disk with the resume data
|
||||
* DHT bandwidth usage optimizations
|
||||
* rate limited DHT send socket
|
||||
* tracker connections are now also subject to IP filtering
|
||||
* improved optimistic unchoke logic
|
||||
* added monitoring of the DHT lookups
|
||||
* added bandwidth reports for estimated TCP/IP overhead and DHT
|
||||
* includes DHT traffic in the rate limiter
|
||||
* added support for bitcomet padding files
|
||||
* improved support for sparse files on windows
|
||||
* added ability to give seeding torrents preference to active slots
|
||||
* added torrent_status::finished_time
|
||||
* automatically caps files and connections by default to rlimit
|
||||
* added session::is_dht_running() function
|
||||
* added torrent_handle::force_dht_announce()
|
||||
* added torrent_info::remap_files()
|
||||
* support min_interval tracker extension
|
||||
* added session saving and loading functions
|
||||
* added support for min-interval in tracker responses
|
||||
* only keeps one outstanding duplicate request per peer
|
||||
reduces waste download, specifically when streaming
|
||||
* added support for storing per-peer rate limits across reconnects
|
||||
* improved fallocate support
|
||||
* fixed magnet link issue when using resume data
|
||||
* support disk I/O priority settings
|
||||
* added info_hash to torrent_deleted_alert
|
||||
* improved LSD performance and made the interval configurable
|
||||
* improved UDP tracker support by caching connect tokens
|
||||
* fast piece optimization
|
||||
|
||||
release 0.14.10
|
||||
|
||||
* fixed udp tracker race condition
|
||||
* added support for torrents with odd piece sizes
|
||||
* fixed issue with disk read cache not being cleared when removing torrents
|
||||
* made the DHT socket bind to the same interface as the session
|
||||
* fixed issue where an http proxy would not be used on redirects
|
||||
* Solaris build fixes
|
||||
* disabled buggy disconnect_peers feature
|
||||
|
||||
release 0.14.9
|
||||
|
||||
* disabled feature to drop requests after having been skipped too many times
|
||||
* fixed range request bug for files larger than 2 GB in web seeds
|
||||
* don't crash when trying to create torrents with 0 files
|
||||
* fixed big_number __init__ in python bindings
|
||||
* fixed optimistic unchoke timer
|
||||
* fixed bug where torrents with incorrectly formatted web seed URLs would be
|
||||
connected multiple times
|
||||
* fixed MinGW support
|
||||
* fixed DHT bootstrapping issue
|
||||
* fixed UDP over SOCKS5 issue
|
||||
* added support for "corrupt" tracker announce
|
||||
* made end-game mode less aggressive
|
||||
|
||||
release 0.14.8
|
||||
|
||||
* ignore unkown metadata messages
|
||||
* fixed typo that would sometimes prevent queued torrents to be checked
|
||||
* fixed bug in auto-manager where active_downloads and active_seeds would
|
||||
sometimes be used incorrectly
|
||||
* force_recheck() no longer crashes on torrents with no metadata
|
||||
* fixed broadcast socket regression from 0.14.7
|
||||
* fixed hang in NATPMP when shut down while waiting for a response
|
||||
* fixed some more error handling in bdecode
|
||||
|
||||
release 0.14.7
|
||||
|
||||
* fixed deadlock in natpmp
|
||||
* resume data alerts are always posted, regardless of alert mask
|
||||
* added wait_for_alert to python binding
|
||||
* improved invalid filename character replacement
|
||||
* improved forward compatibility in DHT
|
||||
* added set_piece_hashes that takes a callback to the python binding
|
||||
* fixed division by zero in get_peer_info()
|
||||
* fixed bug where pieces may have been requested before the metadata
|
||||
was received
|
||||
* fixed incorrect error when deleting files from a torrent where
|
||||
not all files have been created
|
||||
* announces torrents immediately to the DHT when it's started
|
||||
* fixed bug in add_files that would fail to recurse if the path
|
||||
ended with a /
|
||||
* fixed bug in error handling when parsing torrent files
|
||||
* fixed file checking bug when renaming a file before checking the torrent
|
||||
* fixed race conditon when receiving metadata from swarm
|
||||
* fixed assert in ut_metadata plugin
|
||||
* back-ported some fixes for building with no exceptions
|
||||
* fixed create_torrent when passing in a path ending with /
|
||||
* fixed move_storage when source doesn't exist
|
||||
* fixed DHT state save bug for node-id
|
||||
* fixed typo in python binding session_status struct
|
||||
* broadcast sockets now join every network interface (used for UPnP and
|
||||
local peer discovery)
|
||||
|
||||
release 0.14.6
|
||||
|
||||
* various missing include fixes to be buildable with boost 1.40
|
||||
* added missing functions to python binding related to torrent creation
|
||||
* fixed to add filename on web seed urls that lack it
|
||||
* fixed BOOST_ASIO_HASH_MAP_BUCKETS define for boost 1.39
|
||||
* fixed checking of fast and suggest messages when used with magnet links
|
||||
* fixed bug where web seeds would not disconnect if being resolved when
|
||||
the torrent was paused
|
||||
* fixed download piece performance bug in piece picker
|
||||
* fixed bug in connect candidate counter
|
||||
* replaces invalid filename characters with .
|
||||
* added --with-libgeoip option to configure script to allow building and
|
||||
linking against system wide library
|
||||
* fixed potential pure virtual function call in extensions on shutdown
|
||||
* fixed disk buffer leak in smart_ban extension
|
||||
|
||||
release 0.14.5
|
||||
|
||||
* fixed bug when handling malformed webseed urls and an http proxy
|
||||
* fixed bug when setting unlimited upload or download rates for torrents
|
||||
* fix to make torrent_status::list_peers more accurate.
|
||||
* fixed memory leak in disk io thread when not using the cache
|
||||
* fixed bug in connect candidate counter
|
||||
* allow 0 upload slots
|
||||
* fixed bug in rename_file(). The new name would not always be saved in
|
||||
the resume data
|
||||
* fixed resume data compatibility with 0.13
|
||||
* fixed rare piece-picker bug
|
||||
* fixed bug where one allowed-fast message would be sent even when
|
||||
disabled
|
||||
* fixed race condition in UPnP which could lead to crash
|
||||
* fixed inversed seed_time ratio logic
|
||||
* added get_ip_filter() to session
|
||||
|
||||
release 0.14.4
|
||||
|
||||
* connect candidate calculation fix
|
||||
* tightened up disk cache memory usage
|
||||
* fixed magnet link parser to accept hex-encoded info-hashes
|
||||
* fixed inverted logic when picking which peers to connect to
|
||||
(should mean a slight performance improvement)
|
||||
* fixed a bug where a failed rename_file() would leave the storage
|
||||
in an error state which would pause the torrent
|
||||
* fixed case when move_storage() would fail. Added a new alert
|
||||
to be posted when it does
|
||||
* fixed crash bug when shutting down while checking a torrent
|
||||
* fixed handling of web seed urls that didn't end with a
|
||||
slash for multi-file torrents
|
||||
* lowered the default connection speed to 10 connection attempts
|
||||
per second
|
||||
* optimized memory usage when checking files fails
|
||||
* fixed bug when checking a torrent twice
|
||||
* improved handling of out-of-memory conditions in disk I/O thread
|
||||
* fixed bug when force-checking a torrent with partial pieces
|
||||
* fixed memory leak in disk cache
|
||||
* fixed torrent file path vulnerability
|
||||
* fixed upnp
|
||||
* fixed bug when dealing with clients that drop requests (i.e. BitComet)
|
||||
fixes assert as well
|
||||
|
||||
release 0.14.3
|
||||
|
||||
* added python binding for create_torrent
|
||||
* fixed boost-1.38 build
|
||||
* fixed bug where web seeds would be connected before the files
|
||||
were checked
|
||||
* fixed filename bug when using wide characters
|
||||
* fixed rare crash in peer banning code
|
||||
* fixed potential HTTP compatibility issue
|
||||
* fixed UPnP crash
|
||||
* fixed UPnP issue where the control url contained the base url
|
||||
* fixed a replace_trackers bug
|
||||
* fixed bug where the DHT port mapping would not be removed when
|
||||
changing DHT port
|
||||
* fixed move_storage bug when files were renamed to be moved out
|
||||
of the root directory
|
||||
* added error handling for set_piece_hashes
|
||||
* fixed missing include in enum_if.cpp
|
||||
* fixed dual IP stack issue
|
||||
* fixed issue where renamed files were sometimes not saved in resume data
|
||||
* accepts tracker responses with no 'peers' field, as long as 'peers6'
|
||||
is present
|
||||
* fixed CIDR-distance calculation in the precense of IPv6 peers
|
||||
* save partial resume data for torrents that are queued for checking
|
||||
or checking, to maintain stats and renamed files
|
||||
* Don't try IPv6 on windows if it's not installed
|
||||
* move_storage fix
|
||||
* fixed potential crash on shutdown
|
||||
* fixed leaking exception from bdecode on malformed input
|
||||
* fixed bug where connection would hang when receiving a keepalive
|
||||
* fixed bug where an asio exception could be thrown when resolving
|
||||
peer countries
|
||||
* fixed crash when shutting down while checking a torrent
|
||||
* fixed potential crash in connection_queue when a peer_connection
|
||||
fail to open its socket
|
||||
|
||||
release 0.14.2
|
||||
|
||||
* added missing functions to the python bindings torrent_info::map_file,
|
||||
torrent_info::map_block and torrent_info::file_at_offset.
|
||||
* removed support for boost-1.33 and earlier (probably didn't work)
|
||||
* fixed potential freezes issues at shutdown
|
||||
* improved error message for python setup script
|
||||
* fixed bug when torrent file included announce-list, but no valid
|
||||
tracker urls
|
||||
* fixed bug where the files requested from web seeds would be the
|
||||
renamed file names instead of the original file names in the torrent.
|
||||
* documentation fix of queing section
|
||||
* fixed potential issue in udp_socket (affected udp tracker support)
|
||||
* made name, comment and created by also be subject to utf-8 error
|
||||
correction (filenames already were)
|
||||
* fixed dead-lock when settings DHT proxy
|
||||
* added missing export directives to lazy_entry
|
||||
* fixed disk cache expiry settings bug (if changed, it would be set
|
||||
to the cache size)
|
||||
* fixed bug in http_connection when binding to a particular IP
|
||||
* fixed typo in python binding (torrent_handle::piece_prioritize should
|
||||
be torrent_handle::piece_priorities)
|
||||
* fixed race condition when saving DHT state
|
||||
* fixed bugs related to lexical_cast being locale dependent
|
||||
* added support for SunPro C++ compiler
|
||||
* fixed bug where messeges sometimes could be encrypted in the
|
||||
wrong order, for encrypted connections.
|
||||
* fixed race condition where torrents could get stuck waiting to
|
||||
get checked
|
||||
* fixed mapped files bug where it wouldn't be properly restored
|
||||
from resume data properly
|
||||
* removed locale dependency in xml parser (caused asserts on windows)
|
||||
* fixed bug when talking to https 1.0 servers
|
||||
* fixed UPnP bug that could cause stack overflow
|
||||
|
||||
release 0.14.1
|
||||
|
||||
* added converter for python unicode strings to utf-8 paths
|
||||
* fixed bug in http downloader where the host field did not
|
||||
include the port number
|
||||
* fixed headers to not depend on NDEBUG, which would prohibit
|
||||
linking a release build of libtorrent against a debug application
|
||||
* fixed bug in disk I/O thread that would make the thread
|
||||
sometimes quit when an error occurred
|
||||
* fixed DHT bug
|
||||
* fixed potential shutdown crash in disk_io_thread
|
||||
* fixed usage of deprecated boost.filsystem functions
|
||||
* fixed http_connection unit test
|
||||
* fixed bug in DHT when a DHT state was loaded
|
||||
* made rate limiter change in 0.14 optional (to take estimated
|
||||
TCP/IP overhead into account)
|
||||
* made the python plugin buildable through the makefile
|
||||
* fixed UPnP bug when url base ended with a slash and
|
||||
path started with a slash
|
||||
* fixed various potentially leaking exceptions
|
||||
* fixed problem with removing torrents that are checking
|
||||
* fixed documentation bug regarding save_resume_data()
|
||||
* added missing documentation on torrent creation
|
||||
* fixed bugs in python client examples
|
||||
* fixed missing dependency in package-config file
|
||||
* fixed shared geoip linking in Jamfile
|
||||
* fixed python bindings build on windows and made it possible
|
||||
to generate a windows installer
|
||||
* fixed bug in NAT-PMP implementation
|
||||
|
||||
release 0.14
|
||||
|
||||
* deprecated add_torrent() in favor of a new add_torrent()
|
||||
that takes a struct with parameters instead. Torrents
|
||||
are paused and auto managed by default.
|
||||
* removed 'connecting_to_tracker' torrent state. This changes
|
||||
the enum values for the other states.
|
||||
* Improved seeding and choking behavior.
|
||||
* Fixed rare buffer overrun bug when calling get_download_queue
|
||||
* Fixed rare bug where torrent could be put back into downloading
|
||||
state even though it was finished, after checking files.
|
||||
* Fixed rename_file to work before the file on disk has been
|
||||
created.
|
||||
* Fixed bug in tracker connections in case of errors caused
|
||||
in the connection constructor.
|
||||
* Updated alert system to be filtered by category instead of
|
||||
severity level. Alerts can generate a message through
|
||||
alert::message().
|
||||
* Session constructor will now start dht, upnp, natpmp, lsd by
|
||||
default. Flags can be passed in to the constructor to not
|
||||
do this, if these features are to be enabled and disabled
|
||||
at a later point.
|
||||
* Removed 'connecting_to_tracker' torrent state
|
||||
* Fix bug where FAST pieces were cancelled on choke
|
||||
* Fixed problems with restoring piece states when hash failed.
|
||||
* Minimum peer reconnect time fix. Peers with no failures would
|
||||
reconnect immediately.
|
||||
* Improved web seed error handling
|
||||
* DHT announce fixes and off-by-one loop fix
|
||||
* Fixed UPnP xml parse bug where it would ignore the port number
|
||||
for the control url.
|
||||
* Fixed bug in torrent writer where the private flag was added
|
||||
outside of the info dictionary
|
||||
* Made the torrent file parser less strict of what goes in the
|
||||
announce-list entry
|
||||
* Fixed type overflow bug where some statistics was incorrectly
|
||||
reported for file larger than 2 GB
|
||||
* boost-1.35 support
|
||||
* Fixed bug in statistics from web server peers where it sometimes
|
||||
could report too many bytes downloaded.
|
||||
* Fixed bug where statistics from the last second was lost when
|
||||
disconnecting a peer.
|
||||
* receive buffer optimizations (memcpy savings and memory savings)
|
||||
* Support for specifying the TOS byte for peer traffic.
|
||||
* Basic support for queueing of torrents.
|
||||
* Better bias to give connections to downloading torrents
|
||||
with fewer peers.
|
||||
* Optimized resource usage (removed the checking thread)
|
||||
* Support to bind outgoing connections to specific ports
|
||||
* Disk cache support.
|
||||
* New, more memory efficient, piece picker with sequential download
|
||||
support (instead of the more complicated sequential download threshold).
|
||||
* Auto Upload slots. Automtically opens up more slots if
|
||||
upload limit is not met.
|
||||
* Improved NAT-PMP support by querying the default gateway
|
||||
* Improved UPnP support by ignoring routers not on the clients subnet.
|
||||
|
||||
release 0.13
|
||||
|
||||
* Added scrape support
|
||||
* Added add_extension() to torrent_handle. Can instantiate
|
||||
extensions for torrents while downloading
|
||||
* Added support for remove_torrent to delete the files as well
|
||||
* Fixed issue with failing async_accept on windows
|
||||
* DHT improvements, proper error messages are now returned when
|
||||
nodes sends bad packets
|
||||
* Optimized the country table used to resolve country of peers
|
||||
* Copying optimization for sending data. Data is no longer copied from
|
||||
the disk I/O buffer to the send buffer.
|
||||
* Buffer optimization to use a raw buffer instead of std::vector<char>
|
||||
* Improved file storage to use sparse files
|
||||
* Updated python bindings
|
||||
* Added more clients to the identifiable clients list.
|
||||
* Torrents can now be started in paused state (to better support queuing)
|
||||
* Improved IPv6 support (support for IPv6 extension to trackers and
|
||||
listens on both IPv6 and IPv4 interfaces).
|
||||
* Improved asserts used. Generates a stacktrace on linux
|
||||
* Piece picker optimizations and improvements
|
||||
* Improved unchoker, connection limit and rate limiter
|
||||
* Support for FAST extension
|
||||
* Fixed invalid calculation in DHT node distance
|
||||
* Fixed bug in URL parser that failed to parse IPv6 addresses
|
||||
* added peer download rate approximation
|
||||
* added port filter for outgoing connection (to prevent
|
||||
triggering firewalls)
|
||||
* made most parameters configurable via session_settings
|
||||
* added encryption support
|
||||
* added parole mode for peers whose data fails the hash check.
|
||||
* optimized heap usage in piece-picker and web seed downloader.
|
||||
* fixed bug in DHT where older write tokens weren't accepted.
|
||||
* added support for sparse files.
|
||||
* introduced speed categories for peers and pieces, to separate
|
||||
slow and fast peers.
|
||||
* added a half-open tcp connection limit that takes all connections
|
||||
in to account, not just peer connections.
|
||||
* added alerts for filtered IPs.
|
||||
* added support for SOCKS4 and 5 proxies and HTTP CONNECT proxies.
|
||||
* fixed proper distributed copies calculation.
|
||||
* added option to use openssl for sha-1 calculations.
|
||||
* optimized the piece picker in the case where a peer is a seed.
|
||||
* added support for local peer discovery
|
||||
* removed the dependency on the compiled boost.date_time library
|
||||
* deprecated torrent_info::print()
|
||||
* added UPnP support
|
||||
* fixed problem where peer interested flags were not updated correctly
|
||||
when pieces were filtered
|
||||
* improvements to ut_pex messages, including support for seed flag
|
||||
* prioritizes upload bandwidth to peers that might send back data
|
||||
* the following functions have been deprecated:
|
||||
void torrent_handle::filter_piece(int index, bool filter) const;
|
||||
void torrent_handle::filter_pieces(std::vector<bool> const& pieces) const;
|
||||
bool torrent_handle::is_piece_filtered(int index) const;
|
||||
std::vector<bool> torrent_handle::filtered_pieces() const;
|
||||
void torrent_handle::filter_files(std::vector<bool> const& files) const;
|
||||
|
||||
instead, use the piece_priority functions.
|
||||
|
||||
* added support for NAT-PMP
|
||||
* added support for piece priorities. Piece filtering is now set as
|
||||
a priority
|
||||
* Fixed crash when last piece was smaller than one block and reading
|
||||
fastresume data for that piece
|
||||
* Makefiles should do a better job detecting boost
|
||||
* Fixed crash when all tracker urls are removed
|
||||
* Log files can now be created at user supplied path
|
||||
* Log files failing to create is no longer fatal
|
||||
* Fixed dead-lock in torrent_handle
|
||||
* Made it build with boost 1.34 on windows
|
||||
* Fixed bug in URL parser that failed to parse IPv6 addresses
|
||||
* Fixed bug in DHT, related to IPv6 nodes
|
||||
* DHT accepts transaction IDs that have garbage appended to them
|
||||
* DHT logs messages that it fails to decode
|
||||
|
||||
release 0.12
|
||||
|
||||
* fixes to make the DHT more compatible
|
||||
* http seed improvements including error reporting and url encoding issues.
|
||||
* fixed bug where directories would be left behind when moving storage
|
||||
in some cases.
|
||||
* fixed crashing bug when restarting or stopping the DHT.
|
||||
* added python binding, using boost.python
|
||||
* improved character conversion on windows when strings are not utf-8.
|
||||
* metadata extension now respects the private flag in the torrent.
|
||||
* made the DHT to only be used as a fallback to trackers by default.
|
||||
* added support for HTTP redirection support for web seeds.
|
||||
* fixed race condition when accessing a torrent that was checking its
|
||||
fast resume data.
|
||||
* fixed a bug in the DHT which could be triggered if the network was
|
||||
dropped or extremely rare cases.
|
||||
* if the download rate is limited, web seeds will now only use left-over
|
||||
bandwidth after all bt peers have used up as much bandwidth as they can.
|
||||
* added the possibility to have libtorrent resolve the countries of
|
||||
the peers in torrents.
|
||||
* improved the bandwidth limiter (it now implements a leaky bucket/node bucket).
|
||||
* improved the HTTP seed downloader to report accurate progress.
|
||||
* added more client peer-id signatures to be recognized.
|
||||
* added support for HTTP servers that skip the CR before the NL at line breaks.
|
||||
* fixed bug in the HTTP code that only accepted headers case sensitive.
|
||||
* fixed bug where one of the session constructors didn't initialize boost.filesystem.
|
||||
* fixed bug when the initial checking of a torrent fails with an exception.
|
||||
* fixed bug in DHT code which would send incorrect announce messages.
|
||||
* fixed bug where the http header parser was case sensitive to the header
|
||||
names.
|
||||
* Implemented an optmization which frees the piece_picker once a torrent
|
||||
turns into a seed.
|
||||
* Added support for uT peer exchange extension, implemented by Massaroddel.
|
||||
* Modified the quota management to offer better bandwidth balancing
|
||||
between peers.
|
||||
* logging now supports multiple sessions (different sessions now log
|
||||
to different directories).
|
||||
* fixed random number generator seed problem, generating the same
|
||||
peer-id for sessions constructed the same second.
|
||||
* added an option to accept multiple connections from the same IP.
|
||||
* improved tracker logging.
|
||||
* moved the file_pool into session. The number of open files is now
|
||||
limited per session.
|
||||
* fixed uninitialized private flag in torrent_info
|
||||
* fixed long standing issue with file.cpp on windows. Replaced the low level
|
||||
io functions used on windows.
|
||||
* made it possible to associate a name with torrents without metadata.
|
||||
* improved http-downloading performance by requesting entire pieces via
|
||||
http.
|
||||
* added plugin interface for extensions. And changed the interface for
|
||||
enabling extensions.
|
||||
|
||||
release 0.11
|
||||
|
||||
* added support for incorrectly encoded paths in torrent files
|
||||
(assumes Latin-1 encoding and converts to UTF-8).
|
||||
* added support for destructing session objects asynchronously.
|
||||
* fixed bug with file_progress() with files = 0 bytes
|
||||
* fixed a race condition bug in udp_tracker_connection that could
|
||||
cause a crash.
|
||||
* fixed bug occuring when increasing the sequenced download threshold
|
||||
with max availability lower than previous threshold.
|
||||
* fixed an integer overflow bug occuring when built with gcc 4.1.x
|
||||
* fixed crasing bug when closing while checking a torrent
|
||||
* fixed bug causing a crash with a torrent with piece length 0
|
||||
* added an extension to the DHT network protocol to support the
|
||||
exchange of nodes with IPv6 addresses.
|
||||
* modified the ip_filter api slightly to support IPv6
|
||||
* modified the api slightly to make sequenced download threshold
|
||||
a per torrent-setting.
|
||||
* changed the address type to support IPv6
|
||||
* fixed bug in piece picker which would not behave as
|
||||
expected with regard to sequenced download threshold.
|
||||
* fixed bug with file_progress() with files > 2 GB.
|
||||
* added --enable-examples option to configure script.
|
||||
* fixed problem with the resource distribution algorithm
|
||||
(controlling e.g upload/download rates).
|
||||
* fixed incorrect asserts in storage related to torrents with
|
||||
zero-sized files.
|
||||
* added support for trackerless torrents (with kademlia DHT).
|
||||
* support for torrents with the private flag set.
|
||||
* support for torrents containing bootstrap nodes for the
|
||||
DHT network.
|
||||
* fixed problem with the configure script on FreeBSD.
|
||||
* limits the pipelining used on url-seeds.
|
||||
* fixed problem where the shutdown always would delay for
|
||||
session_settings::stop_tracker_timeout seconds.
|
||||
* session::listen_on() won't reopen the socket in case the port and
|
||||
interface is the same as the one currently in use.
|
||||
* added http proxy support for web seeds.
|
||||
* fixed problem where upload and download stats could become incorrect
|
||||
in case of high cpu load.
|
||||
* added more clients to the identifiable list.
|
||||
* fixed fingerprint parser to cope with latest Mainline versions.
|
||||
|
||||
release 0.10
|
||||
|
||||
* fixed a bug where the requested number of peers in a tracker request could
|
||||
be too big.
|
||||
* fixed a bug where empty files were not created in full allocation mode.
|
||||
* fixed a bug in storage that would, in rare cases, fail to do a
|
||||
complete check.
|
||||
* exposed more settings for tweaking parameters in the piece-picker,
|
||||
downloader and uploader (http_settings replaced by session_settings).
|
||||
* tweaked default settings to improve high bandwidth transfers.
|
||||
* improved the piece picker performance and made it possible to download
|
||||
popular pieces in sequence to improve disk performance.
|
||||
* added the possibility to control upload and download limits per peer.
|
||||
* fixed problem with re-requesting skipped pieces when peer was sending pieces
|
||||
out of fifo-order.
|
||||
* added support for http seeding (the GetRight protocol)
|
||||
* renamed identifiers called 'id' in the public interface to support linking
|
||||
with Objective.C++
|
||||
* changed the extensions protocol to use the new one, which is also
|
||||
implemented by uTorrent.
|
||||
* factorized the peer_connection and added web_peer_connection which is
|
||||
able to download from http-sources.
|
||||
* converted the network code to use asio (resulted in slight api changes
|
||||
dealing with network addresses).
|
||||
* made libtorrent build in vc7 (patches from Allen Zhao)
|
||||
* fixed bug caused when binding outgoing connections to a non-local interface.
|
||||
* add_torrent() will now throw if called while the session object is
|
||||
being closed.
|
||||
* added the ability to limit the number of simultaneous half-open
|
||||
TCP connections. Flags in peer_info has been added.
|
||||
|
||||
release 0.9.1
|
||||
|
||||
* made the session disable file name checks within the boost.filsystem library
|
||||
* fixed race condition in the sockets
|
||||
* strings that are invalid utf-8 strings are now decoded with the
|
||||
local codepage on windows
|
||||
* added the ability to build libtorrent both as a shared library
|
||||
* client_test can now monitor a directory for torrent files and automatically
|
||||
start and stop downloads while running
|
||||
* fixed problem with file_size() when building on windows with unicode support
|
||||
* added a new torrent state, allocating
|
||||
* added a new alert, metadata_failed_alert
|
||||
* changed the interface to session::add_torrent for some speed optimizations.
|
||||
* greatly improved the command line control of the example client_test.
|
||||
* fixed bug where upload rate limit was not being applied.
|
||||
* files that are being checked will no longer stall files that don't need
|
||||
checking.
|
||||
* changed the way libtorrent identifies support for its excentions
|
||||
to look for 'ext' at the end of the peer-id.
|
||||
* improved performance by adding a circle buffer for the send buffer.
|
||||
* fixed bugs in the http tracker connection when using an http proxy.
|
||||
* fixed problem with storage's file pool when creating torrents and then
|
||||
starting to seed them.
|
||||
* hard limit on remote request queue and timeout on requests (a timeout
|
||||
triggers rerequests). This makes libtorrent work much better with
|
||||
"broken" clients like BitComet which may ignore requests.
|
||||
|
||||
Initial release 0.9
|
||||
|
||||
* multitracker support
|
||||
* serves multiple torrents on a single port and a single thread
|
||||
* supports http proxies and proxy authentication
|
||||
* gzipped tracker-responses
|
||||
* block level piece picker
|
||||
* queues torrents for file check, instead of checking all of them in parallel
|
||||
* uses separate threads for checking files and for main downloader
|
||||
* upload and download rate limits
|
||||
* piece-wise, unordered, incremental file allocation
|
||||
* fast resume support
|
||||
* supports files > 2 gigabytes
|
||||
* supports the no_peer_id=1 extension
|
||||
* support for udp-tracker protocol
|
||||
* number of connections limit
|
||||
* delays sending have messages
|
||||
* can resume pieces downloaded in any order
|
||||
* adjusts the length of the request queue depending on download rate
|
||||
* supports compact=1
|
||||
* selective downloading
|
||||
* ip filter
|
||||
|
|
@ -1,515 +0,0 @@
|
|||
# This Jamfile requires boost-build v2 to build.
|
||||
# The version shipped with boost 1.34.0
|
||||
|
||||
import modules ;
|
||||
import os ;
|
||||
import errors ;
|
||||
import feature : feature ;
|
||||
import package ;
|
||||
import virtual-target ;
|
||||
|
||||
BOOST_ROOT = [ modules.peek : BOOST_ROOT ] ;
|
||||
CXXFLAGS = [ modules.peek : CXXFLAGS ] ;
|
||||
LDFLAGS = [ modules.peek : LDFLAGS ] ;
|
||||
|
||||
ECHO "BOOST_ROOT =" $(BOOST_ROOT) ;
|
||||
ECHO "OS =" [ os.name ] ;
|
||||
|
||||
if $(BOOST_ROOT)
|
||||
{
|
||||
use-project /boost : $(BOOST_ROOT) ;
|
||||
}
|
||||
|
||||
VERSION = 0.16.0 ;
|
||||
|
||||
# rule for linking the correct libraries depending
|
||||
# on features and target-os
|
||||
rule linking ( properties * )
|
||||
{
|
||||
local result ;
|
||||
|
||||
# openssl libraries, if enabled
|
||||
if <encryption>openssl in $(properties)
|
||||
{
|
||||
# exclude gcc from a regular windows build to make mingw
|
||||
# link against the regular unix library name
|
||||
|
||||
if <target-os>windows in $(properties)
|
||||
{
|
||||
result += <library>gdi32 ;
|
||||
}
|
||||
|
||||
if <target-os>windows in $(properties) && ! <toolset>gcc in $(properties)
|
||||
{
|
||||
result += <library>ssleay32
|
||||
<library>libeay32
|
||||
<library>advapi32
|
||||
<library>user32
|
||||
<library>shell32
|
||||
;
|
||||
}
|
||||
else
|
||||
{
|
||||
result += <library>crypto <library>ssl ;
|
||||
}
|
||||
}
|
||||
|
||||
# gcrypt libraries, if enabled
|
||||
if <encryption>gcrypt in $(properties)
|
||||
{
|
||||
# on mac os x, adding the /opt/local/include path
|
||||
# would include openssl headers incompatible with
|
||||
# the system library. Only add this include path
|
||||
# if we're not using openssl (which we're most
|
||||
# likely not if we're using libgcrypt)
|
||||
result += <library>gcrypt <include>/opt/local/include ;
|
||||
}
|
||||
|
||||
if <encryption>tommath in $(properties)
|
||||
{
|
||||
result += <source>src/mpi.c ;
|
||||
}
|
||||
|
||||
if <geoip>shared in $(properties)
|
||||
{
|
||||
result += <library>GeoIP ;
|
||||
}
|
||||
|
||||
# socket functions on windows require winsock libraries
|
||||
if <target-os>windows in $(properties)
|
||||
|| <target-os>cygwin in $(properties)
|
||||
{
|
||||
result += <library>ws2_32
|
||||
<library>wsock32
|
||||
<library>iphlpapi
|
||||
<define>WIN32_LEAN_AND_MEAN
|
||||
<define>_WIN32_WINNT=0x0600
|
||||
<define>__USE_W32_SOCKETS
|
||||
<define>WIN32
|
||||
<define>_WIN32
|
||||
;
|
||||
}
|
||||
|
||||
if <target-os>beos in $(properties)
|
||||
{
|
||||
result += <library>netkit ;
|
||||
}
|
||||
|
||||
if <target-os>solaris in $(properties)
|
||||
{
|
||||
result += <library>libsocket <library>libnsl ;
|
||||
}
|
||||
|
||||
if <test-coverage>on in $(properties)
|
||||
&& ( <toolset>gcc in $(properties)
|
||||
|| <toolset>darwin in $(properties) )
|
||||
{
|
||||
result += <cxxflags>-fprofile-arcs <cxxflags>-ftest-coverage
|
||||
<linkflags>-lgcov <define>NDEBUG ;
|
||||
}
|
||||
|
||||
# clock_gettime on linux requires librt
|
||||
if <need-librt>yes in $(properties)
|
||||
{
|
||||
result += <library>librt ;
|
||||
}
|
||||
|
||||
if <tcmalloc>yes in $(properties)
|
||||
{
|
||||
result += <library>tcmalloc ;
|
||||
}
|
||||
|
||||
if <boost>system in $(properties)
|
||||
{
|
||||
result += <library>boost_system ;
|
||||
}
|
||||
|
||||
if <toolset>gcc in $(properties)
|
||||
&& <target-os>linux in $(properties)
|
||||
&& <variant>debug in $(properties)
|
||||
{
|
||||
# for backtraces in assertion failures
|
||||
# which only works on ELF targets with gcc
|
||||
result += <linkflags>-export-dynamic <cxxflags>-rdynamic ;
|
||||
}
|
||||
|
||||
if <boost>source in $(properties)
|
||||
{
|
||||
if <boost-link>static in $(properties)
|
||||
{
|
||||
if <toolset>gcc in $(properties) && <link>shared in $(properties)
|
||||
{
|
||||
result += <fpic>on ;
|
||||
}
|
||||
|
||||
result += <library>/boost/system//boost_system/<link>static ;
|
||||
}
|
||||
else
|
||||
{
|
||||
result += <library>/boost/system//boost_system/<link>shared ;
|
||||
}
|
||||
result += <include>$(BOOST_ROOT) <define>BOOST_ALL_NO_LIB ;
|
||||
}
|
||||
|
||||
if <boost>system in $(properties)
|
||||
{
|
||||
# on mac the boost headers are installed in
|
||||
# a directory that isn't automatically accessable
|
||||
result += <include>/opt/local/include/boost-1_35
|
||||
<include>/opt/local/include
|
||||
;
|
||||
}
|
||||
|
||||
return $(result) ;
|
||||
}
|
||||
|
||||
# rule for adding the right source files
|
||||
# depending on target-os and features
|
||||
rule building ( properties * )
|
||||
{
|
||||
local result ;
|
||||
|
||||
if ( <target-os>linux in $(properties)
|
||||
|| <target-os>darwin in $(properties) )
|
||||
&& ( <toolset>gcc in $(properties)
|
||||
|| <toolset>darwin in $(properties) )
|
||||
{
|
||||
result += <source>src/assert.cpp ;
|
||||
}
|
||||
|
||||
if <geoip>static in $(properties)
|
||||
{
|
||||
result += <source>src/GeoIP.c ;
|
||||
}
|
||||
|
||||
if <encryption>off in $(properties)
|
||||
|| <encryption>tommath in $(properties)
|
||||
{
|
||||
result += <source>src/sha1.cpp ;
|
||||
}
|
||||
|
||||
if ! ( <encryption>off in $(properties) )
|
||||
{
|
||||
result += <source>src/pe_crypto.cpp ;
|
||||
|
||||
if <target-os>linux in $(properties)
|
||||
&& <encryption>openssl in $(properties)
|
||||
{
|
||||
# linker library on linux, required when using openssl
|
||||
result += <source>/usr/lib/libdl.so ;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return $(result) ;
|
||||
}
|
||||
|
||||
rule tag ( name : type ? : property-set )
|
||||
{
|
||||
name = [ virtual-target.add-prefix-and-suffix $(name) : $(type) : $(property-set) ] ;
|
||||
|
||||
if $(type) = SHARED_LIB &&
|
||||
( ! ( [ $(property-set).get <target-os> ] in windows cygwin ) )
|
||||
{
|
||||
name = $(name).$(VERSION) ;
|
||||
}
|
||||
|
||||
return $(name) ;
|
||||
}
|
||||
|
||||
feature tcmalloc : no yes : composite propagated link-incompatible ;
|
||||
|
||||
feature timer : auto boost absolute performance clock system_time
|
||||
: composite propagated link-incompatible ;
|
||||
feature.compose <timer>boost : <define>TORRENT_USE_BOOST_DATE_TIME=1 ;
|
||||
feature.compose <timer>absolute : <define>TORRENT_USE_ABSOLUTE_TIME=1 ;
|
||||
feature.compose <timer>performance : <define>TORRENT_USE_PERFORMANCE_TIMER=1 ;
|
||||
feature.compose <timer>clock : <define>TORRENT_USE_CLOCK_GETTIME=1 ;
|
||||
feature.compose <timer>system_time : <define>TORRENT_USE_SYSTEM_TIME=1 ;
|
||||
|
||||
feature ipv6 : on off : composite propagated link-incompatible ;
|
||||
feature.compose <ipv6>off : <define>TORRENT_USE_IPV6=0 ;
|
||||
|
||||
feature need-librt : no yes : composite propagated link-incompatible ;
|
||||
|
||||
feature fiemap : off on : composite propagated ;
|
||||
feature.compose <fiemap>on : <define>HAVE_LINUX_FIEMAP_H ;
|
||||
|
||||
feature full-stats : on off : composite propagated link-incompatible ;
|
||||
feature.compose <full-stats>off : <define>TORRENT_DISABLE_FULL_STATS ;
|
||||
|
||||
feature asserts : on off production : composite propagated ;
|
||||
feature.compose <asserts>production : <define>TORRENT_PRODUCTION_ASSERTS=1 ;
|
||||
feature.compose <asserts>off : <define>TORRENT_NO_ASSERTS=1 ;
|
||||
|
||||
feature asio-debugging : off on : composite propagated link-incompatible ;
|
||||
feature.compose <asio-debugging>on : <define>TORRENT_ASIO_DEBUGGING ;
|
||||
|
||||
feature pool-allocators : on off : composite propagated link-incompatible ;
|
||||
feature.compose <pool-allocators>off : <define>TORRENT_DISABLE_POOL_ALLOCATOR ;
|
||||
|
||||
feature piece-allocator : valloc memalign posix_memalign : composite propagated ;
|
||||
feature.compose <piece-allocator>memalign : <define>TORRENT_USE_MEMALIGN=1 ;
|
||||
feature.compose <piece-allocator>posix_memalign : <define>TORRENT_USE_POSIX_MEMALIGN=1 ;
|
||||
|
||||
feature geoip : off static shared : composite propagated link-incompatible ;
|
||||
feature.compose <geoip>off : <define>TORRENT_DISABLE_GEO_IP ;
|
||||
|
||||
feature bandwidth-limit-logging : off on : composite propagated link-incompatible ;
|
||||
feature.compose <bandwidth-limit-logging>on : <define>TORRENT_VERBOSE_BANDWIDTH_LIMIT ;
|
||||
|
||||
feature invariant-checks : on off full : composite propagated link-incompatible ;
|
||||
feature.compose <invariant-checks>off : <define>TORRENT_DISABLE_INVARIANT_CHECKS ;
|
||||
feature.compose <invariant-checks>full : <define>TORRENT_EXPENSIVE_INVARIANT_CHECKS ;
|
||||
|
||||
feature disk-stats : off on : composite propagated link-incompatible ;
|
||||
feature.compose <disk-stats>on : <define>TORRENT_DISK_STATS ;
|
||||
|
||||
feature simulate-slow-read : off on : composite propagated ;
|
||||
feature.compose <simulate-slow-read>on : <define>TORRENT_SIMULATE_SLOW_READ ;
|
||||
|
||||
feature logging : none default errors verbose : composite propagated link-incompatible ;
|
||||
feature.compose <logging>default : <define>TORRENT_LOGGING ;
|
||||
feature.compose <logging>errors : <define>TORRENT_ERROR_LOGGING ;
|
||||
feature.compose <logging>verbose : <define>TORRENT_VERBOSE_LOGGING ;
|
||||
|
||||
feature dht-support : on off logging : composite propagated link-incompatible ;
|
||||
feature.compose <dht-support>off : <define>TORRENT_DISABLE_DHT ;
|
||||
feature.compose <dht-support>logging : <define>TORRENT_DHT_VERBOSE_LOGGING ;
|
||||
|
||||
feature encryption : tommath off openssl gcrypt : composite propagated link-incompatible ;
|
||||
feature.compose <encryption>openssl : <define>TORRENT_USE_OPENSSL ;
|
||||
feature.compose <encryption>gcrypt : <define>TORRENT_USE_GCRYPT ;
|
||||
feature.compose <encryption>tommath : <define>TORRENT_USE_TOMMATH ;
|
||||
feature.compose <encryption>off : <define>TORRENT_DISABLE_ENCRYPTION ;
|
||||
|
||||
feature resolve-countries : on off : composite propagated link-incompatible ;
|
||||
feature.compose <resolve-countries>off : <define>TORRENT_DISABLE_RESOLVE_COUNTRIES ;
|
||||
|
||||
feature character-set : unicode ansi : composite propagated link-incompatible ;
|
||||
feature.compose <character-set>unicode : <define>_UNICODE <define>UNICODE ;
|
||||
|
||||
feature deprecated-functions : on off : composite propagated link-incompatible ;
|
||||
feature.compose <deprecated-functions>off : <define>TORRENT_NO_DEPRECATE ;
|
||||
|
||||
feature statistics : off on : composite propagated link-incompatible ;
|
||||
feature.compose <statistics>on : <define>TORRENT_STATS ;
|
||||
|
||||
feature upnp-logging : off on : composite propagated link-incompatible ;
|
||||
feature.compose <upnp-logging>on : <define>TORRENT_UPNP_LOGGING ;
|
||||
|
||||
feature boost : system source : link-incompatible propagated ;
|
||||
feature boost-link : static shared : composite ;
|
||||
|
||||
feature debug-iterators : off on : composite propagated link-incompatible ;
|
||||
feature.compose <debug-iterators>on : <define>_SCL_SECURE=1 <define>_GLIBCXX_DEBUG ;
|
||||
|
||||
feature test-coverage : off on : composite propagated ;
|
||||
|
||||
feature fpic : off on : composite propagated link-incompatible ;
|
||||
feature.compose <fpic>on : <cflags>-fPIC ;
|
||||
feature.compose <fpic>off : <toolset>darwin:<cflags>-mdynamic-no-pic ;
|
||||
|
||||
feature visibility : default hidden : composite propagated link-incompatible ;
|
||||
feature.compose <visibility>hidden : <cflags>-fvisibility=hidden ;
|
||||
|
||||
# required for openssl on windows
|
||||
lib ssleay32 : : <name>ssleay32 ;
|
||||
lib libeay32 : : <name>libeay32 ;
|
||||
lib advapi32 : : <name>Advapi32 ;
|
||||
lib user32 : : <name>User32 ;
|
||||
lib shell32 : : <name>shell32 ;
|
||||
lib gdi32 : : <name>gdi32 ;
|
||||
|
||||
# required for networking on beos
|
||||
lib netkit : : <name>net <search>/boot/system/lib <link>shared ;
|
||||
|
||||
local boost-library-search-path =
|
||||
<search>/opt/local/lib
|
||||
<search>/usr/lib
|
||||
<search>/usr/local/lib
|
||||
<search>/sw/lib
|
||||
;
|
||||
|
||||
lib boost_system : : <target-os>darwin <name>boost_system-mt $(boost-library-search-path) ;
|
||||
|
||||
lib boost_system : : <name>boost_system ;
|
||||
|
||||
# openssl on linux/bsd/macos etc.
|
||||
lib gcrypt : : <name>gcrypt <link>shared <search>/opt/local/lib ;
|
||||
lib crypto : : <name>crypto <search>/lib ;
|
||||
lib ssl : : <name>ssl <link>shared <use>crypto ;
|
||||
|
||||
# time functions used on linux require librt
|
||||
lib librt : : <name>rt <link>shared ;
|
||||
|
||||
lib libsocket : : <use>libnsl <name>socket <link>shared <search>/usr/sfw/lib <link>shared ;
|
||||
lib libnsl : : <name>nsl <link>shared <search>/usr/sfw/lib <link>shared ;
|
||||
|
||||
lib tcmalloc : : <name>tcmalloc <link>shared ;
|
||||
|
||||
# GeoIP shared library
|
||||
lib GeoIP : : <name>GeoIP <link>shared ;
|
||||
|
||||
# socket libraries on windows
|
||||
lib wsock32 : : <name>wsock32 <link>shared ;
|
||||
lib ws2_32 : : <name>ws2_32 <link>shared ;
|
||||
lib iphlpapi : : <name>iphlpapi <link>shared ;
|
||||
|
||||
SOURCES =
|
||||
alert
|
||||
allocator
|
||||
assert
|
||||
bandwidth_limit
|
||||
bandwidth_manager
|
||||
bandwidth_queue_entry
|
||||
connection_queue
|
||||
create_torrent
|
||||
disk_buffer_holder
|
||||
entry
|
||||
error_code
|
||||
file_storage
|
||||
lazy_bdecode
|
||||
escape_string
|
||||
file
|
||||
gzip
|
||||
http_connection
|
||||
http_stream
|
||||
http_parser
|
||||
identify_client
|
||||
ip_filter
|
||||
peer_connection
|
||||
bt_peer_connection
|
||||
web_connection_base
|
||||
web_peer_connection
|
||||
http_seed_connection
|
||||
i2p_stream
|
||||
instantiate_connection
|
||||
natpmp
|
||||
packet_buffer
|
||||
piece_picker
|
||||
policy
|
||||
puff
|
||||
session
|
||||
session_impl
|
||||
settings
|
||||
socket_io
|
||||
socket_type
|
||||
socks5_stream
|
||||
stat
|
||||
storage
|
||||
torrent
|
||||
torrent_handle
|
||||
torrent_info
|
||||
time
|
||||
tracker_manager
|
||||
http_tracker_connection
|
||||
udp_tracker_connection
|
||||
sha1
|
||||
timestamp_history
|
||||
udp_socket
|
||||
upnp
|
||||
utp_socket_manager
|
||||
utp_stream
|
||||
logger
|
||||
file_pool
|
||||
lsd
|
||||
disk_io_thread
|
||||
enum_net
|
||||
broadcast_socket
|
||||
magnet_uri
|
||||
parse_url
|
||||
ConvertUTF
|
||||
thread
|
||||
|
||||
# -- extensions --
|
||||
metadata_transfer
|
||||
ut_pex
|
||||
ut_metadata
|
||||
lt_trackers
|
||||
smart_ban
|
||||
;
|
||||
|
||||
KADEMLIA_SOURCES =
|
||||
dht_tracker
|
||||
node
|
||||
refresh
|
||||
rpc_manager
|
||||
find_data
|
||||
node_id
|
||||
routing_table
|
||||
traversal_algorithm
|
||||
;
|
||||
|
||||
local usage-requirements =
|
||||
<include>./include
|
||||
<include>./include/libtorrent
|
||||
<include>/usr/sfw/include
|
||||
<variant>release:<define>NDEBUG
|
||||
<variant>debug:<define>TORRENT_DEBUG
|
||||
<define>_FILE_OFFSET_BITS=64
|
||||
<define>BOOST_EXCEPTION_DISABLE
|
||||
# enable cancel support in asio
|
||||
<define>BOOST_ASIO_ENABLE_CANCELIO
|
||||
<conditional>@linking
|
||||
# these compiler settings just makes the compiler standard conforming
|
||||
<toolset>msvc:<cflags>/Zc:wchar_t
|
||||
<toolset>msvc:<cflags>/Zc:forScope
|
||||
# disable bogus deprecation warnings on msvc8
|
||||
<toolset>msvc:<define>_SCL_SECURE_NO_DEPRECATE
|
||||
<toolset>msvc:<define>_CRT_SECURE_NO_DEPRECATE
|
||||
# msvc optimizations
|
||||
<toolset>msvc,<variant>release:<linkflags>/OPT:ICF=5
|
||||
<toolset>msvc,<variant>release:<linkflags>/OPT:REF
|
||||
# disable warning C4503: decorated name length exceeded, name was truncated
|
||||
<toolset>msvc:<cxxflags>/wd4503
|
||||
# disable warning C4275: non-dll interface class 'x' used as base for dll-interface struct 'y'
|
||||
<toolset>msvc:<cxxflags>/wd4275
|
||||
# disable warning C4251: 'x' needs to have dll-interface to be used by clients of class 'y'
|
||||
<toolset>msvc:<cxxflags>/wd4251
|
||||
# disable some warnings for gcc
|
||||
<toolset>gcc:<cflags>-fno-strict-aliasing
|
||||
<toolset>gcc:<cflags>-Wno-missing-braces
|
||||
<boost>system:<cxxflags>$(CXXFLAGS)
|
||||
<boost>system:<linkflags>$(LDFLAGS)
|
||||
# this works around a bug in asio in boost-1.39
|
||||
<define>BOOST_ASIO_HASH_MAP_BUCKETS=1021
|
||||
<tag>@tag
|
||||
;
|
||||
|
||||
project torrent ;
|
||||
|
||||
lib torrent
|
||||
|
||||
: # sources
|
||||
src/$(SOURCES).cpp
|
||||
|
||||
: # requirements
|
||||
<define>BOOST_THREAD_USE_LIB
|
||||
<threading>multi
|
||||
<link>shared:<define>TORRENT_BUILDING_SHARED
|
||||
<dht-support>on:<source>src/kademlia/$(KADEMLIA_SOURCES).cpp
|
||||
<dht-support>logging:<source>src/kademlia/$(KADEMLIA_SOURCES).cpp
|
||||
<conditional>@building
|
||||
<boost>system:<cxxflags>$(CXXFLAGS)
|
||||
$(usage-requirements)
|
||||
|
||||
: # default build
|
||||
<link>static
|
||||
<threading>multi
|
||||
|
||||
: # usage requirements
|
||||
$(usage-requirements)
|
||||
;
|
||||
|
||||
headers = [ path.glob-tree include/libtorrent : *.hpp ] ;
|
||||
|
||||
package.install install
|
||||
: <install-header-subdir>libtorrent
|
||||
<install-source-root>libtorrent
|
||||
<install-no-version-symlinks>on
|
||||
:
|
||||
: torrent
|
||||
: $(headers)
|
||||
;
|
||||
|
|
@ -1,103 +0,0 @@
|
|||
Copyright (c) 2003-2010, Arvid Norberg
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the author nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
puff.c
|
||||
Copyright (C) 2002, 2003 Mark Adler
|
||||
For conditions of distribution and use, see copyright notice in puff.h
|
||||
version 1.7, 3 Mar 2003
|
||||
|
||||
puff.c is a simple inflate written to be an unambiguous way to specify the
|
||||
deflate format. It is not written for speed but rather simplicity. As a
|
||||
side benefit, this code might actually be useful when small code is more
|
||||
important than speed, such as bootstrap applications. For typical deflate
|
||||
data, zlib's inflate() is about four times as fast as puff(). zlib's
|
||||
inflate compiles to around 20K on my machine, whereas puff.c compiles to
|
||||
around 4K on my machine (a PowerPC using GNU cc). If the faster decode()
|
||||
function here is used, then puff() is only twice as slow as zlib's
|
||||
inflate().
|
||||
|
||||
All dynamically allocated memory comes from the stack. The stack required
|
||||
is less than 2K bytes. This code is compatible with 16-bit int's and
|
||||
assumes that long's are at least 32 bits. puff.c uses the short data type,
|
||||
assumed to be 16 bits, for arrays in order to to conserve memory. The code
|
||||
works whether integers are stored big endian or little endian.
|
||||
|
||||
In the comments below are "Format notes" that describe the inflate process
|
||||
and document some of the less obvious aspects of the format. This source
|
||||
code is meant to supplement RFC 1951, which formally describes the deflate
|
||||
format:
|
||||
|
||||
http://www.zlib.org/rfc-deflate.html
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
GeoIP.c
|
||||
|
||||
Copyright (C) 2006 MaxMind LLC
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
Permission is hereby granted, free of charge, to any person or organization
|
||||
obtaining a copy of the software and accompanying documentation covered by
|
||||
this license (the "Software") to use, reproduce, display, distribute,
|
||||
execute, and transmit the Software, and to prepare derivative works of the
|
||||
Software, and to permit third-parties to whom the Software is furnished to
|
||||
do so, all subject to the following:
|
||||
|
||||
The copyright notices in the Software and this entire statement, including
|
||||
the above license grant, this restriction and the following disclaimer,
|
||||
must be included in all copies of the Software, in whole or in part, and
|
||||
all derivative works of the Software, unless such copies or derivative
|
||||
works are solely in the form of machine-executable object code generated by
|
||||
a source language processor.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
|
@ -1,99 +0,0 @@
|
|||
ACLOCAL_AMFLAGS = -I m4
|
||||
|
||||
#DISTCHECK_CONFIGURE_FLAGS = --enable-tests
|
||||
|
||||
SUBDIRS = include/libtorrent src examples test bindings
|
||||
|
||||
DOCS_IMAGES = \
|
||||
docs/arctic_thumb.png \
|
||||
docs/bitbuddy_thumb.jpg \
|
||||
docs/bitfox.png \
|
||||
docs/bitrocket_thumb.png \
|
||||
docs/bitscast_thumb.png \
|
||||
docs/bitslug_thumb.png \
|
||||
docs/btg_thumb.jpg \
|
||||
docs/bubba.png \
|
||||
docs/client_test.png \
|
||||
docs/deluge.png \
|
||||
docs/disk_access.png \
|
||||
docs/disk_buffer_before_optimization.png \
|
||||
docs/disk_buffer.png \
|
||||
docs/disk_buffer_sample.png \
|
||||
docs/disk_io.png \
|
||||
docs/electric_sheep_thumb.jpg \
|
||||
docs/fatrat.png \
|
||||
docs/fdm.png \
|
||||
docs/firetorrent.png \
|
||||
docs/flush.jpg \
|
||||
docs/halite_thumb.png \
|
||||
docs/im_thumb.jpg \
|
||||
docs/leechcraft.png \
|
||||
docs/libtorrent_screen.png \
|
||||
docs/limewire.png \
|
||||
docs/lince.png \
|
||||
docs/Linkage.png \
|
||||
docs/merkle_tree.graffle \
|
||||
docs/merkle_tree.png \
|
||||
docs/miro.jpg \
|
||||
docs/moopolice_thumb.gif \
|
||||
docs/pump.png \
|
||||
docs/qbittorrent_thumb.jpg \
|
||||
docs/read_disk_buffers.dot \
|
||||
docs/read_disk_buffers.graffle \
|
||||
docs/read_disk_buffers.png \
|
||||
docs/session_stats_peers.png \
|
||||
docs/storage.graffle \
|
||||
docs/storage.png \
|
||||
docs/style.css \
|
||||
docs/tvblob.jpg \
|
||||
docs/tvitty.jpg \
|
||||
docs/unicode_support.png \
|
||||
docs/write_disk_buffers.dot \
|
||||
docs/write_disk_buffers.graffle \
|
||||
docs/write_disk_buffers.png \
|
||||
docs/ziptorrent_thumb.gif
|
||||
|
||||
DOCS_PAGES = \
|
||||
docs/building.html \
|
||||
docs/building.rst \
|
||||
docs/client_test.html \
|
||||
docs/client_test.rst \
|
||||
docs/dht_extensions.html \
|
||||
docs/dht_extensions.rst \
|
||||
docs/examples.html \
|
||||
docs/examples.rst \
|
||||
docs/extension_protocol.html \
|
||||
docs/extension_protocol.rst \
|
||||
docs/features.html \
|
||||
docs/features.rst \
|
||||
docs/index.html \
|
||||
docs/index.rst \
|
||||
docs/libtorrent_plugins.html \
|
||||
docs/libtorrent_plugins.rst \
|
||||
docs/make_torrent.html \
|
||||
docs/make_torrent.rst \
|
||||
docs/manual.html \
|
||||
docs/manual.rst \
|
||||
docs/projects.html \
|
||||
docs/projects.rst \
|
||||
docs/python_binding.html \
|
||||
docs/python_binding.rst \
|
||||
docs/running_tests.html \
|
||||
docs/running_tests.rst \
|
||||
docs/tuning.html \
|
||||
docs/tuning.rst \
|
||||
docs/udp_tracker_protocol.html \
|
||||
docs/udp_tracker_protocol.rst
|
||||
|
||||
EXTRA_DIST = \
|
||||
Jamfile \
|
||||
project-root.jam \
|
||||
CMakeLists.txt \
|
||||
LICENSE \
|
||||
libtorrent-rasterbar.pc \
|
||||
libtorrent-rasterbar-cmake.pc \
|
||||
$(DOCS_PAGES) \
|
||||
$(DOCS_IMAGES)
|
||||
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
pkgconfig_DATA = libtorrent-rasterbar.pc
|
|
@ -1,3 +0,0 @@
|
|||
|
||||
initial release of libtorrent 0.9
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
libtorrent is a C++ library that aims to be a good alternative to all the
|
||||
other bittorrent implementations around. It is a
|
||||
library and not a full featured client, although it comes with a working
|
||||
example client.
|
||||
|
||||
The main goals of libtorrent are:
|
||||
|
||||
* to be cpu efficient
|
||||
* to be memory efficient
|
||||
* to be very easy to use
|
||||
|
||||
See docs/manual.html for more detailed build and usage instructions.
|
||||
|
||||
To build with autotools, run:
|
||||
|
||||
./configure
|
||||
|
||||
Followed by
|
||||
|
||||
make
|
||||
|
||||
When libtorrent is built, finish off by running the tests:
|
||||
|
||||
make check
|
||||
|
|
@ -1,176 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
# Using this script should be identical to the resulto of "autoreconf -fi".
|
||||
# Some code taken from the gnome macros/autogen.sh scripts.
|
||||
|
||||
# $Id$
|
||||
|
||||
|
||||
###############################################################################
|
||||
# utility functions
|
||||
###############################################################################
|
||||
|
||||
# Not all echo versions allow -n, so we check what is possible. This test is
|
||||
# based on the one in autoconf.
|
||||
ECHO_C=
|
||||
ECHO_N=
|
||||
case `echo -n x` in
|
||||
-n*)
|
||||
case `echo 'x\c'` in
|
||||
*c*) ;;
|
||||
*) ECHO_C='\c';;
|
||||
esac;;
|
||||
*)
|
||||
ECHO_N='-n';;
|
||||
esac
|
||||
|
||||
# some terminal codes ...
|
||||
boldface="`tput bold 2>/dev/null`"
|
||||
normal="`tput sgr0 2>/dev/null`"
|
||||
|
||||
printbold() {
|
||||
echo $ECHO_N "$boldface" $ECHO_C
|
||||
echo "$@"
|
||||
echo $ECHO_N "$normal" $ECHO_C
|
||||
}
|
||||
|
||||
printerr() {
|
||||
echo "$@" >&2
|
||||
}
|
||||
|
||||
# Usage:
|
||||
# compare_versions MIN_VERSION ACTUAL_VERSION
|
||||
# returns true if ACTUAL_VERSION >= MIN_VERSION
|
||||
compare_versions() {
|
||||
ch_min_version=$1
|
||||
ch_actual_version=$2
|
||||
ch_status=0
|
||||
IFS="${IFS= }"; ch_save_IFS="$IFS"; IFS="."
|
||||
set $ch_actual_version
|
||||
for ch_min in $ch_min_version; do
|
||||
ch_cur=`echo $1 | sed 's/[^0-9].*$//'`; shift # remove letter suffixes
|
||||
if [ -z "$ch_min" ]; then break; fi
|
||||
if [ -z "$ch_cur" ]; then ch_status=1; break; fi
|
||||
if [ $ch_cur -gt $ch_min ]; then break; fi
|
||||
if [ $ch_cur -lt $ch_min ]; then ch_status=1; break; fi
|
||||
done
|
||||
IFS="$ch_save_IFS"
|
||||
return $ch_status
|
||||
}
|
||||
|
||||
# Usage:
|
||||
# version_check PACKAGE VARIABLE CHECKPROGS MIN_VERSION
|
||||
# checks to see if the package is available
|
||||
version_check() {
|
||||
vc_package=$1
|
||||
vc_variable=$2
|
||||
vc_checkprogs=$3
|
||||
vc_min_version=$4
|
||||
vc_status=1
|
||||
|
||||
vc_checkprog=`eval echo "\\$$vc_variable"`
|
||||
if [ -n "$vc_checkprog" ]; then
|
||||
printbold "Using $vc_checkprog for $vc_package"
|
||||
return 0
|
||||
fi
|
||||
|
||||
vc_comparator=">="
|
||||
|
||||
printbold "Checking for $vc_package $vc_comparator $vc_min_version..."
|
||||
|
||||
for vc_checkprog in $vc_checkprogs; do
|
||||
echo $ECHO_N " testing $vc_checkprog... " $ECHO_C
|
||||
if $vc_checkprog --version < /dev/null > /dev/null 2>&1; then
|
||||
vc_actual_version=`$vc_checkprog --version | head -n 1 | \
|
||||
sed 's/^.*[ ]\([0-9.]*[a-z]*\).*$/\1/'`
|
||||
if compare_versions $vc_min_version $vc_actual_version; then
|
||||
echo "found $vc_actual_version"
|
||||
# set variables
|
||||
eval "$vc_variable=$vc_checkprog; \
|
||||
${vc_variable}_VERSION=$vc_actual_version"
|
||||
vc_status=0
|
||||
break
|
||||
else
|
||||
echo "too old (found version $vc_actual_version)"
|
||||
fi
|
||||
else
|
||||
echo "not found."
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "$vc_status" != 0 ]; then
|
||||
printerr "***Error***: $vc_package $vc_comparator $vc_min_version not found."
|
||||
fi
|
||||
|
||||
return $vc_status
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
# main section
|
||||
###############################################################################
|
||||
|
||||
configure_ac="configure.ac"
|
||||
|
||||
(test -f $configure_ac && test -f src/torrent.cpp) || {
|
||||
printerr "***Error***: Run this script from the top-level source directory."
|
||||
exit 1
|
||||
}
|
||||
|
||||
echo
|
||||
printbold "Bootstrapping autotools for libtorrent-rasterbar"
|
||||
echo
|
||||
|
||||
REQUIRED_AUTOCONF_VERSION=`cat $configure_ac | grep '^AC_PREREQ' |
|
||||
sed -n -e 's/AC_PREREQ(\([^()]*\))/\1/p' | sed -e 's/^\[\(.*\)\]$/\1/' | sed -e 1q`
|
||||
|
||||
REQUIRED_AUTOMAKE_VERSION=`cat configure.ac | grep '^AM_INIT_AUTOMAKE' |
|
||||
sed -n -e 's/AM_INIT_AUTOMAKE(\([^()]*\))/\1/p' | sed -e 's/^\[\(.*\)\]$/\1/' | sed -e 's/\(.*\) .*/\1/' | sed -e 1q`
|
||||
|
||||
REQUIRED_LIBTOOL_VERSION=`cat $configure_ac | grep '^LT_PREREQ' |
|
||||
sed -n -e 's/LT_PREREQ(\([^()]*\))/\1/p' | sed -e 's/^\[\(.*\)\]$/\1/' | sed -e 1q`
|
||||
|
||||
printbold "Checking autotools requirements:"
|
||||
echo
|
||||
|
||||
version_check autoconf AUTOCONF 'autoconf autoconf2.59 autoconf-2.53 autoconf2.50' $REQUIRED_AUTOCONF_VERSION || exit 1
|
||||
AUTOHEADER=`echo $AUTOCONF | sed s/autoconf/autoheader/`
|
||||
|
||||
version_check automake AUTOMAKE "automake automake-1.11 automake-1.10" $REQUIRED_AUTOMAKE_VERSION || exit 1
|
||||
ACLOCAL=`echo $AUTOMAKE | sed s/automake/aclocal/`
|
||||
|
||||
version_check libtool LIBTOOLIZE "libtoolize glibtoolize" $REQUIRED_LIBTOOL_VERSION || exit 1
|
||||
|
||||
echo
|
||||
printbold "Processing $configure_ac"
|
||||
echo
|
||||
|
||||
if grep "^A[CM]_PROG_LIBTOOL" $configure_ac >/dev/null ||
|
||||
grep "^LT_INIT" $configure_ac >/dev/null; then
|
||||
printbold "Running $LIBTOOLIZE..."
|
||||
$LIBTOOLIZE --force --copy || exit 1
|
||||
fi
|
||||
|
||||
m4dir=`cat $configure_ac | grep '^AC_CONFIG_MACRO_DIR' |
|
||||
sed -n -e 's/AC_CONFIG_MACRO_DIR(\([^()]*\))/\1/p' | sed -e 's/^\[\(.*\)\]$/\1/' | sed -e 1q`
|
||||
if [ -n "$m4dir" ]; then
|
||||
m4dir="-I $m4dir"
|
||||
fi
|
||||
printbold "Running $ACLOCAL..."
|
||||
$ACLOCAL $m4dir || exit 1
|
||||
|
||||
printbold "Running $AUTOCONF..."
|
||||
$AUTOCONF || exit 1
|
||||
if grep "^A[CM]_CONFIG_HEADER" $configure_ac >/dev/null; then
|
||||
printbold "Running $AUTOHEADER..."
|
||||
$AUTOHEADER || exit 1
|
||||
# this prevents automake from thinking config.h.in is out of
|
||||
# date, since autoheader doesn't touch the file if it doesn't
|
||||
# change.
|
||||
test -f config.h.in && touch config.h.in
|
||||
fi
|
||||
|
||||
printbold "Running $AUTOMAKE..."
|
||||
$AUTOMAKE --gnu --add-missing --force --copy || exit 1
|
||||
|
||||
echo
|
||||
printbold "Bootstrap complete, now run \`configure'."
|
|
@ -1,4 +0,0 @@
|
|||
|
||||
SUBDIRS = python
|
||||
|
||||
EXTRA_DIST = README.txt
|
|
@ -1,3 +0,0 @@
|
|||
Documentation covering building and using the python binding for libtorrent
|
||||
is located in the main doc directory. See docs/python_binding.html
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
use-project /torrent : ../.. ;
|
||||
|
||||
rule libtorrent_linking ( properties * )
|
||||
{
|
||||
local result ;
|
||||
|
||||
if <toolset>gcc in $(properties) && <link>shared in $(properties)
|
||||
{
|
||||
result += <fpic>on ;
|
||||
}
|
||||
|
||||
# if <toolset>gcc in $(properties) || <toolset>darwin in $(properties)
|
||||
# {
|
||||
# result += <visibility>hidden ;
|
||||
# }
|
||||
|
||||
return $(result) ;
|
||||
}
|
||||
|
||||
lib torrentc
|
||||
|
||||
: # sources
|
||||
library.cpp
|
||||
|
||||
: # requirements
|
||||
<conditional>@libtorrent_linking
|
||||
<library>/torrent//torrent/<link>static
|
||||
<include>.
|
||||
|
||||
: # default build
|
||||
<link>static
|
||||
|
||||
: # usage-requirements
|
||||
<include>.
|
||||
;
|
||||
|
||||
exe simple_client : simple_client.c torrentc ;
|
||||
|
|
@ -1,606 +0,0 @@
|
|||
/*
|
||||
|
||||
Copyright (c) 2009, Arvid Norberg
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the author nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#include "libtorrent/session.hpp"
|
||||
#include "libtorrent/magnet_uri.hpp"
|
||||
#include "libtorrent/torrent_handle.hpp"
|
||||
#include <boost/bind.hpp>
|
||||
|
||||
#include <libtorrent.h>
|
||||
|
||||
namespace
|
||||
{
|
||||
std::vector<libtorrent::torrent_handle> handles;
|
||||
|
||||
int find_handle(libtorrent::torrent_handle h)
|
||||
{
|
||||
std::vector<libtorrent::torrent_handle>::const_iterator i
|
||||
= std::find(handles.begin(), handles.end(), h);
|
||||
if (i == handles.end()) return -1;
|
||||
return i - handles.begin();
|
||||
}
|
||||
|
||||
libtorrent::torrent_handle get_handle(int i)
|
||||
{
|
||||
if (i < 0 || i >= int(handles.size())) return libtorrent::torrent_handle();
|
||||
return handles[i];
|
||||
}
|
||||
|
||||
int add_handle(libtorrent::torrent_handle const& h)
|
||||
{
|
||||
std::vector<libtorrent::torrent_handle>::iterator i = std::find_if(handles.begin()
|
||||
, handles.end(), !boost::bind(&libtorrent::torrent_handle::is_valid, _1));
|
||||
if (i != handles.end())
|
||||
{
|
||||
*i = h;
|
||||
return i - handles.begin();
|
||||
}
|
||||
|
||||
handles.push_back(h);
|
||||
return handles.size() - 1;
|
||||
}
|
||||
|
||||
int set_int_value(void* dst, int* size, int val)
|
||||
{
|
||||
if (*size < sizeof(int)) return -2;
|
||||
*((int*)dst) = val;
|
||||
*size = sizeof(int);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void copy_proxy_setting(libtorrent::proxy_settings* s, proxy_setting const* ps)
|
||||
{
|
||||
s->hostname.assign(ps->hostname);
|
||||
s->port = ps->port;
|
||||
s->username.assign(ps->username);
|
||||
s->password.assign(ps->password);
|
||||
s->type = (libtorrent::proxy_settings::proxy_type)ps->type;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
||||
TORRENT_EXPORT void* session_create(int tag, ...)
|
||||
{
|
||||
using namespace libtorrent;
|
||||
|
||||
va_list lp;
|
||||
va_start(lp, tag);
|
||||
|
||||
fingerprint fing("LT", LIBTORRENT_VERSION_MAJOR, LIBTORRENT_VERSION_MINOR, 0, 0);
|
||||
std::pair<int, int> listen_range(-1, -1);
|
||||
char const* listen_interface = "0.0.0.0";
|
||||
int flags = session::start_default_features | session::add_default_plugins;
|
||||
int alert_mask = alert::error_notification;
|
||||
|
||||
while (tag != TAG_END)
|
||||
{
|
||||
switch (tag)
|
||||
{
|
||||
case SES_FINGERPRINT:
|
||||
{
|
||||
char const* f = va_arg(lp, char const*);
|
||||
fing.name[0] = f[0];
|
||||
fing.name[1] = f[1];
|
||||
break;
|
||||
}
|
||||
case SES_LISTENPORT:
|
||||
listen_range.first = va_arg(lp, int);
|
||||
break;
|
||||
case SES_LISTENPORT_END:
|
||||
listen_range.second = va_arg(lp, int);
|
||||
break;
|
||||
case SES_VERSION_MAJOR:
|
||||
fing.major_version = va_arg(lp, int);
|
||||
break;
|
||||
case SES_VERSION_MINOR:
|
||||
fing.minor_version = va_arg(lp, int);
|
||||
break;
|
||||
case SES_VERSION_TINY:
|
||||
fing.revision_version = va_arg(lp, int);
|
||||
break;
|
||||
case SES_VERSION_TAG:
|
||||
fing.tag_version = va_arg(lp, int);
|
||||
break;
|
||||
case SES_FLAGS:
|
||||
flags = va_arg(lp, int);
|
||||
break;
|
||||
case SES_ALERT_MASK:
|
||||
alert_mask = va_arg(lp, int);
|
||||
break;
|
||||
case SES_LISTEN_INTERFACE:
|
||||
listen_interface = va_arg(lp, char const*);
|
||||
break;
|
||||
default:
|
||||
// skip unknown tags
|
||||
va_arg(lp, void*);
|
||||
break;
|
||||
}
|
||||
|
||||
tag = va_arg(lp, int);
|
||||
}
|
||||
|
||||
if (listen_range.first != -1 && (listen_range.second == -1
|
||||
|| listen_range.second < listen_range.first))
|
||||
listen_range.second = listen_range.first;
|
||||
|
||||
return new (std::nothrow) session(fing, listen_range, listen_interface, flags, alert_mask);
|
||||
}
|
||||
|
||||
TORRENT_EXPORT void session_close(void* ses)
|
||||
{
|
||||
delete (libtorrent::session*)ses;
|
||||
}
|
||||
|
||||
TORRENT_EXPORT int session_add_torrent(void* ses, int tag, ...)
|
||||
{
|
||||
using namespace libtorrent;
|
||||
|
||||
va_list lp;
|
||||
va_start(lp, tag);
|
||||
session* s = (session*)ses;
|
||||
add_torrent_params params;
|
||||
|
||||
char const* torrent_data = 0;
|
||||
int torrent_size = 0;
|
||||
|
||||
char const* resume_data = 0;
|
||||
int resume_size = 0;
|
||||
|
||||
char const* magnet_url = 0;
|
||||
|
||||
error_code ec;
|
||||
|
||||
while (tag != TAG_END)
|
||||
{
|
||||
switch (tag)
|
||||
{
|
||||
case TOR_FILENAME:
|
||||
params.ti = new (std::nothrow) torrent_info(va_arg(lp, char const*), ec);
|
||||
break;
|
||||
case TOR_TORRENT:
|
||||
torrent_data = va_arg(lp, char const*);
|
||||
break;
|
||||
case TOR_TORRENT_SIZE:
|
||||
torrent_size = va_arg(lp, int);
|
||||
break;
|
||||
case TOR_INFOHASH:
|
||||
params.ti = new (std::nothrow) torrent_info(sha1_hash(va_arg(lp, char const*)));
|
||||
break;
|
||||
case TOR_INFOHASH_HEX:
|
||||
{
|
||||
sha1_hash ih;
|
||||
from_hex(va_arg(lp, char const*), 40, (char*)&ih[0]);
|
||||
params.ti = new (std::nothrow) torrent_info(ih);
|
||||
break;
|
||||
}
|
||||
case TOR_MAGNETLINK:
|
||||
magnet_url = va_arg(lp, char const*);
|
||||
break;
|
||||
case TOR_TRACKER_URL:
|
||||
params.tracker_url = va_arg(lp, char const*);
|
||||
break;
|
||||
case TOR_RESUME_DATA:
|
||||
resume_data = va_arg(lp, char const*);
|
||||
break;
|
||||
case TOR_RESUME_DATA_SIZE:
|
||||
resume_size = va_arg(lp, int);
|
||||
break;
|
||||
case TOR_SAVE_PATH:
|
||||
params.save_path = va_arg(lp, char const*);
|
||||
break;
|
||||
case TOR_NAME:
|
||||
params.name = va_arg(lp, char const*);
|
||||
break;
|
||||
case TOR_PAUSED:
|
||||
params.paused = va_arg(lp, int) != 0;
|
||||
break;
|
||||
case TOR_AUTO_MANAGED:
|
||||
params.auto_managed = va_arg(lp, int) != 0;
|
||||
break;
|
||||
case TOR_DUPLICATE_IS_ERROR:
|
||||
params.duplicate_is_error = va_arg(lp, int) != 0;
|
||||
break;
|
||||
case TOR_USER_DATA:
|
||||
params.userdata = va_arg(lp, void*);
|
||||
break;
|
||||
case TOR_SEED_MODE:
|
||||
params.seed_mode = va_arg(lp, int) != 0;
|
||||
break;
|
||||
case TOR_OVERRIDE_RESUME_DATA:
|
||||
params.override_resume_data = va_arg(lp, int) != 0;
|
||||
break;
|
||||
case TOR_STORAGE_MODE:
|
||||
params.storage_mode = (libtorrent::storage_mode_t)va_arg(lp, int);
|
||||
break;
|
||||
default:
|
||||
// ignore unknown tags
|
||||
va_arg(lp, void*);
|
||||
break;
|
||||
}
|
||||
|
||||
tag = va_arg(lp, int);
|
||||
}
|
||||
|
||||
if (!params.ti && torrent_data && torrent_size)
|
||||
params.ti = new (std::nothrow) torrent_info(torrent_data, torrent_size);
|
||||
|
||||
std::vector<char> rd;
|
||||
if (resume_data && resume_size)
|
||||
{
|
||||
rd.assign(resume_data, resume_data + resume_size);
|
||||
params.resume_data = &rd;
|
||||
}
|
||||
torrent_handle h;
|
||||
if (!params.ti && magnet_url)
|
||||
{
|
||||
h = add_magnet_uri(*s, magnet_url, params, ec);
|
||||
}
|
||||
else
|
||||
{
|
||||
h = s->add_torrent(params, ec);
|
||||
}
|
||||
|
||||
if (!h.is_valid())
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int i = find_handle(h);
|
||||
if (i == -1) i = add_handle(h);
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
TORRENT_EXPORT void session_remove_torrent(void* ses, int tor, int flags)
|
||||
{
|
||||
using namespace libtorrent;
|
||||
torrent_handle h = get_handle(tor);
|
||||
if (!h.is_valid()) return;
|
||||
|
||||
session* s = (session*)ses;
|
||||
s->remove_torrent(h, flags);
|
||||
}
|
||||
|
||||
TORRENT_EXPORT int session_pop_alert(void* ses, char* dest, int len, int* category)
|
||||
{
|
||||
using namespace libtorrent;
|
||||
|
||||
session* s = (session*)ses;
|
||||
|
||||
std::auto_ptr<alert> a = s->pop_alert();
|
||||
if (!a.get()) return -1;
|
||||
|
||||
if (category) *category = a->category();
|
||||
strncpy(dest, a->message().c_str(), len - 1);
|
||||
dest[len - 1] = 0;
|
||||
|
||||
return 0; // for now
|
||||
}
|
||||
|
||||
TORRENT_EXPORT int session_set_settings(void* ses, int tag, ...)
|
||||
{
|
||||
using namespace libtorrent;
|
||||
|
||||
session* s = (session*)ses;
|
||||
|
||||
va_list lp;
|
||||
va_start(lp, tag);
|
||||
|
||||
while (tag != TAG_END)
|
||||
{
|
||||
switch (tag)
|
||||
{
|
||||
case SET_UPLOAD_RATE_LIMIT:
|
||||
s->set_upload_rate_limit(va_arg(lp, int));
|
||||
break;
|
||||
case SET_DOWNLOAD_RATE_LIMIT:
|
||||
s->set_download_rate_limit(va_arg(lp, int));
|
||||
break;
|
||||
case SET_LOCAL_UPLOAD_RATE_LIMIT:
|
||||
s->set_local_upload_rate_limit(va_arg(lp, int));
|
||||
break;
|
||||
case SET_LOCAL_DOWNLOAD_RATE_LIMIT:
|
||||
s->set_local_download_rate_limit(va_arg(lp, int));
|
||||
break;
|
||||
case SET_MAX_UPLOAD_SLOTS:
|
||||
s->set_max_uploads(va_arg(lp, int));
|
||||
break;
|
||||
case SET_MAX_CONNECTIONS:
|
||||
s->set_max_connections(va_arg(lp, int));
|
||||
break;
|
||||
case SET_HALF_OPEN_LIMIT:
|
||||
s->set_max_half_open_connections(va_arg(lp, int));
|
||||
break;
|
||||
case SET_PEER_PROXY:
|
||||
{
|
||||
libtorrent::proxy_settings ps;
|
||||
copy_proxy_setting(&ps, va_arg(lp, struct proxy_setting const*));
|
||||
s->set_peer_proxy(ps);
|
||||
}
|
||||
case SET_WEB_SEED_PROXY:
|
||||
{
|
||||
libtorrent::proxy_settings ps;
|
||||
copy_proxy_setting(&ps, va_arg(lp, struct proxy_setting const*));
|
||||
s->set_web_seed_proxy(ps);
|
||||
}
|
||||
case SET_TRACKER_PROXY:
|
||||
{
|
||||
libtorrent::proxy_settings ps;
|
||||
copy_proxy_setting(&ps, va_arg(lp, struct proxy_setting const*));
|
||||
s->set_tracker_proxy(ps);
|
||||
}
|
||||
case SET_ALERT_MASK:
|
||||
{
|
||||
s->set_alert_mask(va_arg(lp, int));
|
||||
}
|
||||
#ifndef TORRENT_DISABLE_DHT
|
||||
case SET_DHT_PROXY:
|
||||
{
|
||||
libtorrent::proxy_settings ps;
|
||||
copy_proxy_setting(&ps, va_arg(lp, struct proxy_setting const*));
|
||||
s->set_dht_proxy(ps);
|
||||
}
|
||||
#endif
|
||||
case SET_PROXY:
|
||||
{
|
||||
libtorrent::proxy_settings ps;
|
||||
copy_proxy_setting(&ps, va_arg(lp, struct proxy_setting const*));
|
||||
s->set_peer_proxy(ps);
|
||||
s->set_web_seed_proxy(ps);
|
||||
s->set_tracker_proxy(ps);
|
||||
#ifndef TORRENT_DISABLE_DHT
|
||||
s->set_dht_proxy(ps);
|
||||
#endif
|
||||
}
|
||||
default:
|
||||
// ignore unknown tags
|
||||
va_arg(lp, void*);
|
||||
break;
|
||||
}
|
||||
|
||||
tag = va_arg(lp, int);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
TORRENT_EXPORT int session_get_setting(void* ses, int tag, void* value, int* value_size)
|
||||
{
|
||||
using namespace libtorrent;
|
||||
session* s = (session*)ses;
|
||||
|
||||
switch (tag)
|
||||
{
|
||||
case SET_UPLOAD_RATE_LIMIT:
|
||||
return set_int_value(value, value_size, s->upload_rate_limit());
|
||||
case SET_DOWNLOAD_RATE_LIMIT:
|
||||
return set_int_value(value, value_size, s->download_rate_limit());
|
||||
case SET_LOCAL_UPLOAD_RATE_LIMIT:
|
||||
return set_int_value(value, value_size, s->local_upload_rate_limit());
|
||||
case SET_LOCAL_DOWNLOAD_RATE_LIMIT:
|
||||
return set_int_value(value, value_size, s->local_download_rate_limit());
|
||||
case SET_MAX_UPLOAD_SLOTS:
|
||||
return set_int_value(value, value_size, s->max_uploads());
|
||||
case SET_MAX_CONNECTIONS:
|
||||
return set_int_value(value, value_size, s->max_connections());
|
||||
case SET_HALF_OPEN_LIMIT:
|
||||
return set_int_value(value, value_size, s->max_half_open_connections());
|
||||
default:
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
|
||||
TORRENT_EXPORT int session_get_status(void* sesptr, struct session_status* s, int struct_size)
|
||||
{
|
||||
libtorrent::session* ses = (libtorrent::session*)sesptr;
|
||||
|
||||
libtorrent::session_status ss = ses->status();
|
||||
if (struct_size != sizeof(session_status)) return -1;
|
||||
|
||||
s->has_incoming_connections = ss.has_incoming_connections;
|
||||
|
||||
s->upload_rate = ss.upload_rate;
|
||||
s->download_rate = ss.download_rate;
|
||||
s->total_download = ss.total_download;
|
||||
s->total_upload = ss.total_upload;
|
||||
|
||||
s->payload_upload_rate = ss.payload_upload_rate;
|
||||
s->payload_download_rate = ss.payload_download_rate;
|
||||
s->total_payload_download = ss.total_payload_download;
|
||||
s->total_payload_upload = ss.total_payload_upload;
|
||||
|
||||
s->ip_overhead_upload_rate = ss.ip_overhead_upload_rate;
|
||||
s->ip_overhead_download_rate = ss.ip_overhead_download_rate;
|
||||
s->total_ip_overhead_download = ss.total_ip_overhead_download;
|
||||
s->total_ip_overhead_upload = ss.total_ip_overhead_upload;
|
||||
|
||||
s->dht_upload_rate = ss.dht_upload_rate;
|
||||
s->dht_download_rate = ss.dht_download_rate;
|
||||
s->total_dht_download = ss.total_dht_download;
|
||||
s->total_dht_upload = ss.total_dht_upload;
|
||||
|
||||
s->tracker_upload_rate = ss.tracker_upload_rate;
|
||||
s->tracker_download_rate = ss.tracker_download_rate;
|
||||
s->total_tracker_download = ss.total_tracker_download;
|
||||
s->total_tracker_upload = ss.total_tracker_upload;
|
||||
|
||||
s->total_redundant_bytes = ss.total_redundant_bytes;
|
||||
s->total_failed_bytes = ss.total_failed_bytes;
|
||||
|
||||
s->num_peers = ss.num_peers;
|
||||
s->num_unchoked = ss.num_unchoked;
|
||||
s->allowed_upload_slots = ss.allowed_upload_slots;
|
||||
|
||||
s->up_bandwidth_queue = ss.up_bandwidth_queue;
|
||||
s->down_bandwidth_queue = ss.down_bandwidth_queue;
|
||||
|
||||
s->up_bandwidth_bytes_queue = ss.up_bandwidth_bytes_queue;
|
||||
s->down_bandwidth_bytes_queue = ss.down_bandwidth_bytes_queue;
|
||||
|
||||
s->optimistic_unchoke_counter = ss.optimistic_unchoke_counter;
|
||||
s->unchoke_counter = ss.unchoke_counter;
|
||||
|
||||
s->dht_nodes = ss.dht_nodes;
|
||||
s->dht_node_cache = ss.dht_node_cache;
|
||||
s->dht_torrents = ss.dht_torrents;
|
||||
s->dht_global_nodes = ss.dht_global_nodes;
|
||||
return 0;
|
||||
}
|
||||
|
||||
TORRENT_EXPORT int torrent_get_status(int tor, torrent_status* s, int struct_size)
|
||||
{
|
||||
libtorrent::torrent_handle h = get_handle(tor);
|
||||
if (!h.is_valid()) return -1;
|
||||
|
||||
libtorrent::torrent_status ts = h.status();
|
||||
|
||||
if (struct_size != sizeof(torrent_status)) return -1;
|
||||
|
||||
s->state = (state_t)ts.state;
|
||||
s->paused = ts.paused;
|
||||
s->progress = ts.progress;
|
||||
strncpy(s->error, ts.error.c_str(), 1025);
|
||||
s->next_announce = ts.next_announce.total_seconds();
|
||||
s->announce_interval = ts.announce_interval.total_seconds();
|
||||
strncpy(s->current_tracker, ts.current_tracker.c_str(), 512);
|
||||
s->total_download = ts.total_download = ts.total_download = ts.total_download;
|
||||
s->total_upload = ts.total_upload = ts.total_upload = ts.total_upload;
|
||||
s->total_payload_download = ts.total_payload_download;
|
||||
s->total_payload_upload = ts.total_payload_upload;
|
||||
s->total_failed_bytes = ts.total_failed_bytes;
|
||||
s->total_redundant_bytes = ts.total_redundant_bytes;
|
||||
s->download_rate = ts.download_rate;
|
||||
s->upload_rate = ts.upload_rate;
|
||||
s->download_payload_rate = ts.download_payload_rate;
|
||||
s->upload_payload_rate = ts.upload_payload_rate;
|
||||
s->num_seeds = ts.num_seeds;
|
||||
s->num_peers = ts.num_peers;
|
||||
s->num_complete = ts.num_complete;
|
||||
s->num_incomplete = ts.num_incomplete;
|
||||
s->list_seeds = ts.list_seeds;
|
||||
s->list_peers = ts.list_peers;
|
||||
s->connect_candidates = ts.connect_candidates;
|
||||
s->num_pieces = ts.num_pieces;
|
||||
s->total_done = ts.total_done;
|
||||
s->total_wanted_done = ts.total_wanted_done;
|
||||
s->total_wanted = ts.total_wanted;
|
||||
s->distributed_copies = ts.distributed_copies;
|
||||
s->block_size = ts.block_size;
|
||||
s->num_uploads = ts.num_uploads;
|
||||
s->num_connections = ts.num_connections;
|
||||
s->uploads_limit = ts.uploads_limit;
|
||||
s->connections_limit = ts.connections_limit;
|
||||
// s->storage_mode = (storage_mode_t)ts.storage_mode;
|
||||
s->up_bandwidth_queue = ts.up_bandwidth_queue;
|
||||
s->down_bandwidth_queue = ts.down_bandwidth_queue;
|
||||
s->all_time_upload = ts.all_time_upload;
|
||||
s->all_time_download = ts.all_time_download;
|
||||
s->active_time = ts.active_time;
|
||||
s->seeding_time = ts.seeding_time;
|
||||
s->seed_rank = ts.seed_rank;
|
||||
s->last_scrape = ts.last_scrape;
|
||||
s->has_incoming = ts.has_incoming;
|
||||
s->sparse_regions = ts.sparse_regions;
|
||||
s->seed_mode = ts.seed_mode;
|
||||
return 0;
|
||||
}
|
||||
|
||||
TORRENT_EXPORT int torrent_set_settings(int tor, int tag, ...)
|
||||
{
|
||||
using namespace libtorrent;
|
||||
torrent_handle h = get_handle(tor);
|
||||
if (!h.is_valid()) return -1;
|
||||
|
||||
va_list lp;
|
||||
va_start(lp, tag);
|
||||
|
||||
while (tag != TAG_END)
|
||||
{
|
||||
switch (tag)
|
||||
{
|
||||
case SET_UPLOAD_RATE_LIMIT:
|
||||
h.set_upload_limit(va_arg(lp, int));
|
||||
break;
|
||||
case SET_DOWNLOAD_RATE_LIMIT:
|
||||
h.set_download_limit(va_arg(lp, int));
|
||||
break;
|
||||
case SET_MAX_UPLOAD_SLOTS:
|
||||
h.set_max_uploads(va_arg(lp, int));
|
||||
break;
|
||||
case SET_MAX_CONNECTIONS:
|
||||
h.set_max_connections(va_arg(lp, int));
|
||||
break;
|
||||
case SET_SEQUENTIAL_DOWNLOAD:
|
||||
h.set_sequential_download(va_arg(lp, int) != 0);
|
||||
break;
|
||||
case SET_SUPER_SEEDING:
|
||||
h.super_seeding(va_arg(lp, int) != 0);
|
||||
break;
|
||||
default:
|
||||
// ignore unknown tags
|
||||
va_arg(lp, void*);
|
||||
break;
|
||||
}
|
||||
|
||||
tag = va_arg(lp, int);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
TORRENT_EXPORT int torrent_get_setting(int tor, int tag, void* value, int* value_size)
|
||||
{
|
||||
using namespace libtorrent;
|
||||
torrent_handle h = get_handle(tor);
|
||||
if (!h.is_valid()) return -1;
|
||||
|
||||
switch (tag)
|
||||
{
|
||||
case SET_UPLOAD_RATE_LIMIT:
|
||||
return set_int_value(value, value_size, h.upload_limit());
|
||||
case SET_DOWNLOAD_RATE_LIMIT:
|
||||
return set_int_value(value, value_size, h.download_limit());
|
||||
case SET_MAX_UPLOAD_SLOTS:
|
||||
return set_int_value(value, value_size, h.max_uploads());
|
||||
case SET_MAX_CONNECTIONS:
|
||||
return set_int_value(value, value_size, h.max_connections());
|
||||
case SET_SEQUENTIAL_DOWNLOAD:
|
||||
return set_int_value(value, value_size, h.is_sequential_download());
|
||||
case SET_SUPER_SEEDING:
|
||||
return set_int_value(value, value_size, h.super_seeding());
|
||||
default:
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
|
|
@ -1,298 +0,0 @@
|
|||
/*
|
||||
|
||||
Copyright (c) 2009, Arvid Norberg
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the author nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef LIBTORRENT_H
|
||||
#define LIBTORRENT_H
|
||||
|
||||
enum tags
|
||||
{
|
||||
TAG_END = 0,
|
||||
|
||||
SES_FINGERPRINT, // char const*, 2 character string
|
||||
SES_LISTENPORT, // int
|
||||
SES_LISTENPORT_END, // int
|
||||
SES_VERSION_MAJOR, // int
|
||||
SES_VERSION_MINOR, // int
|
||||
SES_VERSION_TINY, // int
|
||||
SES_VERSION_TAG, // int
|
||||
SES_FLAGS, // int
|
||||
SES_ALERT_MASK, // int
|
||||
SES_LISTEN_INTERFACE, // char const*
|
||||
|
||||
// === add_torrent tags ===
|
||||
|
||||
// identifying the torrent to add
|
||||
TOR_FILENAME = 0x100, // char const*
|
||||
TOR_TORRENT, // char const*, specify size of buffer with TOR_TORRENT_SIZE
|
||||
TOR_TORRENT_SIZE, // int
|
||||
TOR_INFOHASH, // char const*, must point to a 20 byte array
|
||||
TOR_INFOHASH_HEX, // char const*, must point to a 40 byte string
|
||||
TOR_MAGNETLINK, // char const*, url
|
||||
|
||||
TOR_TRACKER_URL, // char const*
|
||||
TOR_RESUME_DATA, // char const*
|
||||
TOR_RESUME_DATA_SIZE, // int
|
||||
TOR_SAVE_PATH, // char const*
|
||||
TOR_NAME, // char const*
|
||||
TOR_PAUSED, // int
|
||||
TOR_AUTO_MANAGED, // int
|
||||
TOR_DUPLICATE_IS_ERROR, // int
|
||||
TOR_USER_DATA, //void*
|
||||
TOR_SEED_MODE, // int
|
||||
TOR_OVERRIDE_RESUME_DATA, // int
|
||||
TOR_STORAGE_MODE, // int
|
||||
|
||||
SET_UPLOAD_RATE_LIMIT = 0x200, // int
|
||||
SET_DOWNLOAD_RATE_LIMIT, // int
|
||||
SET_LOCAL_UPLOAD_RATE_LIMIT, // int
|
||||
SET_LOCAL_DOWNLOAD_RATE_LIMIT, // int
|
||||
SET_MAX_UPLOAD_SLOTS, // int
|
||||
SET_MAX_CONNECTIONS, // int
|
||||
SET_SEQUENTIAL_DOWNLOAD, // int, torrent only
|
||||
SET_SUPER_SEEDING, // int, torrent only
|
||||
SET_HALF_OPEN_LIMIT, // int, session only
|
||||
SET_PEER_PROXY, // proxy_setting const*, session_only
|
||||
SET_WEB_SEED_PROXY, // proxy_setting const*, session_only
|
||||
SET_TRACKER_PROXY, // proxy_setting const*, session_only
|
||||
SET_DHT_PROXY, // proxy_setting const*, session_only
|
||||
SET_PROXY, // proxy_setting const*, session_only
|
||||
SET_ALERT_MASK, // int, session_only
|
||||
};
|
||||
|
||||
struct proxy_setting
|
||||
{
|
||||
char hostname[256];
|
||||
int port;
|
||||
|
||||
char username[256];
|
||||
char password[256];
|
||||
|
||||
int type;
|
||||
};
|
||||
|
||||
enum category_t
|
||||
{
|
||||
cat_error = 0x1,
|
||||
cat_peer = 0x2,
|
||||
cat_port_mapping = 0x4,
|
||||
cat_storage = 0x8,
|
||||
cat_tracker = 0x10,
|
||||
cat_debug = 0x20,
|
||||
cat_status = 0x40,
|
||||
cat_progress = 0x80,
|
||||
cat_ip_block = 0x100,
|
||||
cat_performance_warning = 0x200,
|
||||
cat_dht = 0x400,
|
||||
|
||||
cat_all_categories = 0xffffffff
|
||||
};
|
||||
|
||||
enum proxy_type_t
|
||||
{
|
||||
proxy_none,
|
||||
proxy_socks4,
|
||||
proxy_socks5,
|
||||
proxy_socks5_pw,
|
||||
proxy_http,
|
||||
proxy_http_pw
|
||||
};
|
||||
|
||||
enum storage_mode_t
|
||||
{
|
||||
storage_mode_allocate = 0,
|
||||
storage_mode_sparse,
|
||||
storage_mode_compact
|
||||
};
|
||||
|
||||
enum state_t
|
||||
{
|
||||
queued_for_checking,
|
||||
checking_files,
|
||||
downloading_metadata,
|
||||
downloading,
|
||||
finished,
|
||||
seeding,
|
||||
allocating,
|
||||
checking_resume_data
|
||||
};
|
||||
|
||||
struct torrent_status
|
||||
{
|
||||
enum state_t state;
|
||||
int paused;
|
||||
float progress;
|
||||
char error[1024];
|
||||
int next_announce;
|
||||
int announce_interval;
|
||||
char current_tracker[512];
|
||||
long long total_download;
|
||||
long long total_upload;
|
||||
long long total_payload_download;
|
||||
long long total_payload_upload;
|
||||
long long total_failed_bytes;
|
||||
long long total_redundant_bytes;
|
||||
float download_rate;
|
||||
float upload_rate;
|
||||
float download_payload_rate;
|
||||
float upload_payload_rate;
|
||||
int num_seeds;
|
||||
int num_peers;
|
||||
int num_complete;
|
||||
int num_incomplete;
|
||||
int list_seeds;
|
||||
int list_peers;
|
||||
int connect_candidates;
|
||||
|
||||
// what to do?
|
||||
// bitfield pieces;
|
||||
|
||||
int num_pieces;
|
||||
long long total_done;
|
||||
long long total_wanted_done;
|
||||
long long total_wanted;
|
||||
float distributed_copies;
|
||||
int block_size;
|
||||
int num_uploads;
|
||||
int num_connections;
|
||||
int uploads_limit;
|
||||
int connections_limit;
|
||||
// enum storage_mode_t storage_mode;
|
||||
int up_bandwidth_queue;
|
||||
int down_bandwidth_queue;
|
||||
long long all_time_upload;
|
||||
long long all_time_download;
|
||||
int active_time;
|
||||
int seeding_time;
|
||||
int seed_rank;
|
||||
int last_scrape;
|
||||
int has_incoming;
|
||||
int sparse_regions;
|
||||
int seed_mode;
|
||||
};
|
||||
|
||||
struct session_status
|
||||
{
|
||||
int has_incoming_connections;
|
||||
|
||||
float upload_rate;
|
||||
float download_rate;
|
||||
long long total_download;
|
||||
long long total_upload;
|
||||
|
||||
float payload_upload_rate;
|
||||
float payload_download_rate;
|
||||
long long total_payload_download;
|
||||
long long total_payload_upload;
|
||||
|
||||
float ip_overhead_upload_rate;
|
||||
float ip_overhead_download_rate;
|
||||
long long total_ip_overhead_download;
|
||||
long long total_ip_overhead_upload;
|
||||
|
||||
float dht_upload_rate;
|
||||
float dht_download_rate;
|
||||
long long total_dht_download;
|
||||
long long total_dht_upload;
|
||||
|
||||
float tracker_upload_rate;
|
||||
float tracker_download_rate;
|
||||
long long total_tracker_download;
|
||||
long long total_tracker_upload;
|
||||
|
||||
long long total_redundant_bytes;
|
||||
long long total_failed_bytes;
|
||||
|
||||
int num_peers;
|
||||
int num_unchoked;
|
||||
int allowed_upload_slots;
|
||||
|
||||
int up_bandwidth_queue;
|
||||
int down_bandwidth_queue;
|
||||
|
||||
int up_bandwidth_bytes_queue;
|
||||
int down_bandwidth_bytes_queue;
|
||||
|
||||
int optimistic_unchoke_counter;
|
||||
int unchoke_counter;
|
||||
|
||||
int dht_nodes;
|
||||
int dht_node_cache;
|
||||
int dht_torrents;
|
||||
long long dht_global_nodes;
|
||||
// std::vector<dht_lookup> active_requests;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
// the functions whose signature ends with:
|
||||
// , int first_tag, ...);
|
||||
// takes a tag list. The tag list is a series
|
||||
// of tag-value pairs. The tags are constants
|
||||
// identifying which property the value controls.
|
||||
// The type of the value varies between tags.
|
||||
// The enumeration above specifies which type
|
||||
// it expects. All tag lists must always be
|
||||
// terminated by TAG_END.
|
||||
|
||||
// use SES_* tags in tag list
|
||||
void* session_create(int first_tag, ...);
|
||||
void session_close(void* ses);
|
||||
|
||||
// use TOR_* tags in tag list
|
||||
int session_add_torrent(void* ses, int first_tag, ...);
|
||||
void session_remove_torrent(void* ses, int tor, int flags);
|
||||
|
||||
// return < 0 if there are no alerts. Otherwise returns the
|
||||
// type of alert that was returned
|
||||
int session_pop_alert(void* ses, char* dest, int len, int* category);
|
||||
|
||||
int session_get_status(void* ses, struct session_status* s, int struct_size);
|
||||
|
||||
// use SET_* tags in tag list
|
||||
int session_set_settings(void* ses, int first_tag, ...);
|
||||
int session_get_setting(void* ses, int tag, void* value, int* value_size);
|
||||
|
||||
int torrent_get_status(int tor, struct torrent_status* s, int struct_size);
|
||||
|
||||
// use SET_* tags in tag list
|
||||
int torrent_set_settings(int tor, int first_tag, ...);
|
||||
int torrent_get_setting(int tor, int tag, void* value, int* value_size);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -1,123 +0,0 @@
|
|||
/*
|
||||
|
||||
Copyright (c) 2009, Arvid Norberg
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the author nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#include <libtorrent.h>
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
|
||||
int quit = 0;
|
||||
|
||||
void stop(int signal)
|
||||
{
|
||||
quit = 1;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
if (argc != 2)
|
||||
{
|
||||
fprintf(stderr, "usage: ./simple_client torrent-file\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ret = 0;
|
||||
void* ses = session_create(
|
||||
SES_LISTENPORT, 6881,
|
||||
SES_LISTENPORT_END, 6889,
|
||||
SES_ALERT_MASK, ~(cat_progress | cat_port_mapping | cat_debug | cat_performance_warning | cat_peer),
|
||||
TAG_END);
|
||||
|
||||
int t = session_add_torrent(ses,
|
||||
TOR_FILENAME, argv[1],
|
||||
TOR_SAVE_PATH, "./",
|
||||
TAG_END);
|
||||
|
||||
if (t < 0)
|
||||
{
|
||||
fprintf(stderr, "Failed to add torrent\n");
|
||||
ret = 1;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
struct torrent_status st;
|
||||
|
||||
printf("press ctrl-C to stop\n");
|
||||
|
||||
signal(SIGINT, &stop);
|
||||
signal(SIGABRT, &stop);
|
||||
signal(SIGQUIT, &stop);
|
||||
|
||||
while (quit == 0)
|
||||
{
|
||||
char const* message = "";
|
||||
|
||||
char const* state[] = {"queued", "checking", "downloading metadata"
|
||||
, "downloading", "finished", "seeding", "allocating"
|
||||
, "checking_resume_data"};
|
||||
|
||||
if (torrent_get_status(t, &st, sizeof(st)) < 0) break;
|
||||
printf("\r%3.f%% %d kB (%5.f kB/s) up: %d kB (%5.f kB/s) peers: %d '%s' %s "
|
||||
, (double)st.progress * 100.
|
||||
, (int)(st.total_payload_download / 1000)
|
||||
, (double)st.download_payload_rate / 1000.
|
||||
, (int)(st.total_payload_upload / 1000)
|
||||
, (double)st.upload_payload_rate / 1000.
|
||||
, st.num_peers
|
||||
, state[st.state]
|
||||
, message);
|
||||
|
||||
|
||||
char msg[400];
|
||||
while (session_pop_alert(ses, msg, sizeof(msg), 0) >= 0)
|
||||
{
|
||||
printf("%s\n", msg);
|
||||
}
|
||||
|
||||
if (strlen(st.error) > 0)
|
||||
{
|
||||
fprintf(stderr, "\nERROR: %s\n", st.error);
|
||||
break;
|
||||
}
|
||||
|
||||
fflush(stdout);
|
||||
usleep(1000000);
|
||||
}
|
||||
printf("\nclosing\n");
|
||||
|
||||
exit:
|
||||
|
||||
session_close(ses);
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -1,66 +0,0 @@
|
|||
import python ;
|
||||
|
||||
use-project /torrent : ../.. ;
|
||||
|
||||
lib boost_python : : <target-os>darwin <name>boost_python-mt $(boost-library-search-path) ;
|
||||
lib boost_python : : <name>boost_python ;
|
||||
|
||||
rule libtorrent_linking ( properties * )
|
||||
{
|
||||
local result ;
|
||||
|
||||
if <toolset>gcc in $(properties)
|
||||
{
|
||||
result += <fpic>on ;
|
||||
}
|
||||
|
||||
# if <toolset>gcc in $(properties) || <toolset>darwin in $(properties)
|
||||
# {
|
||||
# result += <visibility>hidden ;
|
||||
# }
|
||||
|
||||
# when building peer_plugin.cpp on msvc-7.1 it fails
|
||||
# running out of internal heap space. Don't add it
|
||||
# to windows build, since it's not critical anyway
|
||||
if <toolset>msvc in $(properties)
|
||||
{
|
||||
result += <define>TORRENT_NO_PYTHON_PLUGINS ;
|
||||
}
|
||||
else
|
||||
{
|
||||
result += <source>src/peer_plugin.cpp ;
|
||||
}
|
||||
return $(result) ;
|
||||
}
|
||||
|
||||
python-extension libtorrent
|
||||
: src/module.cpp
|
||||
src/big_number.cpp
|
||||
src/converters.cpp
|
||||
src/create_torrent.cpp
|
||||
src/fingerprint.cpp
|
||||
src/utility.cpp
|
||||
src/session.cpp
|
||||
src/entry.cpp
|
||||
src/torrent_info.cpp
|
||||
src/torrent_handle.cpp
|
||||
src/torrent_status.cpp
|
||||
src/session_settings.cpp
|
||||
src/version.cpp
|
||||
src/alert.cpp
|
||||
src/datetime.cpp
|
||||
src/extensions.cpp
|
||||
src/torrent.cpp
|
||||
src/peer_info.cpp
|
||||
src/ip_filter.cpp
|
||||
src/magnet_uri.cpp
|
||||
: <include>src
|
||||
<library>/torrent//torrent/<link>static
|
||||
<boost>system:<library>boost_python
|
||||
<boost>source,<boost-link>static:<library>/boost/python//boost_python/<link>static
|
||||
<boost>source,<boost-link>shared:<library>/boost/python//boost_python/<link>shared
|
||||
<conditional>@libtorrent_linking
|
||||
;
|
||||
|
||||
install stage_module : libtorrent : <location>. ;
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
|
||||
EXTRA_DIST = \
|
||||
Jamfile \
|
||||
setup.py \
|
||||
client.py \
|
||||
simple_client.py \
|
||||
src/alert.cpp \
|
||||
src/big_number.cpp \
|
||||
src/converters.cpp \
|
||||
src/create_torrent.cpp \
|
||||
src/datetime.cpp \
|
||||
src/entry.cpp \
|
||||
src/extensions.cpp \
|
||||
src/fingerprint.cpp \
|
||||
src/gil.hpp \
|
||||
src/ip_filter.cpp \
|
||||
src/magnet_uri.cpp \
|
||||
src/module.cpp \
|
||||
src/optional.hpp \
|
||||
src/peer_info.cpp \
|
||||
src/peer_plugin.cpp \
|
||||
src/session.cpp \
|
||||
src/session_settings.cpp \
|
||||
src/torrent.cpp \
|
||||
src/torrent_handle.cpp \
|
||||
src/torrent_info.cpp \
|
||||
src/torrent_status.cpp \
|
||||
src/utility.cpp \
|
||||
src/version.cpp
|
||||
|
||||
if ENABLE_PYTHON_BINDING
|
||||
|
||||
all-local:
|
||||
$(PYTHON) setup.py build
|
||||
|
||||
install-exec-local:
|
||||
$(PYTHON) setup.py install @PYTHON_INSTALL_PARAMS@
|
||||
|
||||
uninstall-local:
|
||||
rm -rf $(DESTDIR)$(libdir)/python*/*-packages/*libtorrent*
|
||||
|
||||
clean-local:
|
||||
$(PYTHON) setup.py clean --all
|
||||
|
||||
endif
|
|
@ -1,364 +0,0 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
# Copyright Daniel Wallin 2006. Use, modification and distribution is
|
||||
# subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
import sys
|
||||
import libtorrent as lt
|
||||
import time
|
||||
import os.path
|
||||
import sys
|
||||
|
||||
class WindowsConsole:
|
||||
def __init__(self):
|
||||
self.console = Console.getconsole()
|
||||
|
||||
def clear(self):
|
||||
self.console.page()
|
||||
|
||||
def write(self, str):
|
||||
self.console.write(str)
|
||||
|
||||
def sleep_and_input(self, seconds):
|
||||
time.sleep(seconds)
|
||||
if msvcrt.kbhit():
|
||||
return msvcrt.getch()
|
||||
return None
|
||||
|
||||
class UnixConsole:
|
||||
def __init__(self):
|
||||
self.fd = sys.stdin
|
||||
self.old = termios.tcgetattr(self.fd.fileno())
|
||||
new = termios.tcgetattr(self.fd.fileno())
|
||||
new[3] = new[3] & ~termios.ICANON
|
||||
new[6][termios.VTIME] = 0
|
||||
new[6][termios.VMIN] = 1
|
||||
termios.tcsetattr(self.fd.fileno(), termios.TCSADRAIN, new)
|
||||
|
||||
sys.exitfunc = self._onexit
|
||||
|
||||
def _onexit(self):
|
||||
termios.tcsetattr(self.fd.fileno(), termios.TCSADRAIN, self.old)
|
||||
|
||||
def clear(self):
|
||||
sys.stdout.write('\033[2J\033[0;0H')
|
||||
sys.stdout.flush()
|
||||
|
||||
def write(self, str):
|
||||
sys.stdout.write(str)
|
||||
sys.stdout.flush()
|
||||
|
||||
def sleep_and_input(self, seconds):
|
||||
read,_,_ = select.select([self.fd.fileno()], [], [], seconds)
|
||||
if len(read) > 0:
|
||||
return self.fd.read(1)
|
||||
return None
|
||||
|
||||
if os.name == 'nt':
|
||||
import Console
|
||||
import msvcrt
|
||||
else:
|
||||
import termios
|
||||
import select
|
||||
|
||||
class PythonExtension(lt.torrent_plugin):
|
||||
def __init__(self, alerts):
|
||||
lt.torrent_plugin.__init__(self)
|
||||
self.alerts = alerts
|
||||
self.alerts.append('PythonExtension')
|
||||
self.count = 0
|
||||
|
||||
def on_piece_pass(self, index):
|
||||
self.alerts.append('got piece %d' % index)
|
||||
|
||||
def on_piece_failed(self, index):
|
||||
self.alerts.append('failed piece %d' % index)
|
||||
|
||||
def tick(self):
|
||||
self.count += 1
|
||||
if self.count >= 10:
|
||||
self.count = 0
|
||||
self.alerts.append('PythonExtension tick')
|
||||
|
||||
def write_line(console, line):
|
||||
console.write(line)
|
||||
|
||||
def add_suffix(val):
|
||||
prefix = ['B', 'kB', 'MB', 'GB', 'TB']
|
||||
for i in range(len(prefix)):
|
||||
if abs(val) < 1000:
|
||||
if i == 0:
|
||||
return '%5.3g%s' % (val, prefix[i])
|
||||
else:
|
||||
return '%4.3g%s' % (val, prefix[i])
|
||||
val /= 1000
|
||||
|
||||
return '%6.3gPB' % val
|
||||
|
||||
def progress_bar(progress, width):
|
||||
assert(progress <= 1)
|
||||
progress_chars = int(progress * width + 0.5)
|
||||
return progress_chars * '#' + (width - progress_chars) * '-'
|
||||
|
||||
def print_peer_info(console, peers):
|
||||
|
||||
out = ' down (total ) up (total ) q r flags block progress client\n'
|
||||
|
||||
for p in peers:
|
||||
|
||||
out += '%s/s ' % add_suffix(p.down_speed)
|
||||
out += '(%s) ' % add_suffix(p.total_download)
|
||||
out += '%s/s ' % add_suffix(p.up_speed)
|
||||
out += '(%s) ' % add_suffix(p.total_upload)
|
||||
out += '%2d ' % p.download_queue_length
|
||||
out += '%2d ' % p.upload_queue_length
|
||||
|
||||
if p.flags & lt.peer_info.interesting: out += 'I'
|
||||
else: out += '.'
|
||||
if p.flags & lt.peer_info.choked: out += 'C'
|
||||
else: out += '.'
|
||||
if p.flags & lt.peer_info.remote_interested: out += 'i'
|
||||
else: out += '.'
|
||||
if p.flags & lt.peer_info.remote_choked: out += 'c'
|
||||
else: out += '.'
|
||||
if p.flags & lt.peer_info.supports_extensions: out += 'e'
|
||||
else: out += '.'
|
||||
if p.flags & lt.peer_info.local_connection: out += 'l'
|
||||
else: out += 'r'
|
||||
out += ' '
|
||||
|
||||
if p.downloading_piece_index >= 0:
|
||||
assert(p.downloading_progress <= p.downloading_total)
|
||||
out += progress_bar(float(p.downloading_progress) / p.downloading_total, 15)
|
||||
else:
|
||||
out += progress_bar(0, 15)
|
||||
out += ' '
|
||||
|
||||
if p.flags & lt.peer_info.handshake:
|
||||
id = 'waiting for handshake'
|
||||
elif p.flags & lt.peer_info.connecting:
|
||||
id = 'connecting to peer'
|
||||
elif p.flags & lt.peer_info.queued:
|
||||
id = 'queued'
|
||||
else:
|
||||
id = p.client
|
||||
|
||||
out += '%s\n' % id[:10]
|
||||
|
||||
write_line(console, out)
|
||||
|
||||
|
||||
def print_download_queue(console, download_queue):
|
||||
|
||||
out = ""
|
||||
|
||||
for e in download_queue:
|
||||
out += '%4d: [' % e['piece_index'];
|
||||
for b in e['blocks']:
|
||||
s = b['state']
|
||||
if s == 3:
|
||||
out += '#'
|
||||
elif s == 2:
|
||||
out += '='
|
||||
elif s == 1:
|
||||
out += '-'
|
||||
else:
|
||||
out += ' '
|
||||
out += ']\n'
|
||||
|
||||
write_line(console, out)
|
||||
|
||||
def main():
|
||||
from optparse import OptionParser
|
||||
|
||||
parser = OptionParser()
|
||||
|
||||
parser.add_option('-p', '--port',
|
||||
type='int', help='set listening port')
|
||||
|
||||
parser.add_option('-r', '--ratio',
|
||||
type='float', help='set the preferred upload/download ratio. 0 means infinite. Values smaller than 1 are clamped to 1')
|
||||
|
||||
parser.add_option('-d', '--max-download-rate',
|
||||
type='float', help='the maximum download rate given in kB/s. 0 means infinite.')
|
||||
|
||||
parser.add_option('-u', '--max-upload-rate',
|
||||
type='float', help='the maximum upload rate given in kB/s. 0 means infinite.')
|
||||
|
||||
parser.add_option('-s', '--save-path',
|
||||
type='string', help='the path where the downloaded file/folder should be placed.')
|
||||
|
||||
parser.add_option('-a', '--allocation-mode',
|
||||
type='string', help='sets mode used for allocating the downloaded files on disk. Possible options are [full | compact]')
|
||||
|
||||
parser.set_defaults(
|
||||
port=6881
|
||||
, ratio=0
|
||||
, max_download_rate=0
|
||||
, max_upload_rate=0
|
||||
, save_path='./'
|
||||
, allocation_mode='compact'
|
||||
)
|
||||
|
||||
(options, args) = parser.parse_args()
|
||||
|
||||
if options.port < 0 or options.port > 65525:
|
||||
options.port = 6881
|
||||
|
||||
options.max_upload_rate *= 1000
|
||||
options.max_download_rate *= 1000
|
||||
|
||||
if options.max_upload_rate <= 0:
|
||||
options.max_upload_rate = -1
|
||||
if options.max_download_rate <= 0:
|
||||
options.max_download_rate = -1
|
||||
|
||||
compact_allocation = options.allocation_mode == 'compact'
|
||||
|
||||
settings = lt.session_settings()
|
||||
settings.user_agent = 'python_client/' + lt.version
|
||||
|
||||
ses = lt.session()
|
||||
ses.set_download_rate_limit(int(options.max_download_rate))
|
||||
ses.set_upload_rate_limit(int(options.max_upload_rate))
|
||||
ses.listen_on(options.port, options.port + 10)
|
||||
ses.set_settings(settings)
|
||||
# ses.set_severity_level(lt.alert.severity_levels.info)
|
||||
ses.add_extension(lt.create_ut_pex_plugin)
|
||||
ses.add_extension(lt.create_ut_metadata_plugin)
|
||||
ses.add_extension(lt.create_metadata_plugin)
|
||||
|
||||
handles = []
|
||||
alerts = []
|
||||
|
||||
# Extensions
|
||||
# ses.add_extension(lambda x: PythonExtension(alerts))
|
||||
|
||||
for f in args:
|
||||
e = lt.bdecode(open(f, 'rb').read())
|
||||
info = lt.torrent_info(e)
|
||||
print 'Adding \'%s\'...' % info.name()
|
||||
|
||||
atp = {}
|
||||
try:
|
||||
atp["resume_data"] = open(os.path.join(options.save_path, info.name() + '.fastresume'), 'rb').read()
|
||||
except:
|
||||
pass
|
||||
|
||||
atp["ti"] = info
|
||||
atp["save_path"] = options.save_path
|
||||
atp["storage_mode"] = lt.storage_mode_t.storage_mode_sparse
|
||||
atp["paused"] = False
|
||||
atp["auto_managed"] = True
|
||||
atp["duplicate_is_error"] = True
|
||||
|
||||
h = ses.add_torrent(atp)
|
||||
|
||||
handles.append(h)
|
||||
|
||||
h.set_max_connections(60)
|
||||
h.set_max_uploads(-1)
|
||||
h.set_ratio(options.ratio)
|
||||
|
||||
if os.name == 'nt':
|
||||
console = WindowsConsole()
|
||||
else:
|
||||
console = UnixConsole()
|
||||
|
||||
alive = True
|
||||
while alive:
|
||||
console.clear()
|
||||
|
||||
out = ''
|
||||
|
||||
for h in handles:
|
||||
if h.has_metadata():
|
||||
name = h.get_torrent_info().name()[:40]
|
||||
else:
|
||||
name = '-'
|
||||
out += 'name: %-40s\n' % name
|
||||
|
||||
s = h.status()
|
||||
|
||||
if s.state != lt.torrent_status.seeding:
|
||||
state_str = ['queued', 'checking', 'downloading metadata', \
|
||||
'downloading', 'finished', 'seeding', \
|
||||
'allocating', 'checking fastresume']
|
||||
out += state_str[s.state] + ' '
|
||||
|
||||
out += '%5.4f%% ' % (s.progress*100)
|
||||
out += progress_bar(s.progress, 49)
|
||||
out += '\n'
|
||||
|
||||
out += 'total downloaded: %d Bytes\n' % s.total_done
|
||||
out += 'peers: %d seeds: %d distributed copies: %d\n' % \
|
||||
(s.num_peers, s.num_seeds, s.distributed_copies)
|
||||
out += '\n'
|
||||
|
||||
out += 'download: %s/s (%s) ' \
|
||||
% (add_suffix(s.download_rate), add_suffix(s.total_download))
|
||||
out += 'upload: %s/s (%s) ' \
|
||||
% (add_suffix(s.upload_rate), add_suffix(s.total_upload))
|
||||
out += 'ratio: %s\n' % '0'
|
||||
|
||||
if s.state != lt.torrent_status.seeding:
|
||||
out += 'info-hash: %s\n' % h.info_hash()
|
||||
out += 'next announce: %s\n' % s.next_announce
|
||||
out += 'tracker: %s\n' % s.current_tracker
|
||||
|
||||
write_line(console, out)
|
||||
|
||||
print_peer_info(console, h.get_peer_info())
|
||||
print_download_queue(console, h.get_download_queue())
|
||||
|
||||
if True and s.state != lt.torrent_status.seeding:
|
||||
out = '\n'
|
||||
fp = h.file_progress()
|
||||
ti = h.get_torrent_info()
|
||||
for f,p in zip(ti.files(), fp):
|
||||
out += progress_bar(p / f.size, 20)
|
||||
out += ' ' + f.path + '\n'
|
||||
write_line(console, out)
|
||||
|
||||
write_line(console, 76 * '-' + '\n')
|
||||
write_line(console, '(q)uit), (p)ause), (u)npause), (r)eannounce\n')
|
||||
write_line(console, 76 * '-' + '\n')
|
||||
|
||||
while 1:
|
||||
a = ses.pop_alert()
|
||||
if not a: break
|
||||
alerts.append(a)
|
||||
|
||||
if len(alerts) > 8:
|
||||
del alerts[:len(alerts) - 8]
|
||||
|
||||
for a in alerts:
|
||||
if type(a) == str:
|
||||
write_line(console, a + '\n')
|
||||
else:
|
||||
write_line(console, a.message() + '\n')
|
||||
|
||||
c = console.sleep_and_input(0.5)
|
||||
|
||||
if not c:
|
||||
continue
|
||||
|
||||
if c == 'r':
|
||||
for h in handles: h.force_reannounce()
|
||||
elif c == 'q':
|
||||
alive = False
|
||||
elif c == 'p':
|
||||
for h in handles: h.pause()
|
||||
elif c == 'u':
|
||||
for h in handles: h.resume()
|
||||
|
||||
ses.pause()
|
||||
for h in handles:
|
||||
if not h.is_valid() or not h.has_metadata():
|
||||
continue
|
||||
data = lt.bencode(h.write_resume_data())
|
||||
open(os.path.join(options.save_path, h.get_torrent_info().name() + '.fastresume'), 'wb').write(data)
|
||||
|
||||
main()
|
||||
|
|
@ -1,86 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
from distutils import sysconfig
|
||||
from distutils.core import setup, Extension
|
||||
import os
|
||||
import platform
|
||||
import sys
|
||||
|
||||
if '@BOOST_PYTHON_LIB@' == '':
|
||||
print 'You need to pass --enable-python-binding to configure in order ',
|
||||
print 'to properly use this setup. There is no boost.python library configured now'
|
||||
sys.exit(1)
|
||||
|
||||
def parse_cmd(cmdline, prefix, keep_prefix = False):
|
||||
ret = []
|
||||
for token in cmdline.split():
|
||||
if token[:len(prefix)] == prefix:
|
||||
if keep_prefix:
|
||||
ret.append(token)
|
||||
else:
|
||||
ret.append(token[len(prefix):])
|
||||
return ret
|
||||
|
||||
def arch():
|
||||
if platform.system() != 'Darwin': return []
|
||||
a = os.uname()[4]
|
||||
if a == 'Power Macintosh': a = 'ppc'
|
||||
return ['-arch', a]
|
||||
|
||||
if platform.system() == 'Windows':
|
||||
# on windows, build using bjam and build an installer
|
||||
import shutil
|
||||
# msvc 9.0 (2008) is the official windows compiler for python 2.6
|
||||
# http://docs.python.org/whatsnew/2.6.html#build-and-c-api-changes
|
||||
if os.system('bjam boost=source link=static geoip=static boost-link=static release msvc-9.0 optimization=space') != 0:
|
||||
print 'build failed'
|
||||
sys.exit(1)
|
||||
try: os.mkdir(r'build')
|
||||
except: pass
|
||||
try: os.mkdir(r'build\lib')
|
||||
except: pass
|
||||
try: os.mkdir(r'libtorrent')
|
||||
except: pass
|
||||
shutil.copyfile(r'bin\msvc-9.0\release\boost-source\geoip-static\link-static\optimization-space\threading-multi\libtorrent.pyd', r'.\build\lib\libtorrent.pyd')
|
||||
setup( name='python-libtorrent',
|
||||
version='@PACKAGE_VERSION@',
|
||||
author = 'Arvid Norberg',
|
||||
author_email='@PACKAGE_BUGREPORT@',
|
||||
description = 'Python bindings for libtorrent-rasterbar',
|
||||
long_description = 'Python bindings for libtorrent-rasterbar',
|
||||
url = 'http://www.rasterbar.com/products/libtorrent/index.html',
|
||||
platforms = 'Windows',
|
||||
license = 'Boost Software License - Version 1.0 - August 17th, 2003',
|
||||
packages = ['libtorrent'],
|
||||
)
|
||||
sys.exit(0)
|
||||
|
||||
config_vars = sysconfig.get_config_vars()
|
||||
if "CFLAGS" in config_vars and "-Wstrict-prototypes" in config_vars["CFLAGS"]:
|
||||
config_vars["CFLAGS"] = config_vars["CFLAGS"].replace("-Wstrict-prototypes", " ")
|
||||
if "OPT" in config_vars and "-Wstrict-prototypes" in config_vars["OPT"]:
|
||||
config_vars["OPT"] = config_vars["OPT"].replace("-Wstrict-prototypes", " ")
|
||||
|
||||
source_list = os.listdir(os.path.join(os.path.dirname(__file__), "src"))
|
||||
source_list = [os.path.join("src", s) for s in source_list if s.endswith(".cpp")]
|
||||
|
||||
extra_cmd = '@COMPILETIME_OPTIONS@ @CPPFLAGS@ @LIBS@ @BOOST_SYSTEM_LIB@ @BOOST_PYTHON_LIB@ @PTHREAD_LIBS@ @OPENSSL_LIBS@ @OPENSSL_LDFLAGS@ @OPENSSL_INCLUDES@'
|
||||
|
||||
setup( name='python-libtorrent',
|
||||
version='@PACKAGE_VERSION@',
|
||||
author = 'Arvid Norberg',
|
||||
author_email='@PACKAGE_BUGREPORT@',
|
||||
description = 'Python bindings for libtorrent-rasterbar',
|
||||
long_description = 'Python bindings for libtorrent-rasterbar',
|
||||
url = 'http://www.rasterbar.com/products/libtorrent/index.html',
|
||||
platforms = 'any',
|
||||
license = 'Boost Software License - Version 1.0 - August 17th, 2003',
|
||||
ext_modules = [Extension('libtorrent',
|
||||
sources = source_list,
|
||||
language='c++',
|
||||
include_dirs = ['@top_srcdir@/include'] + parse_cmd(extra_cmd, '-I'),
|
||||
library_dirs = ['@top_builddir@/src/.libs'] + parse_cmd(extra_cmd, '-L'),
|
||||
extra_link_args = '@LDFLAGS@'.split() + arch(),
|
||||
extra_compile_args = parse_cmd(extra_cmd, '-D', True) + arch(),
|
||||
libraries = ['torrent-rasterbar'] + parse_cmd(extra_cmd, '-l'))],
|
||||
)
|
|
@ -1,31 +0,0 @@
|
|||
#!/bin/python
|
||||
# Copyright Arvid Norberg 2008. Use, modification and distribution is
|
||||
# subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
|
||||
import libtorrent as lt
|
||||
import time
|
||||
import sys
|
||||
|
||||
ses = lt.session()
|
||||
ses.listen_on(6881, 6891)
|
||||
|
||||
info = lt.torrent_info(sys.argv[1])
|
||||
h = ses.add_torrent({'ti': info, 'save_path': './'})
|
||||
print 'starting', h.name()
|
||||
|
||||
while (not h.is_seed()):
|
||||
s = h.status()
|
||||
|
||||
state_str = ['queued', 'checking', 'downloading metadata', \
|
||||
'downloading', 'finished', 'seeding', 'allocating', 'checking fastresume']
|
||||
print '\r%.2f%% complete (down: %.1f kb/s up: %.1f kB/s peers: %d) %s' % \
|
||||
(s.progress * 100, s.download_rate / 1000, s.upload_rate / 1000, \
|
||||
s.num_peers, state_str[s.state]),
|
||||
sys.stdout.flush()
|
||||
|
||||
time.sleep(1)
|
||||
|
||||
print h.name(), 'complete'
|
||||
|
|
@ -1,400 +0,0 @@
|
|||
// Copyright Daniel Wallin 2006. Use, modification and distribution is
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/python.hpp>
|
||||
#include <libtorrent/alert.hpp>
|
||||
#include <libtorrent/alert_types.hpp>
|
||||
|
||||
using namespace boost::python;
|
||||
using namespace libtorrent;
|
||||
|
||||
std::string get_buffer(read_piece_alert const& rpa)
|
||||
{
|
||||
return rpa.buffer ? std::string(rpa.buffer.get(), rpa.size)
|
||||
: std::string();
|
||||
}
|
||||
|
||||
void bind_alert()
|
||||
{
|
||||
using boost::noncopyable;
|
||||
|
||||
{
|
||||
scope alert_scope = class_<alert, noncopyable>("alert", no_init)
|
||||
.def("message", &alert::message)
|
||||
.def("what", &alert::what)
|
||||
.def("category", &alert::category)
|
||||
#ifndef TORRENT_NO_DEPRECATE
|
||||
.def("severity", &alert::severity)
|
||||
#endif
|
||||
.def("__str__", &alert::message)
|
||||
;
|
||||
|
||||
#ifndef TORRENT_NO_DEPRECATE
|
||||
enum_<alert::severity_t>("severity_levels")
|
||||
.value("debug", alert::debug)
|
||||
.value("info", alert::info)
|
||||
.value("warning", alert::warning)
|
||||
.value("critical", alert::critical)
|
||||
.value("fatal", alert::fatal)
|
||||
.value("none", alert::none)
|
||||
;
|
||||
#endif
|
||||
|
||||
enum_<alert::category_t>("category_t")
|
||||
.value("error_notification", alert::error_notification)
|
||||
.value("peer_notification", alert::peer_notification)
|
||||
.value("port_mapping_notification", alert::port_mapping_notification)
|
||||
.value("storage_notification", alert::storage_notification)
|
||||
.value("tracker_notification", alert::tracker_notification)
|
||||
.value("debug_notification", alert::debug_notification)
|
||||
.value("status_notification", alert::status_notification)
|
||||
.value("progress_notification", alert::progress_notification)
|
||||
.value("ip_block_notification", alert::ip_block_notification)
|
||||
.value("performance_warning", alert::performance_warning)
|
||||
.value("all_categories", alert::all_categories)
|
||||
;
|
||||
|
||||
}
|
||||
|
||||
class_<torrent_alert, bases<alert>, noncopyable>(
|
||||
"torrent_alert", no_init)
|
||||
.def_readonly("handle", &torrent_alert::handle)
|
||||
;
|
||||
|
||||
class_<tracker_alert, bases<torrent_alert>, noncopyable>(
|
||||
"tracker_alert", no_init)
|
||||
.def_readonly("url", &tracker_alert::url)
|
||||
;
|
||||
|
||||
class_<read_piece_alert, bases<torrent_alert>, noncopyable>(
|
||||
"read_piece_alert", 0, no_init)
|
||||
.add_property("buffer", get_buffer)
|
||||
.def_readonly("piece", &read_piece_alert::piece)
|
||||
.def_readonly("size", &read_piece_alert::size)
|
||||
;
|
||||
|
||||
class_<peer_alert, bases<torrent_alert>, noncopyable>(
|
||||
"peer_alert", no_init)
|
||||
.def_readonly("ip", &peer_alert::ip)
|
||||
.def_readonly("pid", &peer_alert::pid)
|
||||
;
|
||||
class_<tracker_error_alert, bases<tracker_alert>, noncopyable>(
|
||||
"tracker_error_alert", no_init)
|
||||
.def_readonly("msg", &tracker_error_alert::msg)
|
||||
.def_readonly("times_in_row", &tracker_error_alert::times_in_row)
|
||||
.def_readonly("status_code", &tracker_error_alert::status_code)
|
||||
;
|
||||
|
||||
class_<tracker_warning_alert, bases<tracker_alert>, noncopyable>(
|
||||
"tracker_warning_alert", no_init);
|
||||
|
||||
class_<tracker_reply_alert, bases<tracker_alert>, noncopyable>(
|
||||
"tracker_reply_alert", no_init)
|
||||
.def_readonly("num_peers", &tracker_reply_alert::num_peers)
|
||||
;
|
||||
|
||||
class_<tracker_announce_alert, bases<tracker_alert>, noncopyable>(
|
||||
"tracker_announce_alert", no_init)
|
||||
.def_readonly("event", &tracker_announce_alert::event)
|
||||
;
|
||||
|
||||
class_<hash_failed_alert, bases<torrent_alert>, noncopyable>(
|
||||
"hash_failed_alert", no_init)
|
||||
.def_readonly("piece_index", &hash_failed_alert::piece_index)
|
||||
;
|
||||
|
||||
class_<peer_ban_alert, bases<peer_alert>, noncopyable>(
|
||||
"peer_ban_alert", no_init);
|
||||
|
||||
class_<peer_error_alert, bases<peer_alert>, noncopyable>(
|
||||
"peer_error_alert", no_init);
|
||||
|
||||
class_<invalid_request_alert, bases<peer_alert>, noncopyable>(
|
||||
"invalid_request_alert", no_init)
|
||||
.def_readonly("request", &invalid_request_alert::request)
|
||||
;
|
||||
|
||||
class_<peer_request>("peer_request")
|
||||
.def_readonly("piece", &peer_request::piece)
|
||||
.def_readonly("start", &peer_request::start)
|
||||
.def_readonly("length", &peer_request::length)
|
||||
.def(self == self)
|
||||
;
|
||||
|
||||
class_<torrent_finished_alert, bases<torrent_alert>, noncopyable>(
|
||||
"torrent_finished_alert", no_init);
|
||||
|
||||
class_<piece_finished_alert, bases<torrent_alert>, noncopyable>(
|
||||
"piece_finished_alert", no_init)
|
||||
.def_readonly("piece_index", &piece_finished_alert::piece_index)
|
||||
;
|
||||
|
||||
class_<block_finished_alert, bases<peer_alert>, noncopyable>(
|
||||
"block_finished_alert", no_init)
|
||||
.def_readonly("block_index", &block_finished_alert::block_index)
|
||||
.def_readonly("piece_index", &block_finished_alert::piece_index)
|
||||
;
|
||||
|
||||
class_<block_downloading_alert, bases<peer_alert>, noncopyable>(
|
||||
"block_downloading_alert", no_init)
|
||||
.def_readonly("peer_speedmsg", &block_downloading_alert::peer_speedmsg)
|
||||
.def_readonly("block_index", &block_downloading_alert::block_index)
|
||||
.def_readonly("piece_index", &block_downloading_alert::piece_index)
|
||||
;
|
||||
|
||||
class_<storage_moved_alert, bases<torrent_alert>, noncopyable>(
|
||||
"storage_moved_alert", no_init)
|
||||
.def_readonly("path", &storage_moved_alert::path)
|
||||
;
|
||||
|
||||
class_<storage_moved_failed_alert, bases<torrent_alert>, noncopyable>(
|
||||
"storage_moved_failed_alert", no_init)
|
||||
.def_readonly("error", &storage_moved_failed_alert::error)
|
||||
;
|
||||
|
||||
class_<torrent_deleted_alert, bases<torrent_alert>, noncopyable>(
|
||||
"torrent_deleted_alert", no_init)
|
||||
.def_readonly("info_hash", &torrent_deleted_alert::info_hash)
|
||||
;
|
||||
|
||||
class_<torrent_paused_alert, bases<torrent_alert>, noncopyable>(
|
||||
"torrent_paused_alert", no_init);
|
||||
|
||||
class_<torrent_checked_alert, bases<torrent_alert>, noncopyable>(
|
||||
"torrent_checked_alert", no_init);
|
||||
|
||||
class_<url_seed_alert, bases<torrent_alert>, noncopyable>(
|
||||
"url_seed_alert", no_init)
|
||||
.def_readonly("url", &url_seed_alert::url)
|
||||
.def_readonly("msg", &url_seed_alert::msg)
|
||||
;
|
||||
|
||||
class_<file_error_alert, bases<torrent_alert>, noncopyable>(
|
||||
"file_error_alert", no_init)
|
||||
.def_readonly("file", &file_error_alert::file)
|
||||
#ifndef TORRENT_NO_DEPRECATE
|
||||
.def_readonly("msg", &file_error_alert::msg)
|
||||
#endif
|
||||
;
|
||||
|
||||
class_<metadata_failed_alert, bases<torrent_alert>, noncopyable>(
|
||||
"metadata_failed_alert", no_init);
|
||||
|
||||
class_<metadata_received_alert, bases<torrent_alert>, noncopyable>(
|
||||
"metadata_received_alert", no_init);
|
||||
|
||||
class_<listen_failed_alert, bases<alert>, noncopyable>(
|
||||
"listen_failed_alert", no_init)
|
||||
.def_readonly("endpoint", &listen_failed_alert::endpoint)
|
||||
.def_readonly("error", &listen_failed_alert::error)
|
||||
;
|
||||
|
||||
class_<listen_succeeded_alert, bases<alert>, noncopyable>(
|
||||
"listen_succeeded_alert", no_init)
|
||||
.def_readonly("endpoint", &listen_succeeded_alert::endpoint)
|
||||
;
|
||||
|
||||
class_<portmap_error_alert, bases<alert>, noncopyable>(
|
||||
"portmap_error_alert", no_init)
|
||||
.def_readonly("mapping", &portmap_error_alert::mapping)
|
||||
.def_readonly("map_type", &portmap_error_alert::map_type)
|
||||
#ifndef TORRENT_NO_DEPRECATE
|
||||
.def_readonly("type", &portmap_error_alert::map_type)
|
||||
.def_readonly("msg", &portmap_error_alert::msg)
|
||||
#endif
|
||||
;
|
||||
|
||||
class_<portmap_alert, bases<alert>, noncopyable>(
|
||||
"portmap_alert", no_init)
|
||||
.def_readonly("mapping", &portmap_alert::mapping)
|
||||
.def_readonly("external_port", &portmap_alert::external_port)
|
||||
#ifndef TORRENT_NO_DEPRECATE
|
||||
.def_readonly("type", &portmap_alert::map_type)
|
||||
#endif
|
||||
.def_readonly("map_type", &portmap_alert::map_type)
|
||||
;
|
||||
|
||||
class_<portmap_log_alert, bases<alert>, noncopyable>(
|
||||
"portmap_log_alert", no_init)
|
||||
.def_readonly("map_type", &portmap_log_alert::map_type)
|
||||
#ifndef TORRENT_NO_DEPRECATE
|
||||
.def_readonly("type", &portmap_log_alert::map_type)
|
||||
.def_readonly("msg", &portmap_log_alert::msg)
|
||||
#endif
|
||||
;
|
||||
|
||||
class_<fastresume_rejected_alert, bases<torrent_alert>, noncopyable>(
|
||||
"fastresume_rejected_alert", no_init)
|
||||
#ifndef TORRENT_NO_DEPRECATE
|
||||
.def_readonly("msg", &fastresume_rejected_alert::msg)
|
||||
#endif
|
||||
;
|
||||
|
||||
class_<peer_blocked_alert, bases<alert>, noncopyable>(
|
||||
"peer_blocked_alert", no_init)
|
||||
.def_readonly("ip", &peer_blocked_alert::ip)
|
||||
;
|
||||
|
||||
class_<scrape_reply_alert, bases<tracker_alert>, noncopyable>(
|
||||
"scrape_reply_alert", no_init)
|
||||
.def_readonly("incomplete", &scrape_reply_alert::incomplete)
|
||||
.def_readonly("complete", &scrape_reply_alert::complete)
|
||||
;
|
||||
|
||||
class_<scrape_failed_alert, bases<tracker_alert>, noncopyable>(
|
||||
"scrape_failed_alert", no_init);
|
||||
|
||||
class_<udp_error_alert, bases<alert>, noncopyable>(
|
||||
"udp_error_alert", no_init)
|
||||
.def_readonly("endpoint", &udp_error_alert::endpoint)
|
||||
.def_readonly("error", &udp_error_alert::error)
|
||||
;
|
||||
|
||||
class_<external_ip_alert, bases<alert>, noncopyable>(
|
||||
"external_ip_alert", no_init)
|
||||
.def_readonly("external_address", &external_ip_alert::external_address)
|
||||
;
|
||||
|
||||
class_<save_resume_data_alert, bases<torrent_alert>, noncopyable>(
|
||||
"save_resume_data_alert", no_init)
|
||||
.def_readonly("resume_data", &save_resume_data_alert::resume_data)
|
||||
;
|
||||
|
||||
class_<file_completed_alert, bases<torrent_alert>, noncopyable>(
|
||||
"file_completed_alert", no_init)
|
||||
.def_readonly("index", &file_completed_alert::index)
|
||||
;
|
||||
|
||||
class_<file_renamed_alert, bases<torrent_alert>, noncopyable>(
|
||||
"file_renamed_alert", no_init)
|
||||
.def_readonly("index", &file_renamed_alert::index)
|
||||
.def_readonly("name", &file_renamed_alert::name)
|
||||
;
|
||||
|
||||
class_<file_rename_failed_alert, bases<torrent_alert>, noncopyable>(
|
||||
"file_rename_failed_alert", no_init)
|
||||
.def_readonly("index", &file_rename_failed_alert::index)
|
||||
.def_readonly("error", &file_rename_failed_alert::error)
|
||||
;
|
||||
|
||||
class_<torrent_resumed_alert, bases<torrent_alert>, noncopyable>(
|
||||
"torrent_resumed_alert", no_init
|
||||
);
|
||||
|
||||
class_<state_changed_alert, bases<torrent_alert>, noncopyable>(
|
||||
"state_changed_alert", no_init)
|
||||
.def_readonly("state", &state_changed_alert::state)
|
||||
.def_readonly("prev_state", &state_changed_alert::prev_state)
|
||||
;
|
||||
|
||||
class_<dht_reply_alert, bases<tracker_alert>, noncopyable>(
|
||||
"dht_reply_alert", no_init)
|
||||
.def_readonly("num_peers", &dht_reply_alert::num_peers)
|
||||
;
|
||||
|
||||
class_<dht_announce_alert, bases<alert>, noncopyable>(
|
||||
"dht_announce_alert", no_init)
|
||||
.def_readonly("ip", &dht_announce_alert::ip)
|
||||
.def_readonly("port", &dht_announce_alert::port)
|
||||
.def_readonly("info_hash", &dht_announce_alert::info_hash)
|
||||
;
|
||||
|
||||
class_<dht_get_peers_alert, bases<alert>, noncopyable>(
|
||||
"dht_get_peers_alert", no_init
|
||||
)
|
||||
.def_readonly("info_hash", &dht_get_peers_alert::info_hash)
|
||||
;
|
||||
|
||||
class_<peer_unsnubbed_alert, bases<peer_alert>, noncopyable>(
|
||||
"peer_unsnubbed_alert", no_init
|
||||
);
|
||||
|
||||
class_<peer_snubbed_alert, bases<peer_alert>, noncopyable>(
|
||||
"peer_snubbed_alert", no_init
|
||||
);
|
||||
|
||||
class_<peer_connect_alert, bases<peer_alert>, noncopyable>(
|
||||
"peer_connect_alert", no_init
|
||||
);
|
||||
|
||||
class_<peer_disconnected_alert, bases<peer_alert>, noncopyable>(
|
||||
"peer_disconnected_alert", no_init)
|
||||
#ifndef TORRENT_NO_DEPRECATE
|
||||
.def_readonly("msg", &peer_disconnected_alert::msg)
|
||||
#endif
|
||||
;
|
||||
|
||||
class_<request_dropped_alert, bases<peer_alert>, noncopyable>(
|
||||
"request_dropped_alert", no_init)
|
||||
.def_readonly("block_index", &request_dropped_alert::block_index)
|
||||
.def_readonly("piece_index", &request_dropped_alert::piece_index)
|
||||
;
|
||||
|
||||
class_<block_timeout_alert, bases<peer_alert>, noncopyable>(
|
||||
"block_timeout_alert", no_init)
|
||||
.def_readonly("block_index", &block_timeout_alert::block_index)
|
||||
.def_readonly("piece_index", &block_timeout_alert::piece_index)
|
||||
;
|
||||
|
||||
class_<unwanted_block_alert, bases<peer_alert>, noncopyable>(
|
||||
"unwanted_block_alert", no_init)
|
||||
.def_readonly("block_index", &unwanted_block_alert::block_index)
|
||||
.def_readonly("piece_index", &unwanted_block_alert::piece_index)
|
||||
;
|
||||
|
||||
class_<torrent_delete_failed_alert, bases<torrent_alert>, noncopyable>(
|
||||
"torrent_delete_failed_alert", no_init)
|
||||
#ifndef TORRENT_NO_DEPRECATE
|
||||
.def_readonly("msg", &torrent_delete_failed_alert::msg)
|
||||
#endif
|
||||
;
|
||||
|
||||
class_<save_resume_data_failed_alert, bases<torrent_alert>, noncopyable>(
|
||||
"save_resume_data_failed_alert", no_init)
|
||||
#ifndef TORRENT_NO_DEPRECATE
|
||||
.def_readonly("msg", &save_resume_data_failed_alert::msg)
|
||||
#endif
|
||||
;
|
||||
|
||||
class_<performance_alert, bases<torrent_alert>, noncopyable>(
|
||||
"performance_alert", no_init)
|
||||
.def_readonly("warning_code", &performance_alert::warning_code)
|
||||
;
|
||||
enum_<performance_alert::performance_warning_t>("performance_warning_t")
|
||||
.value("outstanding_disk_buffer_limit_reached", performance_alert::outstanding_disk_buffer_limit_reached)
|
||||
.value("outstanding_request_limit_reached", performance_alert::outstanding_request_limit_reached)
|
||||
.value("upload_limit_too_low", performance_alert::upload_limit_too_low)
|
||||
.value("download_limit_too_low", performance_alert::download_limit_too_low)
|
||||
;
|
||||
|
||||
|
||||
class_<stats_alert, bases<torrent_alert>, noncopyable>(
|
||||
"stats_alert", no_init)
|
||||
.def_readonly("transferred", &stats_alert::transferred)
|
||||
.def_readonly("interval", &stats_alert::interval)
|
||||
;
|
||||
|
||||
enum_<stats_alert::stats_channel>("stats_channel")
|
||||
.value("upload_payload", stats_alert::upload_payload)
|
||||
.value("upload_protocol", stats_alert::upload_protocol)
|
||||
.value("upload_ip_protocol", stats_alert::upload_ip_protocol)
|
||||
.value("upload_dht_protocol", stats_alert::upload_dht_protocol)
|
||||
.value("upload_tracker_protocol", stats_alert::upload_tracker_protocol)
|
||||
.value("download_payload", stats_alert::download_payload)
|
||||
.value("download_protocol", stats_alert::download_protocol)
|
||||
.value("download_ip_protocol", stats_alert::download_ip_protocol)
|
||||
.value("download_dht_protocol", stats_alert::download_dht_protocol)
|
||||
.value("download_tracker_protocol", stats_alert::download_tracker_protocol)
|
||||
;
|
||||
|
||||
class_<anonymous_mode_alert, bases<torrent_alert>, noncopyable>(
|
||||
"anonymous_mode_alert", no_init)
|
||||
.def_readonly("kind", &anonymous_mode_alert::kind)
|
||||
.def_readonly("str", &anonymous_mode_alert::str)
|
||||
;
|
||||
|
||||
enum_<anonymous_mode_alert::kind_t>("kind")
|
||||
.value("tracker_no_anonymous", anonymous_mode_alert::tracker_not_anonymous)
|
||||
;
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
// Copyright Daniel Wallin 2006. Use, modification and distribution is
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <libtorrent/peer_id.hpp>
|
||||
#include <boost/python.hpp>
|
||||
|
||||
void bind_big_number()
|
||||
{
|
||||
using namespace boost::python;
|
||||
using namespace libtorrent;
|
||||
|
||||
class_<big_number>("big_number")
|
||||
.def(self == self)
|
||||
.def(self != self)
|
||||
.def(self < self)
|
||||
.def(self_ns::str(self))
|
||||
.def(init<char const*>())
|
||||
;
|
||||
}
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
// Copyright Andrew Resch 2009. Use, modification and distribution is
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/python.hpp>
|
||||
|
||||
using namespace boost::python;
|
||||
|
||||
template<class T1, class T2>
|
||||
struct pair_to_tuple
|
||||
{
|
||||
static PyObject* convert(const std::pair<T1, T2>& p)
|
||||
{
|
||||
return incref(make_tuple(p.first, p.second).ptr());
|
||||
}
|
||||
};
|
||||
|
||||
template<class T1, class T2>
|
||||
struct tuple_to_pair
|
||||
{
|
||||
tuple_to_pair()
|
||||
{
|
||||
converter::registry::push_back(
|
||||
&convertible, &construct, type_id<std::pair<T1, T2> >()
|
||||
);
|
||||
}
|
||||
|
||||
static void* convertible(PyObject* x)
|
||||
{
|
||||
return PyTuple_Check(x) ? x: 0;
|
||||
}
|
||||
|
||||
static void construct(PyObject* x, converter::rvalue_from_python_stage1_data* data)
|
||||
{
|
||||
void* storage = ((converter::rvalue_from_python_storage<
|
||||
std::pair<T1, T2> >*)data)->storage.bytes;
|
||||
|
||||
object o(borrowed(x));
|
||||
std::pair<T1, T2> p;
|
||||
p.first = extract<T1>(o[0]);
|
||||
p.second = extract<T2>(o[1]);
|
||||
new (storage) std::pair<T1, T2>(p);
|
||||
data->convertible = storage;
|
||||
}
|
||||
};
|
||||
|
||||
void bind_converters()
|
||||
{
|
||||
to_python_converter<std::pair<int, int>, pair_to_tuple<int, int> >();
|
||||
tuple_to_pair<int, int>();
|
||||
}
|
|
@ -1,128 +0,0 @@
|
|||
// Copyright Daniel Wallin & Arvid Norberg 2009. Use, modification and distribution is
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/python.hpp>
|
||||
#include <libtorrent/create_torrent.hpp>
|
||||
#include <libtorrent/file_storage.hpp>
|
||||
#include "libtorrent/intrusive_ptr_base.hpp"
|
||||
|
||||
using namespace boost::python;
|
||||
using namespace libtorrent;
|
||||
|
||||
namespace
|
||||
{
|
||||
void set_hash(create_torrent& c, int p, char const* hash)
|
||||
{
|
||||
c.set_hash(p, sha1_hash(hash));
|
||||
}
|
||||
|
||||
void call_python_object(boost::python::object const& obj, int i)
|
||||
{
|
||||
obj(i);
|
||||
}
|
||||
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
void set_piece_hashes_callback(create_torrent& c, std::string const& p
|
||||
, boost::python::object cb)
|
||||
{
|
||||
set_piece_hashes(c, p, boost::bind(call_python_object, cb, _1));
|
||||
}
|
||||
#else
|
||||
void set_piece_hashes_callback(create_torrent& c, std::string const& p
|
||||
, boost::python::object cb)
|
||||
{
|
||||
error_code ec;
|
||||
set_piece_hashes(c, p, boost::bind(call_python_object, cb, _1), ec);
|
||||
}
|
||||
|
||||
void set_piece_hashes0(create_torrent& c, std::string const & s)
|
||||
{
|
||||
error_code ec;
|
||||
set_piece_hashes(c, s, ec);
|
||||
}
|
||||
#endif
|
||||
|
||||
void add_node(create_torrent& ct, std::string const& addr, int port)
|
||||
{
|
||||
ct.add_node(std::make_pair(addr, port));
|
||||
}
|
||||
|
||||
void add_file(file_storage& ct, file_entry const& fe
|
||||
, std::string const& hash, std::string const& linkpath)
|
||||
{
|
||||
ct.add_file(fe, hash.empty() ? 0 : hash.c_str()
|
||||
, linkpath.empty() ? 0 : &linkpath);
|
||||
}
|
||||
}
|
||||
|
||||
void bind_create_torrent()
|
||||
{
|
||||
void (file_storage::*add_file0)(std::string const&, size_type, int, std::time_t, std::string const&) = &file_storage::add_file;
|
||||
#if TORRENT_USE_WSTRING
|
||||
void (file_storage::*add_file1)(std::wstring const&, size_type, int, std::time_t, std::string const&) = &file_storage::add_file;
|
||||
#endif
|
||||
|
||||
void (file_storage::*set_name0)(std::string const&) = &file_storage::set_name;
|
||||
#if TORRENT_USE_WSTRING
|
||||
void (file_storage::*set_name1)(std::wstring const&) = &file_storage::set_name;
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
void (*set_piece_hashes0)(create_torrent&, std::string const&) = &set_piece_hashes;
|
||||
#endif
|
||||
void (*add_files0)(file_storage&, std::string const&, boost::uint32_t) = add_files;
|
||||
|
||||
class_<file_storage>("file_storage")
|
||||
.def("is_valid", &file_storage::is_valid)
|
||||
.def("add_file", add_file, (arg("entry"), arg("hash") = std::string(), arg("symlink") = std::string()))
|
||||
.def("add_file", add_file0, (arg("path"), arg("size"), arg("flags") = 0, arg("mtime") = 0, arg("linkpath") = ""))
|
||||
#if TORRENT_USE_WSTRING
|
||||
.def("add_file", add_file1, (arg("path"), arg("size"), arg("flags") = 0, arg("mtime") = 0, arg("linkpath") = ""))
|
||||
#endif
|
||||
.def("num_files", &file_storage::num_files)
|
||||
.def("at", &file_storage::at, return_internal_reference<>())
|
||||
.def("hash", &file_storage::hash)
|
||||
.def("symlink", &file_storage::symlink, return_internal_reference<>())
|
||||
.def("file_index", &file_storage::file_index)
|
||||
.def("file_base", &file_storage::file_base)
|
||||
.def("set_file_base", &file_storage::set_file_base)
|
||||
.def("file_path", &file_storage::file_path)
|
||||
.def("total_size", &file_storage::total_size)
|
||||
.def("set_num_pieces", &file_storage::set_num_pieces)
|
||||
.def("num_pieces", &file_storage::num_pieces)
|
||||
.def("set_piece_length", &file_storage::set_piece_length)
|
||||
.def("piece_length", &file_storage::piece_length)
|
||||
.def("piece_size", &file_storage::piece_size)
|
||||
.def("set_name", set_name0)
|
||||
#if TORRENT_USE_WSTRING
|
||||
.def("set_name", set_name1)
|
||||
#endif
|
||||
.def("name", &file_storage::name, return_internal_reference<>())
|
||||
;
|
||||
|
||||
class_<create_torrent>("create_torrent", no_init)
|
||||
.def(init<file_storage&>())
|
||||
.def(init<file_storage&, int>())
|
||||
|
||||
.def("generate", &create_torrent::generate)
|
||||
|
||||
.def("files", &create_torrent::files, return_internal_reference<>())
|
||||
.def("set_comment", &create_torrent::set_comment)
|
||||
.def("set_creator", &create_torrent::set_creator)
|
||||
.def("set_hash", &set_hash)
|
||||
.def("add_url_seed", &create_torrent::add_url_seed)
|
||||
.def("add_node", &add_node)
|
||||
.def("add_tracker", &create_torrent::add_tracker)
|
||||
.def("set_priv", &create_torrent::set_priv)
|
||||
.def("num_pieces", &create_torrent::num_pieces)
|
||||
.def("piece_length", &create_torrent::piece_length)
|
||||
.def("piece_size", &create_torrent::piece_size)
|
||||
.def("priv", &create_torrent::priv)
|
||||
;
|
||||
|
||||
def("add_files", add_files0, (arg("fs"), arg("path"), arg("flags") = 0));
|
||||
def("set_piece_hashes", set_piece_hashes0);
|
||||
def("set_piece_hashes", set_piece_hashes_callback);
|
||||
|
||||
}
|
|
@ -1,81 +0,0 @@
|
|||
// Copyright Daniel Wallin 2006. Use, modification and distribution is
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/python.hpp>
|
||||
#include <boost/date_time/posix_time/posix_time_types.hpp>
|
||||
#include "optional.hpp"
|
||||
#include <boost/version.hpp>
|
||||
|
||||
using namespace boost::python;
|
||||
|
||||
#if BOOST_VERSION < 103400
|
||||
|
||||
// From Boost 1.34
|
||||
object import(str name)
|
||||
{
|
||||
// should be 'char const *' but older python versions don't use 'const' yet.
|
||||
char *n = extract<char *>(name);
|
||||
handle<> module(borrowed(PyImport_ImportModule(n)));
|
||||
return object(module);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
object datetime_timedelta;
|
||||
object datetime_datetime;
|
||||
|
||||
struct time_duration_to_python
|
||||
{
|
||||
static PyObject* convert(boost::posix_time::time_duration const& d)
|
||||
{
|
||||
object result = datetime_timedelta(
|
||||
0 // days
|
||||
, 0 // seconds
|
||||
, d.total_microseconds()
|
||||
);
|
||||
|
||||
return incref(result.ptr());
|
||||
}
|
||||
};
|
||||
|
||||
struct ptime_to_python
|
||||
{
|
||||
static PyObject* convert(boost::posix_time::ptime const& pt)
|
||||
{
|
||||
boost::gregorian::date date = pt.date();
|
||||
boost::posix_time::time_duration td = pt.time_of_day();
|
||||
|
||||
object result = datetime_datetime(
|
||||
(int)date.year()
|
||||
, (int)date.month()
|
||||
, (int)date.day()
|
||||
, td.hours()
|
||||
, td.minutes()
|
||||
, td.seconds()
|
||||
);
|
||||
|
||||
return incref(result.ptr());
|
||||
}
|
||||
};
|
||||
|
||||
void bind_datetime()
|
||||
{
|
||||
object datetime = import("datetime").attr("__dict__");
|
||||
|
||||
datetime_timedelta = datetime["timedelta"];
|
||||
datetime_datetime = datetime["datetime"];
|
||||
|
||||
to_python_converter<
|
||||
boost::posix_time::time_duration
|
||||
, time_duration_to_python
|
||||
>();
|
||||
|
||||
to_python_converter<
|
||||
boost::posix_time::ptime
|
||||
, ptime_to_python
|
||||
>();
|
||||
|
||||
optional_to_python<boost::posix_time::ptime>();
|
||||
}
|
||||
|
|
@ -1,140 +0,0 @@
|
|||
// Copyright Daniel Wallin 2006. Use, modification and distribution is
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/python.hpp>
|
||||
#include <libtorrent/session.hpp>
|
||||
|
||||
using namespace boost::python;
|
||||
using namespace libtorrent;
|
||||
|
||||
struct entry_to_python
|
||||
{
|
||||
static object convert(entry::list_type const& l)
|
||||
{
|
||||
list result;
|
||||
|
||||
for (entry::list_type::const_iterator i(l.begin()), e(l.end()); i != e; ++i)
|
||||
{
|
||||
result.append(*i);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static object convert(entry::dictionary_type const& d)
|
||||
{
|
||||
dict result;
|
||||
|
||||
for (entry::dictionary_type::const_iterator i(d.begin()), e(d.end()); i != e; ++i)
|
||||
result[i->first] = i->second;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static object convert0(entry const& e)
|
||||
{
|
||||
switch (e.type())
|
||||
{
|
||||
case entry::int_t:
|
||||
return object(e.integer());
|
||||
case entry::string_t:
|
||||
return object(e.string());
|
||||
case entry::list_t:
|
||||
return convert(e.list());
|
||||
case entry::dictionary_t:
|
||||
return convert(e.dict());
|
||||
default:
|
||||
return object();
|
||||
}
|
||||
}
|
||||
|
||||
static PyObject* convert(boost::shared_ptr<entry> const& e)
|
||||
{
|
||||
if (!e)
|
||||
return incref(Py_None);
|
||||
return convert(*e);
|
||||
}
|
||||
|
||||
static PyObject* convert(entry const& e)
|
||||
{
|
||||
return incref(convert0(e).ptr());
|
||||
}
|
||||
};
|
||||
|
||||
struct entry_from_python
|
||||
{
|
||||
entry_from_python()
|
||||
{
|
||||
converter::registry::push_back(
|
||||
&convertible, &construct, type_id<entry>()
|
||||
);
|
||||
}
|
||||
|
||||
static void* convertible(PyObject* e)
|
||||
{
|
||||
return e;
|
||||
}
|
||||
|
||||
static entry construct0(object e)
|
||||
{
|
||||
if (extract<dict>(e).check())
|
||||
{
|
||||
dict d = extract<dict>(e);
|
||||
list items(d.items());
|
||||
std::size_t length = extract<std::size_t>(items.attr("__len__")());
|
||||
entry result(entry::dictionary_t);
|
||||
|
||||
for (std::size_t i = 0; i < length; ++i)
|
||||
{
|
||||
result.dict().insert(
|
||||
std::make_pair(
|
||||
extract<char const*>(items[i][0])()
|
||||
, construct0(items[i][1])
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
else if (extract<list>(e).check())
|
||||
{
|
||||
list l = extract<list>(e);
|
||||
|
||||
std::size_t length = extract<std::size_t>(l.attr("__len__")());
|
||||
entry result(entry::list_t);
|
||||
|
||||
for (std::size_t i = 0; i < length; ++i)
|
||||
{
|
||||
result.list().push_back(construct0(l[i]));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
else if (extract<str>(e).check())
|
||||
{
|
||||
return entry(extract<std::string>(e)());
|
||||
}
|
||||
else if (extract<entry::integer_type>(e).check())
|
||||
{
|
||||
return entry(extract<entry::integer_type>(e)());
|
||||
}
|
||||
|
||||
return entry();
|
||||
}
|
||||
|
||||
static void construct(PyObject* e, converter::rvalue_from_python_stage1_data* data)
|
||||
{
|
||||
void* storage = ((converter::rvalue_from_python_storage<entry>*)data)->storage.bytes;
|
||||
new (storage) entry(construct0(object(borrowed(e))));
|
||||
data->convertible = storage;
|
||||
}
|
||||
};
|
||||
|
||||
void bind_entry()
|
||||
{
|
||||
to_python_converter<boost::shared_ptr<libtorrent::entry>, entry_to_python>();
|
||||
to_python_converter<entry, entry_to_python>();
|
||||
entry_from_python();
|
||||
}
|
||||
|
|
@ -1,172 +0,0 @@
|
|||
// Copyright Daniel Wallin, Arvid Norberg 2007. Use, modification and distribution is
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/python.hpp>
|
||||
#include <libtorrent/extensions.hpp>
|
||||
#include <libtorrent/torrent.hpp>
|
||||
#include <libtorrent/entry.hpp>
|
||||
#include <libtorrent/peer_request.hpp>
|
||||
#include <libtorrent/peer_connection.hpp>
|
||||
#include <libtorrent/extensions/ut_pex.hpp>
|
||||
#include <libtorrent/extensions/metadata_transfer.hpp>
|
||||
#include <libtorrent/extensions/ut_metadata.hpp>
|
||||
#include <libtorrent/extensions/smart_ban.hpp>
|
||||
#include "gil.hpp"
|
||||
|
||||
using namespace boost::python;
|
||||
using namespace libtorrent;
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
struct torrent_plugin_wrap : torrent_plugin, wrapper<torrent_plugin>
|
||||
{
|
||||
boost::shared_ptr<peer_plugin> new_connection(peer_connection* p)
|
||||
{
|
||||
lock_gil lock;
|
||||
|
||||
if (override f = this->get_override("new_connection"))
|
||||
return f(ptr(p));
|
||||
return torrent_plugin::new_connection(p);
|
||||
}
|
||||
|
||||
boost::shared_ptr<peer_plugin> default_new_connection(peer_connection* p)
|
||||
{
|
||||
return this->torrent_plugin::new_connection(p);
|
||||
}
|
||||
|
||||
void on_piece_pass(int index)
|
||||
{
|
||||
lock_gil lock;
|
||||
|
||||
if (override f = this->get_override("on_piece_pass"))
|
||||
f(index);
|
||||
else
|
||||
torrent_plugin::on_piece_pass(index);
|
||||
}
|
||||
|
||||
void default_on_piece_pass(int index)
|
||||
{
|
||||
this->torrent_plugin::on_piece_pass(index);
|
||||
}
|
||||
|
||||
void on_piece_failed(int index)
|
||||
{
|
||||
lock_gil lock;
|
||||
|
||||
if (override f = this->get_override("on_piece_failed"))
|
||||
f(index);
|
||||
else
|
||||
torrent_plugin::on_piece_failed(index);
|
||||
}
|
||||
|
||||
void default_on_piece_failed(int index)
|
||||
{
|
||||
return this->torrent_plugin::on_piece_failed(index);
|
||||
}
|
||||
|
||||
void tick()
|
||||
{
|
||||
lock_gil lock;
|
||||
|
||||
if (override f = this->get_override("tick"))
|
||||
f();
|
||||
else
|
||||
torrent_plugin::tick();
|
||||
}
|
||||
|
||||
void default_tick()
|
||||
{
|
||||
return this->torrent_plugin::tick();
|
||||
}
|
||||
|
||||
bool on_pause()
|
||||
{
|
||||
lock_gil lock;
|
||||
|
||||
if (override f = this->get_override("on_pause"))
|
||||
return f();
|
||||
return torrent_plugin::on_pause();
|
||||
}
|
||||
|
||||
bool default_on_pause()
|
||||
{
|
||||
return this->torrent_plugin::on_pause();
|
||||
}
|
||||
|
||||
bool on_resume()
|
||||
{
|
||||
lock_gil lock;
|
||||
|
||||
if (override f = this->get_override("on_resume"))
|
||||
return f();
|
||||
return torrent_plugin::on_resume();
|
||||
}
|
||||
|
||||
bool default_on_resume()
|
||||
{
|
||||
return this->torrent_plugin::on_resume();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace unnamed
|
||||
|
||||
|
||||
boost::shared_ptr<torrent_plugin> create_metadata_plugin_wrapper(torrent* t) {
|
||||
return create_metadata_plugin(t, NULL);
|
||||
}
|
||||
|
||||
boost::shared_ptr<torrent_plugin> create_ut_metadata_plugin_wrapper(torrent *t) {
|
||||
return create_ut_metadata_plugin(t, NULL);
|
||||
}
|
||||
|
||||
boost::shared_ptr<torrent_plugin> create_ut_pex_plugin_wrapper(torrent* t) {
|
||||
return create_ut_pex_plugin(t, NULL);
|
||||
}
|
||||
|
||||
boost::shared_ptr<torrent_plugin> create_smart_ban_plugin_wrapper(torrent* t) {
|
||||
return create_smart_ban_plugin(t, NULL);
|
||||
}
|
||||
|
||||
void bind_extensions()
|
||||
{
|
||||
class_<
|
||||
torrent_plugin_wrap, boost::shared_ptr<torrent_plugin_wrap>, boost::noncopyable
|
||||
>("torrent_plugin")
|
||||
.def(
|
||||
"new_connection"
|
||||
, &torrent_plugin::new_connection, &torrent_plugin_wrap::default_new_connection
|
||||
)
|
||||
.def(
|
||||
"on_piece_pass"
|
||||
, &torrent_plugin::on_piece_pass, &torrent_plugin_wrap::default_on_piece_pass
|
||||
)
|
||||
.def(
|
||||
"on_piece_failed"
|
||||
, &torrent_plugin::on_piece_failed, &torrent_plugin_wrap::default_on_piece_failed
|
||||
)
|
||||
.def(
|
||||
"tick"
|
||||
, &torrent_plugin::tick, &torrent_plugin_wrap::default_tick
|
||||
)
|
||||
.def(
|
||||
"on_pause"
|
||||
, &torrent_plugin::on_pause, &torrent_plugin_wrap::default_on_pause
|
||||
)
|
||||
.def(
|
||||
"on_resume"
|
||||
, &torrent_plugin::on_resume, &torrent_plugin_wrap::default_on_resume
|
||||
);
|
||||
|
||||
// TODO move to it's own file
|
||||
class_<peer_connection, boost::noncopyable>("peer_connection", no_init);
|
||||
|
||||
class_<torrent_plugin, boost::shared_ptr<torrent_plugin> >("torrent_plugin", no_init);
|
||||
def("create_ut_pex_plugin", create_ut_pex_plugin_wrapper);
|
||||
def("create_metadata_plugin", create_metadata_plugin_wrapper);
|
||||
def("create_ut_metadata_plugin", create_ut_metadata_plugin_wrapper);
|
||||
def("create_smart_ban_plugin", create_smart_ban_plugin_wrapper);
|
||||
}
|
||||
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
// Copyright Daniel Wallin 2006. Use, modification and distribution is
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <libtorrent/fingerprint.hpp>
|
||||
#include <boost/python.hpp>
|
||||
|
||||
void bind_fingerprint()
|
||||
{
|
||||
using namespace boost::python;
|
||||
using namespace libtorrent;
|
||||
|
||||
class_<fingerprint>("fingerprint", no_init)
|
||||
.def(
|
||||
init<char const*,int,int,int,int>(
|
||||
(arg("id"), "major", "minor", "revision", "tag")
|
||||
)
|
||||
)
|
||||
.def("__str__", &fingerprint::to_string)
|
||||
.def_readonly("name", &fingerprint::name)
|
||||
.def_readonly("major_version", &fingerprint::major_version)
|
||||
.def_readonly("minor_version", &fingerprint::minor_version)
|
||||
.def_readonly("revision_version", &fingerprint::revision_version)
|
||||
.def_readonly("tag_version", &fingerprint::tag_version)
|
||||
;
|
||||
}
|
||||
|
|
@ -1,144 +0,0 @@
|
|||
// Copyright Daniel Wallin 2007. Use, modification and distribution is
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef GIL_070107_HPP
|
||||
# define GIL_070107_HPP
|
||||
|
||||
# include <boost/python/make_function.hpp>
|
||||
# include <boost/python/def_visitor.hpp>
|
||||
# include <boost/python/signature.hpp>
|
||||
# include <boost/mpl/at.hpp>
|
||||
|
||||
//namespace libtorrent { namespace python {
|
||||
|
||||
// RAII helper to release GIL.
|
||||
struct allow_threading_guard
|
||||
{
|
||||
allow_threading_guard()
|
||||
: save(PyEval_SaveThread())
|
||||
{}
|
||||
|
||||
~allow_threading_guard()
|
||||
{
|
||||
PyEval_RestoreThread(save);
|
||||
}
|
||||
|
||||
PyThreadState* save;
|
||||
};
|
||||
|
||||
struct lock_gil
|
||||
{
|
||||
lock_gil()
|
||||
: state(PyGILState_Ensure())
|
||||
{}
|
||||
|
||||
~lock_gil()
|
||||
{
|
||||
PyGILState_Release(state);
|
||||
}
|
||||
|
||||
PyGILState_STATE state;
|
||||
};
|
||||
|
||||
template <class F, class R>
|
||||
struct allow_threading
|
||||
{
|
||||
allow_threading(F fn)
|
||||
: fn(fn)
|
||||
{}
|
||||
|
||||
template <class A0>
|
||||
R operator()(A0& a0)
|
||||
{
|
||||
allow_threading_guard guard;
|
||||
return (a0.*fn)();
|
||||
}
|
||||
|
||||
template <class A0, class A1>
|
||||
R operator()(A0& a0, A1& a1)
|
||||
{
|
||||
allow_threading_guard guard;
|
||||
return (a0.*fn)(a1);
|
||||
}
|
||||
|
||||
template <class A0, class A1, class A2>
|
||||
R operator()(A0& a0, A1& a1, A2& a2)
|
||||
{
|
||||
allow_threading_guard guard;
|
||||
return (a0.*fn)(a1,a2);
|
||||
}
|
||||
|
||||
template <class A0, class A1, class A2, class A3>
|
||||
R operator()(A0& a0, A1& a1, A2& a2, A3& a3)
|
||||
{
|
||||
allow_threading_guard guard;
|
||||
return (a0.*fn)(a1,a2,a3);
|
||||
}
|
||||
|
||||
template <class A0, class A1, class A2, class A3, class A4>
|
||||
R operator()(A0& a0, A1& a1, A2& a2, A3& a3, A4& a4)
|
||||
{
|
||||
allow_threading_guard guard;
|
||||
return (a0.*fn)(a1,a2,a3,a4);
|
||||
}
|
||||
|
||||
template <class A0, class A1, class A2, class A3, class A4, class A5>
|
||||
R operator()(A0& a0, A1& a1, A2& a2, A3& a3, A4& a4, A5& a5)
|
||||
{
|
||||
allow_threading_guard guard;
|
||||
return (a0.*fn)(a1,a2,a3,a4,a5);
|
||||
}
|
||||
|
||||
F fn;
|
||||
};
|
||||
|
||||
template <class F>
|
||||
struct visitor : boost::python::def_visitor<visitor<F> >
|
||||
{
|
||||
visitor(F fn)
|
||||
: fn(fn)
|
||||
{}
|
||||
|
||||
template <class Class, class Options, class Signature>
|
||||
void visit_aux(
|
||||
Class& cl, char const* name
|
||||
, Options const& options, Signature const& signature) const
|
||||
{
|
||||
typedef typename boost::mpl::at_c<Signature,0>::type return_type;
|
||||
|
||||
cl.def(
|
||||
name
|
||||
, boost::python::make_function(
|
||||
allow_threading<F, return_type>(fn)
|
||||
, options.policies()
|
||||
, options.keywords()
|
||||
, signature
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
template <class Class, class Options>
|
||||
void visit(Class& cl, char const* name, Options const& options) const
|
||||
{
|
||||
this->visit_aux(
|
||||
cl, name, options
|
||||
, boost::python::detail::get_signature(fn, (typename Class::wrapped_type*)0)
|
||||
);
|
||||
}
|
||||
|
||||
F fn;
|
||||
};
|
||||
|
||||
// Member function adaptor that releases and aqcuires the GIL
|
||||
// around the function call.
|
||||
template <class F>
|
||||
visitor<F> allow_threads(F fn)
|
||||
{
|
||||
return visitor<F>(fn);
|
||||
}
|
||||
|
||||
//}} // namespace libtorrent::python
|
||||
|
||||
#endif // GIL_070107_HPP
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
// Copyright Andrew Resch 2008. Use, modification and distribution is
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <libtorrent/ip_filter.hpp>
|
||||
#include <boost/python.hpp>
|
||||
#include "gil.hpp"
|
||||
|
||||
using namespace boost::python;
|
||||
using namespace libtorrent;
|
||||
|
||||
namespace
|
||||
{
|
||||
void add_rule(ip_filter& filter, std::string start, std::string end, int flags)
|
||||
{
|
||||
return filter.add_rule(address::from_string(start), address::from_string(end), flags);
|
||||
}
|
||||
|
||||
int access0(ip_filter& filter, std::string addr)
|
||||
{
|
||||
return filter.access(address::from_string(addr));
|
||||
}
|
||||
}
|
||||
|
||||
void bind_ip_filter()
|
||||
{
|
||||
class_<ip_filter>("ip_filter")
|
||||
.def("add_rule", add_rule)
|
||||
.def("access", access0)
|
||||
.def("export_filter", allow_threads(&ip_filter::export_filter))
|
||||
;
|
||||
}
|
|
@ -1,59 +0,0 @@
|
|||
// Copyright Andrew Resch 2008. Use, modification and distribution is
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/python.hpp>
|
||||
#include <libtorrent/session.hpp>
|
||||
#include <libtorrent/torrent.hpp>
|
||||
#include <libtorrent/magnet_uri.hpp>
|
||||
#include "gil.hpp"
|
||||
|
||||
using namespace boost::python;
|
||||
using namespace libtorrent;
|
||||
|
||||
namespace {
|
||||
|
||||
torrent_handle _add_magnet_uri(session& s, std::string uri, dict params)
|
||||
{
|
||||
add_torrent_params p;
|
||||
|
||||
std::string url;
|
||||
if (params.has_key("tracker_url"))
|
||||
{
|
||||
url = extract<std::string>(params["tracker_url"]);
|
||||
p.tracker_url = url.c_str();
|
||||
}
|
||||
std::string name;
|
||||
if (params.has_key("name"))
|
||||
{
|
||||
name = extract<std::string>(params["name"]);
|
||||
p.name = name.c_str();
|
||||
}
|
||||
p.save_path = extract<std::string>(params["save_path"]);
|
||||
|
||||
std::vector<char> resume_buf;
|
||||
if (params.has_key("resume_data"))
|
||||
{
|
||||
std::string resume = extract<std::string>(params["resume_data"]);
|
||||
resume_buf.resize(resume.size());
|
||||
std::memcpy(&resume_buf[0], &resume[0], resume.size());
|
||||
p.resume_data = &resume_buf;
|
||||
}
|
||||
p.storage_mode = extract<storage_mode_t>(params["storage_mode"]);
|
||||
p.paused = params["paused"];
|
||||
p.auto_managed = params["auto_managed"];
|
||||
p.duplicate_is_error = params["duplicate_is_error"];
|
||||
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
return add_magnet_uri(s, uri, p);
|
||||
#else
|
||||
error_code ec;
|
||||
return add_magnet_uri(s, uri, p, ec);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void bind_magnet_uri()
|
||||
{
|
||||
def("add_magnet_uri", &_add_magnet_uri);
|
||||
}
|
|
@ -1,55 +0,0 @@
|
|||
// Copyright Daniel Wallin 2006. Use, modification and distribution is
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/python/module.hpp>
|
||||
|
||||
void bind_utility();
|
||||
void bind_fingerprint();
|
||||
void bind_big_number();
|
||||
void bind_session();
|
||||
void bind_entry();
|
||||
void bind_torrent_info();
|
||||
void bind_torrent_handle();
|
||||
void bind_torrent_status();
|
||||
void bind_session_settings();
|
||||
void bind_version();
|
||||
void bind_alert();
|
||||
void bind_datetime();
|
||||
void bind_extensions();
|
||||
void bind_peer_plugin();
|
||||
void bind_torrent();
|
||||
void bind_peer_info();
|
||||
void bind_ip_filter();
|
||||
void bind_magnet_uri();
|
||||
void bind_converters();
|
||||
void bind_create_torrent();
|
||||
|
||||
BOOST_PYTHON_MODULE(libtorrent)
|
||||
{
|
||||
Py_Initialize();
|
||||
PyEval_InitThreads();
|
||||
|
||||
bind_utility();
|
||||
bind_fingerprint();
|
||||
bind_big_number();
|
||||
bind_entry();
|
||||
bind_session();
|
||||
bind_torrent_info();
|
||||
bind_torrent_handle();
|
||||
bind_torrent_status();
|
||||
bind_session_settings();
|
||||
bind_version();
|
||||
bind_alert();
|
||||
bind_datetime();
|
||||
bind_extensions();
|
||||
#ifndef TORRENT_NO_PYTHON_PLUGINS
|
||||
bind_peer_plugin();
|
||||
#endif
|
||||
bind_torrent();
|
||||
bind_peer_info();
|
||||
bind_ip_filter();
|
||||
bind_magnet_uri();
|
||||
bind_converters();
|
||||
bind_create_torrent();
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
// Copyright Daniel Wallin 2007. Use, modification and distribution is
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef OPTIONAL_070108_HPP
|
||||
# define OPTIONAL_070108_HPP
|
||||
|
||||
# include <boost/python.hpp>
|
||||
# include <boost/optional.hpp>
|
||||
|
||||
template <class T>
|
||||
struct optional_to_python
|
||||
{
|
||||
optional_to_python()
|
||||
{
|
||||
boost::python::to_python_converter<
|
||||
boost::optional<T>, optional_to_python<T>
|
||||
>();
|
||||
}
|
||||
|
||||
static PyObject* convert(boost::optional<T> const& x)
|
||||
{
|
||||
if (!x)
|
||||
return boost::python::incref(Py_None);
|
||||
|
||||
return boost::python::incref(boost::python::object(*x).ptr());
|
||||
}
|
||||
};
|
||||
|
||||
#endif // OPTIONAL_070108_HPP
|
||||
|
|
@ -1,131 +0,0 @@
|
|||
// Copyright Daniel Wallin 2007. Use, modification and distribution is
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <libtorrent/peer_info.hpp>
|
||||
#include <libtorrent/bitfield.hpp>
|
||||
#include <boost/python.hpp>
|
||||
#include <boost/python/iterator.hpp>
|
||||
|
||||
using namespace boost::python;
|
||||
using namespace libtorrent;
|
||||
|
||||
int get_last_active(peer_info const& pi)
|
||||
{
|
||||
return total_seconds(pi.last_active);
|
||||
}
|
||||
|
||||
int get_last_request(peer_info const& pi)
|
||||
{
|
||||
return total_seconds(pi.last_request);
|
||||
}
|
||||
|
||||
#ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES
|
||||
str get_country(peer_info const& pi)
|
||||
{
|
||||
return str(pi.country, 2);
|
||||
}
|
||||
#endif
|
||||
|
||||
tuple get_ip(peer_info const& pi)
|
||||
{
|
||||
return make_tuple(pi.ip.address().to_string(), pi.ip.port());
|
||||
}
|
||||
|
||||
list get_pieces(peer_info const& pi)
|
||||
{
|
||||
list ret;
|
||||
|
||||
for (bitfield::const_iterator i = pi.pieces.begin()
|
||||
, end(pi.pieces.end()); i != end; ++i)
|
||||
{
|
||||
ret.append(*i);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void bind_peer_info()
|
||||
{
|
||||
scope pi = class_<peer_info>("peer_info")
|
||||
.def_readonly("flags", &peer_info::flags)
|
||||
.def_readonly("source", &peer_info::source)
|
||||
.def_readonly("read_state", &peer_info::read_state)
|
||||
.def_readonly("write_state", &peer_info::write_state)
|
||||
.add_property("ip", get_ip)
|
||||
.def_readonly("up_speed", &peer_info::up_speed)
|
||||
.def_readonly("down_speed", &peer_info::down_speed)
|
||||
.def_readonly("payload_up_speed", &peer_info::payload_up_speed)
|
||||
.def_readonly("payload_down_speed", &peer_info::payload_down_speed)
|
||||
.def_readonly("total_download", &peer_info::total_download)
|
||||
.def_readonly("total_upload", &peer_info::total_upload)
|
||||
.def_readonly("pid", &peer_info::pid)
|
||||
.add_property("pieces", get_pieces)
|
||||
.def_readonly("upload_limit", &peer_info::upload_limit)
|
||||
.def_readonly("download_limit", &peer_info::download_limit)
|
||||
.add_property("last_request", get_last_request)
|
||||
.add_property("last_active", get_last_active)
|
||||
.def_readonly("send_buffer_size", &peer_info::send_buffer_size)
|
||||
.def_readonly("used_send_buffer", &peer_info::used_send_buffer)
|
||||
.def_readonly("num_hashfails", &peer_info::num_hashfails)
|
||||
#ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES
|
||||
.add_property("country", get_country)
|
||||
#endif
|
||||
#ifndef TORRENT_DISABLE_GEO_IP
|
||||
.def_readonly("inet_as_name", &peer_info::inet_as_name)
|
||||
.def_readonly("inet_as", &peer_info::inet_as)
|
||||
#endif
|
||||
.def_readonly("load_balancing", &peer_info::load_balancing)
|
||||
.def_readonly("download_queue_length", &peer_info::download_queue_length)
|
||||
.def_readonly("upload_queue_length", &peer_info::upload_queue_length)
|
||||
.def_readonly("failcount", &peer_info::failcount)
|
||||
.def_readonly("downloading_piece_index", &peer_info::downloading_piece_index)
|
||||
.def_readonly("downloading_block_index", &peer_info::downloading_block_index)
|
||||
.def_readonly("downloading_progress", &peer_info::downloading_progress)
|
||||
.def_readonly("downloading_total", &peer_info::downloading_total)
|
||||
.def_readonly("client", &peer_info::client)
|
||||
.def_readonly("connection_type", &peer_info::connection_type)
|
||||
.def_readonly("remote_dl_rate", &peer_info::remote_dl_rate)
|
||||
.def_readonly("pending_disk_bytes", &peer_info::pending_disk_bytes)
|
||||
.def_readonly("send_quota", &peer_info::send_quota)
|
||||
.def_readonly("receive_quota", &peer_info::receive_quota)
|
||||
.def_readonly("rtt", &peer_info::rtt)
|
||||
.def_readonly("progress", &peer_info::progress)
|
||||
;
|
||||
|
||||
// flags
|
||||
pi.attr("interesting") = (int)peer_info::interesting;
|
||||
pi.attr("choked") = (int)peer_info::choked;
|
||||
pi.attr("remote_interested") = (int)peer_info::remote_interested;
|
||||
pi.attr("remote_choked") = (int)peer_info::remote_choked;
|
||||
pi.attr("supports_extensions") = (int)peer_info::supports_extensions;
|
||||
pi.attr("local_connection") = (int)peer_info::local_connection;
|
||||
pi.attr("handshake") = (int)peer_info::handshake;
|
||||
pi.attr("connecting") = (int)peer_info::connecting;
|
||||
pi.attr("queued") = (int)peer_info::queued;
|
||||
pi.attr("on_parole") = (int)peer_info::on_parole;
|
||||
pi.attr("seed") = (int)peer_info::seed;
|
||||
#ifndef TORRENT_DISABLE_ENCRYPTION
|
||||
pi.attr("rc4_encrypted") = (int)peer_info::rc4_encrypted;
|
||||
pi.attr("plaintext_encrypted") = (int)peer_info::plaintext_encrypted;
|
||||
#endif
|
||||
|
||||
// connection_type
|
||||
pi.attr("standard_bittorrent") = (int)peer_info::standard_bittorrent;
|
||||
pi.attr("web_seed") = (int)peer_info::web_seed;
|
||||
|
||||
// source
|
||||
pi.attr("tracker") = (int)peer_info::tracker;
|
||||
pi.attr("dht") = (int)peer_info::dht;
|
||||
pi.attr("pex") = (int)peer_info::pex;
|
||||
pi.attr("lsd") = (int)peer_info::lsd;
|
||||
pi.attr("resume_data") = (int)peer_info::resume_data;
|
||||
|
||||
// read/write state
|
||||
pi.attr("bw_idle") = (int)peer_info::bw_idle;
|
||||
#ifndef TORRENT_NO_DEPRECATE
|
||||
pi.attr("bw_torrent") = (int)peer_info::bw_torrent;
|
||||
pi.attr("bw_global") = (int)peer_info::bw_global;
|
||||
#endif
|
||||
pi.attr("bw_network") = (int)peer_info::bw_network;
|
||||
}
|
||||
|
|
@ -1,359 +0,0 @@
|
|||
// Copyright Daniel Wallin 2007. Use, modification and distribution is
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <cctype>
|
||||
#include <iostream>
|
||||
|
||||
#include <libtorrent/extensions.hpp>
|
||||
#include <libtorrent/entry.hpp>
|
||||
#include <libtorrent/lazy_entry.hpp>
|
||||
#include <libtorrent/peer_request.hpp>
|
||||
#include <libtorrent/disk_buffer_holder.hpp>
|
||||
#include <libtorrent/bitfield.hpp>
|
||||
#include <boost/python.hpp>
|
||||
|
||||
using namespace boost::python;
|
||||
using namespace libtorrent;
|
||||
|
||||
namespace
|
||||
{
|
||||
struct peer_plugin_wrap : peer_plugin, wrapper<peer_plugin>
|
||||
{
|
||||
void add_handshake(entry& e)
|
||||
{
|
||||
if (override f = this->get_override("add_handshake"))
|
||||
e = call<entry>(f.ptr(), e);
|
||||
else
|
||||
peer_plugin::add_handshake(e);
|
||||
}
|
||||
|
||||
void default_add_handshake(entry& e)
|
||||
{
|
||||
this->peer_plugin::add_handshake(e);
|
||||
}
|
||||
|
||||
bool on_handshake(char const* reserved_bits)
|
||||
{
|
||||
if (override f = this->get_override("on_handshake"))
|
||||
return f();
|
||||
else
|
||||
return peer_plugin::on_handshake(reserved_bits);
|
||||
}
|
||||
|
||||
bool default_on_handshake(char const* reserved_bits)
|
||||
{
|
||||
return this->peer_plugin::on_handshake(reserved_bits);
|
||||
}
|
||||
|
||||
bool on_extension_handshake(lazy_entry const& e)
|
||||
{
|
||||
if (override f = this->get_override("on_extension_handshake"))
|
||||
return f(e);
|
||||
else
|
||||
return peer_plugin::on_extension_handshake(e);
|
||||
}
|
||||
|
||||
bool default_on_extension_handshake(lazy_entry const& e)
|
||||
{
|
||||
return this->peer_plugin::on_extension_handshake(e);
|
||||
}
|
||||
|
||||
bool on_choke()
|
||||
{
|
||||
if (override f = this->get_override("on_choke"))
|
||||
return f();
|
||||
else
|
||||
return peer_plugin::on_choke();
|
||||
}
|
||||
|
||||
bool default_on_choke()
|
||||
{
|
||||
return this->peer_plugin::on_choke();
|
||||
}
|
||||
|
||||
bool on_unchoke()
|
||||
{
|
||||
if (override f = this->get_override("on_unchoke"))
|
||||
return f();
|
||||
else
|
||||
return peer_plugin::on_unchoke();
|
||||
}
|
||||
|
||||
bool default_on_unchoke()
|
||||
{
|
||||
return this->peer_plugin::on_unchoke();
|
||||
}
|
||||
|
||||
bool on_interested()
|
||||
{
|
||||
if (override f = this->get_override("on_interested"))
|
||||
return f();
|
||||
else
|
||||
return peer_plugin::on_interested();
|
||||
}
|
||||
|
||||
bool default_on_interested()
|
||||
{
|
||||
return this->peer_plugin::on_interested();
|
||||
}
|
||||
|
||||
bool on_not_interested()
|
||||
{
|
||||
if (override f = this->get_override("on_not_interested"))
|
||||
return f();
|
||||
else
|
||||
return peer_plugin::on_not_interested();
|
||||
}
|
||||
|
||||
bool default_on_not_interested()
|
||||
{
|
||||
return this->peer_plugin::on_not_interested();
|
||||
}
|
||||
|
||||
bool on_have(int index)
|
||||
{
|
||||
if (override f = this->get_override("on_have"))
|
||||
return f(index);
|
||||
else
|
||||
return peer_plugin::on_have(index);
|
||||
}
|
||||
|
||||
bool default_on_have(int index)
|
||||
{
|
||||
return this->peer_plugin::on_have(index);
|
||||
}
|
||||
|
||||
bool on_bitfield(list _bf)
|
||||
{
|
||||
//Convert list to a bitfield
|
||||
bitfield bf(len(_bf));
|
||||
for (int i = 0; i < len(_bf); ++i)
|
||||
{
|
||||
if (_bf[i])
|
||||
bf.set_bit(i);
|
||||
else
|
||||
bf.clear_bit(i);
|
||||
}
|
||||
if (override f = this->get_override("on_bitfield"))
|
||||
return f(bf);
|
||||
else
|
||||
return peer_plugin::on_bitfield(bf);
|
||||
}
|
||||
|
||||
bool default_on_bitfield(const bitfield &bf)
|
||||
{
|
||||
return this->peer_plugin::on_bitfield(bf);
|
||||
}
|
||||
|
||||
bool on_request(peer_request const& req)
|
||||
{
|
||||
if (override f = this->get_override("on_request"))
|
||||
return f(req);
|
||||
else
|
||||
return peer_plugin::on_request(req);
|
||||
}
|
||||
|
||||
bool default_on_request(peer_request const& req)
|
||||
{
|
||||
return this->peer_plugin::on_request(req);
|
||||
}
|
||||
|
||||
bool on_piece(peer_request const& piece, disk_buffer_holder& data)
|
||||
{
|
||||
if (override f = this->get_override("on_piece"))
|
||||
return f(piece, data);
|
||||
else
|
||||
return peer_plugin::on_piece(piece, data);
|
||||
}
|
||||
|
||||
bool default_on_piece(peer_request const& piece, disk_buffer_holder& data)
|
||||
{
|
||||
return this->peer_plugin::on_piece(piece, data);
|
||||
}
|
||||
|
||||
bool on_cancel(peer_request const& req)
|
||||
{
|
||||
if (override f = this->get_override("on_cancel"))
|
||||
return f(req);
|
||||
else
|
||||
return peer_plugin::on_cancel(req);
|
||||
}
|
||||
|
||||
bool default_on_cancel(peer_request const& req)
|
||||
{
|
||||
return this->peer_plugin::on_cancel(req);
|
||||
}
|
||||
|
||||
bool on_extended(int length, int msg, buffer::const_interval body)
|
||||
{
|
||||
if (override f = this->get_override("on_extended"))
|
||||
return f(length, msg, body);
|
||||
else
|
||||
return peer_plugin::on_extended(length, msg, body);
|
||||
}
|
||||
|
||||
bool default_on_extended(int length, int msg, buffer::const_interval body)
|
||||
{
|
||||
return this->peer_plugin::on_extended(length, msg, body);
|
||||
}
|
||||
|
||||
bool on_unknown_message(int length, int msg, buffer::const_interval body)
|
||||
{
|
||||
if (override f = this->get_override("on_unknown_message"))
|
||||
return f(length, msg, body);
|
||||
else
|
||||
return peer_plugin::on_unknown_message(length, msg, body);
|
||||
}
|
||||
|
||||
bool default_on_unknown_message(int length, int msg, buffer::const_interval body)
|
||||
{
|
||||
return this->peer_plugin::on_unknown_message(length, msg, body);
|
||||
}
|
||||
|
||||
void on_piece_pass(int index)
|
||||
{
|
||||
if (override f = this->get_override("on_piece_pass"))
|
||||
f(index);
|
||||
else
|
||||
peer_plugin::on_piece_pass(index);
|
||||
}
|
||||
|
||||
void default_on_piece_pass(int index)
|
||||
{
|
||||
this->peer_plugin::on_piece_pass(index);
|
||||
}
|
||||
|
||||
void on_piece_failed(int index)
|
||||
{
|
||||
if (override f = this->get_override("on_piece_failed"))
|
||||
f(index);
|
||||
else
|
||||
peer_plugin::on_piece_failed(index);
|
||||
}
|
||||
|
||||
void default_on_piece_failed(int index)
|
||||
{
|
||||
this->peer_plugin::on_piece_failed(index);
|
||||
}
|
||||
|
||||
void tick()
|
||||
{
|
||||
if (override f = this->get_override("tick"))
|
||||
f();
|
||||
else
|
||||
peer_plugin::tick();
|
||||
}
|
||||
|
||||
void default_tick()
|
||||
{
|
||||
this->peer_plugin::tick();
|
||||
}
|
||||
|
||||
bool write_request(peer_request const& req)
|
||||
{
|
||||
if (override f = this->get_override("write_request"))
|
||||
return f(req);
|
||||
else
|
||||
return peer_plugin::write_request(req);
|
||||
}
|
||||
|
||||
bool default_write_request(peer_request const& req)
|
||||
{
|
||||
return this->peer_plugin::write_request(req);
|
||||
}
|
||||
};
|
||||
|
||||
object get_buffer()
|
||||
{
|
||||
static char const data[] = "foobar";
|
||||
return object(handle<>(PyBuffer_FromMemory((void*)data, 6)));
|
||||
}
|
||||
|
||||
} // namespace unnamed
|
||||
|
||||
void bind_peer_plugin()
|
||||
{
|
||||
class_<
|
||||
peer_plugin_wrap, boost::shared_ptr<peer_plugin_wrap>, boost::noncopyable
|
||||
>("peer_plugin")
|
||||
.def(
|
||||
"add_handshake"
|
||||
, &peer_plugin::add_handshake, &peer_plugin_wrap::default_add_handshake
|
||||
)
|
||||
.def(
|
||||
"on_handshake"
|
||||
, &peer_plugin::on_handshake, &peer_plugin_wrap::default_on_handshake
|
||||
)
|
||||
.def(
|
||||
"on_extension_handshake"
|
||||
, &peer_plugin::on_extension_handshake
|
||||
, &peer_plugin_wrap::default_on_extension_handshake
|
||||
)
|
||||
.def(
|
||||
"on_choke"
|
||||
, &peer_plugin::on_choke, &peer_plugin_wrap::default_on_choke
|
||||
)
|
||||
.def(
|
||||
"on_unchoke"
|
||||
, &peer_plugin::on_unchoke, &peer_plugin_wrap::default_on_unchoke
|
||||
)
|
||||
.def(
|
||||
"on_interested"
|
||||
, &peer_plugin::on_interested, &peer_plugin_wrap::default_on_interested
|
||||
)
|
||||
.def(
|
||||
"on_not_interested"
|
||||
, &peer_plugin::on_not_interested, &peer_plugin_wrap::default_on_not_interested
|
||||
)
|
||||
.def(
|
||||
"on_have"
|
||||
, &peer_plugin::on_have, &peer_plugin_wrap::default_on_have
|
||||
)
|
||||
.def(
|
||||
"on_bitfield"
|
||||
, &peer_plugin::on_bitfield, &peer_plugin_wrap::default_on_bitfield
|
||||
)
|
||||
.def(
|
||||
"on_request"
|
||||
, &peer_plugin::on_request, &peer_plugin_wrap::default_on_request
|
||||
)
|
||||
.def(
|
||||
"on_piece"
|
||||
, &peer_plugin::on_piece, &peer_plugin_wrap::default_on_piece
|
||||
)
|
||||
.def(
|
||||
"on_cancel"
|
||||
, &peer_plugin::on_cancel, &peer_plugin_wrap::default_on_cancel
|
||||
)
|
||||
.def(
|
||||
"on_piece_pass"
|
||||
, &peer_plugin::on_piece_pass, &peer_plugin_wrap::default_on_piece_pass
|
||||
)
|
||||
.def(
|
||||
"on_piece_failed"
|
||||
, &peer_plugin::on_piece_failed, &peer_plugin_wrap::default_on_piece_failed
|
||||
)
|
||||
.def(
|
||||
"tick"
|
||||
, &peer_plugin::tick, &peer_plugin_wrap::default_tick
|
||||
)
|
||||
.def(
|
||||
"write_request"
|
||||
, &peer_plugin::write_request, &peer_plugin_wrap::default_write_request
|
||||
)
|
||||
// These seem to make VC7.1 freeze. Needs special handling.
|
||||
|
||||
/*.def(
|
||||
"on_extended"
|
||||
, &peer_plugin::on_extended, &peer_plugin_wrap::default_on_extended
|
||||
)
|
||||
.def(
|
||||
"on_unknown_message"
|
||||
, &peer_plugin::on_unknown_message, &peer_plugin_wrap::default_on_unknown_message
|
||||
)*/
|
||||
;
|
||||
|
||||
def("get_buffer", &get_buffer);
|
||||
}
|
||||
|
|
@ -1,407 +0,0 @@
|
|||
// Copyright Daniel Wallin, Arvid Norberg 2006. Use, modification and distribution is
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/python.hpp>
|
||||
#include <libtorrent/session.hpp>
|
||||
#include <libtorrent/torrent.hpp>
|
||||
#include <libtorrent/storage.hpp>
|
||||
#include <libtorrent/ip_filter.hpp>
|
||||
#include <libtorrent/disk_io_thread.hpp>
|
||||
#include "gil.hpp"
|
||||
|
||||
using namespace boost::python;
|
||||
using namespace libtorrent;
|
||||
|
||||
namespace
|
||||
{
|
||||
bool listen_on(session& s, int min_, int max_, char const* interface)
|
||||
{
|
||||
allow_threading_guard guard;
|
||||
return s.listen_on(std::make_pair(min_, max_), interface);
|
||||
}
|
||||
|
||||
void outgoing_ports(session& s, int _min, int _max)
|
||||
{
|
||||
allow_threading_guard guard;
|
||||
session_settings settings = s.settings();
|
||||
settings.outgoing_ports = std::make_pair(_min, _max);
|
||||
s.set_settings(settings);
|
||||
return;
|
||||
}
|
||||
#ifndef TORRENT_DISABLE_DHT
|
||||
void add_dht_router(session& s, std::string router_, int port_)
|
||||
{
|
||||
allow_threading_guard guard;
|
||||
return s.add_dht_router(std::make_pair(router_, port_));
|
||||
}
|
||||
#endif
|
||||
|
||||
struct invoke_extension_factory
|
||||
{
|
||||
invoke_extension_factory(object const& callback)
|
||||
: cb(callback)
|
||||
{}
|
||||
|
||||
boost::shared_ptr<torrent_plugin> operator()(torrent* t, void*)
|
||||
{
|
||||
lock_gil lock;
|
||||
return extract<boost::shared_ptr<torrent_plugin> >(cb(ptr(t)))();
|
||||
}
|
||||
|
||||
object cb;
|
||||
};
|
||||
|
||||
void add_extension(session& s, object const& e)
|
||||
{
|
||||
allow_threading_guard guard;
|
||||
s.add_extension(invoke_extension_factory(e));
|
||||
}
|
||||
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
#ifndef TORRENT_NO_DEPRECATE
|
||||
torrent_handle add_torrent_depr(session& s, torrent_info const& ti
|
||||
, std::string const& save, entry const& resume
|
||||
, storage_mode_t storage_mode, bool paused)
|
||||
{
|
||||
allow_threading_guard guard;
|
||||
return s.add_torrent(ti, save, resume, storage_mode, paused, default_storage_constructor);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
torrent_handle add_torrent(session& s, dict params)
|
||||
{
|
||||
add_torrent_params p;
|
||||
|
||||
if (params.has_key("ti"))
|
||||
p.ti = new torrent_info(extract<torrent_info const&>(params["ti"]));
|
||||
|
||||
std::string url;
|
||||
if (params.has_key("tracker_url"))
|
||||
{
|
||||
url = extract<std::string>(params["tracker_url"]);
|
||||
p.tracker_url = url.c_str();
|
||||
}
|
||||
if (params.has_key("info_hash"))
|
||||
p.info_hash = extract<sha1_hash>(params["info_hash"]);
|
||||
std::string name;
|
||||
if (params.has_key("name"))
|
||||
{
|
||||
name = extract<std::string>(params["name"]);
|
||||
p.name = name.c_str();
|
||||
}
|
||||
p.save_path = extract<std::string>(params["save_path"]);
|
||||
|
||||
std::vector<char> resume_buf;
|
||||
if (params.has_key("resume_data"))
|
||||
{
|
||||
std::string resume = extract<std::string>(params["resume_data"]);
|
||||
resume_buf.resize(resume.size());
|
||||
std::memcpy(&resume_buf[0], &resume[0], resume.size());
|
||||
p.resume_data = &resume_buf;
|
||||
}
|
||||
if (params.has_key("storage_mode"))
|
||||
p.storage_mode = extract<storage_mode_t>(params["storage_mode"]);
|
||||
if (params.has_key("paused"))
|
||||
p.paused = params["paused"];
|
||||
if (params.has_key("auto_managed"))
|
||||
p.auto_managed = params["auto_managed"];
|
||||
if (params.has_key("duplicate_is_error"))
|
||||
p.duplicate_is_error = params["duplicate_is_error"];
|
||||
if (params.has_key("seed_mode"))
|
||||
p.seed_mode = params["seed_mode"];
|
||||
if (params.has_key("upload_mode"))
|
||||
p.upload_mode = params["upload_mode"];
|
||||
if (params.has_key("share_mode"))
|
||||
p.upload_mode = params["share_mode"];
|
||||
if (params.has_key("override_resume_data"))
|
||||
p.override_resume_data = params["override_resume_data"];
|
||||
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
return s.add_torrent(p);
|
||||
#else
|
||||
error_code ec;
|
||||
return s.add_torrent(p, ec);
|
||||
#endif
|
||||
}
|
||||
|
||||
void start_natpmp(session& s)
|
||||
{
|
||||
allow_threading_guard guard;
|
||||
s.start_natpmp();
|
||||
}
|
||||
|
||||
void start_upnp(session& s)
|
||||
{
|
||||
allow_threading_guard guard;
|
||||
s.start_upnp();
|
||||
}
|
||||
|
||||
alert const* wait_for_alert(session& s, int ms)
|
||||
{
|
||||
return s.wait_for_alert(milliseconds(ms));
|
||||
}
|
||||
|
||||
list get_torrents(session& s)
|
||||
{
|
||||
list ret;
|
||||
std::vector<torrent_handle> torrents = s.get_torrents();
|
||||
|
||||
for (std::vector<torrent_handle>::iterator i = torrents.begin(); i != torrents.end(); ++i)
|
||||
{
|
||||
ret.append(*i);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifndef TORRENT_DISABLE_GEO_IP
|
||||
void load_asnum_db(session& s, std::string file)
|
||||
{
|
||||
allow_threading_guard guard;
|
||||
s.load_asnum_db(file.c_str());
|
||||
}
|
||||
|
||||
void load_country_db(session& s, std::string file)
|
||||
{
|
||||
allow_threading_guard guard;
|
||||
s.load_country_db(file.c_str());
|
||||
}
|
||||
#endif
|
||||
|
||||
entry save_state(session const& s, boost::uint32_t flags)
|
||||
{
|
||||
entry e;
|
||||
s.save_state(e, flags);
|
||||
return e;
|
||||
}
|
||||
|
||||
} // namespace unnamed
|
||||
|
||||
|
||||
void bind_session()
|
||||
{
|
||||
#ifndef TORRENT_DISABLE_DHT
|
||||
void (session::*start_dht0)() = &session::start_dht;
|
||||
#ifndef TORRENT_NO_DEPRECATE
|
||||
void (session::*start_dht1)(entry const&) = &session::start_dht;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
void (session::*load_state0)(lazy_entry const&) = &session::load_state;
|
||||
#ifndef TORRENT_NO_DEPRECATE
|
||||
void (session::*load_state1)(entry const&) = &session::load_state;
|
||||
#endif
|
||||
|
||||
class_<session_status>("session_status")
|
||||
.def_readonly("has_incoming_connections", &session_status::has_incoming_connections)
|
||||
|
||||
.def_readonly("upload_rate", &session_status::upload_rate)
|
||||
.def_readonly("download_rate", &session_status::download_rate)
|
||||
.def_readonly("total_download", &session_status::total_download)
|
||||
.def_readonly("total_upload", &session_status::total_upload)
|
||||
|
||||
.def_readonly("payload_upload_rate", &session_status::payload_upload_rate)
|
||||
.def_readonly("payload_download_rate", &session_status::payload_download_rate)
|
||||
.def_readonly("total_payload_download", &session_status::total_payload_download)
|
||||
.def_readonly("total_payload_upload", &session_status::total_payload_upload)
|
||||
|
||||
.def_readonly("ip_overhead_upload_rate", &session_status::ip_overhead_upload_rate)
|
||||
.def_readonly("ip_overhead_download_rate", &session_status::ip_overhead_download_rate)
|
||||
.def_readonly("total_ip_overhead_download", &session_status::total_ip_overhead_download)
|
||||
.def_readonly("total_ip_overhead_upload", &session_status::total_ip_overhead_upload)
|
||||
|
||||
.def_readonly("dht_upload_rate", &session_status::dht_upload_rate)
|
||||
.def_readonly("dht_download_rate", &session_status::dht_download_rate)
|
||||
.def_readonly("total_dht_download", &session_status::total_dht_download)
|
||||
.def_readonly("total_dht_upload", &session_status::total_dht_upload)
|
||||
|
||||
.def_readonly("tracker_upload_rate", &session_status::tracker_upload_rate)
|
||||
.def_readonly("tracker_download_rate", &session_status::tracker_download_rate)
|
||||
.def_readonly("total_tracker_download", &session_status::total_tracker_download)
|
||||
.def_readonly("total_tracker_upload", &session_status::total_tracker_upload)
|
||||
|
||||
.def_readonly("total_redundant_bytes", &session_status::total_redundant_bytes)
|
||||
.def_readonly("total_failed_bytes", &session_status::total_failed_bytes)
|
||||
|
||||
.def_readonly("num_peers", &session_status::num_peers)
|
||||
.def_readonly("num_unchoked", &session_status::num_unchoked)
|
||||
.def_readonly("allowed_upload_slots", &session_status::allowed_upload_slots)
|
||||
|
||||
.def_readonly("up_bandwidth_queue", &session_status::up_bandwidth_queue)
|
||||
.def_readonly("down_bandwidth_queue", &session_status::down_bandwidth_queue)
|
||||
|
||||
.def_readonly("up_bandwidth_bytes_queue", &session_status::up_bandwidth_bytes_queue)
|
||||
.def_readonly("down_bandwidth_bytes_queue", &session_status::down_bandwidth_bytes_queue)
|
||||
|
||||
.def_readonly("optimistic_unchoke_counter", &session_status::optimistic_unchoke_counter)
|
||||
.def_readonly("unchoke_counter", &session_status::unchoke_counter)
|
||||
|
||||
#ifndef TORRENT_DISABLE_DHT
|
||||
.def_readonly("dht_nodes", &session_status::dht_nodes)
|
||||
.def_readonly("dht_node_cache", &session_status::dht_node_cache)
|
||||
.def_readonly("dht_torrents", &session_status::dht_torrents)
|
||||
.def_readonly("dht_global_nodes", &session_status::dht_global_nodes)
|
||||
.def_readonly("active_requests", &session_status::active_requests)
|
||||
#endif
|
||||
;
|
||||
|
||||
class_<dht_lookup>("dht_lookup")
|
||||
.def_readonly("type", &dht_lookup::type)
|
||||
.def_readonly("outstanding_requests", &dht_lookup::outstanding_requests)
|
||||
.def_readonly("timeouts", &dht_lookup::timeouts)
|
||||
.def_readonly("response", &dht_lookup::responses)
|
||||
.def_readonly("branch_factor", &dht_lookup::branch_factor)
|
||||
;
|
||||
|
||||
enum_<storage_mode_t>("storage_mode_t")
|
||||
.value("storage_mode_allocate", storage_mode_allocate)
|
||||
.value("storage_mode_sparse", storage_mode_sparse)
|
||||
.value("storage_mode_compact", storage_mode_compact)
|
||||
;
|
||||
|
||||
enum_<session::options_t>("options_t")
|
||||
.value("none", session::none)
|
||||
.value("delete_files", session::delete_files)
|
||||
;
|
||||
|
||||
enum_<session::session_flags_t>("session_flags_t")
|
||||
.value("add_default_plugins", session::add_default_plugins)
|
||||
.value("start_default_features", session::start_default_features)
|
||||
;
|
||||
|
||||
class_<cache_status>("cache_status")
|
||||
.def_readonly("blocks_written", &cache_status::blocks_written)
|
||||
.def_readonly("writes", &cache_status::writes)
|
||||
.def_readonly("blocks_read", &cache_status::blocks_read)
|
||||
.def_readonly("blocks_read_hit", &cache_status::blocks_read_hit)
|
||||
.def_readonly("reads", &cache_status::reads)
|
||||
.def_readonly("cache_size", &cache_status::cache_size)
|
||||
.def_readonly("read_cache_size", &cache_status::read_cache_size)
|
||||
.def_readonly("total_used_buffers", &cache_status::total_used_buffers)
|
||||
;
|
||||
|
||||
class_<session, boost::noncopyable>("session", no_init)
|
||||
.def(
|
||||
init<fingerprint, int>((
|
||||
arg("fingerprint")=fingerprint("LT",0,1,0,0)
|
||||
, arg("flags")=session::start_default_features | session::add_default_plugins))
|
||||
)
|
||||
.def(
|
||||
"listen_on", &listen_on
|
||||
, (arg("min"), "max", arg("interface") = (char const*)0)
|
||||
)
|
||||
.def("outgoing_ports", &outgoing_ports)
|
||||
.def("is_listening", allow_threads(&session::is_listening))
|
||||
.def("listen_port", allow_threads(&session::listen_port))
|
||||
.def("status", allow_threads(&session::status))
|
||||
#ifndef TORRENT_DISABLE_DHT
|
||||
.def(
|
||||
"add_dht_router", &add_dht_router
|
||||
, (arg("router"), "port")
|
||||
)
|
||||
.def("start_dht", allow_threads(start_dht0))
|
||||
#ifndef TORRENT_NO_DEPRECATE
|
||||
.def("start_dht", allow_threads(start_dht1))
|
||||
#endif
|
||||
.def("stop_dht", allow_threads(&session::stop_dht))
|
||||
#ifndef TORRENT_NO_DEPRECATE
|
||||
.def("dht_state", allow_threads(&session::dht_state))
|
||||
#endif
|
||||
.def("set_dht_proxy", allow_threads(&session::set_dht_proxy))
|
||||
.def("dht_proxy", allow_threads(&session::dht_proxy))
|
||||
#endif
|
||||
.def("add_torrent", &add_torrent)
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
#ifndef TORRENT_NO_DEPRECATE
|
||||
.def(
|
||||
"add_torrent", &add_torrent_depr
|
||||
, (
|
||||
arg("resume_data") = entry(),
|
||||
arg("storage_mode") = storage_mode_sparse,
|
||||
arg("paused") = false
|
||||
)
|
||||
)
|
||||
#endif
|
||||
#endif
|
||||
.def("remove_torrent", allow_threads(&session::remove_torrent), arg("option") = session::none
|
||||
)
|
||||
.def("set_local_download_rate_limit", allow_threads(&session::set_local_download_rate_limit))
|
||||
.def("local_download_rate_limit", allow_threads(&session::local_download_rate_limit))
|
||||
|
||||
.def("set_local_upload_rate_limit", allow_threads(&session::set_local_upload_rate_limit))
|
||||
.def("local_upload_rate_limit", allow_threads(&session::local_upload_rate_limit))
|
||||
|
||||
.def("set_download_rate_limit", allow_threads(&session::set_download_rate_limit))
|
||||
.def("download_rate_limit", allow_threads(&session::download_rate_limit))
|
||||
|
||||
.def("set_upload_rate_limit", allow_threads(&session::set_upload_rate_limit))
|
||||
.def("upload_rate_limit", allow_threads(&session::upload_rate_limit))
|
||||
|
||||
.def("set_max_uploads", allow_threads(&session::set_max_uploads))
|
||||
.def("set_max_connections", allow_threads(&session::set_max_connections))
|
||||
.def("set_max_half_open_connections", allow_threads(&session::set_max_half_open_connections))
|
||||
.def("num_connections", allow_threads(&session::num_connections))
|
||||
.def("set_settings", allow_threads(&session::set_settings))
|
||||
.def("settings", allow_threads(&session::settings))
|
||||
#ifndef TORRENT_DISABLE_ENCRYPTION
|
||||
.def("set_pe_settings", allow_threads(&session::set_pe_settings))
|
||||
.def("get_pe_settings", allow_threads(&session::get_pe_settings))
|
||||
#endif
|
||||
#ifndef TORRENT_DISABLE_GEO_IP
|
||||
.def("load_asnum_db", &load_asnum_db)
|
||||
.def("load_country_db", &load_country_db)
|
||||
#endif
|
||||
.def("load_state", load_state0)
|
||||
.def("save_state", &save_state, (arg("entry"), arg("flags") = 0xffffffff))
|
||||
#ifndef TORRENT_NO_DEPRECATE
|
||||
.def("load_state", load_state1)
|
||||
.def("set_severity_level", allow_threads(&session::set_severity_level))
|
||||
#endif
|
||||
.def("set_alert_mask", allow_threads(&session::set_alert_mask))
|
||||
.def("set_alert_queue_size_limit", allow_threads(&session::set_alert_queue_size_limit))
|
||||
.def("pop_alert", allow_threads(&session::pop_alert))
|
||||
.def("wait_for_alert", &wait_for_alert, return_internal_reference<>())
|
||||
.def("add_extension", &add_extension)
|
||||
#ifndef TORRENT_NO_DEPRECATE
|
||||
.def("set_peer_proxy", allow_threads(&session::set_peer_proxy))
|
||||
.def("set_tracker_proxy", allow_threads(&session::set_tracker_proxy))
|
||||
.def("set_web_seed_proxy", allow_threads(&session::set_web_seed_proxy))
|
||||
.def("peer_proxy", allow_threads(&session::peer_proxy))
|
||||
.def("tracker_proxy", allow_threads(&session::tracker_proxy))
|
||||
.def("web_seed_proxy", allow_threads(&session::web_seed_proxy))
|
||||
#endif
|
||||
.def("set_proxy", allow_threads(&session::set_proxy))
|
||||
.def("proxy", allow_threads(&session::proxy))
|
||||
.def("start_upnp", &start_upnp)
|
||||
.def("stop_upnp", allow_threads(&session::stop_upnp))
|
||||
.def("start_lsd", allow_threads(&session::start_lsd))
|
||||
.def("stop_lsd", allow_threads(&session::stop_lsd))
|
||||
.def("start_natpmp", &start_natpmp)
|
||||
.def("stop_natpmp", allow_threads(&session::stop_natpmp))
|
||||
.def("set_ip_filter", allow_threads(&session::set_ip_filter))
|
||||
.def("get_ip_filter", allow_threads(&session::get_ip_filter))
|
||||
.def("find_torrent", allow_threads(&session::find_torrent))
|
||||
.def("get_torrents", &get_torrents)
|
||||
.def("pause", allow_threads(&session::pause))
|
||||
.def("resume", allow_threads(&session::resume))
|
||||
.def("is_paused", allow_threads(&session::is_paused))
|
||||
.def("id", allow_threads(&session::id))
|
||||
.def("get_cache_status", allow_threads(&session::get_cache_status))
|
||||
;
|
||||
|
||||
enum_<session::save_state_flags_t>("save_state_flags_t")
|
||||
.value("save_settings", session::save_settings)
|
||||
.value("save_dht_settings", session::save_dht_settings)
|
||||
.value("save_dht_proxy", session::save_dht_proxy)
|
||||
.value("save_dht_state", session::save_dht_state)
|
||||
.value("save_i2p_proxy", session::save_i2p_proxy)
|
||||
.value("save_encryption_settings", session:: save_encryption_settings)
|
||||
.value("save_peer_proxy", session::save_peer_proxy)
|
||||
.value("save_web_proxy", session::save_web_proxy)
|
||||
.value("save_tracker_proxy", session::save_tracker_proxy)
|
||||
.value("save_as_map", session::save_as_map)
|
||||
;
|
||||
|
||||
register_ptr_to_python<std::auto_ptr<alert> >();
|
||||
}
|
|
@ -1,203 +0,0 @@
|
|||
// Copyright Daniel Wallin 2006. Use, modification and distribution is
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/python.hpp>
|
||||
#include <libtorrent/session.hpp>
|
||||
|
||||
using namespace boost::python;
|
||||
using namespace libtorrent;
|
||||
|
||||
void bind_session_settings()
|
||||
{
|
||||
class_<session_settings>("session_settings")
|
||||
.def_readwrite("user_agent", &session_settings::user_agent)
|
||||
.def_readwrite("tracker_completion_timeout", &session_settings::tracker_completion_timeout)
|
||||
.def_readwrite("tracker_receive_timeout", &session_settings::tracker_receive_timeout)
|
||||
.def_readwrite("stop_tracker_timeout", &session_settings::stop_tracker_timeout)
|
||||
.def_readwrite("tracker_maximum_response_length", &session_settings::tracker_maximum_response_length)
|
||||
.def_readwrite("piece_timeout", &session_settings::piece_timeout)
|
||||
.def_readwrite("request_timeout", &session_settings::request_timeout)
|
||||
.def_readwrite("request_queue_time", &session_settings::request_queue_time)
|
||||
.def_readwrite("max_allowed_in_request_queue", &session_settings::max_allowed_in_request_queue)
|
||||
.def_readwrite("max_out_request_queue", &session_settings::max_out_request_queue)
|
||||
.def_readwrite("whole_pieces_threshold", &session_settings::whole_pieces_threshold)
|
||||
.def_readwrite("peer_timeout", &session_settings::peer_timeout)
|
||||
.def_readwrite("urlseed_timeout", &session_settings::urlseed_timeout)
|
||||
.def_readwrite("urlseed_pipeline_size", &session_settings::urlseed_pipeline_size)
|
||||
.def_readwrite("urlseed_wait_retry", &session_settings::urlseed_wait_retry)
|
||||
.def_readwrite("file_pool_size", &session_settings::file_pool_size)
|
||||
.def_readwrite("allow_multiple_connections_per_ip", &session_settings::allow_multiple_connections_per_ip)
|
||||
.def_readwrite("max_failcount", &session_settings::max_failcount)
|
||||
.def_readwrite("min_reconnect_time", &session_settings::min_reconnect_time)
|
||||
.def_readwrite("peer_connect_timeout", &session_settings::peer_connect_timeout)
|
||||
.def_readwrite("ignore_limits_on_local_network", &session_settings::ignore_limits_on_local_network)
|
||||
.def_readwrite("connection_speed", &session_settings::connection_speed)
|
||||
.def_readwrite("send_redundant_have", &session_settings::send_redundant_have)
|
||||
.def_readwrite("lazy_bitfields", &session_settings::lazy_bitfields)
|
||||
.def_readwrite("inactivity_timeout", &session_settings::inactivity_timeout)
|
||||
.def_readwrite("unchoke_interval", &session_settings::unchoke_interval)
|
||||
.def_readwrite("optimistic_unchoke_interval", &session_settings::optimistic_unchoke_interval)
|
||||
.def_readwrite("num_want", &session_settings::num_want)
|
||||
.def_readwrite("initial_picker_threshold", &session_settings::initial_picker_threshold)
|
||||
.def_readwrite("allowed_fast_set_size", &session_settings::allowed_fast_set_size)
|
||||
.def_readwrite("max_queued_disk_bytes", &session_settings::max_queued_disk_bytes)
|
||||
.def_readwrite("handshake_timeout", &session_settings::handshake_timeout)
|
||||
#ifndef TORRENT_DISABLE_DHT
|
||||
.def_readwrite("use_dht_as_fallback", &session_settings::use_dht_as_fallback)
|
||||
#endif
|
||||
.def_readwrite("free_torrent_hashes", &session_settings::free_torrent_hashes)
|
||||
.def_readwrite("upnp_ignore_nonrouters", &session_settings::upnp_ignore_nonrouters)
|
||||
.def_readwrite("send_buffer_watermark", &session_settings::send_buffer_watermark)
|
||||
#ifndef TORRENT_NO_DEPRECATE
|
||||
.def_readwrite("auto_upload_slots", &session_settings::auto_upload_slots)
|
||||
.def_readwrite("auto_upload_slots_rate_based", &session_settings::auto_upload_slots_rate_based)
|
||||
#endif
|
||||
.def_readwrite("choking_algorithm", &session_settings::choking_algorithm)
|
||||
.def_readwrite("use_parole_mode", &session_settings::use_parole_mode)
|
||||
.def_readwrite("cache_size", &session_settings::cache_size)
|
||||
.def_readwrite("cache_buffer_chunk_size", &session_settings::cache_buffer_chunk_size)
|
||||
.def_readwrite("cache_expiry", &session_settings::cache_expiry)
|
||||
.def_readwrite("use_read_cache", &session_settings::use_read_cache)
|
||||
.def_readwrite("disk_io_write_mode", &session_settings::disk_io_write_mode)
|
||||
.def_readwrite("disk_io_read_mode", &session_settings::disk_io_read_mode)
|
||||
.def_readwrite("coalesce_reads", &session_settings::coalesce_reads)
|
||||
.def_readwrite("coalesce_writes", &session_settings::coalesce_writes)
|
||||
.def_readwrite("outgoing_ports", &session_settings::outgoing_ports)
|
||||
.def_readwrite("peer_tos", &session_settings::peer_tos)
|
||||
.def_readwrite("active_downloads", &session_settings::active_downloads)
|
||||
.def_readwrite("active_seeds", &session_settings::active_seeds)
|
||||
.def_readwrite("active_dht_limit", &session_settings::active_dht_limit)
|
||||
.def_readwrite("active_tracker_limit", &session_settings::active_tracker_limit)
|
||||
.def_readwrite("active_lsd_limit", &session_settings::active_lsd_limit)
|
||||
.def_readwrite("active_limit", &session_settings::active_limit)
|
||||
.def_readwrite("auto_manage_prefer_seeds", &session_settings::auto_manage_prefer_seeds)
|
||||
.def_readwrite("dont_count_slow_torrents", &session_settings::dont_count_slow_torrents)
|
||||
.def_readwrite("auto_manage_interval", &session_settings::auto_manage_interval)
|
||||
.def_readwrite("share_ratio_limit", &session_settings::share_ratio_limit)
|
||||
.def_readwrite("seed_time_ratio_limit", &session_settings::seed_time_ratio_limit)
|
||||
.def_readwrite("seed_time_limit", &session_settings::seed_time_limit)
|
||||
.def_readwrite("peer_turnover_interval", &session_settings::peer_turnover_interval)
|
||||
.def_readwrite("peer_turnover", &session_settings::peer_turnover)
|
||||
.def_readwrite("peer_turnover_cutoff", &session_settings::peer_turnover_cutoff)
|
||||
.def_readwrite("close_redundant_connections", &session_settings::close_redundant_connections)
|
||||
.def_readwrite("auto_scrape_interval", &session_settings::auto_scrape_interval)
|
||||
.def_readwrite("auto_scrape_min_interval", &session_settings::auto_scrape_min_interval)
|
||||
.def_readwrite("max_peerlist_size", &session_settings::max_peerlist_size)
|
||||
.def_readwrite("max_paused_peerlist_size", &session_settings::max_paused_peerlist_size)
|
||||
.def_readwrite("min_announce_interval", &session_settings::min_announce_interval)
|
||||
.def_readwrite("prioritize_partial_pieces", &session_settings::prioritize_partial_pieces)
|
||||
.def_readwrite("auto_manage_startup", &session_settings::auto_manage_startup)
|
||||
.def_readwrite("rate_limit_ip_overhead", &session_settings::rate_limit_ip_overhead)
|
||||
.def_readwrite("announce_to_all_trackers", &session_settings::announce_to_all_trackers)
|
||||
.def_readwrite("announce_to_all_tiers", &session_settings::announce_to_all_tiers)
|
||||
.def_readwrite("prefer_udp_trackers", &session_settings::prefer_udp_trackers)
|
||||
.def_readwrite("strict_super_seeding", &session_settings::strict_super_seeding)
|
||||
.def_readwrite("seeding_piece_quota", &session_settings::seeding_piece_quota)
|
||||
.def_readwrite("max_sparse_regions", &session_settings::max_sparse_regions)
|
||||
#ifndef TORRENT_DISABLE_MLOCK
|
||||
.def_readwrite("lock_disk_cache", &session_settings::lock_disk_cache)
|
||||
#endif
|
||||
.def_readwrite("max_rejects", &session_settings::max_rejects)
|
||||
.def_readwrite("recv_socket_buffer_size", &session_settings::recv_socket_buffer_size)
|
||||
.def_readwrite("send_socket_buffer_size", &session_settings::send_socket_buffer_size)
|
||||
.def_readwrite("optimize_hashing_for_speed", &session_settings::optimize_hashing_for_speed)
|
||||
.def_readwrite("file_checks_delay_per_block", &session_settings::file_checks_delay_per_block)
|
||||
.def_readwrite("disk_cache_algorithm", &session_settings::disk_cache_algorithm)
|
||||
.def_readwrite("read_cache_line_size", &session_settings::read_cache_line_size)
|
||||
.def_readwrite("write_cache_line_size", &session_settings::write_cache_line_size)
|
||||
.def_readwrite("optimistic_disk_retry", &session_settings::optimistic_disk_retry)
|
||||
.def_readwrite("disable_hash_checks", &session_settings::disable_hash_checks)
|
||||
.def_readwrite("allow_reordered_disk_operations", &session_settings::allow_reordered_disk_operations)
|
||||
.def_readwrite("allow_i2p_mixed", &session_settings::allow_i2p_mixed)
|
||||
.def_readwrite("max_suggest_pieces", &session_settings::max_suggest_pieces)
|
||||
.def_readwrite("drop_skipped_requests", &session_settings::drop_skipped_requests)
|
||||
.def_readwrite("low_prio_disk", &session_settings::low_prio_disk)
|
||||
.def_readwrite("local_service_announce_interval", &session_settings::local_service_announce_interval)
|
||||
.def_readwrite("dht_announce_interval", &session_settings::dht_announce_interval)
|
||||
.def_readwrite("udp_tracker_token_expiry", &session_settings::udp_tracker_token_expiry)
|
||||
.def_readwrite("volatile_read_cache", &session_settings::volatile_read_cache)
|
||||
.def_readwrite("guided_read_cache", &session_settings::guided_read_cache)
|
||||
.def_readwrite("default_cache_min_age", &session_settings::default_cache_min_age)
|
||||
.def_readwrite("num_optimistic_unchoke_slots", &session_settings::num_optimistic_unchoke_slots)
|
||||
.def_readwrite("no_atime_storage", &session_settings::no_atime_storage)
|
||||
.def_readwrite("default_est_reciprocation_rate", &session_settings::default_est_reciprocation_rate)
|
||||
.def_readwrite("increase_est_reciprocation_rate", &session_settings::increase_est_reciprocation_rate)
|
||||
.def_readwrite("decrease_est_reciprocation_rate", &session_settings::decrease_est_reciprocation_rate)
|
||||
.def_readwrite("incoming_starts_queued_torrents", &session_settings::incoming_starts_queued_torrents)
|
||||
.def_readwrite("report_true_downoaded", &session_settings::report_true_downloaded)
|
||||
.def_readwrite("strict_end_game_mode", &session_settings::strict_end_game_mode)
|
||||
.def_readwrite("broadcast_lsd", &session_settings::broadcast_lsd)
|
||||
.def_readwrite("ignore_resume_timestamps", &session_settings::ignore_resume_timestamps)
|
||||
.def_readwrite("anonymous_mode", &session_settings::anonymous_mode)
|
||||
.def_readwrite("tick_interval", &session_settings::tick_interval)
|
||||
.def_readwrite("report_web_seed_downloads", &session_settings::report_web_seed_downloads)
|
||||
.def_readwrite("share_mode_target", &session_settings::share_mode_target)
|
||||
;
|
||||
|
||||
enum_<proxy_settings::proxy_type>("proxy_type")
|
||||
.value("none", proxy_settings::none)
|
||||
.value("socks4", proxy_settings::socks4)
|
||||
.value("socks5", proxy_settings::socks5)
|
||||
.value("socks5_pw", proxy_settings::socks5_pw)
|
||||
.value("http", proxy_settings::http)
|
||||
.value("http_pw", proxy_settings::http_pw)
|
||||
;
|
||||
|
||||
enum_<session_settings::disk_cache_algo_t>("disk_cache_algo_t")
|
||||
.value("lru", session_settings::lru)
|
||||
.value("largest_contiguous", session_settings::largest_contiguous)
|
||||
;
|
||||
|
||||
enum_<session_settings::choking_algorithm_t>("choking_algorithm_t")
|
||||
.value("fixed_slots_choker", session_settings::fixed_slots_choker)
|
||||
.value("auto_expand_choker", session_settings::auto_expand_choker)
|
||||
.value("rate_based_choker", session_settings::rate_based_choker)
|
||||
.value("bittyrant_choker", session_settings::bittyrant_choker)
|
||||
;
|
||||
|
||||
enum_<session_settings::io_buffer_mode_t>("io_buffer_mode_t")
|
||||
.value("enable_os_cache", session_settings::enable_os_cache)
|
||||
.value("disable_os_cache_for_aligned_files", session_settings::disable_os_cache_for_aligned_files)
|
||||
.value("disable_os_cache", session_settings::disable_os_cache)
|
||||
;
|
||||
|
||||
class_<proxy_settings>("proxy_settings")
|
||||
.def_readwrite("hostname", &proxy_settings::hostname)
|
||||
.def_readwrite("port", &proxy_settings::port)
|
||||
.def_readwrite("password", &proxy_settings::password)
|
||||
.def_readwrite("username", &proxy_settings::username)
|
||||
.def_readwrite("type", &proxy_settings::type)
|
||||
;
|
||||
|
||||
#ifndef TORRENT_DISABLE_DHT
|
||||
class_<dht_settings>("dht_settings")
|
||||
.def_readwrite("max_peers_reply", &dht_settings::max_peers_reply)
|
||||
.def_readwrite("search_branching", &dht_settings::search_branching)
|
||||
.def_readwrite("service_port", &dht_settings::service_port)
|
||||
.def_readwrite("max_fail_count", &dht_settings::max_fail_count)
|
||||
;
|
||||
#endif
|
||||
|
||||
#ifndef TORRENT_DISABLE_ENCRYPTION
|
||||
enum_<pe_settings::enc_policy>("enc_policy")
|
||||
.value("forced", pe_settings::forced)
|
||||
.value("enabled", pe_settings::enabled)
|
||||
.value("disabled", pe_settings::disabled)
|
||||
;
|
||||
|
||||
enum_<pe_settings::enc_level>("enc_level")
|
||||
.value("rc4", pe_settings::rc4)
|
||||
.value("plaintext", pe_settings::plaintext)
|
||||
.value("both", pe_settings::both)
|
||||
;
|
||||
|
||||
class_<pe_settings>("pe_settings")
|
||||
.def_readwrite("out_enc_policy", &pe_settings::out_enc_policy)
|
||||
.def_readwrite("in_enc_policy", &pe_settings::in_enc_policy)
|
||||
.def_readwrite("allowed_enc_level", &pe_settings::allowed_enc_level)
|
||||
.def_readwrite("prefer_rc4", &pe_settings::prefer_rc4)
|
||||
;
|
||||
#endif
|
||||
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
// Copyright Daniel Wallin 2007. Use, modification and distribution is
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/python.hpp>
|
||||
#include <libtorrent/torrent.hpp>
|
||||
|
||||
using namespace boost::python;
|
||||
using namespace libtorrent;
|
||||
|
||||
void bind_torrent()
|
||||
{
|
||||
class_<torrent, boost::noncopyable>("torrent", no_init);
|
||||
}
|
||||
|
|
@ -1,381 +0,0 @@
|
|||
// Copyright Daniel Wallin 2006. Use, modification and distribution is
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/python.hpp>
|
||||
#include <boost/python/tuple.hpp>
|
||||
#include <libtorrent/torrent_handle.hpp>
|
||||
#include <libtorrent/peer_info.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include "gil.hpp"
|
||||
|
||||
using namespace boost::python;
|
||||
using namespace libtorrent;
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
list url_seeds(torrent_handle& handle)
|
||||
{
|
||||
list ret;
|
||||
std::set<std::string> urls;
|
||||
{
|
||||
allow_threading_guard guard;
|
||||
urls = handle.url_seeds();
|
||||
}
|
||||
|
||||
for (std::set<std::string>::iterator i(urls.begin())
|
||||
, end(urls.end()); i != end; ++i)
|
||||
ret.append(*i);
|
||||
return ret;
|
||||
}
|
||||
|
||||
list piece_availability(torrent_handle& handle)
|
||||
{
|
||||
list ret;
|
||||
std::vector<int> avail;
|
||||
{
|
||||
allow_threading_guard guard;
|
||||
handle.piece_availability(avail);
|
||||
}
|
||||
|
||||
for (std::vector<int>::iterator i(avail.begin())
|
||||
, end(avail.end()); i != end; ++i)
|
||||
ret.append(*i);
|
||||
return ret;
|
||||
}
|
||||
|
||||
list piece_priorities(torrent_handle& handle)
|
||||
{
|
||||
list ret;
|
||||
std::vector<int> prio;
|
||||
{
|
||||
allow_threading_guard guard;
|
||||
prio = handle.piece_priorities();
|
||||
}
|
||||
|
||||
for (std::vector<int>::iterator i(prio.begin())
|
||||
, end(prio.end()); i != end; ++i)
|
||||
ret.append(*i);
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // namespace unnamed
|
||||
|
||||
list file_progress(torrent_handle& handle)
|
||||
{
|
||||
std::vector<size_type> p;
|
||||
|
||||
{
|
||||
allow_threading_guard guard;
|
||||
p.reserve(handle.get_torrent_info().num_files());
|
||||
handle.file_progress(p);
|
||||
}
|
||||
|
||||
list result;
|
||||
|
||||
for (std::vector<size_type>::iterator i(p.begin()), e(p.end()); i != e; ++i)
|
||||
result.append(*i);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
list get_peer_info(torrent_handle const& handle)
|
||||
{
|
||||
std::vector<peer_info> pi;
|
||||
|
||||
{
|
||||
allow_threading_guard guard;
|
||||
handle.get_peer_info(pi);
|
||||
}
|
||||
|
||||
list result;
|
||||
|
||||
for (std::vector<peer_info>::iterator i = pi.begin(); i != pi.end(); ++i)
|
||||
result.append(*i);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void prioritize_pieces(torrent_handle& info, object o)
|
||||
{
|
||||
std::vector<int> result;
|
||||
try
|
||||
{
|
||||
object iter_obj = object( handle<>( PyObject_GetIter( o.ptr() ) ));
|
||||
while( 1 )
|
||||
{
|
||||
object obj = extract<object>( iter_obj.attr( "next" )() );
|
||||
result.push_back(extract<int const>( obj ));
|
||||
}
|
||||
}
|
||||
catch( error_already_set )
|
||||
{
|
||||
PyErr_Clear();
|
||||
info.prioritize_pieces(result);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void prioritize_files(torrent_handle& info, object o)
|
||||
{
|
||||
std::vector<int> result;
|
||||
try
|
||||
{
|
||||
object iter_obj = object( handle<>( PyObject_GetIter( o.ptr() ) ));
|
||||
while( 1 )
|
||||
{
|
||||
object obj = extract<object>( iter_obj.attr( "next" )() );
|
||||
result.push_back(extract<int const>( obj ));
|
||||
}
|
||||
}
|
||||
catch( error_already_set )
|
||||
{
|
||||
PyErr_Clear();
|
||||
info.prioritize_files(result);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
list file_priorities(torrent_handle& handle)
|
||||
{
|
||||
list ret;
|
||||
std::vector<int> priorities = handle.file_priorities();
|
||||
|
||||
for (std::vector<int>::iterator i = priorities.begin(); i != priorities.end(); ++i)
|
||||
ret.append(*i);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void replace_trackers(torrent_handle& h, object trackers)
|
||||
{
|
||||
object iter(trackers.attr("__iter__")());
|
||||
|
||||
std::vector<announce_entry> result;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
handle<> entry(allow_null(PyIter_Next(iter.ptr())));
|
||||
|
||||
if (entry == handle<>())
|
||||
break;
|
||||
|
||||
result.push_back(extract<announce_entry const&>(object(entry)));
|
||||
}
|
||||
|
||||
allow_threading_guard guard;
|
||||
h.replace_trackers(result);
|
||||
}
|
||||
|
||||
list trackers(torrent_handle &h)
|
||||
{
|
||||
list ret;
|
||||
std::vector<announce_entry> const trackers = h.trackers();
|
||||
for (std::vector<announce_entry>::const_iterator i = trackers.begin(), end(trackers.end()); i != end; ++i)
|
||||
{
|
||||
dict d;
|
||||
d["url"] = i->url;
|
||||
d["tier"] = i->tier;
|
||||
d["fail_limit"] = i->fail_limit;
|
||||
d["fails"] = i->fails;
|
||||
d["source"] = i->source;
|
||||
d["verified"] = i->verified;
|
||||
d["updating"] = i->updating;
|
||||
d["start_sent"] = i->start_sent;
|
||||
d["complete_sent"] = i->complete_sent;
|
||||
ret.append(d);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
list get_download_queue(torrent_handle& handle)
|
||||
{
|
||||
using boost::python::make_tuple;
|
||||
|
||||
list ret;
|
||||
|
||||
std::vector<partial_piece_info> downloading;
|
||||
|
||||
{
|
||||
allow_threading_guard guard;
|
||||
handle.get_download_queue(downloading);
|
||||
}
|
||||
|
||||
for (std::vector<partial_piece_info>::iterator i = downloading.begin()
|
||||
, end(downloading.end()); i != end; ++i)
|
||||
{
|
||||
dict partial_piece;
|
||||
partial_piece["piece_index"] = i->piece_index;
|
||||
partial_piece["blocks_in_piece"] = i->blocks_in_piece;
|
||||
list block_list;
|
||||
for (int k = 0; k < i->blocks_in_piece; ++k)
|
||||
{
|
||||
dict block_info;
|
||||
block_info["state"] = i->blocks[k].state;
|
||||
block_info["num_peers"] = i->blocks[k].num_peers;
|
||||
block_info["bytes_progress"] = i->blocks[k].bytes_progress;
|
||||
block_info["block_size"] = i->blocks[k].block_size;
|
||||
block_info["peer"] = make_tuple(
|
||||
boost::lexical_cast<std::string>(i->blocks[k].peer().address()), i->blocks[k].peer().port());
|
||||
block_list.append(block_info);
|
||||
}
|
||||
partial_piece["blocks"] = block_list;
|
||||
|
||||
ret.append(partial_piece);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
tcp::endpoint tuple_to_endpoint(tuple const& t)
|
||||
{
|
||||
return tcp::endpoint(address::from_string(extract<std::string>(t[0])), extract<int>(t[1]));
|
||||
}
|
||||
}
|
||||
|
||||
void force_reannounce(torrent_handle& th, int s)
|
||||
{
|
||||
th.force_reannounce(boost::posix_time::seconds(s));
|
||||
}
|
||||
|
||||
void connect_peer(torrent_handle& th, tuple ip, int source)
|
||||
{
|
||||
th.connect_peer(tuple_to_endpoint(ip), source);
|
||||
}
|
||||
|
||||
void set_peer_upload_limit(torrent_handle& th, tuple const& ip, int limit)
|
||||
{
|
||||
th.set_peer_upload_limit(tuple_to_endpoint(ip), limit);
|
||||
}
|
||||
|
||||
void set_peer_download_limit(torrent_handle& th, tuple const& ip, int limit)
|
||||
{
|
||||
th.set_peer_download_limit(tuple_to_endpoint(ip), limit);
|
||||
}
|
||||
|
||||
void add_piece(torrent_handle& th, int piece, char const *data, int flags)
|
||||
{
|
||||
th.add_piece(piece, data, flags);
|
||||
}
|
||||
|
||||
void bind_torrent_handle()
|
||||
{
|
||||
void (torrent_handle::*force_reannounce0)() const = &torrent_handle::force_reannounce;
|
||||
|
||||
int (torrent_handle::*piece_priority0)(int) const = &torrent_handle::piece_priority;
|
||||
void (torrent_handle::*piece_priority1)(int, int) const = &torrent_handle::piece_priority;
|
||||
|
||||
void (torrent_handle::*move_storage0)(std::string const&) const = &torrent_handle::move_storage;
|
||||
void (torrent_handle::*rename_file0)(int, std::string const&) const = &torrent_handle::rename_file;
|
||||
|
||||
#if TORRENT_USE_WSTRING
|
||||
void (torrent_handle::*move_storage1)(std::wstring const&) const = &torrent_handle::move_storage;
|
||||
void (torrent_handle::*rename_file1)(int, std::wstring const&) const = &torrent_handle::rename_file;
|
||||
#endif
|
||||
|
||||
#ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES
|
||||
bool (torrent_handle::*resolve_countries0)() const = &torrent_handle::resolve_countries;
|
||||
void (torrent_handle::*resolve_countries1)(bool) = &torrent_handle::resolve_countries;
|
||||
#endif
|
||||
|
||||
#define _ allow_threads
|
||||
|
||||
class_<torrent_handle>("torrent_handle")
|
||||
.def("get_peer_info", get_peer_info)
|
||||
.def("status", _(&torrent_handle::status))
|
||||
.def("get_download_queue", get_download_queue)
|
||||
.def("file_progress", file_progress)
|
||||
.def("trackers", trackers)
|
||||
.def("replace_trackers", replace_trackers)
|
||||
.def("add_url_seed", _(&torrent_handle::add_url_seed))
|
||||
.def("remove_url_seed", _(&torrent_handle::remove_url_seed))
|
||||
.def("url_seeds", url_seeds)
|
||||
.def("has_metadata", _(&torrent_handle::has_metadata))
|
||||
.def("get_torrent_info", _(&torrent_handle::get_torrent_info), return_internal_reference<>())
|
||||
.def("is_valid", _(&torrent_handle::is_valid))
|
||||
.def("is_seed", _(&torrent_handle::is_seed))
|
||||
.def("is_finished", _(&torrent_handle::is_finished))
|
||||
.def("is_paused", _(&torrent_handle::is_paused))
|
||||
.def("pause", _(&torrent_handle::pause), arg("flags") = 0)
|
||||
.def("resume", _(&torrent_handle::resume))
|
||||
.def("clear_error", _(&torrent_handle::clear_error))
|
||||
.def("set_priority", _(&torrent_handle::set_priority))
|
||||
|
||||
.def("is_auto_managed", _(&torrent_handle::is_auto_managed))
|
||||
.def("auto_managed", _(&torrent_handle::auto_managed))
|
||||
.def("queue_position", _(&torrent_handle::queue_position))
|
||||
.def("queue_position_up", _(&torrent_handle::queue_position_up))
|
||||
.def("queue_position_down", _(&torrent_handle::queue_position_down))
|
||||
.def("queue_position_top", _(&torrent_handle::queue_position_top))
|
||||
.def("queue_position_bottom", _(&torrent_handle::queue_position_bottom))
|
||||
|
||||
#ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES
|
||||
.def("resolve_countries", _(resolve_countries0))
|
||||
.def("resolve_countries", _(resolve_countries1))
|
||||
#endif
|
||||
// deprecated
|
||||
#ifndef TORRENT_NO_DEPRECATE
|
||||
.def("filter_piece", _(&torrent_handle::filter_piece))
|
||||
.def("is_piece_filtered", _(&torrent_handle::is_piece_filtered))
|
||||
.def("write_resume_data", _(&torrent_handle::write_resume_data))
|
||||
#endif
|
||||
.def("add_piece", add_piece)
|
||||
.def("read_piece", _(&torrent_handle::read_piece))
|
||||
.def("set_piece_deadline", _(&torrent_handle::set_piece_deadline)
|
||||
, (arg("index"), arg("deadline"), arg("flags") = 0))
|
||||
.def("piece_availability", &piece_availability)
|
||||
.def("piece_priority", _(piece_priority0))
|
||||
.def("piece_priority", _(piece_priority1))
|
||||
.def("prioritize_pieces", &prioritize_pieces)
|
||||
.def("piece_priorities", &piece_priorities)
|
||||
.def("prioritize_files", &prioritize_files)
|
||||
.def("file_priorities", &file_priorities)
|
||||
.def("use_interface", &torrent_handle::use_interface)
|
||||
.def("save_resume_data", _(&torrent_handle::save_resume_data), arg("flags") = 0)
|
||||
.def("need_save_resume_data", _(&torrent_handle::need_save_resume_data))
|
||||
.def("force_reannounce", _(force_reannounce0))
|
||||
.def("force_reannounce", &force_reannounce)
|
||||
.def("force_dht_announce", _(&torrent_handle::force_dht_announce))
|
||||
.def("scrape_tracker", _(&torrent_handle::scrape_tracker))
|
||||
.def("name", _(&torrent_handle::name))
|
||||
.def("set_upload_mode", _(&torrent_handle::set_upload_mode))
|
||||
.def("set_share_mode", _(&torrent_handle::set_share_mode))
|
||||
.def("set_upload_limit", _(&torrent_handle::set_upload_limit))
|
||||
.def("upload_limit", _(&torrent_handle::upload_limit))
|
||||
.def("set_download_limit", _(&torrent_handle::set_download_limit))
|
||||
.def("download_limit", _(&torrent_handle::download_limit))
|
||||
.def("set_sequential_download", _(&torrent_handle::set_sequential_download))
|
||||
.def("set_peer_upload_limit", &set_peer_upload_limit)
|
||||
.def("set_peer_download_limit", &set_peer_download_limit)
|
||||
.def("connect_peer", &connect_peer)
|
||||
.def("set_ratio", _(&torrent_handle::set_ratio))
|
||||
.def("save_path", _(&torrent_handle::save_path))
|
||||
.def("set_max_uploads", _(&torrent_handle::set_max_uploads))
|
||||
.def("set_max_connections", _(&torrent_handle::set_max_connections))
|
||||
.def("set_tracker_login", _(&torrent_handle::set_tracker_login))
|
||||
.def("move_storage", _(move_storage0))
|
||||
.def("info_hash", _(&torrent_handle::info_hash))
|
||||
.def("force_recheck", _(&torrent_handle::force_recheck))
|
||||
.def("rename_file", _(rename_file0))
|
||||
#if TORRENT_USE_WSTRING
|
||||
.def("move_storage", _(move_storage1))
|
||||
.def("rename_file", _(rename_file1))
|
||||
#endif
|
||||
;
|
||||
|
||||
enum_<torrent_handle::pause_flags_t>("pause_flags_t")
|
||||
.value("graceful_pause", torrent_handle::graceful_pause)
|
||||
;
|
||||
|
||||
enum_<torrent_handle::save_resume_flags_t>("save_resume_flags_t")
|
||||
.value("flush_disk_cache", torrent_handle::flush_disk_cache)
|
||||
;
|
||||
|
||||
enum_<torrent_handle::deadline_flags>("deadline_flags")
|
||||
.value("alert_when_available", torrent_handle::alert_when_available)
|
||||
;
|
||||
|
||||
}
|
|
@ -1,221 +0,0 @@
|
|||
// Copyright Daniel Wallin 2006. Use, modification and distribution is
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/python.hpp>
|
||||
#include <libtorrent/torrent_info.hpp>
|
||||
#include "libtorrent/intrusive_ptr_base.hpp"
|
||||
|
||||
using namespace boost::python;
|
||||
using namespace libtorrent;
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
std::vector<announce_entry>::const_iterator begin_trackers(torrent_info& i)
|
||||
{
|
||||
return i.trackers().begin();
|
||||
}
|
||||
|
||||
std::vector<announce_entry>::const_iterator end_trackers(torrent_info& i)
|
||||
{
|
||||
return i.trackers().end();
|
||||
}
|
||||
|
||||
void add_node(torrent_info& ti, char const* hostname, int port)
|
||||
{
|
||||
ti.add_node(std::make_pair(hostname, port));
|
||||
}
|
||||
|
||||
list nodes(torrent_info const& ti)
|
||||
{
|
||||
list result;
|
||||
|
||||
typedef std::vector<std::pair<std::string, int> > list_type;
|
||||
|
||||
for (list_type::const_iterator i = ti.nodes().begin(); i != ti.nodes().end(); ++i)
|
||||
{
|
||||
result.append(make_tuple(i->first, i->second));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
file_storage::iterator begin_files(torrent_info& i)
|
||||
{
|
||||
return i.begin_files();
|
||||
}
|
||||
|
||||
file_storage::iterator end_files(torrent_info& i)
|
||||
{
|
||||
return i.end_files();
|
||||
}
|
||||
|
||||
//list files(torrent_info const& ti, bool storage) {
|
||||
list files(torrent_info const& ti, bool storage) {
|
||||
list result;
|
||||
|
||||
typedef std::vector<file_entry> list_type;
|
||||
|
||||
for (list_type::const_iterator i = ti.begin_files(); i != ti.end_files(); ++i)
|
||||
result.append(*i);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string metadata(torrent_info const& ti) {
|
||||
std::string result(ti.metadata().get(), ti.metadata_size());
|
||||
return result;
|
||||
}
|
||||
|
||||
torrent_info construct0(std::string path) {
|
||||
return torrent_info(path);
|
||||
}
|
||||
|
||||
list map_block(torrent_info& ti, int piece, size_type offset, int size)
|
||||
{
|
||||
std::vector<file_slice> p = ti.map_block(piece, offset, size);
|
||||
list result;
|
||||
|
||||
for (std::vector<file_slice>::iterator i(p.begin()), e(p.end()); i != e; ++i)
|
||||
result.append(*i);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool get_tier(announce_entry const& ae)
|
||||
{ return ae.tier; }
|
||||
bool get_fail_limit(announce_entry const& ae)
|
||||
{ return ae.fail_limit; }
|
||||
bool get_fails(announce_entry const& ae)
|
||||
{ return ae.fails; }
|
||||
bool get_source(announce_entry const& ae)
|
||||
{ return ae.source; }
|
||||
bool get_verified(announce_entry const& ae)
|
||||
{ return ae.verified; }
|
||||
bool get_updating(announce_entry const& ae)
|
||||
{ return ae.updating; }
|
||||
bool get_start_sent(announce_entry const& ae)
|
||||
{ return ae.start_sent; }
|
||||
bool get_complete_sent(announce_entry const& ae)
|
||||
{ return ae.complete_sent; }
|
||||
bool get_send_stats(announce_entry const& ae)
|
||||
{ return ae.send_stats; }
|
||||
|
||||
|
||||
bool get_size(file_entry const& fe)
|
||||
{ return fe.size; }
|
||||
bool get_offset(file_entry const& fe)
|
||||
{ return fe.offset; }
|
||||
bool get_pad_file(file_entry const& fe)
|
||||
{ return fe.pad_file; }
|
||||
bool get_executable_attribute(file_entry const& fe)
|
||||
{ return fe.executable_attribute; }
|
||||
bool get_hidden_attribute(file_entry const& fe)
|
||||
{ return fe.hidden_attribute; }
|
||||
bool get_symlink_attribute(file_entry const& fe)
|
||||
{ return fe.symlink_attribute; }
|
||||
|
||||
} // namespace unnamed
|
||||
|
||||
void bind_torrent_info()
|
||||
{
|
||||
return_value_policy<copy_const_reference> copy;
|
||||
|
||||
void (torrent_info::*rename_file0)(int, std::string const&) = &torrent_info::rename_file;
|
||||
#if TORRENT_USE_WSTRING
|
||||
void (torrent_info::*rename_file1)(int, std::wstring const&) = &torrent_info::rename_file;
|
||||
#endif
|
||||
|
||||
class_<file_slice>("file_slice")
|
||||
.def_readwrite("file_index", &file_slice::file_index)
|
||||
.def_readwrite("offset", &file_slice::offset)
|
||||
.def_readwrite("size", &file_slice::size)
|
||||
;
|
||||
|
||||
class_<torrent_info, boost::intrusive_ptr<torrent_info> >("torrent_info", no_init)
|
||||
#ifndef TORRENT_NO_DEPRECATE
|
||||
.def(init<entry const&>())
|
||||
#endif
|
||||
.def(init<sha1_hash const&>())
|
||||
.def(init<char const*, int>())
|
||||
.def(init<std::string>())
|
||||
#if TORRENT_USE_WSTRING
|
||||
.def(init<std::wstring>())
|
||||
#endif
|
||||
|
||||
.def("add_tracker", &torrent_info::add_tracker, arg("url"))
|
||||
.def("add_url_seed", &torrent_info::add_url_seed)
|
||||
|
||||
.def("name", &torrent_info::name, copy)
|
||||
.def("comment", &torrent_info::comment, copy)
|
||||
.def("creator", &torrent_info::creator, copy)
|
||||
.def("total_size", &torrent_info::total_size)
|
||||
.def("piece_length", &torrent_info::piece_length)
|
||||
.def("num_pieces", &torrent_info::num_pieces)
|
||||
#ifndef TORRENT_NO_DEPRECATE
|
||||
.def("info_hash", &torrent_info::info_hash, copy)
|
||||
#endif
|
||||
.def("hash_for_piece", &torrent_info::hash_for_piece)
|
||||
.def("piece_size", &torrent_info::piece_size)
|
||||
|
||||
.def("num_files", &torrent_info::num_files, (arg("storage")=false))
|
||||
.def("file_at", &torrent_info::file_at, return_internal_reference<>())
|
||||
.def("file_at_offset", &torrent_info::file_at_offset)
|
||||
.def("files", &files, (arg("storage")=false))
|
||||
.def("rename_file", rename_file0)
|
||||
#if TORRENT_USE_WSTRING
|
||||
.def("rename_file", rename_file1)
|
||||
#endif
|
||||
|
||||
.def("priv", &torrent_info::priv)
|
||||
.def("trackers", range(begin_trackers, end_trackers))
|
||||
|
||||
.def("creation_date", &torrent_info::creation_date)
|
||||
|
||||
.def("add_node", &add_node)
|
||||
.def("nodes", &nodes)
|
||||
.def("metadata", &metadata)
|
||||
.def("metadata_size", &torrent_info::metadata_size)
|
||||
.def("map_block", map_block)
|
||||
.def("map_file", &torrent_info::map_file)
|
||||
;
|
||||
|
||||
class_<file_entry>("file_entry")
|
||||
.def("filename", &file_entry::filename)
|
||||
.def("set_name", &file_entry::set_name)
|
||||
.add_property("pad_file", &get_pad_file)
|
||||
.add_property("executable_attribute", &get_executable_attribute)
|
||||
.add_property("hidden_attribute", &get_hidden_attribute)
|
||||
.add_property("symlink_attribute", &get_symlink_attribute)
|
||||
.add_property("offset", &get_offset)
|
||||
.add_property("size", &get_size)
|
||||
;
|
||||
|
||||
class_<announce_entry>("announce_entry", init<std::string const&>())
|
||||
.def_readwrite("url", &announce_entry::url)
|
||||
.add_property("tier", &get_tier)
|
||||
.add_property("fail_limit", &get_fail_limit)
|
||||
.add_property("fails", &get_fails)
|
||||
.add_property("source", &get_source)
|
||||
.add_property("verified", &get_verified)
|
||||
.add_property("updating", &get_updating)
|
||||
.add_property("start_sent", &get_start_sent)
|
||||
.add_property("complete_sent", &get_complete_sent)
|
||||
.add_property("send_stats", &get_send_stats)
|
||||
|
||||
.def("reset", &announce_entry::reset)
|
||||
.def("failed", &announce_entry::failed, arg("retry_interval") = 0)
|
||||
.def("can_announce", &announce_entry::can_announce)
|
||||
.def("is_working", &announce_entry::is_working)
|
||||
.def("trim", &announce_entry::trim)
|
||||
;
|
||||
|
||||
enum_<announce_entry::tracker_source>("tracker_source")
|
||||
.value("source_torrent", announce_entry::source_torrent)
|
||||
.value("source_client", announce_entry::source_client)
|
||||
.value("source_magnet_link", announce_entry::source_magnet_link)
|
||||
.value("source_tex", announce_entry::source_tex)
|
||||
;
|
||||
}
|
||||
|
|
@ -1,112 +0,0 @@
|
|||
// Copyright Daniel Wallin 2006. Use, modification and distribution is
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/python.hpp>
|
||||
#include <libtorrent/torrent_handle.hpp>
|
||||
#include <libtorrent/bitfield.hpp>
|
||||
|
||||
using namespace boost::python;
|
||||
using namespace libtorrent;
|
||||
|
||||
object pieces(torrent_status const& s)
|
||||
{
|
||||
list result;
|
||||
|
||||
for (bitfield::const_iterator i(s.pieces.begin()), e(s.pieces.end()); i != e; ++i)
|
||||
result.append(*i);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void bind_torrent_status()
|
||||
{
|
||||
scope status = class_<torrent_status>("torrent_status")
|
||||
.def_readonly("state", &torrent_status::state)
|
||||
.def_readonly("paused", &torrent_status::paused)
|
||||
.def_readonly("auto_managed", &torrent_status::auto_managed)
|
||||
.def_readonly("sequential_download", &torrent_status::sequential_download)
|
||||
.def_readonly("is_seeding", &torrent_status::is_seeding)
|
||||
.def_readonly("is_finished", &torrent_status::is_finished)
|
||||
.def_readonly("has_metadata", &torrent_status::has_metadata)
|
||||
.def_readonly("progress", &torrent_status::progress)
|
||||
.def_readonly("progress_ppm", &torrent_status::progress_ppm)
|
||||
.add_property(
|
||||
"next_announce"
|
||||
, make_getter(
|
||||
&torrent_status::next_announce, return_value_policy<return_by_value>()
|
||||
)
|
||||
)
|
||||
.add_property(
|
||||
"announce_interval"
|
||||
, make_getter(
|
||||
&torrent_status::announce_interval, return_value_policy<return_by_value>()
|
||||
)
|
||||
)
|
||||
.def_readonly("current_tracker", &torrent_status::current_tracker)
|
||||
.def_readonly("total_download", &torrent_status::total_download)
|
||||
.def_readonly("total_upload", &torrent_status::total_upload)
|
||||
.def_readonly("total_payload_download", &torrent_status::total_payload_download)
|
||||
.def_readonly("total_payload_upload", &torrent_status::total_payload_upload)
|
||||
.def_readonly("total_failed_bytes", &torrent_status::total_failed_bytes)
|
||||
.def_readonly("total_redundant_bytes", &torrent_status::total_redundant_bytes)
|
||||
.def_readonly("download_rate", &torrent_status::download_rate)
|
||||
.def_readonly("upload_rate", &torrent_status::upload_rate)
|
||||
.def_readonly("download_payload_rate", &torrent_status::download_payload_rate)
|
||||
.def_readonly("upload_payload_rate", &torrent_status::upload_payload_rate)
|
||||
.def_readonly("num_seeds", &torrent_status::num_seeds)
|
||||
.def_readonly("num_peers", &torrent_status::num_peers)
|
||||
.def_readonly("num_complete", &torrent_status::num_complete)
|
||||
.def_readonly("num_incomplete", &torrent_status::num_incomplete)
|
||||
.def_readonly("list_seeds", &torrent_status::list_seeds)
|
||||
.def_readonly("list_peers", &torrent_status::list_peers)
|
||||
.add_property("pieces", pieces)
|
||||
.def_readonly("num_pieces", &torrent_status::num_pieces)
|
||||
.def_readonly("total_done", &torrent_status::total_done)
|
||||
.def_readonly("total_wanted_done", &torrent_status::total_wanted_done)
|
||||
.def_readonly("total_wanted", &torrent_status::total_wanted)
|
||||
.def_readonly("distributed_full_copies", &torrent_status::distributed_full_copies)
|
||||
.def_readonly("distributed_fraction", &torrent_status::distributed_fraction)
|
||||
.def_readonly("distributed_copies", &torrent_status::distributed_copies)
|
||||
.def_readonly("block_size", &torrent_status::block_size)
|
||||
.def_readonly("num_uploads", &torrent_status::num_uploads)
|
||||
.def_readonly("num_connections", &torrent_status::num_connections)
|
||||
.def_readonly("uploads_limit", &torrent_status::uploads_limit)
|
||||
.def_readonly("connections_limit", &torrent_status::connections_limit)
|
||||
.def_readonly("storage_mode", &torrent_status::storage_mode)
|
||||
.def_readonly("up_bandwidth_queue", &torrent_status::up_bandwidth_queue)
|
||||
.def_readonly("down_bandwidth_queue", &torrent_status::down_bandwidth_queue)
|
||||
.def_readonly("all_time_upload", &torrent_status::all_time_upload)
|
||||
.def_readonly("all_time_download", &torrent_status::all_time_download)
|
||||
.def_readonly("active_time", &torrent_status::active_time)
|
||||
.def_readonly("finished_time", &torrent_status::finished_time)
|
||||
.def_readonly("seeding_time", &torrent_status::seeding_time)
|
||||
.def_readonly("seed_rank", &torrent_status::seed_rank)
|
||||
.def_readonly("last_scrape", &torrent_status::last_scrape)
|
||||
.def_readonly("has_incoming", &torrent_status::has_incoming)
|
||||
.def_readonly("sparse_regions", &torrent_status::sparse_regions)
|
||||
.def_readonly("seed_mode", &torrent_status::seed_mode)
|
||||
.def_readonly("upload_mode", &torrent_status::upload_mode)
|
||||
.def_readonly("share_mode", &torrent_status::share_mode)
|
||||
.def_readonly("error", &torrent_status::error)
|
||||
.def_readonly("priority", &torrent_status::priority)
|
||||
.def_readonly("added_time", &torrent_status::added_time)
|
||||
.def_readonly("completed_time", &torrent_status::completed_time)
|
||||
.def_readonly("last_seen_complete", &torrent_status::last_seen_complete)
|
||||
.def_readonly("time_since_upload", &torrent_status::time_since_upload)
|
||||
.def_readonly("time_since_download", &torrent_status::time_since_download)
|
||||
.def_readonly("queue_position", &torrent_status::queue_position)
|
||||
.def_readonly("need_save_resume", &torrent_status::need_save_resume)
|
||||
;
|
||||
|
||||
enum_<torrent_status::state_t>("states")
|
||||
.value("queued_for_checking", torrent_status::queued_for_checking)
|
||||
.value("checking_files", torrent_status::checking_files)
|
||||
.value("downloading", torrent_status::downloading)
|
||||
.value("finished", torrent_status::finished)
|
||||
.value("seeding", torrent_status::seeding)
|
||||
.value("allocating", torrent_status::allocating)
|
||||
.export_values()
|
||||
;
|
||||
}
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
// Copyright Daniel Wallin 2006. Use, modification and distribution is
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <libtorrent/identify_client.hpp>
|
||||
#include <libtorrent/bencode.hpp>
|
||||
#include <boost/python.hpp>
|
||||
|
||||
using namespace boost::python;
|
||||
using namespace libtorrent;
|
||||
|
||||
object client_fingerprint_(peer_id const& id)
|
||||
{
|
||||
boost::optional<fingerprint> result = client_fingerprint(id);
|
||||
return result ? object(*result) : object();
|
||||
}
|
||||
|
||||
entry bdecode_(std::string const& data)
|
||||
{
|
||||
return bdecode(data.begin(), data.end());
|
||||
}
|
||||
|
||||
std::string bencode_(entry const& e)
|
||||
{
|
||||
std::string result;
|
||||
bencode(std::back_inserter(result), e);
|
||||
return result;
|
||||
}
|
||||
|
||||
void bind_utility()
|
||||
{
|
||||
def("identify_client", &libtorrent::identify_client);
|
||||
def("client_fingerprint", &client_fingerprint_);
|
||||
def("bdecode", &bdecode_);
|
||||
def("bencode", &bencode_);
|
||||
}
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
// Copyright Daniel Wallin 2006. Use, modification and distribution is
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <libtorrent/version.hpp>
|
||||
#include <boost/python.hpp>
|
||||
|
||||
using namespace boost::python;
|
||||
|
||||
void bind_version()
|
||||
{
|
||||
scope().attr("version") = LIBTORRENT_VERSION;
|
||||
scope().attr("version_major") = LIBTORRENT_VERSION_MAJOR;
|
||||
scope().attr("version_minor") = LIBTORRENT_VERSION_MINOR;
|
||||
}
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
|
||||
#clear out any extended attributes that Finder may add
|
||||
sudo xattr -r -d com.apple.FinderInfo *
|
||||
|
||||
rm -f config.log config.report configure
|
||||
rm -f m4/libtool.m4 m4/lt~obsolete.m4 m4/ltsugar.m4 m4/ltversion.m4 m4/ltoptions.m4
|
||||
rm -fr autom4te.cache build-aux
|
||||
rm -f Makefile Makefile.in
|
||||
rm -f src/Makefile src/Makefile.in
|
||||
rm -f include/libtorrent/Makefile include/libtorrent/Makefile.in
|
||||
rm -f examples/Makefile examples/Makefile.in
|
||||
rm -f test/Makefile test/Makefile.in
|
||||
rm -f bindings/Makefile bindings/Makefile.in
|
||||
rm -f bindings/python/Makefile bindings/python/Makefile.in
|
||||
chmod a-x docs/*.rst docs/*.htm* src/*.cpp include/libtorrent/*.hpp
|
||||
|
||||
./autotool.sh
|
||||
./configure --enable-python-binding --enable-examples=yes --enable-tests=yes --with-boost-system=mt --with-boost-python=mt
|
||||
make V=1 -j8 dist check
|
|
@ -1,759 +0,0 @@
|
|||
# -*- Autoconf -*-
|
||||
# Process this file with autoconf to produce a configure script.
|
||||
|
||||
# $Id$
|
||||
|
||||
AC_PREREQ([2.63])
|
||||
|
||||
AC_INIT([libtorrent-rasterbar],[0.16.0],[arvid@cs.umu.se],
|
||||
[libtorrent-rasterbar],[http://www.libtorrent.org])
|
||||
AC_CONFIG_SRCDIR([src/torrent.cpp])
|
||||
AC_CONFIG_AUX_DIR([build-aux])
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
|
||||
# Silencing build output (automake-1.11)
|
||||
m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])])
|
||||
|
||||
|
||||
###############################################################################
|
||||
dnl ---------------------------------------------------------------------------
|
||||
dnl interface version info
|
||||
dnl ---------------------------------------------------------------------------
|
||||
dnl Advanced information about versioning:
|
||||
dnl * "Writing shared libraries" by Mike Hearn
|
||||
dnl http://navi.cx/~mike/writing-shared-libraries.html
|
||||
dnl * libtool.info chapter "Versioning"
|
||||
dnl * libtool.info chapter "Updating library version information"
|
||||
dnl ---------------------------------------------------------------------------
|
||||
dnl Versioning:
|
||||
dnl - CURRENT (Major): Increment if the interface has changes. AGE is always
|
||||
dnl *changed* at the same time.
|
||||
dnl - AGE (Micro): Increment if any interfaces have been added; set to 0
|
||||
dnl if any interfaces have been removed. Removal has
|
||||
dnl precedence over adding, so set to 0 if both happened.
|
||||
dnl It denotes upward compatibility.
|
||||
dnl - REVISION (Minor): Increment any time the source changes; set to
|
||||
dnl 0 if you incremented CURRENT.
|
||||
dnl
|
||||
dnl To summarize. Any interface *change* increment CURRENT. If that interface
|
||||
dnl change does not break upward compatibility (ie it is an addition),
|
||||
dnl increment AGE, Otherwise AGE is reset to 0. If CURRENT has changed,
|
||||
dnl REVISION is set to 0, otherwise REVISION is incremented.
|
||||
dnl ---------------------------------------------------------------------------
|
||||
|
||||
m4_define([VERSION_INFO_CURRENT],[6])
|
||||
m4_define([VERSION_INFO_REVISION],[0])
|
||||
m4_define([VERSION_INFO_AGE],[0])
|
||||
INTERFACE_VERSION_INFO=VERSION_INFO_CURRENT:VERSION_INFO_REVISION:VERSION_INFO_AGE
|
||||
AC_SUBST(INTERFACE_VERSION_INFO)
|
||||
###############################################################################
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Start
|
||||
###############################################################################
|
||||
|
||||
AS_ECHO
|
||||
AS_ECHO "Building $PACKAGE_STRING"
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Performing some basic checks and initializing the build system
|
||||
###############################################################################
|
||||
|
||||
AS_ECHO
|
||||
AS_ECHO "Checking for a C/C++ compiler to use:"
|
||||
AC_PROG_CC
|
||||
AC_PROG_CPP
|
||||
AC_PROG_CC_C_O
|
||||
AC_PROG_CXX
|
||||
AC_PROG_CXXCPP
|
||||
AC_PROG_CXX_C_O
|
||||
|
||||
AS_ECHO
|
||||
AS_ECHO "Checking system type:"
|
||||
AC_CANONICAL_BUILD
|
||||
AC_CANONICAL_HOST
|
||||
AC_CANONICAL_TARGET
|
||||
|
||||
AS_ECHO
|
||||
AS_ECHO "Initializing Automake:"
|
||||
AM_INIT_AUTOMAKE([1.11 foreign])
|
||||
|
||||
|
||||
AS_ECHO
|
||||
AS_ECHO "Initializing Libtool:"
|
||||
LT_PREREQ([2.2.6])
|
||||
LT_INIT
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Checking for needed base libraries
|
||||
###############################################################################
|
||||
|
||||
AS_ECHO
|
||||
AS_ECHO "Checking for posix thread support:"
|
||||
|
||||
AX_PTHREAD()
|
||||
|
||||
LIBS="$PTHREAD_LIBS $LIBS"
|
||||
CFLAGS="$PTHREAD_CFLAGS $CFLAGS"
|
||||
CC="$PTHREAD_CC"
|
||||
|
||||
AS_ECHO
|
||||
AS_ECHO "Checking for boost libraries:"
|
||||
|
||||
AX_BOOST_BASE([1.36])
|
||||
|
||||
AX_BOOST_SYSTEM()
|
||||
AS_IF([test -z "$BOOST_SYSTEM_LIB"],
|
||||
[AC_MSG_ERROR(Boost.System library not found. Try using --with-boost-system=lib)])
|
||||
|
||||
CPPFLAGS="$BOOST_CPPFLAGS $CPPFLAGS"
|
||||
LDFLAGS="$BOOST_LDFLAGS $LDFLAGS"
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Checking for functions and other stuffs
|
||||
###############################################################################
|
||||
|
||||
|
||||
AS_ECHO
|
||||
AS_ECHO "Checking for pkg-config:"
|
||||
|
||||
PKG_PROG_PKG_CONFIG([0.20])
|
||||
|
||||
AS_ECHO
|
||||
AS_ECHO "Checking for functions and headers:"
|
||||
|
||||
AC_SYS_LARGEFILE
|
||||
AC_PROG_INSTALL
|
||||
AC_PROG_LN_S
|
||||
AC_PROG_MAKE_SET
|
||||
|
||||
# check for gethostbyname and gethostbyname_r (used in src/GeoIP.c)
|
||||
AC_CHECK_FUNCS([gethostbyname], [],
|
||||
[AC_CHECK_LIB([nsl], [gethostbyname], [],
|
||||
[AC_CHECK_LIB([resolv], [gethostbyname], [],
|
||||
[AC_CHECK_LIB([socket], [gethostbyname], [],
|
||||
[AC_CHECK_LIB([ws2_32], [main],
|
||||
[AC_CHECK_LIB([wsock32], [main],
|
||||
[LIBS="-lws2_32 -lwsock32 $LIBS"],
|
||||
[AC_MSG_ERROR([wsock32 function not found.])])],
|
||||
[AC_MSG_ERROR([gethostbyname function not found.])])])])])]
|
||||
)
|
||||
|
||||
AC_CHECK_FUNCS(gethostbyname_r, [
|
||||
# We look for the one that returns `int'.
|
||||
# Hopefully this check is robust enough.
|
||||
AC_EGREP_HEADER(int.*gethostbyname_r, netdb.h, [
|
||||
AC_DEFINE(GETHOSTBYNAME_R_RETURNS_INT)])
|
||||
])
|
||||
|
||||
AC_CHECK_FUNCS([clock_gettime], [],
|
||||
[AC_CHECK_LIB([rt], [clock_gettime], [],
|
||||
[AC_CHECK_LIB([posix4], [clock_gettime], [],
|
||||
[AC_MSG_WARN([clock_gettime function not found.])])])]
|
||||
)
|
||||
|
||||
|
||||
dnl Pass some build options to setup.py and .pc file
|
||||
COMPILETIME_OPTIONS=""
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Setting configure options
|
||||
###############################################################################
|
||||
|
||||
AC_ARG_ENABLE(
|
||||
[logging],
|
||||
[AS_HELP_STRING(
|
||||
[--enable-logging],
|
||||
[enable logging to disk (use value "verbose" to enable verbose peer wire logging or "errors" limit logging to errors ) [default=no]])],
|
||||
[[ARG_ENABLE_LOGGING=$enableval]],
|
||||
[[ARG_ENABLE_LOGGING=no]]
|
||||
)
|
||||
|
||||
AC_ARG_ENABLE(
|
||||
[debug],
|
||||
[AS_HELP_STRING(
|
||||
[--enable-debug],
|
||||
[enable debug build [default=no]])],
|
||||
[
|
||||
ARG_ENABLE_DEBUG=$enableval
|
||||
ac_arg_enable_debug=$enableval
|
||||
],
|
||||
[
|
||||
ARG_ENABLE_DEBUG=no
|
||||
ac_arg_enable_debug=no
|
||||
]
|
||||
)
|
||||
|
||||
AC_ARG_ENABLE(
|
||||
[dht],
|
||||
[AS_HELP_STRING(
|
||||
[--disable-dht],
|
||||
[disable dht support (use value "logging" to add extra logging) [default=yes]])],
|
||||
[[ARG_ENABLE_DHT=$enableval]],
|
||||
[[ARG_ENABLE_DHT=yes]]
|
||||
)
|
||||
|
||||
AC_ARG_ENABLE(
|
||||
[encryption],
|
||||
[AS_HELP_STRING(
|
||||
[--disable-encryption],
|
||||
[disable encryption support (requires OpenSSL to be installed on your system, you can use --with-openssl to set the path) [default=yes]])],
|
||||
[[ARG_ENABLE_ENCRYPTION=$enableval]],
|
||||
[[ARG_ENABLE_ENCRYPTION=yes]]
|
||||
)
|
||||
|
||||
AC_ARG_ENABLE(
|
||||
[pool-allocators],
|
||||
[AS_HELP_STRING(
|
||||
[--disable-pool-allocators],
|
||||
[disable pool allocators for send buffers [default=yes]])],
|
||||
[[ARG_ENABLE_POOL_ALLOC=$enableval]],
|
||||
[[ARG_ENABLE_POOL_ALLOC=yes]]
|
||||
)
|
||||
|
||||
AC_ARG_ENABLE(
|
||||
[invariant-checks],
|
||||
[AS_HELP_STRING(
|
||||
[--enable-invariant-checks],
|
||||
[enable invariant checks (use value "full" to turn on extra expensive invariant checks) @<:@default=yes if debug is enabled, no otherwhise@:>@])],
|
||||
[[ARG_ENABLE_INVARIANT=$enableval]],
|
||||
[
|
||||
AS_IF([test "x$ac_arg_enable_debug" = "xyes"],
|
||||
[ARG_ENABLE_INVARIANT=yes],
|
||||
[ARG_ENABLE_INVARIANT=no])
|
||||
]
|
||||
)
|
||||
|
||||
AC_ARG_ENABLE(
|
||||
[deprecated-functions],
|
||||
[AS_HELP_STRING(
|
||||
[--disable-deprecated-functions],
|
||||
[disable deprecated functions from the API [default=yes]])],
|
||||
[[ARG_ENABLE_DEPRECATED=$enableval]],
|
||||
[[ARG_ENABLE_DEPRECATED=yes]]
|
||||
)
|
||||
|
||||
AC_ARG_ENABLE(
|
||||
[statistics],
|
||||
[AS_HELP_STRING(
|
||||
[--enable-statistics],
|
||||
[enable statistics logging feature [default=no]])],
|
||||
[[ARG_ENABLE_STATS=$enableval]],
|
||||
[[ARG_ENABLE_STATS=no]]
|
||||
)
|
||||
|
||||
AC_ARG_ENABLE(
|
||||
[disk-stats],
|
||||
[AS_HELP_STRING(
|
||||
[--enable-disk-stats],
|
||||
[enable disk activity logging feature [default=no]])],
|
||||
[[ARG_ENABLE_DISK_STATS=$enableval]],
|
||||
[[ARG_ENABLE_DISK_STATS=no]]
|
||||
)
|
||||
|
||||
AC_ARG_ENABLE(
|
||||
[geoip],
|
||||
[AS_HELP_STRING(
|
||||
[--disable-geoip],
|
||||
[disable geoip support (if enabled, you can use --with-libgeoip to choose whether to link against shipped or system library) [default=yes]])],
|
||||
[
|
||||
ARG_ENABLE_GEOIP=$enableval
|
||||
ac_arg_enable_geoip=$enableval
|
||||
],
|
||||
[
|
||||
ARG_ENABLE_GEOIP=yes
|
||||
ac_arg_enable_geoip=yes
|
||||
]
|
||||
)
|
||||
|
||||
AC_ARG_ENABLE(
|
||||
[examples],
|
||||
[AS_HELP_STRING(
|
||||
[--enable-examples],
|
||||
[build example files [default=no]])],
|
||||
[[ARG_ENABLE_EXAMPLES=$enableval]],
|
||||
[[ARG_ENABLE_EXAMPLES=no]]
|
||||
)
|
||||
|
||||
AC_ARG_ENABLE(
|
||||
[tests],
|
||||
[AS_HELP_STRING(
|
||||
[--enable-tests],
|
||||
[build test files [default=no]])],
|
||||
[[ARG_ENABLE_TESTS=$enableval]],
|
||||
[[ARG_ENABLE_TESTS=no]]
|
||||
)
|
||||
|
||||
AC_ARG_ENABLE(
|
||||
[python-binding],
|
||||
[AS_HELP_STRING(
|
||||
[--enable-python-binding],
|
||||
[build python bindings [default=no]])],
|
||||
[[ARG_ENABLE_PYTHON_BINDING=$enableval]],
|
||||
[[ARG_ENABLE_PYTHON_BINDING=no]]
|
||||
)
|
||||
|
||||
AC_ARG_WITH(
|
||||
[libgeoip],
|
||||
[AS_HELP_STRING(
|
||||
[--with-libgeoip],
|
||||
[enable linking against system libgeoip [default=shipped]])],
|
||||
[[ARG_WITH_LIBGEOIP=$withval]],
|
||||
[[ARG_WITH_LIBGEOIP=no]]
|
||||
)
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Checking configure options
|
||||
###############################################################################
|
||||
|
||||
AS_ECHO
|
||||
AS_ECHO "Checking build options:"
|
||||
|
||||
AC_MSG_CHECKING([whether deprecated functions should be enabled])
|
||||
AS_CASE(["$ARG_ENABLE_DEPRECATED"],
|
||||
["yes"|"on"], [
|
||||
AC_MSG_RESULT([yes])
|
||||
],
|
||||
["no"|"off"], [
|
||||
AC_MSG_RESULT([no])
|
||||
AC_DEFINE([TORRENT_NO_DEPRECATE],[1],[Define to exclude all deprecated functions from the API.])
|
||||
],
|
||||
[AC_MSG_RESULT([$ARG_ENABLE_DEPRECATED])
|
||||
AC_MSG_ERROR([Unknown option "$ARG_ENABLE_DEPRECATED". Use either "yes" or "no".])]
|
||||
)
|
||||
|
||||
AC_MSG_CHECKING([whether debug build should be enabled])
|
||||
AS_CASE(["$ARG_ENABLE_DEBUG"],
|
||||
["yes"], [
|
||||
AC_MSG_RESULT([yes])
|
||||
AC_DEFINE([TORRENT_DEBUG],[1],[Define to enable debug code.])
|
||||
COMPILETIME_OPTIONS+="-DTORRENT_DEBUG "
|
||||
DEBUGFLAGS="-g"
|
||||
],
|
||||
["no"], [
|
||||
AC_MSG_RESULT([no])
|
||||
AC_DEFINE([NDEBUG],[1],[Define to disable debug code.])
|
||||
#COMPILETIME_OPTIONS+="-DNDEBUG "
|
||||
DEBUGFLAGS="-Os"
|
||||
],
|
||||
[AC_MSG_RESULT([$ARG_ENABLE_DEBUG])
|
||||
AC_MSG_ERROR([Unknown option "$ARG_ENABLE_DEBUG". Use either "yes" or "no".])]
|
||||
)
|
||||
|
||||
AC_MSG_CHECKING([whether invariant check should be enabled]) #depends: $ac_arg_enable_debug
|
||||
AS_CASE(["$ARG_ENABLE_INVARIANT"],
|
||||
["yes"|"on"], [
|
||||
AC_MSG_RESULT([yes])
|
||||
AS_IF([test "x$ac_arg_enable_debug" = "xno"],
|
||||
[AC_MSG_ERROR([invariant-checks: this setting only affects debug build. Try using --enable-debug.])])
|
||||
],
|
||||
["no"|"off"], [
|
||||
AC_MSG_RESULT([no])
|
||||
AS_IF([test "x$ac_arg_enable_debug" = "xyes"],
|
||||
[AC_DEFINE([TORRENT_DISABLE_INVARIANT_CHECKS],[1],[Define to disable internal invariant checks. Asserts are still enabled while debug is on.])])
|
||||
],
|
||||
["full"], [
|
||||
AC_MSG_RESULT([full])
|
||||
AS_IF([test "x$ac_arg_enable_debug" = "xyes"],
|
||||
[AC_DEFINE([TORRENT_EXPENSIVE_INVARIANT_CHECKS],[1],[Define to enable extra expensive invariant checks.])],
|
||||
[AC_MSG_ERROR([invariant-checks: this setting only affects debug build. Try using --enable-debug.])])
|
||||
],
|
||||
[AC_MSG_RESULT([$ARG_ENABLE_INVARIANT])
|
||||
AC_MSG_ERROR([Unknown option "$ARG_ENABLE_INVARIANT". Use either "yes", "no" or "full".])]
|
||||
)
|
||||
|
||||
AC_MSG_CHECKING([whether logging to disk should be enabled])
|
||||
AS_CASE(["$ARG_ENABLE_LOGGING"],
|
||||
["yes"|"default"], [
|
||||
AC_MSG_RESULT([yes])
|
||||
AC_DEFINE([TORRENT_LOGGING],[1],[Define to enable logging of the session events.])
|
||||
COMPILETIME_OPTIONS+="-DTORRENT_LOGGING "
|
||||
],
|
||||
["no"|"none"], [
|
||||
AC_MSG_RESULT([no])
|
||||
],
|
||||
["verbose"], [
|
||||
AC_MSG_RESULT([verbose])
|
||||
AC_DEFINE([TORRENT_VERBOSE_LOGGING],[1],[Define to enable logging of the session events and every peer connection.])
|
||||
COMPILETIME_OPTIONS+="-DTORRENT_VERBOSE_LOGGING "
|
||||
],
|
||||
["errors"], [
|
||||
AC_MSG_RESULT([errors])
|
||||
AC_DEFINE([TORRENT_ERROR_LOGGING],[1],[Define to enable logging of the session events and every peer connection limited to errors.])
|
||||
COMPILETIME_OPTIONS+="-DTORRENT_ERROR_LOGGING "
|
||||
],
|
||||
[AC_MSG_RESULT([$ARG_ENABLE_LOGGING])
|
||||
AC_MSG_ERROR([Unknown option "$ARG_ENABLE_LOGGING". Use either "yes", "no", "verbose" or "errors".])]
|
||||
)
|
||||
|
||||
AC_MSG_CHECKING([whether statistics logging should be enabled])
|
||||
AS_CASE(["$ARG_ENABLE_STATS"],
|
||||
["yes"|"on"], [
|
||||
AC_MSG_RESULT([yes])
|
||||
AC_DEFINE([TORRENT_STATS],[1],[Define to generate a log with statistics.])
|
||||
],
|
||||
["no"|"off"], [
|
||||
AC_MSG_RESULT([no])
|
||||
],
|
||||
[AC_MSG_RESULT([$ARG_ENABLE_STATS])
|
||||
AC_MSG_ERROR([Unknown option "$ARG_ENABLE_STATS". Use either "yes" or "no".])]
|
||||
)
|
||||
|
||||
AC_MSG_CHECKING([whether disk activity logging should be enabled])
|
||||
AS_CASE(["$ARG_ENABLE_DISK_STATS"],
|
||||
["yes"|"on"], [
|
||||
AC_MSG_RESULT([yes])
|
||||
AC_DEFINE([TORRENT_DISK_STATS],[1],[Define to create a log of all disk activities.])
|
||||
],
|
||||
["no"|"off"], [
|
||||
AC_MSG_RESULT([no])
|
||||
],
|
||||
[AC_MSG_RESULT([$ARG_ENABLE_DISK_STATS])
|
||||
AC_MSG_ERROR([Unknown option "$ARG_ENABLE_DISK_STATS". Use either "yes" or "no".])]
|
||||
)
|
||||
|
||||
AS_ECHO
|
||||
AS_ECHO "Checking features to be enabled:"
|
||||
|
||||
AC_MSG_CHECKING([whether encryption support should be enabled])
|
||||
AS_CASE(["$ARG_ENABLE_ENCRYPTION"],
|
||||
["yes"|"on"], [
|
||||
AC_MSG_RESULT([yes])
|
||||
AC_MSG_NOTICE([encryption support: now checking for the OpenSSL library...])
|
||||
|
||||
AX_CHECK_OPENSSL([
|
||||
AC_DEFINE([TORRENT_USE_OPENSSL],[1],[Define to use OpenSSL support.])
|
||||
COMPILETIME_OPTIONS+="-DTORRENT_USE_OPENSSL "
|
||||
], [
|
||||
AC_MSG_ERROR([OpenSSL library not found. Try using --with-openssl=DIR or disabling encryption at all.])
|
||||
])
|
||||
],
|
||||
["no"|"off"], [
|
||||
AC_MSG_RESULT([no])
|
||||
AC_DEFINE([TORRENT_DISABLE_ENCRYPTION],[1],[Define to disable any encryption support and avoid linking against OpenSSL.])
|
||||
COMPILETIME_OPTIONS+="-DTORRENT_DISABLE_ENCRYPTION "
|
||||
],
|
||||
[AC_MSG_RESULT([$ARG_ENABLE_ENCRYPTION])
|
||||
AC_MSG_ERROR([Unknown option "$ARG_ENABLE_ENCRYPTION". Use either "yes" or "no".])]
|
||||
)
|
||||
|
||||
AC_MSG_CHECKING([whether geoip support should be enabled])
|
||||
AS_CASE(["$ARG_ENABLE_GEOIP"],
|
||||
["yes"], [
|
||||
AC_MSG_RESULT([yes])
|
||||
],
|
||||
["no"], [
|
||||
AC_MSG_RESULT([no])
|
||||
AC_DEFINE([TORRENT_DISABLE_GEO_IP],[1],[Define to disable the GeoIP support and avoid linking against LGPLed code.])
|
||||
COMPILETIME_OPTIONS+="-DTORRENT_DISABLE_GEO_IP "
|
||||
],
|
||||
[AC_MSG_RESULT([$ARG_ENABLE_GEOIP])
|
||||
AC_MSG_ERROR([Unknown option "$ARG_ENABLE_GEOIP". Use either "yes" or "no".])]
|
||||
)
|
||||
|
||||
AC_MSG_CHECKING([whether dht support should be enabled])
|
||||
AS_CASE(["$ARG_ENABLE_DHT"],
|
||||
["yes"|"on"], [
|
||||
AC_MSG_RESULT([yes])
|
||||
],
|
||||
["no"|"off"], [
|
||||
AC_MSG_RESULT([no])
|
||||
AC_DEFINE([TORRENT_DISABLE_DHT],[1],[Define to disable the DHT support.])
|
||||
COMPILETIME_OPTIONS+="-DTORRENT_DISABLE_DHT "
|
||||
],
|
||||
["logging"], [
|
||||
AC_MSG_RESULT([logging])
|
||||
AC_DEFINE([TORRENT_DHT_VERBOSE_LOGGING],[1],[Define to enable DHT support with verbose logging.])
|
||||
COMPILETIME_OPTIONS+="-DTORRENT_DHT_VERBOSE_LOGGING "
|
||||
],
|
||||
[AC_MSG_RESULT([$ARG_ENABLE_DHT])
|
||||
AC_MSG_ERROR([Unknown option "$ARG_ENABLE_DHT". Use either "yes", "no" or "logging".])]
|
||||
)
|
||||
|
||||
AC_MSG_CHECKING([whether pool allocators should be enabled])
|
||||
AS_CASE(["$ARG_ENABLE_POOL_ALLOC"],
|
||||
["yes"|"on"], [
|
||||
AC_MSG_RESULT([yes])
|
||||
],
|
||||
["no"|"off"], [
|
||||
AC_MSG_RESULT([no])
|
||||
AC_DEFINE([TORRENT_DISABLE_POOL_ALLOCATOR],[1],[Define to disable use of boost::pool for pool allocators.])
|
||||
],
|
||||
[AC_MSG_RESULT([$ARG_ENABLE_POOL_ALLOC])
|
||||
AC_MSG_ERROR([Unknown option "$ARG_ENABLE_POOL_ALLOC". Use either "yes" or "no".])]
|
||||
)
|
||||
|
||||
AS_ECHO
|
||||
AS_ECHO "Checking for extra build files:"
|
||||
|
||||
AC_MSG_CHECKING([whether example files should be built])
|
||||
AS_CASE(["$ARG_ENABLE_EXAMPLES"],
|
||||
["yes"], [AC_MSG_RESULT([yes])],
|
||||
["no"], [AC_MSG_RESULT([no])],
|
||||
[AC_MSG_RESULT([$ARG_ENABLE_EXAMPLES])
|
||||
AC_MSG_ERROR([Unknown option "$ARG_ENABLE_EXAMPLES". Use either "yes" or "no".])]
|
||||
)
|
||||
|
||||
AC_MSG_CHECKING([whether test files should be built])
|
||||
AS_CASE(["$ARG_ENABLE_TESTS"],
|
||||
["yes"], [AC_MSG_RESULT([yes])],
|
||||
["no"], [AC_MSG_RESULT([no])],
|
||||
[AC_MSG_RESULT([$ARG_ENABLE_TESTS])
|
||||
AC_MSG_ERROR([Unknown option "$ARG_ENABLE_TESTS". Use either "yes" or "no".])]
|
||||
)
|
||||
|
||||
AC_MSG_CHECKING([whether python bindings should be built])
|
||||
AS_CASE(["$ARG_ENABLE_PYTHON_BINDING"],
|
||||
["yes"], [
|
||||
AC_MSG_RESULT([yes])
|
||||
|
||||
AM_PATH_PYTHON([2.4], [], AC_MSG_ERROR([Python interpreter not found.]))
|
||||
AX_PYTHON_DEVEL([>= '2.4'])
|
||||
AX_BOOST_PYTHON()
|
||||
|
||||
AS_IF([test -z "$BOOST_PYTHON_LIB"],
|
||||
[AC_MSG_ERROR([Boost.Python library not found. Try using --with-boost-python=lib.])])
|
||||
],
|
||||
["no"], [
|
||||
AC_MSG_RESULT([no])
|
||||
],
|
||||
[AC_MSG_RESULT([$ARG_ENABLE_PYTHON_BINDING])
|
||||
AC_MSG_ERROR([Unknown option "$ARG_ENABLE_PYTHON_BINDING". Use either "yes" or "no".])]
|
||||
)
|
||||
|
||||
AS_ECHO
|
||||
AS_ECHO "Checking for external libraries:"
|
||||
|
||||
AC_MSG_CHECKING([for FIEMAP support])
|
||||
AC_CHECK_HEADERS([linux/fiemap.h])
|
||||
|
||||
AC_MSG_CHECKING([whether to link against system libgeoip]) #depends: $ac_arg_enable_geoip
|
||||
AS_CASE(["$ARG_WITH_LIBGEOIP"],
|
||||
["yes"|"system"], [
|
||||
AC_MSG_RESULT([yes])
|
||||
|
||||
AS_IF([test "x$ac_arg_enable_geoip" = "xno"],
|
||||
[AC_MSG_ERROR([GeoIP support is disabled with this build configuration. Try using --enable-geoip.])])
|
||||
|
||||
AC_MSG_NOTICE([libgeoip: now checking for the libgeoip library...])
|
||||
|
||||
AC_CHECK_GEOIP([
|
||||
LIBS="$GEOIP_LIBS $LIBS"
|
||||
CFLAGS="$GEOIP_CFLAGS $CFLAGS"
|
||||
],[
|
||||
AC_MSG_ERROR([GeoIP library not found. Try using --without-libgeoip to link against the shipped copy.])
|
||||
])
|
||||
],
|
||||
["no"|"shipped"], [
|
||||
AS_IF([test "x$ac_arg_enable_geoip" = "xno"], [
|
||||
# redundant check: session_impl.hpp just won't check for any
|
||||
# GeoIP.h, so any value would be ok (ie. this AS_IF could be
|
||||
# removed)
|
||||
AC_MSG_RESULT([disabled])
|
||||
ARG_WITH_LIBGEOIP="disabled"
|
||||
], [
|
||||
AC_MSG_RESULT([no])
|
||||
ARG_WITH_LIBGEOIP="no"
|
||||
AC_DEFINE([WITH_SHIPPED_GEOIP_H],[1],[Define to use shipped copy of GeoIP.h])
|
||||
COMPILETIME_OPTIONS+="-DWITH_SHIPPED_GEOIP_H "
|
||||
])
|
||||
],
|
||||
[AC_MSG_RESULT([$ARG_WITH_LIBGEOIP])
|
||||
AC_MSG_ERROR([Unknown option "$ARG_WITH_LIBGEOIP". Use either "yes" or "no".])]
|
||||
)
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Setting conditional variables for Makefiles
|
||||
###############################################################################
|
||||
|
||||
AM_CONDITIONAL([ENABLE_DHT], [test "x$ARG_ENABLE_DHT" = "xyes" -o "x$ARG_ENABLE_DHT" = "xlogging" ])
|
||||
AM_CONDITIONAL([ENABLE_EXAMPLES], [test "x$ARG_ENABLE_EXAMPLES" = "xyes"])
|
||||
AM_CONDITIONAL([ENABLE_TESTS], [test "x$ARG_ENABLE_TESTS" = "xyes"])
|
||||
AM_CONDITIONAL([ENABLE_PYTHON_BINDING], [test "x$ARG_ENABLE_PYTHON_BINDING" = "xyes"])
|
||||
|
||||
AM_CONDITIONAL([WITH_SHIPPED_GEOIP], [test "x$ARG_WITH_LIBGEOIP" = "xno" ])
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Other useful stuff
|
||||
###############################################################################
|
||||
|
||||
# this works around a bug in asio in boost-1.39
|
||||
# see: https://svn.boost.org/trac/boost/ticket/3095
|
||||
AC_DEFINE([BOOST_ASIO_HASH_MAP_BUCKETS],[1021],[Define to fix a wrong behavior in boost 1.39.])
|
||||
COMPILETIME_OPTIONS+="-DBOOST_ASIO_HASH_MAP_BUCKETS=1021 "
|
||||
|
||||
AC_DEFINE([BOOST_EXCEPTION_DISABLE],[1],[Define to disable the boost.exception features.])
|
||||
COMPILETIME_OPTIONS+="-DBOOST_EXCEPTION_DISABLE "
|
||||
|
||||
AC_DEFINE([BOOST_ASIO_ENABLE_CANCELIO],[1],[Define to enable cancel support in asio on windows XP and older.])
|
||||
COMPILETIME_OPTIONS+="-DBOOST_ASIO_ENABLE_CANCELIO "
|
||||
|
||||
dnl Use possibly specific python install params
|
||||
AC_ARG_VAR([PYTHON_INSTALL_PARAMS], [Set specific install parameters for python bindings.])
|
||||
AS_IF([test "x$PYTHON_INSTALL_PARAMS" = "x"],
|
||||
[PYTHON_INSTALL_PARAMS='--prefix=$(DESTDIR)$(prefix)'])
|
||||
|
||||
dnl Set some defines if we are building a shared library
|
||||
AS_IF([test "x$enable_shared" = "xyes"],
|
||||
[AC_DEFINE([TORRENT_BUILDING_SHARED],[1],[Define to exports functions and classes with default visibility in GCC.])
|
||||
COMPILETIME_OPTIONS+="-DTORRENT_LINKING_SHARED "])
|
||||
|
||||
AC_SUBST(DEBUGFLAGS)
|
||||
AC_SUBST(PYTHON_INSTALL_PARAMS)
|
||||
AC_SUBST(COMPILETIME_OPTIONS)
|
||||
|
||||
|
||||
# Try to guess real svn revision if any, fallback to hardcoded otherwise
|
||||
SVN_REVISION=`svn info 2>/dev/null | sed -n -e '/^URL\:.*libtorrent.svn.sourceforge.net/,$!d;s,^Revision\: \([[0-9]]*\)$,\1,p'`
|
||||
AS_IF([test -z "$SVN_REVISION"],
|
||||
[SVN_REVISION=`sed -n -e 's/^#define LIBTORRENT_REVISION \"\$Rev\: \([0-9]*\) \$\" $/\1/p' include/libtorrent/version.hpp`])
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Generating Makefiles
|
||||
###############################################################################
|
||||
|
||||
AS_ECHO
|
||||
AS_ECHO "Generating Makefiles:"
|
||||
|
||||
AC_CONFIG_FILES(
|
||||
[Makefile]
|
||||
[src/Makefile]
|
||||
[include/libtorrent/Makefile]
|
||||
[examples/Makefile]
|
||||
[test/Makefile]
|
||||
[bindings/Makefile]
|
||||
[bindings/python/Makefile]
|
||||
[bindings/python/setup.py]
|
||||
[libtorrent-rasterbar.pc]
|
||||
[libtorrent-rasterbar-cmake.pc]
|
||||
)
|
||||
|
||||
AC_OUTPUT
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Generating config.report
|
||||
###############################################################################
|
||||
|
||||
AS_ECHO
|
||||
AS_ECHO "Configure script has finished system check."
|
||||
AS_ECHO
|
||||
|
||||
cat > config.report << END
|
||||
Config results:
|
||||
-=-=-=-=-=-=-=-=-
|
||||
|
||||
Package:
|
||||
name: ${PACKAGE_NAME}
|
||||
version: ${PACKAGE_VERSION}
|
||||
svn revision: ${SVN_REVISION}
|
||||
|
||||
Build environment:
|
||||
build system: ${build}
|
||||
host system: ${host}
|
||||
target system: ${target}
|
||||
|
||||
Compiler and linker flags:
|
||||
CPPFlags: ${CPPFLAGS}
|
||||
CFlags: ${CFLAGS}
|
||||
CXXFlags: ${CXXFLAGS}
|
||||
LDFlags: ${LDFLAGS}
|
||||
Libs: ${LIBS}
|
||||
Defs: ${DEFS}
|
||||
|
||||
Build options:
|
||||
deprecated functions: ${ARG_ENABLE_DEPRECATED:-yes}
|
||||
debug build: ${ARG_ENABLE_DEBUG:-no}
|
||||
invariant checks: ${ARG_ENABLE_INVARIANT:-no}
|
||||
logging support: ${ARG_ENABLE_LOGGING:-no}
|
||||
statistics: ${ARG_ENABLE_STATS:-no}
|
||||
disk statistics: ${ARG_ENABLE_DISK_STATS:-no}
|
||||
|
||||
Features:
|
||||
encryption support: ${ARG_ENABLE_ENCRYPTION:-yes}
|
||||
geoip support: ${ARG_ENABLE_GEOIP:-yes}
|
||||
dht support: ${ARG_ENABLE_DHT:-yes}
|
||||
pool allocators: ${ARG_ENABLE_POOL_ALLOC:-yes}
|
||||
|
||||
Extra builds:
|
||||
examples: ${ARG_ENABLE_EXAMPLES:-no}
|
||||
tests: ${ARG_ENABLE_TESTS:-no}
|
||||
python bindings: ${ARG_ENABLE_PYTHON_BINDING:-no}
|
||||
|
||||
Pthread library:
|
||||
CFlags: ${PTHREAD_CFLAGS}
|
||||
Libs: ${PTHREAD_LIBS}
|
||||
|
||||
Boost libraries:
|
||||
version: ${BOOST_VERSION}
|
||||
CPPFlags: ${BOOST_CPPFLAGS}
|
||||
LDFlags: ${BOOST_LDFLAGS}
|
||||
boost.system: ${BOOST_SYSTEM_LIB}
|
||||
END
|
||||
|
||||
AS_IF([test "x$ARG_ENABLE_PYTHON_BINDING" = "xyes"], [
|
||||
cat >> config.report << END
|
||||
boost.python: ${BOOST_PYTHON_LIB}
|
||||
|
||||
Python environment:
|
||||
-automake-
|
||||
binary: ${PYTHON}
|
||||
version: ${PYTHON_VERSION}
|
||||
platform: ${PYTHON_PLATFORM}
|
||||
prefix: ${PYTHON_PREFIX}
|
||||
exec_prefix: ${PYTHON_EXEC_PREFIX}
|
||||
pythondir: ${pythondir}
|
||||
pkgpythondir: ${pkgpythondir}
|
||||
pyexecdir: ${pyexecdir}
|
||||
pkgpyexecdir: ${pkgpyexecdir}
|
||||
|
||||
-m4-
|
||||
cppflags: ${PYTHON_CPPFLAGS}
|
||||
ldflags: ${PYTHON_LDFLAGS}
|
||||
extra libs: ${PYTHON_EXTRA_LIBS}
|
||||
extra ldflags: ${PYTHON_EXTRA_LDFLAGS}
|
||||
|
||||
END
|
||||
])
|
||||
|
||||
cat >> config.report << END
|
||||
|
||||
External libraries:
|
||||
system libgeoip: ${ARG_WITH_LIBGEOIP:-no}
|
||||
END
|
||||
|
||||
AS_IF([test "x$ARG_WITH_LIBGEOIP" = "xyes"], [
|
||||
cat >> config.report << END
|
||||
|
||||
GeoIP library:
|
||||
GeoIP CFlags: ${GEOIP_CFLAGS}
|
||||
GeoIP Libs: ${GEOIP_LIBS}
|
||||
END
|
||||
])
|
||||
|
||||
AS_IF([test "x$ARG_ENABLE_ENCRYPTION" = "xyes"], [
|
||||
cat >> config.report << END
|
||||
|
||||
OpenSSL library:
|
||||
OpenSSL Libs: ${OPENSSL_LIBS}
|
||||
OpenSSL LDFlags: ${OPENSSL_LDFLAGS}
|
||||
OpenSSL Includes: ${OPENSSL_INCLUDES}
|
||||
END
|
||||
])
|
||||
|
||||
cat config.report
|
||||
|
||||
AS_ECHO
|
||||
AS_ECHO "Type 'make' to compile $PACKAGE_STRING"
|
||||
AS_ECHO "or type 'make V=1' for verbose compiling"
|
||||
AS_ECHO "and then 'make install' to install it into $prefix"
|
||||
AS_ECHO
|
|
@ -1,68 +0,0 @@
|
|||
#! /usr/bin/env python
|
||||
|
||||
import socket
|
||||
import sys
|
||||
from types import StringType, IntType, LongType, DictType, ListType, TupleType
|
||||
import random
|
||||
|
||||
port = int(sys.argv[1])
|
||||
|
||||
# from BitTorrent 4.3.0
|
||||
def encode_bencached(x,r):
|
||||
r.append(x.bencoded)
|
||||
|
||||
def encode_int(x, r):
|
||||
r.extend(('i', str(x), 'e'))
|
||||
|
||||
def encode_string(x, r):
|
||||
r.extend((str(len(x)), ':', x))
|
||||
|
||||
def encode_list(x, r):
|
||||
r.append('l')
|
||||
for i in x:
|
||||
encode_func[type(i)](i, r)
|
||||
r.append('e')
|
||||
|
||||
def encode_dict(x,r):
|
||||
r.append('d')
|
||||
ilist = x.items()
|
||||
ilist.sort()
|
||||
for k, v in ilist:
|
||||
r.extend((str(len(k)), ':', k))
|
||||
encode_func[type(v)](v, r)
|
||||
r.append('e')
|
||||
|
||||
encode_func = {}
|
||||
encode_func[IntType] = encode_int
|
||||
encode_func[LongType] = encode_int
|
||||
encode_func[StringType] = encode_string
|
||||
encode_func[ListType] = encode_list
|
||||
encode_func[TupleType] = encode_list
|
||||
encode_func[DictType] = encode_dict
|
||||
|
||||
def bencode(x):
|
||||
r = []
|
||||
encode_func[type(x)](x, r)
|
||||
return ''.join(r)
|
||||
|
||||
def send_dht_message(msg):
|
||||
s.sendto(bencode(msg), 0, ('127.0.0.1', port))
|
||||
|
||||
def random_key():
|
||||
ret = ''
|
||||
for i in range(0, 20):
|
||||
ret += chr(random.randint(0, 255))
|
||||
return ret
|
||||
|
||||
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||
node_id = '1' * 20;
|
||||
query = 'get_peers'
|
||||
|
||||
print 'test random info-hashes'
|
||||
for i in xrange(1, 30000):
|
||||
send_dht_message({'a': {'id': node_id, 'info_hash': random_key()}, 'q': query, 'y': 'q', 't': '%d' % i})
|
||||
|
||||
print 'test random peer-ids'
|
||||
for i in xrange(1, 30000):
|
||||
send_dht_message({'a': {'id': random_key(), 'info_hash': random_key()}, 'q': query, 'y': 'q', 't': '%d' % i})
|
||||
|
Before Width: | Height: | Size: 37 KiB |
Before Width: | Height: | Size: 5.1 KiB |
Before Width: | Height: | Size: 2.7 KiB |
Before Width: | Height: | Size: 4.6 KiB |
Before Width: | Height: | Size: 9.3 KiB |
Before Width: | Height: | Size: 23 KiB |
Before Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 42 KiB |
Before Width: | Height: | Size: 29 KiB |
|
@ -1,746 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta name="generator" content="Docutils 0.5: http://docutils.sourceforge.net/" />
|
||||
<title>libtorrent manual</title>
|
||||
<meta name="author" content="Arvid Norberg, arvid@rasterbar.com" />
|
||||
<link rel="stylesheet" type="text/css" href="../../css/base.css" />
|
||||
<link rel="stylesheet" type="text/css" href="../../css/rst.css" />
|
||||
<link rel="stylesheet" href="style.css" type="text/css" />
|
||||
<style type="text/css">
|
||||
/* Hides from IE-mac \*/
|
||||
* html pre { height: 1%; }
|
||||
/* End hide from IE-mac */
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="document" id="libtorrent-manual">
|
||||
<div id="container">
|
||||
<div id="headerNav">
|
||||
<ul>
|
||||
<li class="first"><a href="/">Home</a></li>
|
||||
<li><a href="../../products.html">Products</a></li>
|
||||
<li><a href="../../contact.html">Contact</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="header">
|
||||
<h1><span>Rasterbar Software</span></h1>
|
||||
<h2><span>Software developement and consulting</span></h2>
|
||||
</div>
|
||||
<div id="main">
|
||||
<h1 class="title">libtorrent manual</h1>
|
||||
<table class="docinfo" frame="void" rules="none">
|
||||
<col class="docinfo-name" />
|
||||
<col class="docinfo-content" />
|
||||
<tbody valign="top">
|
||||
<tr><th class="docinfo-name">Author:</th>
|
||||
<td>Arvid Norberg, <a class="last reference external" href="mailto:arvid@rasterbar.com">arvid@rasterbar.com</a></td></tr>
|
||||
<tr><th class="docinfo-name">Version:</th>
|
||||
<td>0.16.0</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="contents topic" id="table-of-contents">
|
||||
<p class="topic-title first">Table of contents</p>
|
||||
<ul class="simple">
|
||||
<li><a class="reference internal" href="#downloading-and-building" id="id9">downloading and building</a><ul>
|
||||
<li><a class="reference internal" href="#building-from-svn" id="id10">building from svn</a></li>
|
||||
<li><a class="reference internal" href="#building-with-bbv2" id="id11">building with BBv2</a></li>
|
||||
<li><a class="reference internal" href="#building-with-autotools" id="id12">building with autotools</a></li>
|
||||
<li><a class="reference internal" href="#building-with-other-build-systems" id="id13">building with other build systems</a></li>
|
||||
<li><a class="reference internal" href="#build-configurations" id="id14">build configurations</a></li>
|
||||
<li><a class="reference internal" href="#building-openssl-for-windows" id="id15">building openssl for windows</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="section" id="downloading-and-building">
|
||||
<h1>downloading and building</h1>
|
||||
<p>To acquire the latest version of libtorrent, you'll have to grab it from SVN.
|
||||
You'll find instructions on how to do this <a class="reference external" href="http://sourceforge.net/svn/?group_id=79942">here</a> (see subversion access).</p>
|
||||
<p>The build systems supported "out of the box" in libtorrent are boost-build v2
|
||||
(BBv2) and autotools (for unix-like systems). If you still can't build after
|
||||
following these instructions, you can usually get help in the <tt class="docutils literal"><span class="pre">#libtorrent</span></tt>
|
||||
IRC channel on <tt class="docutils literal"><span class="pre">irc.freenode.net</span></tt>.</p>
|
||||
<div class="warning">
|
||||
<p class="first admonition-title">Warning</p>
|
||||
<p>A common mistake when building and linking against libtorrent is
|
||||
to build with one set of configuration options (#defines) and
|
||||
link against it using a different set of configuration options. Since
|
||||
libtorrent has some code in header files, that code will not be
|
||||
compatible with the built library if they see different configurations.</p>
|
||||
<p>Always make sure that the same TORRENT_* macros are defined when you
|
||||
link against libtorrent as when you build it.</p>
|
||||
<p class="last">Boost-build supports propagating configuration options to dependencies.
|
||||
When building using the makefiles, this is handled by setting the
|
||||
configuration options in the pkg-config file. Always use pkg-config
|
||||
when linking against libtorrent.</p>
|
||||
</div>
|
||||
<div class="section" id="building-from-svn">
|
||||
<h2>building from svn</h2>
|
||||
<p>To build libtorrent from svn you need to check out the libtorrent sources from
|
||||
sourceforge and also check out the asio sources from its sourceforge cvs.
|
||||
If you downloaded a release tarball, you can skip this section.</p>
|
||||
<p>To prepare the directory structure for building, follow these steps:</p>
|
||||
<ul class="simple">
|
||||
<li>Check out libtorrent (<a class="reference external" href="http://sourceforge.net/svn/?group_id=79942">instructions</a>).</li>
|
||||
<li>Check out asio (<a class="reference external" href="http://sourceforge.net/cvs/?group_id=122478">instructions</a>).</li>
|
||||
<li>Copy the <tt class="docutils literal"><span class="pre">asio/include/asio/</span></tt> directory into the <tt class="docutils literal"><span class="pre">libtorrent/include/libtorrent/</span></tt>
|
||||
directory. Alternatively you can make a symbolic link.</li>
|
||||
<li>Copy <tt class="docutils literal"><span class="pre">asio/include/asio.hpp</span></tt> into <tt class="docutils literal"><span class="pre">libtorrent/include/libtorrent</span></tt>.</li>
|
||||
</ul>
|
||||
<p>Now the libtorrent directory is ready for building. Follow the steps in one
|
||||
of the following sections depending on which build system you prefer to use.</p>
|
||||
</div>
|
||||
<div class="section" id="building-with-bbv2">
|
||||
<h2>building with BBv2</h2>
|
||||
<p>The primary reason to use boost-build is that it will automatically build the
|
||||
dependent boost libraries with the correct compiler settings, in order to
|
||||
ensure that the build targets are link compatible (see <a class="reference external" href="http://boost.org/more/separate_compilation.html">boost guidelines</a>
|
||||
for some details on this issue).</p>
|
||||
<p>Since BBv2 will build the boost libraries for you, you need the full boost
|
||||
source package. Having boost installed via some package system is usually not
|
||||
enough (and even if it is enough, the necessary environment variables are
|
||||
usually not set by the package installer).</p>
|
||||
<p>If you want to build against an installed copy of boost, you can skip directly
|
||||
to step 3 (assuming you also have boost build installed).</p>
|
||||
<div class="section" id="step-1-download-boost">
|
||||
<h3>Step 1: Download boost</h3>
|
||||
<p>You'll find boost <a class="reference external" href="http://sourceforge.net/project/showfiles.php?group_id=7586&package_id=8041&release_id=619445">here</a>.</p>
|
||||
<p>Extract the archive to some directory where you want it. For the sake of this
|
||||
guide, let's assume you extract the package to <tt class="docutils literal"><span class="pre">c:\boost_1_34_0</span></tt> (I'm using
|
||||
a windows path in this example since if you're on linux/unix you're more likely
|
||||
to use the autotools). You'll need at least version 1.34 of the boost library
|
||||
in order to build libtorrent.</p>
|
||||
</div>
|
||||
<div class="section" id="step-2-setup-bbv2">
|
||||
<h3>Step 2: Setup BBv2</h3>
|
||||
<p>First you need to build <tt class="docutils literal"><span class="pre">bjam</span></tt>. You do this by opening a terminal (In
|
||||
windows, run <tt class="docutils literal"><span class="pre">cmd</span></tt>). Change directory to
|
||||
<tt class="docutils literal"><span class="pre">c:\boost_1_34_0\tools\jam\src</span></tt>. Then run the script called
|
||||
<tt class="docutils literal"><span class="pre">build.bat</span></tt> or <tt class="docutils literal"><span class="pre">build.sh</span></tt> on a unix system. This will build <tt class="docutils literal"><span class="pre">bjam</span></tt> and
|
||||
place it in a directory starting with <tt class="docutils literal"><span class="pre">bin.</span></tt> and then have the name of your
|
||||
platform. Copy the <tt class="docutils literal"><span class="pre">bjam.exe</span></tt> (or <tt class="docutils literal"><span class="pre">bjam</span></tt> on a unix system) to a place
|
||||
that's in you shell's <tt class="docutils literal"><span class="pre">PATH</span></tt>. On linux systems a place commonly used may be
|
||||
<tt class="docutils literal"><span class="pre">/usr/local/bin</span></tt> or on windows <tt class="docutils literal"><span class="pre">c:\windows</span></tt> (you can also add directories
|
||||
to the search paths by modifying the environment variable called <tt class="docutils literal"><span class="pre">PATH</span></tt>).</p>
|
||||
<p>Now you have <tt class="docutils literal"><span class="pre">bjam</span></tt> installed. <tt class="docutils literal"><span class="pre">bjam</span></tt> can be considered an interpreter
|
||||
that the boost-build system is implemented on. So boost-build uses <tt class="docutils literal"><span class="pre">bjam</span></tt>.
|
||||
So, to complete the installation you need to make two more things. You need to
|
||||
set the environment variable <tt class="docutils literal"><span class="pre">BOOST_BUILD_PATH</span></tt>. This is the path that tells
|
||||
<tt class="docutils literal"><span class="pre">bjam</span></tt> where it can find boost-build, your configuration file and all the
|
||||
toolsets (descriptions used by boost-build to know how to use different
|
||||
compilers on different platforms). Assuming the boost install path above, set
|
||||
it to <tt class="docutils literal"><span class="pre">c:\boost_1_34_0\tools\build\v2</span></tt>.</p>
|
||||
<p>To set an environment variable in windows, type for example:</p>
|
||||
<pre class="literal-block">
|
||||
set BOOST_BUILD_PATH=c:\boost_1_34_0\tools\build\v2
|
||||
</pre>
|
||||
<p>In a terminal window.</p>
|
||||
<p>The last thing to do to complete the setup of BBv2 is to modify your
|
||||
<tt class="docutils literal"><span class="pre">user-config.jam</span></tt> file. It is located in <tt class="docutils literal"><span class="pre">c:\boost_1_34_0\tools\build\v2</span></tt>.
|
||||
Depending on your platform and which compiler you're using, you should add a
|
||||
line for each compiler and compiler version you have installed on your system
|
||||
that you want to be able to use with BBv2. For example, if you're using
|
||||
Microsoft Visual Studio 7.1 (2003), just add a line:</p>
|
||||
<pre class="literal-block">
|
||||
using msvc : 7.1 ;
|
||||
</pre>
|
||||
<p>If you use GCC, add the line:</p>
|
||||
<pre class="literal-block">
|
||||
using gcc ;
|
||||
</pre>
|
||||
<p>If you have more than one version of GCC installed, you can add the
|
||||
commandline used to invoke g++ after the version number, like this:</p>
|
||||
<pre class="literal-block">
|
||||
using gcc : 3.3 : g++-3.3 ;
|
||||
using gcc : 4.0 : g++-4.0 ;
|
||||
</pre>
|
||||
<p>Another toolset worth mentioning is the <tt class="docutils literal"><span class="pre">darwin</span></tt> toolset (For MacOS X).
|
||||
From Tiger (10.4) MacOS X comes with both GCC 3.3 and GCC 4.0. Then you can
|
||||
use the following toolsets:</p>
|
||||
<pre class="literal-block">
|
||||
using darwin : 3.3 : g++-3.3 ;
|
||||
using darwin : 4.0 : g++-4.0 ;
|
||||
</pre>
|
||||
<p>Note that the spaces around the semi-colons and colons are important!</p>
|
||||
<p>Also see the <a class="reference external" href="http://www.boost.org/doc/html/bbv2/installation.html">official installation instructions</a>.</p>
|
||||
</div>
|
||||
<div class="section" id="step-3-building-libtorrent">
|
||||
<h3>Step 3: Building libtorrent</h3>
|
||||
<p>When building libtorrent, the <tt class="docutils literal"><span class="pre">Jamfile</span></tt> expects the environment variable
|
||||
<tt class="docutils literal"><span class="pre">BOOST_ROOT</span></tt> to be set to the boost installation directory. It uses this to
|
||||
find the boost libraries it depends on, so they can be built and their headers
|
||||
files found. So, set this to <tt class="docutils literal"><span class="pre">c:\boost_1_34_0</span></tt>. You only need this if you're
|
||||
building against a source distribution of boost.</p>
|
||||
<p>Then the only thing left is simply to invoke <tt class="docutils literal"><span class="pre">bjam</span></tt>. If you want to specify
|
||||
a specific toolset to use (compiler) you can just add that to the commandline.
|
||||
For example:</p>
|
||||
<pre class="literal-block">
|
||||
bjam msvc-7.1 boost=source
|
||||
bjam gcc-3.3 boost=source
|
||||
bjam darwin-4.0 boost=source
|
||||
</pre>
|
||||
<p>If you're building against a system installed boost, specify <tt class="docutils literal"><span class="pre">boost=system</span></tt>.</p>
|
||||
<p>To build different versions you can also just add the name of the build
|
||||
variant. Some default build variants in BBv2 are <tt class="docutils literal"><span class="pre">release</span></tt>, <tt class="docutils literal"><span class="pre">debug</span></tt>,
|
||||
<tt class="docutils literal"><span class="pre">profile</span></tt>.</p>
|
||||
<p>You can build libtorrent as a dll too, by typing <tt class="docutils literal"><span class="pre">link=shared</span></tt>, or
|
||||
<tt class="docutils literal"><span class="pre">link=static</span></tt> to build a static library.</p>
|
||||
<p>If you want to explicitly say how to link against the runtime library, you
|
||||
can set the <tt class="docutils literal"><span class="pre">runtime-link</span></tt> feature on the commandline, either to <tt class="docutils literal"><span class="pre">shared</span></tt>
|
||||
or <tt class="docutils literal"><span class="pre">static</span></tt>. Most operating systems will only allow linking shared against
|
||||
the runtime, but on windows you can do both. Example:</p>
|
||||
<pre class="literal-block">
|
||||
bjam msvc-7.1 link=static runtime-link=static boost=source
|
||||
</pre>
|
||||
<div class="warning">
|
||||
<p class="first admonition-title">Warning</p>
|
||||
<p class="last">If you link statically to the runtime library, you cannot build libtorrent
|
||||
as a shared library (DLL), since you will get separate heaps in the library
|
||||
and in the client application. It will result in crashes and possibly link
|
||||
errors.</p>
|
||||
</div>
|
||||
<div class="warning">
|
||||
<p class="first admonition-title">Warning</p>
|
||||
<p class="last">With boost-build V2 (Milestone 11), the darwin toolset uses the <tt class="docutils literal"><span class="pre">-s</span></tt> linker
|
||||
option to strip debug symbols. This option is buggy in Apple's GCC, and
|
||||
will make the executable crash on startup. On Mac OS X, instead build
|
||||
your release executables with the <tt class="docutils literal"><span class="pre">debug-symbols=on</span></tt> option, and
|
||||
later strip your executable with <tt class="docutils literal"><span class="pre">strip</span></tt>.</p>
|
||||
</div>
|
||||
<div class="warning">
|
||||
<p class="first admonition-title">Warning</p>
|
||||
<p class="last">Some linux systems requires linking against <tt class="docutils literal"><span class="pre">librt</span></tt> in order to access
|
||||
the POSIX clock functions. If you get an error complaining about a missing
|
||||
symbol <tt class="docutils literal"><span class="pre">clock_gettime</span></tt>, you have to give <tt class="docutils literal"><span class="pre">need-librt=yes</span></tt> on the
|
||||
bjam command line. This will make libtorrent link against <tt class="docutils literal"><span class="pre">librt</span></tt>.</p>
|
||||
</div>
|
||||
<div class="note">
|
||||
<p class="first admonition-title">Note</p>
|
||||
<p class="last">When building on Solaris, you might have to specify <tt class="docutils literal"><span class="pre">stdlib=sun-stlport</span></tt>
|
||||
on the bjam command line.</p>
|
||||
</div>
|
||||
<p>The build targets are put in a directory called bin, and under it they are
|
||||
sorted in directories depending on the toolset and build variant used.</p>
|
||||
<p>To build the examples, just change directory to the examples directory and
|
||||
invoke <tt class="docutils literal"><span class="pre">bjam</span></tt> from there. To build and run the tests, go to the test
|
||||
directory and run <tt class="docutils literal"><span class="pre">bjam</span></tt>.</p>
|
||||
<p>Note that if you're building on windows using the <tt class="docutils literal"><span class="pre">msvc</span></tt> toolset, you cannot run it
|
||||
from a cygwin terminal, you'll have to run it from a <tt class="docutils literal"><span class="pre">cmd</span></tt> terminal. The same goes for
|
||||
cygwin, if you're building with gcc in cygwin you'll have to run it from a cygwin terminal.
|
||||
Also, make sure the paths are correct in the different environments. In cygwin, the paths
|
||||
(<tt class="docutils literal"><span class="pre">BOOST_BUILD_PATH</span></tt> and <tt class="docutils literal"><span class="pre">BOOST_ROOT</span></tt>) should be in the typical unix-format (e.g.
|
||||
<tt class="docutils literal"><span class="pre">/cygdrive/c/boost_1_34_0</span></tt>). In the windows environment, they should have the typical
|
||||
windows format (<tt class="docutils literal"><span class="pre">c:/boost_1_34_0</span></tt>).</p>
|
||||
<p>The <tt class="docutils literal"><span class="pre">Jamfile</span></tt> will define <tt class="docutils literal"><span class="pre">NDEBUG</span></tt> when it's building a release build.
|
||||
For more build configuration flags see <a class="reference internal" href="#build-configurations">Build configurations</a>.</p>
|
||||
<p>Build features:</p>
|
||||
<table border="1" class="docutils">
|
||||
<colgroup>
|
||||
<col width="33%" />
|
||||
<col width="67%" />
|
||||
</colgroup>
|
||||
<thead valign="bottom">
|
||||
<tr><th class="head">boost build feature</th>
|
||||
<th class="head">values</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody valign="top">
|
||||
<tr><td><tt class="docutils literal"><span class="pre">boost</span></tt></td>
|
||||
<td><ul class="first last simple">
|
||||
<li><tt class="docutils literal"><span class="pre">system</span></tt> - default. Tells the Jamfile that
|
||||
boost is installed and should be linked against
|
||||
the system libraries.</li>
|
||||
<li><tt class="docutils literal"><span class="pre">source</span></tt> - Specifies that boost is to be built
|
||||
from source. The environment variable
|
||||
<tt class="docutils literal"><span class="pre">BOOST_ROOT</span></tt> must be defined to point to the
|
||||
boost directory.</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
<tr><td><tt class="docutils literal"><span class="pre">boost-link</span></tt></td>
|
||||
<td><ul class="first last simple">
|
||||
<li><tt class="docutils literal"><span class="pre">static</span></tt> - links statically against the boost
|
||||
libraries.</li>
|
||||
<li><tt class="docutils literal"><span class="pre">shared</span></tt> - links dynamically against the boost
|
||||
libraries.</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
<tr><td><tt class="docutils literal"><span class="pre">logging</span></tt></td>
|
||||
<td><ul class="first last simple">
|
||||
<li><tt class="docutils literal"><span class="pre">none</span></tt> - no logging.</li>
|
||||
<li><tt class="docutils literal"><span class="pre">default</span></tt> - basic session logging.</li>
|
||||
<li><tt class="docutils literal"><span class="pre">verbose</span></tt> - verbose peer wire logging.</li>
|
||||
<li><tt class="docutils literal"><span class="pre">errors</span></tt> - like verbose, but limited to errors.</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
<tr><td><tt class="docutils literal"><span class="pre">dht-support</span></tt></td>
|
||||
<td><ul class="first last simple">
|
||||
<li><tt class="docutils literal"><span class="pre">on</span></tt> - build with support for tracker less
|
||||
torrents and DHT support.</li>
|
||||
<li><tt class="docutils literal"><span class="pre">logging</span></tt> - build with DHT support and verbose
|
||||
logging of the DHT protocol traffic.</li>
|
||||
<li><tt class="docutils literal"><span class="pre">off</span></tt> - build without DHT support.</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
<tr><td><tt class="docutils literal"><span class="pre">need-librt</span></tt></td>
|
||||
<td><ul class="first last simple">
|
||||
<li><tt class="docutils literal"><span class="pre">no</span></tt> - this platform does not need to link
|
||||
against librt to have POSIX time functions.</li>
|
||||
<li><tt class="docutils literal"><span class="pre">yes</span></tt> - specify this if your linux system
|
||||
requires you to link against librt.a. This is
|
||||
typically the case on x86 64 bit systems.</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
<tr><td><tt class="docutils literal"><span class="pre">asserts</span></tt></td>
|
||||
<td><ul class="first last simple">
|
||||
<li><tt class="docutils literal"><span class="pre">on</span></tt> - asserts are on if in debug mode</li>
|
||||
<li><tt class="docutils literal"><span class="pre">off</span></tt> - asserts are disabled</li>
|
||||
<li><tt class="docutils literal"><span class="pre">production</span></tt> - assertion failures are logged
|
||||
to <tt class="docutils literal"><span class="pre">asserts.log</span></tt> in the current working
|
||||
directory, but won't abort the process.</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
<tr><td><tt class="docutils literal"><span class="pre">geoip</span></tt></td>
|
||||
<td><ul class="first last simple">
|
||||
<li><tt class="docutils literal"><span class="pre">off</span></tt> - geo ip lookups disabled</li>
|
||||
<li><tt class="docutils literal"><span class="pre">static</span></tt> - <a class="reference external" href="http://www.maxmind.com/app/api">MaxMind</a> geo ip lookup code linked
|
||||
in statically. Note that this code is under
|
||||
LGPL license.</li>
|
||||
<li><tt class="docutils literal"><span class="pre">shared</span></tt> - The <a class="reference external" href="http://www.maxmind.com/app/api">MaxMind</a> geo ip lookup library
|
||||
is expected to be installed on the system and
|
||||
it will be used.</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
<tr><td><tt class="docutils literal"><span class="pre">upnp-logging</span></tt></td>
|
||||
<td><ul class="first last simple">
|
||||
<li><tt class="docutils literal"><span class="pre">off</span></tt> - default. Does not log UPnP traffic.</li>
|
||||
<li><tt class="docutils literal"><span class="pre">on</span></tt> - creates "upnp.log" with the messages
|
||||
sent to and received from UPnP devices.</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
<tr><td><tt class="docutils literal"><span class="pre">encryption</span></tt></td>
|
||||
<td><ul class="first last simple">
|
||||
<li><tt class="docutils literal"><span class="pre">openssl</span></tt> - links against openssl and
|
||||
libcrypto to enable https and encrypted
|
||||
bittorrent connections.</li>
|
||||
<li><tt class="docutils literal"><span class="pre">gcrypt</span></tt> - links against libgcrypt to enable
|
||||
encrypted bittorrent connections.</li>
|
||||
<li><tt class="docutils literal"><span class="pre">tommath</span></tt> - uses a shipped version of
|
||||
libtommath and a custom rc4 implementation
|
||||
(based on libtomcrypt). This is the default
|
||||
option.</li>
|
||||
<li><tt class="docutils literal"><span class="pre">off</span></tt> - turns off support for encrypted
|
||||
connections. The shipped public domain SHA-1
|
||||
implementation is used.</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
<tr><td><tt class="docutils literal"><span class="pre">pool-allocators</span></tt></td>
|
||||
<td><ul class="first last simple">
|
||||
<li><tt class="docutils literal"><span class="pre">on</span></tt> - default, uses pool allocators for send
|
||||
buffers.</li>
|
||||
<li><tt class="docutils literal"><span class="pre">off</span></tt> - uses <tt class="docutils literal"><span class="pre">malloc()</span></tt> and <tt class="docutils literal"><span class="pre">free()</span></tt>
|
||||
instead. Might be useful to debug buffer issues
|
||||
with tools like electric fence or libgmalloc.</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
<tr><td><tt class="docutils literal"><span class="pre">link</span></tt></td>
|
||||
<td><ul class="first last simple">
|
||||
<li><tt class="docutils literal"><span class="pre">static</span></tt> - builds libtorrent as a static
|
||||
library (.a / .lib)</li>
|
||||
<li><tt class="docutils literal"><span class="pre">shared</span></tt> - builds libtorrent as a shared
|
||||
library (.so / .dll).</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
<tr><td><tt class="docutils literal"><span class="pre">runtime-link</span></tt></td>
|
||||
<td><ul class="first last simple">
|
||||
<li><tt class="docutils literal"><span class="pre">static</span></tt> - links statically against the
|
||||
run-time library (if available on your
|
||||
platform).</li>
|
||||
<li><tt class="docutils literal"><span class="pre">shared</span></tt> - link dynamically against the
|
||||
run-time library (default).</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
<tr><td><tt class="docutils literal"><span class="pre">variant</span></tt></td>
|
||||
<td><ul class="first last simple">
|
||||
<li><tt class="docutils literal"><span class="pre">debug</span></tt> - builds libtorrent with debug
|
||||
information and invariant checks.</li>
|
||||
<li><tt class="docutils literal"><span class="pre">release</span></tt> - builds libtorrent in release mode
|
||||
without invariant checks and with optimization.</li>
|
||||
<li><tt class="docutils literal"><span class="pre">profile</span></tt> - builds libtorrent with profile
|
||||
information.</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
<tr><td><tt class="docutils literal"><span class="pre">character-set</span></tt></td>
|
||||
<td><p class="first">This setting will only have an affect on windows.
|
||||
Other platforms are expected to support UTF-8.</p>
|
||||
<ul class="last simple">
|
||||
<li><tt class="docutils literal"><span class="pre">unicode</span></tt> - The unicode version of the win32
|
||||
API is used. This is default.</li>
|
||||
<li><tt class="docutils literal"><span class="pre">ansi</span></tt> - The ansi version of the win32 API is
|
||||
used.</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
<tr><td><tt class="docutils literal"><span class="pre">invariant-checks</span></tt></td>
|
||||
<td><p class="first">This setting only affects debug builds (where
|
||||
<tt class="docutils literal"><span class="pre">NDEBUG</span></tt> is not defined). It defaults to <tt class="docutils literal"><span class="pre">on</span></tt>.</p>
|
||||
<ul class="last simple">
|
||||
<li><tt class="docutils literal"><span class="pre">on</span></tt> - internal invariant checks are enabled.</li>
|
||||
<li><tt class="docutils literal"><span class="pre">off</span></tt> - internal invariant checks are
|
||||
disabled. The resulting executable will run
|
||||
faster than a regular debug build.</li>
|
||||
<li><tt class="docutils literal"><span class="pre">full</span></tt> - turns on extra expensive invariant
|
||||
checks.</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
<tr><td><tt class="docutils literal"><span class="pre">debug-symbols</span></tt></td>
|
||||
<td><ul class="first last simple">
|
||||
<li><tt class="docutils literal"><span class="pre">on</span></tt> - default for debug builds. This setting
|
||||
is useful for building release builds with
|
||||
symbols.</li>
|
||||
<li><tt class="docutils literal"><span class="pre">off</span></tt> - default for release builds.</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
<tr><td><tt class="docutils literal"><span class="pre">deprecated-functions</span></tt></td>
|
||||
<td><ul class="first last simple">
|
||||
<li><tt class="docutils literal"><span class="pre">on</span></tt> - default. Includes deprecated functions
|
||||
of the API (might produce warnings during build
|
||||
when deprecated functions are used).</li>
|
||||
<li><tt class="docutils literal"><span class="pre">off</span></tt> - excludes deprecated functions from the
|
||||
API. Generates build errors when deprecated
|
||||
functions are used.</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
<tr><td><tt class="docutils literal"><span class="pre">full-stats</span></tt></td>
|
||||
<td><ul class="first last simple">
|
||||
<li><tt class="docutils literal"><span class="pre">on</span></tt> - default, collects stats for IP overhead
|
||||
and DHT and trackers. This uses a little bit
|
||||
extra memory for each peer and torrent.</li>
|
||||
<li><tt class="docutils literal"><span class="pre">off</span></tt> - only collects the standard stats for
|
||||
upload and download rate.</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p>The <tt class="docutils literal"><span class="pre">variant</span></tt> feature is <em>implicit</em>, which means you don't need to specify
|
||||
the name of the feature, just the value.</p>
|
||||
<p>The logs created when building vlog or log mode are put in a directory called
|
||||
<tt class="docutils literal"><span class="pre">libtorrent_logs</span></tt> in the current working directory.</p>
|
||||
<p>When building the example client on windows, you need to build with
|
||||
<tt class="docutils literal"><span class="pre">link=static</span></tt> otherwise you may get unresolved external symbols for some
|
||||
boost.program-options symbols.</p>
|
||||
<p>For more information, see the <a class="reference external" href="http://www.boost.org/tools/build/v2/index.html">Boost build v2 documentation</a>, or more
|
||||
specifically <a class="reference external" href="http://www.boost.org/doc/html/bbv2/reference.html#bbv2.advanced.builtins.features">the section on builtin features</a>.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" id="building-with-autotools">
|
||||
<h2>building with autotools</h2>
|
||||
<p>First of all, you need to install <tt class="docutils literal"><span class="pre">automake</span></tt> and <tt class="docutils literal"><span class="pre">autoconf</span></tt>. Many
|
||||
unix/linux systems comes with these preinstalled.</p>
|
||||
<p>The prerequisites for building libtorrent are boost.thread, boost.date_time
|
||||
and boost.filesystem. Those are the <em>compiled</em> boost libraries needed. The
|
||||
headers-only libraries needed include (but is not necessarily limited to)
|
||||
boost.bind, boost.ref, boost.multi_index, boost.optional, boost.lexical_cast,
|
||||
boost.integer, boost.iterator, boost.tuple, boost.array, boost.function,
|
||||
boost.smart_ptr, boost.preprocessor, boost.static_assert.</p>
|
||||
<p>If you want to build the <tt class="docutils literal"><span class="pre">client_test</span></tt> example, you'll also need boost.regex
|
||||
and boost.program_options.</p>
|
||||
<div class="section" id="step-1-generating-the-build-system">
|
||||
<h3>Step 1: Generating the build system</h3>
|
||||
<p>No build system is present if libtorrent is checked out from CVS - it
|
||||
needs to be generated first. If you're building from a released tarball,
|
||||
you may skip directly to <a class="reference internal" href="#step-2-running-configure">Step 2: Running configure</a>.</p>
|
||||
<p>Execute the following commands, in the given order, to generate
|
||||
the build system:</p>
|
||||
<pre class="literal-block">
|
||||
aclocal -I m4
|
||||
autoheader
|
||||
libtoolize --copy --force
|
||||
automake --add-missing --copy --gnu
|
||||
autoconf
|
||||
</pre>
|
||||
<p>On darwin/OSX you have to run <tt class="docutils literal"><span class="pre">glibtoolize</span></tt> instead of <tt class="docutils literal"><span class="pre">libtoolize</span></tt>.</p>
|
||||
</div>
|
||||
<div class="section" id="step-2-running-configure">
|
||||
<h3>Step 2: Running configure</h3>
|
||||
<p>In your shell, change directory to the libtorrent directory and run
|
||||
<tt class="docutils literal"><span class="pre">./configure</span></tt>. This will look for libraries and C++ features that libtorrent
|
||||
is dependent on. If something is missing or can't be found it will print an
|
||||
error telling you what failed.</p>
|
||||
<p>The most likely problem you may encounter is that the configure script won't
|
||||
find the boost libraries. Make sure you have boost installed on your system.
|
||||
The easiest way to install boost is usually to use the preferred package
|
||||
system on your platform. Usually libraries and headers are installed in
|
||||
standard directories where the compiler will find them, but sometimes that
|
||||
may not be the case. For example when installing boost on darwin using
|
||||
darwinports (the package system based on BSD ports) all libraries are
|
||||
installed to <tt class="docutils literal"><span class="pre">/opt/local/lib</span></tt> and headers are installed to
|
||||
<tt class="docutils literal"><span class="pre">/opt/local/include</span></tt>. By default the compiler will not look in these
|
||||
directories. You have to set the enviornment variables <tt class="docutils literal"><span class="pre">LDFLAGS</span></tt> and
|
||||
<tt class="docutils literal"><span class="pre">CXXFLAGS</span></tt> in order to make the compiler find those libs. In this example
|
||||
you'd set them like this:</p>
|
||||
<pre class="literal-block">
|
||||
export LDFLAGS=-L/opt/local/lib
|
||||
export CXXFLAGS=-I/opt/local/include
|
||||
</pre>
|
||||
<p>It was observed on FreeBSD (release 6.0) that one needs to add '-lpthread' to
|
||||
LDFLAGS, as Boost::Thread detection will fail without it, even if
|
||||
Boost::Thread is installed.</p>
|
||||
<p>If you need to set these variables, it may be a good idea to add those lines
|
||||
to your <tt class="docutils literal"><span class="pre">~/.profile</span></tt> or <tt class="docutils literal"><span class="pre">~/.tcshrc</span></tt> depending on your shell.</p>
|
||||
<p>If the boost libraries are named with a suffix on your platform, you may use
|
||||
the <tt class="docutils literal"><span class="pre">--with-boost-thread=</span></tt> option to specify the suffix used for the thread
|
||||
library in this case. For more information about these options, run:</p>
|
||||
<pre class="literal-block">
|
||||
./configure --help
|
||||
</pre>
|
||||
<p>On gentoo the boost libraries that are built with multi-threading support have
|
||||
the suffix <tt class="docutils literal"><span class="pre">mt</span></tt>.</p>
|
||||
<p>You know that the boost libraries were found if you see the following output
|
||||
from the configure script:</p>
|
||||
<pre class="literal-block">
|
||||
checking whether the Boost::DateTime library is available... yes
|
||||
checking for main in -lboost_date_time... yes
|
||||
checking whether the Boost::Filesystem library is available... yes
|
||||
checking for main in -lboost_filesystem... yes
|
||||
checking whether the Boost::Thread library is available... yes
|
||||
checking for main in -lboost_thread... yes
|
||||
</pre>
|
||||
<p>Another possible source of problems may be if the path to your libtorrent
|
||||
directory contains spaces. Make sure you either rename the directories with
|
||||
spaces in their names to remove the spaces or move the libtorrent directory.</p>
|
||||
</div>
|
||||
<div class="section" id="creating-a-debug-build">
|
||||
<h3>Creating a debug build</h3>
|
||||
<p>To tell configure to build a debug version (with debug info, asserts
|
||||
and invariant checks enabled), you have to run the configure script
|
||||
with the following option:</p>
|
||||
<pre class="literal-block">
|
||||
./configure --enable-debug=yes
|
||||
</pre>
|
||||
</div>
|
||||
<div class="section" id="creating-a-release-build">
|
||||
<h3>Creating a release build</h3>
|
||||
<p>To tell the configure to build a release version (without debug info,
|
||||
asserts and invariant checks), you have to run the configure script
|
||||
with the following option:</p>
|
||||
<pre class="literal-block">
|
||||
./configure --enable-debug=no
|
||||
</pre>
|
||||
<p>The above option make use of -DNDEBUG, which is used throughout libtorrent.</p>
|
||||
</div>
|
||||
<div class="section" id="id8">
|
||||
<h3>Step 3: Building libtorrent</h3>
|
||||
<p>Once the configure script is run successfully, you just type <tt class="docutils literal"><span class="pre">make</span></tt> and
|
||||
libtorrent, the examples and the tests will be built.</p>
|
||||
<p>When libtorrent is built it may be a good idea to run the tests, you do this
|
||||
by running <tt class="docutils literal"><span class="pre">make</span> <span class="pre">check</span></tt>.</p>
|
||||
<p>If you want to build a release version (without debug info, asserts and
|
||||
invariant checks), you have to rerun the configure script and rebuild, like this:</p>
|
||||
<pre class="literal-block">
|
||||
./configure --disable-debug
|
||||
make clean
|
||||
make
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" id="building-with-other-build-systems">
|
||||
<h2>building with other build systems</h2>
|
||||
<p>If you're building in MS Visual Studio, you may have to set the compiler
|
||||
options "force conformance in for loop scope", "treat wchar_t as built-in
|
||||
type" and "Enable Run-Time Type Info" to Yes.</p>
|
||||
</div>
|
||||
<div class="section" id="build-configurations">
|
||||
<h2>build configurations</h2>
|
||||
<p>By default libtorrent is built In debug mode, and will have pretty expensive
|
||||
invariant checks and asserts built into it. If you want to disable such checks
|
||||
(you want to do that in a release build) you can see the table below for which
|
||||
defines you can use to control the build.</p>
|
||||
<table border="1" class="docutils">
|
||||
<colgroup>
|
||||
<col width="45%" />
|
||||
<col width="55%" />
|
||||
</colgroup>
|
||||
<thead valign="bottom">
|
||||
<tr><th class="head">macro</th>
|
||||
<th class="head">description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody valign="top">
|
||||
<tr><td><tt class="docutils literal"><span class="pre">NDEBUG</span></tt></td>
|
||||
<td>If you define this macro, all asserts,
|
||||
invariant checks and general debug code will be
|
||||
removed. Since there is quite a lot of code in
|
||||
in header files in libtorrent, it may be
|
||||
important to define the symbol consistently
|
||||
across compilation units, including the clients
|
||||
files. Potential problems is different
|
||||
compilation units having different views of
|
||||
structs and class layouts and sizes.</td>
|
||||
</tr>
|
||||
<tr><td><tt class="docutils literal"><span class="pre">TORRENT_LOGGING</span></tt></td>
|
||||
<td>This macro will enable logging of the session
|
||||
events, such as tracker announces and incoming
|
||||
connections (as well as blocked connections).</td>
|
||||
</tr>
|
||||
<tr><td><tt class="docutils literal"><span class="pre">TORRENT_DISABLE_GEO_IP</span></tt></td>
|
||||
<td>This is defined by default by the Jamfile. It
|
||||
disables the GeoIP features, and avoids linking
|
||||
against LGPL:ed code.</td>
|
||||
</tr>
|
||||
<tr><td><tt class="docutils literal"><span class="pre">TORRENT_VERBOSE_LOGGING</span></tt></td>
|
||||
<td>If you define this macro, every peer connection
|
||||
will log its traffic to a log file as well as
|
||||
the session log.</td>
|
||||
</tr>
|
||||
<tr><td><tt class="docutils literal"><span class="pre">TORRENT_STORAGE_DEBUG</span></tt></td>
|
||||
<td>This will enable extra expensive invariant
|
||||
checks in the storage, including logging of
|
||||
piece sorting.</td>
|
||||
</tr>
|
||||
<tr><td><tt class="docutils literal"><span class="pre">TORRENT_UPNP_LOGGING</span></tt></td>
|
||||
<td>Generates a "upnp.log" file with the UPnP
|
||||
traffic. This is very useful when debugging
|
||||
support for various UPnP routers.
|
||||
support for various UPnP routers.</td>
|
||||
</tr>
|
||||
<tr><td><tt class="docutils literal"><span class="pre">TORRENT_DISK_STATS</span></tt></td>
|
||||
<td>This will create a log of all disk activity
|
||||
which later can parsed and graphed using
|
||||
<tt class="docutils literal"><span class="pre">parse_disk_log.py</span></tt>.</td>
|
||||
</tr>
|
||||
<tr><td><tt class="docutils literal"><span class="pre">TORRENT_STATS</span></tt></td>
|
||||
<td>This will generate a log with transfer rates,
|
||||
downloading torrents, seeding torrents, peers,
|
||||
connecting peers and disk buffers in use. The
|
||||
log can be parsed and graphed with
|
||||
<tt class="docutils literal"><span class="pre">parse_session_stats.py</span></tt>.</td>
|
||||
</tr>
|
||||
<tr><td><tt class="docutils literal"><span class="pre">UNICODE</span></tt></td>
|
||||
<td>If building on windows this will make sure the
|
||||
UTF-8 strings in pathnames are converted into
|
||||
UTF-16 before they are passed to the file
|
||||
operations.</td>
|
||||
</tr>
|
||||
<tr><td><tt class="docutils literal"><span class="pre">TORRENT_DISABLE_POOL_ALLOCATOR</span></tt></td>
|
||||
<td>Disables use of <tt class="docutils literal"><span class="pre">boost::pool<></span></tt>.</td>
|
||||
</tr>
|
||||
<tr><td><tt class="docutils literal"><span class="pre">TORRENT_LINKING_SHARED</span></tt></td>
|
||||
<td>If this is defined when including the
|
||||
libtorrent headers, the classes and functions
|
||||
will be tagged with <tt class="docutils literal"><span class="pre">__declspec(dllimport)</span></tt>
|
||||
on msvc and default visibility on GCC 4 and
|
||||
later. Set this in your project if you're
|
||||
linking against libtorrent as a shared library.
|
||||
(This is set by the Jamfile when
|
||||
<tt class="docutils literal"><span class="pre">link=shared</span></tt> is set).</td>
|
||||
</tr>
|
||||
<tr><td><tt class="docutils literal"><span class="pre">TORRENT_BUILDING_SHARED</span></tt></td>
|
||||
<td>If this is defined, the functions and classes
|
||||
in libtorrent are marked with
|
||||
<tt class="docutils literal"><span class="pre">__declspec(dllexport)</span></tt> on msvc, or with
|
||||
default visibility on GCC 4 and later. This
|
||||
should be defined when building libtorrent as
|
||||
a shared library. (This is set by the Jamfile
|
||||
when <tt class="docutils literal"><span class="pre">link=shared</span></tt> is set).</td>
|
||||
</tr>
|
||||
<tr><td><tt class="docutils literal"><span class="pre">TORRENT_DISABLE_DHT</span></tt></td>
|
||||
<td>If this is defined, the support for trackerless
|
||||
torrents will be disabled.</td>
|
||||
</tr>
|
||||
<tr><td><tt class="docutils literal"><span class="pre">TORRENT_DHT_VERBOSE_LOGGING</span></tt></td>
|
||||
<td>This will enable verbose logging of the DHT
|
||||
protocol traffic.</td>
|
||||
</tr>
|
||||
<tr><td><tt class="docutils literal"><span class="pre">TORRENT_DISABLE_ENCRYPTION</span></tt></td>
|
||||
<td>This will disable any encryption support and
|
||||
the dependencies of a crypto library.
|
||||
Encryption support is the peer connection
|
||||
encrypted supported by clients such as
|
||||
uTorrent, Azureus and KTorrent.
|
||||
If this is not defined, either
|
||||
<tt class="docutils literal"><span class="pre">TORRENT_USE_OPENSSL</span></tt> or
|
||||
<tt class="docutils literal"><span class="pre">TORRENT_USE_GCRYPT</span></tt> must be defined.</td>
|
||||
</tr>
|
||||
<tr><td><tt class="docutils literal"><span class="pre">_UNICODE</span></tt></td>
|
||||
<td>On windows, this will cause the file IO
|
||||
use wide character API, to properly support
|
||||
non-ansi characters.</td>
|
||||
</tr>
|
||||
<tr><td><tt class="docutils literal"><span class="pre">TORRENT_DISABLE_RESOLVE_COUNTRIES</span></tt></td>
|
||||
<td>Defining this will disable the ability to
|
||||
resolve countries of origin for peer IPs.</td>
|
||||
</tr>
|
||||
<tr><td><tt class="docutils literal"><span class="pre">TORRENT_DISABLE_INVARIANT_CHECKS</span></tt></td>
|
||||
<td>This will disable internal invariant checks in
|
||||
libtorrent. The invariant checks can sometime
|
||||
be quite expensive, they typically don't scale
|
||||
very well. This option can be used to still
|
||||
build in debug mode, with asserts enabled, but
|
||||
make the resulting executable faster.</td>
|
||||
</tr>
|
||||
<tr><td><tt class="docutils literal"><span class="pre">TORRENT_EXPENSIVE_INVARIANT_CHECKS</span></tt></td>
|
||||
<td>This will enable extra expensive invariant
|
||||
checks. Useful for finding particular bugs
|
||||
or for running before releases.</td>
|
||||
</tr>
|
||||
<tr><td><tt class="docutils literal"><span class="pre">TORRENT_NO_DEPRECATE</span></tt></td>
|
||||
<td>This will exclude all deprecated functions from
|
||||
the header files and cpp files.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p>If you experience that libtorrent uses unreasonable amounts of cpu, it will
|
||||
definitely help to define <tt class="docutils literal"><span class="pre">NDEBUG</span></tt>, since it will remove the invariant checks
|
||||
within the library.</p>
|
||||
</div>
|
||||
<div class="section" id="building-openssl-for-windows">
|
||||
<h2>building openssl for windows</h2>
|
||||
<p>To build openssl for windows with Visual Studio 7.1 (2003) execute the following commands
|
||||
in a command shell:</p>
|
||||
<pre class="literal-block">
|
||||
perl Configure VC-WIN32 --prefix="c:/openssl
|
||||
call ms\do_nasm
|
||||
call "C:\Program Files\Microsoft Visual Studio .NET 2003\vc7\bin\vcvars32.bat"
|
||||
nmake -f ms\nt.mak
|
||||
copy inc32\openssl "C:\Program Files\Microsoft Visual Studio .NET 2003\vc7\include\"
|
||||
copy out32\libeay32.lib "C:\Program Files\Microsoft Visual Studio .NET 2003\vc7\lib"
|
||||
copy out32\ssleay32.lib "C:\Program Files\Microsoft Visual Studio .NET 2003\vc7\lib"
|
||||
</pre>
|
||||
<p>This will also install the headers and library files in the visual studio directories to
|
||||
be picked up by libtorrent.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="footer">
|
||||
<span>Copyright © 2005 Rasterbar Software.</span>
|
||||
</div>
|
||||
</div>
|
||||
<script src="http://www.google-analytics.com/urchin.js" type="text/javascript">
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
_uacct = "UA-1599045-1";
|
||||
urchinTracker();
|
||||
</script>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -1,645 +0,0 @@
|
|||
=================
|
||||
libtorrent manual
|
||||
=================
|
||||
|
||||
:Author: Arvid Norberg, arvid@rasterbar.com
|
||||
:Version: 0.16.0
|
||||
|
||||
.. contents:: Table of contents
|
||||
:depth: 2
|
||||
:backlinks: none
|
||||
|
||||
downloading and building
|
||||
========================
|
||||
|
||||
To acquire the latest version of libtorrent, you'll have to grab it from SVN.
|
||||
You'll find instructions on how to do this here__ (see subversion access).
|
||||
|
||||
__ http://sourceforge.net/svn/?group_id=79942
|
||||
|
||||
The build systems supported "out of the box" in libtorrent are boost-build v2
|
||||
(BBv2) and autotools (for unix-like systems). If you still can't build after
|
||||
following these instructions, you can usually get help in the ``#libtorrent``
|
||||
IRC channel on ``irc.freenode.net``.
|
||||
|
||||
.. warning::
|
||||
|
||||
A common mistake when building and linking against libtorrent is
|
||||
to build with one set of configuration options (#defines) and
|
||||
link against it using a different set of configuration options. Since
|
||||
libtorrent has some code in header files, that code will not be
|
||||
compatible with the built library if they see different configurations.
|
||||
|
||||
Always make sure that the same TORRENT_* macros are defined when you
|
||||
link against libtorrent as when you build it.
|
||||
|
||||
Boost-build supports propagating configuration options to dependencies.
|
||||
When building using the makefiles, this is handled by setting the
|
||||
configuration options in the pkg-config file. Always use pkg-config
|
||||
when linking against libtorrent.
|
||||
|
||||
building from svn
|
||||
-----------------
|
||||
|
||||
To build libtorrent from svn you need to check out the libtorrent sources from
|
||||
sourceforge and also check out the asio sources from its sourceforge cvs.
|
||||
If you downloaded a release tarball, you can skip this section.
|
||||
|
||||
To prepare the directory structure for building, follow these steps:
|
||||
|
||||
* Check out libtorrent (instructions__).
|
||||
* Check out asio (instructions__).
|
||||
* Copy the ``asio/include/asio/`` directory into the ``libtorrent/include/libtorrent/``
|
||||
directory. Alternatively you can make a symbolic link.
|
||||
* Copy ``asio/include/asio.hpp`` into ``libtorrent/include/libtorrent``.
|
||||
|
||||
__ http://sourceforge.net/svn/?group_id=79942
|
||||
__ http://sourceforge.net/cvs/?group_id=122478
|
||||
|
||||
Now the libtorrent directory is ready for building. Follow the steps in one
|
||||
of the following sections depending on which build system you prefer to use.
|
||||
|
||||
building with BBv2
|
||||
------------------
|
||||
|
||||
The primary reason to use boost-build is that it will automatically build the
|
||||
dependent boost libraries with the correct compiler settings, in order to
|
||||
ensure that the build targets are link compatible (see `boost guidelines`__
|
||||
for some details on this issue).
|
||||
|
||||
__ http://boost.org/more/separate_compilation.html
|
||||
|
||||
Since BBv2 will build the boost libraries for you, you need the full boost
|
||||
source package. Having boost installed via some package system is usually not
|
||||
enough (and even if it is enough, the necessary environment variables are
|
||||
usually not set by the package installer).
|
||||
|
||||
If you want to build against an installed copy of boost, you can skip directly
|
||||
to step 3 (assuming you also have boost build installed).
|
||||
|
||||
|
||||
Step 1: Download boost
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
You'll find boost here__.
|
||||
|
||||
__ http://sourceforge.net/project/showfiles.php?group_id=7586&package_id=8041&release_id=619445
|
||||
|
||||
Extract the archive to some directory where you want it. For the sake of this
|
||||
guide, let's assume you extract the package to ``c:\boost_1_34_0`` (I'm using
|
||||
a windows path in this example since if you're on linux/unix you're more likely
|
||||
to use the autotools). You'll need at least version 1.34 of the boost library
|
||||
in order to build libtorrent.
|
||||
|
||||
|
||||
Step 2: Setup BBv2
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
First you need to build ``bjam``. You do this by opening a terminal (In
|
||||
windows, run ``cmd``). Change directory to
|
||||
``c:\boost_1_34_0\tools\jam\src``. Then run the script called
|
||||
``build.bat`` or ``build.sh`` on a unix system. This will build ``bjam`` and
|
||||
place it in a directory starting with ``bin.`` and then have the name of your
|
||||
platform. Copy the ``bjam.exe`` (or ``bjam`` on a unix system) to a place
|
||||
that's in you shell's ``PATH``. On linux systems a place commonly used may be
|
||||
``/usr/local/bin`` or on windows ``c:\windows`` (you can also add directories
|
||||
to the search paths by modifying the environment variable called ``PATH``).
|
||||
|
||||
Now you have ``bjam`` installed. ``bjam`` can be considered an interpreter
|
||||
that the boost-build system is implemented on. So boost-build uses ``bjam``.
|
||||
So, to complete the installation you need to make two more things. You need to
|
||||
set the environment variable ``BOOST_BUILD_PATH``. This is the path that tells
|
||||
``bjam`` where it can find boost-build, your configuration file and all the
|
||||
toolsets (descriptions used by boost-build to know how to use different
|
||||
compilers on different platforms). Assuming the boost install path above, set
|
||||
it to ``c:\boost_1_34_0\tools\build\v2``.
|
||||
|
||||
To set an environment variable in windows, type for example::
|
||||
|
||||
set BOOST_BUILD_PATH=c:\boost_1_34_0\tools\build\v2
|
||||
|
||||
In a terminal window.
|
||||
|
||||
The last thing to do to complete the setup of BBv2 is to modify your
|
||||
``user-config.jam`` file. It is located in ``c:\boost_1_34_0\tools\build\v2``.
|
||||
Depending on your platform and which compiler you're using, you should add a
|
||||
line for each compiler and compiler version you have installed on your system
|
||||
that you want to be able to use with BBv2. For example, if you're using
|
||||
Microsoft Visual Studio 7.1 (2003), just add a line::
|
||||
|
||||
using msvc : 7.1 ;
|
||||
|
||||
If you use GCC, add the line::
|
||||
|
||||
using gcc ;
|
||||
|
||||
If you have more than one version of GCC installed, you can add the
|
||||
commandline used to invoke g++ after the version number, like this::
|
||||
|
||||
using gcc : 3.3 : g++-3.3 ;
|
||||
using gcc : 4.0 : g++-4.0 ;
|
||||
|
||||
Another toolset worth mentioning is the ``darwin`` toolset (For MacOS X).
|
||||
From Tiger (10.4) MacOS X comes with both GCC 3.3 and GCC 4.0. Then you can
|
||||
use the following toolsets::
|
||||
|
||||
using darwin : 3.3 : g++-3.3 ;
|
||||
using darwin : 4.0 : g++-4.0 ;
|
||||
|
||||
Note that the spaces around the semi-colons and colons are important!
|
||||
|
||||
Also see the `official installation instructions`_.
|
||||
|
||||
.. _`official installation instructions`: http://www.boost.org/doc/html/bbv2/installation.html
|
||||
|
||||
|
||||
Step 3: Building libtorrent
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
When building libtorrent, the ``Jamfile`` expects the environment variable
|
||||
``BOOST_ROOT`` to be set to the boost installation directory. It uses this to
|
||||
find the boost libraries it depends on, so they can be built and their headers
|
||||
files found. So, set this to ``c:\boost_1_34_0``. You only need this if you're
|
||||
building against a source distribution of boost.
|
||||
|
||||
Then the only thing left is simply to invoke ``bjam``. If you want to specify
|
||||
a specific toolset to use (compiler) you can just add that to the commandline.
|
||||
For example::
|
||||
|
||||
bjam msvc-7.1 boost=source
|
||||
bjam gcc-3.3 boost=source
|
||||
bjam darwin-4.0 boost=source
|
||||
|
||||
If you're building against a system installed boost, specify ``boost=system``.
|
||||
|
||||
To build different versions you can also just add the name of the build
|
||||
variant. Some default build variants in BBv2 are ``release``, ``debug``,
|
||||
``profile``.
|
||||
|
||||
You can build libtorrent as a dll too, by typing ``link=shared``, or
|
||||
``link=static`` to build a static library.
|
||||
|
||||
If you want to explicitly say how to link against the runtime library, you
|
||||
can set the ``runtime-link`` feature on the commandline, either to ``shared``
|
||||
or ``static``. Most operating systems will only allow linking shared against
|
||||
the runtime, but on windows you can do both. Example::
|
||||
|
||||
bjam msvc-7.1 link=static runtime-link=static boost=source
|
||||
|
||||
.. warning::
|
||||
|
||||
If you link statically to the runtime library, you cannot build libtorrent
|
||||
as a shared library (DLL), since you will get separate heaps in the library
|
||||
and in the client application. It will result in crashes and possibly link
|
||||
errors.
|
||||
|
||||
.. warning::
|
||||
|
||||
With boost-build V2 (Milestone 11), the darwin toolset uses the ``-s`` linker
|
||||
option to strip debug symbols. This option is buggy in Apple's GCC, and
|
||||
will make the executable crash on startup. On Mac OS X, instead build
|
||||
your release executables with the ``debug-symbols=on`` option, and
|
||||
later strip your executable with ``strip``.
|
||||
|
||||
.. warning::
|
||||
|
||||
Some linux systems requires linking against ``librt`` in order to access
|
||||
the POSIX clock functions. If you get an error complaining about a missing
|
||||
symbol ``clock_gettime``, you have to give ``need-librt=yes`` on the
|
||||
bjam command line. This will make libtorrent link against ``librt``.
|
||||
|
||||
.. note::
|
||||
|
||||
When building on Solaris, you might have to specify ``stdlib=sun-stlport``
|
||||
on the bjam command line.
|
||||
|
||||
The build targets are put in a directory called bin, and under it they are
|
||||
sorted in directories depending on the toolset and build variant used.
|
||||
|
||||
To build the examples, just change directory to the examples directory and
|
||||
invoke ``bjam`` from there. To build and run the tests, go to the test
|
||||
directory and run ``bjam``.
|
||||
|
||||
Note that if you're building on windows using the ``msvc`` toolset, you cannot run it
|
||||
from a cygwin terminal, you'll have to run it from a ``cmd`` terminal. The same goes for
|
||||
cygwin, if you're building with gcc in cygwin you'll have to run it from a cygwin terminal.
|
||||
Also, make sure the paths are correct in the different environments. In cygwin, the paths
|
||||
(``BOOST_BUILD_PATH`` and ``BOOST_ROOT``) should be in the typical unix-format (e.g.
|
||||
``/cygdrive/c/boost_1_34_0``). In the windows environment, they should have the typical
|
||||
windows format (``c:/boost_1_34_0``).
|
||||
|
||||
The ``Jamfile`` will define ``NDEBUG`` when it's building a release build.
|
||||
For more build configuration flags see `Build configurations`_.
|
||||
|
||||
Build features:
|
||||
|
||||
+--------------------------+----------------------------------------------------+
|
||||
| boost build feature | values |
|
||||
+==========================+====================================================+
|
||||
| ``boost`` | * ``system`` - default. Tells the Jamfile that |
|
||||
| | boost is installed and should be linked against |
|
||||
| | the system libraries. |
|
||||
| | * ``source`` - Specifies that boost is to be built |
|
||||
| | from source. The environment variable |
|
||||
| | ``BOOST_ROOT`` must be defined to point to the |
|
||||
| | boost directory. |
|
||||
+--------------------------+----------------------------------------------------+
|
||||
| ``boost-link`` | * ``static`` - links statically against the boost |
|
||||
| | libraries. |
|
||||
| | * ``shared`` - links dynamically against the boost |
|
||||
| | libraries. |
|
||||
+--------------------------+----------------------------------------------------+
|
||||
| ``logging`` | * ``none`` - no logging. |
|
||||
| | * ``default`` - basic session logging. |
|
||||
| | * ``verbose`` - verbose peer wire logging. |
|
||||
| | * ``errors`` - like verbose, but limited to errors.|
|
||||
+--------------------------+----------------------------------------------------+
|
||||
| ``dht-support`` | * ``on`` - build with support for tracker less |
|
||||
| | torrents and DHT support. |
|
||||
| | * ``logging`` - build with DHT support and verbose |
|
||||
| | logging of the DHT protocol traffic. |
|
||||
| | * ``off`` - build without DHT support. |
|
||||
+--------------------------+----------------------------------------------------+
|
||||
| ``need-librt`` | * ``no`` - this platform does not need to link |
|
||||
| | against librt to have POSIX time functions. |
|
||||
| | * ``yes`` - specify this if your linux system |
|
||||
| | requires you to link against librt.a. This is |
|
||||
| | typically the case on x86 64 bit systems. |
|
||||
+--------------------------+----------------------------------------------------+
|
||||
| ``asserts`` | * ``on`` - asserts are on if in debug mode |
|
||||
| | * ``off`` - asserts are disabled |
|
||||
| | * ``production`` - assertion failures are logged |
|
||||
| | to ``asserts.log`` in the current working |
|
||||
| | directory, but won't abort the process. |
|
||||
+--------------------------+----------------------------------------------------+
|
||||
| ``geoip`` | * ``off`` - geo ip lookups disabled |
|
||||
| | * ``static`` - MaxMind_ geo ip lookup code linked |
|
||||
| | in statically. Note that this code is under |
|
||||
| | LGPL license. |
|
||||
| | * ``shared`` - The MaxMind_ geo ip lookup library |
|
||||
| | is expected to be installed on the system and |
|
||||
| | it will be used. |
|
||||
+--------------------------+----------------------------------------------------+
|
||||
| ``upnp-logging`` | * ``off`` - default. Does not log UPnP traffic. |
|
||||
| | * ``on`` - creates "upnp.log" with the messages |
|
||||
| | sent to and received from UPnP devices. |
|
||||
+--------------------------+----------------------------------------------------+
|
||||
| ``encryption`` | * ``openssl`` - links against openssl and |
|
||||
| | libcrypto to enable https and encrypted |
|
||||
| | bittorrent connections. |
|
||||
| | * ``gcrypt`` - links against libgcrypt to enable |
|
||||
| | encrypted bittorrent connections. |
|
||||
| | * ``tommath`` - uses a shipped version of |
|
||||
| | libtommath and a custom rc4 implementation |
|
||||
| | (based on libtomcrypt). This is the default |
|
||||
| | option. |
|
||||
| | * ``off`` - turns off support for encrypted |
|
||||
| | connections. The shipped public domain SHA-1 |
|
||||
| | implementation is used. |
|
||||
+--------------------------+----------------------------------------------------+
|
||||
| ``pool-allocators`` | * ``on`` - default, uses pool allocators for send |
|
||||
| | buffers. |
|
||||
| | * ``off`` - uses ``malloc()`` and ``free()`` |
|
||||
| | instead. Might be useful to debug buffer issues |
|
||||
| | with tools like electric fence or libgmalloc. |
|
||||
+--------------------------+----------------------------------------------------+
|
||||
| ``link`` | * ``static`` - builds libtorrent as a static |
|
||||
| | library (.a / .lib) |
|
||||
| | * ``shared`` - builds libtorrent as a shared |
|
||||
| | library (.so / .dll). |
|
||||
+--------------------------+----------------------------------------------------+
|
||||
| ``runtime-link`` | * ``static`` - links statically against the |
|
||||
| | run-time library (if available on your |
|
||||
| | platform). |
|
||||
| | * ``shared`` - link dynamically against the |
|
||||
| | run-time library (default). |
|
||||
+--------------------------+----------------------------------------------------+
|
||||
| ``variant`` | * ``debug`` - builds libtorrent with debug |
|
||||
| | information and invariant checks. |
|
||||
| | * ``release`` - builds libtorrent in release mode |
|
||||
| | without invariant checks and with optimization. |
|
||||
| | * ``profile`` - builds libtorrent with profile |
|
||||
| | information. |
|
||||
+--------------------------+----------------------------------------------------+
|
||||
| ``character-set`` | This setting will only have an affect on windows. |
|
||||
| | Other platforms are expected to support UTF-8. |
|
||||
| | |
|
||||
| | * ``unicode`` - The unicode version of the win32 |
|
||||
| | API is used. This is default. |
|
||||
| | * ``ansi`` - The ansi version of the win32 API is |
|
||||
| | used. |
|
||||
+--------------------------+----------------------------------------------------+
|
||||
| ``invariant-checks`` | This setting only affects debug builds (where |
|
||||
| | ``NDEBUG`` is not defined). It defaults to ``on``. |
|
||||
| | |
|
||||
| | * ``on`` - internal invariant checks are enabled. |
|
||||
| | * ``off`` - internal invariant checks are |
|
||||
| | disabled. The resulting executable will run |
|
||||
| | faster than a regular debug build. |
|
||||
| | * ``full`` - turns on extra expensive invariant |
|
||||
| | checks. |
|
||||
+--------------------------+----------------------------------------------------+
|
||||
| ``debug-symbols`` | * ``on`` - default for debug builds. This setting |
|
||||
| | is useful for building release builds with |
|
||||
| | symbols. |
|
||||
| | * ``off`` - default for release builds. |
|
||||
+--------------------------+----------------------------------------------------+
|
||||
| ``deprecated-functions`` | * ``on`` - default. Includes deprecated functions |
|
||||
| | of the API (might produce warnings during build |
|
||||
| | when deprecated functions are used). |
|
||||
| | * ``off`` - excludes deprecated functions from the |
|
||||
| | API. Generates build errors when deprecated |
|
||||
| | functions are used. |
|
||||
+--------------------------+----------------------------------------------------+
|
||||
| ``full-stats`` | * ``on`` - default, collects stats for IP overhead |
|
||||
| | and DHT and trackers. This uses a little bit |
|
||||
| | extra memory for each peer and torrent. |
|
||||
| | * ``off`` - only collects the standard stats for |
|
||||
| | upload and download rate. |
|
||||
+--------------------------+----------------------------------------------------+
|
||||
|
||||
.. _MaxMind: http://www.maxmind.com/app/api
|
||||
|
||||
The ``variant`` feature is *implicit*, which means you don't need to specify
|
||||
the name of the feature, just the value.
|
||||
|
||||
The logs created when building vlog or log mode are put in a directory called
|
||||
``libtorrent_logs`` in the current working directory.
|
||||
|
||||
When building the example client on windows, you need to build with
|
||||
``link=static`` otherwise you may get unresolved external symbols for some
|
||||
boost.program-options symbols.
|
||||
|
||||
For more information, see the `Boost build v2 documentation`__, or more
|
||||
specifically `the section on builtin features`__.
|
||||
|
||||
__ http://www.boost.org/tools/build/v2/index.html
|
||||
__ http://www.boost.org/doc/html/bbv2/reference.html#bbv2.advanced.builtins.features
|
||||
|
||||
|
||||
building with autotools
|
||||
-----------------------
|
||||
|
||||
First of all, you need to install ``automake`` and ``autoconf``. Many
|
||||
unix/linux systems comes with these preinstalled.
|
||||
|
||||
The prerequisites for building libtorrent are boost.thread, boost.date_time
|
||||
and boost.filesystem. Those are the *compiled* boost libraries needed. The
|
||||
headers-only libraries needed include (but is not necessarily limited to)
|
||||
boost.bind, boost.ref, boost.multi_index, boost.optional, boost.lexical_cast,
|
||||
boost.integer, boost.iterator, boost.tuple, boost.array, boost.function,
|
||||
boost.smart_ptr, boost.preprocessor, boost.static_assert.
|
||||
|
||||
If you want to build the ``client_test`` example, you'll also need boost.regex
|
||||
and boost.program_options.
|
||||
|
||||
Step 1: Generating the build system
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
No build system is present if libtorrent is checked out from CVS - it
|
||||
needs to be generated first. If you're building from a released tarball,
|
||||
you may skip directly to `Step 2: Running configure`_.
|
||||
|
||||
Execute the following commands, in the given order, to generate
|
||||
the build system::
|
||||
|
||||
aclocal -I m4
|
||||
autoheader
|
||||
libtoolize --copy --force
|
||||
automake --add-missing --copy --gnu
|
||||
autoconf
|
||||
|
||||
On darwin/OSX you have to run ``glibtoolize`` instead of ``libtoolize``.
|
||||
|
||||
Step 2: Running configure
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
In your shell, change directory to the libtorrent directory and run
|
||||
``./configure``. This will look for libraries and C++ features that libtorrent
|
||||
is dependent on. If something is missing or can't be found it will print an
|
||||
error telling you what failed.
|
||||
|
||||
The most likely problem you may encounter is that the configure script won't
|
||||
find the boost libraries. Make sure you have boost installed on your system.
|
||||
The easiest way to install boost is usually to use the preferred package
|
||||
system on your platform. Usually libraries and headers are installed in
|
||||
standard directories where the compiler will find them, but sometimes that
|
||||
may not be the case. For example when installing boost on darwin using
|
||||
darwinports (the package system based on BSD ports) all libraries are
|
||||
installed to ``/opt/local/lib`` and headers are installed to
|
||||
``/opt/local/include``. By default the compiler will not look in these
|
||||
directories. You have to set the enviornment variables ``LDFLAGS`` and
|
||||
``CXXFLAGS`` in order to make the compiler find those libs. In this example
|
||||
you'd set them like this::
|
||||
|
||||
export LDFLAGS=-L/opt/local/lib
|
||||
export CXXFLAGS=-I/opt/local/include
|
||||
|
||||
It was observed on FreeBSD (release 6.0) that one needs to add '-lpthread' to
|
||||
LDFLAGS, as Boost::Thread detection will fail without it, even if
|
||||
Boost::Thread is installed.
|
||||
|
||||
If you need to set these variables, it may be a good idea to add those lines
|
||||
to your ``~/.profile`` or ``~/.tcshrc`` depending on your shell.
|
||||
|
||||
If the boost libraries are named with a suffix on your platform, you may use
|
||||
the ``--with-boost-thread=`` option to specify the suffix used for the thread
|
||||
library in this case. For more information about these options, run::
|
||||
|
||||
./configure --help
|
||||
|
||||
On gentoo the boost libraries that are built with multi-threading support have
|
||||
the suffix ``mt``.
|
||||
|
||||
You know that the boost libraries were found if you see the following output
|
||||
from the configure script::
|
||||
|
||||
checking whether the Boost::DateTime library is available... yes
|
||||
checking for main in -lboost_date_time... yes
|
||||
checking whether the Boost::Filesystem library is available... yes
|
||||
checking for main in -lboost_filesystem... yes
|
||||
checking whether the Boost::Thread library is available... yes
|
||||
checking for main in -lboost_thread... yes
|
||||
|
||||
Another possible source of problems may be if the path to your libtorrent
|
||||
directory contains spaces. Make sure you either rename the directories with
|
||||
spaces in their names to remove the spaces or move the libtorrent directory.
|
||||
|
||||
Creating a debug build
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
To tell configure to build a debug version (with debug info, asserts
|
||||
and invariant checks enabled), you have to run the configure script
|
||||
with the following option::
|
||||
|
||||
./configure --enable-debug=yes
|
||||
|
||||
Creating a release build
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
To tell the configure to build a release version (without debug info,
|
||||
asserts and invariant checks), you have to run the configure script
|
||||
with the following option::
|
||||
|
||||
./configure --enable-debug=no
|
||||
|
||||
The above option make use of -DNDEBUG, which is used throughout libtorrent.
|
||||
|
||||
Step 3: Building libtorrent
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Once the configure script is run successfully, you just type ``make`` and
|
||||
libtorrent, the examples and the tests will be built.
|
||||
|
||||
When libtorrent is built it may be a good idea to run the tests, you do this
|
||||
by running ``make check``.
|
||||
|
||||
If you want to build a release version (without debug info, asserts and
|
||||
invariant checks), you have to rerun the configure script and rebuild, like this::
|
||||
|
||||
./configure --disable-debug
|
||||
make clean
|
||||
make
|
||||
|
||||
building with other build systems
|
||||
---------------------------------
|
||||
|
||||
If you're building in MS Visual Studio, you may have to set the compiler
|
||||
options "force conformance in for loop scope", "treat wchar_t as built-in
|
||||
type" and "Enable Run-Time Type Info" to Yes.
|
||||
|
||||
build configurations
|
||||
--------------------
|
||||
|
||||
By default libtorrent is built In debug mode, and will have pretty expensive
|
||||
invariant checks and asserts built into it. If you want to disable such checks
|
||||
(you want to do that in a release build) you can see the table below for which
|
||||
defines you can use to control the build.
|
||||
|
||||
+----------------------------------------+-------------------------------------------------+
|
||||
| macro | description |
|
||||
+========================================+=================================================+
|
||||
| ``NDEBUG`` | If you define this macro, all asserts, |
|
||||
| | invariant checks and general debug code will be |
|
||||
| | removed. Since there is quite a lot of code in |
|
||||
| | in header files in libtorrent, it may be |
|
||||
| | important to define the symbol consistently |
|
||||
| | across compilation units, including the clients |
|
||||
| | files. Potential problems is different |
|
||||
| | compilation units having different views of |
|
||||
| | structs and class layouts and sizes. |
|
||||
+----------------------------------------+-------------------------------------------------+
|
||||
| ``TORRENT_LOGGING`` | This macro will enable logging of the session |
|
||||
| | events, such as tracker announces and incoming |
|
||||
| | connections (as well as blocked connections). |
|
||||
+----------------------------------------+-------------------------------------------------+
|
||||
| ``TORRENT_DISABLE_GEO_IP`` | This is defined by default by the Jamfile. It |
|
||||
| | disables the GeoIP features, and avoids linking |
|
||||
| | against LGPL:ed code. |
|
||||
+----------------------------------------+-------------------------------------------------+
|
||||
| ``TORRENT_VERBOSE_LOGGING`` | If you define this macro, every peer connection |
|
||||
| | will log its traffic to a log file as well as |
|
||||
| | the session log. |
|
||||
+----------------------------------------+-------------------------------------------------+
|
||||
| ``TORRENT_STORAGE_DEBUG`` | This will enable extra expensive invariant |
|
||||
| | checks in the storage, including logging of |
|
||||
| | piece sorting. |
|
||||
+----------------------------------------+-------------------------------------------------+
|
||||
| ``TORRENT_UPNP_LOGGING`` | Generates a "upnp.log" file with the UPnP |
|
||||
| | traffic. This is very useful when debugging |
|
||||
| | support for various UPnP routers. |
|
||||
| | support for various UPnP routers. |
|
||||
+----------------------------------------+-------------------------------------------------+
|
||||
| ``TORRENT_DISK_STATS`` | This will create a log of all disk activity |
|
||||
| | which later can parsed and graphed using |
|
||||
| | ``parse_disk_log.py``. |
|
||||
+----------------------------------------+-------------------------------------------------+
|
||||
| ``TORRENT_STATS`` | This will generate a log with transfer rates, |
|
||||
| | downloading torrents, seeding torrents, peers, |
|
||||
| | connecting peers and disk buffers in use. The |
|
||||
| | log can be parsed and graphed with |
|
||||
| | ``parse_session_stats.py``. |
|
||||
+----------------------------------------+-------------------------------------------------+
|
||||
| ``UNICODE`` | If building on windows this will make sure the |
|
||||
| | UTF-8 strings in pathnames are converted into |
|
||||
| | UTF-16 before they are passed to the file |
|
||||
| | operations. |
|
||||
+----------------------------------------+-------------------------------------------------+
|
||||
| ``TORRENT_DISABLE_POOL_ALLOCATOR`` | Disables use of ``boost::pool<>``. |
|
||||
+----------------------------------------+-------------------------------------------------+
|
||||
| ``TORRENT_LINKING_SHARED`` | If this is defined when including the |
|
||||
| | libtorrent headers, the classes and functions |
|
||||
| | will be tagged with ``__declspec(dllimport)`` |
|
||||
| | on msvc and default visibility on GCC 4 and |
|
||||
| | later. Set this in your project if you're |
|
||||
| | linking against libtorrent as a shared library. |
|
||||
| | (This is set by the Jamfile when |
|
||||
| | ``link=shared`` is set). |
|
||||
+----------------------------------------+-------------------------------------------------+
|
||||
| ``TORRENT_BUILDING_SHARED`` | If this is defined, the functions and classes |
|
||||
| | in libtorrent are marked with |
|
||||
| | ``__declspec(dllexport)`` on msvc, or with |
|
||||
| | default visibility on GCC 4 and later. This |
|
||||
| | should be defined when building libtorrent as |
|
||||
| | a shared library. (This is set by the Jamfile |
|
||||
| | when ``link=shared`` is set). |
|
||||
+----------------------------------------+-------------------------------------------------+
|
||||
| ``TORRENT_DISABLE_DHT`` | If this is defined, the support for trackerless |
|
||||
| | torrents will be disabled. |
|
||||
+----------------------------------------+-------------------------------------------------+
|
||||
| ``TORRENT_DHT_VERBOSE_LOGGING`` | This will enable verbose logging of the DHT |
|
||||
| | protocol traffic. |
|
||||
+----------------------------------------+-------------------------------------------------+
|
||||
| ``TORRENT_DISABLE_ENCRYPTION`` | This will disable any encryption support and |
|
||||
| | the dependencies of a crypto library. |
|
||||
| | Encryption support is the peer connection |
|
||||
| | encrypted supported by clients such as |
|
||||
| | uTorrent, Azureus and KTorrent. |
|
||||
| | If this is not defined, either |
|
||||
| | ``TORRENT_USE_OPENSSL`` or |
|
||||
| | ``TORRENT_USE_GCRYPT`` must be defined. |
|
||||
+----------------------------------------+-------------------------------------------------+
|
||||
| ``_UNICODE`` | On windows, this will cause the file IO |
|
||||
| | use wide character API, to properly support |
|
||||
| | non-ansi characters. |
|
||||
+----------------------------------------+-------------------------------------------------+
|
||||
| ``TORRENT_DISABLE_RESOLVE_COUNTRIES`` | Defining this will disable the ability to |
|
||||
| | resolve countries of origin for peer IPs. |
|
||||
+----------------------------------------+-------------------------------------------------+
|
||||
| ``TORRENT_DISABLE_INVARIANT_CHECKS`` | This will disable internal invariant checks in |
|
||||
| | libtorrent. The invariant checks can sometime |
|
||||
| | be quite expensive, they typically don't scale |
|
||||
| | very well. This option can be used to still |
|
||||
| | build in debug mode, with asserts enabled, but |
|
||||
| | make the resulting executable faster. |
|
||||
+----------------------------------------+-------------------------------------------------+
|
||||
| ``TORRENT_EXPENSIVE_INVARIANT_CHECKS`` | This will enable extra expensive invariant |
|
||||
| | checks. Useful for finding particular bugs |
|
||||
| | or for running before releases. |
|
||||
+----------------------------------------+-------------------------------------------------+
|
||||
| ``TORRENT_NO_DEPRECATE`` | This will exclude all deprecated functions from |
|
||||
| | the header files and cpp files. |
|
||||
+----------------------------------------+-------------------------------------------------+
|
||||
|
||||
|
||||
If you experience that libtorrent uses unreasonable amounts of cpu, it will
|
||||
definitely help to define ``NDEBUG``, since it will remove the invariant checks
|
||||
within the library.
|
||||
|
||||
building openssl for windows
|
||||
----------------------------
|
||||
|
||||
To build openssl for windows with Visual Studio 7.1 (2003) execute the following commands
|
||||
in a command shell::
|
||||
|
||||
perl Configure VC-WIN32 --prefix="c:/openssl
|
||||
call ms\do_nasm
|
||||
call "C:\Program Files\Microsoft Visual Studio .NET 2003\vc7\bin\vcvars32.bat"
|
||||
nmake -f ms\nt.mak
|
||||
copy inc32\openssl "C:\Program Files\Microsoft Visual Studio .NET 2003\vc7\include\"
|
||||
copy out32\libeay32.lib "C:\Program Files\Microsoft Visual Studio .NET 2003\vc7\lib"
|
||||
copy out32\ssleay32.lib "C:\Program Files\Microsoft Visual Studio .NET 2003\vc7\lib"
|
||||
|
||||
This will also install the headers and library files in the visual studio directories to
|
||||
be picked up by libtorrent.
|
||||
|
|
@ -1,86 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta name="generator" content="Docutils 0.5: http://docutils.sourceforge.net/" />
|
||||
<title>client_test example program</title>
|
||||
<link rel="stylesheet" type="text/css" href="../../css/base.css" />
|
||||
<link rel="stylesheet" type="text/css" href="../../css/rst.css" />
|
||||
<link rel="stylesheet" href="style.css" type="text/css" />
|
||||
<style type="text/css">
|
||||
/* Hides from IE-mac \*/
|
||||
* html pre { height: 1%; }
|
||||
/* End hide from IE-mac */
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="document" id="client-test-example-program">
|
||||
<div id="container">
|
||||
<div id="headerNav">
|
||||
<ul>
|
||||
<li class="first"><a href="/">Home</a></li>
|
||||
<li><a href="../../products.html">Products</a></li>
|
||||
<li><a href="../../contact.html">Contact</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="header">
|
||||
<h1><span>Rasterbar Software</span></h1>
|
||||
<h2><span>Software developement and consulting</span></h2>
|
||||
</div>
|
||||
<div id="main">
|
||||
<h1 class="title">client_test example program</h1>
|
||||
|
||||
<p>Client test is a, more or less, complete bittorrent client. It lacks most
|
||||
settings and you can't start or stop torrents once you've started it. All
|
||||
the settings are hardcoded. The commandline arguments are:</p>
|
||||
<pre class="literal-block">
|
||||
client_test <filename1.torrent> <filename2.torrent> ...
|
||||
</pre>
|
||||
<p>You can start any number of torrent downloads/seeds via the commandline.
|
||||
If one argument starts with <tt class="docutils literal"><span class="pre">http://</span></tt> it is interpreted as a tracker
|
||||
announce url, and it expects an info-hash as the next argument. The info-hash
|
||||
has to be hex-encoded. For example: <tt class="docutils literal"><span class="pre">2410d4554d5ed856d69f426c38791673c59f4418</span></tt>.
|
||||
If you pass an announce url and info-hash, a torrent-less download is started.
|
||||
It relies on that at least one peer on the tracker is running a libtorrent based
|
||||
client and has the metadata (.torrent file). The metadata extension in
|
||||
libtorrent will then download it from that peer (or from those peers if more
|
||||
than one).</p>
|
||||
<p>While running, the <tt class="docutils literal"><span class="pre">client_test</span></tt> sample will look something like this:</p>
|
||||
<img alt="client_test.png" src="client_test.png" />
|
||||
<p>The commands available in the client are:</p>
|
||||
<ul class="simple">
|
||||
<li><tt class="docutils literal"><span class="pre">q</span></tt> quits the client (there will be a delay while the client waits
|
||||
for tracker responses)</li>
|
||||
<li><tt class="docutils literal"><span class="pre">l</span></tt> toggle log. Will display the log at the bottom, informing about
|
||||
tracker and peer events.</li>
|
||||
<li><tt class="docutils literal"><span class="pre">i</span></tt> toggles torrent info. Will show the peer list for each torrent.</li>
|
||||
<li><tt class="docutils literal"><span class="pre">d</span></tt> toggle download info. Will show the block list for each torrent,
|
||||
showing downloaded and requested blocks.</li>
|
||||
<li><tt class="docutils literal"><span class="pre">p</span></tt> pause all torrents.</li>
|
||||
<li><tt class="docutils literal"><span class="pre">u</span></tt> unpause all torrents.</li>
|
||||
<li><tt class="docutils literal"><span class="pre">r</span></tt> force tracker reannounce for all torrents.</li>
|
||||
<li><tt class="docutils literal"><span class="pre">f</span></tt> toggle show file progress. Displays a list of all files and the
|
||||
download progress for each file.</li>
|
||||
</ul>
|
||||
<p>The list at the bottom (shown if you press <tt class="docutils literal"><span class="pre">d</span></tt>) shows which blocks has
|
||||
been requested from which peer. The green background means that it has been
|
||||
downloaded. It shows that fast peers will prefer to request whole pieces
|
||||
instead of dowloading parts of pieces. It may make it easier to determine
|
||||
which peer that sent the corrupt data if a piece fails the hash test.</p>
|
||||
<img alt="unicode_support.png" src="unicode_support.png" />
|
||||
<p>There's unicode support on linux, MacOS X and Windows.</p>
|
||||
</div>
|
||||
<div id="footer">
|
||||
<span>Copyright © 2005 Rasterbar Software.</span>
|
||||
</div>
|
||||
</div>
|
||||
<script src="http://www.google-analytics.com/urchin.js" type="text/javascript">
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
_uacct = "UA-1599045-1";
|
||||
urchinTracker();
|
||||
</script>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
Before Width: | Height: | Size: 108 KiB |
|
@ -1,50 +0,0 @@
|
|||
===========================
|
||||
client_test example program
|
||||
===========================
|
||||
|
||||
Client test is a, more or less, complete bittorrent client. It lacks most
|
||||
settings and you can't start or stop torrents once you've started it. All
|
||||
the settings are hardcoded. The commandline arguments are::
|
||||
|
||||
client_test <filename1.torrent> <filename2.torrent> ...
|
||||
|
||||
You can start any number of torrent downloads/seeds via the commandline.
|
||||
If one argument starts with ``http://`` it is interpreted as a tracker
|
||||
announce url, and it expects an info-hash as the next argument. The info-hash
|
||||
has to be hex-encoded. For example: ``2410d4554d5ed856d69f426c38791673c59f4418``.
|
||||
If you pass an announce url and info-hash, a torrent-less download is started.
|
||||
It relies on that at least one peer on the tracker is running a libtorrent based
|
||||
client and has the metadata (.torrent file). The metadata extension in
|
||||
libtorrent will then download it from that peer (or from those peers if more
|
||||
than one).
|
||||
|
||||
While running, the ``client_test`` sample will look something like this:
|
||||
|
||||
.. image:: client_test.png
|
||||
|
||||
The commands available in the client are:
|
||||
|
||||
* ``q`` quits the client (there will be a delay while the client waits
|
||||
for tracker responses)
|
||||
* ``l`` toggle log. Will display the log at the bottom, informing about
|
||||
tracker and peer events.
|
||||
* ``i`` toggles torrent info. Will show the peer list for each torrent.
|
||||
* ``d`` toggle download info. Will show the block list for each torrent,
|
||||
showing downloaded and requested blocks.
|
||||
* ``p`` pause all torrents.
|
||||
* ``u`` unpause all torrents.
|
||||
* ``r`` force tracker reannounce for all torrents.
|
||||
* ``f`` toggle show file progress. Displays a list of all files and the
|
||||
download progress for each file.
|
||||
|
||||
The list at the bottom (shown if you press ``d``) shows which blocks has
|
||||
been requested from which peer. The green background means that it has been
|
||||
downloaded. It shows that fast peers will prefer to request whole pieces
|
||||
instead of dowloading parts of pieces. It may make it easier to determine
|
||||
which peer that sent the corrupt data if a piece fails the hash test.
|
||||
|
||||
.. image:: unicode_support.png
|
||||
|
||||
There's unicode support on linux, MacOS X and Windows.
|
||||
|
||||
|
|
@ -1,103 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta name="generator" content="Docutils 0.5: http://docutils.sourceforge.net/" />
|
||||
<title>libtorrent manual</title>
|
||||
<meta name="author" content="Arvid Norberg, arvid@rasterbar.com" />
|
||||
<link rel="stylesheet" type="text/css" href="../../css/base.css" />
|
||||
<link rel="stylesheet" type="text/css" href="../../css/rst.css" />
|
||||
<link rel="stylesheet" href="style.css" type="text/css" />
|
||||
<style type="text/css">
|
||||
/* Hides from IE-mac \*/
|
||||
* html pre { height: 1%; }
|
||||
/* End hide from IE-mac */
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="document" id="libtorrent-manual">
|
||||
<div id="container">
|
||||
<div id="headerNav">
|
||||
<ul>
|
||||
<li class="first"><a href="/">Home</a></li>
|
||||
<li><a href="../../products.html">Products</a></li>
|
||||
<li><a href="../../contact.html">Contact</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="header">
|
||||
<h1><span>Rasterbar Software</span></h1>
|
||||
<h2><span>Software developement and consulting</span></h2>
|
||||
</div>
|
||||
<div id="main">
|
||||
<h1 class="title">libtorrent manual</h1>
|
||||
<table class="docinfo" frame="void" rules="none">
|
||||
<col class="docinfo-name" />
|
||||
<col class="docinfo-content" />
|
||||
<tbody valign="top">
|
||||
<tr><th class="docinfo-name">Author:</th>
|
||||
<td>Arvid Norberg, <a class="last reference external" href="mailto:arvid@rasterbar.com">arvid@rasterbar.com</a></td></tr>
|
||||
<tr><th class="docinfo-name">Version:</th>
|
||||
<td>0.16.0</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="contents topic" id="table-of-contents">
|
||||
<p class="topic-title first">Table of contents</p>
|
||||
<ul class="simple">
|
||||
<li><a class="reference internal" href="#contributing-to-libtorrent" id="id1">contributing to libtorrent</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="section" id="contributing-to-libtorrent">
|
||||
<h1>contributing to libtorrent</h1>
|
||||
<p>There are several ways to contribute to libtorrent at various levels. Any help is
|
||||
much appreciated. If you're interested in something libtorrent related that's not
|
||||
enumerated on this page, please contact <a class="reference external" href="mailto:arvid@rasterbar.com">arvid@rasterbar.com</a> or the <a class="reference external" href="http://lists.sourceforge.net/lists/listinfo/libtorrent-discuss">mailing list</a>.</p>
|
||||
<ol class="arabic">
|
||||
<li><dl class="first docutils">
|
||||
<dt>Testing</dt>
|
||||
<dd><p class="first">This is not just limited to finding bugs and ways to reproduce crashes, but also
|
||||
sub-optimal behavior is certain scenarios and finding ways to reproduce those. Please
|
||||
report any issue to the bug tracker at <a class="reference external" href="http://code.google.com/p/libtorrent/issues/entry">google code</a>.</p>
|
||||
<p class="last">New features that need testing are streaming (<tt class="docutils literal"><span class="pre">set_piece_deadline()</span></tt>), the different
|
||||
choking algorithms (especially the new BitTyrant choker), the disk cache options (such
|
||||
as <tt class="docutils literal"><span class="pre">explicit_cache</span></tt>).</p>
|
||||
</dd>
|
||||
</dl>
|
||||
</li>
|
||||
</ol>
|
||||
<ol class="arabic" start="2">
|
||||
<li><dl class="first docutils">
|
||||
<dt>Documentation</dt>
|
||||
<dd><p class="first last">Finding typos or outdated sections in the documentation. Contributing documentation
|
||||
based on your own experience and experimentation with the library or with BitTorrent
|
||||
in general. Non-reference documentation is very much welcome as well, higher level
|
||||
descriptions on how to configure libtorrent for various situations for instance.</p>
|
||||
</dd>
|
||||
</dl>
|
||||
</li>
|
||||
<li><dl class="first docutils">
|
||||
<dt>Code</dt>
|
||||
<dd><p class="first">Contributing code for new features or bug-fixes is highly welcome. If you're interested
|
||||
in adding a feature but not sure where to start, please contact the <a class="reference external" href="http://lists.sourceforge.net/lists/listinfo/libtorrent-discuss">mailing list</a> or
|
||||
<tt class="docutils literal"><span class="pre">#libtorrent</span></tt> @ <tt class="docutils literal"><span class="pre">irc.freenode.net</span></tt>.</p>
|
||||
<p class="last">New features might be better support for integrating with other services, new choking
|
||||
algorithms, seeding policies, ports to new platforms etc.</p>
|
||||
</dd>
|
||||
</dl>
|
||||
</li>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
<div id="footer">
|
||||
<span>Copyright © 2005 Rasterbar Software.</span>
|
||||
</div>
|
||||
</div>
|
||||
<script src="http://www.google-analytics.com/urchin.js" type="text/javascript">
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
_uacct = "UA-1599045-1";
|
||||
urchinTracker();
|
||||
</script>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -1,45 +0,0 @@
|
|||
=================
|
||||
libtorrent manual
|
||||
=================
|
||||
|
||||
:Author: Arvid Norberg, arvid@rasterbar.com
|
||||
:Version: 0.16.0
|
||||
|
||||
.. contents:: Table of contents
|
||||
:depth: 2
|
||||
:backlinks: none
|
||||
|
||||
contributing to libtorrent
|
||||
==========================
|
||||
|
||||
There are several ways to contribute to libtorrent at various levels. Any help is
|
||||
much appreciated. If you're interested in something libtorrent related that's not
|
||||
enumerated on this page, please contact arvid@rasterbar.com or the `mailing list`_.
|
||||
|
||||
.. _`mailing list`: http://lists.sourceforge.net/lists/listinfo/libtorrent-discuss
|
||||
|
||||
1. Testing
|
||||
This is not just limited to finding bugs and ways to reproduce crashes, but also
|
||||
sub-optimal behavior is certain scenarios and finding ways to reproduce those. Please
|
||||
report any issue to the bug tracker at `google code`_.
|
||||
|
||||
New features that need testing are streaming (``set_piece_deadline()``), the different
|
||||
choking algorithms (especially the new BitTyrant choker), the disk cache options (such
|
||||
as ``explicit_cache``).
|
||||
|
||||
.. _`google code`: http://code.google.com/p/libtorrent/issues/entry
|
||||
|
||||
2. Documentation
|
||||
Finding typos or outdated sections in the documentation. Contributing documentation
|
||||
based on your own experience and experimentation with the library or with BitTorrent
|
||||
in general. Non-reference documentation is very much welcome as well, higher level
|
||||
descriptions on how to configure libtorrent for various situations for instance.
|
||||
|
||||
3. Code
|
||||
Contributing code for new features or bug-fixes is highly welcome. If you're interested
|
||||
in adding a feature but not sure where to start, please contact the `mailing list`_ or
|
||||
``#libtorrent`` @ ``irc.freenode.net``.
|
||||
|
||||
New features might be better support for integrating with other services, new choking
|
||||
algorithms, seeding policies, ports to new platforms etc.
|
||||
|
Before Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 36 KiB |
|
@ -1,111 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta name="generator" content="Docutils 0.5: http://docutils.sourceforge.net/" />
|
||||
<title></title>
|
||||
<meta name="author" content="Arvid Norberg, arvid@rasterbar.com" />
|
||||
<link rel="stylesheet" type="text/css" href="../../css/base.css" />
|
||||
<link rel="stylesheet" type="text/css" href="../../css/rst.css" />
|
||||
<link rel="stylesheet" href="style.css" type="text/css" />
|
||||
<style type="text/css">
|
||||
/* Hides from IE-mac \*/
|
||||
* html pre { height: 1%; }
|
||||
/* End hide from IE-mac */
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="document">
|
||||
<div id="container">
|
||||
<div id="headerNav">
|
||||
<ul>
|
||||
<li class="first"><a href="/">Home</a></li>
|
||||
<li><a href="../../products.html">Products</a></li>
|
||||
<li><a href="../../contact.html">Contact</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="header">
|
||||
<h1><span>Rasterbar Software</span></h1>
|
||||
<h2><span>Software developement and consulting</span></h2>
|
||||
</div>
|
||||
<div id="main">
|
||||
|
||||
<table class="docinfo" frame="void" rules="none">
|
||||
<col class="docinfo-name" />
|
||||
<col class="docinfo-content" />
|
||||
<tbody valign="top">
|
||||
<tr><th class="docinfo-name">Author:</th>
|
||||
<td>Arvid Norberg, <a class="last reference external" href="mailto:arvid@rasterbar.com">arvid@rasterbar.com</a></td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="section" id="mainline-dht-extensions">
|
||||
<h1>Mainline DHT extensions</h1>
|
||||
<p>libtorrent implements a few extensions to the Mainline DHT protocol.</p>
|
||||
<div class="section" id="get-peers-response">
|
||||
<h2>get_peers response</h2>
|
||||
<p>libtorrent always responds with <tt class="docutils literal"><span class="pre">nodes</span></tt> to a get_peers request. If it has
|
||||
peers for the specified info-hash, it will return <tt class="docutils literal"><span class="pre">values</span></tt> as well. This is
|
||||
because just because some peer announced to us, doesn't mean that we are
|
||||
among the 8 closest nodes of the info hash. libtorrent also keeps traversing
|
||||
nodes using get_peers until it has found the 8 closest ones, and then announces
|
||||
to those nodes.</p>
|
||||
</div>
|
||||
<div class="section" id="client-identification">
|
||||
<h2>client identification</h2>
|
||||
<p>In each DHT packet, an extra key is inserted named "v". This is a string
|
||||
describing the client and version used. This can help alot when debugging
|
||||
and finding errors in client implementations. The string is encoded as four
|
||||
characters, two characters describing the client and two characters interpreted
|
||||
as a binary number describing the client version.</p>
|
||||
<p>Currently known clients:</p>
|
||||
<table border="1" class="docutils">
|
||||
<colgroup>
|
||||
<col width="65%" />
|
||||
<col width="35%" />
|
||||
</colgroup>
|
||||
<tbody valign="top">
|
||||
<tr><td>uTorrent</td>
|
||||
<td><tt class="docutils literal"><span class="pre">UT</span></tt></td>
|
||||
</tr>
|
||||
<tr><td>libtorrent</td>
|
||||
<td><tt class="docutils literal"><span class="pre">LT</span></tt></td>
|
||||
</tr>
|
||||
<tr><td>MooPolice</td>
|
||||
<td><tt class="docutils literal"><span class="pre">MP</span></tt></td>
|
||||
</tr>
|
||||
<tr><td>GetRight</td>
|
||||
<td><tt class="docutils literal"><span class="pre">GR</span></tt></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="section" id="ipv6-support">
|
||||
<h2>IPv6 support</h2>
|
||||
<p>The DHT messages that don't support IPv6 are the <tt class="docutils literal"><span class="pre">nodes</span></tt> replies.
|
||||
They encode all the contacts as 6 bytes packed together in sequence in a
|
||||
string. The problem is that IPv6 endpoints cannot be encoded as 6 bytes, but
|
||||
needs 18 bytes. The extension libtorrent applies is to add another key, called
|
||||
<tt class="docutils literal"><span class="pre">nodes2</span></tt>.</p>
|
||||
<p><tt class="docutils literal"><span class="pre">nodes2</span></tt> may be present in replies that contains a <tt class="docutils literal"><span class="pre">nodes</span></tt> key. It is encoded
|
||||
as a list of strings. Each string represents one contact and is encoded as 20
|
||||
bytes node-id and then a variable length encoded IP address (6 bytes in IPv4 case
|
||||
and 18 bytes in IPv6 case).</p>
|
||||
<p>As an optimization, libtorrent does not include the extra key in case there are
|
||||
only IPv4 nodes present.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="footer">
|
||||
<span>Copyright © 2005 Rasterbar Software.</span>
|
||||
</div>
|
||||
</div>
|
||||
<script src="http://www.google-analytics.com/urchin.js" type="text/javascript">
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
_uacct = "UA-1599045-1";
|
||||
urchinTracker();
|
||||
</script>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -1,55 +0,0 @@
|
|||
:Author: Arvid Norberg, arvid@rasterbar.com
|
||||
|
||||
Mainline DHT extensions
|
||||
=======================
|
||||
|
||||
libtorrent implements a few extensions to the Mainline DHT protocol.
|
||||
|
||||
get_peers response
|
||||
------------------
|
||||
|
||||
libtorrent always responds with ``nodes`` to a get_peers request. If it has
|
||||
peers for the specified info-hash, it will return ``values`` as well. This is
|
||||
because just because some peer announced to us, doesn't mean that we are
|
||||
among the 8 closest nodes of the info hash. libtorrent also keeps traversing
|
||||
nodes using get_peers until it has found the 8 closest ones, and then announces
|
||||
to those nodes.
|
||||
|
||||
client identification
|
||||
---------------------
|
||||
|
||||
In each DHT packet, an extra key is inserted named "v". This is a string
|
||||
describing the client and version used. This can help alot when debugging
|
||||
and finding errors in client implementations. The string is encoded as four
|
||||
characters, two characters describing the client and two characters interpreted
|
||||
as a binary number describing the client version.
|
||||
|
||||
Currently known clients:
|
||||
|
||||
+---------------+--------+
|
||||
| uTorrent | ``UT`` |
|
||||
+---------------+--------+
|
||||
| libtorrent | ``LT`` |
|
||||
+---------------+--------+
|
||||
| MooPolice | ``MP`` |
|
||||
+---------------+--------+
|
||||
| GetRight | ``GR`` |
|
||||
+---------------+--------+
|
||||
|
||||
IPv6 support
|
||||
------------
|
||||
|
||||
The DHT messages that don't support IPv6 are the ``nodes`` replies.
|
||||
They encode all the contacts as 6 bytes packed together in sequence in a
|
||||
string. The problem is that IPv6 endpoints cannot be encoded as 6 bytes, but
|
||||
needs 18 bytes. The extension libtorrent applies is to add another key, called
|
||||
``nodes2``.
|
||||
|
||||
``nodes2`` may be present in replies that contains a ``nodes`` key. It is encoded
|
||||
as a list of strings. Each string represents one contact and is encoded as 20
|
||||
bytes node-id and then a variable length encoded IP address (6 bytes in IPv4 case
|
||||
and 18 bytes in IPv6 case).
|
||||
|
||||
As an optimization, libtorrent does not include the extra key in case there are
|
||||
only IPv4 nodes present.
|
||||
|
Before Width: | Height: | Size: 3.0 KiB |
Before Width: | Height: | Size: 5.6 KiB |
Before Width: | Height: | Size: 5.2 KiB |
Before Width: | Height: | Size: 5.0 KiB |
Before Width: | Height: | Size: 4.7 KiB |
Before Width: | Height: | Size: 5.2 KiB |
Before Width: | Height: | Size: 4.3 KiB |
Before Width: | Height: | Size: 6.7 KiB |
|
@ -1,313 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta name="generator" content="Docutils 0.5: http://docutils.sourceforge.net/" />
|
||||
<title>libtorrent Examples</title>
|
||||
<meta name="author" content="Arvid Norberg, arvid@rasterbar.com" />
|
||||
<link rel="stylesheet" type="text/css" href="../../css/base.css" />
|
||||
<link rel="stylesheet" type="text/css" href="../../css/rst.css" />
|
||||
<link rel="stylesheet" href="style.css" type="text/css" />
|
||||
<style type="text/css">
|
||||
/* Hides from IE-mac \*/
|
||||
* html pre { height: 1%; }
|
||||
/* End hide from IE-mac */
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="document" id="libtorrent-examples">
|
||||
<div id="container">
|
||||
<div id="headerNav">
|
||||
<ul>
|
||||
<li class="first"><a href="/">Home</a></li>
|
||||
<li><a href="../../products.html">Products</a></li>
|
||||
<li><a href="../../contact.html">Contact</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="header">
|
||||
<h1><span>Rasterbar Software</span></h1>
|
||||
<h2><span>Software developement and consulting</span></h2>
|
||||
</div>
|
||||
<div id="main">
|
||||
<h1 class="title">libtorrent Examples</h1>
|
||||
<table class="docinfo" frame="void" rules="none">
|
||||
<col class="docinfo-name" />
|
||||
<col class="docinfo-content" />
|
||||
<tbody valign="top">
|
||||
<tr><th class="docinfo-name">Author:</th>
|
||||
<td>Arvid Norberg, <a class="last reference external" href="mailto:arvid@rasterbar.com">arvid@rasterbar.com</a></td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="contents topic" id="table-of-contents">
|
||||
<p class="topic-title first">Table of contents</p>
|
||||
<ul class="simple">
|
||||
<li><a class="reference internal" href="#examples" id="id2">examples</a><ul>
|
||||
<li><a class="reference internal" href="#dump-torrent" id="id3">dump_torrent</a></li>
|
||||
<li><a class="reference internal" href="#simple-client" id="id4">simple client</a></li>
|
||||
<li><a class="reference internal" href="#make-torrent" id="id5">make_torrent</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="section" id="examples">
|
||||
<h1>examples</h1>
|
||||
<p>Except for the example programs in this manual, there's also a bigger example
|
||||
of a (little bit) more complete client, <tt class="docutils literal"><span class="pre">client_test</span></tt>. There are separate
|
||||
instructions for how to use it <a class="reference external" href="client_test.html">here</a> if you'd like to try it. Note that building
|
||||
<tt class="docutils literal"><span class="pre">client_test</span></tt> also requires boost.regex and boost.program_options library.</p>
|
||||
<div class="section" id="dump-torrent">
|
||||
<h2>dump_torrent</h2>
|
||||
<p>This is an example of a program that will take a torrent-file as a parameter and
|
||||
print information about it to std out:</p>
|
||||
<pre class="literal-block">
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <iterator>
|
||||
#include <iomanip>
|
||||
|
||||
#include "libtorrent/entry.hpp"
|
||||
#include "libtorrent/bencode.hpp"
|
||||
#include "libtorrent/torrent_info.hpp"
|
||||
#include "libtorrent/lazy_entry.hpp"
|
||||
#include <boost/filesystem/operations.hpp>
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
using namespace libtorrent;
|
||||
using namespace boost::filesystem;
|
||||
|
||||
if (argc != 2)
|
||||
{
|
||||
std::cerr << "usage: dump_torrent torrent-file\n";
|
||||
return 1;
|
||||
}
|
||||
#if BOOST_VERSION < 103400
|
||||
boost::filesystem::path::default_name_check(boost::filesystem::no_check);
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
try
|
||||
{
|
||||
#endif
|
||||
|
||||
int size = file_size(argv[1]);
|
||||
if (size > 10 * 1000000)
|
||||
{
|
||||
std::cerr << "file too big (" << size << "), aborting\n";
|
||||
return 1;
|
||||
}
|
||||
std::vector<char> buf(size);
|
||||
std::ifstream(argv[1], std::ios_base::binary).read(&buf[0], size);
|
||||
lazy_entry e;
|
||||
int ret = lazy_bdecode(&buf[0], &buf[0] + buf.size(), e);
|
||||
|
||||
if (ret != 0)
|
||||
{
|
||||
std::cerr << "invalid bencoding: " << ret << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::cout << "\n\n----- raw info -----\n\n";
|
||||
std::cout << e << std::endl;
|
||||
|
||||
torrent_info t(e);
|
||||
|
||||
// print info about torrent
|
||||
std::cout << "\n\n----- torrent file info -----\n\n";
|
||||
std::cout << "nodes:\n";
|
||||
typedef std::vector<std::pair<std::string, int> > node_vec;
|
||||
node_vec const& nodes = t.nodes();
|
||||
for (node_vec::const_iterator i = nodes.begin(), end(nodes.end());
|
||||
i != end; ++i)
|
||||
{
|
||||
std::cout << i->first << ":" << i->second << "\n";
|
||||
}
|
||||
std::cout << "trackers:\n";
|
||||
for (std::vector<announce_entry>::const_iterator i = t.trackers().begin();
|
||||
i != t.trackers().end(); ++i)
|
||||
{
|
||||
std::cout << i->tier << ": " << i->url << "\n";
|
||||
}
|
||||
|
||||
std::cout << "number of pieces: " << t.num_pieces() << "\n";
|
||||
std::cout << "piece length: " << t.piece_length() << "\n";
|
||||
std::cout << "info hash: " << t.info_hash() << "\n";
|
||||
std::cout << "comment: " << t.comment() << "\n";
|
||||
std::cout << "created by: " << t.creator() << "\n";
|
||||
std::cout << "files:\n";
|
||||
int index = 0;
|
||||
for (torrent_info::file_iterator i = t.begin_files();
|
||||
i != t.end_files(); ++i, ++index)
|
||||
{
|
||||
int first = t.map_file(index, 0, 1).piece;
|
||||
int last = t.map_file(index, i->size - 1, 1).piece;
|
||||
std::cout << " " << std::setw(11) << i->size
|
||||
<< " " << i->path.string() << "[ " << first << ", "
|
||||
<< last << " ]\n";
|
||||
}
|
||||
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
std::cout << e.what() << "\n";
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
<div class="section" id="simple-client">
|
||||
<h2>simple client</h2>
|
||||
<p>This is a simple client. It doesn't have much output to keep it simple:</p>
|
||||
<pre class="literal-block">
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
using namespace libtorrent;
|
||||
#if BOOST_VERSION < 103400
|
||||
namespace fs = boost::filesystem;
|
||||
fs::path::default_name_check(fs::no_check);
|
||||
#endif
|
||||
|
||||
if (argc != 2)
|
||||
{
|
||||
std::cerr << "usage: ./simple_client torrent-file\n"
|
||||
"to stop the client, press return.\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
try
|
||||
#endif
|
||||
{
|
||||
session s;
|
||||
s.listen_on(std::make_pair(6881, 6889));
|
||||
add_torrent_params p;
|
||||
p.save_path = "./";
|
||||
p.ti = new torrent_info(argv[1]);
|
||||
s.add_torrent(p);
|
||||
|
||||
// wait for the user to end
|
||||
char a;
|
||||
std::cin.unsetf(std::ios_base::skipws);
|
||||
std::cin >> a;
|
||||
}
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
catch (std::exception& e)
|
||||
{
|
||||
std::cout << e.what() << "\n";
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
<div class="section" id="make-torrent">
|
||||
<h2>make_torrent</h2>
|
||||
<p>Shows how to create a torrent from a directory tree:</p>
|
||||
<pre class="literal-block">
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <iterator>
|
||||
#include <iomanip>
|
||||
|
||||
#include "libtorrent/entry.hpp"
|
||||
#include "libtorrent/bencode.hpp"
|
||||
#include "libtorrent/torrent_info.hpp"
|
||||
#include "libtorrent/file.hpp"
|
||||
#include "libtorrent/storage.hpp"
|
||||
#include "libtorrent/hasher.hpp"
|
||||
#include "libtorrent/create_torrent.hpp"
|
||||
|
||||
#include <boost/filesystem/operations.hpp>
|
||||
#include <boost/filesystem/path.hpp>
|
||||
#include <boost/filesystem/fstream.hpp>
|
||||
#include <boost/bind.hpp>
|
||||
|
||||
using namespace boost::filesystem;
|
||||
using namespace libtorrent;
|
||||
|
||||
// do not include files and folders whose
|
||||
// name starts with a .
|
||||
bool file_filter(boost::filesystem::path const& filename)
|
||||
{
|
||||
if (filename.leaf()[0] == '.') return false;
|
||||
std::cerr << filename << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
void print_progress(int i, int num)
|
||||
{
|
||||
std::cerr << "\r" << (i+1) << "/" << num;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
using namespace libtorrent;
|
||||
using namespace boost::filesystem;
|
||||
|
||||
int piece_size = 256 * 1024;
|
||||
char const* creator_str = "libtorrent";
|
||||
|
||||
path::default_name_check(no_check);
|
||||
|
||||
if (argc != 4 && argc != 5)
|
||||
{
|
||||
std::cerr << "usage: make_torrent <output torrent-file> "
|
||||
"<announce url> <file or directory to create torrent from> "
|
||||
"[url-seed]\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
try
|
||||
{
|
||||
#endif
|
||||
file_storage fs;
|
||||
file_pool fp;
|
||||
path full_path = complete(path(argv[3]));
|
||||
|
||||
add_files(fs, full_path, file_filter);
|
||||
|
||||
create_torrent t(fs, piece_size);
|
||||
t.add_tracker(argv[2]);
|
||||
set_piece_hashes(t, full_path.branch_path()
|
||||
, boost::bind(&print_progress, _1, t.num_pieces()));
|
||||
std::cerr << std::endl;
|
||||
t.set_creator(creator_str);
|
||||
|
||||
if (argc == 5) t.add_url_seed(argv[4]);
|
||||
|
||||
// create the torrent and print it to out
|
||||
ofstream out(complete(path(argv[1])), std::ios_base::binary);
|
||||
bencode(std::ostream_iterator<char>(out), t.generate());
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
std::cerr << e.what() << "\n";
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="footer">
|
||||
<span>Copyright © 2005 Rasterbar Software.</span>
|
||||
</div>
|
||||
</div>
|
||||
<script src="http://www.google-analytics.com/urchin.js" type="text/javascript">
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
_uacct = "UA-1599045-1";
|
||||
urchinTracker();
|
||||
</script>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -1,260 +0,0 @@
|
|||
===================
|
||||
libtorrent Examples
|
||||
===================
|
||||
|
||||
:Author: Arvid Norberg, arvid@rasterbar.com
|
||||
|
||||
.. contents:: Table of contents
|
||||
:depth: 2
|
||||
:backlinks: none
|
||||
|
||||
examples
|
||||
========
|
||||
|
||||
Except for the example programs in this manual, there's also a bigger example
|
||||
of a (little bit) more complete client, ``client_test``. There are separate
|
||||
instructions for how to use it here__ if you'd like to try it. Note that building
|
||||
``client_test`` also requires boost.regex and boost.program_options library.
|
||||
|
||||
__ client_test.html
|
||||
|
||||
dump_torrent
|
||||
------------
|
||||
|
||||
This is an example of a program that will take a torrent-file as a parameter and
|
||||
print information about it to std out::
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <iterator>
|
||||
#include <iomanip>
|
||||
|
||||
#include "libtorrent/entry.hpp"
|
||||
#include "libtorrent/bencode.hpp"
|
||||
#include "libtorrent/torrent_info.hpp"
|
||||
#include "libtorrent/lazy_entry.hpp"
|
||||
#include <boost/filesystem/operations.hpp>
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
using namespace libtorrent;
|
||||
using namespace boost::filesystem;
|
||||
|
||||
if (argc != 2)
|
||||
{
|
||||
std::cerr << "usage: dump_torrent torrent-file\n";
|
||||
return 1;
|
||||
}
|
||||
#if BOOST_VERSION < 103400
|
||||
boost::filesystem::path::default_name_check(boost::filesystem::no_check);
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
try
|
||||
{
|
||||
#endif
|
||||
|
||||
int size = file_size(argv[1]);
|
||||
if (size > 10 * 1000000)
|
||||
{
|
||||
std::cerr << "file too big (" << size << "), aborting\n";
|
||||
return 1;
|
||||
}
|
||||
std::vector<char> buf(size);
|
||||
std::ifstream(argv[1], std::ios_base::binary).read(&buf[0], size);
|
||||
lazy_entry e;
|
||||
int ret = lazy_bdecode(&buf[0], &buf[0] + buf.size(), e);
|
||||
|
||||
if (ret != 0)
|
||||
{
|
||||
std::cerr << "invalid bencoding: " << ret << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::cout << "\n\n----- raw info -----\n\n";
|
||||
std::cout << e << std::endl;
|
||||
|
||||
torrent_info t(e);
|
||||
|
||||
// print info about torrent
|
||||
std::cout << "\n\n----- torrent file info -----\n\n";
|
||||
std::cout << "nodes:\n";
|
||||
typedef std::vector<std::pair<std::string, int> > node_vec;
|
||||
node_vec const& nodes = t.nodes();
|
||||
for (node_vec::const_iterator i = nodes.begin(), end(nodes.end());
|
||||
i != end; ++i)
|
||||
{
|
||||
std::cout << i->first << ":" << i->second << "\n";
|
||||
}
|
||||
std::cout << "trackers:\n";
|
||||
for (std::vector<announce_entry>::const_iterator i = t.trackers().begin();
|
||||
i != t.trackers().end(); ++i)
|
||||
{
|
||||
std::cout << i->tier << ": " << i->url << "\n";
|
||||
}
|
||||
|
||||
std::cout << "number of pieces: " << t.num_pieces() << "\n";
|
||||
std::cout << "piece length: " << t.piece_length() << "\n";
|
||||
std::cout << "info hash: " << t.info_hash() << "\n";
|
||||
std::cout << "comment: " << t.comment() << "\n";
|
||||
std::cout << "created by: " << t.creator() << "\n";
|
||||
std::cout << "files:\n";
|
||||
int index = 0;
|
||||
for (torrent_info::file_iterator i = t.begin_files();
|
||||
i != t.end_files(); ++i, ++index)
|
||||
{
|
||||
int first = t.map_file(index, 0, 1).piece;
|
||||
int last = t.map_file(index, i->size - 1, 1).piece;
|
||||
std::cout << " " << std::setw(11) << i->size
|
||||
<< " " << i->path.string() << "[ " << first << ", "
|
||||
<< last << " ]\n";
|
||||
}
|
||||
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
std::cout << e.what() << "\n";
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
simple client
|
||||
-------------
|
||||
|
||||
This is a simple client. It doesn't have much output to keep it simple::
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
using namespace libtorrent;
|
||||
#if BOOST_VERSION < 103400
|
||||
namespace fs = boost::filesystem;
|
||||
fs::path::default_name_check(fs::no_check);
|
||||
#endif
|
||||
|
||||
if (argc != 2)
|
||||
{
|
||||
std::cerr << "usage: ./simple_client torrent-file\n"
|
||||
"to stop the client, press return.\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
try
|
||||
#endif
|
||||
{
|
||||
session s;
|
||||
s.listen_on(std::make_pair(6881, 6889));
|
||||
add_torrent_params p;
|
||||
p.save_path = "./";
|
||||
p.ti = new torrent_info(argv[1]);
|
||||
s.add_torrent(p);
|
||||
|
||||
// wait for the user to end
|
||||
char a;
|
||||
std::cin.unsetf(std::ios_base::skipws);
|
||||
std::cin >> a;
|
||||
}
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
catch (std::exception& e)
|
||||
{
|
||||
std::cout << e.what() << "\n";
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
make_torrent
|
||||
------------
|
||||
|
||||
Shows how to create a torrent from a directory tree::
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <iterator>
|
||||
#include <iomanip>
|
||||
|
||||
#include "libtorrent/entry.hpp"
|
||||
#include "libtorrent/bencode.hpp"
|
||||
#include "libtorrent/torrent_info.hpp"
|
||||
#include "libtorrent/file.hpp"
|
||||
#include "libtorrent/storage.hpp"
|
||||
#include "libtorrent/hasher.hpp"
|
||||
#include "libtorrent/create_torrent.hpp"
|
||||
|
||||
#include <boost/filesystem/operations.hpp>
|
||||
#include <boost/filesystem/path.hpp>
|
||||
#include <boost/filesystem/fstream.hpp>
|
||||
#include <boost/bind.hpp>
|
||||
|
||||
using namespace boost::filesystem;
|
||||
using namespace libtorrent;
|
||||
|
||||
// do not include files and folders whose
|
||||
// name starts with a .
|
||||
bool file_filter(boost::filesystem::path const& filename)
|
||||
{
|
||||
if (filename.leaf()[0] == '.') return false;
|
||||
std::cerr << filename << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
void print_progress(int i, int num)
|
||||
{
|
||||
std::cerr << "\r" << (i+1) << "/" << num;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
using namespace libtorrent;
|
||||
using namespace boost::filesystem;
|
||||
|
||||
int piece_size = 256 * 1024;
|
||||
char const* creator_str = "libtorrent";
|
||||
|
||||
path::default_name_check(no_check);
|
||||
|
||||
if (argc != 4 && argc != 5)
|
||||
{
|
||||
std::cerr << "usage: make_torrent <output torrent-file> "
|
||||
"<announce url> <file or directory to create torrent from> "
|
||||
"[url-seed]\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
try
|
||||
{
|
||||
#endif
|
||||
file_storage fs;
|
||||
file_pool fp;
|
||||
path full_path = complete(path(argv[3]));
|
||||
|
||||
add_files(fs, full_path, file_filter);
|
||||
|
||||
create_torrent t(fs, piece_size);
|
||||
t.add_tracker(argv[2]);
|
||||
set_piece_hashes(t, full_path.branch_path()
|
||||
, boost::bind(&print_progress, _1, t.num_pieces()));
|
||||
std::cerr << std::endl;
|
||||
t.set_creator(creator_str);
|
||||
|
||||
if (argc == 5) t.add_url_seed(argv[4]);
|
||||
|
||||
// create the torrent and print it to out
|
||||
ofstream out(complete(path(argv[1])), std::ios_base::binary);
|
||||
bencode(std::ostream_iterator<char>(out), t.generate());
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
std::cerr << e.what() << "\n";
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,301 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta name="generator" content="Docutils 0.5: http://docutils.sourceforge.net/" />
|
||||
<title></title>
|
||||
<meta name="author" content="Arvid Norberg, arvid@rasterbar.com Ludvig Strigeus, ludde@utorrent.com" />
|
||||
<link rel="stylesheet" type="text/css" href="../../css/base.css" />
|
||||
<link rel="stylesheet" type="text/css" href="../../css/rst.css" />
|
||||
<link rel="stylesheet" href="style.css" type="text/css" />
|
||||
<style type="text/css">
|
||||
/* Hides from IE-mac \*/
|
||||
* html pre { height: 1%; }
|
||||
/* End hide from IE-mac */
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="document">
|
||||
<div id="container">
|
||||
<div id="headerNav">
|
||||
<ul>
|
||||
<li class="first"><a href="/">Home</a></li>
|
||||
<li><a href="../../products.html">Products</a></li>
|
||||
<li><a href="../../contact.html">Contact</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="header">
|
||||
<h1><span>Rasterbar Software</span></h1>
|
||||
<h2><span>Software developement and consulting</span></h2>
|
||||
</div>
|
||||
<div id="main">
|
||||
|
||||
<table class="docinfo" frame="void" rules="none">
|
||||
<col class="docinfo-name" />
|
||||
<col class="docinfo-content" />
|
||||
<tbody valign="top">
|
||||
<tr><th class="docinfo-name">Author:</th>
|
||||
<td>Arvid Norberg, <a class="reference external" href="mailto:arvid@rasterbar.com">arvid@rasterbar.com</a>
|
||||
Ludvig Strigeus, <a class="last reference external" href="mailto:ludde@utorrent.com">ludde@utorrent.com</a></td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="section" id="extension-protocol-for-bittorrent">
|
||||
<h1>extension protocol for bittorrent</h1>
|
||||
<p>The intention of this protocol is to provide a simple and thin transport
|
||||
for extensions to the bittorrent protocol. Supporting this protocol makes
|
||||
it easy to add new extensions without interfering with the standard
|
||||
bittorrent protocol or clients that don't support this extension or the
|
||||
one you want to add.</p>
|
||||
<p>To advertise to other clients that you support, one bit from the reserved
|
||||
bytes is used.</p>
|
||||
<p>The bit selected for the extension protocol is bit 20 from the right (counting
|
||||
starts at 0). So (reserved_byte[5] & 0x10) is the expression to use for checking
|
||||
if the client supports extended messaging.</p>
|
||||
<p>Once support for the protocol is established, the client is supposed to
|
||||
support 1 new message:</p>
|
||||
<table border="1" class="docutils">
|
||||
<colgroup>
|
||||
<col width="86%" />
|
||||
<col width="14%" />
|
||||
</colgroup>
|
||||
<thead valign="bottom">
|
||||
<tr><th class="head">name</th>
|
||||
<th class="head">id</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody valign="top">
|
||||
<tr><td><tt class="docutils literal"><span class="pre">extended</span></tt></td>
|
||||
<td>20</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p>This message is sent as any other bittorrent message, with a 4 byte length
|
||||
prefix and a single byte identifying the message (the single byte being 20
|
||||
in this case). At the start of the payload of the message, is a single byte
|
||||
message identifier. This identifier can refer to different extension messages
|
||||
and only one ID is specified, 0. If the ID is 0, the message is a handshake
|
||||
message which is described below. The layout of a general <tt class="docutils literal"><span class="pre">extended</span></tt> message
|
||||
follows (including the message headers used by the bittorrent protocol):</p>
|
||||
<table border="1" class="docutils">
|
||||
<colgroup>
|
||||
<col width="15%" />
|
||||
<col width="85%" />
|
||||
</colgroup>
|
||||
<thead valign="bottom">
|
||||
<tr><th class="head">size</th>
|
||||
<th class="head">description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody valign="top">
|
||||
<tr><td>uint32_t</td>
|
||||
<td>length prefix. Specifies the number of bytes for the
|
||||
entire message. (Big endian)</td>
|
||||
</tr>
|
||||
<tr><td>uint8_t</td>
|
||||
<td>bittorrent message ID, = 20</td>
|
||||
</tr>
|
||||
<tr><td>uint8_t</td>
|
||||
<td>extended message ID. 0 = handshake, >0 = extended
|
||||
message as specified by the handshake.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="section" id="handshake-message">
|
||||
<h2>handshake message</h2>
|
||||
<p>The payload of the handshake message is a bencoded dictionary. All items
|
||||
in the dictionary are optional. Any unknown names should be ignored
|
||||
by the client. All parts of the dictionary are case sensitive.
|
||||
This is the defined item in the dictionary:</p>
|
||||
<table border="1" class="docutils">
|
||||
<colgroup>
|
||||
<col width="11%" />
|
||||
<col width="89%" />
|
||||
</colgroup>
|
||||
<thead valign="bottom">
|
||||
<tr><th class="head">name</th>
|
||||
<th class="head">description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody valign="top">
|
||||
<tr><td>m</td>
|
||||
<td><p class="first">Dictionary of supported extension messages which maps
|
||||
names of extensions to an extended message ID for each
|
||||
extension message. The only requirement on these IDs
|
||||
is that no extension message share the same one. Setting
|
||||
an extension number to zero means that the extension is
|
||||
not supported/disabled. The client should ignore any
|
||||
extension names it doesn't recognize.</p>
|
||||
<p class="last">The extension message IDs are the IDs used to send the
|
||||
extension messages to the peer sending this handshake.
|
||||
i.e. The IDs are local to this particular peer.</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p>Here are some other items that an implementation may choose to support:</p>
|
||||
<table border="1" class="docutils">
|
||||
<colgroup>
|
||||
<col width="12%" />
|
||||
<col width="88%" />
|
||||
</colgroup>
|
||||
<thead valign="bottom">
|
||||
<tr><th class="head">name</th>
|
||||
<th class="head">description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody valign="top">
|
||||
<tr><td>p</td>
|
||||
<td>Local TCP listen port. Allows each side to learn about
|
||||
the TCP port number of the other side. Note that there is
|
||||
no need for the receiving side of the connection to send
|
||||
this extension message, since its port number is already
|
||||
known.</td>
|
||||
</tr>
|
||||
<tr><td>v</td>
|
||||
<td>Client name and version (as a utf-8 string).
|
||||
This is a much more reliable way of identifying the
|
||||
client than relying on the peer id encoding.</td>
|
||||
</tr>
|
||||
<tr><td>yourip</td>
|
||||
<td>A string containing the compact representation of the ip
|
||||
address this peer sees you as. i.e. this is the
|
||||
receiver's external ip address (no port is included).
|
||||
This may be either an IPv4 (4 bytes) or an IPv6
|
||||
(16 bytes) address.</td>
|
||||
</tr>
|
||||
<tr><td>ipv6</td>
|
||||
<td>If this peer has an IPv6 interface, this is the compact
|
||||
representation of that address (16 bytes). The client may
|
||||
prefer to connect back via the IPv6 address.</td>
|
||||
</tr>
|
||||
<tr><td>ipv4</td>
|
||||
<td>If this peer has an IPv4 interface, this is the compact
|
||||
representation of that address (4 bytes). The client may
|
||||
prefer to connect back via this interface.</td>
|
||||
</tr>
|
||||
<tr><td>reqq</td>
|
||||
<td>An integer, the number of outstanding request messages
|
||||
this client supports without dropping any. The default in
|
||||
in libtorrent is 250.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p>The handshake dictionary could also include extended handshake
|
||||
information, such as support for encrypted headers or anything
|
||||
imaginable.</p>
|
||||
<p>An example of what the payload of a handshake message could look like:</p>
|
||||
<table border="1" class="docutils">
|
||||
<colgroup>
|
||||
<col width="36%" />
|
||||
<col width="64%" />
|
||||
</colgroup>
|
||||
<thead valign="bottom">
|
||||
<tr><th class="head" colspan="2">Dictionary</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody valign="top">
|
||||
<tr><td><tt class="docutils literal"><span class="pre">m</span></tt></td>
|
||||
<td><table border="1" class="first last docutils">
|
||||
<colgroup>
|
||||
<col width="88%" />
|
||||
<col width="12%" />
|
||||
</colgroup>
|
||||
<thead valign="bottom">
|
||||
<tr><th class="head" colspan="2">Dictionary</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody valign="top">
|
||||
<tr><td><tt class="docutils literal"><span class="pre">LT_metadata</span></tt></td>
|
||||
<td>1</td>
|
||||
</tr>
|
||||
<tr><td><tt class="docutils literal"><span class="pre">ut_pex</span></tt></td>
|
||||
<td>2</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
<tr><td><tt class="docutils literal"><span class="pre">p</span></tt></td>
|
||||
<td>6881</td>
|
||||
</tr>
|
||||
<tr><td><tt class="docutils literal"><span class="pre">v</span></tt></td>
|
||||
<td>"µTorrent 1.2"</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p>and in the encoded form:</p>
|
||||
<p><tt class="docutils literal"><span class="pre">d1:md11:LT_metadatai1e6:µT_PEXi2ee1:pi6881e1:v13:\xc2\xb5Torrent</span> <span class="pre">1.2e</span></tt></p>
|
||||
<p>To make sure the extension names do not collide by mistake, they should be
|
||||
prefixed with the two (or one) character code that is used to identify the
|
||||
client that introduced the extension. This applies for both the names of
|
||||
extension messages, and for any additional information put inside the
|
||||
top-level dictionary. All one and two byte identifiers are invalid to use
|
||||
unless defined by this specification.</p>
|
||||
<p>This message should be sent immediately after the standard bittorrent handshake
|
||||
to any peer that supports this extension protocol. It is valid to send the
|
||||
handshake message more than once during the lifetime of a connection,
|
||||
the sending client should not be disconnected. An implementation may choose
|
||||
to ignore the subsequent handshake messages (or parts of them).</p>
|
||||
<p>Subsequent handshake messages can be used to enable/disable extensions
|
||||
without restarting the connection. If a peer supports changing extensions
|
||||
at run time, it should note that the <tt class="docutils literal"><span class="pre">m</span></tt> dictionary is additive.
|
||||
It's enough that it contains the actual <em>CHANGES</em> to the extension list.
|
||||
To disable the support for <tt class="docutils literal"><span class="pre">LT_metadata</span></tt> at run-time, without affecting
|
||||
any other extensions, this message should be sent:
|
||||
<tt class="docutils literal"><span class="pre">d11:LT_metadatai0ee</span></tt>.
|
||||
As specified above, the value 0 is used to turn off an extension.</p>
|
||||
<p>The extension IDs must be stored for every peer, becuase every peer may have
|
||||
different IDs for the same extension.</p>
|
||||
<p>This specification, deliberately, does not specify any extensions such as
|
||||
peer-exchange or metadata exchange. This protocol is merely a transport
|
||||
for the actual extensions to the bittorrent protocol and the extensions
|
||||
named in the example above (such as <tt class="docutils literal"><span class="pre">p</span></tt>) are just examples of possible
|
||||
extensions.</p>
|
||||
</div>
|
||||
<div class="section" id="rationale">
|
||||
<h2>rationale</h2>
|
||||
<p>The reason why the extension messages' IDs would be defined in the handshake
|
||||
is to avoid having a global registry of message IDs. Instead the names of the
|
||||
extension messages requires unique names, which is much easier to do without
|
||||
a global registry. The convention is to use a two letter prefix on the
|
||||
extension message names, the prefix would identify the client first
|
||||
implementing the extension message. e.g. <tt class="docutils literal"><span class="pre">LT_metadata</span></tt> is implemented by
|
||||
libtorrent, and hence it has the <tt class="docutils literal"><span class="pre">LT</span></tt> prefix.</p>
|
||||
<p>If the client supporting the extensions can decide which numbers the messages
|
||||
it receives will have, it means they are constants within that client. i.e.
|
||||
they can be used in <tt class="docutils literal"><span class="pre">switch</span></tt> statements. It's easy for the other end to
|
||||
store an array with the ID's we expect for each message and use that for
|
||||
lookups each time it sends an extension message.</p>
|
||||
<p>The reason for having a dictionary instead of having an array (using
|
||||
implicitly assigned index numbers to the extensions) is that if a client
|
||||
want to disable some extensions, the ID numbers would change, and it wouldn't
|
||||
be able to use constants (and hence, not use them in a <tt class="docutils literal"><span class="pre">switch</span></tt>). If the
|
||||
messages IDs would map directly to bittorrent message IDs, It would also make
|
||||
it possible to map extensions in the handshake to existing extensions with
|
||||
fixed message IDs.</p>
|
||||
<p>The reasoning behind having a single byte as extended message identifier is
|
||||
to follow the the bittorrent spec. with its single byte message identifiers.
|
||||
It is also considered to be enough. It won't limit the total number of
|
||||
extensions, only the number of extensions used simultaneously.</p>
|
||||
<p>The reason for using single byte identifiers for the standardized handshake
|
||||
identifiers is 1) The mainline DHT uses single byte identifiers. 2) Saves
|
||||
bandwidth. The only advantage of longer messages is that it makes the
|
||||
protocol more readable for a human, but the BT protocol wasn't designed to
|
||||
be a human readable protocol, so why bother.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="footer">
|
||||
<span>Copyright © 2005 Rasterbar Software.</span>
|
||||
</div>
|
||||
</div>
|
||||
<script src="http://www.google-analytics.com/urchin.js" type="text/javascript">
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
_uacct = "UA-1599045-1";
|
||||
urchinTracker();
|
||||
</script>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -1,202 +0,0 @@
|
|||
:Author: Arvid Norberg, arvid@rasterbar.com
|
||||
Ludvig Strigeus, ludde@utorrent.com
|
||||
|
||||
extension protocol for bittorrent
|
||||
=================================
|
||||
|
||||
The intention of this protocol is to provide a simple and thin transport
|
||||
for extensions to the bittorrent protocol. Supporting this protocol makes
|
||||
it easy to add new extensions without interfering with the standard
|
||||
bittorrent protocol or clients that don't support this extension or the
|
||||
one you want to add.
|
||||
|
||||
To advertise to other clients that you support, one bit from the reserved
|
||||
bytes is used.
|
||||
|
||||
The bit selected for the extension protocol is bit 20 from the right (counting
|
||||
starts at 0). So (reserved_byte[5] & 0x10) is the expression to use for checking
|
||||
if the client supports extended messaging.
|
||||
|
||||
Once support for the protocol is established, the client is supposed to
|
||||
support 1 new message:
|
||||
|
||||
+------------------------+----+
|
||||
|name | id |
|
||||
+========================+====+
|
||||
|``extended`` | 20 |
|
||||
+------------------------+----+
|
||||
|
||||
This message is sent as any other bittorrent message, with a 4 byte length
|
||||
prefix and a single byte identifying the message (the single byte being 20
|
||||
in this case). At the start of the payload of the message, is a single byte
|
||||
message identifier. This identifier can refer to different extension messages
|
||||
and only one ID is specified, 0. If the ID is 0, the message is a handshake
|
||||
message which is described below. The layout of a general ``extended`` message
|
||||
follows (including the message headers used by the bittorrent protocol):
|
||||
|
||||
+----------+---------------------------------------------------------+
|
||||
| size | description |
|
||||
+==========+=========================================================+
|
||||
| uint32_t | length prefix. Specifies the number of bytes for the |
|
||||
| | entire message. (Big endian) |
|
||||
+----------+---------------------------------------------------------+
|
||||
| uint8_t | bittorrent message ID, = 20 |
|
||||
+----------+---------------------------------------------------------+
|
||||
| uint8_t | extended message ID. 0 = handshake, >0 = extended |
|
||||
| | message as specified by the handshake. |
|
||||
+----------+---------------------------------------------------------+
|
||||
|
||||
|
||||
handshake message
|
||||
-----------------
|
||||
|
||||
The payload of the handshake message is a bencoded dictionary. All items
|
||||
in the dictionary are optional. Any unknown names should be ignored
|
||||
by the client. All parts of the dictionary are case sensitive.
|
||||
This is the defined item in the dictionary:
|
||||
|
||||
+-------+-----------------------------------------------------------+
|
||||
| name | description |
|
||||
+=======+===========================================================+
|
||||
| m | Dictionary of supported extension messages which maps |
|
||||
| | names of extensions to an extended message ID for each |
|
||||
| | extension message. The only requirement on these IDs |
|
||||
| | is that no extension message share the same one. Setting |
|
||||
| | an extension number to zero means that the extension is |
|
||||
| | not supported/disabled. The client should ignore any |
|
||||
| | extension names it doesn't recognize. |
|
||||
| | |
|
||||
| | The extension message IDs are the IDs used to send the |
|
||||
| | extension messages to the peer sending this handshake. |
|
||||
| | i.e. The IDs are local to this particular peer. |
|
||||
+-------+-----------------------------------------------------------+
|
||||
|
||||
|
||||
Here are some other items that an implementation may choose to support:
|
||||
|
||||
+--------+-----------------------------------------------------------+
|
||||
| name | description |
|
||||
+========+===========================================================+
|
||||
| p | Local TCP listen port. Allows each side to learn about |
|
||||
| | the TCP port number of the other side. Note that there is |
|
||||
| | no need for the receiving side of the connection to send |
|
||||
| | this extension message, since its port number is already |
|
||||
| | known. |
|
||||
+--------+-----------------------------------------------------------+
|
||||
| v | Client name and version (as a utf-8 string). |
|
||||
| | This is a much more reliable way of identifying the |
|
||||
| | client than relying on the peer id encoding. |
|
||||
+--------+-----------------------------------------------------------+
|
||||
| yourip | A string containing the compact representation of the ip |
|
||||
| | address this peer sees you as. i.e. this is the |
|
||||
| | receiver's external ip address (no port is included). |
|
||||
| | This may be either an IPv4 (4 bytes) or an IPv6 |
|
||||
| | (16 bytes) address. |
|
||||
+--------+-----------------------------------------------------------+
|
||||
| ipv6 | If this peer has an IPv6 interface, this is the compact |
|
||||
| | representation of that address (16 bytes). The client may |
|
||||
| | prefer to connect back via the IPv6 address. |
|
||||
+--------+-----------------------------------------------------------+
|
||||
| ipv4 | If this peer has an IPv4 interface, this is the compact |
|
||||
| | representation of that address (4 bytes). The client may |
|
||||
| | prefer to connect back via this interface. |
|
||||
+--------+-----------------------------------------------------------+
|
||||
| reqq | An integer, the number of outstanding request messages |
|
||||
| | this client supports without dropping any. The default in |
|
||||
| | in libtorrent is 250. |
|
||||
+--------+-----------------------------------------------------------+
|
||||
|
||||
The handshake dictionary could also include extended handshake
|
||||
information, such as support for encrypted headers or anything
|
||||
imaginable.
|
||||
|
||||
An example of what the payload of a handshake message could look like:
|
||||
|
||||
+------------------------------------------------------+
|
||||
| Dictionary |
|
||||
+===================+==================================+
|
||||
| ``m`` | +--------------------------+ |
|
||||
| | | Dictionary | |
|
||||
| | +======================+===+ |
|
||||
| | | ``LT_metadata`` | 1 | |
|
||||
| | +----------------------+---+ |
|
||||
| | | ``ut_pex`` | 2 | |
|
||||
| | +----------------------+---+ |
|
||||
| | |
|
||||
+-------------------+----------------------------------+
|
||||
| ``p`` | 6881 |
|
||||
+-------------------+----------------------------------+
|
||||
| ``v`` | "µTorrent 1.2" |
|
||||
+-------------------+----------------------------------+
|
||||
|
||||
and in the encoded form:
|
||||
|
||||
``d1:md11:LT_metadatai1e6:µT_PEXi2ee1:pi6881e1:v13:\xc2\xb5Torrent 1.2e``
|
||||
|
||||
To make sure the extension names do not collide by mistake, they should be
|
||||
prefixed with the two (or one) character code that is used to identify the
|
||||
client that introduced the extension. This applies for both the names of
|
||||
extension messages, and for any additional information put inside the
|
||||
top-level dictionary. All one and two byte identifiers are invalid to use
|
||||
unless defined by this specification.
|
||||
|
||||
This message should be sent immediately after the standard bittorrent handshake
|
||||
to any peer that supports this extension protocol. It is valid to send the
|
||||
handshake message more than once during the lifetime of a connection,
|
||||
the sending client should not be disconnected. An implementation may choose
|
||||
to ignore the subsequent handshake messages (or parts of them).
|
||||
|
||||
Subsequent handshake messages can be used to enable/disable extensions
|
||||
without restarting the connection. If a peer supports changing extensions
|
||||
at run time, it should note that the ``m`` dictionary is additive.
|
||||
It's enough that it contains the actual *CHANGES* to the extension list.
|
||||
To disable the support for ``LT_metadata`` at run-time, without affecting
|
||||
any other extensions, this message should be sent:
|
||||
``d11:LT_metadatai0ee``.
|
||||
As specified above, the value 0 is used to turn off an extension.
|
||||
|
||||
The extension IDs must be stored for every peer, becuase every peer may have
|
||||
different IDs for the same extension.
|
||||
|
||||
This specification, deliberately, does not specify any extensions such as
|
||||
peer-exchange or metadata exchange. This protocol is merely a transport
|
||||
for the actual extensions to the bittorrent protocol and the extensions
|
||||
named in the example above (such as ``p``) are just examples of possible
|
||||
extensions.
|
||||
|
||||
rationale
|
||||
---------
|
||||
|
||||
The reason why the extension messages' IDs would be defined in the handshake
|
||||
is to avoid having a global registry of message IDs. Instead the names of the
|
||||
extension messages requires unique names, which is much easier to do without
|
||||
a global registry. The convention is to use a two letter prefix on the
|
||||
extension message names, the prefix would identify the client first
|
||||
implementing the extension message. e.g. ``LT_metadata`` is implemented by
|
||||
libtorrent, and hence it has the ``LT`` prefix.
|
||||
|
||||
If the client supporting the extensions can decide which numbers the messages
|
||||
it receives will have, it means they are constants within that client. i.e.
|
||||
they can be used in ``switch`` statements. It's easy for the other end to
|
||||
store an array with the ID's we expect for each message and use that for
|
||||
lookups each time it sends an extension message.
|
||||
|
||||
The reason for having a dictionary instead of having an array (using
|
||||
implicitly assigned index numbers to the extensions) is that if a client
|
||||
want to disable some extensions, the ID numbers would change, and it wouldn't
|
||||
be able to use constants (and hence, not use them in a ``switch``). If the
|
||||
messages IDs would map directly to bittorrent message IDs, It would also make
|
||||
it possible to map extensions in the handshake to existing extensions with
|
||||
fixed message IDs.
|
||||
|
||||
The reasoning behind having a single byte as extended message identifier is
|
||||
to follow the the bittorrent spec. with its single byte message identifiers.
|
||||
It is also considered to be enough. It won't limit the total number of
|
||||
extensions, only the number of extensions used simultaneously.
|
||||
|
||||
The reason for using single byte identifiers for the standardized handshake
|
||||
identifiers is 1) The mainline DHT uses single byte identifiers. 2) Saves
|
||||
bandwidth. The only advantage of longer messages is that it makes the
|
||||
protocol more readable for a human, but the BT protocol wasn't designed to
|
||||
be a human readable protocol, so why bother.
|
||||
|
Before Width: | Height: | Size: 44 KiB |
Before Width: | Height: | Size: 51 KiB |
|
@ -1,401 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta name="generator" content="Docutils 0.5: http://docutils.sourceforge.net/" />
|
||||
<title>libtorrent manual</title>
|
||||
<meta name="author" content="Arvid Norberg, arvid@rasterbar.com" />
|
||||
<link rel="stylesheet" type="text/css" href="../../css/base.css" />
|
||||
<link rel="stylesheet" type="text/css" href="../../css/rst.css" />
|
||||
<link rel="stylesheet" href="style.css" type="text/css" />
|
||||
<style type="text/css">
|
||||
/* Hides from IE-mac \*/
|
||||
* html pre { height: 1%; }
|
||||
/* End hide from IE-mac */
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="document" id="libtorrent-manual">
|
||||
<div id="container">
|
||||
<div id="headerNav">
|
||||
<ul>
|
||||
<li class="first"><a href="/">Home</a></li>
|
||||
<li><a href="../../products.html">Products</a></li>
|
||||
<li><a href="../../contact.html">Contact</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="header">
|
||||
<h1><span>Rasterbar Software</span></h1>
|
||||
<h2><span>Software developement and consulting</span></h2>
|
||||
</div>
|
||||
<div id="main">
|
||||
<h1 class="title">libtorrent manual</h1>
|
||||
<table class="docinfo" frame="void" rules="none">
|
||||
<col class="docinfo-name" />
|
||||
<col class="docinfo-content" />
|
||||
<tbody valign="top">
|
||||
<tr><th class="docinfo-name">Author:</th>
|
||||
<td>Arvid Norberg, <a class="last reference external" href="mailto:arvid@rasterbar.com">arvid@rasterbar.com</a></td></tr>
|
||||
<tr><th class="docinfo-name">Version:</th>
|
||||
<td>0.16.0</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="contents topic" id="table-of-contents">
|
||||
<p class="topic-title first">Table of contents</p>
|
||||
<ul class="simple">
|
||||
<li><a class="reference internal" href="#introduction" id="id2">introduction</a></li>
|
||||
<li><a class="reference internal" href="#features" id="id3">features</a><ul>
|
||||
<li><a class="reference internal" href="#extensions" id="id4">extensions</a></li>
|
||||
<li><a class="reference internal" href="#disk-management" id="id5">disk management</a></li>
|
||||
<li><a class="reference internal" href="#network" id="id6">network</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#highlighted-features" id="id7">highlighted features</a><ul>
|
||||
<li><a class="reference internal" href="#disk-caching" id="id8">disk caching</a></li>
|
||||
<li><a class="reference internal" href="#high-performance-disk-subsystem" id="id9">high performance disk subsystem</a></li>
|
||||
<li><a class="reference internal" href="#network-buffers" id="id10">network buffers</a></li>
|
||||
<li><a class="reference internal" href="#piece-picker" id="id11">piece picker</a></li>
|
||||
<li><a class="reference internal" href="#share-mode" id="id12">share mode</a></li>
|
||||
<li><a class="reference internal" href="#merkle-hash-tree-torrents" id="id13">merkle hash tree torrents</a></li>
|
||||
<li><a class="reference internal" href="#customizable-file-storage" id="id14">customizable file storage</a></li>
|
||||
<li><a class="reference internal" href="#easy-to-use-api" id="id15">easy to use API</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#portability" id="id16">portability</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="section" id="introduction">
|
||||
<h1>introduction</h1>
|
||||
<p>libtorrent is a feature complete C++ bittorrent implementation focusing
|
||||
on efficiency and scalability. It runs on embedded devices as well as
|
||||
desktops. It boasts a well documented library interface that is easy to
|
||||
use. It comes with a simple bittorrent client demonstrating the use of
|
||||
the library.</p>
|
||||
</div>
|
||||
<div class="section" id="features">
|
||||
<h1>features</h1>
|
||||
<p>libtorrent is under active development. It is an ongoing project. Its
|
||||
current state supports and includes the following features:</p>
|
||||
<div class="section" id="extensions">
|
||||
<h2>extensions</h2>
|
||||
<ul class="simple">
|
||||
<li>plugin interface for implementing custom bittorrent extensions
|
||||
without having to modify libtorrent</li>
|
||||
<li>supports trackerless torrents (using the Mainline kademlia DHT protocol) with
|
||||
some <a class="reference external" href="dht_extensions.html">DHT extensions</a>. <a class="reference external" href="http://bittorrent.org/beps/bep_0005.html">BEP 5</a>.</li>
|
||||
<li>supports the bittorrent <a class="reference external" href="extension_protocol.html">extension protocol</a>. See <a class="reference external" href="manual.html#extensions">extensions</a>. <a class="reference external" href="http://bittorrent.org/beps/bep_0010.html">BEP 10</a>.</li>
|
||||
<li>supports the uTorrent metadata transfer protocol <a class="reference external" href="http://bittorrent.org/beps/bep_0009.html">BEP 9</a> (i.e. magnet links).</li>
|
||||
<li>supports the uTorrent peer exchange protocol (PEX).</li>
|
||||
<li>supports local peer discovery (multicasts for peers on the same local network)</li>
|
||||
<li>multitracker extension support (supports both strict <a class="reference external" href="http://bittorrent.org/beps/bep_0012.html">BEP 12</a> and the
|
||||
uTorrent interpretation).</li>
|
||||
<li>tracker scrapes</li>
|
||||
<li>supports lt_trackers extension, to exchange trackers between peers</li>
|
||||
<li><a class="reference external" href="manual.html#http-seeding">HTTP seeding</a>, as specified in <a class="reference external" href="http://bittorrent.org/beps/bep_0017.html">BEP 17</a> and <a class="reference external" href="http://bittorrent.org/beps/bep_0019.html">BEP 19</a>.</li>
|
||||
<li>supports the udp-tracker protocol. (<a class="reference external" href="http://bittorrent.org/beps/bep_0015.html">BEP 15</a>).</li>
|
||||
<li>supports the <tt class="docutils literal"><span class="pre">no_peer_id=1</span></tt> extension that will ease the load off trackers.</li>
|
||||
<li>supports the <tt class="docutils literal"><span class="pre">compact=1</span></tt> tracker parameter.</li>
|
||||
<li>super seeding/initial seeding (<a class="reference external" href="http://bittorrent.org/beps/bep_0016.html">BEP 16</a>).</li>
|
||||
<li>private torrents (<a class="reference external" href="http://bittorrent.org/beps/bep_0027.html">BEP 27</a>).</li>
|
||||
<li>upload-only extension (<a class="reference external" href="http://bittorrent.org/beps/bep_0021.html">BEP 21</a>).</li>
|
||||
<li>support for IPv6, including <a class="reference external" href="http://bittorrent.org/beps/bep_0007.html">BEP 7</a> and <a class="reference external" href="http://bittorrent.org/beps/bep_0024.html">BEP 24</a>.</li>
|
||||
<li>support for merkle hash tree torrents. This makes the size of torrent files
|
||||
scale well with the size of the content.</li>
|
||||
<li>share-mode. This is a special mode torrents can be put in to optimize share
|
||||
ratio rather than downloading the torrent.</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="section" id="disk-management">
|
||||
<h2>disk management</h2>
|
||||
<ul class="simple">
|
||||
<li>uses a separate disk I/O thread to not have the disk ever block on network or
|
||||
client interaction. (see <a class="reference external" href="manual.html#threads">threads</a>).</li>
|
||||
<li>supports files > 2 gigabytes.</li>
|
||||
<li>fast resume support, a way to get rid of the costly piece check at the
|
||||
start of a resumed torrent. Saves the storage state, piece_picker state
|
||||
as well as all local peers in a separate fast-resume file.</li>
|
||||
<li>has an adjustable read and write disk cache for improved disk throughput.</li>
|
||||
<li>queues torrents for file check, instead of checking all of them in parallel.</li>
|
||||
<li>does not have any requirements on the piece order in a torrent that it
|
||||
resumes. This means it can resume a torrent downloaded by any client.</li>
|
||||
<li>supports both sparse files and compact file allocation (where pieces
|
||||
are kept consolidated on disk)</li>
|
||||
<li>seed mode, where the files on disk are assumed to be complete, and each
|
||||
piece's hash is verified the first time it is requested.</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="section" id="network">
|
||||
<h2>network</h2>
|
||||
<ul class="simple">
|
||||
<li>a high quality uTP implementation (<a href="#id17"><span class="problematic" id="id18">BEP29_</span></a>). A transport protocol with
|
||||
delay based congestion control. See separate <a class="reference external" href="utp.html">article</a>.</li>
|
||||
<li>adjusts the length of the request queue depending on download rate.</li>
|
||||
<li>serves multiple torrents on a single port and in a single thread</li>
|
||||
<li>piece picking on block-level (as opposed to piece-level).
|
||||
This means it can download parts of the same piece from different peers.
|
||||
It will also prefer to download whole pieces from single peers if the
|
||||
download speed is high enough from that particular peer.</li>
|
||||
<li>supports http proxies and basic proxy authentication</li>
|
||||
<li>supports gzipped tracker-responses</li>
|
||||
<li>can limit the upload and download bandwidth usage and the maximum number of
|
||||
unchoked peers</li>
|
||||
<li>possibility to limit the number of connections.</li>
|
||||
<li>delays have messages if there's no other outgoing traffic to the peer, and
|
||||
doesn't send have messages to peers that already has the piece. This saves
|
||||
bandwidth.</li>
|
||||
<li>selective downloading. The ability to select which parts of a torrent you
|
||||
want to download.</li>
|
||||
<li>ip filter to disallow ip addresses and ip ranges from connecting and
|
||||
being connected.</li>
|
||||
<li>NAT-PMP and UPnP support (automatic port mapping on routers that supports it)</li>
|
||||
<li>implements automatic upload slots, to optimize download rate without spreading
|
||||
upload capacity too thin. The number of upload slots is adjusted based on the
|
||||
peers' download capacity to work even for connections that are orders of
|
||||
magnitude faster than others.</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" id="highlighted-features">
|
||||
<h1>highlighted features</h1>
|
||||
<div class="section" id="disk-caching">
|
||||
<h2>disk caching</h2>
|
||||
<p>All disk I/O in libtorrent is done asynchronously to the network thread, by the
|
||||
disk io thread. When a block is read, the disk io thread reads all subsequent
|
||||
blocks from that piece into the read cache, assuming that the peer requesting
|
||||
the block will also request more blocks from the same piece. This decreases the
|
||||
number of syscalls for reading data. It also decreases delay from seeking.</p>
|
||||
<p>Similarly, for write requests, blocks are cached and flushed to disk once one full
|
||||
piece is complete or the piece is the least recently updated one when more cache
|
||||
space is needed. The cache dynamically allocates space between the write and read
|
||||
cache. The write cache is strictly prioritized over the read cache.</p>
|
||||
<p>The cache blocks that are in used, are locked into physical memory to avoid it
|
||||
being paged out to disk. Allowing the disk cache to be paged out to disk means
|
||||
that it would become extremely inefficient to flush it, since it would have to be
|
||||
read back into physical memory only to be flushed back out to disk again.</p>
|
||||
<p>In order to conserve memory, and system calls, iovec file operations are
|
||||
used to flush multiple cache blocks in a single call.</p>
|
||||
<p>On low-memory systems, the disk cache can be disabled altogether or set to smaller
|
||||
limit, to save memory.</p>
|
||||
<p>The disk caching algorithm is configurable between 'LRU' and 'largest contiguous'.
|
||||
The largest contiguous algorithm is the default and flushes the largest contiguous
|
||||
block of buffers, instead of flushing all blocks belonging to the piece which was
|
||||
written to least recently.</p>
|
||||
<p>For version 0.15 a lot of work went into optimizing the cache algorithm, trying
|
||||
to increase the cache hit rate and utilization. The graph to the left shows the
|
||||
memory utilization in 0.14. This cache is a straight forward, fairly naive, implementation.
|
||||
Every block read will also read all subsequent blocks in that piece into the cache.
|
||||
Whenever we need more space, the entire oldest piece is evicted from the cache. Caching
|
||||
writes always takes presedence over the read cache. Whenever a piece is fully downloaded,
|
||||
it is flushed to disk.</p>
|
||||
<img alt="disk_buffer_before_optimization.png" src="disk_buffer_before_optimization.png" style="width: 49%;" />
|
||||
<img alt="disk_buffer.png" src="disk_buffer.png" style="width: 49%;" />
|
||||
<p>The left graph shows the problem of evicting entire pieces at a time, and waiting until
|
||||
an entire piece is downloaded until flushing it. These graphs were generated for a torrent
|
||||
with fairly large pieces. This means that granularity was poor in 0.14, since it only
|
||||
dealt with entire pieces. In 0.15, the granularity problem has been fixed by evicting one
|
||||
block at a time from the read cache. This maximizes the read cache utilization. The write
|
||||
cache is also flushed when a sufficient number of contiguous blocks have been downloaded
|
||||
for a piece, which is not tied to the piece size anymore. This way the cache scales a lot
|
||||
better with piece sizes.</p>
|
||||
<p>The graph to the right shows the same download but with the new optimized disk cache
|
||||
algorithm. It clearly shows an increased utilization, which means higher read hit rates
|
||||
or smaller caches with maintained hit rate.</p>
|
||||
</div>
|
||||
<div class="section" id="high-performance-disk-subsystem">
|
||||
<h2>high performance disk subsystem</h2>
|
||||
<p>In some circumstances, the disk cache may not suffice to provide maximum performance.
|
||||
One such example is high performance seeding, to a large number of peers, over a fast
|
||||
up-link. In such a case, the amount of RAM may simply not be enough to cache disk
|
||||
reads. When there's not enough RAM to cache disk reads, the disk throughput would
|
||||
typically degrade to perform as poorly as with no cache at all, with the majority
|
||||
of the time spent waiting for the disk head to seek.</p>
|
||||
<p>To solve this problem, libtorrent sorts read requests by their physical offset on the
|
||||
disk. They are processed by having the disk read head sweep back and forth over the drive.</p>
|
||||
<p>This makes libtorrent very suitable for large scale, high-throughput seeding.</p>
|
||||
<img alt="disk_access_no_elevator.png" src="disk_access_no_elevator.png" style="width: 49%;" />
|
||||
<img alt="disk_access_elevator.png" src="disk_access_elevator.png" style="width: 49%;" />
|
||||
<p>These plots illustrates the physical disk offset for reads over time. The left plot
|
||||
is of a run where disk operation re-ordering is turned off and the righ is when it's
|
||||
turned on. The right one has a relatively smooth sine wave shape whereas the left
|
||||
one is more random and involves much longer seeks back and forth over the disk.</p>
|
||||
<p>True physical disk offset queries are only supported on newer linux kernels, Mac OS X and
|
||||
Windows 2000 and up.</p>
|
||||
</div>
|
||||
<div class="section" id="network-buffers">
|
||||
<h2>network buffers</h2>
|
||||
<p>On CPUs with small L2 caches, copying memory can be expensive operations. It is important
|
||||
to keep copying to a minimum on such machines. This mostly applies to embedded systems.</p>
|
||||
<p>In order to minimize the number of times received data is copied, the receive buffer
|
||||
for payload data is received directly into a page aligned disk buffer. If the connection
|
||||
is encrypted, the buffer is decrypted in-place. The buffer is then moved into the disk
|
||||
cache without being copied. Once all the blocks for a piece have been received, or the
|
||||
cache needs to be flushed, all the blocks are passed directly to <tt class="docutils literal"><span class="pre">writev()</span></tt> to flush
|
||||
them in a single syscall. This means a single copy into user space memory, and a single
|
||||
copy back into kernel memory, as illustrated by this figure:</p>
|
||||
<img alt="write_disk_buffers.png" src="write_disk_buffers.png" style="width: 100%;" />
|
||||
<p>When seeding and uploading in general, unnecessary copying is avoided by caching blocks
|
||||
in aligned buffers, that are copied once into the peer's send buffer. The peer's send buffer
|
||||
is not guaranteed to be aligned, even though it is most of the time. The send buffer is
|
||||
then encrypted with the peer specific key and chained onto the <tt class="docutils literal"><span class="pre">iovec</span></tt> for sending.
|
||||
This means there is one user space copy in order to allow unaligned peer requests and
|
||||
peer-specific encryption. This is illustrated by the following figure:</p>
|
||||
<img alt="read_disk_buffers.png" src="read_disk_buffers.png" style="width: 100%;" />
|
||||
</div>
|
||||
<div class="section" id="piece-picker">
|
||||
<h2>piece picker</h2>
|
||||
<p>The piece picker is a central component in a bittorrent implementation. The piece picker
|
||||
in libtorrent is optimized for quickly finding the rarest pieces. It keeps a list of all
|
||||
available pieces sorted by rarity, and pieces with the same rarity, shuffled. The rarest
|
||||
first mode is the dominant piece picker mode. Other modes are supported as well, and
|
||||
used by peers in specific situations.</p>
|
||||
<p>The piece picker allows to combine the availability of a piece with a priority. Together
|
||||
they determine the sort order of the piece list. Pieces with priority 0 will never be
|
||||
picked, which is used for the selective download feature.</p>
|
||||
<p>In order to have as few partially finished pieces as possible, peers have an affinity
|
||||
towards picking blocks from the same pieces as other peers in the same speed category.
|
||||
The speed category is a coarse categorization of peers based on their download rate. This
|
||||
makes slow peers pick blocks from the same piece, and fast peers pick from the same piece,
|
||||
and hence decreasing the likelihood of slow peers blocking the completion of pieces.</p>
|
||||
<p>The piece picker can also be set to download pieces in sequential order.</p>
|
||||
</div>
|
||||
<div class="section" id="share-mode">
|
||||
<h2>share mode</h2>
|
||||
<p>The share mode feature in libtorrent is intended for users who are only interested in
|
||||
helping out swarms, not downloading the torrents.</p>
|
||||
<p>It works by predicting the demand for pieces, and only download pieces if there is enough
|
||||
demand. New pieces will only be downloaded once the share ratio has hit a certain target.</p>
|
||||
<p>This feature is especially useful when combined with RSS, so that a client can be set up
|
||||
to provide additional bandwidth to an entire feed.</p>
|
||||
</div>
|
||||
<div class="section" id="merkle-hash-tree-torrents">
|
||||
<h2>merkle hash tree torrents</h2>
|
||||
<p>Merkle hash tree torrents is an extension that lets a torrent file only contain the
|
||||
root hash of the hash tree forming the piece hashes. The main benefit of this feature
|
||||
is that regardless of how many pieces there is in a torrent, the .torrent file will
|
||||
always be the same size. It will only grow with the number of files (since it still
|
||||
has to contain the file names).</p>
|
||||
<p>With regular torrents, clients have to request multiple blocks for pieces, typically
|
||||
from different peers, before the data can be verified against the piece hash. The
|
||||
larger the pieces are, the longer it will take to download a complete piece and verify
|
||||
it. Before the piece is verified, it cannot be shared with the swarm, which means the
|
||||
larger piece sizes, the slower turnaround data has when it is downloaded by peers.
|
||||
Since on average the data has to sit around, waiting, in client buffers before it has
|
||||
been verified and can be uploaded again.</p>
|
||||
<p>Another problem with large piece sizes is that it is harder for a client to pinpoint
|
||||
the malicious or buggy peer when a piece fails, and it will take longer to re-download
|
||||
it and take more tries before the piece succeeds the larger the pieces are.</p>
|
||||
<p>The piece size in regular torrents is a tradeoff between the size of the .torrent file
|
||||
itself and the piece size. Often, for files that are 4 GB, the piece size is 2 or 4 MB,
|
||||
just to avoid making the .torrent file too big.</p>
|
||||
<p>Merkle torrents solves these problems by removing the tradeoff between .torrent size and
|
||||
piece size. With merkle torrents, the piece size can be the minimum block size (16 kB),
|
||||
which lets peers verify every block of data received from peers, immediately. This
|
||||
gives a minimum turnaround time and completely removes the problem of identifying malicious
|
||||
peers.</p>
|
||||
<img alt="merkle_tree.png" src="merkle_tree.png" />
|
||||
<p>The root hash is built by hashing all the piece hashes pair-wise, until they all collapse
|
||||
down to the root.</p>
|
||||
<img align="right" alt="storage.png" class="align-right" src="storage.png" />
|
||||
</div>
|
||||
<div class="section" id="customizable-file-storage">
|
||||
<h2>customizable file storage</h2>
|
||||
<p>libtorrent's storage implementation is customizable. That means a special purpose bittorrent
|
||||
client can replace the default way to store files on disk.</p>
|
||||
<p>When implementing a bittorrent cache, it doesn't matter how the data is stored on disk, as
|
||||
long as it can be retrieved and seeded. In that case a new storage class can be implemented
|
||||
(inheriting from the <tt class="docutils literal"><span class="pre">storage_interface</span></tt> class) that avoids the unnecessary step of mapping
|
||||
slots to files and offsets. The storage can ignore the file boundaries and just store the
|
||||
entire torrent in a single file (which will end up being all the files concatenated). The main
|
||||
advantage of this, other than a slight cpu performance gain, is that all file operations would
|
||||
be page (and sector) aligned. This enables efficient unbuffered I/O, and can potentially
|
||||
lead to more efficient read caching (using the built in disk cache rather than relying on the
|
||||
operating system's disk cache).</p>
|
||||
<p>The storage interface supports operating systems where you can ask for sparse regions
|
||||
(such as Windows and Solaris). The advantage of this is that when checking files, the regions
|
||||
that are known to be sparse can be skipped, which can reduce the time to check a torrent
|
||||
significantly.</p>
|
||||
</div>
|
||||
<div class="section" id="easy-to-use-api">
|
||||
<h2>easy to use API</h2>
|
||||
<p>One of the design goals of the libtorrent API is to make common operations simple, but still
|
||||
have it possible to do complicated and advanced operations. This is best illustrated by example
|
||||
code to implement a simple bittorrent client:</p>
|
||||
<pre class="literal-block">
|
||||
#include <iostream>
|
||||
#include "libtorrent/session.hpp"
|
||||
|
||||
// usage a.out [torrent-file]
|
||||
int main(int argc, char* argv[]) try
|
||||
{
|
||||
using namespace libtorrent;
|
||||
|
||||
session s;
|
||||
s.listen_on(std::make_pair(6881, 6889));
|
||||
add_torrent_params p;
|
||||
p.save_path = "./";
|
||||
p.ti = new torrent_info(argv[1]);
|
||||
s.add_torrent(p);
|
||||
|
||||
// wait for the user to end
|
||||
char a;
|
||||
std::cin.unsetf(std::ios_base::skipws);
|
||||
std::cin >> a;
|
||||
return 0;
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
std::cerr << ec.what() << std::endl;
|
||||
return 1;
|
||||
}
|
||||
</pre>
|
||||
<p>This client doesn't give the user any status information or progress about the torrent, but
|
||||
it is fully functional.</p>
|
||||
<p>libtorrent also comes with python bindings for easy access for python developers.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" id="portability">
|
||||
<h1>portability</h1>
|
||||
<p>libtorrent runs on most major operating systems, including Windows,
|
||||
MacOS X, Linux, BSD and Solaris.
|
||||
It uses Boost.Thread, Boost.Filesystem, Boost.Date_time and various other
|
||||
boost libraries as well as <a class="reference external" href="http://www.zlib.org">zlib</a> (shipped) and <a class="reference external" href="http://asio.sf.net">asio</a> (shipped). At least version
|
||||
1.34.1 of boost is required.</p>
|
||||
<p>libtorrent uses asio, hence it will take full advantage of high performance
|
||||
network APIs on the most popular platforms. I/O completion ports on windows,
|
||||
epoll on linux and kqueue on MacOS X and BSD.</p>
|
||||
<p>libtorrent has been successfully compiled and tested on:</p>
|
||||
<ul class="simple">
|
||||
<li>Windows 2000, XP and Vista vc7.1, vc8</li>
|
||||
<li>Linux x86 GCC 3.3, GCC 3.4.2, 4.x</li>
|
||||
<li>Linux PPC GCC 4.1.1</li>
|
||||
<li>MacOS X (darwin), (Apple's) GCC 3.3, (Apple's) GCC 4.0</li>
|
||||
<li>SunOS 5.8 GCC 3.1 and Sunpro</li>
|
||||
<li>Cygwin GCC 3.3.3</li>
|
||||
</ul>
|
||||
<p>Fails on:</p>
|
||||
<ul class="simple">
|
||||
<li>GCC 2.95.4</li>
|
||||
<li>msvc6</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="system-messages section">
|
||||
<h1>Docutils System Messages</h1>
|
||||
<div class="system-message" id="id17">
|
||||
<p class="system-message-title">System Message: ERROR/3 (<tt class="docutils">features.rst</tt>, line 82); <em><a href="#id18">backlink</a></em></p>
|
||||
Unknown target name: "bep29".</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="footer">
|
||||
<span>Copyright © 2005 Rasterbar Software.</span>
|
||||
</div>
|
||||
</div>
|
||||
<script src="http://www.google-analytics.com/urchin.js" type="text/javascript">
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
_uacct = "UA-1599045-1";
|
||||
urchinTracker();
|
||||
</script>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -1,405 +0,0 @@
|
|||
=================
|
||||
libtorrent manual
|
||||
=================
|
||||
|
||||
:Author: Arvid Norberg, arvid@rasterbar.com
|
||||
:Version: 0.16.0
|
||||
|
||||
.. contents:: Table of contents
|
||||
:depth: 2
|
||||
:backlinks: none
|
||||
|
||||
introduction
|
||||
============
|
||||
|
||||
libtorrent is a feature complete C++ bittorrent implementation focusing
|
||||
on efficiency and scalability. It runs on embedded devices as well as
|
||||
desktops. It boasts a well documented library interface that is easy to
|
||||
use. It comes with a simple bittorrent client demonstrating the use of
|
||||
the library.
|
||||
|
||||
features
|
||||
========
|
||||
|
||||
libtorrent is under active development. It is an ongoing project. Its
|
||||
current state supports and includes the following features:
|
||||
|
||||
extensions
|
||||
----------
|
||||
|
||||
* plugin interface for implementing custom bittorrent extensions
|
||||
without having to modify libtorrent
|
||||
* supports trackerless torrents (using the Mainline kademlia DHT protocol) with
|
||||
some `DHT extensions`_. `BEP 5`_.
|
||||
* supports the bittorrent `extension protocol`_. See extensions_. `BEP 10`_.
|
||||
* supports the uTorrent metadata transfer protocol `BEP 9`_ (i.e. magnet links).
|
||||
* supports the uTorrent peer exchange protocol (PEX).
|
||||
* supports local peer discovery (multicasts for peers on the same local network)
|
||||
* multitracker extension support (supports both strict `BEP 12`_ and the
|
||||
uTorrent interpretation).
|
||||
* tracker scrapes
|
||||
* supports lt_trackers extension, to exchange trackers between peers
|
||||
* `HTTP seeding`_, as specified in `BEP 17`_ and `BEP 19`_.
|
||||
* supports the udp-tracker protocol. (`BEP 15`_).
|
||||
* supports the ``no_peer_id=1`` extension that will ease the load off trackers.
|
||||
* supports the ``compact=1`` tracker parameter.
|
||||
* super seeding/initial seeding (`BEP 16`_).
|
||||
* private torrents (`BEP 27`_).
|
||||
* upload-only extension (`BEP 21`_).
|
||||
* support for IPv6, including `BEP 7`_ and `BEP 24`_.
|
||||
* support for merkle hash tree torrents. This makes the size of torrent files
|
||||
scale well with the size of the content.
|
||||
* share-mode. This is a special mode torrents can be put in to optimize share
|
||||
ratio rather than downloading the torrent.
|
||||
|
||||
.. _article: utp.html
|
||||
.. _extensions: manual.html#extensions
|
||||
.. _`http seeding`: manual.html#http-seeding
|
||||
|
||||
disk management
|
||||
---------------
|
||||
|
||||
* uses a separate disk I/O thread to not have the disk ever block on network or
|
||||
client interaction. (see threads_).
|
||||
* supports files > 2 gigabytes.
|
||||
* fast resume support, a way to get rid of the costly piece check at the
|
||||
start of a resumed torrent. Saves the storage state, piece_picker state
|
||||
as well as all local peers in a separate fast-resume file.
|
||||
* has an adjustable read and write disk cache for improved disk throughput.
|
||||
* queues torrents for file check, instead of checking all of them in parallel.
|
||||
* does not have any requirements on the piece order in a torrent that it
|
||||
resumes. This means it can resume a torrent downloaded by any client.
|
||||
* supports both sparse files and compact file allocation (where pieces
|
||||
are kept consolidated on disk)
|
||||
* seed mode, where the files on disk are assumed to be complete, and each
|
||||
piece's hash is verified the first time it is requested.
|
||||
|
||||
.. _threads: manual.html#threads
|
||||
|
||||
network
|
||||
-------
|
||||
|
||||
* a high quality uTP implementation (BEP29_). A transport protocol with
|
||||
delay based congestion control. See separate article_.
|
||||
* adjusts the length of the request queue depending on download rate.
|
||||
* serves multiple torrents on a single port and in a single thread
|
||||
* piece picking on block-level (as opposed to piece-level).
|
||||
This means it can download parts of the same piece from different peers.
|
||||
It will also prefer to download whole pieces from single peers if the
|
||||
download speed is high enough from that particular peer.
|
||||
* supports http proxies and basic proxy authentication
|
||||
* supports gzipped tracker-responses
|
||||
* can limit the upload and download bandwidth usage and the maximum number of
|
||||
unchoked peers
|
||||
* possibility to limit the number of connections.
|
||||
* delays have messages if there's no other outgoing traffic to the peer, and
|
||||
doesn't send have messages to peers that already has the piece. This saves
|
||||
bandwidth.
|
||||
* selective downloading. The ability to select which parts of a torrent you
|
||||
want to download.
|
||||
* ip filter to disallow ip addresses and ip ranges from connecting and
|
||||
being connected.
|
||||
* NAT-PMP and UPnP support (automatic port mapping on routers that supports it)
|
||||
* implements automatic upload slots, to optimize download rate without spreading
|
||||
upload capacity too thin. The number of upload slots is adjusted based on the
|
||||
peers' download capacity to work even for connections that are orders of
|
||||
magnitude faster than others.
|
||||
|
||||
|
||||
.. _`DHT extensions`: dht_extensions.html
|
||||
.. _`BEP 5`: http://bittorrent.org/beps/bep_0005.html
|
||||
.. _`BEP 7`: http://bittorrent.org/beps/bep_0007.html
|
||||
.. _`BEP 9`: http://bittorrent.org/beps/bep_0009.html
|
||||
.. _`BEP 10`: http://bittorrent.org/beps/bep_0010.html
|
||||
.. _`BEP 12`: http://bittorrent.org/beps/bep_0012.html
|
||||
.. _`BEP 15`: http://bittorrent.org/beps/bep_0015.html
|
||||
.. _`BEP 16`: http://bittorrent.org/beps/bep_0016.html
|
||||
.. _`BEP 17`: http://bittorrent.org/beps/bep_0017.html
|
||||
.. _`BEP 19`: http://bittorrent.org/beps/bep_0019.html
|
||||
.. _`BEP 21`: http://bittorrent.org/beps/bep_0021.html
|
||||
.. _`BEP 24`: http://bittorrent.org/beps/bep_0024.html
|
||||
.. _`BEP 27`: http://bittorrent.org/beps/bep_0027.html
|
||||
.. _`BEP 29`: http://bittorrent.org/beps/bep_0029.html
|
||||
.. _`extension protocol`: extension_protocol.html
|
||||
|
||||
highlighted features
|
||||
====================
|
||||
|
||||
disk caching
|
||||
------------
|
||||
|
||||
All disk I/O in libtorrent is done asynchronously to the network thread, by the
|
||||
disk io thread. When a block is read, the disk io thread reads all subsequent
|
||||
blocks from that piece into the read cache, assuming that the peer requesting
|
||||
the block will also request more blocks from the same piece. This decreases the
|
||||
number of syscalls for reading data. It also decreases delay from seeking.
|
||||
|
||||
Similarly, for write requests, blocks are cached and flushed to disk once one full
|
||||
piece is complete or the piece is the least recently updated one when more cache
|
||||
space is needed. The cache dynamically allocates space between the write and read
|
||||
cache. The write cache is strictly prioritized over the read cache.
|
||||
|
||||
The cache blocks that are in used, are locked into physical memory to avoid it
|
||||
being paged out to disk. Allowing the disk cache to be paged out to disk means
|
||||
that it would become extremely inefficient to flush it, since it would have to be
|
||||
read back into physical memory only to be flushed back out to disk again.
|
||||
|
||||
In order to conserve memory, and system calls, iovec file operations are
|
||||
used to flush multiple cache blocks in a single call.
|
||||
|
||||
On low-memory systems, the disk cache can be disabled altogether or set to smaller
|
||||
limit, to save memory.
|
||||
|
||||
The disk caching algorithm is configurable between 'LRU' and 'largest contiguous'.
|
||||
The largest contiguous algorithm is the default and flushes the largest contiguous
|
||||
block of buffers, instead of flushing all blocks belonging to the piece which was
|
||||
written to least recently.
|
||||
|
||||
For version 0.15 a lot of work went into optimizing the cache algorithm, trying
|
||||
to increase the cache hit rate and utilization. The graph to the left shows the
|
||||
memory utilization in 0.14. This cache is a straight forward, fairly naive, implementation.
|
||||
Every block read will also read all subsequent blocks in that piece into the cache.
|
||||
Whenever we need more space, the entire oldest piece is evicted from the cache. Caching
|
||||
writes always takes presedence over the read cache. Whenever a piece is fully downloaded,
|
||||
it is flushed to disk.
|
||||
|
||||
.. image:: disk_buffer_before_optimization.png
|
||||
:width: 49%
|
||||
|
||||
.. image:: disk_buffer.png
|
||||
:width: 49%
|
||||
|
||||
The left graph shows the problem of evicting entire pieces at a time, and waiting until
|
||||
an entire piece is downloaded until flushing it. These graphs were generated for a torrent
|
||||
with fairly large pieces. This means that granularity was poor in 0.14, since it only
|
||||
dealt with entire pieces. In 0.15, the granularity problem has been fixed by evicting one
|
||||
block at a time from the read cache. This maximizes the read cache utilization. The write
|
||||
cache is also flushed when a sufficient number of contiguous blocks have been downloaded
|
||||
for a piece, which is not tied to the piece size anymore. This way the cache scales a lot
|
||||
better with piece sizes.
|
||||
|
||||
The graph to the right shows the same download but with the new optimized disk cache
|
||||
algorithm. It clearly shows an increased utilization, which means higher read hit rates
|
||||
or smaller caches with maintained hit rate.
|
||||
|
||||
high performance disk subsystem
|
||||
-------------------------------
|
||||
|
||||
In some circumstances, the disk cache may not suffice to provide maximum performance.
|
||||
One such example is high performance seeding, to a large number of peers, over a fast
|
||||
up-link. In such a case, the amount of RAM may simply not be enough to cache disk
|
||||
reads. When there's not enough RAM to cache disk reads, the disk throughput would
|
||||
typically degrade to perform as poorly as with no cache at all, with the majority
|
||||
of the time spent waiting for the disk head to seek.
|
||||
|
||||
To solve this problem, libtorrent sorts read requests by their physical offset on the
|
||||
disk. They are processed by having the disk read head sweep back and forth over the drive.
|
||||
|
||||
This makes libtorrent very suitable for large scale, high-throughput seeding.
|
||||
|
||||
.. image:: disk_access_no_elevator.png
|
||||
:width: 49%
|
||||
|
||||
.. image:: disk_access_elevator.png
|
||||
:width: 49%
|
||||
|
||||
These plots illustrates the physical disk offset for reads over time. The left plot
|
||||
is of a run where disk operation re-ordering is turned off and the righ is when it's
|
||||
turned on. The right one has a relatively smooth sine wave shape whereas the left
|
||||
one is more random and involves much longer seeks back and forth over the disk.
|
||||
|
||||
True physical disk offset queries are only supported on newer linux kernels, Mac OS X and
|
||||
Windows 2000 and up.
|
||||
|
||||
network buffers
|
||||
---------------
|
||||
|
||||
On CPUs with small L2 caches, copying memory can be expensive operations. It is important
|
||||
to keep copying to a minimum on such machines. This mostly applies to embedded systems.
|
||||
|
||||
In order to minimize the number of times received data is copied, the receive buffer
|
||||
for payload data is received directly into a page aligned disk buffer. If the connection
|
||||
is encrypted, the buffer is decrypted in-place. The buffer is then moved into the disk
|
||||
cache without being copied. Once all the blocks for a piece have been received, or the
|
||||
cache needs to be flushed, all the blocks are passed directly to ``writev()`` to flush
|
||||
them in a single syscall. This means a single copy into user space memory, and a single
|
||||
copy back into kernel memory, as illustrated by this figure:
|
||||
|
||||
.. image:: write_disk_buffers.png
|
||||
:width: 100%
|
||||
|
||||
When seeding and uploading in general, unnecessary copying is avoided by caching blocks
|
||||
in aligned buffers, that are copied once into the peer's send buffer. The peer's send buffer
|
||||
is not guaranteed to be aligned, even though it is most of the time. The send buffer is
|
||||
then encrypted with the peer specific key and chained onto the ``iovec`` for sending.
|
||||
This means there is one user space copy in order to allow unaligned peer requests and
|
||||
peer-specific encryption. This is illustrated by the following figure:
|
||||
|
||||
.. image:: read_disk_buffers.png
|
||||
:width: 100%
|
||||
|
||||
|
||||
piece picker
|
||||
------------
|
||||
|
||||
The piece picker is a central component in a bittorrent implementation. The piece picker
|
||||
in libtorrent is optimized for quickly finding the rarest pieces. It keeps a list of all
|
||||
available pieces sorted by rarity, and pieces with the same rarity, shuffled. The rarest
|
||||
first mode is the dominant piece picker mode. Other modes are supported as well, and
|
||||
used by peers in specific situations.
|
||||
|
||||
The piece picker allows to combine the availability of a piece with a priority. Together
|
||||
they determine the sort order of the piece list. Pieces with priority 0 will never be
|
||||
picked, which is used for the selective download feature.
|
||||
|
||||
In order to have as few partially finished pieces as possible, peers have an affinity
|
||||
towards picking blocks from the same pieces as other peers in the same speed category.
|
||||
The speed category is a coarse categorization of peers based on their download rate. This
|
||||
makes slow peers pick blocks from the same piece, and fast peers pick from the same piece,
|
||||
and hence decreasing the likelihood of slow peers blocking the completion of pieces.
|
||||
|
||||
The piece picker can also be set to download pieces in sequential order.
|
||||
|
||||
share mode
|
||||
----------
|
||||
|
||||
The share mode feature in libtorrent is intended for users who are only interested in
|
||||
helping out swarms, not downloading the torrents.
|
||||
|
||||
It works by predicting the demand for pieces, and only download pieces if there is enough
|
||||
demand. New pieces will only be downloaded once the share ratio has hit a certain target.
|
||||
|
||||
This feature is especially useful when combined with RSS, so that a client can be set up
|
||||
to provide additional bandwidth to an entire feed.
|
||||
|
||||
merkle hash tree torrents
|
||||
-------------------------
|
||||
|
||||
Merkle hash tree torrents is an extension that lets a torrent file only contain the
|
||||
root hash of the hash tree forming the piece hashes. The main benefit of this feature
|
||||
is that regardless of how many pieces there is in a torrent, the .torrent file will
|
||||
always be the same size. It will only grow with the number of files (since it still
|
||||
has to contain the file names).
|
||||
|
||||
With regular torrents, clients have to request multiple blocks for pieces, typically
|
||||
from different peers, before the data can be verified against the piece hash. The
|
||||
larger the pieces are, the longer it will take to download a complete piece and verify
|
||||
it. Before the piece is verified, it cannot be shared with the swarm, which means the
|
||||
larger piece sizes, the slower turnaround data has when it is downloaded by peers.
|
||||
Since on average the data has to sit around, waiting, in client buffers before it has
|
||||
been verified and can be uploaded again.
|
||||
|
||||
Another problem with large piece sizes is that it is harder for a client to pinpoint
|
||||
the malicious or buggy peer when a piece fails, and it will take longer to re-download
|
||||
it and take more tries before the piece succeeds the larger the pieces are.
|
||||
|
||||
The piece size in regular torrents is a tradeoff between the size of the .torrent file
|
||||
itself and the piece size. Often, for files that are 4 GB, the piece size is 2 or 4 MB,
|
||||
just to avoid making the .torrent file too big.
|
||||
|
||||
Merkle torrents solves these problems by removing the tradeoff between .torrent size and
|
||||
piece size. With merkle torrents, the piece size can be the minimum block size (16 kB),
|
||||
which lets peers verify every block of data received from peers, immediately. This
|
||||
gives a minimum turnaround time and completely removes the problem of identifying malicious
|
||||
peers.
|
||||
|
||||
.. image:: merkle_tree.png
|
||||
|
||||
The root hash is built by hashing all the piece hashes pair-wise, until they all collapse
|
||||
down to the root.
|
||||
|
||||
.. image:: storage.png
|
||||
:align: right
|
||||
|
||||
customizable file storage
|
||||
-------------------------
|
||||
|
||||
libtorrent's storage implementation is customizable. That means a special purpose bittorrent
|
||||
client can replace the default way to store files on disk.
|
||||
|
||||
When implementing a bittorrent cache, it doesn't matter how the data is stored on disk, as
|
||||
long as it can be retrieved and seeded. In that case a new storage class can be implemented
|
||||
(inheriting from the ``storage_interface`` class) that avoids the unnecessary step of mapping
|
||||
slots to files and offsets. The storage can ignore the file boundaries and just store the
|
||||
entire torrent in a single file (which will end up being all the files concatenated). The main
|
||||
advantage of this, other than a slight cpu performance gain, is that all file operations would
|
||||
be page (and sector) aligned. This enables efficient unbuffered I/O, and can potentially
|
||||
lead to more efficient read caching (using the built in disk cache rather than relying on the
|
||||
operating system's disk cache).
|
||||
|
||||
The storage interface supports operating systems where you can ask for sparse regions
|
||||
(such as Windows and Solaris). The advantage of this is that when checking files, the regions
|
||||
that are known to be sparse can be skipped, which can reduce the time to check a torrent
|
||||
significantly.
|
||||
|
||||
easy to use API
|
||||
---------------
|
||||
|
||||
One of the design goals of the libtorrent API is to make common operations simple, but still
|
||||
have it possible to do complicated and advanced operations. This is best illustrated by example
|
||||
code to implement a simple bittorrent client::
|
||||
|
||||
#include <iostream>
|
||||
#include "libtorrent/session.hpp"
|
||||
|
||||
// usage a.out [torrent-file]
|
||||
int main(int argc, char* argv[]) try
|
||||
{
|
||||
using namespace libtorrent;
|
||||
|
||||
session s;
|
||||
s.listen_on(std::make_pair(6881, 6889));
|
||||
add_torrent_params p;
|
||||
p.save_path = "./";
|
||||
p.ti = new torrent_info(argv[1]);
|
||||
s.add_torrent(p);
|
||||
|
||||
// wait for the user to end
|
||||
char a;
|
||||
std::cin.unsetf(std::ios_base::skipws);
|
||||
std::cin >> a;
|
||||
return 0;
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
std::cerr << ec.what() << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
This client doesn't give the user any status information or progress about the torrent, but
|
||||
it is fully functional.
|
||||
|
||||
libtorrent also comes with python bindings for easy access for python developers.
|
||||
|
||||
|
||||
portability
|
||||
===========
|
||||
|
||||
libtorrent runs on most major operating systems, including Windows,
|
||||
MacOS X, Linux, BSD and Solaris.
|
||||
It uses Boost.Thread, Boost.Filesystem, Boost.Date_time and various other
|
||||
boost libraries as well as zlib_ (shipped) and asio_ (shipped). At least version
|
||||
1.34.1 of boost is required.
|
||||
|
||||
.. _zlib: http://www.zlib.org
|
||||
.. _asio: http://asio.sf.net
|
||||
|
||||
libtorrent uses asio, hence it will take full advantage of high performance
|
||||
network APIs on the most popular platforms. I/O completion ports on windows,
|
||||
epoll on linux and kqueue on MacOS X and BSD.
|
||||
|
||||
libtorrent has been successfully compiled and tested on:
|
||||
|
||||
* Windows 2000, XP and Vista vc7.1, vc8
|
||||
* Linux x86 GCC 3.3, GCC 3.4.2, 4.x
|
||||
* Linux PPC GCC 4.1.1
|
||||
* MacOS X (darwin), (Apple's) GCC 3.3, (Apple's) GCC 4.0
|
||||
* SunOS 5.8 GCC 3.1 and Sunpro
|
||||
* Cygwin GCC 3.3.3
|
||||
|
||||
Fails on:
|
||||
|
||||
* GCC 2.95.4
|
||||
* msvc6
|
||||
|
||||
|
Before Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 9.4 KiB |
Before Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 12 KiB |
|
@ -1,138 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta name="generator" content="Docutils 0.5: http://docutils.sourceforge.net/" />
|
||||
<title></title>
|
||||
<link rel="stylesheet" type="text/css" href="../../css/base.css" />
|
||||
<link rel="stylesheet" type="text/css" href="../../css/rst.css" />
|
||||
<link rel="stylesheet" href="style.css" type="text/css" />
|
||||
<style type="text/css">
|
||||
/* Hides from IE-mac \*/
|
||||
* html pre { height: 1%; }
|
||||
/* End hide from IE-mac */
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="document">
|
||||
<div id="container">
|
||||
<div id="headerNav">
|
||||
<ul>
|
||||
<li class="first"><a href="/">Home</a></li>
|
||||
<li><a href="../../products.html">Products</a></li>
|
||||
<li><a href="../../contact.html">Contact</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="header">
|
||||
<h1><span>Rasterbar Software</span></h1>
|
||||
<h2><span>Software developement and consulting</span></h2>
|
||||
</div>
|
||||
<div id="main">
|
||||
|
||||
|
||||
<div id="librarySidebar"><ul class="simple">
|
||||
<li><a class="reference external" href="http://code.google.com/p/libtorrent/downloads/list">download</a></li>
|
||||
<li><a class="reference external" href="features.html">features</a></li>
|
||||
<li><a class="reference external" href="contributing.html">contributing</a></li>
|
||||
<li><a class="reference external" href="building.html">building libtorrent</a></li>
|
||||
<li><a class="reference external" href="examples.html">examples</a></li>
|
||||
<li><a class="reference external" href="manual.html">api documentation</a></li>
|
||||
<li><a class="reference external" href="make_torrent.html">create torrents</a></li>
|
||||
<li><a class="reference external" href="running_tests.html">running tests</a></li>
|
||||
<li><a class="reference external" href="tuning.html">tuning</a></li>
|
||||
<li><a class="reference external" href="client_test.png">screenshot</a></li>
|
||||
<li><a class="reference external" href="http://lists.sourceforge.net/lists/listinfo/libtorrent-discuss">mailing list</a> (<a class="reference external" href="http://dir.gmane.org/gmane.network.bit-torrent.libtorrent">archive</a>)</li>
|
||||
<li><a class="reference external" href="projects.html">who's using libtorrent?</a></li>
|
||||
<li><a class="reference external" href="http://code.google.com/p/libtorrent/issues/entry">report bugs</a></li>
|
||||
<li><a class="reference external" href="http://www.sourceforge.net/projects/libtorrent">sourceforge page</a></li>
|
||||
<li><a class="reference external" href="http://code.google.com/p/libtorrent/wiki/index">wiki</a></li>
|
||||
</ul>
|
||||
<hr class="docutils" />
|
||||
<p>Extensions</p>
|
||||
<ul class="simple">
|
||||
<li><a class="reference external" href="utp.html">uTP</a></li>
|
||||
<li><a class="reference external" href="extension_protocol.html">extensions protocol</a></li>
|
||||
<li><a class="reference external" href="libtorrent_plugins.html">plugin interface</a></li>
|
||||
<li><a class="reference external" href="dht_extensions.html">DHT extensions</a></li>
|
||||
<li><a class="reference external" href="udp_tracker_protocol.html">UDP tracker protocol</a></li>
|
||||
<li><a class="reference external" href="http://www.getright.com/seedtorrent.html">HTTP seed</a></li>
|
||||
<li><a class="reference external" href="http://bittorrent.org/beps/bep_0012.html">multitracker</a></li>
|
||||
</ul>
|
||||
<hr class="docutils" />
|
||||
<p>Bindings</p>
|
||||
<ul class="simple">
|
||||
<li><a class="reference external" href="http://libtorrent-ruby.rubyforge.org/">ruby bindings</a></li>
|
||||
<li><a class="reference external" href="python_binding.html">python bindings</a></li>
|
||||
</ul>
|
||||
<hr class="docutils" />
|
||||
<ul class="simple">
|
||||
<li><a class="reference external" href="bittorrent.pdf">Introduction, slides</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="libraryBody"><div class="section" id="libtorrent">
|
||||
<h1>libtorrent</h1>
|
||||
<p>libtorrent is a feature complete C++ bittorrent implementation focusing
|
||||
on efficiency and scalability. It runs on embedded devices as well as
|
||||
desktops. It boasts a well documented library interface that is easy to
|
||||
use. It comes with a <a class="reference external" href="client_test.html">simple bittorrent client</a> demonstrating the use of
|
||||
the library.</p>
|
||||
<p>The main goals of libtorrent are:</p>
|
||||
<ul class="simple">
|
||||
<li>to be cpu efficient</li>
|
||||
<li>to be memory efficient</li>
|
||||
<li>to be very easy to use</li>
|
||||
</ul>
|
||||
<div class="section" id="donate">
|
||||
<h2>Donate</h2>
|
||||
<p>Support the development of libtorrent</p>
|
||||
<form action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_top">
|
||||
<input type="hidden" name="cmd" value="_xclick">
|
||||
<input type="hidden" name="business" value="arvid@cs.umu.se">
|
||||
<input type="hidden" name="item_name" value="libtorrent">
|
||||
<input type="hidden" name="return" value="http://libtorrent.sf.net">
|
||||
<input type="hidden" name="currency_code" value="USD">
|
||||
<input type="hidden" name="tax" value="0">
|
||||
<input type="image" src="https://www.paypal.com/images/x-click-but04.gif"
|
||||
border="0" name="submit" alt="Make payments with PayPal - it's fast, free and secure!">
|
||||
</form></div>
|
||||
<div class="section" id="feedback">
|
||||
<h2>Feedback</h2>
|
||||
<p>There's a <a class="reference external" href="http://lists.sourceforge.net/lists/listinfo/libtorrent-discuss">mailing list</a>, general libtorrent discussion.</p>
|
||||
<p>You can usually find me as hydri in <tt class="docutils literal"><span class="pre">#libtorrent</span></tt> on <tt class="docutils literal"><span class="pre">irc.freenode.net</span></tt>.</p>
|
||||
</div>
|
||||
<div class="section" id="license">
|
||||
<h2>license</h2>
|
||||
<p>libtorrent is released under the <a class="reference external" href="http://www.opensource.org/licenses/bsd-license.php">BSD-license</a>.</p>
|
||||
<p>This means that you can use the library in your project without having to
|
||||
release its source code. The only requirement is that you give credit
|
||||
to the author of the library by including the libtorrent license in your
|
||||
software or documentation.</p>
|
||||
<p>It is however greatly appreciated if additional features are contributed
|
||||
back to the open source project. Patches can be emailed to the mailing
|
||||
list or posted to the <a class="reference external" href="http://code.rasterbar.com/libtorrent/newticket">bug tracker</a>.</p>
|
||||
</div>
|
||||
<div class="section" id="acknowledgements">
|
||||
<h2>Acknowledgements</h2>
|
||||
<p>Written by Arvid Norberg. Copyright © 2003-2009</p>
|
||||
<p>Contributions by Magnus Jonsson, Daniel Wallin and Cory Nelson</p>
|
||||
<p>Thanks to Reimond Retz for bugfixes, suggestions and testing</p>
|
||||
<p>Thanks to <a class="reference external" href="http://www.cs.umu.se">Umeå University</a> for providing development and test hardware.</p>
|
||||
<p>Project is hosted by sourceforge.</p>
|
||||
<p><a class="reference external" href="http://sourceforge.net"><img alt="sf_logo" src="http://sourceforge.net/sflogo.php?group_id=7994" /></a></p>
|
||||
</div></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="footer">
|
||||
<span>Copyright © 2005 Rasterbar Software.</span>
|
||||
</div>
|
||||
</div>
|
||||
<script src="http://www.google-analytics.com/urchin.js" type="text/javascript">
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
_uacct = "UA-1599045-1";
|
||||
urchinTracker();
|
||||
</script>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -1,169 +0,0 @@
|
|||
.. raw:: html
|
||||
|
||||
<div id="librarySidebar">
|
||||
|
||||
* download_
|
||||
* features_
|
||||
* contributing_
|
||||
* `building libtorrent`_
|
||||
* examples_
|
||||
* `api documentation`_
|
||||
* `create torrents`_
|
||||
* `running tests`_
|
||||
* `tuning`_
|
||||
* screenshot_
|
||||
* `mailing list`_ (archive_)
|
||||
* `who's using libtorrent?`_
|
||||
* `report bugs`_
|
||||
* `sourceforge page`_
|
||||
* `wiki`_
|
||||
|
||||
--------
|
||||
|
||||
Extensions
|
||||
|
||||
* `uTP`_
|
||||
* `extensions protocol`_
|
||||
* `plugin interface`_
|
||||
* `DHT extensions`_
|
||||
* `UDP tracker protocol`_
|
||||
* `HTTP seed`_
|
||||
* multitracker_
|
||||
|
||||
--------
|
||||
|
||||
Bindings
|
||||
|
||||
* `ruby bindings`_
|
||||
* `python bindings`_
|
||||
|
||||
--------
|
||||
|
||||
* `Introduction, slides`_
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</div>
|
||||
<div id="libraryBody">
|
||||
|
||||
==========
|
||||
libtorrent
|
||||
==========
|
||||
|
||||
.. _download: http://code.google.com/p/libtorrent/downloads/list
|
||||
.. _features: features.html
|
||||
.. _contributing: contributing.html
|
||||
.. _`building libtorrent`: building.html
|
||||
.. _examples: examples.html
|
||||
.. _`api documentation`: manual.html
|
||||
.. _`create torrents`: make_torrent.html
|
||||
.. _`running tests`: running_tests.html
|
||||
.. _`tuning`: tuning.html
|
||||
.. _screenshot: client_test.png
|
||||
.. _`uTP`: utp.html
|
||||
.. _`extensions protocol`: extension_protocol.html
|
||||
.. _`plugin interface`: libtorrent_plugins.html
|
||||
.. _`DHT extensions`: dht_extensions.html
|
||||
.. _`UDP tracker protocol`: udp_tracker_protocol.html
|
||||
.. _`HTTP seed`: http://www.getright.com/seedtorrent.html
|
||||
.. _multitracker: http://bittorrent.org/beps/bep_0012.html
|
||||
.. _mailing list: http://lists.sourceforge.net/lists/listinfo/libtorrent-discuss
|
||||
.. _archive: http://dir.gmane.org/gmane.network.bit-torrent.libtorrent
|
||||
.. _`who's using libtorrent?`: projects.html
|
||||
.. _`report bugs`: http://code.google.com/p/libtorrent/issues/entry
|
||||
.. _sourceforge page: http://www.sourceforge.net/projects/libtorrent
|
||||
.. _wiki: http://code.google.com/p/libtorrent/wiki/index
|
||||
|
||||
.. _`ruby bindings`: http://libtorrent-ruby.rubyforge.org/
|
||||
.. _`python bindings`: python_binding.html
|
||||
|
||||
.. _`Introduction, slides`: bittorrent.pdf
|
||||
|
||||
libtorrent is a feature complete C++ bittorrent implementation focusing
|
||||
on efficiency and scalability. It runs on embedded devices as well as
|
||||
desktops. It boasts a well documented library interface that is easy to
|
||||
use. It comes with a `simple bittorrent client`__ demonstrating the use of
|
||||
the library.
|
||||
|
||||
__ client_test.html
|
||||
|
||||
The main goals of libtorrent are:
|
||||
|
||||
* to be cpu efficient
|
||||
* to be memory efficient
|
||||
* to be very easy to use
|
||||
|
||||
|
||||
Donate
|
||||
======
|
||||
|
||||
Support the development of libtorrent
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<form action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_top">
|
||||
<input type="hidden" name="cmd" value="_xclick">
|
||||
<input type="hidden" name="business" value="arvid@cs.umu.se">
|
||||
<input type="hidden" name="item_name" value="libtorrent">
|
||||
<input type="hidden" name="return" value="http://libtorrent.sf.net">
|
||||
<input type="hidden" name="currency_code" value="USD">
|
||||
<input type="hidden" name="tax" value="0">
|
||||
<input type="image" src="https://www.paypal.com/images/x-click-but04.gif"
|
||||
border="0" name="submit" alt="Make payments with PayPal - it's fast, free and secure!">
|
||||
</form>
|
||||
|
||||
|
||||
|
||||
Feedback
|
||||
========
|
||||
|
||||
There's a `mailing list`__, general libtorrent discussion.
|
||||
|
||||
__ http://lists.sourceforge.net/lists/listinfo/libtorrent-discuss
|
||||
|
||||
You can usually find me as hydri in ``#libtorrent`` on ``irc.freenode.net``.
|
||||
|
||||
license
|
||||
=======
|
||||
|
||||
libtorrent is released under the BSD-license_.
|
||||
|
||||
.. _BSD-license: http://www.opensource.org/licenses/bsd-license.php
|
||||
|
||||
This means that you can use the library in your project without having to
|
||||
release its source code. The only requirement is that you give credit
|
||||
to the author of the library by including the libtorrent license in your
|
||||
software or documentation.
|
||||
|
||||
It is however greatly appreciated if additional features are contributed
|
||||
back to the open source project. Patches can be emailed to the mailing
|
||||
list or posted to the `bug tracker`_.
|
||||
|
||||
.. _`bug tracker`: http://code.rasterbar.com/libtorrent/newticket
|
||||
|
||||
Acknowledgements
|
||||
================
|
||||
|
||||
Written by Arvid Norberg. Copyright |copy| 2003-2009
|
||||
|
||||
Contributions by Magnus Jonsson, Daniel Wallin and Cory Nelson
|
||||
|
||||
Thanks to Reimond Retz for bugfixes, suggestions and testing
|
||||
|
||||
Thanks to `Umeå University`__ for providing development and test hardware.
|
||||
|
||||
__ http://www.cs.umu.se
|
||||
|
||||
Project is hosted by sourceforge.
|
||||
|
||||
|sf_logo|__
|
||||
|
||||
__ http://sourceforge.net
|
||||
|
||||
.. |sf_logo| image:: http://sourceforge.net/sflogo.php?group_id=7994
|
||||
.. |copy| unicode:: 0xA9 .. copyright sign
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</div>
|
||||
|
Before Width: | Height: | Size: 28 KiB |
|
@ -1,273 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta name="generator" content="Docutils 0.5: http://docutils.sourceforge.net/" />
|
||||
<title></title>
|
||||
<meta name="author" content="Arvid Norberg, arvid@rasterbar.com" />
|
||||
<link rel="stylesheet" type="text/css" href="../../css/base.css" />
|
||||
<link rel="stylesheet" type="text/css" href="../../css/rst.css" />
|
||||
<link rel="stylesheet" href="style.css" type="text/css" />
|
||||
<style type="text/css">
|
||||
/* Hides from IE-mac \*/
|
||||
* html pre { height: 1%; }
|
||||
/* End hide from IE-mac */
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="document">
|
||||
<div id="container">
|
||||
<div id="headerNav">
|
||||
<ul>
|
||||
<li class="first"><a href="/">Home</a></li>
|
||||
<li><a href="../../products.html">Products</a></li>
|
||||
<li><a href="../../contact.html">Contact</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="header">
|
||||
<h1><span>Rasterbar Software</span></h1>
|
||||
<h2><span>Software developement and consulting</span></h2>
|
||||
</div>
|
||||
<div id="main">
|
||||
|
||||
<table class="docinfo" frame="void" rules="none">
|
||||
<col class="docinfo-name" />
|
||||
<col class="docinfo-content" />
|
||||
<tbody valign="top">
|
||||
<tr><th class="docinfo-name">Author:</th>
|
||||
<td>Arvid Norberg, <a class="last reference external" href="mailto:arvid@rasterbar.com">arvid@rasterbar.com</a></td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="section" id="libtorrent-plugins">
|
||||
<h1>libtorrent plugins</h1>
|
||||
<div class="contents topic" id="contents">
|
||||
<p class="topic-title first">Contents</p>
|
||||
<ul class="simple">
|
||||
<li><a class="reference internal" href="#libtorrent-plugins" id="id1">libtorrent plugins</a><ul>
|
||||
<li><a class="reference internal" href="#a-word-of-caution" id="id2">a word of caution</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#plugin-interface" id="id3">plugin interface</a></li>
|
||||
<li><a class="reference internal" href="#torrent-plugin" id="id4">torrent_plugin</a><ul>
|
||||
<li><a class="reference internal" href="#new-connection" id="id5">new_connection()</a></li>
|
||||
<li><a class="reference internal" href="#on-piece-pass-on-piece-fail" id="id6">on_piece_pass() on_piece_fail()</a></li>
|
||||
<li><a class="reference internal" href="#tick" id="id7">tick()</a></li>
|
||||
<li><a class="reference internal" href="#on-pause-on-resume" id="id8">on_pause() on_resume()</a></li>
|
||||
<li><a class="reference internal" href="#on-files-checked" id="id9">on_files_checked()</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#peer-plugin" id="id10">peer_plugin</a></li>
|
||||
<li><a class="reference internal" href="#disk-buffer-holder" id="id11">disk_buffer_holder</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<p>libtorrent has a plugin interface for implementing extensions to the protocol.
|
||||
These can be general extensions for transferring metadata or peer exchange
|
||||
extensions, or it could be used to provide a way to customize the protocol
|
||||
to fit a particular (closed) network.</p>
|
||||
<p>In short, the plugin interface makes it possible to:</p>
|
||||
<ul class="simple">
|
||||
<li>register extension messages (sent in the extension handshake), see
|
||||
<a class="reference external" href="extension_protocol.html">extensions</a>.</li>
|
||||
<li>add data and parse data from the extension handshake.</li>
|
||||
<li>send extension messages and standard bittorrent messages.</li>
|
||||
<li>override or block the handling of standard bittorrent messages.</li>
|
||||
</ul>
|
||||
<div class="section" id="a-word-of-caution">
|
||||
<h2>a word of caution</h2>
|
||||
<p>Writing your own plugin is a very easy way to introduce serious bugs such as
|
||||
dead locks and race conditions. Since a plugin has access to internal
|
||||
structures it is also quite easy to sabotage libtorrent's operation.</p>
|
||||
<p>All the callbacks in this interface are called with the main libtorrent thread
|
||||
mutex locked. And they are always called from the libtorrent main thread. In
|
||||
case portions of your plugin are called from other threads, typically the main
|
||||
thread, you cannot use any of the member functions on the internal structures
|
||||
in libtorrent, since those require the mutex to be locked. Futhermore, you would
|
||||
also need to have a mutex on your own shared data within the plugin, to make
|
||||
sure it is not accessed at the same time from the libtorrent thread (through a
|
||||
callback). See <a class="reference external" href="http://www.boost.org/doc/html/mutex.html">boost thread's mutex</a>. If you need to send out a message from
|
||||
another thread, use an internal queue, and do the actual sending in <tt class="docutils literal"><span class="pre">tick()</span></tt>.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" id="plugin-interface">
|
||||
<h1>plugin interface</h1>
|
||||
<p>The plugin interface consists of two base classes that the plugin may
|
||||
implement. These are called <tt class="docutils literal"><span class="pre">torrent_plugin</span></tt> and <tt class="docutils literal"><span class="pre">peer_plugin</span></tt>. They are
|
||||
both found in the <tt class="docutils literal"><span class="pre"><libtorrent/extensions.hpp></span></tt> header.</p>
|
||||
<p>These plugins are instantiated for each torrent and possibly each peer,
|
||||
respectively.</p>
|
||||
<p>This is done by passing in a function or function object to
|
||||
<tt class="docutils literal"><span class="pre">session::add_extension()</span></tt> or <tt class="docutils literal"><span class="pre">torrent_handle::add_extension()</span></tt> (if the
|
||||
torrent has already been started and you want to hook in the extension at
|
||||
run-time).</p>
|
||||
<p>The signature of the function is:</p>
|
||||
<pre class="literal-block">
|
||||
boost::shared_ptr<torrent_plugin> (*)(torrent*, void*);
|
||||
</pre>
|
||||
<p>The first argument is the internal torrent object, the second argument
|
||||
is the userdata passed to <tt class="docutils literal"><span class="pre">session::add_torrent()</span></tt> or
|
||||
<tt class="docutils literal"><span class="pre">torrent_handle::add_extension()</span></tt>.</p>
|
||||
<p>The function should return a <tt class="docutils literal"><span class="pre">boost::shared_ptr<torrent_plugin></span></tt> which
|
||||
may or may not be 0. If it is a null pointer, the extension is simply ignored
|
||||
for this torrent. If it is a valid pointer (to a class inheriting
|
||||
<tt class="docutils literal"><span class="pre">torrent_plugin</span></tt>), it will be associated with this torrent and callbacks
|
||||
will be made on torrent events.</p>
|
||||
</div>
|
||||
<div class="section" id="torrent-plugin">
|
||||
<h1>torrent_plugin</h1>
|
||||
<p>The synopsis for <tt class="docutils literal"><span class="pre">torrent_plugin</span></tt> follows:</p>
|
||||
<pre class="literal-block">
|
||||
struct torrent_plugin
|
||||
{
|
||||
virtual ~torrent_plugin();
|
||||
virtual boost::shared_ptr<peer_plugin> new_connection(peer_connection*);
|
||||
|
||||
virtual void on_piece_pass(int index);
|
||||
virtual void on_piece_failed(int index);
|
||||
|
||||
virtual void tick();
|
||||
|
||||
virtual bool on_pause();
|
||||
virtual bool on_resume();
|
||||
|
||||
virtual void on_files_checked();
|
||||
};
|
||||
</pre>
|
||||
<p>This is the base class for a torrent_plugin. Your derived class is (if added
|
||||
as an extension) instantiated for each torrent in the session. The callback
|
||||
hook functions are defined as follows.</p>
|
||||
<div class="section" id="new-connection">
|
||||
<h2>new_connection()</h2>
|
||||
<pre class="literal-block">
|
||||
boost::shared_ptr<peer_plugin> new_connection(peer_connection*);
|
||||
</pre>
|
||||
<p>This function is called each time a new peer is connected to the torrent. You
|
||||
may choose to ignore this by just returning a default constructed
|
||||
<tt class="docutils literal"><span class="pre">shared_ptr</span></tt> (in which case you don't need to override this member
|
||||
function).</p>
|
||||
<p>If you need an extension to the peer connection (which most plugins do) you
|
||||
are supposed to return an instance of your <tt class="docutils literal"><span class="pre">peer_plugin</span></tt> class. Which in
|
||||
turn will have its hook functions called on event specific to that peer.</p>
|
||||
<p>The <tt class="docutils literal"><span class="pre">peer_connection</span></tt> will be valid as long as the <tt class="docutils literal"><span class="pre">shared_ptr</span></tt> is being
|
||||
held by the torrent object. So, it is generally a good idea to not keep a
|
||||
<tt class="docutils literal"><span class="pre">shared_ptr</span></tt> to your own peer_plugin. If you want to keep references to it,
|
||||
use <tt class="docutils literal"><span class="pre">weak_ptr</span></tt>.</p>
|
||||
<p>If this function throws an exception, the connection will be closed.</p>
|
||||
</div>
|
||||
<div class="section" id="on-piece-pass-on-piece-fail">
|
||||
<h2>on_piece_pass() on_piece_fail()</h2>
|
||||
<pre class="literal-block">
|
||||
void on_piece_pass(int index);
|
||||
void on_piece_failed(int index);
|
||||
</pre>
|
||||
<p>These hooks are called when a piece passes the hash check or fails the hash
|
||||
check, respectively. The <tt class="docutils literal"><span class="pre">index</span></tt> is the piece index that was downloaded.
|
||||
It is possible to access the list of peers that participated in sending the
|
||||
piece through the <tt class="docutils literal"><span class="pre">torrent</span></tt> and the <tt class="docutils literal"><span class="pre">piece_picker</span></tt>.</p>
|
||||
</div>
|
||||
<div class="section" id="tick">
|
||||
<h2>tick()</h2>
|
||||
<pre class="literal-block">
|
||||
void tick();
|
||||
</pre>
|
||||
<p>This hook is called approximately once per second. It is a way of making it
|
||||
easy for plugins to do timed events, for sending messages or whatever.</p>
|
||||
</div>
|
||||
<div class="section" id="on-pause-on-resume">
|
||||
<h2>on_pause() on_resume()</h2>
|
||||
<pre class="literal-block">
|
||||
bool on_pause();
|
||||
bool on_resume();
|
||||
</pre>
|
||||
<p>These hooks are called when the torrent is paused and unpaused respectively.
|
||||
The return value indicates if the event was handled. A return value of
|
||||
<tt class="docutils literal"><span class="pre">true</span></tt> indicates that it was handled, and no other plugin after this one
|
||||
will have this hook function called, and the standard handler will also not be
|
||||
invoked. So, returning true effectively overrides the standard behavior of
|
||||
pause or unpause.</p>
|
||||
<p>Note that if you call <tt class="docutils literal"><span class="pre">pause()</span></tt> or <tt class="docutils literal"><span class="pre">resume()</span></tt> on the torrent from your
|
||||
handler it will recurse back into your handler, so in order to invoke the
|
||||
standard handler, you have to keep your own state on whether you want standard
|
||||
behavior or overridden behavior.</p>
|
||||
</div>
|
||||
<div class="section" id="on-files-checked">
|
||||
<h2>on_files_checked()</h2>
|
||||
<pre class="literal-block">
|
||||
void on_files_checked();
|
||||
</pre>
|
||||
<p>This function is called when the initial files of the torrent have been
|
||||
checked. If there are no files to check, this function is called immediately.</p>
|
||||
<p>i.e. This function is always called when the torrent is in a state where it
|
||||
can start downloading.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" id="peer-plugin">
|
||||
<h1>peer_plugin</h1>
|
||||
<pre class="literal-block">
|
||||
struct peer_plugin
|
||||
{
|
||||
virtual ~peer_plugin();
|
||||
|
||||
virtual void add_handshake(entry&);
|
||||
virtual bool on_handshake(char const* reserved_bits);
|
||||
virtual bool on_extension_handshake(lazy_entry const& h);
|
||||
|
||||
virtual bool on_choke();
|
||||
virtual bool on_unchoke();
|
||||
virtual bool on_interested();
|
||||
virtual bool on_not_interested();
|
||||
virtual bool on_have(int index);
|
||||
virtual bool on_bitfield(bitfield const& bits);
|
||||
virtual bool on_have_all();
|
||||
virtual bool on_have_none();
|
||||
virtual bool on_allowed_fast(int index);
|
||||
virtual bool on_request(peer_request const& req);
|
||||
virtual bool on_piece(peer_request const& piece, disk_buffer_holder& buffer);
|
||||
virtual bool on_cancel(peer_request const& req);
|
||||
virtual bool on_reject(peer_request const& req);
|
||||
virtual bool on_suggest(int index);
|
||||
virtual bool on_extended(int length
|
||||
, int msg, buffer::const_interval body);
|
||||
virtual bool on_unknown_message(int length, int msg
|
||||
, buffer::const_interval body);
|
||||
virtual void on_piece_pass(int index);
|
||||
virtual void on_piece_failed(int index);
|
||||
|
||||
virtual void tick();
|
||||
|
||||
virtual bool write_request(peer_request const& r);
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
<div class="section" id="disk-buffer-holder">
|
||||
<h1>disk_buffer_holder</h1>
|
||||
<pre class="literal-block">
|
||||
struct disk_buffer_holder
|
||||
{
|
||||
disk_buffer_holder(aux::session_impl& s, char* b);
|
||||
~disk_buffer_holder();
|
||||
char* release();
|
||||
char* buffer();
|
||||
};
|
||||
</pre>
|
||||
<p>The disk buffer holder acts like a <tt class="docutils literal"><span class="pre">scoped_ptr</span></tt> that frees a disk buffer
|
||||
when it's destructed, unless it's released. <tt class="docutils literal"><span class="pre">release</span></tt> returns the disk
|
||||
buffer and transferres ownership and responsibility to free it to the caller.</p>
|
||||
<p>A disk buffer is freed by passing it to <tt class="docutils literal"><span class="pre">session_impl::free_disk_buffer()</span></tt>.</p>
|
||||
<p><tt class="docutils literal"><span class="pre">buffer()</span></tt> returns the pointer without transferring responsibility. If
|
||||
this buffer has been released, <tt class="docutils literal"><span class="pre">buffer()</span></tt> will return 0.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div id="footer">
|
||||
<span>Copyright © 2005 Rasterbar Software.</span>
|
||||
</div>
|
||||
</div>
|
||||
<script src="http://www.google-analytics.com/urchin.js" type="text/javascript">
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
_uacct = "UA-1599045-1";
|
||||
urchinTracker();
|
||||
</script>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -1,240 +0,0 @@
|
|||
:Author: Arvid Norberg, arvid@rasterbar.com
|
||||
|
||||
libtorrent plugins
|
||||
==================
|
||||
|
||||
.. contents::
|
||||
|
||||
libtorrent has a plugin interface for implementing extensions to the protocol.
|
||||
These can be general extensions for transferring metadata or peer exchange
|
||||
extensions, or it could be used to provide a way to customize the protocol
|
||||
to fit a particular (closed) network.
|
||||
|
||||
In short, the plugin interface makes it possible to:
|
||||
|
||||
* register extension messages (sent in the extension handshake), see
|
||||
extensions_.
|
||||
* add data and parse data from the extension handshake.
|
||||
* send extension messages and standard bittorrent messages.
|
||||
* override or block the handling of standard bittorrent messages.
|
||||
|
||||
.. _extensions: extension_protocol.html
|
||||
|
||||
a word of caution
|
||||
-----------------
|
||||
|
||||
Writing your own plugin is a very easy way to introduce serious bugs such as
|
||||
dead locks and race conditions. Since a plugin has access to internal
|
||||
structures it is also quite easy to sabotage libtorrent's operation.
|
||||
|
||||
All the callbacks in this interface are called with the main libtorrent thread
|
||||
mutex locked. And they are always called from the libtorrent main thread. In
|
||||
case portions of your plugin are called from other threads, typically the main
|
||||
thread, you cannot use any of the member functions on the internal structures
|
||||
in libtorrent, since those require the mutex to be locked. Futhermore, you would
|
||||
also need to have a mutex on your own shared data within the plugin, to make
|
||||
sure it is not accessed at the same time from the libtorrent thread (through a
|
||||
callback). See `boost thread's mutex`_. If you need to send out a message from
|
||||
another thread, use an internal queue, and do the actual sending in ``tick()``.
|
||||
|
||||
.. _`boost thread's mutex`: http://www.boost.org/doc/html/mutex.html
|
||||
|
||||
|
||||
plugin interface
|
||||
================
|
||||
|
||||
The plugin interface consists of two base classes that the plugin may
|
||||
implement. These are called ``torrent_plugin`` and ``peer_plugin``. They are
|
||||
both found in the ``<libtorrent/extensions.hpp>`` header.
|
||||
|
||||
These plugins are instantiated for each torrent and possibly each peer,
|
||||
respectively.
|
||||
|
||||
This is done by passing in a function or function object to
|
||||
``session::add_extension()`` or ``torrent_handle::add_extension()`` (if the
|
||||
torrent has already been started and you want to hook in the extension at
|
||||
run-time).
|
||||
|
||||
The signature of the function is::
|
||||
|
||||
boost::shared_ptr<torrent_plugin> (*)(torrent*, void*);
|
||||
|
||||
The first argument is the internal torrent object, the second argument
|
||||
is the userdata passed to ``session::add_torrent()`` or
|
||||
``torrent_handle::add_extension()``.
|
||||
|
||||
The function should return a ``boost::shared_ptr<torrent_plugin>`` which
|
||||
may or may not be 0. If it is a null pointer, the extension is simply ignored
|
||||
for this torrent. If it is a valid pointer (to a class inheriting
|
||||
``torrent_plugin``), it will be associated with this torrent and callbacks
|
||||
will be made on torrent events.
|
||||
|
||||
|
||||
torrent_plugin
|
||||
==============
|
||||
|
||||
The synopsis for ``torrent_plugin`` follows::
|
||||
|
||||
struct torrent_plugin
|
||||
{
|
||||
virtual ~torrent_plugin();
|
||||
virtual boost::shared_ptr<peer_plugin> new_connection(peer_connection*);
|
||||
|
||||
virtual void on_piece_pass(int index);
|
||||
virtual void on_piece_failed(int index);
|
||||
|
||||
virtual void tick();
|
||||
|
||||
virtual bool on_pause();
|
||||
virtual bool on_resume();
|
||||
|
||||
virtual void on_files_checked();
|
||||
};
|
||||
|
||||
This is the base class for a torrent_plugin. Your derived class is (if added
|
||||
as an extension) instantiated for each torrent in the session. The callback
|
||||
hook functions are defined as follows.
|
||||
|
||||
|
||||
new_connection()
|
||||
----------------
|
||||
|
||||
::
|
||||
|
||||
boost::shared_ptr<peer_plugin> new_connection(peer_connection*);
|
||||
|
||||
This function is called each time a new peer is connected to the torrent. You
|
||||
may choose to ignore this by just returning a default constructed
|
||||
``shared_ptr`` (in which case you don't need to override this member
|
||||
function).
|
||||
|
||||
If you need an extension to the peer connection (which most plugins do) you
|
||||
are supposed to return an instance of your ``peer_plugin`` class. Which in
|
||||
turn will have its hook functions called on event specific to that peer.
|
||||
|
||||
The ``peer_connection`` will be valid as long as the ``shared_ptr`` is being
|
||||
held by the torrent object. So, it is generally a good idea to not keep a
|
||||
``shared_ptr`` to your own peer_plugin. If you want to keep references to it,
|
||||
use ``weak_ptr``.
|
||||
|
||||
If this function throws an exception, the connection will be closed.
|
||||
|
||||
on_piece_pass() on_piece_fail()
|
||||
-------------------------------
|
||||
|
||||
::
|
||||
|
||||
void on_piece_pass(int index);
|
||||
void on_piece_failed(int index);
|
||||
|
||||
These hooks are called when a piece passes the hash check or fails the hash
|
||||
check, respectively. The ``index`` is the piece index that was downloaded.
|
||||
It is possible to access the list of peers that participated in sending the
|
||||
piece through the ``torrent`` and the ``piece_picker``.
|
||||
|
||||
tick()
|
||||
------
|
||||
|
||||
::
|
||||
|
||||
void tick();
|
||||
|
||||
This hook is called approximately once per second. It is a way of making it
|
||||
easy for plugins to do timed events, for sending messages or whatever.
|
||||
|
||||
|
||||
on_pause() on_resume()
|
||||
----------------------
|
||||
|
||||
::
|
||||
|
||||
bool on_pause();
|
||||
bool on_resume();
|
||||
|
||||
These hooks are called when the torrent is paused and unpaused respectively.
|
||||
The return value indicates if the event was handled. A return value of
|
||||
``true`` indicates that it was handled, and no other plugin after this one
|
||||
will have this hook function called, and the standard handler will also not be
|
||||
invoked. So, returning true effectively overrides the standard behavior of
|
||||
pause or unpause.
|
||||
|
||||
Note that if you call ``pause()`` or ``resume()`` on the torrent from your
|
||||
handler it will recurse back into your handler, so in order to invoke the
|
||||
standard handler, you have to keep your own state on whether you want standard
|
||||
behavior or overridden behavior.
|
||||
|
||||
on_files_checked()
|
||||
------------------
|
||||
|
||||
::
|
||||
|
||||
void on_files_checked();
|
||||
|
||||
This function is called when the initial files of the torrent have been
|
||||
checked. If there are no files to check, this function is called immediately.
|
||||
|
||||
i.e. This function is always called when the torrent is in a state where it
|
||||
can start downloading.
|
||||
|
||||
|
||||
peer_plugin
|
||||
===========
|
||||
|
||||
::
|
||||
|
||||
struct peer_plugin
|
||||
{
|
||||
virtual ~peer_plugin();
|
||||
|
||||
virtual void add_handshake(entry&);
|
||||
virtual bool on_handshake(char const* reserved_bits);
|
||||
virtual bool on_extension_handshake(lazy_entry const& h);
|
||||
|
||||
virtual bool on_choke();
|
||||
virtual bool on_unchoke();
|
||||
virtual bool on_interested();
|
||||
virtual bool on_not_interested();
|
||||
virtual bool on_have(int index);
|
||||
virtual bool on_bitfield(bitfield const& bits);
|
||||
virtual bool on_have_all();
|
||||
virtual bool on_have_none();
|
||||
virtual bool on_allowed_fast(int index);
|
||||
virtual bool on_request(peer_request const& req);
|
||||
virtual bool on_piece(peer_request const& piece, disk_buffer_holder& buffer);
|
||||
virtual bool on_cancel(peer_request const& req);
|
||||
virtual bool on_reject(peer_request const& req);
|
||||
virtual bool on_suggest(int index);
|
||||
virtual bool on_extended(int length
|
||||
, int msg, buffer::const_interval body);
|
||||
virtual bool on_unknown_message(int length, int msg
|
||||
, buffer::const_interval body);
|
||||
virtual void on_piece_pass(int index);
|
||||
virtual void on_piece_failed(int index);
|
||||
|
||||
virtual void tick();
|
||||
|
||||
virtual bool write_request(peer_request const& r);
|
||||
};
|
||||
|
||||
disk_buffer_holder
|
||||
==================
|
||||
|
||||
::
|
||||
|
||||
struct disk_buffer_holder
|
||||
{
|
||||
disk_buffer_holder(aux::session_impl& s, char* b);
|
||||
~disk_buffer_holder();
|
||||
char* release();
|
||||
char* buffer();
|
||||
};
|
||||
|
||||
The disk buffer holder acts like a ``scoped_ptr`` that frees a disk buffer
|
||||
when it's destructed, unless it's released. ``release`` returns the disk
|
||||
buffer and transferres ownership and responsibility to free it to the caller.
|
||||
|
||||
A disk buffer is freed by passing it to ``session_impl::free_disk_buffer()``.
|
||||
|
||||
``buffer()`` returns the pointer without transferring responsibility. If
|
||||
this buffer has been released, ``buffer()`` will return 0.
|
||||
|
Before Width: | Height: | Size: 52 KiB |
Before Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 15 KiB |
|
@ -1,2 +0,0 @@
|
|||
convert $1 -resize 150x130 $1
|
||||
|