forked from premiere/premiere-libtorrent
update examples to use C++11 and more succinct error handling
This commit is contained in:
parent
672556b4b2
commit
4c5ef920f0
|
@ -45,14 +45,13 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
std::vector<char> load_file(std::string const& filename)
|
std::vector<char> load_file(std::string const& filename)
|
||||||
{
|
{
|
||||||
std::vector<char> ret;
|
|
||||||
std::fstream in;
|
std::fstream in;
|
||||||
in.exceptions(std::ifstream::failbit);
|
in.exceptions(std::ifstream::failbit);
|
||||||
in.open(filename.c_str(), std::ios_base::in | std::ios_base::binary);
|
in.open(filename.c_str(), std::ios_base::in | std::ios_base::binary);
|
||||||
in.seekg(0, std::ios_base::end);
|
in.seekg(0, std::ios_base::end);
|
||||||
auto const size = in.tellg();
|
size_t const size = size_t(in.tellg());
|
||||||
in.seekg(0, std::ios_base::beg);
|
in.seekg(0, std::ios_base::beg);
|
||||||
ret.resize(static_cast<std::size_t>(size));
|
std::vector<char> ret(size);
|
||||||
in.read(ret.data(), ret.size());
|
in.read(ret.data(), ret.size());
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -60,7 +59,7 @@ std::vector<char> load_file(std::string const& filename)
|
||||||
int main(int argc, char* argv[]) try
|
int main(int argc, char* argv[]) try
|
||||||
{
|
{
|
||||||
if (argc < 2 || argc > 4) {
|
if (argc < 2 || argc > 4) {
|
||||||
fputs("usage: dump_torrent torrent-file [total-items-limit] [recursion-limit]\n", stderr);
|
std::cerr << "usage: dump_torrent torrent-file [total-items-limit] [recursion-limit]\n";
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,10 +119,10 @@ int main(int argc, char* argv[]) try
|
||||||
, t.name().c_str()
|
, t.name().c_str()
|
||||||
, t.num_files());
|
, t.num_files());
|
||||||
lt::file_storage const& st = t.files();
|
lt::file_storage const& st = t.files();
|
||||||
for (lt::file_index_t i(0); i < lt::file_index_t(st.num_files()); ++i)
|
for (lt::file_index_t i(0); i < st.end_file(); ++i)
|
||||||
{
|
{
|
||||||
lt::piece_index_t const first = st.map_file(i, 0, 0).piece;
|
auto 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 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);
|
auto const flags = st.file_flags(i);
|
||||||
std::stringstream file_hash;
|
std::stringstream file_hash;
|
||||||
if (!st.hash(i).is_all_zeros())
|
if (!st.hash(i).is_all_zeros())
|
||||||
|
|
|
@ -52,14 +52,13 @@ using namespace std::placeholders;
|
||||||
|
|
||||||
std::vector<char> load_file(std::string const& filename)
|
std::vector<char> load_file(std::string const& filename)
|
||||||
{
|
{
|
||||||
std::vector<char> ret;
|
|
||||||
std::fstream in;
|
std::fstream in;
|
||||||
in.exceptions(std::ifstream::failbit);
|
in.exceptions(std::ifstream::failbit);
|
||||||
in.open(filename.c_str(), std::ios_base::in | std::ios_base::binary);
|
in.open(filename.c_str(), std::ios_base::in | std::ios_base::binary);
|
||||||
in.seekg(0, std::ios_base::end);
|
in.seekg(0, std::ios_base::end);
|
||||||
size_t const size = size_t(in.tellg());
|
size_t const size = size_t(in.tellg());
|
||||||
in.seekg(0, std::ios_base::beg);
|
in.seekg(0, std::ios_base::beg);
|
||||||
ret.resize(size);
|
std::vector<char> ret(size);
|
||||||
in.read(ret.data(), ret.size());
|
in.read(ret.data(), ret.size());
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -76,8 +75,7 @@ std::string branch_path(std::string const& f)
|
||||||
int len = int(f.size());
|
int len = int(f.size());
|
||||||
// if the last character is / or \ ignore it
|
// if the last character is / or \ ignore it
|
||||||
if (f[len-1] == '/' || f[len-1] == '\\') --len;
|
if (f[len-1] == '/' || f[len-1] == '\\') --len;
|
||||||
while (len > 0)
|
while (len > 0) {
|
||||||
{
|
|
||||||
--len;
|
--len;
|
||||||
if (f[len] == '/' || f[len] == '\\')
|
if (f[len] == '/' || f[len] == '\\')
|
||||||
break;
|
break;
|
||||||
|
@ -108,63 +106,61 @@ bool file_filter(std::string const& f)
|
||||||
// return false if the first character of the filename is a .
|
// return false if the first character of the filename is a .
|
||||||
if (sep[0] == '.') return false;
|
if (sep[0] == '.') return false;
|
||||||
|
|
||||||
std::fprintf(stderr, "%s\n", f.c_str());
|
std::cerr << f << "\n";
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void print_progress(lt::piece_index_t i, int num)
|
|
||||||
{
|
|
||||||
std::fprintf(stderr, "\r%d/%d", static_cast<int>(i)+1, num);
|
|
||||||
}
|
|
||||||
|
|
||||||
void print_usage()
|
void print_usage()
|
||||||
{
|
{
|
||||||
fputs("usage: make_torrent FILE [OPTIONS]\n"
|
std::cerr << R"(usage: make_torrent FILE [OPTIONS]
|
||||||
"\n"
|
|
||||||
"Generates a torrent file from the specified file\n"
|
Generates a torrent file from the specified file
|
||||||
"or directory and writes it to standard out\n\n"
|
or directory and writes it to standard out
|
||||||
"OPTIONS:\n"
|
|
||||||
"-m file generate a merkle hash tree torrent.\n"
|
|
||||||
" merkle torrents require client support\n"
|
OPTIONS:
|
||||||
" the resulting full merkle tree is written to\n"
|
-m file generate a merkle hash tree torrent.
|
||||||
" the specified file\n"
|
merkle torrents require client support
|
||||||
"-w url adds a web seed to the torrent with\n"
|
the resulting full merkle tree is written to
|
||||||
" the specified url\n"
|
the specified file
|
||||||
"-t url adds the specified tracker to the\n"
|
-w url adds a web seed to the torrent with
|
||||||
" torrent. For multiple trackers, specify more\n"
|
the specified url
|
||||||
" -t options\n"
|
-t url adds the specified tracker to the
|
||||||
"-c comment sets the comment to the specified string\n"
|
torrent. For multiple trackers, specify more
|
||||||
"-C creator sets the created-by field to the specified string\n"
|
-t options
|
||||||
"-p bytes enables padding files. Files larger\n"
|
-c comment sets the comment to the specified string
|
||||||
" than bytes will be piece-aligned\n"
|
-C creator sets the created-by field to the specified string
|
||||||
"-s bytes specifies a piece size for the torrent\n"
|
-p bytes enables padding files. Files larger
|
||||||
" This has to be a multiple of 16 kiB\n"
|
than bytes will be piece-aligned
|
||||||
"-l Don't follow symlinks, instead encode them as\n"
|
-s bytes specifies a piece size for the torrent
|
||||||
" links in the torrent file\n"
|
This has to be a multiple of 16 kiB
|
||||||
"-o file specifies the output filename of the torrent file\n"
|
-l Don't follow symlinks, instead encode them as
|
||||||
" If this is not specified, the torrent file is\n"
|
links in the torrent file
|
||||||
" printed to the standard out, except on windows\n"
|
-o file specifies the output filename of the torrent file
|
||||||
" where the filename defaults to a.torrent\n"
|
If this is not specified, the torrent file is
|
||||||
"-r file add root certificate to the torrent, to verify\n"
|
printed to the standard out, except on windows
|
||||||
" the HTTPS tracker\n"
|
where the filename defaults to a.torrent
|
||||||
"-S info-hash add a similar torrent by info-hash. The similar\n"
|
-r file add root certificate to the torrent, to verify
|
||||||
" torrent is expected to share some files with this one\n"
|
the HTTPS tracker
|
||||||
"-L collection add a collection name to this torrent. Other torrents\n"
|
-S info-hash add a similar torrent by info-hash. The similar
|
||||||
" in the same collection is expected to share files\n"
|
torrent is expected to share some files with this one
|
||||||
" with this one.\n"
|
-L collection add a collection name to this torrent. Other torrents
|
||||||
"-M make the torrent compatible with mutable torrents\n"
|
in the same collection is expected to share files
|
||||||
" this means aligning large files and pad them in order\n"
|
with this one.
|
||||||
" for piece hashes to uniquely indentify a file without\n"
|
-M make the torrent compatible with mutable torrents
|
||||||
" overlap\n"
|
this means aligning large files and pad them in order
|
||||||
, stderr);
|
for piece hashes to uniquely indentify a file without
|
||||||
|
overlap
|
||||||
|
)";
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char* argv[]) try
|
int main(int argc_, char const* argv_[]) try
|
||||||
{
|
{
|
||||||
|
lt::span<char const*> args(argv_, size_t(argc_));
|
||||||
std::string creator_str = "libtorrent";
|
std::string creator_str = "libtorrent";
|
||||||
std::string comment_str;
|
std::string comment_str;
|
||||||
|
|
||||||
if (argc < 2) {
|
if (args.size() < 2) {
|
||||||
print_usage();
|
print_usage();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -186,17 +182,16 @@ int main(int argc, char* argv[]) try
|
||||||
outfile = "a.torrent";
|
outfile = "a.torrent";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
std::string full_path = argv[1];
|
std::string full_path = args[1];
|
||||||
argv += 2;
|
args = args.subspan(2);
|
||||||
argc -= 2;
|
|
||||||
|
|
||||||
for (; argc > 0; --argc, ++argv) {
|
for (; !args.empty(); args = args.subspan(1)) {
|
||||||
if (argv[0][0] != '-') {
|
if (args[0][0] != '-') {
|
||||||
print_usage();
|
print_usage();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
char const flag = argv[0][1];
|
char const flag = args[0][1];
|
||||||
|
|
||||||
switch (flag)
|
switch (flag)
|
||||||
{
|
{
|
||||||
|
@ -209,41 +204,41 @@ int main(int argc, char* argv[]) try
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (argc < 2) {
|
if (args.size() < 2) {
|
||||||
print_usage();
|
print_usage();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (flag)
|
switch (flag)
|
||||||
{
|
{
|
||||||
case 'w': web_seeds.push_back(argv[1]); break;
|
case 'w': web_seeds.push_back(args[1]); break;
|
||||||
case 't': trackers.push_back(argv[1]); break;
|
case 't': trackers.push_back(args[1]); break;
|
||||||
case 's': piece_size = atoi(argv[1]); break;
|
case 's': piece_size = atoi(args[1]); break;
|
||||||
case 'o': outfile = argv[1]; break;
|
case 'o': outfile = args[1]; break;
|
||||||
case 'C': creator_str = argv[1]; break;
|
case 'C': creator_str = args[1]; break;
|
||||||
case 'c': comment_str = argv[1]; break;
|
case 'c': comment_str = args[1]; break;
|
||||||
case 'r': root_cert = argv[1]; break;
|
case 'r': root_cert = args[1]; break;
|
||||||
case 'L': collections.push_back(argv[1]); break;
|
case 'L': collections.push_back(args[1]); break;
|
||||||
case 'p':
|
case 'p':
|
||||||
pad_file_limit = atoi(argv[1]);
|
pad_file_limit = atoi(args[1]);
|
||||||
flags |= lt::create_torrent::optimize_alignment;
|
flags |= lt::create_torrent::optimize_alignment;
|
||||||
break;
|
break;
|
||||||
case 'm':
|
case 'm':
|
||||||
merklefile = argv[1];
|
merklefile = args[1];
|
||||||
flags |= lt::create_torrent::merkle;
|
flags |= lt::create_torrent::merkle;
|
||||||
break;
|
break;
|
||||||
case 'S': {
|
case 'S': {
|
||||||
if (strlen(argv[1]) != 40) {
|
if (strlen(args[1]) != 40) {
|
||||||
std::fprintf(stderr, "invalid info-hash for -S. "
|
std::cerr << "invalid info-hash for -S. "
|
||||||
"Expected 40 hex characters\n");
|
"Expected 40 hex characters\n";
|
||||||
print_usage();
|
print_usage();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
std::stringstream hash(argv[1]);
|
std::stringstream hash(args[1]);
|
||||||
lt::sha1_hash ih;
|
lt::sha1_hash ih;
|
||||||
hash >> ih;
|
hash >> ih;
|
||||||
if (hash.fail()) {
|
if (hash.fail()) {
|
||||||
std::fprintf(stderr, "invalid info-hash for -S\n");
|
std::cerr << "invalid info-hash for -S\n";
|
||||||
print_usage();
|
print_usage();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -254,8 +249,7 @@ int main(int argc, char* argv[]) try
|
||||||
print_usage();
|
print_usage();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
++argv;
|
args = args.subspan(1);
|
||||||
--argc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
lt::file_storage fs;
|
lt::file_storage fs;
|
||||||
|
@ -271,10 +265,9 @@ int main(int argc, char* argv[]) try
|
||||||
full_path = cwd + ("\\" + full_path);
|
full_path = cwd + ("\\" + full_path);
|
||||||
#else
|
#else
|
||||||
char const* ret = getcwd(cwd, sizeof(cwd));
|
char const* ret = getcwd(cwd, sizeof(cwd));
|
||||||
if (ret == NULL)
|
if (ret == nullptr) {
|
||||||
{
|
std::cerr << "failed to get current working directory: "
|
||||||
std::fprintf(stderr, "failed to get current working directory: %s\n"
|
<< strerror(errno) << "\n";
|
||||||
, strerror(errno));
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
full_path = cwd + ("/" + full_path);
|
full_path = cwd + ("/" + full_path);
|
||||||
|
@ -289,30 +282,26 @@ int main(int argc, char* argv[]) try
|
||||||
|
|
||||||
lt::create_torrent t(fs, piece_size, pad_file_limit, flags);
|
lt::create_torrent t(fs, piece_size, pad_file_limit, flags);
|
||||||
int tier = 0;
|
int tier = 0;
|
||||||
for (std::vector<std::string>::iterator i = trackers.begin()
|
for (std::string const& tr : trackers) {
|
||||||
, end(trackers.end()); i != end; ++i, ++tier)
|
t.add_tracker(tr, tier);
|
||||||
t.add_tracker(*i, tier);
|
++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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (std::string const& ws : web_seeds)
|
||||||
|
t.add_url_seed(ws);
|
||||||
|
|
||||||
|
for (std::string const& c : collections)
|
||||||
|
t.add_collection(c);
|
||||||
|
|
||||||
|
for (lt::sha1_hash const& s : similar)
|
||||||
|
t.add_similar_torrent(s);
|
||||||
|
|
||||||
|
auto const num = t.num_pieces();
|
||||||
|
lt::set_piece_hashes(t, branch_path(full_path)
|
||||||
|
, [num] (lt::piece_index_t const p) {
|
||||||
|
std::cerr << "\r" << p << "/" << num;
|
||||||
|
});
|
||||||
|
|
||||||
std::cerr << "\n";
|
std::cerr << "\n";
|
||||||
t.set_creator(creator_str.c_str());
|
t.set_creator(creator_str.c_str());
|
||||||
if (!comment_str.empty()) {
|
if (!comment_str.empty()) {
|
||||||
|
@ -331,17 +320,18 @@ int main(int argc, char* argv[]) try
|
||||||
std::fstream out;
|
std::fstream out;
|
||||||
out.exceptions(std::ifstream::failbit);
|
out.exceptions(std::ifstream::failbit);
|
||||||
out.open(outfile.c_str(), std::ios_base::out | std::ios_base::binary);
|
out.open(outfile.c_str(), std::ios_base::out | std::ios_base::binary);
|
||||||
out.write(&torrent[0], torrent.size());
|
out.write(torrent.data(), torrent.size());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
std::cout.write(&torrent[0], torrent.size());
|
std::cout.write(torrent.data(), torrent.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!merklefile.empty()) {
|
if (!merklefile.empty()) {
|
||||||
std::fstream merkle;
|
std::fstream merkle;
|
||||||
merkle.exceptions(std::ifstream::failbit);
|
merkle.exceptions(std::ifstream::failbit);
|
||||||
merkle.open(merklefile.c_str(), std::ios_base::out | std::ios_base::binary);
|
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);
|
auto const& tree = t.merkle_tree();
|
||||||
|
merkle.write(reinterpret_cast<char const*>(tree.data()), tree.size() * 20);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,8 +40,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
int main(int argc, char* argv[]) try
|
int main(int argc, char* argv[]) try
|
||||||
{
|
{
|
||||||
if (argc != 2)
|
if (argc != 2) {
|
||||||
{
|
|
||||||
std::cerr << "usage: ./simple_client torrent-file\n"
|
std::cerr << "usage: ./simple_client torrent-file\n"
|
||||||
"to stop the client, press return.\n";
|
"to stop the client, press return.\n";
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -50,7 +49,7 @@ int main(int argc, char* argv[]) try
|
||||||
lt::session s;
|
lt::session s;
|
||||||
lt::add_torrent_params p;
|
lt::add_torrent_params p;
|
||||||
p.save_path = "./";
|
p.save_path = "./";
|
||||||
p.ti = std::make_shared<lt::torrent_info>(std::string(argv[1]));
|
p.ti = std::make_shared<lt::torrent_info>(argv[1]);
|
||||||
s.add_torrent(p);
|
s.add_torrent(p);
|
||||||
|
|
||||||
// wait for the user to end
|
// wait for the user to end
|
||||||
|
@ -59,8 +58,6 @@ int main(int argc, char* argv[]) try
|
||||||
(void)ret; // ignore
|
(void)ret; // ignore
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
catch (std::exception const& e)
|
catch (std::exception const& e) {
|
||||||
{
|
|
||||||
std::cerr << "ERROR: " << e.what() << "\n";
|
std::cerr << "ERROR: " << e.what() << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue