std::string make_magnet_uri(torrent_handle const& handle) { if (!handle.is_valid()) return ""; char ret[1024]; sha1_hash const& ih = handle.info_hash(); int num_chars = snprintf(ret, sizeof(ret), "magnet:?xt=urn:btih:%s" , base32encode(std::string((char const*)&ih[0], 20)).c_str()); std::string name = handle.name(); if (!name.empty()) num_chars += snprintf(ret + num_chars, sizeof(ret) - num_chars, "&dn=%s" , escape_string(name.c_str(), name.length()).c_str()); std::string tracker; torrent_status st = handle.status(); if (!st.current_tracker.empty()) { tracker = st.current_tracker; } else { std::vector<announce_entry> const& tr = handle.trackers(); if (!tr.empty()) tracker = tr[0].url; } if (!tracker.empty()) num_chars += snprintf(ret + num_chars, sizeof(ret) - num_chars, "&tr=%s" , escape_string(tracker.c_str(), tracker.size()).c_str()); return ret; }
std::string make_magnet_uri(torrent_handle const& handle) { std::stringstream ret; if (!handle.is_valid()) return ret.str(); std::string name = handle.name(); ret << "magnet:?xt=urn:btih:" << base32encode( std::string((char*)handle.info_hash().begin(), 20)); if (!name.empty()) ret << "&dn=" << escape_string(name.c_str(), name.length()); torrent_status st = handle.status(); if (!st.current_tracker.empty()) { ret << "&tr=" << escape_string(st.current_tracker.c_str() , st.current_tracker.length()); } else { std::vector<announce_entry> const& tr = handle.trackers(); if (!tr.empty()) { ret << "&tr=" << escape_string(tr[0].url.c_str() , tr[0].url.length()); } } return ret.str(); }
std::string make_magnet_uri(torrent_info const& info) { std::stringstream ret; if (!info.is_valid()) return ret.str(); std::string name = info.name(); ret << "magnet:?xt=urn:btih:" << base32encode( std::string((char*)info.info_hash().begin(), 20)); if (!name.empty()) ret << "&dn=" << escape_string(name.c_str(), name.length()); std::vector<announce_entry> const& tr = info.trackers(); if (!tr.empty()) { ret << "&tr=" << escape_string(tr[0].url.c_str() , tr[0].url.length()); } return ret.str(); }
std::string make_magnet_uri(torrent_info const& info) { char ret[1024]; int num_chars = snprintf(ret, sizeof(ret), "magnet:?xt=urn:btih:%s" , base32encode(std::string((char*)info.info_hash().begin(), 20)).c_str()); std::string const& name = info.name(); if (!name.empty()) num_chars += snprintf(ret + num_chars, sizeof(ret) - num_chars, "&dn=%s" , escape_string(name.c_str(), name.length()).c_str()); std::vector<announce_entry> const& tr = info.trackers(); if (!tr.empty()) { num_chars += snprintf(ret + num_chars, sizeof(ret) - num_chars, "&tr=%s" , escape_string(tr[0].url.c_str(), tr[0].url.length()).c_str()); } return ret; }
int main(int argc, char **argv) { long long r, w; if (argv[0]) if (argv[1]) if (str_equal(argv[1], "-h")) die_usage(); for (;;) { r = readblock(0, bufr, sizeof bufr); if (r == -1) die_fatal("unable to read input", 0); if (r == 0) die(); w = (((r * 8) + 4) / 5); if (!base32encode(bufw, w + 1, bufr, r)) { errno = 0; die_fatal("unable to encode to base32", 0); } out(bufw, w); if (r != sizeof bufr) die(); } return 0; }
tracker_response parse_tracker_response(char const* data, int size, error_code& ec , int flags, sha1_hash scrape_ih) { tracker_response resp; bdecode_node e; int res = bdecode(data, data + size, e, ec); if (ec) return resp; if (res != 0 || e.type() != bdecode_node::dict_t) { ec.assign(errors::invalid_tracker_response, get_libtorrent_category()); return resp; } int interval = int(e.dict_find_int_value("interval", 0)); // if no interval is specified, default to 30 minutes if (interval == 0) interval = 1800; int min_interval = int(e.dict_find_int_value("min interval", 30)); resp.interval = interval; resp.min_interval = min_interval; bdecode_node tracker_id = e.dict_find_string("tracker id"); if (tracker_id) resp.trackerid = tracker_id.string_value(); // parse the response bdecode_node failure = e.dict_find_string("failure reason"); if (failure) { resp.failure_reason = failure.string_value(); ec.assign(errors::tracker_failure, get_libtorrent_category()); return resp; } bdecode_node warning = e.dict_find_string("warning message"); if (warning) resp.warning_message = warning.string_value(); if (0 != (flags & tracker_request::scrape_request)) { bdecode_node files = e.dict_find_dict("files"); if (!files) { ec.assign(errors::invalid_files_entry, get_libtorrent_category()); return resp; } bdecode_node scrape_data = files.dict_find_dict( scrape_ih.to_string()); if (!scrape_data) { ec.assign(errors::invalid_hash_entry, get_libtorrent_category()); return resp; } resp.complete = int(scrape_data.dict_find_int_value("complete", -1)); resp.incomplete = int(scrape_data.dict_find_int_value("incomplete", -1)); resp.downloaded = int(scrape_data.dict_find_int_value("downloaded", -1)); resp.downloaders = int(scrape_data.dict_find_int_value("downloaders", -1)); return resp; } // look for optional scrape info resp.complete = int(e.dict_find_int_value("complete", -1)); resp.incomplete = int(e.dict_find_int_value("incomplete", -1)); resp.downloaded = int(e.dict_find_int_value("downloaded", -1)); bdecode_node peers_ent = e.dict_find("peers"); if (peers_ent && peers_ent.type() == bdecode_node::string_t) { char const* peers = peers_ent.string_ptr(); int len = peers_ent.string_length(); #if TORRENT_USE_I2P if (0 != (flags & tracker_request::i2p)) { error_code parse_error; for (int i = 0; i < len; i += 32) { if (len - i < 32) break; peer_entry p; p.hostname = base32encode(std::string(peers + i, 32), string::i2p); p.hostname += ".b32.i2p"; p.port = 6881; resp.peers.push_back(p); } } else #endif { resp.peers4.reserve(len / 6); for (int i = 0; i < len; i += 6) { if (len - i < 6) break; ipv4_peer_entry p; p.ip = detail::read_v4_address(peers).to_v4().to_bytes(); p.port = detail::read_uint16(peers); resp.peers4.push_back(p); } } } else if (peers_ent && peers_ent.type() == bdecode_node::list_t) { int len = peers_ent.list_size(); resp.peers.reserve(len); error_code parse_error; for (int i = 0; i < len; ++i) { peer_entry p; if (!extract_peer_info(peers_ent.list_at(i), p, parse_error)) continue; resp.peers.push_back(p); } // only report an error if all peer entries are invalid if (resp.peers.empty() && parse_error) { ec = parse_error; return resp; } } else { peers_ent.clear(); } #if TORRENT_USE_IPV6 bdecode_node ipv6_peers = e.dict_find_string("peers6"); if (ipv6_peers) { char const* peers = ipv6_peers.string_ptr(); int len = ipv6_peers.string_length(); resp.peers6.reserve(len / 18); for (int i = 0; i < len; i += 18) { if (len - i < 18) break; ipv6_peer_entry p; p.ip = detail::read_v6_address(peers).to_v6().to_bytes(); p.port = detail::read_uint16(peers); resp.peers6.push_back(p); } } else { ipv6_peers.clear(); } #else bdecode_node ipv6_peers; #endif /* // if we didn't receive any peers. We don't care if we're stopping anyway if (peers_ent == 0 && ipv6_peers == 0 && tracker_req().event != tracker_request::stopped) { ec.assign(errors::invalid_peers_entry, get_libtorrent_category()); return resp; } */ bdecode_node ip_ent = e.dict_find_string("external ip"); if (ip_ent) { char const* p = ip_ent.string_ptr(); if (ip_ent.string_length() == int(address_v4::bytes_type().size())) resp.external_ip = detail::read_v4_address(p); #if TORRENT_USE_IPV6 else if (ip_ent.string_length() == int(address_v6::bytes_type().size())) resp.external_ip = detail::read_v6_address(p); #endif } return resp; }