torrent_handle session::add_torrent(add_torrent_params const& params, error_code& ec) { ec.clear(); TORRENT_SYNC_CALL_RET2(torrent_handle, add_torrent, params, boost::ref(ec)); return r; }
address bind_to_device(io_service& ios, Socket& sock , bool ipv4, char const* device_name, int port, error_code& ec) { tcp::endpoint bind_ep(address_v4::any(), port); address ip = address::from_string(device_name, ec); if (!ec) { #if TORRENT_USE_IPV6 // this is to cover the case where "0.0.0.0" is considered any IPv4 or // IPv6 address. If we're asking to be bound to an IPv6 address and // providing 0.0.0.0 as the device, turn it into "::0" if (ip == address_v4::any() && !ipv4) ip = address_v6::any(); #endif bind_ep.address(ip); // it appears to be an IP. Just bind to that address sock.bind(bind_ep, ec); return bind_ep.address(); } ec.clear(); #ifdef SO_BINDTODEVICE // try to use SO_BINDTODEVICE here, if that exists. If it fails, // fall back to the mechanism we have below sock.set_option(bind_to_device_opt(device_name), ec); if (ec) #endif { ec.clear(); // TODO: 2 this could be done more efficiently by just looking up // the interface with the given name, maybe even with if_nametoindex() std::vector<ip_interface> ifs = enum_net_interfaces(ios, ec); if (ec) return bind_ep.address(); bool found = false; for (int i = 0; i < int(ifs.size()); ++i) { // we're looking for a specific interface, and its address // (which must be of the same family as the address we're // connecting to) if (strcmp(ifs[i].name, device_name) != 0) continue; if (ifs[i].interface_address.is_v4() != ipv4) continue; bind_ep.address(ifs[i].interface_address); found = true; break; } if (!found) { ec = error_code(boost::system::errc::no_such_device, generic_category()); return bind_ep.address(); } } sock.bind(bind_ep, ec); return bind_ep.address(); }
void parse_magnet_uri(std::string const& uri, add_torrent_params& p, error_code& ec) { ec.clear(); std::string name; std::string tracker; error_code e; std::string display_name = url_has_argument(uri, "dn"); if (!display_name.empty()) name = unescape_string(display_name.c_str(), e); // parse trackers out of the magnet link std::string::size_type pos = std::string::npos; std::string url = url_has_argument(uri, "tr", &pos); while (pos != std::string::npos) { error_code e; url = unescape_string(url, e); if (e) continue; p.trackers.push_back(url); pos = uri.find("&tr=", pos); if (pos == std::string::npos) break; pos += 4; url = uri.substr(pos, uri.find('&', pos) - pos); } std::string btih = url_has_argument(uri, "xt"); if (btih.empty()) { ec = errors::missing_info_hash_in_uri; return; } if (btih.compare(0, 9, "urn:btih:") != 0) { ec = errors::missing_info_hash_in_uri; return; } #ifndef TORRENT_DISABLE_DHT std::string::size_type node_pos = std::string::npos; std::string node = url_has_argument(uri, "dht", &node_pos); while (!node.empty()) { std::string::size_type divider = node.find_last_of(':'); if (divider != std::string::npos) { int port = atoi(node.c_str()+divider+1); if (port != 0) p.dht_nodes.push_back(std::make_pair(node.substr(0, divider), port)); } node_pos = uri.find("&dht=", node_pos); if (node_pos == std::string::npos) break; node_pos += 5; node = uri.substr(node_pos, uri.find('&', node_pos) - node_pos); } #endif sha1_hash info_hash; if (btih.size() == 40 + 9) from_hex(&btih[9], 40, (char*)&info_hash[0]); else info_hash.assign(base32decode(btih.substr(9))); p.info_hash = info_hash; if (!name.empty()) p.name = name; }
directory_iterator::directory_iterator(const path& p, error_code& ec) noexcept { ec.clear(); open_dir(p, ec); if (!ec) increment(ec); }
int load_file(std::string const& filename, std::vector<char>& v, error_code& ec, int limit = 8000000) { ec.clear(); FILE* f = fopen(filename.c_str(), "rb"); if (f == NULL) { ec.assign(errno, boost::system::get_generic_category()); return -1; } int r = fseek(f, 0, SEEK_END); if (r != 0) { ec.assign(errno, boost::system::get_generic_category()); fclose(f); return -1; } long s = ftell(f); if (s < 0) { ec.assign(errno, boost::system::get_generic_category()); fclose(f); return -1; } if (s > limit) { fclose(f); return -2; } r = fseek(f, 0, SEEK_SET); if (r != 0) { ec.assign(errno, boost::system::get_generic_category()); fclose(f); return -1; } v.resize(s); if (s == 0) { fclose(f); return 0; } r = fread(&v[0], 1, v.size(), f); if (r < 0) { ec.assign(errno, boost::system::get_generic_category()); fclose(f); return -1; } fclose(f); if (r != s) { return -3; } return 0; }
void parse_magnet_uri(std::string const& uri, add_torrent_params& p, error_code& ec) { ec.clear(); std::string name; { error_code e; std::string display_name = url_has_argument(uri, "dn"); if (!display_name.empty()) name = unescape_string(display_name.c_str(), e); } // parse trackers out of the magnet link std::string::size_type pos = std::string::npos; std::string url = url_has_argument(uri, "tr", &pos); while (pos != std::string::npos) { error_code e; url = unescape_string(url, e); if (e) continue; p.trackers.push_back(url); pos = uri.find("&tr=", pos); if (pos == std::string::npos) break; pos += 4; url = uri.substr(pos, uri.find('&', pos) - pos); } // parse web seeds out of the magnet link pos = std::string::npos; url = url_has_argument(uri, "ws", &pos); while (pos != std::string::npos) { error_code e; url = unescape_string(url, e); if (e) continue; p.url_seeds.push_back(url); pos = uri.find("&ws=", pos); if (pos == std::string::npos) break; pos += 4; url = uri.substr(pos, uri.find('&', pos) - pos); } std::string btih = url_has_argument(uri, "xt"); if (btih.empty()) { ec = errors::missing_info_hash_in_uri; return; } if (btih.compare(0, 9, "urn:btih:") != 0) { ec = errors::missing_info_hash_in_uri; return; } std::string::size_type peer_pos = std::string::npos; std::string peer = url_has_argument(uri, "x.pe", &peer_pos); while (!peer.empty()) { error_code e; tcp::endpoint endp = parse_endpoint(peer, e); if (!e) p.peers.push_back(endp); peer_pos = uri.find("&x.pe=", peer_pos); if (peer_pos == std::string::npos) break; peer_pos += 6; peer = uri.substr(peer_pos, uri.find('&', peer_pos) - peer_pos); } #ifndef TORRENT_DISABLE_DHT std::string::size_type node_pos = std::string::npos; std::string node = url_has_argument(uri, "dht", &node_pos); while (!node.empty()) { std::string::size_type divider = node.find_last_of(':'); if (divider != std::string::npos) { int port = atoi(node.c_str() + divider + 1); if (port != 0) p.dht_nodes.push_back(std::make_pair(node.substr(0, divider), port)); } node_pos = uri.find("&dht=", node_pos); if (node_pos == std::string::npos) break; node_pos += 5; node = uri.substr(node_pos, uri.find('&', node_pos) - node_pos); } #endif sha1_hash info_hash; if (btih.size() == 40 + 9) aux::from_hex(&btih[9], 40, info_hash.data()); else if (btih.size() == 32 + 9) { std::string ih = base32decode(btih.substr(9)); if (ih.size() != 20) { ec = errors::invalid_info_hash; return; } info_hash.assign(ih); } else { ec = errors::invalid_info_hash; return; } p.info_hash = info_hash; if (!name.empty()) p.name = name; }
// This has to be thread safe, i.e. atomic. // that means, on posix this has to be turned into a series of // pwrite() calls std::int64_t file::writev(std::int64_t file_offset, span<iovec_t const> bufs , error_code& ec, open_mode_t flags) { if (m_file_handle == INVALID_HANDLE_VALUE) { #ifdef TORRENT_WINDOWS ec = error_code(ERROR_INVALID_HANDLE, system_category()); #else ec = error_code(boost::system::errc::bad_file_descriptor, generic_category()); #endif return -1; } TORRENT_ASSERT((m_open_mode & open_mode::rw_mask) == open_mode::write_only || (m_open_mode & open_mode::rw_mask) == open_mode::read_write); TORRENT_ASSERT(!bufs.empty()); TORRENT_ASSERT(is_open()); ec.clear(); #if TORRENT_USE_PREADV TORRENT_UNUSED(flags); std::int64_t ret = iov(&::pwritev, native_handle(), file_offset, bufs, ec); #else // there's no point in coalescing single buffer writes if (bufs.size() == 1) { flags &= ~open_mode::coalesce_buffers; } iovec_t tmp; if (flags & open_mode::coalesce_buffers) { if (!coalesce_write_buffers(bufs, tmp)) // ok, that failed, don't coalesce writes flags &= ~open_mode::coalesce_buffers; } #if TORRENT_USE_PREAD std::int64_t ret = iov(&::pwrite, native_handle(), file_offset, bufs, ec); #else std::int64_t ret = iov(&::write, native_handle(), file_offset, bufs, ec); #endif if (flags & open_mode::coalesce_buffers) delete[] tmp.data(); #endif #if TORRENT_USE_FDATASYNC \ && !defined F_NOCACHE && \ !defined DIRECTIO_ON if (m_open_mode & open_mode::no_cache) { if (::fdatasync(native_handle()) != 0 && errno != EINVAL && errno != ENOSYS) { ec.assign(errno, system_category()); } } #endif return ret; }
void mapped_surface::commit_changes(const rectangle& area, error_code& ec) noexcept { cairo_surface_mark_dirty_rectangle(_Mapped_surface.csfce, static_cast<int>(area.x()), static_cast<int>(area.y()), static_cast<int>(area.width()), static_cast<int>(area.height())); ec.clear(); }