コード例 #1
0
ファイル: worker.hpp プロジェクト: FataliBud/gearmand
 gearman_return_t error_code() const
 {
   return universal.error_code();
 }
コード例 #2
0
ファイル: windows_error.hpp プロジェクト: EricAlex/PDAL
 inline error_code make_error_code( windows_error_code e )
   { return error_code( e, system_category() ); }
コード例 #3
0
ファイル: file_pool.cpp プロジェクト: Meonardo/libtorrent
	file_handle file_pool::open_file(void* st, std::string const& p
		, int file_index, file_storage const& fs, int m, error_code& ec)
	{
		// potentially used to hold a reference to a file object that's
		// about to be destructed. If we have such object we assign it to
		// this member to be destructed after we release the std::mutex. On some
		// operating systems (such as OSX) closing a file may take a long
		// time. We don't want to hold the std::mutex for that.
		file_handle defer_destruction;

		std::unique_lock<std::mutex> l(m_mutex);

#if TORRENT_USE_ASSERTS
		// we're not allowed to open a file
		// from a deleted storage!
		TORRENT_ASSERT(std::find(m_deleted_storages.begin(), m_deleted_storages.end()
			, std::make_pair(fs.name(), static_cast<void const*>(&fs)))
			== m_deleted_storages.end());
#endif

		TORRENT_ASSERT(st != 0);
		TORRENT_ASSERT(is_complete(p));
		TORRENT_ASSERT((m & file::rw_mask) == file::read_only
			|| (m & file::rw_mask) == file::read_write);
		file_set::iterator i = m_files.find(std::make_pair(st, file_index));
		if (i != m_files.end())
		{
			lru_file_entry& e = i->second;
			e.last_use = aux::time_now();

			if (e.key != st && ((e.mode & file::rw_mask) != file::read_only
				|| (m & file::rw_mask) != file::read_only))
			{
				// this means that another instance of the storage
				// is using the exact same file.
				ec = errors::file_collision;
				return file_handle();
			}

			e.key = st;
			// if we asked for a file in write mode,
			// and the cached file is is not opened in
			// write mode, re-open it
			if ((((e.mode & file::rw_mask) != file::read_write)
				&& ((m & file::rw_mask) == file::read_write))
				|| (e.mode & file::random_access) != (m & file::random_access))
			{
				// close the file before we open it with
				// the new read/write privileges, since windows may
				// file opening a file twice. However, since there may
				// be outstanding operations on it, we can't close the
				// file, we can only delete our reference to it.
				// if this is the only reference to the file, it will be closed
				defer_destruction = e.file_ptr;
				e.file_ptr = boost::make_shared<file>();

				std::string full_path = fs.file_path(file_index, p);
				if (!e.file_ptr->open(full_path, m, ec))
				{
					m_files.erase(i);
					return file_handle();
				}
#ifdef TORRENT_WINDOWS
				if (m_low_prio_io)
					set_low_priority(e.file_ptr);
#endif

				TORRENT_ASSERT(e.file_ptr->is_open());
				e.mode = m;
			}
			return e.file_ptr;
		}

		lru_file_entry e;
		e.file_ptr = boost::make_shared<file>();
		if (!e.file_ptr)
		{
			ec = error_code(boost::system::errc::not_enough_memory, generic_category());
			return e.file_ptr;
		}
		std::string full_path = fs.file_path(file_index, p);
		if (!e.file_ptr->open(full_path, m, ec))
			return file_handle();
#ifdef TORRENT_WINDOWS
		if (m_low_prio_io)
			set_low_priority(e.file_ptr);
#endif
		e.mode = m;
		e.key = st;
		m_files.insert(std::make_pair(std::make_pair(st, file_index), e));
		TORRENT_ASSERT(e.file_ptr->is_open());

		file_handle file_ptr = e.file_ptr;

		// the file is not in our cache
		if (int(m_files.size()) >= m_size)
		{
			// the file cache is at its maximum size, close
			// the least recently used (lru) file from it
			remove_oldest(l);
		}
		return file_ptr;
	}
コード例 #4
0
ファイル: storage.hpp プロジェクト: 771805315/avplayer
		virtual void clear_error() { m_error = error_code(); m_error_file.resize(0); }
コード例 #5
0
 //  explicit conversion:
 inline error_code make_error_code( errc_t e )
   { return error_code( e, get_generic_category() ); }
コード例 #6
0
ファイル: memory.c プロジェクト: jimmy-zhao-tainio/project.m
void *memory_grow (void *memory, size_t size)
{
	char *pointer;
	char *pointer_resized;
	size_t size_current;

	if (!memory) {
		error (InvalidArgument);
		return NULL;
	}
	if (size == 0) {
		error (InvalidArgument);
		return NULL;
	}
	size_current = memory_size (memory);
	if (size_current >= size) {
		error (InvalidOperation);
		return NULL;
	}
	if (!size_t_add (sizeof (size_t), size, NULL)) {
		error_code (Overflow, 1);
		return NULL;
	}
        LOCK ();
	if (!unsigned_long_long_add (size - size_current, commit_size, NULL)) {
                UNLOCK ();
		error_code (Overflow, 2);
		return NULL;
	}
	if (!unsigned_long_long_add (size - size_current, total_create_size, NULL)) {
                UNLOCK ();
		error_code (Overflow, 3);
		return NULL;
	}
	if (commit_limit != ULLONG_MAX) {
		if ((size - size_current) + commit_size > commit_limit) {
                        UNLOCK ();
			error (MemoryCommitLimit);
			return NULL;
		}
	}
	if (total_create_limit != ULLONG_MAX) {
		if ((size - size_current) + total_create_size > total_create_limit) {
                        UNLOCK ();
			error (MemoryTotalCreateLimit);
			return NULL;
		}
	}
        total_create_size += size - size_current;
	commit_size += size - size_current;
        UNLOCK ();

	pointer = memory;
	pointer = pointer - sizeof (size_t);
	if (!(pointer_resized = realloc (pointer, sizeof (size_t) + size))) {
                LOCK ();
                total_create_size -= size - size_current;
                commit_size -= size - size_current;
                UNLOCK ();
		error (OutOfMemory);
		return NULL;
	}
	set_size (pointer_resized, size);
	return pointer_resized + sizeof (size_t);
}
コード例 #7
0
ファイル: inet_server_posix.hpp プロジェクト: semenovf/pfs
 error_code listen (int/* backlog */)
 {
     return error_code();
 }
コード例 #8
0
ファイル: linux_error.hpp プロジェクト: RagnarHauge/crava
 inline error_code make_error_code( linux_errno e )
   { return error_code( e, get_system_category() ); }
コード例 #9
0
void TestPeerLogicSyncClient::on_connect ()
{
    {
        // pre-handshake hook is optional
        on_pre_handshake ();
        if (failure (error ()))
            return ;
    }

    if (socket ().needs_handshake ())
    {
        if (failure (socket ().handshake (to_handshake_type (get_role ()), error ())))
            return;
    }

    {
        std::size_t const amount = boost::asio::write (
            socket (), boost::asio::buffer ("hello", 5), error ());

        if (failure (error ()))
            return;

        if (unexpected (amount == 5, error ()))
            return;
    }

    {
        char data [7];

        size_t const amount = boost::asio::read (
            socket (), boost::asio::buffer (data, 7), error ());

        if (failure (error ()))
            return;

        if (unexpected (amount == 7, error ()))
            return;

        if (unexpected (memcmp (&data, "goodbye", 7) == 0, error ()))
            return;
    }

    // Wait for 1 byte which should never come. Instead,
    // the server should close its end and we will get eof
    {
        char data [1];
        boost::asio::read (socket (), boost::asio::buffer (data, 1), error ());

        if (error () == boost::asio::error::eof)
        {
            error () = error_code ();
        }
        else if (unexpected (failure (error ()), error ()))
        {
            return;
        }
    }

    if (socket ().needs_handshake ())
    {
        if (failure (socket ().shutdown (error ()), true))
            return;
    }

    if (failure (socket ().shutdown (Socket::shutdown_both, error ())))
        return;

    if (failure (socket ().close (error ())))
        return;
}
コード例 #10
0
	void http_tracker_connection::parse(int status_code, lazy_entry const& e)
	{
		boost::shared_ptr<request_callback> cb = requester();
		if (!cb) return;

		int interval = int(e.dict_find_int_value("interval", 0));
		int min_interval = int(e.dict_find_int_value("min interval", 30));

		// if no interval is specified, default to 30 minutes
		if (interval == 0) interval = 1800;
		
		std::string trackerid;
		lazy_entry const* tracker_id = e.dict_find_string("tracker id");
		if (tracker_id)
			trackerid = tracker_id->string_value();
		// parse the response
		lazy_entry const* failure = e.dict_find_string("failure reason");
		if (failure)
		{
			fail(error_code(errors::tracker_failure), status_code
				, failure->string_value().c_str(), interval, min_interval);
			return;
		}

		lazy_entry const* warning = e.dict_find_string("warning message");
		if (warning)
			cb->tracker_warning(tracker_req(), warning->string_value());

		std::vector<peer_entry> peer_list;

		if (tracker_req().kind == tracker_request::scrape_request)
		{
			std::string ih = tracker_req().info_hash.to_string();

			lazy_entry const* files = e.dict_find_dict("files");
			if (files == 0)
			{
				fail(error_code(errors::invalid_files_entry), -1, ""
					, interval, min_interval);
				return;
			}

			lazy_entry const* scrape_data = files->dict_find_dict(ih.c_str());
			if (scrape_data == 0)
			{
				fail(error_code(errors::invalid_hash_entry), -1, ""
					, interval, min_interval);
				return;
			}

			int complete = int(scrape_data->dict_find_int_value("complete", -1));
			int incomplete = int(scrape_data->dict_find_int_value("incomplete", -1));
			int downloaded = int(scrape_data->dict_find_int_value("downloaded", -1));
			int downloaders = int(scrape_data->dict_find_int_value("downloaders", -1));
			cb->tracker_scrape_response(tracker_req(), complete
				, incomplete, downloaded, downloaders);
			return;
		}

		lazy_entry const* peers_ent = e.dict_find("peers");
		if (peers_ent && peers_ent->type() == lazy_entry::string_t)
		{
			char const* peers = peers_ent->string_ptr();
			int len = peers_ent->string_length();
			for (int i = 0; i < len; i += 6)
			{
				if (len - i < 6) break;

				peer_entry p;
				p.pid.clear();
				error_code ec;
				p.ip = detail::read_v4_address(peers).to_string(ec);
				p.port = detail::read_uint16(peers);
				if (ec) continue;
				peer_list.push_back(p);
			}
		}
		else if (peers_ent && peers_ent->type() == lazy_entry::list_t)
		{
			int len = peers_ent->list_size();
			for (int i = 0; i < len; ++i)
			{
				peer_entry p;
				if (!extract_peer_info(*peers_ent->list_at(i), p)) return;
				peer_list.push_back(p);
			}
		}
		else
		{
			peers_ent = 0;
		}

#if TORRENT_USE_IPV6
		lazy_entry const* ipv6_peers = e.dict_find_string("peers6");
		if (ipv6_peers)
		{
			char const* peers = ipv6_peers->string_ptr();
			int len = ipv6_peers->string_length();
			for (int i = 0; i < len; i += 18)
			{
				if (len - i < 18) break;

				peer_entry p;
				p.pid.clear();
				error_code ec;
				p.ip = detail::read_v6_address(peers).to_string(ec);
				p.port = detail::read_uint16(peers);
				if (ec) continue;
				peer_list.push_back(p);
			}
		}
		else
		{
			ipv6_peers = 0;
		}
#else
		lazy_entry const* ipv6_peers = 0;
#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)
		{
			fail(error_code(errors::invalid_peers_entry), -1, ""
				, interval, min_interval);
			return;
		}


		// look for optional scrape info
		address external_ip;

		lazy_entry const* ip_ent = e.dict_find_string("external ip");
		if (ip_ent)
		{
			char const* p = ip_ent->string_ptr();
			if (ip_ent->string_length() == address_v4::bytes_type().size())
				external_ip = detail::read_v4_address(p);
#if TORRENT_USE_IPV6
			else if (ip_ent->string_length() == address_v6::bytes_type().size())
				external_ip = detail::read_v6_address(p);
#endif
		}
		
		int complete = int(e.dict_find_int_value("complete", -1));
		int incomplete = int(e.dict_find_int_value("incomplete", -1));

		std::list<address> ip_list;
		if (m_tracker_connection)
		{
			error_code ec;
			ip_list.push_back(m_tracker_connection->socket().remote_endpoint(ec).address());
			std::list<tcp::endpoint> const& epts = m_tracker_connection->endpoints();
			for (std::list<tcp::endpoint>::const_iterator i = epts.begin()
				, end(epts.end()); i != end; ++i)
			{
				ip_list.push_back(i->address());
			}
		}

		cb->tracker_response(tracker_req(), m_tracker_ip, ip_list, peer_list
			, interval, min_interval, complete, incomplete, external_ip, trackerid);
	}
コード例 #11
0
	void http_tracker_connection::start()
	{
		// TODO: authentication
		std::string url = tracker_req().url;

		if (tracker_req().kind == tracker_request::scrape_request)
		{
			// find and replace "announce" with "scrape"
			// in request

			std::size_t pos = url.find("announce");
			if (pos == std::string::npos)
			{
				m_ios.post(boost::bind(&http_tracker_connection::fail_disp, self()
					, error_code(errors::scrape_not_available)));
				return;
			}
			url.replace(pos, 8, "scrape");
		}
		
#if TORRENT_USE_I2P
		bool i2p = is_i2p_url(url);
#else
		static const bool i2p = false;
#endif

		session_settings const& settings = m_ses.settings();

		// if request-string already contains
		// some parameters, append an ampersand instead
		// of a question mark
		size_t arguments_start = url.find('?');
		if (arguments_start != std::string::npos)
			url += "&";
		else
			url += "?";

		url += "info_hash=";
		url += escape_string((const char*)&tracker_req().info_hash[0], 20);
		
		if (tracker_req().kind == tracker_request::announce_request)
		{
			char str[1024];
			const bool stats = tracker_req().send_stats;
			snprintf(str, sizeof(str), "&peer_id=%s&port=%d&uploaded=%" PRId64
				"&downloaded=%" PRId64 "&left=%" PRId64 "&corrupt=%" PRId64 "&redundant=%" PRId64
				"&compact=1&numwant=%d&key=%x&no_peer_id=1"
				, escape_string((const char*)&tracker_req().pid[0], 20).c_str()
				// the i2p tracker seems to verify that the port is not 0,
				// even though it ignores it otherwise
				, i2p ? 1 : tracker_req().listen_port
				, stats ? tracker_req().uploaded : 0
				, stats ? tracker_req().downloaded : 0
				, stats ? tracker_req().left : 0
				, stats ? tracker_req().corrupt : 0
				, stats ? tracker_req().redundant: 0
				, tracker_req().num_want
				, tracker_req().key);
			url += str;
#ifndef TORRENT_DISABLE_ENCRYPTION
			if (m_ses.get_pe_settings().in_enc_policy != pe_settings::disabled)
				url += "&supportcrypto=1";
#endif
			if (!tracker_req().trackerid.empty())
			{
				std::string id = tracker_req().trackerid;
				url += "&trackerid=";
				url += escape_string(id.c_str(), id.length());
			}

			if (tracker_req().event != tracker_request::none)
			{
				const char* event_string[] = {"completed", "started", "stopped", "paused"};
				url += "&event=";
				url += event_string[tracker_req().event - 1];
			}

#if TORRENT_USE_I2P
			if (i2p)
			{
				url += "&ip=";
				url += escape_string(m_i2p_conn->local_endpoint().c_str()
					, m_i2p_conn->local_endpoint().size());
				url += ".i2p";
			}
			else
#endif
			if (!m_ses.settings().anonymous_mode)
			{
				if (!settings.announce_ip.empty())
				{
					url += "&ip=" + escape_string(
						settings.announce_ip.c_str(), settings.announce_ip.size());
				}
				else if (m_ses.settings().announce_double_nat
					&& is_local(m_ses.listen_address()))
				{
					// only use the global external listen address here
					// if it turned out to be on a local network
					// since otherwise the tracker should use our
					// source IP to determine our origin
					url += "&ip=" + print_address(m_ses.listen_address());
				}
   
				if (!tracker_req().ipv6.empty() && !i2p)
				{
					url += "&ipv6=";
					url += tracker_req().ipv6;
				}
   
				if (!tracker_req().ipv4.empty() && !i2p)
				{
					url += "&ipv4=";
					url += tracker_req().ipv4;
				}
			}
		}

		m_tracker_connection.reset(new http_connection(m_ios, m_cc
			, boost::bind(&http_tracker_connection::on_response, self(), _1, _2, _3, _4)
			, true
			, boost::bind(&http_tracker_connection::on_connect, self(), _1)
			, boost::bind(&http_tracker_connection::on_filter, self(), _1, _2)
#ifdef TORRENT_USE_OPENSSL
			, tracker_req().ssl_ctx
#endif
			));

		int timeout = tracker_req().event==tracker_request::stopped
			?settings.stop_tracker_timeout
			:settings.tracker_completion_timeout;

		m_tracker_connection->get(url, seconds(timeout)
			, tracker_req().event == tracker_request::stopped ? 2 : 1
			, &m_ps, 5, settings.anonymous_mode ? "" : settings.user_agent
			, bind_interface()
#if TORRENT_USE_I2P
			, m_i2p_conn
#endif
			);

		// the url + 100 estimated header size
		sent_bytes(url.size() + 100);

#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)

		boost::shared_ptr<request_callback> cb = requester();
		if (cb)
		{
			cb->debug_log("==> TRACKER_REQUEST [ url: %s ]", url.c_str());
		}
#endif
	}
コード例 #12
0
	void http_seed_connection::on_receive(error_code const& error
		, std::size_t bytes_transferred)
	{
		INVARIANT_CHECK;

		if (error)
		{
			m_statistics.received_bytes(0, bytes_transferred);
#ifdef TORRENT_VERBOSE_LOGGING
			peer_log("*** http_seed_connection error: %s", error.message().c_str());
#endif
			return;
		}

		boost::shared_ptr<torrent> t = associated_torrent().lock();
		TORRENT_ASSERT(t);

		for (;;)
		{
			buffer::const_interval recv_buffer = receive_buffer();

			if (bytes_transferred == 0) break;
			TORRENT_ASSERT(recv_buffer.left() > 0);

			TORRENT_ASSERT(!m_requests.empty());
			if (m_requests.empty())
			{
				m_statistics.received_bytes(0, bytes_transferred);
				disconnect(errors::http_error, 2);
				return;
			}

			peer_request front_request = m_requests.front();

			bool header_finished = m_parser.header_finished();
			if (!header_finished)
			{
				bool parse_error = false;
				int protocol = 0;
				int payload = 0;
				boost::tie(payload, protocol) = m_parser.incoming(recv_buffer, parse_error);
				m_statistics.received_bytes(0, protocol);
				bytes_transferred -= protocol;
#if defined TORRENT_DEBUG || TORRENT_RELEASE_ASSERTS
				if (payload > front_request.length) payload = front_request.length;
#endif

				if (parse_error)
				{
					m_statistics.received_bytes(0, bytes_transferred);
					disconnect(errors::http_parse_error, 2);
					return;
				}

				TORRENT_ASSERT(recv_buffer.left() == 0 || *recv_buffer.begin == 'H');
			
				TORRENT_ASSERT(recv_buffer.left() <= packet_size());
				
				// this means the entire status line hasn't been received yet
				if (m_parser.status_code() == -1)
				{
					TORRENT_ASSERT(payload == 0);
					TORRENT_ASSERT(bytes_transferred == 0);
					break;
				}

				// if the status code is not one of the accepted ones, abort
				if (!is_ok_status(m_parser.status_code()))
				{
					int retry_time = atoi(m_parser.header("retry-after").c_str());
					if (retry_time <= 0) retry_time = 5 * 60;
					// temporarily unavailable, retry later
					t->retry_web_seed(this, retry_time);

					std::string error_msg = to_string(m_parser.status_code()).elems
						+ (" " + m_parser.message());
					if (m_ses.m_alerts.should_post<url_seed_alert>())
					{
						m_ses.m_alerts.post_alert(url_seed_alert(t->get_handle(), url()
							, error_msg));
					}
					m_statistics.received_bytes(0, bytes_transferred);
					disconnect(error_code(m_parser.status_code(), get_http_category()), 1);
					return;
				}
				if (!m_parser.header_finished())
				{
					TORRENT_ASSERT(payload == 0);
					TORRENT_ASSERT(bytes_transferred == 0);
					break;
				}
			}

			// we just completed reading the header
			if (!header_finished)
			{
				if (is_redirect(m_parser.status_code()))
				{
					// this means we got a redirection request
					// look for the location header
					std::string location = m_parser.header("location");
					m_statistics.received_bytes(0, bytes_transferred);

					if (location.empty())
					{
						// we should not try this server again.
						t->remove_web_seed(this);
						disconnect(errors::missing_location, 2);
						return;
					}
					
					// add the redirected url and remove the current one
					t->add_web_seed(location, web_seed_entry::http_seed);
					t->remove_web_seed(this);
					disconnect(errors::redirecting, 2);
					return;
				}

				std::string const& server_version = m_parser.header("server");
				if (!server_version.empty())
				{
					m_server_string = "URL seed @ ";
					m_server_string += m_host;
					m_server_string += " (";
					m_server_string += server_version;
					m_server_string += ")";
				}

				m_response_left = atol(m_parser.header("content-length").c_str());
				if (m_response_left == -1)
				{
					m_statistics.received_bytes(0, bytes_transferred);
					// we should not try this server again.
					t->remove_web_seed(this);
					disconnect(errors::no_content_length, 2);
					return;
				}
				if (m_response_left != front_request.length)
				{
					m_statistics.received_bytes(0, bytes_transferred);
					// we should not try this server again.
					t->remove_web_seed(this);
					disconnect(errors::invalid_range, 2);
					return;
				}
				m_body_start = m_parser.body_start();
			}

			recv_buffer.begin += m_body_start;

			// =========================
			// === CHUNKED ENCODING  ===
			// =========================
			while (m_parser.chunked_encoding()
				&& m_chunk_pos >= 0
				&& m_chunk_pos < recv_buffer.left())
			{
				int header_size = 0;
				size_type chunk_size = 0;
				buffer::const_interval chunk_start = recv_buffer;
				chunk_start.begin += m_chunk_pos;
				TORRENT_ASSERT(chunk_start.begin[0] == '\r' || is_hex(chunk_start.begin, 1));
				bool ret = m_parser.parse_chunk_header(chunk_start, &chunk_size, &header_size);
				if (!ret)
				{
					TORRENT_ASSERT(bytes_transferred >= size_t(chunk_start.left() - m_partial_chunk_header));
					bytes_transferred -= chunk_start.left() - m_partial_chunk_header;
					m_statistics.received_bytes(0, chunk_start.left() - m_partial_chunk_header);
					m_partial_chunk_header = chunk_start.left();
					if (bytes_transferred == 0) return;
					break;
				}
				else
				{
#ifdef TORRENT_VERBOSE_LOGGING
					peer_log("*** parsed chunk: %d header_size: %d", chunk_size, header_size);
#endif
					TORRENT_ASSERT(bytes_transferred >= size_t(header_size - m_partial_chunk_header));
					bytes_transferred -= header_size - m_partial_chunk_header;

					m_statistics.received_bytes(0, header_size - m_partial_chunk_header);
					m_partial_chunk_header = 0;
					TORRENT_ASSERT(chunk_size != 0 || chunk_start.left() <= header_size || chunk_start.begin[header_size] == 'H');
					// cut out the chunk header from the receive buffer
					TORRENT_ASSERT(m_chunk_pos + m_body_start < INT_MAX);
					cut_receive_buffer(header_size, t->block_size() + 1024, int(m_chunk_pos + m_body_start));
					recv_buffer = receive_buffer();
					recv_buffer.begin += m_body_start;
					m_chunk_pos += chunk_size;
					if (chunk_size == 0)
					{
						TORRENT_ASSERT(receive_buffer().left() < m_chunk_pos + m_body_start + 1
							|| receive_buffer()[int(m_chunk_pos + m_body_start)] == 'H'
							|| (m_parser.chunked_encoding() && receive_buffer()[int(m_chunk_pos + m_body_start)] == '\r'));
						m_chunk_pos = -1;
					}
				}
			}

			int payload = bytes_transferred;
			if (payload > m_response_left) payload = int(m_response_left);
			if (payload > front_request.length) payload = front_request.length;
			m_statistics.received_bytes(payload, 0);
			incoming_piece_fragment(payload);
			m_response_left -= payload;

			if (m_parser.status_code() == 503)
			{
				if (!m_parser.finished()) return;

				int retry_time = atol(std::string(recv_buffer.begin, recv_buffer.end).c_str());
				if (retry_time <= 0) retry_time = 60;
#ifdef TORRENT_VERBOSE_LOGGING
				peer_log("*** retrying in %d seconds", retry_time);
#endif

				m_statistics.received_bytes(0, bytes_transferred);
				// temporarily unavailable, retry later
				t->retry_web_seed(this, retry_time);
				disconnect(error_code(m_parser.status_code(), get_http_category()), 1);
				return;
			}


			// we only received the header, no data
			if (recv_buffer.left() == 0) break;

			if (recv_buffer.left() < front_request.length) break;

			// if the response is chunked, we need to receive the last
			// terminating chunk and the tail headers before we can proceed
			if (m_parser.chunked_encoding() && m_chunk_pos >= 0) break;

			m_requests.pop_front();
			incoming_piece(front_request, recv_buffer.begin);
			if (associated_torrent().expired()) return;

			int size_to_cut = m_body_start + front_request.length;
			TORRENT_ASSERT(receive_buffer().left() < size_to_cut + 1
				|| receive_buffer()[size_to_cut] == 'H'
				|| (m_parser.chunked_encoding() && receive_buffer()[size_to_cut] == '\r'));

			cut_receive_buffer(size_to_cut, t->block_size() + 1024);
			if (m_response_left == 0) m_chunk_pos = 0;
			else m_chunk_pos -= front_request.length;
			bytes_transferred -= payload;
			m_body_start = 0;
			if (m_response_left > 0) continue;
			TORRENT_ASSERT(m_response_left == 0);
			m_parser.reset();
		}
	}
コード例 #13
0
		void clear_error() { m_error = error_code(); m_error_file.clear(); }
コード例 #14
0
ファイル: enum_net.hpp プロジェクト: tchen0123/libtorrent
	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();
	}
コード例 #15
0
 bool has_error() const {
   return error_code() != CASS_OK;
 }
コード例 #16
0
	file_handle file_pool::open_file(storage_index_t st, std::string const& p
		, file_index_t const file_index, file_storage const& fs, int m, error_code& ec)
	{
		// potentially used to hold a reference to a file object that's
		// about to be destructed. If we have such object we assign it to
		// this member to be destructed after we release the std::mutex. On some
		// operating systems (such as OSX) closing a file may take a long
		// time. We don't want to hold the std::mutex for that.
		file_handle defer_destruction;

		std::unique_lock<std::mutex> l(m_mutex);

#if TORRENT_USE_ASSERTS
		// we're not allowed to open a file
		// from a deleted storage!
		TORRENT_ASSERT(std::find(m_deleted_storages.begin(), m_deleted_storages.end()
			, std::make_pair(fs.name(), static_cast<void const*>(&fs)))
			== m_deleted_storages.end());
#endif

		TORRENT_ASSERT(is_complete(p));
		TORRENT_ASSERT((m & file::rw_mask) == file::read_only
			|| (m & file::rw_mask) == file::read_write);
		auto const i = m_files.find(std::make_pair(st, file_index));
		if (i != m_files.end())
		{
			lru_file_entry& e = i->second;
			e.last_use = aux::time_now();

			// if we asked for a file in write mode,
			// and the cached file is is not opened in
			// write mode, re-open it
			if ((((e.mode & file::rw_mask) != file::read_write)
				&& ((m & file::rw_mask) == file::read_write))
				|| (e.mode & file::random_access) != (m & file::random_access))
			{
				file_handle new_file = std::make_shared<file>();

				std::string full_path = fs.file_path(file_index, p);
				if (!new_file->open(full_path, m, ec))
					return file_handle();
#ifdef TORRENT_WINDOWS
				if (m_low_prio_io)
					set_low_priority(new_file);
#endif

				TORRENT_ASSERT(new_file->is_open());
				defer_destruction = std::move(e.file_ptr);
				e.file_ptr = std::move(new_file);
				e.mode = m;
			}
			return e.file_ptr;
		}

		lru_file_entry e;
		e.file_ptr = std::make_shared<file>();
		if (!e.file_ptr)
		{
			ec = error_code(boost::system::errc::not_enough_memory, generic_category());
			return file_handle();
		}
		std::string full_path = fs.file_path(file_index, p);
		if (!e.file_ptr->open(full_path, m, ec))
			return file_handle();
#ifdef TORRENT_WINDOWS
		if (m_low_prio_io)
			set_low_priority(e.file_ptr);
#endif
		e.mode = m;
		file_handle file_ptr = e.file_ptr;
		m_files.insert(std::make_pair(std::make_pair(st, file_index), e));
		TORRENT_ASSERT(file_ptr->is_open());

		if (int(m_files.size()) >= m_size)
		{
			// the file cache is at its maximum size, close
			// the least recently used (lru) file from it
			remove_oldest(l);
		}
		return file_ptr;
	}
コード例 #17
0
void HTTPCallbackTcpConnection::start() {
	httpMessage.clear();

	handleHttpRequest(error_code(), 0);
}
コード例 #18
0
		void do_async_handshake(handshake_type, HandshakeHandler handler) { get_io_service().post(bind(handler, error_code())); }
コード例 #19
0
ファイル: cygwin_error.hpp プロジェクト: TheRyaz/c_reading
inline error_code make_error_code( cygwin_errno e )
{
    return error_code( e, system_category() );
}
コード例 #20
0
		error_code do_handshake(handshake_type, error_code &ec) { return ec = error_code(); }
コード例 #21
0
ファイル: inet_server_posix.hpp プロジェクト: semenovf/pfs
 error_code listen (int backlog)
 {
     return (::listen(_fd, backlog) != 0)
             ? get_last_system_error()
             : error_code();
 }
コード例 #22
0
/// This is where the link is actually performed.
bool Driver::link(const LinkingContext &context, raw_ostream &diagnostics) {
  // Honor -mllvm
  if (!context.llvmOptions().empty()) {
    unsigned numArgs = context.llvmOptions().size();
    const char **args = new const char *[numArgs + 2];
    args[0] = "lld (LLVM option parsing)";
    for (unsigned i = 0; i != numArgs; ++i)
      args[i + 1] = context.llvmOptions()[i];
    args[numArgs + 1] = 0;
    llvm::cl::ParseCommandLineOptions(numArgs + 1, args);
  }
  InputGraph &inputGraph = context.inputGraph();
  if (!inputGraph.numFiles())
    return false;

  // Read inputs
  ScopedTask readTask(getDefaultDomain(), "Read Args");
  std::vector<std::vector<std::unique_ptr<File> > > files(
      inputGraph.numFiles());
  size_t index = 0;
  std::atomic<bool> fail(false);
  TaskGroup tg;
  std::vector<std::unique_ptr<LinkerInput> > linkerInputs;
  for (auto &ie : inputGraph.inputElements()) {
    if (ie->kind() == InputElement::Kind::File) {
      FileNode *fileNode = (llvm::dyn_cast<FileNode>)(ie.get());
      auto linkerInput = fileNode->createLinkerInput(context);
      if (!linkerInput) {
        llvm::outs() << fileNode->errStr(error_code(linkerInput)) << "\n";
        return false;
      }
      linkerInputs.push_back(std::move(*linkerInput));
    }
    else {
      llvm_unreachable("Not handling other types of InputElements");
    }
  }
  for (const auto &input : linkerInputs) {
    if (context.logInputFiles())
      llvm::outs() << input->getUserPath() << "\n";

    tg.spawn([ &, index]{
      if (error_code ec = context.parseFile(*input, files[index])) {
        diagnostics << "Failed to read file: " << input->getUserPath() << ": "
                    << ec.message() << "\n";
        fail = true;
        return;
      }
    });
    ++index;
  }
  tg.sync();
  readTask.end();

  if (fail)
    return false;

  InputFiles inputs;

  for (auto &f : inputGraph.internalFiles())
    inputs.appendFile(*f.get());

  for (auto &f : files)
    inputs.appendFiles(f);

  // Give target a chance to add files.
  context.addImplicitFiles(inputs);

  // assign an ordinal to each file so sort() can preserve command line order
  inputs.assignFileOrdinals();

  // Do core linking.
  ScopedTask resolveTask(getDefaultDomain(), "Resolve");
  Resolver resolver(context, inputs);
  if (resolver.resolve()) {
    if (!context.allowRemainingUndefines())
      return false;
  }
  MutableFile &merged = resolver.resultFile();
  resolveTask.end();

  // Run passes on linked atoms.
  ScopedTask passTask(getDefaultDomain(), "Passes");
  PassManager pm;
  context.addPasses(pm);
  pm.runOnFile(merged);
  passTask.end();

  // Give linked atoms to Writer to generate output file.
  ScopedTask writeTask(getDefaultDomain(), "Write");
  if (error_code ec = context.writeFile(merged)) {
    diagnostics << "Failed to write file '" << context.outputPath()
                << "': " << ec.message() << "\n";
    return false;
  }

  return true;
}
コード例 #23
0
ファイル: file_pool.cpp プロジェクト: bitemyapp/ecksy
	boost::intrusive_ptr<file> file_pool::open_file(void* st, std::string const& p
		, file_storage::iterator fe, file_storage const& fs, int m, error_code& ec)
	{
		TORRENT_ASSERT(st != 0);
		TORRENT_ASSERT(is_complete(p));
		TORRENT_ASSERT((m & file::rw_mask) == file::read_only
			|| (m & file::rw_mask) == file::read_write);
		mutex::scoped_lock l(m_mutex);
		file_set::iterator i = m_files.find(std::make_pair(st, fs.file_index(*fe)));
		if (i != m_files.end())
		{
			lru_file_entry& e = i->second;
			e.last_use = time_now();

			if (e.key != st && ((e.mode & file::rw_mask) != file::read_only
				|| (m & file::rw_mask) != file::read_only))
			{
				// this means that another instance of the storage
				// is using the exact same file.
#if BOOST_VERSION >= 103500
				ec = errors::file_collision;
#endif
				return boost::intrusive_ptr<file>();
			}

			e.key = st;
			// if we asked for a file in write mode,
			// and the cached file is is not opened in
			// write mode, re-open it
			if ((((e.mode & file::rw_mask) != file::read_write)
				&& ((m & file::rw_mask) == file::read_write))
				|| (e.mode & file::no_buffer) != (m & file::no_buffer)
				|| (e.mode & file::random_access) != (m & file::random_access))
			{
				// close the file before we open it with
				// the new read/write privilages
				TORRENT_ASSERT(e.file_ptr->refcount() == 1);

#if TORRENT_CLOSE_MAY_BLOCK
				mutex::scoped_lock l(m_closer_mutex);
				m_queued_for_close.push_back(e.file_ptr);
				l.unlock();
				e.file_ptr = new file;
#else
				e.file_ptr->close();
#endif
				std::string full_path = combine_path(p, fs.file_path(*fe));
				if (!e.file_ptr->open(full_path, m, ec))
				{
					m_files.erase(i);
					return boost::intrusive_ptr<file>();
				}
#ifdef TORRENT_WINDOWS
// file prio is supported on vista and up
#if _WIN32_WINNT >= 0x0600
				if (m_low_prio_io)
				{
					// TODO: load this function dynamically from Kernel32.dll
					FILE_IO_PRIORITY_HINT_INFO priorityHint;
					priorityHint.PriorityHint = IoPriorityHintLow;
					SetFileInformationByHandle(e.file_ptr->native_handle(),
						FileIoPriorityHintInfo, &priorityHint, sizeof(PriorityHint));
				}
#endif
#endif
				TORRENT_ASSERT(e.file_ptr->is_open());
				e.mode = m;
			}
			TORRENT_ASSERT((e.mode & file::no_buffer) == (m & file::no_buffer));
			return e.file_ptr;
		}
		// the file is not in our cache
		if ((int)m_files.size() >= m_size)
		{
			// the file cache is at its maximum size, close
			// the least recently used (lru) file from it
			remove_oldest();
		}
		lru_file_entry e;
		e.file_ptr.reset(new (std::nothrow)file);
		if (!e.file_ptr)
		{
			ec = error_code(ENOMEM, get_posix_category());
			return e.file_ptr;
		}
		std::string full_path = combine_path(p, fs.file_path(*fe));
		if (!e.file_ptr->open(full_path, m, ec))
			return boost::intrusive_ptr<file>();
		e.mode = m;
		e.key = st;
		m_files.insert(std::make_pair(std::make_pair(st, fs.file_index(*fe)), e));
		TORRENT_ASSERT(e.file_ptr->is_open());
		return e.file_ptr;
	}
コード例 #24
0
void http_tracker_connection::on_response(error_code const& ec
        , http_parser const& parser, char const* data, int size)
{
    // keep this alive
    boost::shared_ptr<http_tracker_connection> me(shared_from_this());

    if (ec && ec != boost::asio::error::eof)
    {
        fail(ec);
        return;
    }

    if (!parser.header_finished())
    {
        fail(boost::asio::error::eof);
        return;
    }

    if (parser.status_code() != 200)
    {
        fail(error_code(parser.status_code(), get_http_category())
             , parser.status_code(), parser.message().c_str());
        return;
    }

    if (ec && ec != boost::asio::error::eof)
    {
        fail(ec, parser.status_code());
        return;
    }

    received_bytes(size + parser.body_start());

    // handle tracker response
    error_code ecode;

    boost::shared_ptr<request_callback> cb = requester();
    if (!cb)
    {
        close();
        return;
    }

    tracker_response resp = parse_tracker_response(data, size, ecode
                            , tracker_req().kind, tracker_req().info_hash);

    if (!resp.warning_message.empty())
        cb->tracker_warning(tracker_req(), resp.warning_message);

    if (ecode)
    {
        fail(ecode, parser.status_code(), resp.failure_reason.c_str()
             , resp.interval, resp.min_interval);
        close();
        return;
    }

    // do slightly different things for scrape requests
    if (0 != (tracker_req().kind & tracker_request::scrape_request))
    {
        cb->tracker_scrape_response(tracker_req(), resp.complete
                                    , resp.incomplete, resp.downloaded, resp.downloaders);
    }
    else
    {
        std::list<address> ip_list;
        if (m_tracker_connection)
        {
            error_code ignore;
            std::vector<tcp::endpoint> const& epts = m_tracker_connection->endpoints();
            for (std::vector<tcp::endpoint>::const_iterator i = epts.begin()
                    , end(epts.end()); i != end; ++i)
            {
                ip_list.push_back(i->address());
            }
        }

        cb->tracker_response(tracker_req(), m_tracker_ip, ip_list, resp);
    }
    close();
}
コード例 #25
0
ファイル: packet_parser.hpp プロジェクト: hyg19831230/Bex
        // 压入待解析数据
        void parse(char const* data, std::size_t size)
        {
            char const* buf = data;
            std::size_t len = size;

            while (len)
            {
                if (0 == pos_)
                {
                    // 缓冲区中无数据, 直接在上层缓冲区中尝试组包.
                    if (len < head_size)
                    {
                        // 不足一个封包头, 写入缓冲区即可
                        write_buffer(buf, len);
                        return ;
                    }
                    else
                    {
                        // 有完整的封包头, 进一步检测是否有完整的封包.
                        std::size_t packet_len = Sizer()(packethead(buf)) + head_size;
                        if (packet_len > size_)
                        {
                            // 封包长错误
                            invoke_callback(generate_error(bee::parse_error), 0, 0, 0);
                            return ;
                        }

                        if (len < packet_len)
                        {
                            // 不足一个封包, 放入缓冲区中, 等待后续数据.
                            write_buffer(buf, len);
                            return ;
                        }
                        else
                        {
                            // 有完整的封包, 直接处理.
                            invoke_callback(error_code(), &packethead(buf), buf + head_size, packet_len - head_size);
                            buf += packet_len;
                            len -= packet_len;
                            continue;
                        }
                    }
                }
                else if (pos_ < head_size)
                {
                    // 缓冲区中有数据, 但不足一个封包头, 尝试拼足一个封包头
                    std::size_t delta = head_size - pos_;
                    std::size_t cpy_size = (std::min)(delta, len);
                    write_buffer(buf, cpy_size);
                    buf += cpy_size;
                    len -= cpy_size;
                    continue;
                }
                else
                {
                    // 缓冲区中有完整的封包头
                    std::size_t packet_len = Sizer()(packethead(buf_)) + head_size;
                    if (packet_len > size_)
                    {
                        // 封包长错误
                        invoke_callback(generate_error(bee::parse_error), 0, 0, 0);
                        return ;
                    }

                    std::size_t delta = packet_len - pos_;
                    if (delta > len)
                    {
                        // 无法拼出一个完整的封包
                        write_buffer(buf, len);
                        return ;
                    }
                    else
                    {
                        // 可以拼出一个完整的封包
                        write_buffer(buf, delta);
                        invoke_callback(error_code(), &packethead(buf_), buf_ + head_size, pos_ - head_size);
                        pos_ = 0;
                        buf += delta;
                        len -= delta;
                        continue;
                    }
                }
            }
        }
コード例 #26
0
void http_tracker_connection::start()
{
    std::string url = tracker_req().url;

    if (0 != (tracker_req().kind & tracker_request::scrape_request))
    {
        // find and replace "announce" with "scrape"
        // in request

        std::size_t pos = url.find("announce");
        if (pos == std::string::npos)
        {
            tracker_connection::fail(error_code(errors::scrape_not_available));
            return;
        }
        url.replace(pos, 8, "scrape");
    }

#if TORRENT_USE_I2P
    bool i2p = is_i2p_url(url);
#else
    static const bool i2p = false;
#endif

    aux::session_settings const& settings = m_man.settings();

    // if request-string already contains
    // some parameters, append an ampersand instead
    // of a question mark
    size_t arguments_start = url.find('?');
    if (arguments_start != std::string::npos)
        url += "&";
    else
        url += "?";

    url += "info_hash=";
    url += escape_string(tracker_req().info_hash.data(), 20);

    if (0 == (tracker_req().kind & tracker_request::scrape_request))
    {
        const char* event_string[] = {"completed", "started", "stopped", "paused"};

        char str[1024];
        const bool stats = tracker_req().send_stats;
        snprintf(str, sizeof(str)
                 , "&peer_id=%s"
                 "&port=%d"
                 "&uploaded=%" PRId64
                 "&downloaded=%" PRId64
                 "&left=%" PRId64
                 "&corrupt=%" PRId64
                 "&key=%08X"
                 "%s%s" // event
                 "&numwant=%d"
                 "&compact=1"
                 "&no_peer_id=1"
                 , escape_string(tracker_req().pid.data(), 20).c_str()
                 // the i2p tracker seems to verify that the port is not 0,
                 // even though it ignores it otherwise
                 , i2p ? 1 : tracker_req().listen_port
                 , stats ? tracker_req().uploaded : 0
                 , stats ? tracker_req().downloaded : 0
                 , stats ? tracker_req().left : 0
                 , stats ? tracker_req().corrupt : 0
                 , tracker_req().key
                 , (tracker_req().event != tracker_request::none) ? "&event=" : ""
                 , (tracker_req().event != tracker_request::none) ? event_string[tracker_req().event - 1] : ""
                 , tracker_req().num_want);
        url += str;
#if !defined(TORRENT_DISABLE_ENCRYPTION) && !defined(TORRENT_DISABLE_EXTENSIONS)
        if (settings.get_int(settings_pack::in_enc_policy) != settings_pack::pe_disabled
                && settings.get_bool(settings_pack::announce_crypto_support))
            url += "&supportcrypto=1";
#endif
        if (stats && settings.get_bool(settings_pack::report_redundant_bytes))
        {
            url += "&redundant=";
            url += to_string(tracker_req().redundant).elems;
        }
        if (!tracker_req().trackerid.empty())
        {
            std::string id = tracker_req().trackerid;
            url += "&trackerid=";
            url += escape_string(id.c_str(), id.length());
        }

#if TORRENT_USE_I2P
        if (i2p && tracker_req().i2pconn)
        {
            if (tracker_req().i2pconn->local_endpoint().empty())
            {
                fail(error_code(errors::no_i2p_endpoint), -1, "Waiting for i2p acceptor from SAM bridge", 5);
                return;
            }
            else
            {
                url += "&ip=" + tracker_req ().i2pconn->local_endpoint () + ".i2p";
            }
        }
        else
#endif
            if (!settings.get_bool(settings_pack::anonymous_mode))
            {
                std::string announce_ip = settings.get_str(settings_pack::announce_ip);
                if (!announce_ip.empty())
                {
                    url += "&ip=" + escape_string(announce_ip.c_str(), announce_ip.size());
                }
// TODO: support this somehow
                /*				else if (settings.get_bool(settings_pack::announce_double_nat)
                					&& is_local(m_ses.listen_address()))
                				{
                					// only use the global external listen address here
                					// if it turned out to be on a local network
                					// since otherwise the tracker should use our
                					// source IP to determine our origin
                					url += "&ip=" + print_address(m_ses.listen_address());
                				}
                */
            }
    }

    m_tracker_connection.reset(new http_connection(get_io_service(), m_man.host_resolver()
                               , boost::bind(&http_tracker_connection::on_response, shared_from_this(), _1, _2, _3, _4)
                               , true, settings.get_int(settings_pack::max_http_recv_buffer_size)
                               , boost::bind(&http_tracker_connection::on_connect, shared_from_this(), _1)
                               , boost::bind(&http_tracker_connection::on_filter, shared_from_this(), _1, _2)
#ifdef TORRENT_USE_OPENSSL
                               , tracker_req().ssl_ctx
#endif
                                                  ));

    int timeout = tracker_req().event==tracker_request::stopped
                  ?settings.get_int(settings_pack::stop_tracker_timeout)
                  :settings.get_int(settings_pack::tracker_completion_timeout);

    // when sending stopped requests, prefer the cached DNS entry
    // to avoid being blocked for slow or failing responses. Chances
    // are that we're shutting down, and this should be a best-effort
    // attempt. It's not worth stalling shutdown.
    aux::proxy_settings ps(settings);
    m_tracker_connection->get(url, seconds(timeout)
                              , tracker_req().event == tracker_request::stopped ? 2 : 1
                              , ps.proxy_tracker_connections ? &ps : NULL
                              , 5, settings.get_bool(settings_pack::anonymous_mode)
                              ? "" : settings.get_str(settings_pack::user_agent)
                              , bind_interface()
                              , tracker_req().event == tracker_request::stopped
                              ? resolver_interface::prefer_cache
                              : resolver_interface::abort_on_shutdown
                              , tracker_req().auth
#if TORRENT_USE_I2P
                              , tracker_req().i2pconn
#endif
                             );

    // the url + 100 estimated header size
    sent_bytes(url.size() + 100);

#ifndef TORRENT_DISABLE_LOGGING

    boost::shared_ptr<request_callback> cb = requester();
    if (cb)
    {
        cb->debug_log("==> TRACKER_REQUEST [ url: %s ]", url.c_str());
    }
#endif
}
コード例 #27
0
static bool argument_named (int argc, char **argv, int *argi, AppArgument *arguments)
{
        size_t i, digits;

        for (i = 0; arguments[i].type != AppArgumentTypeEnd; i++) {
                if (arguments[i].type != AppArgumentTypeNamed) {
                        continue;
                }
                if (!((arguments[i].object.named.short_form && 
                       string_equals (argv[*argi], arguments[i].object.named.short_form)) ||
                      (arguments[i].object.named.long_form && 
                       string_equals (argv[*argi], arguments[i].object.named.long_form)))) {
                        continue;
                }
                if (arguments[i].have_value) {
                        print ("The argument ");
                        app_arguments_print_named_form (arguments[i]);
                        print (" is duplicated.\n");
                        error (AppArgumentDuplicate);
                        return false;
                }
                switch (arguments[i].value_type) {
                case AppArgumentBoolean:
                        *arguments[i].value.boolean = !arguments[i].value_default.boolean;
                        arguments[i].have_value = true;
                        *argi += 1;
                        return true;
                case AppArgumentInteger:
                        if (*argi + 1 == argc) {
                                print ("The argument ");
                                app_arguments_print_named_form (arguments[i]);
                                print (" is missing an integer value.\n");
                                error (AppArgumentMissingIntegerValue);
                                return false;
                        }
                        if (!convert_string_to_int (argv[*argi + 1], arguments[i].value.integer, &digits)) {
                                print ("The value '%s' for ", argv[*argi + 1]);
                                app_arguments_print_named_form (arguments[i]);
                                print (" could not be converted to an integer value.\n");
                                error_code (FunctionCall, 1);
                                return false;
                        }
                        if (digits != string_length (argv[*argi + 1])) {
                                print ("The value '%s' for ", argv[*argi + 1]);
                                app_arguments_print_named_form (arguments[i]);
                                print (" could not be converted to an integer value.\n");
                                error (AppArgumentInvalidIntegerValue);
                                return false;
                        }
                        arguments[i].have_value = true;
                        *argi += 2;
                        return true;
                case AppArgumentUInt64:
                        if (*argi + 1 == argc) {
                                print ("The argument ");
                                app_arguments_print_named_form (arguments[i]);
                                print (" is missing an UInt64 value.\n");
                                error (AppArgumentMissingUInt64Value);
                                return false;
                        }
                        if (!convert_string_to_unsigned_long_long (argv[*argi + 1], 
                                                                   (unsigned long long *)arguments[i].value.uint64, 
                                                                   &digits)) {
                                print ("The value '%s' for ", argv[*argi + 1]);
                                app_arguments_print_named_form (arguments[i]);
                                print (" could not be converted to an UInt64 value.\n");
                                error_code (FunctionCall, 2);
                                return false;
                        }
                        if (digits != string_length (argv[*argi + 1])) {
                                print ("The value '%s' for ", argv[*argi + 1]);
                                app_arguments_print_named_form (arguments[i]);
                                print (" could not be converted to an UInt64 value.\n");
                                error (AppArgumentInvalidUInt64Value);
                                return false;
                        }
                        arguments[i].have_value = true;
                        *argi += 2;
                        return true;
                case AppArgumentString:
                        if (*argi + 1 == argc) {
                                print ("The argument ");
                                app_arguments_print_named_form (arguments[i]);
                                print (" is missing a string value.\n");
                                error (AppArgumentMissingStringValue);
                                return false;
                        }
                        *arguments[i].value.string = argv[*argi + 1];
                        arguments[i].have_value = true;
                        *argi += 2;
                        return true;
                }
        }
        print ("Unrecognized argument '%s'.\n", argv[*argi]);
        error (AppArgumentUnknownNamedArgument);
        return false;
}
コード例 #28
0
void set_error(error_code& ec, int e)
{
  ec = error_code(e, asio::error::get_system_category());
}
コード例 #29
0
	std::vector<ip_interface> enum_net_interfaces(io_service& ios, error_code& ec)
	{
		TORRENT_UNUSED(ios); // this may be unused depending on configuration
		std::vector<ip_interface> ret;
#if defined TORRENT_BUILD_SIMULATOR

		TORRENT_UNUSED(ec);

		ip_interface wan;
		wan.interface_address = ios.get_ip();
		wan.netmask = address_v4::from_string("255.255.255.255");
		strcpy(wan.name, "eth0");
		wan.mtu = ios.sim().config().path_mtu(ios.get_ip(), ios.get_ip());
		ret.push_back(wan);

#elif TORRENT_USE_IFADDRS
		int s = socket(AF_INET, SOCK_DGRAM, 0);
		if (s < 0)
		{
			ec = error_code(errno, boost::asio::error::system_category);
			return ret;
		}

		ifaddrs *ifaddr;
		if (getifaddrs(&ifaddr) == -1)
		{
			ec = error_code(errno, boost::asio::error::system_category);
			close(s);
			return ret;
		}

		for (ifaddrs* ifa = ifaddr; ifa; ifa = ifa->ifa_next)
		{
			if (ifa->ifa_addr == 0) continue;
			if ((ifa->ifa_flags & IFF_UP) == 0) continue;

			int family = ifa->ifa_addr->sa_family;
			if (family == AF_INET
#if TORRENT_USE_IPV6
				|| family == AF_INET6
#endif
				)
			{
				ip_interface iface;
				if (iface_from_ifaddrs(ifa, iface))
				{
					ifreq req;
					memset(&req, 0, sizeof(req));
					// -1 to leave a null terminator
					strncpy(req.ifr_name, iface.name, IF_NAMESIZE - 1);
					if (ioctl(s, siocgifmtu, &req) < 0)
					{
						continue;
					}
					iface.mtu = req.ifr_mtu;
					ret.push_back(iface);
				}
			}
		}
		close(s);
		freeifaddrs(ifaddr);
// MacOS X, BSD and solaris
#elif TORRENT_USE_IFCONF
		int s = socket(AF_INET, SOCK_DGRAM, 0);
		if (s < 0)
		{
			ec = error_code(errno, boost::asio::error::system_category);
			return ret;
		}
		ifconf ifc;
		// make sure the buffer is aligned to hold ifreq structs
		ifreq buf[40];
		ifc.ifc_len = sizeof(buf);
		ifc.ifc_buf = (char*)buf;
		if (ioctl(s, SIOCGIFCONF, &ifc) < 0)
		{
			ec = error_code(errno, boost::asio::error::system_category);
			close(s);
			return ret;
		}

		char *ifr = (char*)ifc.ifc_req;
		int remaining = ifc.ifc_len;

		while (remaining > 0)
		{
			ifreq const& item = *reinterpret_cast<ifreq*>(ifr);

#ifdef _SIZEOF_ADDR_IFREQ
			int current_size = _SIZEOF_ADDR_IFREQ(item);
#elif defined TORRENT_BSD
			int current_size = item.ifr_addr.sa_len + IFNAMSIZ;
#else
			int current_size = sizeof(ifreq);
#endif

			if (remaining < current_size) break;

			if (item.ifr_addr.sa_family == AF_INET
#if TORRENT_USE_IPV6
				|| item.ifr_addr.sa_family == AF_INET6
#endif
				)
			{
				ip_interface iface;
				iface.interface_address = sockaddr_to_address(&item.ifr_addr);
				strcpy(iface.name, item.ifr_name);

				ifreq req;
				memset(&req, 0, sizeof(req));
				// -1 to leave a null terminator
				strncpy(req.ifr_name, item.ifr_name, IF_NAMESIZE - 1);
				if (ioctl(s, siocgifmtu, &req) < 0)
				{
					ec = error_code(errno, boost::asio::error::system_category);
					close(s);
					return ret;
				}
#ifndef TORRENT_OS2
				iface.mtu = req.ifr_mtu;
#else
				iface.mtu = req.ifr_metric; // according to tcp/ip reference
#endif

				memset(&req, 0, sizeof(req));
				strncpy(req.ifr_name, item.ifr_name, IF_NAMESIZE - 1);
				if (ioctl(s, SIOCGIFNETMASK, &req) < 0)
				{
#if TORRENT_USE_IPV6
					if (iface.interface_address.is_v6())
					{
						// this is expected to fail (at least on MacOS X)
						iface.netmask = address_v6::any();
					}
					else
#endif
					{
						ec = error_code(errno, boost::asio::error::system_category);
						close(s);
						return ret;
					}
				}
				else
				{
					iface.netmask = sockaddr_to_address(&req.ifr_addr, item.ifr_addr.sa_family);
				}
				ret.push_back(iface);
			}

			ifr += current_size;
			remaining -= current_size;
		}
		close(s);

#elif TORRENT_USE_GETADAPTERSADDRESSES

#if _WIN32_WINNT >= 0x0501
		// Load Iphlpapi library
		HMODULE iphlp = LoadLibraryA("Iphlpapi.dll");
		if (iphlp)
		{
			// Get GetAdaptersAddresses() pointer
			typedef ULONG (WINAPI *GetAdaptersAddresses_t)(ULONG,ULONG,PVOID,PIP_ADAPTER_ADDRESSES,PULONG);
			GetAdaptersAddresses_t GetAdaptersAddresses = (GetAdaptersAddresses_t)GetProcAddress(
				iphlp, "GetAdaptersAddresses");

			if (GetAdaptersAddresses)
			{
				PIP_ADAPTER_ADDRESSES adapter_addresses = 0;
				ULONG out_buf_size = 0;
				if (GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER
					| GAA_FLAG_SKIP_ANYCAST, NULL, adapter_addresses, &out_buf_size) != ERROR_BUFFER_OVERFLOW)
				{
					FreeLibrary(iphlp);
					ec = boost::asio::error::operation_not_supported;
					return std::vector<ip_interface>();
				}

				adapter_addresses = (IP_ADAPTER_ADDRESSES*)malloc(out_buf_size);
				if (!adapter_addresses)
				{
					FreeLibrary(iphlp);
					ec = boost::asio::error::no_memory;
					return std::vector<ip_interface>();
				}

				if (GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER
					| GAA_FLAG_SKIP_ANYCAST, NULL, adapter_addresses, &out_buf_size) == NO_ERROR)
				{
					for (PIP_ADAPTER_ADDRESSES adapter = adapter_addresses;
						adapter != 0; adapter = adapter->Next)
					{
						ip_interface r;
						strncpy(r.name, adapter->AdapterName, sizeof(r.name));
						r.name[sizeof(r.name)-1] = 0;
						r.mtu = adapter->Mtu;
						IP_ADAPTER_UNICAST_ADDRESS* unicast = adapter->FirstUnicastAddress;
						while (unicast)
						{
							r.interface_address = sockaddr_to_address(unicast->Address.lpSockaddr);

							ret.push_back(r);

							unicast = unicast->Next;
						}
					}
				}

				// Free memory
				free(adapter_addresses);
				FreeLibrary(iphlp);
				return ret;
			}
			FreeLibrary(iphlp);
		}
#endif

		SOCKET s = socket(AF_INET, SOCK_DGRAM, 0);
		if (s == SOCKET_ERROR)
		{
			ec = error_code(WSAGetLastError(), boost::asio::error::system_category);
			return ret;
		}

		INTERFACE_INFO buffer[30];
		DWORD size;

		if (WSAIoctl(s, SIO_GET_INTERFACE_LIST, 0, 0, buffer,
			sizeof(buffer), &size, 0, 0) != 0)
		{
			ec = error_code(WSAGetLastError(), boost::asio::error::system_category);
			closesocket(s);
			return ret;
		}
		closesocket(s);

		int n = size / sizeof(INTERFACE_INFO);

		ip_interface iface;
		for (int i = 0; i < n; ++i)
		{
			iface.interface_address = sockaddr_to_address(&buffer[i].iiAddress.Address);
			if (iface.interface_address == address_v4::any()) continue;
			iface.netmask = sockaddr_to_address(&buffer[i].iiNetmask.Address
				, iface.interface_address.is_v4() ? AF_INET : AF_INET6);
			iface.name[0] = 0;
			iface.mtu = 1500; // how to get the MTU?
			ret.push_back(iface);
		}

#else

#ifdef _MSC_VER
#pragma message ( "THIS OS IS NOT RECOGNIZED, enum_net_interfaces WILL PROBABLY NOT WORK" )
#else
#warning "THIS OS IS NOT RECOGNIZED, enum_net_interfaces WILL PROBABLY NOT WORK"
#endif

		// make a best guess of the interface we're using and its IP
		udp::resolver r(ios);
		udp::resolver::iterator i = r.resolve(udp::resolver::query(boost::asio::ip::host_name(ec), "0"), ec);
		if (ec) return ret;
		ip_interface iface;
		for (;i != udp::resolver_iterator(); ++i)
		{
			iface.interface_address = i->endpoint().address();
			iface.mtu = 1500;
			if (iface.interface_address.is_v4())
				iface.netmask = address_v4::netmask(iface.interface_address.to_v4());
			ret.push_back(iface);
		}
#endif
		return ret;
	}
コード例 #30
0
vector<EncodedAttributeInfo*> LoadSavedDataSources::loadCodedAttributesFromMultipleFiles( string dsName,int rowCount,bool limit )
{
	vector<EncodedAttributeInfo*> codedAtts;
	try
	{
		for (int j = 0 ; j < this->saved_file_names.size() ; j++)
		{
			this->_fileName = ConfigurationReader::ReadConfiguration(ConfigurationReader::configutation::SAVE_DATA_FOLDER) + this->_saved_folder + "\\" + this->saved_file_names[j];
			TiXmlDocument *doc_1 = new TiXmlDocument(this->_fileName.c_str());
			doc_1->LoadFile();
			TiXmlHandle handler(doc_1);
			TiXmlElement *dsElement = handler.FirstChild("DataSources").ToElement();
			dsElement = dsElement->FirstChildElement("DataSource");
			if (strcmp(dsElement->Attribute("Name"),dsName.c_str()) == 0)
			{
				dsElement = dsElement->FirstChildElement("CodedAttribute");
				int attID = dsElement->FirstAttribute()->IntValue();
				int attType = atoi(dsElement->Attribute("Type"));
				string attName = dsElement->Attribute("Name");
				int noVStreams = dsElement->LastAttribute()->IntValue();
				EncodedAttributeInfo* attr;
				switch(attType){
					case 0:
						{
							EncodedIntAttribute *intAtt = new EncodedIntAttribute();
							intAtt->setAttID(attID);
							intAtt->setAttName(attName);
							intAtt->setNoOfVBitStreams(noVStreams,rowCount);
							intAtt->setAttType(getAttType(attType));

							BitStreamInfo** bitStreams = new BitStreamInfo*[noVStreams];
							TiXmlElement *vbs = dsElement->FirstChildElement("VBitStreams")->FirstChildElement("vbitstream");
							for (int k = 0 ; k < noVStreams ; k++)
							{
								BitStreamInfo* bitStr = new VBitStream();
								bitStr->setBitCount(rowCount);
								bitStr->setBitStreamAllocAttID(attID);
								bitStr->setBitStreamAllocAttName(attName);
								string bitStream;
								if (limit)
								{
									bitStream = vbs->GetText();
									long offset = rowCount - this->_rowLimit;
									bitStream = bitStream.substr(offset,this->_rowLimit);
								}
								else bitStream = vbs->GetText();
								dynamic_bitset<> temp(bitStream);
								bitStr->convert(temp);
								bitStreams[k] = bitStr;
								vbs = vbs->NextSiblingElement("vbitstream");
							}
							vector<BitStreamInfo*> tempVB(bitStreams , bitStreams + noVStreams);
							intAtt->setVBitStreams(tempVB);
							attr = intAtt;
							codedAtts.push_back(attr);
							break;
						}
					case 1:
						{
							EncodedDoubleAttribute *doubleAtt = new EncodedDoubleAttribute();
							doubleAtt->setAttID(attID);
							doubleAtt->setAttName(attName);
							doubleAtt->setNoOfVBitStreams(noVStreams,rowCount);
							doubleAtt->setAttType(getAttType(attType));

							BitStreamInfo** bitStreams = new BitStreamInfo*[noVStreams];
							TiXmlElement *vbs = dsElement->FirstChildElement("VBitStreams")->FirstChildElement("vbitstream");
							for (int k = 0 ; k < noVStreams ; k++)
							{
								BitStreamInfo* bitStr = new VBitStream();
								bitStr->setBitCount(rowCount);
								bitStr->setBitStreamAllocAttID(attID);
								bitStr->setBitStreamAllocAttName(attName);
								string bitStream;
								if (limit)
								{
									bitStream = vbs->GetText();
									long offset = rowCount - this->_rowLimit;
									bitStream = bitStream.substr(offset,this->_rowLimit);
								}
								else bitStream = vbs->GetText();
								dynamic_bitset<> temp(bitStream);
								bitStr->convert(temp);
								bitStreams[k] = bitStr;
								vbs = vbs->NextSiblingElement("vbitstream");
							}
							vector<BitStreamInfo*> tempVB(bitStreams , bitStreams + noVStreams);
							doubleAtt->setVBitStreams(tempVB);
							attr = doubleAtt;
							codedAtts.push_back(attr);
							break;
						}
					case 3:
						{
							EncodedMultiCatAttribute *catAtt = new EncodedMultiCatAttribute();
							catAtt->setAttID(attID);
							catAtt->setAttName(attName);
							catAtt->setAttType(getAttType(attType));
							catAtt->setNoOfVBitStreams(noVStreams,rowCount);

							BitStreamInfo** bitStreams = new BitStreamInfo*[noVStreams];
							TiXmlElement *vbs = dsElement->FirstChildElement("VBitStreams")->FirstChildElement("vbitstream");
							for (int k = 0 ; k < noVStreams ; k++)
							{
								BitStreamInfo* bitStr = new VBitStream();
								bitStr->setBitCount(rowCount);
								bitStr->setBitStreamAllocAttID(attID);
								bitStr->setBitStreamAllocAttName(attName);
								string bitStream;
								if (limit)
								{
									bitStream = vbs->GetText();
									long offset = rowCount - this->_rowLimit;
									bitStream = bitStream.substr(offset,this->_rowLimit);
								}
								else bitStream = vbs->GetText();
								dynamic_bitset<> temp(bitStream);
								bitStr->convert(temp);
								bitStreams[k] = bitStr;
								vbs = vbs->NextSiblingElement("vbitstream");
							}
							vector<BitStreamInfo*> tempVB(bitStreams , bitStreams + noVStreams);
							catAtt->setVBitStreams(tempVB);
							attr = catAtt;
							codedAtts.push_back(attr);
							break;
						}
				}
			}
			delete doc_1;
		}
	}
	catch(...)
	{
		error_loading_encoded_data ex;
		string err = ExceptionReader::GetError(SM1017);
		err += "-> Try to load from a multiple attribute data files";
		ex << error_message(err);
		ex << error_code(SM1017);
		BOOST_THROW_EXCEPTION(ex);
	}
	return codedAtts;
}