Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add new example program, to organize a fuzzing corpus of .torrent files #7751

Merged
merged 1 commit into from
Oct 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion examples/Jamfile
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ exe bt-get2 : bt-get2.cpp ;
exe bt-get3 : bt-get3.cpp ;
exe stats_counters : stats_counters.cpp ;
exe dump_torrent : dump_torrent.cpp ;
exe rename_torrents : rename_torrents.cpp ;
exe torrent2magnet : torrent2magnet.cpp ;
exe magnet2torrent : magnet2torrent.cpp ;
exe dump_bdecode : dump_bdecode.cpp ;
Expand All @@ -49,7 +50,7 @@ explicit stage_connection_tester ;
explicit stage ;
explicit stage_dependencies ;

install stage : client_test connection_tester torrent2magnet magnet2torrent make_torrent dump_torrent check_files upnp_test stats_counters bt-get bt-get2 simple_client dump_bdecode custom_storage : <location>. ;
install stage : client_test connection_tester torrent2magnet magnet2torrent make_torrent dump_torrent rename_torrents check_files upnp_test stats_counters bt-get bt-get2 simple_client dump_bdecode custom_storage : <location>. ;
install stage_client_test : client_test : <location>. ;
install stage_connection_tester : connection_tester : <location>. ;

Expand Down
102 changes: 102 additions & 0 deletions examples/rename_torrents.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
/*
Copyright (c) 2024, Arvid Norberg
All rights reserved.
You may use, distribute and modify this code under the terms of the BSD license,
see LICENSE file.
*/

#include <cstdio> // for snprintf
#include <cinttypes> // for PRId64 et.al.
#include <fstream>
#include <iostream>
#include <filesystem>

#include "libtorrent/entry.hpp"
#include "libtorrent/bencode.hpp"
#include "libtorrent/load_torrent.hpp"
#include "libtorrent/bdecode.hpp"
#include "libtorrent/magnet_uri.hpp"
#include "libtorrent/span.hpp"

namespace {

[[noreturn]] void print_usage()
{
std::cerr << R"(usage: rename_torrents input-dir output-dir
This tool traversese the input directory, copying any torrent file into the
output directory under the name of the info-hash of the torrent. This can be
useful for organizing a fuzzing corpus.
)";
std::exit(1);
}

}

int main(int argc, char const* argv[]) try
{
namespace fs = std::filesystem;

lt::span<char const*> args(argv, argc);

// strip executable name
args = args.subspan(1);

lt::load_torrent_limits cfg;

if (args.empty() || args.size() != 2) print_usage();

char const* in_dir = args[0];
auto out_dir = fs::path(args[1]);

using namespace lt::literals;

for(auto& p: fs::recursive_directory_iterator(in_dir))
{
if (!p.is_regular_file()) continue;
if (p.path().extension() != ".torrent") continue;

try
{
lt::add_torrent_params const atp = lt::load_torrent_file(p.path().string(), cfg);
std::stringstream new_name;
if (atp.info_hashes.has_v1())
new_name << atp.info_hashes.v1;
if (atp.info_hashes.has_v2())
{
if (atp.info_hashes.has_v1())
new_name << "-";
new_name << atp.info_hashes.v2;
}
new_name << ".torrent";
try
{
fs::copy(p.path(), out_dir / fs::path(new_name.str()));
std::cout << "\33[2K\r" << p.path();
std::cout.flush();
}
catch (std::system_error const& err)
{
if (err.code() != std::errc::file_exists)
{
std::cerr << "\33[2K\rfailed to copy: " << p.path()
<< " -> " << (out_dir / fs::path(new_name.str()))
<< ": " << err.code().message() << "\n\n";
}
}
}
catch (std::system_error const& err)
{
std::cerr << "\33[2K\rfailed to load " << p.path()
<< ": " << err.code().message() << "\n\n";
}
}
return 0;
}
catch (std::exception const& e)
{
std::cerr << "ERROR: " << e.what() << "\n";
}

Loading