示例#1
0
	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;
	}
示例#2
0
	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();
	}
示例#3
0
	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);
	}
示例#5
0
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;
}
示例#6
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;
	}
示例#7
0
	// 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;
	}
示例#8
0
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();
}