Skip to content

Commit c7de3ee

Browse files
committed
add support for libtorrent-rasterbar-1.2
1 parent b514d3f commit c7de3ee

File tree

3 files changed

+135
-45
lines changed

3 files changed

+135
-45
lines changed

Makefile

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
#CXXFLAGS=-std=c++11 -DBOOST_ASIO_SEPARATE_COMPILATION
2-
CXXFLAGS=-std=c++11 -DBOOST_ASIO_DYN_LINK
2+
#CXXFLAGS=-std=c++11 -DBOOST_ASIO_DYN_LINK
3+
#since 2018-09-02:
4+
#CXXFLAGS=-std=c++11
5+
#since 2021-12-13:
6+
CXXFLAGS=-std=c++14 -Wall -Wfatal-errors
37
LDFLAGS=-lstdc++ -lboost_system -ltorrent-rasterbar
48

59
mag2tor: mag2tor.cpp

README

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,8 @@ libtorrent-rasterbar.
1616

1717
C++ version of mag2tor works almost the same way as mag2tor.py but
1818
doesn't require Python and Python bindings for libtorrent-rasterbar.
19+
20+
https://www.rasterbar.com/products/libtorrent/tutorial-ref.html
21+
https://www.rasterbar.com/products/libtorrent/manual-ref.html
22+
https://github.com/arvidn/libtorrent/releases/tag/libtorrent-1_2_5
23+
https://github.com/arvidn/libtorrent/releases/download/libtorrent-1_2_5/libtorrent-rasterbar-1.2.5.tar.gz

mag2tor.cpp

Lines changed: 125 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,28 @@
88
#include <iostream>
99
#include <thread>
1010

11+
#include <libtorrent/version.hpp>
1112
#include <libtorrent/add_torrent_params.hpp>
1213
#include <libtorrent/alert_types.hpp>
1314
#include <libtorrent/bencode.hpp>
1415
#include <libtorrent/create_torrent.hpp>
1516
#include <libtorrent/fingerprint.hpp>
1617
#include <libtorrent/session.hpp>
18+
#if LIBTORRENT_VERSION_NUM < 10200
1719
#include <libtorrent/session_settings.hpp>
20+
#else
21+
#include <libtorrent/settings_pack.hpp>
22+
#include <libtorrent/torrent_flags.hpp> // lt::torrent_flags::paused
23+
#include <libtorrent/magnet_uri.hpp> // lt::parse_magnet_uri()
24+
// struct lt::aux::session_impl::session_plugin_wrapper:
25+
#include <libtorrent/aux_/session_impl.hpp>
26+
// lt::create_ut_metadata_plugin():
27+
#include <libtorrent/extensions/ut_metadata.hpp>
28+
// lt::create_ut_pex_plugin():
29+
#include <libtorrent/extensions/ut_pex.hpp>
30+
// lt::create_smart_ban_plugin():
31+
#include <libtorrent/extensions/smart_ban.hpp>
32+
#endif
1833
#include <libtorrent/storage_defs.hpp> // lt::disabled_storage_constructor
1934
#include <libtorrent/torrent_handle.hpp>
2035
#include <libtorrent/torrent_info.hpp>
@@ -23,7 +38,8 @@ static int usage(const char *argv0) {
2338
std::cerr << "usage: [options] " << argv0 << " <magnet-url>" <<
2439
std::endl;
2540
std::cerr << "where options are:" << std::endl;
26-
std::cerr << " -a, --anonymous anonymous mode" << std::endl;
41+
std::cerr << " -a, --anonymous anonymous mode"
42+
<< " via socks5://localhost:9050" << std::endl;
2743
std::cerr << " -t, --tcp TCP mode" << std::endl;
2844
std::cerr << " -u, --udp UDP mode (specifying both"
2945
<< " -t and -u enables both protocols" << std::endl;
@@ -36,11 +52,16 @@ namespace lt = libtorrent;
3652
int main(int argc, char *argv[]) {
3753
std::set_terminate(__gnu_cxx::__verbose_terminate_handler);
3854

55+
#if LIBTORRENT_VERSION_NUM < 10200
3956
lt::session_settings sset;
40-
lt::add_torrent_params atp;
57+
#else
58+
lt::settings_pack spack;
59+
#endif
4160
int sess_tcp_udp = 0;
61+
int sess_anon = 0;
4262
char *magnet_url = NULL;
4363

64+
// Parse cmdline options and args:
4465
for (;;) {
4566
static struct option lopts[] = {
4667
{"anonymous", no_argument, NULL, 'a'},
@@ -51,66 +72,114 @@ int main(int argc, char *argv[]) {
5172
int c = getopt_long(argc, argv, "atu", lopts, &loptind);
5273
if (c == -1) break;
5374
switch (c) {
54-
case 'a': sset.anonymous_mode = true; break;
55-
case 't': sess_tcp_udp |= 1; break;
56-
case 'u': sess_tcp_udp |= 2; break;
57-
default: return usage(argv[0]);;
75+
case 'a': sess_anon = 1; break;
76+
case 't': sess_tcp_udp |= 1; break;
77+
case 'u': sess_tcp_udp |= 2; break;
78+
default: return usage(argv[0]);
5879
}
5980
}
6081
if (argc - optind != 1) return usage(argv[0]);
61-
atp.url = argv[optind];
62-
switch (sess_tcp_udp) {
63-
case 0:
64-
sset.prefer_udp_trackers = false;
65-
sset.enable_outgoing_tcp = true;
66-
sset.enable_incoming_tcp = true;
67-
sset.enable_outgoing_utp = true;
68-
sset.enable_incoming_utp = true;
69-
break;
70-
case 1:
71-
sset.prefer_udp_trackers = false;
72-
sset.enable_outgoing_tcp = true;
73-
sset.enable_incoming_tcp = true;
74-
sset.enable_outgoing_utp = false;
75-
sset.enable_incoming_utp = false;
76-
break;
77-
case 2:
78-
sset.prefer_udp_trackers = true;
79-
sset.enable_outgoing_tcp = false;
80-
sset.enable_incoming_tcp = false;
81-
sset.enable_outgoing_utp = true;
82-
sset.enable_incoming_utp = true;
83-
break;
84-
case 3:
85-
sset.prefer_udp_trackers = true;
86-
sset.enable_outgoing_tcp = true;
87-
sset.enable_incoming_tcp = true;
88-
sset.enable_outgoing_utp = true;
89-
sset.enable_incoming_utp = true;
90-
break;
91-
}
82+
magnet_url = argv[optind];
83+
84+
// Init session settings:
85+
#if LIBTORRENT_VERSION_NUM < 10200
86+
sset.prefer_udp_trackers = sess_tcp_udp & 2 ? true : false;
87+
sset.enable_outgoing_tcp = sess_tcp_udp == 2 ? false : true;
88+
sset.enable_incoming_tcp = sess_tcp_udp == 2 ? false : true;
89+
sset.enable_outgoing_utp = sess_tcp_udp == 1 ? false : true
90+
sset.enable_incoming_utp = sess_tcp_udp == 1 ? false : true;
91+
sset.anonymous_mode = sess_anon ? true : false;
92+
#else
93+
spack.set_bool(lt::settings_pack::prefer_udp_trackers,
94+
sess_tcp_udp & 2 ? true : false);
95+
spack.set_bool(lt::settings_pack::enable_outgoing_tcp,
96+
sess_tcp_udp == 2 ? false : true);
97+
spack.set_bool(lt::settings_pack::enable_incoming_tcp,
98+
sess_tcp_udp == 2 ? false : true);
99+
spack.set_bool(lt::settings_pack::enable_outgoing_utp,
100+
sess_tcp_udp == 1 ? false : true);
101+
spack.set_bool(lt::settings_pack::enable_incoming_utp,
102+
sess_tcp_udp == 1 ? false : true);
103+
spack.set_str(lt::settings_pack::peer_fingerprint,
104+
lt::generate_fingerprint("LT", 0, 0, 0, 0));
105+
spack.set_str(lt::settings_pack::user_agent,
106+
"libtorrent/" LIBTORRENT_VERSION);
107+
if (sess_anon == 1) {
108+
spack.set_str(lt::settings_pack::proxy_hostname,
109+
"127.0.0.1");
110+
spack.set_int(lt::settings_pack::proxy_port, 9050);
111+
spack.set_int(lt::settings_pack::proxy_type,
112+
lt::settings_pack::proxy_type_t::socks5);
113+
// External listen interfaces are not needed when going via
114+
// 127.0.0.1:9050 (in fact, internal aren't too, but there's
115+
// no way to stop libtorrent from trying to bind to
116+
// something):
117+
spack.set_str(lt::settings_pack::listen_interfaces,
118+
"127.0.0.1:6881");
119+
// Connect only via proxy:
120+
spack.set_bool(lt::settings_pack::anonymous_mode, true);
121+
spack.set_bool(lt::settings_pack::proxy_peer_connections,
122+
true);
123+
spack.set_bool(lt::settings_pack::proxy_tracker_connections,
124+
true);
125+
// Resolve DNS via proxy:
126+
spack.set_bool(lt::settings_pack::proxy_hostnames, true);
127+
};
128+
// lt::session::start_default_features flag causes these to be set
129+
// to true, but neither is necessary for converting magnet: link
130+
// into .torrent file:
131+
spack.set_bool(lt::settings_pack::enable_upnp, false);
132+
spack.set_bool(lt::settings_pack::enable_natpmp, false);
133+
spack.set_bool(lt::settings_pack::enable_lsd, false);
134+
spack.set_bool(lt::settings_pack::enable_dht, false);
135+
#endif
92136

137+
#if LIBTORRENT_VERSION_NUM < 10200
93138
lt::session sess(lt::fingerprint("LT", 0, 0, 0, 0),
94139
lt::session::add_default_plugins);
95140
sess.set_settings(sset);
141+
lt::add_torrent_params atp;
96142
atp.upload_mode = true;
97143
atp.auto_managed = false;
98144
atp.paused = false;
99-
// Start with "storage == disabled" to avoid pre-allocating any files
100-
// mentioned in the torrent file on disk:
101-
atp.storage = lt::disabled_storage_constructor;
102-
atp.save_path = "."; // save in current dir
103145
/*
104146
// .flags duplicate .upload_mode/auto_managed/paused
105147
// functionality:
106148
atp.flags = lt::add_torrent_params::flag_update_subscribe
107149
| lt::add_torrent_params::flag_upload_mode
108150
| lt::add_torrent_params::flag_apply_ip_filter;
109151
*/
152+
#else
153+
// Create session_params and session. The ut_metadata extension
154+
// (plugin) is requited to get .torrent metadata via magnet: link,
155+
// but the other two default plugins (ut_pex and smart_ban) aren't.
156+
using plgnwrp = lt::aux::session_impl::session_plugin_wrapper;
157+
std::vector<std::shared_ptr<lt::plugin>> exts;
158+
exts.push_back(
159+
std::make_shared<plgnwrp>(&lt::create_ut_metadata_plugin));
160+
lt::session_params sparams(spack, exts);
161+
// sparams.disk_io_constructor = lt::disabled_disk_io_constructor();
162+
lt::session sess(sparams);
163+
// sess.add_extension(&lt::create_ut_pex_plugin);
164+
// sess.add_extension(&lt::create_smart_ban_plugin);
165+
lt::add_torrent_params atp = lt::parse_magnet_uri(magnet_url);
166+
atp.flags = lt::torrent_flags::upload_mode
167+
| lt::torrent_flags::auto_managed
168+
| lt::torrent_flags::paused;
169+
#endif
170+
// Start loading torrent metadata with "storage == disabled" to avoid
171+
// pre-allocating any files mentioned in the torrent file on disk:
172+
atp.storage = lt::disabled_storage_constructor;
173+
atp.save_path = "."; // save in current dir
174+
110175
lt::torrent_handle torh = sess.add_torrent(atp);
111-
std::cout << atp.url << ":";
176+
std::cout << magnet_url << ":";
112177
for (;;) {
178+
#if LIBTORRENT_VERSION_NUM < 10200
113179
std::deque<lt::alert*> alerts;
180+
#else
181+
std::vector<lt::alert*> alerts;
182+
#endif
114183
sess.pop_alerts(&alerts);
115184
for (lt::alert const* a : alerts) {
116185
std::cout << std::endl << a->message() << std::endl;
@@ -122,18 +191,30 @@ int main(int argc, char *argv[]) {
122191
}
123192
if (torh.status().has_metadata) {
124193
sess.pause();
194+
#if LIBTORRENT_VERSION_NUM < 10200
125195
lt::torrent_info tinf =
126196
torh.get_torrent_info();
127-
std::cout << tinf.name() << std::endl;
197+
const std::string &tname = tinf.name();
198+
#else
199+
std::shared_ptr<const lt::torrent_info> tinf =
200+
torh.torrent_file();
201+
const std::string &tname = tinf->name();
202+
#endif
203+
std::cout << tname << std::endl;
128204
std::cout.flush();
129205
std::ofstream ofs;
130206
ofs.exceptions(std::ofstream::failbit
131207
| std::ofstream::badbit);
132-
ofs.open(tinf.name() + ".torrent",
208+
ofs.open(tname + ".torrent",
133209
std::ofstream::binary);
134210
std::ostream_iterator<char> ofsi(ofs);
211+
#if LIBTORRENT_VERSION_NUM < 10200
135212
lt::bencode(ofsi, lt::create_torrent(tinf)
136213
.generate());
214+
#else
215+
lt::bencode(ofsi, lt::create_torrent(*tinf)
216+
.generate());
217+
#endif
137218
ofs.close();
138219
sess.remove_torrent(torh);
139220
goto done0;

0 commit comments

Comments
 (0)