made the examples build without exception support. added overloads of add_torrent() and add_magnet_uri() that don't throw

This commit is contained in:
Arvid Norberg
2009-02-26 07:09:56 +00:00
parent f8e72650bd
commit 7aacfca292
14 changed files with 894 additions and 1017 deletions

View File

@@ -147,13 +147,6 @@ if test -z "$BOOST_REGEX_LIB"; then
BUILD_TESTCLIENT=no; BUILD_TESTCLIENT=no;
fi fi
AX_BOOST_PROGRAM_OPTIONS
dnl check that Boost.Program_options was found:
if test -z "$BOOST_PROGRAM_OPTIONS_LIB"; then
AC_MSG_RESULT([Unable to find Boost.Program_options library, example test_client will not be build.])
BUILD_TESTCLIENT=no;
fi
dnl Apply boost config. dnl Apply boost config.
CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS"
LDFLAGS="$LDFLAGS $BOOST_LDFLAGS" LDFLAGS="$LDFLAGS $BOOST_LDFLAGS"

View File

@@ -89,6 +89,9 @@ The ``session`` class has the following synopsis::
torrent_handle add_torrent( torrent_handle add_torrent(
add_torrent_params const& params); add_torrent_params const& params);
torrent_handle add_torrent(
add_torrent_params const& params
, error_code& ec);
void pause(); void pause();
void resume(); void resume();
@@ -299,10 +302,15 @@ add_torrent()
}; };
torrent_handle add_torrent(add_torrent_params const& params); torrent_handle add_torrent(add_torrent_params const& params);
torrent_handle add_torrent(add_torrent_params const& params
, error_code& ec);
You add torrents through the ``add_torrent()`` function where you give an You add torrents through the ``add_torrent()`` function where you give an
object with all the parameters. object with all the parameters.
The overload that does not take an ``error_code`` throws an exception on
error and is not available when building without exception support.
The only mandatory parameter is ``save_path`` which is the directory where you The only mandatory parameter is ``save_path`` which is the directory where you
want the files to be saved. You also need to specify either the ``ti`` (the want the files to be saved. You also need to specify either the ``ti`` (the
torrent file) or ``info_hash`` (the info hash of the torrent). If you specify the torrent file) or ``info_hash`` (the info hash of the torrent). If you specify the
@@ -4173,6 +4181,8 @@ add_magnet_uri()
torrent_handle add_magnet_uri(session& ses, std::string const& uri torrent_handle add_magnet_uri(session& ses, std::string const& uri
add_torrent_params p); add_torrent_params p);
torrent_handle add_magnet_uri(session& ses, std::string const& uri
add_torrent_params p, error_code& ec);
This function parses the magnet URI (``uri``) as a bittorrent magnet link, This function parses the magnet URI (``uri``) as a bittorrent magnet link,
and adds the torrent to the specified session (``ses``). It returns the and adds the torrent to the specified session (``ses``). It returns the
@@ -4180,6 +4190,9 @@ handle to the newly added torrent, or an invalid handle in case parsing
failed. To control some initial settings of the torrent, sepcify those in failed. To control some initial settings of the torrent, sepcify those in
the ``add_torrent_params``, ``p``. See `add_torrent()`_. the ``add_torrent_params``, ``p``. See `add_torrent()`_.
The overload that does not take an ``error_code`` throws an exception on
error and is not available when building without exception support.
For more information about magnet links, see `magnet links`_. For more information about magnet links, see `magnet links`_.
make_magnet_uri() make_magnet_uri()
@@ -5008,6 +5021,12 @@ code symbol description
------ ---------------------------- ----------------------------------------------------------------- ------ ---------------------------- -----------------------------------------------------------------
19 duplicate_torrent There's already a torrent with that info-hash added to the 19 duplicate_torrent There's already a torrent with that info-hash added to the
session session
------ ---------------------------- -----------------------------------------------------------------
20 invalid_torrent_handle The supplied torrent_handle is not referring to a valid torrent
------ ---------------------------- -----------------------------------------------------------------
21 invalid_entry_type The type requested from the entry did not match its type
------ ---------------------------- -----------------------------------------------------------------
22 missing_info_hash_in_uri The specified URI does not contain a valid info-hash
====== ============================ ================================================================= ====== ============================ =================================================================
The names of these error codes are declared in then ``libtorrent::errors`` namespace. The names of these error codes are declared in then ``libtorrent::errors`` namespace.

View File

@@ -9,7 +9,6 @@ if $(BOOST_ROOT)
use-project /boost : $(BOOST_ROOT) ; use-project /boost : $(BOOST_ROOT) ;
} }
lib program-options : : <name>boost_program_options ;
lib regex : : <name>boost_regex ; lib regex : : <name>boost_regex ;
project client_test project client_test
@@ -20,8 +19,7 @@ project client_test
; ;
exe client_test : client_test.cpp exe client_test : client_test.cpp
: <library>/boost/program_options : <library>/boost/regex
<library>/boost/regex
; ;
exe simple_client : simple_client.cpp ; exe simple_client : simple_client.cpp ;

View File

@@ -6,7 +6,7 @@ EXTRA_PROGRAMS = client_test dump_torrent make_torrent simple_client enum_if
EXTRA_DIST = Jamfile EXTRA_DIST = Jamfile
client_test_SOURCES = client_test.cpp client_test_SOURCES = client_test.cpp
client_test_LDADD = $(top_builddir)/src/libtorrent-rasterbar.la @BOOST_REGEX_LIB@ @BOOST_PROGRAM_OPTIONS_LIB@ client_test_LDADD = $(top_builddir)/src/libtorrent-rasterbar.la @BOOST_REGEX_LIB@
dump_torrent_SOURCES = dump_torrent.cpp dump_torrent_SOURCES = dump_torrent.cpp
dump_torrent_LDADD = $(top_builddir)/src/libtorrent-rasterbar.la dump_torrent_LDADD = $(top_builddir)/src/libtorrent-rasterbar.la

View File

@@ -44,9 +44,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include <boost/filesystem/operations.hpp> #include <boost/filesystem/operations.hpp>
#include <boost/filesystem/convenience.hpp> #include <boost/filesystem/convenience.hpp>
#include <boost/filesystem/fstream.hpp> #include <boost/filesystem/fstream.hpp>
#include <boost/filesystem/exception.hpp>
#include <boost/bind.hpp> #include <boost/bind.hpp>
#include <boost/program_options.hpp>
#include <boost/regex.hpp> #include <boost/regex.hpp>
#ifdef _MSC_VER #ifdef _MSC_VER
@@ -349,8 +347,9 @@ void print_peer_info(std::ostream& out, std::vector<libtorrent::peer_info> const
out.fill(' '); out.fill(' ');
if (print_ip) if (print_ip)
{ {
error_code ec;
std::stringstream ip; std::stringstream ip;
ip << i->ip.address().to_string() << ":" << i->ip.port(); ip << i->ip.address().to_string(ec) << ":" << i->ip.port();
out.width(22); out.width(22);
out << ip.str() << " "; out << ip.str() << " ";
} }
@@ -496,13 +495,11 @@ void add_torrent(libtorrent::session& ses
using namespace libtorrent; using namespace libtorrent;
boost::intrusive_ptr<torrent_info> t; boost::intrusive_ptr<torrent_info> t;
try error_code ec;
t = new torrent_info(torrent.c_str(), ec);
if (ec)
{ {
t = new torrent_info(torrent.c_str()); std::cout << torrent << ": " << ec.message() << std::endl;
}
catch (std::exception& e)
{
std::cout << torrent << ": " << e.what() << std::endl;
return; return;
} }
@@ -523,7 +520,7 @@ void add_torrent(libtorrent::session& ses
p.paused = true; p.paused = true;
p.duplicate_is_error = false; p.duplicate_is_error = false;
p.auto_managed = true; p.auto_managed = true;
torrent_handle h = ses.add_torrent(p); torrent_handle h = ses.add_torrent(p, ec);
handles.insert(std::make_pair( handles.insert(std::make_pair(
monitored_dir?std::string(torrent):std::string(), h)); monitored_dir?std::string(torrent):std::string(), h));
@@ -672,191 +669,51 @@ static char const* state_str[] =
{"checking (q)", "checking", "dl metadata" {"checking (q)", "checking", "dl metadata"
, "downloading", "finished", "seeding", "allocating", "checking (r)"}; , "downloading", "finished", "seeding", "allocating", "checking (r)"};
int main(int ac, char* av[]) int main(int argc, char* argv[])
{ {
#if BOOST_VERSION < 103400 #if BOOST_VERSION < 103400
using boost::filesystem::no_check; using boost::filesystem::no_check;
path::default_name_check(no_check); path::default_name_check(no_check);
#endif #endif
int listen_port; if (argc == 1)
float preferred_ratio;
int download_limit;
int upload_limit;
int torrent_upload_limit;
int torrent_download_limit;
int upload_slots_limit;
int half_open_limit;
std::string save_path_str;
std::string log_level;
std::string log_file_name;
std::string ip_filter_file;
std::string allocation_mode;
std::string in_monitor_dir;
std::string bind_to_interface;
std::string proxy;
std::string proxy_login;
std::string proxy_type;
int poll_interval;
int wait_retry;
int bind_port_start = 0;
int bind_port_end = 0;
namespace po = boost::program_options;
try
{ {
std::cerr << "usage: client_test [OPTIONS] [TORRENT|MAGNETURL]\n\n"
po::options_description desc("supported options"); "OPTIONS:\n"
desc.add_options() " -f <log file> logs all events to the given file\n"
("help,h", "display this help message") " -o <limit> limits the number of simultaneous\n"
("port,p", po::value<int>(&listen_port)->default_value(6881) " half-open TCP connections to the\n"
, "set listening port") " given number.\n"
("ratio,r", po::value<float>(&preferred_ratio)->default_value(0) " -p <port> sets the listen port\n"
, "set the preferred upload/download ratio. 0 means infinite. Values " " -r <ratio> sets the preferred share ratio\n"
"smaller than 1 are clamped to 1.") " -d <rate> limits the download rate\n"
("max-download-rate,d", po::value<int>(&download_limit)->default_value(0) " -u <rate> limits the upload rate\n"
, "the maximum download rate given in kB/s. 0 means infinite.") " -S <limit> limits the upload slots\n"
("max-upload-rate,u", po::value<int>(&upload_limit)->default_value(0) " -a <mode> sets the allocation mode. [compact|full]\n"
, "the maximum upload rate given in kB/s. 0 means infinite.") " -s <path> sets the save path for downloads\n"
("max-torrent-upload-rate", po::value<int>(&torrent_upload_limit)->default_value(20) " -U <rate> sets per-torrent upload rate\n"
, "the maximum upload rate for an individual torrent, given in kB/s. 0 means infinite.") " -D <rate> sets per-torrent download rate\n"
("max-torrent-download-rate", po::value<int>(&torrent_download_limit)->default_value(0) " -m <path> sets the .torrent monitor directory\n"
, "the maximum download rate for an individual torrent, given in kB/s. 0 means infinite.") " -b <IP> sets IP of the interface to bind the\n"
("max-upload-slots", po::value<int>(&upload_slots_limit)->default_value(5) " listen socket to\n"
, "the maximum number of upload slots. 0 means infinite.") " -w <seconds> sets the retry time for failed web seeds\n"
("save-path,s", po::value<std::string>(&save_path_str)->default_value("./") " -t <seconds> sets the scan interval of the monitor dir\n"
, "the path where the downloaded file/folder should be placed.") " -x <file> loads an emule IP-filter file\n"
("log-level,l", po::value<std::string>(&log_level)->default_value("info") " -c <limit> sets the max number of connections\n"
, "sets the level at which events are logged [debug | info | warning | fatal].") "\n\n"
("log-file,f", po::value<std::string>(&log_file_name)->default_value("") "TORRENT is a path to a .torrent file\n"
, "sets a file to log all events to") "MAGNETURL is a magnet: url\n"
("ip-filter,f", po::value<std::string>(&ip_filter_file)->default_value("")
, "sets the path to the ip-filter file used to block access from certain "
"ips. ")
("allocation-mode,a", po::value<std::string>(&allocation_mode)->default_value("full")
, "sets mode used for allocating the downloaded files on disk. "
"Possible options are [full | compact]")
("input-file,i", po::value<std::vector<std::string> >()
, "adds an input .torrent file. At least one is required. arguments "
"without any flag are implicitly an input file. To start a torrentless "
"download, use <info-hash>@<tracker-url> instead of specifying a file.")
("monitor-dir,m", po::value<std::string>(&in_monitor_dir)
, "monitors the given directory, looking for .torrent files and "
"automatically starts downloading them. It will stop downloading "
"torrent files that are removed from the directory")
("poll-interval,t", po::value<int>(&poll_interval)->default_value(2)
, "if a directory is being monitored, this is the interval (given "
"in seconds) between two refreshes of the directory listing")
("wait-retry,w", po::value<int>(&wait_retry)->default_value(30)
, "if the download of a url seed failes, this is the interval (given "
"in seconds) to wait until the next retry")
("half-open-limit,o", po::value<int>(&half_open_limit)->default_value(-1)
, "Sets the maximum number of simultaneous half-open tcp connections")
("bind,b", po::value<std::string>(&bind_to_interface)->default_value("")
, "Sets the local interface to bind outbound and the listen "
"socket to")
("proxy-server,x", po::value<std::string>(&proxy)->default_value("")
, "Sets the http proxy to be used for tracker and web seeds "
"connections. The string is expected to be on the form: "
"<hostname>:<port>. If no port is specified, 8080 is assumed")
("proxy-login,n", po::value<std::string>(&proxy_login)->default_value("")
, "Sets the username and password used to authenticate with the http "
"proxy. The string should be given in the form: <username>:<password>")
("proxy-type", po::value<std::string>(&proxy_type)->default_value("socks5")
, "Sets the type of proxy to use [socks5 | http] ")
("bind-port-start", po::value<int>(&bind_port_start)->default_value(0)
, "The lower port number that outgoing connections will be bound to")
("bind-port-end", po::value<int>(&bind_port_end)->default_value(0)
, "The upper port number that outgoing connections will be bound to")
; ;
return 0;
po::positional_options_description p;
p.add("input-file", -1);
po::variables_map vm;
po::store(po::command_line_parser(ac, av).
options(desc).positional(p).run(), vm);
po::notify(vm);
// make sure the arguments stays within the usable limits
path monitor_dir(in_monitor_dir);
if (listen_port < 0 || listen_port > 65525) listen_port = 6881;
if (preferred_ratio != 0 && preferred_ratio < 1.f) preferred_ratio = 1.f;
upload_limit *= 1000;
torrent_upload_limit *= 1000;
torrent_download_limit *= 1000;
download_limit *= 1000;
if (download_limit <= 0) download_limit = -1;
if (upload_limit <= 0) upload_limit = -1;
if (torrent_upload_limit <= 0) torrent_upload_limit = -1;
if (torrent_download_limit <= 0) torrent_download_limit = -1;
if (poll_interval < 2) poll_interval = 2;
if (wait_retry < 0) wait_retry = 0;
if (half_open_limit < 1) half_open_limit = -1;
if (upload_slots_limit <= 0) upload_slots_limit = -1;
if (!monitor_dir.empty() && !exists(monitor_dir))
{
std::cerr << "The monitor directory doesn't exist: " << monitor_dir.string() << std::endl;
return 1;
} }
if (vm.count("help")
|| vm.count("input-file") + vm.count("monitor-dir") == 0)
{
std::cout << desc << "\n";
return 1;
}
if (!log_file_name.empty())
g_log_file.open(log_file_name.c_str());
bool compact_allocation_mode = (allocation_mode == "compact");
using namespace libtorrent; using namespace libtorrent;
std::vector<std::string> input;
if (vm.count("input-file") > 0)
input = vm["input-file"].as< std::vector<std::string> >();
session_settings settings; session_settings settings;
proxy_settings ps; proxy_settings ps;
if (!proxy.empty())
{
std::size_t i = proxy.find(':');
ps.hostname = proxy.substr(0, i);
if (i == std::string::npos) ps.port = 8080;
else ps.port = atoi(proxy.substr(i + 1).c_str());
if (proxy_type == "socks5")
ps.type = proxy_settings::socks5;
else
ps.type = proxy_settings::http;
if (!proxy_login.empty())
{
std::size_t i = proxy_login.find(':');
if (i == std::string::npos)
{
std::cerr << "Proxy login did not match the required format: "
<< proxy_login << std::endl;
return 1;
}
ps.username = proxy_login.substr(0, i);
ps.password = proxy_login.substr(i + 1);
if (proxy_type == "socks5")
ps.type = proxy_settings::socks5_pw;
else
ps.type = proxy_settings::http_pw;
}
}
settings.user_agent = "client_test/" LIBTORRENT_VERSION; settings.user_agent = "client_test/" LIBTORRENT_VERSION;
settings.urlseed_wait_retry = wait_retry;
settings.announce_to_all_trackers = true; settings.announce_to_all_trackers = true;
settings.outgoing_ports.first = bind_port_start;
settings.outgoing_ports.second = bind_port_end;
std::deque<std::string> events; std::deque<std::string> events;
ptime next_dir_scan = time_now(); ptime next_dir_scan = time_now();
@@ -868,42 +725,6 @@ int main(int ac, char* av[])
handles_t handles; handles_t handles;
session ses(fingerprint("LT", LIBTORRENT_VERSION_MAJOR, LIBTORRENT_VERSION_MINOR, 0, 0) session ses(fingerprint("LT", LIBTORRENT_VERSION_MAJOR, LIBTORRENT_VERSION_MINOR, 0, 0)
, session::start_default_features | session::add_default_plugins, alert::all_categories); , session::start_default_features | session::add_default_plugins, alert::all_categories);
#ifndef TORRENT_DISABLE_GEO_IP
ses.load_asnum_db("GeoIPASNum.dat");
ses.load_country_db("GeoIP.dat");
#endif
// UPnP port mapping
ses.start_upnp();
// NAT-PMP port mapping
ses.start_natpmp();
// Local service discovery (finds peers on the local network)
ses.start_lsd();
ses.add_extension(&create_metadata_plugin);
ses.add_extension(&create_ut_pex_plugin);
ses.add_extension(&create_ut_metadata_plugin);
ses.add_extension(&create_smart_ban_plugin);
ses.set_max_uploads(upload_slots_limit);
ses.set_max_half_open_connections(half_open_limit);
ses.set_download_rate_limit(download_limit);
ses.set_upload_rate_limit(upload_limit);
ses.listen_on(std::make_pair(listen_port, listen_port + 10)
, bind_to_interface.c_str());
ses.set_settings(settings);
ses.set_tracker_proxy(ps);
ses.set_peer_proxy(ps);
ses.set_web_seed_proxy(ps);
#ifndef TORRENT_NO_DEPRECATE
if (log_level == "debug")
ses.set_severity_level(alert::debug);
else if (log_level == "warning")
ses.set_severity_level(alert::warning);
else if (log_level == "fatal")
ses.set_severity_level(alert::fatal);
else
ses.set_severity_level(alert::info);
#endif
boost::filesystem::ifstream ses_state_file(".ses_state" boost::filesystem::ifstream ses_state_file(".ses_state"
, std::ios_base::binary); , std::ios_base::binary);
@@ -932,28 +753,122 @@ int main(int ac, char* av[])
ses.start_dht(dht_state); ses.start_dht(dht_state);
#endif #endif
// look for ipfilter.dat #ifndef TORRENT_DISABLE_GEO_IP
// poor man's parser ses.load_asnum_db("GeoIPASNum.dat");
// reads emule ipfilter files. ses.load_country_db("GeoIP.dat");
// with the following format: #endif
//
// <first-ip> - <last-ip> , <access> , <comment> int listen_port = 6881;
// float preferred_ratio = 0.f;
// first-ip is an ip address that defines the first std::string allocation_mode = "sparse";
// address of the range boost::filesystem::path save_path(".");
// last-ip is the last ip address in the range int torrent_upload_limit = 0;
// access is a number specifying the access control int torrent_download_limit = 0;
// for this ip-range. Right now values > 127 = allowed boost::filesystem::path monitor_dir;
// and numbers <= 127 = blocked std::string bind_to_interface = "";
// the rest of the line is ignored int poll_interval = 5;
//
// In the original spec ranges may not overlap, but // load the torrents given on the commandline
// here ranges may overlap, and it is the last added boost::regex ex("([0-9A-Fa-f]{40})@(.+)");
// rule that has precedence for addresses that may fall
// into more than one range. for (int i = 1; i < argc; ++i)
if (!ip_filter_file.empty())
{ {
std::ifstream in(ip_filter_file.c_str()); if (argv[i][0] != '-')
{
// interpret this as a torrent
// first see if this is a torrentless download
if (std::strstr("magnet:", argv[i]) == argv[i])
{
add_torrent_params p;
p.save_path = save_path;
p.storage_mode = allocation_mode == "compact" ? storage_mode_compact
: storage_mode_sparse;
std::cout << "adding MANGET link: " << argv[i] << std::endl;
error_code ec;
torrent_handle h = add_magnet_uri(ses, argv[i], p, ec);
if (ec)
{
std::cerr << ec.message() << std::endl;
continue;
}
handles.insert(std::make_pair(std::string(), h));
h.set_max_connections(50);
h.set_max_uploads(-1);
h.set_ratio(preferred_ratio);
h.set_upload_limit(torrent_upload_limit);
h.set_download_limit(torrent_download_limit);
continue;
}
// match it against the <hash>@<tracker> format
boost::cmatch what;
if (boost::regex_match(argv[i], what, ex))
{
sha1_hash info_hash = boost::lexical_cast<sha1_hash>(what[1]);
add_torrent_params p;
p.name = std::string(what[2]).c_str();
p.info_hash = info_hash;
p.save_path = save_path;
p.storage_mode = allocation_mode == "compact" ? storage_mode_compact
: storage_mode_sparse;
p.paused = true;
p.duplicate_is_error = false;
p.auto_managed = true;
error_code ec;
torrent_handle h = ses.add_torrent(p, ec);
if (ec)
{
std::cerr << ec.message() << std::endl;
continue;
}
handles.insert(std::make_pair(std::string(), h));
h.set_max_connections(50);
h.set_max_uploads(-1);
h.set_ratio(preferred_ratio);
h.set_upload_limit(torrent_upload_limit);
h.set_download_limit(torrent_download_limit);
continue;
}
// if it's a torrent file, open it as usual
add_torrent(ses, handles, argv[i], preferred_ratio
, allocation_mode == "compact", save_path, false
, torrent_upload_limit, torrent_download_limit);
continue;
}
// if there's a flag but no argument following, ignore it
if (argc == i) continue;
char const* arg = argv[i+1];
switch (argv[i][1])
{
case 'f': g_log_file.open(arg); break;
case 'o': ses.set_max_half_open_connections(atoi(arg)); break;
case 'p': listen_port = atoi(arg); break;
case 'r':
preferred_ratio = atoi(arg);
if (preferred_ratio != 0 && preferred_ratio < 1.f) preferred_ratio = 1.f;
break;
case 'd': ses.set_download_rate_limit(atoi(arg) * 1000); break;
case 'u': ses.set_upload_rate_limit(atoi(arg) * 1000); break;
case 'S': ses.set_max_uploads(atoi(arg)); break;
case 'a': allocation_mode = arg; break;
case 's': save_path = arg; break;
case 'U': torrent_upload_limit = atoi(arg) * 1000; break;
case 'D': torrent_download_limit = atoi(arg) * 1000; break;
case 'm': monitor_dir = arg; break;
case 'b': bind_to_interface = arg; break;
case 'w': settings.urlseed_wait_retry = atoi(arg); break;
case 't': poll_interval = atoi(arg); break;
case 'x':
{
std::ifstream in(arg);
ip_filter filter; ip_filter filter;
while (in.good()) while (in.good())
{ {
@@ -978,72 +893,15 @@ int main(int ac, char* av[])
} }
ses.set_ip_filter(filter); ses.set_ip_filter(filter);
} }
boost::filesystem::path save_path(save_path_str); break;
case 'c': ses.set_max_connections(atoi(arg)); break;
// load the torrents given on the commandline }
boost::regex ex("([0-9A-Fa-f]{40})@(.+)");
for (std::vector<std::string>::const_iterator i = input.begin();
i != input.end(); ++i)
{
#ifndef BOOST_NO_EXCEPTIONS
try
{
#endif
// first see if this is a torrentless download
if (i->substr(0, 7) == "magnet:")
{
add_torrent_params p;
p.save_path = save_path;
p.storage_mode = compact_allocation_mode ? storage_mode_compact
: storage_mode_sparse;
std::cout << "adding MANGET link: " << *i << std::endl;
torrent_handle h = add_magnet_uri(ses, *i, p);
handles.insert(std::make_pair(std::string(), h));
h.set_max_connections(50);
h.set_max_uploads(-1);
h.set_ratio(preferred_ratio);
h.set_upload_limit(torrent_upload_limit);
h.set_download_limit(torrent_download_limit);
continue;
} }
boost::cmatch what;
if (boost::regex_match(i->c_str(), what, ex))
{
sha1_hash info_hash = boost::lexical_cast<sha1_hash>(what[1]);
add_torrent_params p; ses.listen_on(std::make_pair(listen_port, listen_port + 10)
p.name = std::string(what[2]).c_str(); , bind_to_interface.c_str());
p.info_hash = info_hash;
p.save_path = save_path;
p.storage_mode = compact_allocation_mode ? storage_mode_compact : storage_mode_sparse;
p.paused = true;
p.duplicate_is_error = false;
p.auto_managed = true;
torrent_handle h = ses.add_torrent(p);
handles.insert(std::make_pair(std::string(), h)); ses.set_settings(settings);
h.set_max_connections(50);
h.set_max_uploads(-1);
h.set_ratio(preferred_ratio);
h.set_upload_limit(torrent_upload_limit);
h.set_download_limit(torrent_download_limit);
continue;
}
// if it's a torrent file, open it as usual
add_torrent(ses, handles, i->c_str(), preferred_ratio
, compact_allocation_mode, save_path, false
, torrent_upload_limit, torrent_download_limit);
#ifndef BOOST_NO_EXCEPTIONS
}
catch (std::exception& e)
{
std::cout << e.what() << "\n";
}
#endif
}
// main loop // main loop
std::vector<peer_info> peers; std::vector<peer_info> peers;
@@ -1386,7 +1244,7 @@ int main(int ac, char* av[])
<< "seeds: " << esc("37") << s.num_seeds << esc("0") << " " << "seeds: " << esc("37") << s.num_seeds << esc("0") << " "
<< "distributed copies: " << esc("37") << s.distributed_copies << esc("0") << "distributed copies: " << esc("37") << s.distributed_copies << esc("0")
<< " sparse regions: " << s.sparse_regions << " sparse regions: " << s.sparse_regions
// << " magnet-link: " << make_magnet_uri(h) << "\n" // << " magnet-link: " << make_magnet_uri(h) << "\n"
<< " download: " << esc("32") << (s.download_rate > 0 ? add_suffix(s.download_rate) + "/s ": " ") << esc("0"); << " download: " << esc("32") << (s.download_rate > 0 ? add_suffix(s.download_rate) + "/s ": " ") << esc("0");
boost::posix_time::time_duration t = s.next_announce; boost::posix_time::time_duration t = s.next_announce;
out << " next announce: " << esc("37") out << " next announce: " << esc("37")
@@ -1600,7 +1458,7 @@ int main(int ac, char* av[])
&& next_dir_scan < time_now()) && next_dir_scan < time_now())
{ {
scan_dir(monitor_dir, ses, handles, preferred_ratio scan_dir(monitor_dir, ses, handles, preferred_ratio
, compact_allocation_mode, save_path, torrent_upload_limit , allocation_mode == "compact", save_path, torrent_upload_limit
, torrent_download_limit); , torrent_download_limit);
next_dir_scan = time_now() + seconds(poll_interval); next_dir_scan = time_now() + seconds(poll_interval);
} }
@@ -1624,13 +1482,6 @@ int main(int ac, char* av[])
bencode(std::ostream_iterator<char>(out), dht_state); bencode(std::ostream_iterator<char>(out), dht_state);
#endif #endif
std::cout << "closing session" << std::endl; std::cout << "closing session" << std::endl;
}
#ifndef BOOST_NO_EXCEPTIONS
catch (std::exception& e)
{
std::cout << e.what() << "\n";
}
#endif
return 0; return 0;
} }

View File

@@ -57,11 +57,6 @@ int main(int argc, char* argv[])
boost::filesystem::path::default_name_check(boost::filesystem::no_check); boost::filesystem::path::default_name_check(boost::filesystem::no_check);
#endif #endif
#ifndef BOOST_NO_EXCEPTIONS
try
{
#endif
int size = file_size(argv[1]); int size = file_size(argv[1]);
if (size > 10 * 1000000) if (size > 10 * 1000000)
{ {
@@ -82,7 +77,13 @@ int main(int argc, char* argv[])
std::cout << "\n\n----- raw info -----\n\n"; std::cout << "\n\n----- raw info -----\n\n";
std::cout << e << std::endl; std::cout << e << std::endl;
torrent_info t(e); error_code ec;
torrent_info t(e, ec);
if (ec)
{
std::cout << ec.message() << std::endl;
return 1;
}
// print info about torrent // print info about torrent
std::cout << "\n\n----- torrent file info -----\n\n"; std::cout << "\n\n----- torrent file info -----\n\n";
@@ -125,14 +126,6 @@ int main(int argc, char* argv[])
<< last << " ]\n"; << last << " ]\n";
} }
#ifndef BOOST_NO_EXCEPTIONS
}
catch (std::exception& e)
{
std::cout << e.what() << "\n";
}
#endif
return 0; return 0;
} }

View File

@@ -54,28 +54,28 @@ int main(int argc, char* argv[])
return 1; return 1;
} }
#ifndef BOOST_NO_EXCEPTIONS
try
#endif
{
session s; session s;
s.listen_on(std::make_pair(6881, 6889)); s.listen_on(std::make_pair(6881, 6889));
add_torrent_params p; add_torrent_params p;
p.save_path = "./"; p.save_path = "./";
p.ti = new torrent_info(argv[1]); error_code ec;
s.add_torrent(p); p.ti = new torrent_info(argv[1], ec);
if (ec)
{
std::cout << ec.message() << std::endl;
return 1;
}
s.add_torrent(p, ec);
if (ec)
{
std::cerr << ec.message() << std::endl;
return 1;
}
// wait for the user to end // wait for the user to end
char a; char a;
std::cin.unsetf(std::ios_base::skipws); std::cin.unsetf(std::ios_base::skipws);
std::cin >> a; std::cin >> a;
}
#ifndef BOOST_NO_EXCEPTIONS
catch (std::exception& e)
{
std::cout << e.what() << "\n";
}
#endif
return 0; return 0;
} }

View File

@@ -73,6 +73,7 @@ namespace libtorrent
duplicate_torrent, duplicate_torrent,
invalid_torrent_handle, invalid_torrent_handle,
invalid_entry_type, invalid_entry_type,
missing_info_hash_in_uri,
}; };
} }

View File

@@ -48,6 +48,7 @@ namespace libtorrent
std::string TORRENT_EXPORT make_magnet_uri(torrent_handle const& handle); std::string TORRENT_EXPORT make_magnet_uri(torrent_handle const& handle);
std::string TORRENT_EXPORT make_magnet_uri(torrent_info const& info); std::string TORRENT_EXPORT make_magnet_uri(torrent_info const& info);
#ifndef BOOST_NO_EXCEPTIONS
#ifndef TORRENT_NO_DEPRECATE #ifndef TORRENT_NO_DEPRECATE
// deprecated in 0.14 // deprecated in 0.14
torrent_handle TORRENT_EXPORT add_magnet_uri(session& ses, std::string const& uri torrent_handle TORRENT_EXPORT add_magnet_uri(session& ses, std::string const& uri
@@ -60,6 +61,10 @@ namespace libtorrent
torrent_handle TORRENT_EXPORT add_magnet_uri(session& ses, std::string const& uri torrent_handle TORRENT_EXPORT add_magnet_uri(session& ses, std::string const& uri
, add_torrent_params p); , add_torrent_params p);
#endif
torrent_handle TORRENT_EXPORT add_magnet_uri(session& ses, std::string const& uri
, add_torrent_params p, error_code& ec);
} }
#endif #endif

View File

@@ -172,7 +172,7 @@ namespace libtorrent
torrent_info(fs::wpath const& filename); torrent_info(fs::wpath const& filename);
#endif #endif
torrent_info(sha1_hash const& info_hash, error_code& ec); torrent_info(sha1_hash const& info_hash);
torrent_info(lazy_entry const& torrent_file, error_code& ec); torrent_info(lazy_entry const& torrent_file, error_code& ec);
torrent_info(char const* buffer, int size, error_code& ec); torrent_info(char const* buffer, int size, error_code& ec);
torrent_info(fs::path const& filename, error_code& ec); torrent_info(fs::path const& filename, error_code& ec);

View File

@@ -69,6 +69,7 @@ namespace libtorrent
"torrent already exists in session", "torrent already exists in session",
"invalid torrent handle used", "invalid torrent handle used",
"invalid type requested from entry", "invalid type requested from entry",
"missing info-hash from URI",
}; };
if (ev < 0 || ev >= sizeof(msgs)/sizeof(msgs[0])) if (ev < 0 || ev >= sizeof(msgs)/sizeof(msgs[0]))
return "Unknown error"; return "Unknown error";

View File

@@ -89,6 +89,7 @@ namespace libtorrent
return ret.str(); return ret.str();
} }
#ifndef BOOST_NO_EXCEPTIONS
#ifndef TORRENT_NO_DEPRECATE #ifndef TORRENT_NO_DEPRECATE
torrent_handle add_magnet_uri(session& ses, std::string const& uri torrent_handle add_magnet_uri(session& ses, std::string const& uri
, fs::path const& save_path , fs::path const& save_path
@@ -121,27 +122,44 @@ namespace libtorrent
torrent_handle add_magnet_uri(session& ses, std::string const& uri torrent_handle add_magnet_uri(session& ses, std::string const& uri
, add_torrent_params p) , add_torrent_params p)
{
error_code ec;
torrent_handle ret = add_magnet_uri(ses, uri, p, ec);
if (ec) throw libtorrent_exceptions(ec);
return ret;
}
#endif
torrent_handle add_magnet_uri(session& ses, std::string const& uri
, add_torrent_params p, error_code& ec)
{ {
std::string name; std::string name;
std::string tracker; std::string tracker;
error_code ec; error_code e;
boost::optional<std::string> display_name = url_has_argument(uri, "dn"); boost::optional<std::string> display_name = url_has_argument(uri, "dn");
if (display_name) name = unescape_string(display_name->c_str(), ec); if (display_name) name = unescape_string(display_name->c_str(), e);
boost::optional<std::string> tracker_string = url_has_argument(uri, "tr"); boost::optional<std::string> tracker_string = url_has_argument(uri, "tr");
if (tracker_string) tracker = unescape_string(tracker_string->c_str(), ec); if (tracker_string) tracker = unescape_string(tracker_string->c_str(), e);
boost::optional<std::string> btih = url_has_argument(uri, "xt"); boost::optional<std::string> btih = url_has_argument(uri, "xt");
if (!btih) return torrent_handle(); if (!btih)
{
ec = error_code(errors::missing_info_hash_in_uri, libtorrent_category);
return torrent_handle();
}
if (btih->compare(0, 9, "urn:btih:") != 0) return torrent_handle(); if (btih->compare(0, 9, "urn:btih:") != 0)
{
ec = error_code(errors::missing_info_hash_in_uri, libtorrent_category);
return torrent_handle();
}
sha1_hash info_hash(base32decode(btih->substr(9))); sha1_hash info_hash(base32decode(btih->substr(9)));
if (!tracker.empty()) p.tracker_url = tracker.c_str(); if (!tracker.empty()) p.tracker_url = tracker.c_str();
p.info_hash = info_hash; p.info_hash = info_hash;
if (!name.empty()) p.name = name.c_str(); if (!name.empty()) p.name = name.c_str();
return ses.add_torrent(p); return ses.add_torrent(p, ec);
} }
} }

View File

@@ -313,6 +313,7 @@ namespace libtorrent
return m_impl->add_torrent(params, ec); return m_impl->add_torrent(params, ec);
} }
#ifndef BOOST_NO_EXCEPTIONS
#ifndef TORRENT_NO_DEPRECATE #ifndef TORRENT_NO_DEPRECATE
// if the torrent already exists, this will throw duplicate_torrent // if the torrent already exists, this will throw duplicate_torrent
torrent_handle session::add_torrent( torrent_handle session::add_torrent(
@@ -381,6 +382,7 @@ namespace libtorrent
p.userdata = userdata; p.userdata = userdata;
return add_torrent(p); return add_torrent(p);
} }
#endif
#endif #endif
void session::remove_torrent(const torrent_handle& h, int options) void session::remove_torrent(const torrent_handle& h, int options)

View File

@@ -2420,7 +2420,6 @@ namespace aux {
void session_impl::set_max_connections(int limit) void session_impl::set_max_connections(int limit)
{ {
TORRENT_ASSERT(limit > 0 || limit == -1);
mutex_t::scoped_lock l(m_mutex); mutex_t::scoped_lock l(m_mutex);
INVARIANT_CHECK; INVARIANT_CHECK;
@@ -2443,7 +2442,6 @@ namespace aux {
void session_impl::set_max_half_open_connections(int limit) void session_impl::set_max_half_open_connections(int limit)
{ {
TORRENT_ASSERT(limit > 0 || limit == -1);
mutex_t::scoped_lock l(m_mutex); mutex_t::scoped_lock l(m_mutex);
INVARIANT_CHECK; INVARIANT_CHECK;
@@ -2454,7 +2452,6 @@ namespace aux {
void session_impl::set_download_rate_limit(int bytes_per_second) void session_impl::set_download_rate_limit(int bytes_per_second)
{ {
TORRENT_ASSERT(bytes_per_second > 0 || bytes_per_second == -1);
mutex_t::scoped_lock l(m_mutex); mutex_t::scoped_lock l(m_mutex);
INVARIANT_CHECK; INVARIANT_CHECK;
@@ -2465,7 +2462,6 @@ namespace aux {
void session_impl::set_upload_rate_limit(int bytes_per_second) void session_impl::set_upload_rate_limit(int bytes_per_second)
{ {
TORRENT_ASSERT(bytes_per_second > 0 || bytes_per_second == -1);
mutex_t::scoped_lock l(m_mutex); mutex_t::scoped_lock l(m_mutex);
INVARIANT_CHECK; INVARIANT_CHECK;