merged RC_1_1 into master

This commit is contained in:
arvidn 2017-12-30 15:38:26 +01:00
commit 672556b4b2
9 changed files with 245 additions and 354 deletions

View File

@ -82,6 +82,8 @@
* resume data no longer has timestamps of files
* require C++11 to build libtorrent
1.1.6 release
* deprecate save_encryption_settings (they are part of the normal settings)
* add getters for peer_class_filter and peer_class_type_filter
* make torrent_handler::set_priority() to use peer_classes

View File

@ -1,25 +1,15 @@
#!/bin/sh
make clean
set -e
set -x
python tools/clean.py
cd docs
make clean
make RST2HTML=rst2html.py
make RST2HTML=rst2html-2.7.py
cd ..
#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 examples/.dep examples/.libs
rm -rf test/Makefile test/Makefile.in test/.dep test/.lib
rm -rf bindings/Makefile bindings/Makefile.in bindings/.dep bindings/.libs
rm -f bindings/python/Makefile bindings/python/Makefile.in
chmod a-x docs/*.rst docs/*.htm* src/*.cpp include/libtorrent/*.hpp
./autotool.sh

View File

@ -292,11 +292,8 @@ code to implement a simple bittorrent client::
// 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;
lt::session s;
lt::add_torrent_params p;
p.save_path = "./";
p.ti = new torrent_info(argv[1]);
s.add_torrent(p);
@ -324,10 +321,10 @@ 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. At least version 1.46.1 of boost is required.
It uses Boost.Thread, Boost.Asio, Boost.Chrono, Boost.Random, Boost.Date_time
and various other boost libraries. At least version 1.49 of boost is required.
libtorrent uses asio, hence it will take full advantage of high performance
Since libtorrent uses Boost.Asio 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.

View File

@ -1,6 +1,6 @@
/*
Copyright (c) 2003, Arvid Norberg
Copyright (c) 2003-2017, Arvid Norberg
All rights reserved.
Redistribution and use in source and binary forms, with or without
@ -40,74 +40,26 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/bdecode.hpp"
#include "libtorrent/magnet_uri.hpp"
int load_file(std::string const& filename, std::vector<char>& v
, lt::error_code& ec, int limit = 8000000)
#include <fstream>
#include <iostream>
std::vector<char> load_file(std::string const& filename)
{
ec.clear();
FILE* f = std::fopen(filename.c_str(), "rb");
if (f == nullptr)
{
ec.assign(errno, boost::system::system_category());
return -1;
}
int r = fseek(f, 0, SEEK_END);
if (r != 0)
{
ec.assign(errno, boost::system::system_category());
std::fclose(f);
return -1;
}
long s = ftell(f);
if (s < 0)
{
ec.assign(errno, boost::system::system_category());
std::fclose(f);
return -1;
}
if (s > limit)
{
std::fclose(f);
return -2;
}
r = fseek(f, 0, SEEK_SET);
if (r != 0)
{
ec.assign(errno, boost::system::system_category());
std::fclose(f);
return -1;
}
v.resize(s);
if (s == 0)
{
std::fclose(f);
return 0;
}
r = int(fread(&v[0], 1, v.size(), f));
if (r < 0)
{
ec.assign(errno, boost::system::system_category());
std::fclose(f);
return -1;
}
std::fclose(f);
if (r != s) return -3;
return 0;
std::vector<char> ret;
std::fstream in;
in.exceptions(std::ifstream::failbit);
in.open(filename.c_str(), std::ios_base::in | std::ios_base::binary);
in.seekg(0, std::ios_base::end);
auto const size = in.tellg();
in.seekg(0, std::ios_base::beg);
ret.resize(static_cast<std::size_t>(size));
in.read(ret.data(), ret.size());
return ret;
}
int main(int argc, char* argv[])
int main(int argc, char* argv[]) try
{
using namespace lt;
if (argc < 2 || argc > 4)
{
if (argc < 2 || argc > 4) {
fputs("usage: dump_torrent torrent-file [total-items-limit] [recursion-limit]\n", stderr);
return 1;
}
@ -118,41 +70,23 @@ int main(int argc, char* argv[])
if (argc > 2) item_limit = atoi(argv[2]);
if (argc > 3) depth_limit = atoi(argv[3]);
std::vector<char> buf;
error_code ec;
int ret = load_file(argv[1], buf, ec, 40 * 1000000);
if (ret == -1)
{
std::fprintf(stderr, "file too big, aborting\n");
return 1;
}
if (ret != 0)
{
std::fprintf(stderr, "failed to load file: %s\n", ec.message().c_str());
return 1;
}
bdecode_node e;
std::vector<char> buf = load_file(argv[1]);
lt::bdecode_node e;
int pos = -1;
std::printf("decoding. recursion limit: %d total item count limit: %d\n"
, depth_limit, item_limit);
ret = bdecode(&buf[0], &buf[0] + buf.size(), e, ec, &pos
lt::error_code ec;
std::cout << "decoding. recursion limit: " << depth_limit
<< " total item count limit: " << item_limit << "\n";
int const ret = lt::bdecode(&buf[0], &buf[0] + buf.size(), e, ec, &pos
, depth_limit, item_limit);
std::printf("\n\n----- raw info -----\n\n%s\n", print_entry(e).c_str());
if (ret != 0)
{
std::fprintf(stderr, "failed to decode: '%s' at character: %d\n", ec.message().c_str(), pos);
if (ret != 0) {
std::cerr << "failed to decode: '" << ec.message() << "' at character: " << pos<< "\n";
return 1;
}
torrent_info t(e, ec);
if (ec)
{
std::fprintf(stderr, "%s\n", ec.message().c_str());
return 1;
}
lt::torrent_info const t(e);
e.clear();
std::vector<char>().swap(buf);
@ -185,11 +119,11 @@ int main(int argc, char* argv[])
, make_magnet_uri(t).c_str()
, t.name().c_str()
, t.num_files());
file_storage const& st = t.files();
for (file_index_t i(0); i < file_index_t(st.num_files()); ++i)
lt::file_storage const& st = t.files();
for (lt::file_index_t i(0); i < lt::file_index_t(st.num_files()); ++i)
{
piece_index_t const first = st.map_file(i, 0, 0).piece;
piece_index_t const last = st.map_file(i, (std::max)(std::int64_t(st.file_size(i))-1, std::int64_t(0)), 0).piece;
lt::piece_index_t const first = st.map_file(i, 0, 0).piece;
lt::piece_index_t const last = st.map_file(i, (std::max)(std::int64_t(st.file_size(i))-1, std::int64_t(0)), 0).piece;
auto const flags = st.file_flags(i);
std::stringstream file_hash;
if (!st.hash(i).is_all_zeros())
@ -197,25 +131,29 @@ int main(int argc, char* argv[])
std::printf(" %8" PRIx64 " %11" PRId64 " %c%c%c%c [ %5d, %5d ] %7u %s %s %s%s\n"
, st.file_offset(i)
, st.file_size(i)
, ((flags & file_storage::flag_pad_file)?'p':'-')
, ((flags & file_storage::flag_executable)?'x':'-')
, ((flags & file_storage::flag_hidden)?'h':'-')
, ((flags & file_storage::flag_symlink)?'l':'-')
, ((flags & lt::file_storage::flag_pad_file)?'p':'-')
, ((flags & lt::file_storage::flag_executable)?'x':'-')
, ((flags & lt::file_storage::flag_hidden)?'h':'-')
, ((flags & lt::file_storage::flag_symlink)?'l':'-')
, static_cast<int>(first)
, static_cast<int>(last)
, std::uint32_t(st.mtime(i))
, file_hash.str().c_str()
, st.file_path(i).c_str()
, (flags & file_storage::flag_symlink) ? "-> " : ""
, (flags & file_storage::flag_symlink) ? st.symlink(i).c_str() : "");
, (flags & lt::file_storage::flag_symlink) ? "-> " : ""
, (flags & lt::file_storage::flag_symlink) ? st.symlink(i).c_str() : "");
}
std::printf("web seeds:\n");
for (auto const& ws : t.web_seeds())
{
std::printf("%s %s\n"
, ws.type == web_seed_entry::url_seed ? "BEP19" : "BEP17"
, ws.type == lt::web_seed_entry::url_seed ? "BEP19" : "BEP17"
, ws.url.c_str());
}
return 0;
}
catch (std::exception const& e)
{
std::cerr << "ERROR: " << e.what() << "\n";
}

View File

@ -1,6 +1,6 @@
/*
Copyright (c) 2006, Arvid Norberg
Copyright (c) 2006-2017, Arvid Norberg
All rights reserved.
Redistribution and use in source and binary forms, with or without
@ -42,12 +42,12 @@ POSSIBILITY OF SUCH DAMAGE.
#include <cstdio>
#include <sstream>
#include <fstream>
#include <iostream>
#ifdef TORRENT_WINDOWS
#include <direct.h> // for _getcwd
#endif
using namespace lt;
using namespace std::placeholders;
std::vector<char> load_file(std::string const& filename)
@ -112,7 +112,7 @@ bool file_filter(std::string const& f)
return true;
}
void print_progress(piece_index_t i, int num)
void print_progress(lt::piece_index_t i, int num)
{
std::fprintf(stderr, "\r%d/%d", static_cast<int>(i)+1, num);
}
@ -159,227 +159,193 @@ void print_usage()
, stderr);
}
int main(int argc, char* argv[])
int main(int argc, char* argv[]) try
{
using namespace lt;
std::string creator_str = "libtorrent";
std::string comment_str;
if (argc < 2)
{
if (argc < 2) {
print_usage();
return 1;
}
#ifndef BOOST_NO_EXCEPTIONS
try
{
#endif
std::vector<std::string> web_seeds;
std::vector<std::string> trackers;
std::vector<std::string> collections;
std::vector<sha1_hash> similar;
int pad_file_limit = -1;
int piece_size = 0;
create_flags_t flags = {};
std::string root_cert;
std::vector<std::string> web_seeds;
std::vector<std::string> trackers;
std::vector<std::string> collections;
std::vector<lt::sha1_hash> similar;
int pad_file_limit = -1;
int piece_size = 0;
lt::create_flags_t flags = {};
std::string root_cert;
std::string outfile;
std::string merklefile;
std::string outfile;
std::string merklefile;
#ifdef TORRENT_WINDOWS
// don't ever write binary data to the console on windows
// it will just be interpreted as text and corrupted
outfile = "a.torrent";
// don't ever write binary data to the console on windows
// it will just be interpreted as text and corrupted
outfile = "a.torrent";
#endif
for (int i = 2; i < argc; ++i)
{
if (argv[i][0] != '-')
{
print_usage();
return 1;
}
std::string full_path = argv[1];
argv += 2;
argc -= 2;
switch (argv[i][1])
{
case 'w':
++i;
web_seeds.push_back(argv[i]);
break;
case 't':
++i;
trackers.push_back(argv[i]);
break;
case 'M':
flags |= create_torrent::mutable_torrent_support;
pad_file_limit = 0x4000;
break;
case 'p':
++i;
pad_file_limit = atoi(argv[i]);
flags |= create_torrent::optimize_alignment;
break;
case 's':
++i;
piece_size = atoi(argv[i]);
break;
case 'm':
++i;
merklefile = argv[i];
flags |= create_torrent::merkle;
break;
case 'o':
++i;
outfile = argv[i];
break;
case 'l':
flags |= create_torrent::symlinks;
break;
case 'C':
++i;
creator_str = argv[i];
break;
case 'c':
++i;
comment_str = argv[i];
break;
case 'r':
++i;
root_cert = argv[i];
break;
case 'S':
{
++i;
if (strlen(argv[i]) != 40)
{
std::fprintf(stderr, "invalid info-hash for -S. "
"Expected 40 hex characters\n");
print_usage();
return 1;
}
std::stringstream hash(argv[i]);
sha1_hash ih;
hash >> ih;
if (hash.fail())
{
std::fprintf(stderr, "invalid info-hash for -S\n");
print_usage();
return 1;
}
similar.push_back(ih);
}
break;
case 'L':
++i;
collections.push_back(argv[i]);
break;
default:
for (; argc > 0; --argc, ++argv) {
if (argv[0][0] != '-') {
print_usage();
return 1;
}
char const flag = argv[0][1];
switch (flag)
{
case 'M':
flags |= lt::create_torrent::mutable_torrent_support;
pad_file_limit = 0x4000;
continue;
case 'l':
flags |= lt::create_torrent::symlinks;
continue;
}
if (argc < 2) {
print_usage();
return 1;
}
switch (flag)
{
case 'w': web_seeds.push_back(argv[1]); break;
case 't': trackers.push_back(argv[1]); break;
case 's': piece_size = atoi(argv[1]); break;
case 'o': outfile = argv[1]; break;
case 'C': creator_str = argv[1]; break;
case 'c': comment_str = argv[1]; break;
case 'r': root_cert = argv[1]; break;
case 'L': collections.push_back(argv[1]); break;
case 'p':
pad_file_limit = atoi(argv[1]);
flags |= lt::create_torrent::optimize_alignment;
break;
case 'm':
merklefile = argv[1];
flags |= lt::create_torrent::merkle;
break;
case 'S': {
if (strlen(argv[1]) != 40) {
std::fprintf(stderr, "invalid info-hash for -S. "
"Expected 40 hex characters\n");
print_usage();
return 1;
}
std::stringstream hash(argv[1]);
lt::sha1_hash ih;
hash >> ih;
if (hash.fail()) {
std::fprintf(stderr, "invalid info-hash for -S\n");
print_usage();
return 1;
}
similar.push_back(ih);
break;
}
}
file_storage fs;
std::string full_path = argv[1];
#ifdef TORRENT_WINDOWS
if (full_path[1] != ':')
#else
if (full_path[0] != '/')
#endif
{
char cwd[TORRENT_MAX_PATH];
#ifdef TORRENT_WINDOWS
_getcwd(cwd, sizeof(cwd));
full_path = cwd + ("\\" + full_path);
#else
char const* ret = getcwd(cwd, sizeof(cwd));
if (ret == NULL)
{
std::fprintf(stderr, "failed to get current working directory: %s\n"
, strerror(errno));
default:
print_usage();
return 1;
}
full_path = cwd + ("/" + full_path);
#endif
}
add_files(fs, full_path, file_filter, flags);
if (fs.num_files() == 0)
{
fputs("no files specified.\n", stderr);
return 1;
}
create_torrent t(fs, piece_size, pad_file_limit, flags);
int tier = 0;
for (std::vector<std::string>::iterator i = trackers.begin()
, end(trackers.end()); i != end; ++i, ++tier)
t.add_tracker(*i, tier);
for (std::vector<std::string>::iterator i = web_seeds.begin()
, end(web_seeds.end()); i != end; ++i)
t.add_url_seed(*i);
for (std::vector<std::string>::iterator i = collections.begin()
, end(collections.end()); i != end; ++i)
t.add_collection(*i);
for (std::vector<sha1_hash>::iterator i = similar.begin()
, end(similar.end()); i != end; ++i)
t.add_similar_torrent(*i);
error_code ec;
set_piece_hashes(t, branch_path(full_path)
, std::bind(&print_progress, _1, t.num_pieces()), ec);
if (ec)
{
std::fprintf(stderr, "%s\n", ec.message().c_str());
return 1;
}
std::fprintf(stderr, "\n");
t.set_creator(creator_str.c_str());
if (!comment_str.empty())
t.set_comment(comment_str.c_str());
if (!root_cert.empty())
{
std::vector<char> pem = load_file(root_cert);
t.set_root_cert(std::string(&pem[0], pem.size()));
}
// create the torrent and print it to stdout
std::vector<char> torrent;
bencode(back_inserter(torrent), t.generate());
if (!outfile.empty())
{
std::fstream out;
out.exceptions(std::ifstream::failbit);
out.open(outfile.c_str(), std::ios_base::out | std::ios_base::binary);
out.write(&torrent[0], torrent.size());
}
else
{
fwrite(&torrent[0], 1, torrent.size(), stdout);
}
if (!merklefile.empty())
{
std::fstream merkle;
merkle.exceptions(std::ifstream::failbit);
merkle.open(merklefile.c_str(), std::ios_base::out | std::ios_base::binary);
merkle.write(reinterpret_cast<char const*>(&t.merkle_tree()[0]), t.merkle_tree().size() * 20);
}
#ifndef BOOST_NO_EXCEPTIONS
++argv;
--argc;
}
catch (std::exception const& e)
lt::file_storage fs;
#ifdef TORRENT_WINDOWS
if (full_path[1] != ':')
#else
if (full_path[0] != '/')
#endif
{
std::fprintf(stderr, "%s\n", e.what());
}
char cwd[TORRENT_MAX_PATH];
#ifdef TORRENT_WINDOWS
_getcwd(cwd, sizeof(cwd));
full_path = cwd + ("\\" + full_path);
#else
char const* ret = getcwd(cwd, sizeof(cwd));
if (ret == NULL)
{
std::fprintf(stderr, "failed to get current working directory: %s\n"
, strerror(errno));
return 1;
}
full_path = cwd + ("/" + full_path);
#endif
}
lt::add_files(fs, full_path, file_filter, flags);
if (fs.num_files() == 0) {
std::cerr << "no files specified.\n";
return 1;
}
lt::create_torrent t(fs, piece_size, pad_file_limit, flags);
int tier = 0;
for (std::vector<std::string>::iterator i = trackers.begin()
, end(trackers.end()); i != end; ++i, ++tier)
t.add_tracker(*i, tier);
for (std::vector<std::string>::iterator i = web_seeds.begin()
, end(web_seeds.end()); i != end; ++i)
t.add_url_seed(*i);
for (std::vector<std::string>::iterator i = collections.begin()
, end(collections.end()); i != end; ++i)
t.add_collection(*i);
for (std::vector<lt::sha1_hash>::iterator i = similar.begin()
, end(similar.end()); i != end; ++i)
t.add_similar_torrent(*i);
lt::error_code ec;
set_piece_hashes(t, branch_path(full_path)
, std::bind(&print_progress, _1, t.num_pieces()), ec);
if (ec) {
std::cerr << ec.message() << "\n";
return 1;
}
std::cerr << "\n";
t.set_creator(creator_str.c_str());
if (!comment_str.empty()) {
t.set_comment(comment_str.c_str());
}
if (!root_cert.empty()) {
std::vector<char> const pem = load_file(root_cert);
t.set_root_cert(std::string(&pem[0], pem.size()));
}
// create the torrent and print it to stdout
std::vector<char> torrent;
lt::bencode(back_inserter(torrent), t.generate());
if (!outfile.empty()) {
std::fstream out;
out.exceptions(std::ifstream::failbit);
out.open(outfile.c_str(), std::ios_base::out | std::ios_base::binary);
out.write(&torrent[0], torrent.size());
}
else {
std::cout.write(&torrent[0], torrent.size());
}
if (!merklefile.empty()) {
std::fstream merkle;
merkle.exceptions(std::ifstream::failbit);
merkle.open(merklefile.c_str(), std::ios_base::out | std::ios_base::binary);
merkle.write(reinterpret_cast<char const*>(&t.merkle_tree()[0]), t.merkle_tree().size() * 20);
}
return 0;
}
catch (std::exception& e) {
std::cerr << "ERROR: " << e.what() << "\n";
return 1;
}

View File

@ -1,6 +1,6 @@
/*
Copyright (c) 2003, Arvid Norberg
Copyright (c) 2003-2017, Arvid Norberg
All rights reserved.
Redistribution and use in source and binary forms, with or without
@ -36,35 +36,22 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/session.hpp"
#include "libtorrent/torrent_info.hpp"
int main(int argc, char* argv[])
{
using namespace lt;
#include <iostream>
int main(int argc, char* argv[]) try
{
if (argc != 2)
{
fputs("usage: ./simple_client torrent-file\n"
"to stop the client, press return.\n", stderr);
std::cerr << "usage: ./simple_client torrent-file\n"
"to stop the client, press return.\n";
return 1;
}
settings_pack sett;
sett.set_str(settings_pack::listen_interfaces, "0.0.0.0:6881");
lt::session s(sett);
error_code ec;
add_torrent_params p;
lt::session s;
lt::add_torrent_params p;
p.save_path = "./";
p.ti = std::make_shared<torrent_info>(std::string(argv[1]), std::ref(ec));
if (ec)
{
std::fprintf(stderr, "%s\n", ec.message().c_str());
return 1;
}
s.add_torrent(p, ec);
if (ec)
{
std::fprintf(stderr, "%s\n", ec.message().c_str());
return 1;
}
p.ti = std::make_shared<lt::torrent_info>(std::string(argv[1]));
s.add_torrent(p);
// wait for the user to end
char a;
@ -72,4 +59,8 @@ int main(int argc, char* argv[])
(void)ret; // ignore
return 0;
}
catch (std::exception const& e)
{
std::cerr << "ERROR: " << e.what() << "\n";
}

View File

@ -670,7 +670,7 @@ namespace libtorrent {
// class and returns a unique identifier.
//
// Identifiers are assigned from low numbers to higher. So if you plan on
// using certain peer classes in a call to `set_peer_class_filter()`_,
// using certain peer classes in a call to set_peer_class_filter(),
// make sure to create those early on, to get low identifiers.
//
// For more information on peer classes, see peer-classes_.

View File

@ -1595,7 +1595,7 @@ namespace libtorrent {
// the number of bytes of padding files
std::uint32_t m_padding:24;
// TODO: 8 bits available here
// TODO: gap of 8 bits available here
// ----

View File

@ -13,6 +13,8 @@ def clean():
'upnp.log',
'natpmp.log',
'bin',
'build-aux',
'.deps',
'test_tmp_*',
'bjam_build.*.xml'
'*.exe',
@ -34,6 +36,11 @@ def clean():
'Jamfile.orig',
'*.o',
'*.lo',
'autom4te.cache',
'configure',
'config.report',
'config.log',
'.lib',
]
directories = [