示例#1
0
	Node* _select(Node* node, size_t rank) const
	{
		if (! node || node == _end) return nullptr;
		
		size_t size = node->left ? node->left->size : 0;
		
		if (size > rank) return _select(node->left, rank);
		
		else if (size < rank) return _select(node->right, rank - size - 1);
		
		else return node;
	}
示例#2
0
文件: main.cpp 项目: CCJY/coliru
 Map pick_dashes(int n) {
     Map map;
     if (!_dashes.empty())
         for (int i = 0; i < n; ++i)
             map += *std::next(_dashes.begin(), _select(_rng));
     return map;
 }
示例#3
0
void OptionButton::_select_int(int p_which) {

	if (p_which<0 || p_which>=popup->get_item_count())
		return;
	_select(p_which,false);

}
ferroResult Hackscribble_Ferro::read(unsigned int startAddress, byte numberOfBytes, byte *buffer)
{
	// Copies numberOfBytes bytes from FRAM (starting at startAddress) into buffer (starting at 0)
	// Returns result code
		
	// Validations:
	//		_bottomAddress <= startAddress <= _topAddress
	//		0 < numberOfBytes <= maxBuffer
	//		startAddress + numberOfBytes <= _topAddress
		
	if ((startAddress < _bottomAddress) || (startAddress > _topAddress))
	{
		return ferroBadStartAddress;
	}
	if ((numberOfBytes > _maxBufferSize) || (numberOfBytes == 0))
	{
		return ferroBadNumberOfBytes;
	}
	if ((startAddress + numberOfBytes - 1) > _topAddress)
	{
		return ferroBadFinishAddress;
	}
		
	_select();
	SPI.transfer(_READ);
	SPI.transfer(startAddress / 256);
	SPI.transfer(startAddress % 256);
	for (byte i = 0; i < numberOfBytes; i++)
	{
		buffer[i] = SPI.transfer(_dummy);
	}
	_deselect();
		
	return ferroOK;
}
示例#5
0
void
svc_run()
{
	fd_set readfds, cleanfds;
	struct timeval timeout;

	timeout.tv_sec = 30;
	timeout.tv_usec = 0;

	for (;;) {
		rwlock_rdlock(&svc_fd_lock);
		readfds = svc_fdset;
		cleanfds = svc_fdset;
		rwlock_unlock(&svc_fd_lock);
		switch (_select(svc_maxfd+1, &readfds, NULL, NULL, &timeout)) {
		case -1:
			FD_ZERO(&readfds);
			if (errno == EINTR) {
				continue;
			}
			_warn("svc_run: - select failed");
			return;
		case 0:
			__svc_clean_idle(&cleanfds, 30, FALSE);
			continue;
		default:
			svc_getreqset(&readfds);
		}
	}
}
示例#6
0
文件: select.hpp 项目: LuisBL/pythran
 long _select(Ichoice ibegin, Ichoice iend, Iout obegin, Isel sbegin,
              Icond cbegin, long size, utils::int_<N>)
 {
   for (; ibegin != iend and size != 0;
        ibegin++, obegin++, sbegin++, cbegin++)
     size = _select((*ibegin).begin(), (*ibegin).end(), (*obegin).begin(),
                    (*sbegin).begin(), (*cbegin).begin(), size,
                    utils::int_<N - 1>());
   return size;
 }
ferroResult Hackscribble_Ferro::checkForFRAM()
{
	// Tests that the unused status register bits can be read, inverted, written back and read again
		
	const byte srMask = 0x70; // Unused bits are bits 6..4
	byte registerValue = 0;
	byte newValue = 0;
	boolean isPresent = true;
		
	// Read current value
	_select();
	SPI.transfer(_RDSR);
	registerValue = SPI.transfer(_dummy);
	_deselect();
		
	// Invert current value
	newValue = registerValue ^ srMask;
		
	// Write new value
	_select();
	SPI.transfer(_WREN);
	_deselect();
	_select();
	SPI.transfer(_WRSR);
	SPI.transfer(newValue);
	_deselect();
		
	// Read again
	_select();
	SPI.transfer(_RDSR);
	registerValue = SPI.transfer(_dummy);
	_deselect();
		
	if (((registerValue & srMask) == (newValue & srMask)))
	{
		return ferroOK;
	}
	else
	{
		return ferroBadResponse;	
	}
		
}
void Hackscribble_Ferro::writeControlBlock(byte *buffer)
{
	_select();
	SPI.transfer(_WREN);
	_deselect();

	_select();
	SPI.transfer(_WRITE);
		
	SPI.transfer(_baseAddress / 256);
	SPI.transfer(_baseAddress % 256);
		
	for (byte i = 0; i < _maxBufferSize; i++)
	{
		SPI.transfer(buffer[i]);
	}
		
	_deselect();

}
示例#9
0
void * wait_for_incoming_connections(void * arg){
	struct select_fds fds[MAX_SERVICES];
	int len = MAX_SERVICES;
	int i;
	for(i = 0; i< MAX_SERVICES; i++){
		fds[i].fd = services[i].sfd;
		fds[i].type = READ_ARRAY;
		fds[i].function = on_set;
	}
	_select(fds, &len);
}
示例#10
0
/**
*	Definition 4 (Successor state). Let s = l, r, t, b be a cipher state, k ∈ (F 82 ) 8
*	be a key and y ∈ F 2 be the input bit. Then, the successor cipher state s ′ =
*	l ′ , r ′ , t ′ , b ′ is defined as
*	t ′ := (T (t) ⊕ r 0 ⊕ r 4 )t 0 . . . t 14 l ′ := (k [select(T (t),y,r)] ⊕ b ′ ) ⊞ l ⊞ r
*	b ′ := (B(b) ⊕ r 7 )b 0 . . . b 6 r ′ := (k [select(T (t),y,r)] ⊕ b ′ ) ⊞ l
*
* @param s - state
* @param k - array containing 8 bytes
**/
State successor(uint8_t* k, State s, bool y)
{
	bool r0 = s.r >> 7 & 0x1;
	bool r4 = s.r >> 3 & 0x1;
	bool r7 = s.r & 0x1;

	State successor = {0,0,0,0};

	successor.t = s.t >> 1;
	successor.t |= (T(s) ^ r0 ^ r4) << 15;

	successor.b = s.b >> 1;
	successor.b |= (B(s) ^ r7) << 7;

	bool Tt = T(s);

	successor.l = ((k[_select(Tt,y,s.r)] ^ successor.b) + s.l+s.r ) & 0xFF;
	successor.r = ((k[_select(Tt,y,s.r)] ^ successor.b) + s.l ) & 0xFF;

	return successor;
}
示例#11
0
void OptionButton::_selected(int p_which) {

	int selid = -1;
	for (int i = 0; i < popup->get_item_count(); i++) {

		bool is_clicked = popup->get_item_ID(i) == p_which;
		if (is_clicked) {
			selid = i;
			break;
		}
	}

	if (selid == -1 && p_which >= 0 && p_which < popup->get_item_count()) {
		_select(p_which, true);
	} else {

		ERR_FAIL_COND(selid == -1);

		_select(selid, true);
	}
}
示例#12
0
/** @brief Select a @ref m_stream matching a @ref m_stream_id

Matches the @ref m_stream_id (pattern) to the available media stream
IDs and selects the stream. This function returns immediately
if a matching ID was found.  The ID value may be a comma-separated value
(e.g. "foo,bar,baz"). The ID may also contain the keywords 'croak' and
'best' (see the notes below).
@note
  - ID value is used as regular expression pattern
  - ID may contain the reserved keyword 'best'
    - Defining this in the ID is identical to calling
      @ref quvi_media_stream_choose_best, refer to it for details
  - ID may contain the reserved keyword 'croak'
    - This will cause the function to exit immediately when it is reached
    - The result may be checked with @ref quvi_ok
      - The code may be retrieved using @ref quvi_get
      - The error message may be retrieved using @ref quvi_errmsg
  - If nothing matched (and the 'croak' keyword was specified) the
    function will return the first (default) available language
  - Always confirm the result with @ref quvi_ok
@sa @ref parse_media
@ingroup mediaprop
*/
void quvi_media_stream_select(quvi_media_t handle, const char *id)
{
  _quvi_media_t qm;
  _quvi_t q;

  /* If G_DISABLE_CHECKS is defined then the check is not performed. */
  g_return_if_fail(handle != NULL);

  qm = (_quvi_media_t) handle;
  q = qm->handle.quvi;

  q->status.rc = _select(qm, id);
}
示例#13
0
文件: termios.c 项目: coyizumi/cs111
int
tcsendbreak(int fd, int len __unused)
{
	struct timeval sleepytime;

	sleepytime.tv_sec = 0;
	sleepytime.tv_usec = 400000;
	if (_ioctl(fd, TIOCSBRK, 0) == -1)
		return (-1);
	(void)_select(0, 0, 0, 0, &sleepytime);
	if (_ioctl(fd, TIOCCBRK, 0) == -1)
		return (-1);
	return (0);
}
示例#14
0
文件: select.hpp 项目: LuisBL/pythran
 types::ndarray<typename U::type, U::value>
 select(types::list<T> const &condlist, types::list<U> const &choicelist,
        typename U::dtype _default)
 {
   constexpr size_t N = U::value;
   auto &&choicelist0_shape = choicelist[0].shape();
   types::ndarray<T, N> out(choicelist0_shape, _default);
   types::ndarray<T, N> selected(choicelist0_shape(), false);
   long size = selected.flat_size();
   for (long i = 0; i < condlist.size() && size != 0; i++)
     size =
         _select(choicelist[i].begin(), choicelist[i].end(), out.begin(),
                 selected.begin(), condlist.begin(), size, utils::int_<N>());
   return out;
 }
void Hackscribble_Ferro::readControlBlock(byte *buffer)
{

	_select();
	SPI.transfer(_READ);

	SPI.transfer(_baseAddress / 256);
	SPI.transfer(_baseAddress % 256);

	for (byte i = 0; i < _maxBufferSize; i++)
	{
		buffer[i] = SPI.transfer(_dummy);
	}

	_deselect();
		
}
示例#16
0
文件: tcp.c 项目: Distrotech/FreeRDP
BOOL freerdp_tcp_connect_timeout(int sockfd, struct sockaddr* addr, socklen_t addrlen, int timeout)
{
	int status;

#ifndef _WIN32
	int flags;
	fd_set cfds;
	socklen_t optlen;
	struct timeval tv;

	/* set socket in non-blocking mode */

	flags = fcntl(sockfd, F_GETFL);

	if (flags < 0)
		return FALSE;

	fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);

	/* non-blocking tcp connect */

	status = connect(sockfd, addr, addrlen);

	if (status >= 0)
		return TRUE; /* connection success */

	if (errno != EINPROGRESS)
		return FALSE;

	FD_ZERO(&cfds);
	FD_SET(sockfd, &cfds);

	tv.tv_sec = timeout;
	tv.tv_usec = 0;

	status = _select(sockfd + 1, NULL, &cfds, NULL, &tv);

	if (status != 1)
		return FALSE; /* connection timeout or error */

	status = 0;
	optlen = sizeof(status);

	if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, (void*) &status, &optlen) < 0)
		return FALSE;

	if (status != 0)
		return FALSE;

	/* set socket in blocking mode */

	flags = fcntl(sockfd, F_GETFL);

	if (flags < 0)
		return FALSE;

	fcntl(sockfd, F_SETFL, flags & ~O_NONBLOCK);

#else
	status = connect(sockfd, addr, addrlen);

	if (status >= 0)
		return TRUE;

	return FALSE;
#endif

	return TRUE;
}
示例#17
0
int
rtime(struct sockaddr_in *addrp, struct timeval *timep,
    struct timeval *timeout)
{
	int s;
	fd_set readfds;
	int res;
	unsigned long thetime;
	struct sockaddr_in from;
	socklen_t fromlen;
	int type;
	struct servent *serv;

	if (timeout == NULL) {
		type = SOCK_STREAM;
	} else {
		type = SOCK_DGRAM;
	}
	s = _socket(AF_INET, type, 0);
	if (s < 0) {
		return(-1);
	}
	addrp->sin_family = AF_INET;

	/* TCP and UDP port are the same in this case */
	if ((serv = getservbyname("time", "tcp")) == NULL) {
		return(-1);
	}

	addrp->sin_port = serv->s_port;

	if (type == SOCK_DGRAM) {
		res = _sendto(s, (char *)&thetime, sizeof(thetime), 0,
			     (struct sockaddr *)addrp, sizeof(*addrp));
		if (res < 0) {
			do_close(s);
			return(-1);
		}
		do {
			FD_ZERO(&readfds);
			FD_SET(s, &readfds);
			res = _select(_rpc_dtablesize(), &readfds,
				     (fd_set *)NULL, (fd_set *)NULL, timeout);
		} while (res < 0 && errno == EINTR);
		if (res <= 0) {
			if (res == 0) {
				errno = ETIMEDOUT;
			}
			do_close(s);
			return(-1);
		}
		fromlen = sizeof(from);
		res = _recvfrom(s, (char *)&thetime, sizeof(thetime), 0,
			       (struct sockaddr *)&from, &fromlen);
		do_close(s);
		if (res < 0) {
			return(-1);
		}
	} else {
		if (_connect(s, (struct sockaddr *)addrp, sizeof(*addrp)) < 0) {
			do_close(s);
			return(-1);
		}
		res = _read(s, (char *)&thetime, sizeof(thetime));
		do_close(s);
		if (res < 0) {
			return(-1);
		}
	}
	if (res != sizeof(thetime)) {
		errno = EIO;
		return(-1);
	}
	thetime = ntohl(thetime);
	timep->tv_sec = thetime - TOFFSET;
	timep->tv_usec = 0;
	return(0);
}
示例#18
0
文件: tcp.c 项目: CoryXie/FreeRDP
BOOL tcp_connect(rdpTcp* tcp, const char* hostname, int port, int timeout)
{
	int status;
	UINT32 option_value;
	socklen_t option_len;

	if (!hostname)
		return FALSE;

	if (hostname[0] == '/')
	{
		tcp->sockfd = freerdp_uds_connect(hostname);

		if (tcp->sockfd < 0)
			return FALSE;

		tcp->socketBio = BIO_new_fd(tcp->sockfd, 1);

		if (!tcp->socketBio)
			return FALSE;
	}
	else
	{
#ifdef HAVE_POLL_H
		struct pollfd pollfds;
#else
		fd_set cfds;
		struct timeval tv;
#endif

		tcp->socketBio = BIO_new(BIO_s_connect());

		if (!tcp->socketBio)
			return FALSE;

		if (BIO_set_conn_hostname(tcp->socketBio, hostname) < 0 || BIO_set_conn_int_port(tcp->socketBio, &port) < 0)
			return FALSE;

		BIO_set_nbio(tcp->socketBio, 1);

		status = BIO_do_connect(tcp->socketBio);

		if ((status <= 0) && !BIO_should_retry(tcp->socketBio))
			return FALSE;

		tcp->sockfd = BIO_get_fd(tcp->socketBio, NULL);

		if (tcp->sockfd < 0)
			return FALSE;

		if (status <= 0)
		{
#ifdef HAVE_POLL_H
			pollfds.fd = tcp->sockfd;
			pollfds.events = POLLOUT;
			pollfds.revents = 0;
			do
			{
				status = poll(&pollfds, 1, timeout * 1000);
			}
			while ((status < 0) && (errno == EINTR));
#else
			FD_ZERO(&cfds);
			FD_SET(tcp->sockfd, &cfds);

			tv.tv_sec = timeout;
			tv.tv_usec = 0;

			status = _select(tcp->sockfd + 1, NULL, &cfds, NULL, &tv);
#endif
			if (status == 0)
			{
				return FALSE; /* timeout */
			}
		}

		BIO_set_close(tcp->socketBio, BIO_NOCLOSE);
		BIO_free(tcp->socketBio);

		tcp->socketBio = BIO_new(BIO_s_simple_socket());

		if (!tcp->socketBio)
			return -1;

		BIO_set_fd(tcp->socketBio, tcp->sockfd, BIO_CLOSE);
	}

	SetEventFileDescriptor(tcp->event, tcp->sockfd);

	tcp_get_ip_address(tcp);
	tcp_get_mac_address(tcp);

	option_value = 1;
	option_len = sizeof(option_value);

	if (setsockopt(tcp->sockfd, IPPROTO_TCP, TCP_NODELAY, (void*) &option_value, option_len) < 0)
		fprintf(stderr, "%s: unable to set TCP_NODELAY\n", __FUNCTION__);

	/* receive buffer must be a least 32 K */
	if (getsockopt(tcp->sockfd, SOL_SOCKET, SO_RCVBUF, (void*) &option_value, &option_len) == 0)
	{
		if (option_value < (1024 * 32))
		{
			option_value = 1024 * 32;
			option_len = sizeof(option_value);

			if (setsockopt(tcp->sockfd, SOL_SOCKET, SO_RCVBUF, (void*) &option_value, option_len) < 0)
			{
				fprintf(stderr, "%s: unable to set receive buffer len\n", __FUNCTION__);
				return FALSE;
			}
		}
	}

	if (!tcp_set_keep_alive_mode(tcp))
		return FALSE;

	tcp->bufferedBio = BIO_new(BIO_s_buffered_socket());

	if (!tcp->bufferedBio)
		return FALSE;

	tcp->bufferedBio->ptr = tcp;

	tcp->bufferedBio = BIO_push(tcp->bufferedBio, tcp->socketBio);

	return TRUE;
}
示例#19
0
文件: tls.c 项目: JozLes77/FreeRDP
int tls_do_handshake(rdpTls* tls, BOOL clientMode)
{
	CryptoCert cert;
	int verify_status, status;

	do
	{
#ifdef HAVE_POLL_H
		struct pollfd pollfds;
#else
		struct timeval tv;
		fd_set rset;
#endif
		int fd;

		status = BIO_do_handshake(tls->bio);

		if (status == 1)
			break;

		if (!BIO_should_retry(tls->bio))
			return -1;

		/* we select() only for read even if we should test both read and write
		 * depending of what have blocked */
		fd = BIO_get_fd(tls->bio, NULL);

		if (fd < 0)
		{
			DEBUG_WARN( "%s: unable to retrieve BIO fd\n", __FUNCTION__);
			return -1;
		}

#ifdef HAVE_POLL_H
		pollfds.fd = fd;
		pollfds.events = POLLIN;
		pollfds.revents = 0;

		do
		{
			status = poll(&pollfds, 1, 10 * 1000);
		}
		while ((status < 0) && (errno == EINTR));
#else
		FD_ZERO(&rset);
		FD_SET(fd, &rset);
		tv.tv_sec = 0;
		tv.tv_usec = 10 * 1000; /* 10ms */

		status = _select(fd + 1, &rset, NULL, NULL, &tv);
#endif
		if (status < 0)
		{
			DEBUG_WARN( "%s: error during select()\n", __FUNCTION__);
			return -1;
		}
	}
	while (TRUE);

	cert = tls_get_certificate(tls, clientMode);
	if (!cert)
	{
		DEBUG_WARN( "%s: tls_get_certificate failed to return the server certificate.\n", __FUNCTION__);
		return -1;
	}

	tls->Bindings = tls_get_channel_bindings(cert->px509);
	if (!tls->Bindings)
	{
		DEBUG_WARN( "%s: unable to retrieve bindings\n", __FUNCTION__);
		verify_status = -1;
		goto out;
	}

	if (!crypto_cert_get_public_key(cert, &tls->PublicKey, &tls->PublicKeyLength))
	{
		DEBUG_WARN( "%s: crypto_cert_get_public_key failed to return the server public key.\n", __FUNCTION__);
		verify_status = -1;
		goto out;
	}

	/* Note: server-side NLA needs public keys (keys from us, the server) but no
	 * 		certificate verify
	 */
	verify_status = 1;
	if (clientMode)
	{
		verify_status = tls_verify_certificate(tls, cert, tls->hostname, tls->port);

		if (verify_status < 1)
		{
			DEBUG_WARN( "%s: certificate not trusted, aborting.\n", __FUNCTION__);
			tls_disconnect(tls);
			verify_status = 0;
		}
	}

out:
	tls_free_certificate(cert);

	return verify_status;
}
示例#20
0
文件: tls.c 项目: JozLes77/FreeRDP
int tls_write_all(rdpTls* tls, const BYTE* data, int length)
{
	int status, nchunks, commitedBytes;
	rdpTcp *tcp;
#ifdef HAVE_POLL_H
	struct pollfd pollfds;
#else
	fd_set rset, wset;
	fd_set *rsetPtr, *wsetPtr;
	struct timeval tv;
#endif
	BIO* bio = tls->bio;
	DataChunk chunks[2];

	BIO* bufferedBio = findBufferedBio(bio);

	if (!bufferedBio)
	{
		DEBUG_WARN( "%s: error unable to retrieve the bufferedBio in the BIO chain\n", __FUNCTION__);
		return -1;
	}

	tcp = (rdpTcp*) bufferedBio->ptr;

	do
	{
		status = BIO_write(bio, data, length);

		if (status > 0)
			break;

		if (!BIO_should_retry(bio))
			return -1;
#ifdef HAVE_POLL_H
		pollfds.fd = tcp->sockfd;
		pollfds.revents = 0;
		pollfds.events = 0;

		if (tcp->writeBlocked)
		{
			pollfds.events |= POLLOUT;
		}
		else if (tcp->readBlocked)
		{
			pollfds.events |= POLLIN;
		}
		else
		{
			DEBUG_WARN( "%s: weird we're blocked but the underlying is not read or write blocked !\n", __FUNCTION__);
			USleep(10);
			continue;
		}

		do
		{
			status = poll(&pollfds, 1, 100);
		}
		while ((status < 0) && (errno == EINTR));
#else
		/* we try to handle SSL want_read and want_write nicely */
		rsetPtr = wsetPtr = NULL;

		if (tcp->writeBlocked)
		{
			wsetPtr = &wset;
			FD_ZERO(&wset);
			FD_SET(tcp->sockfd, &wset);
		}
		else if (tcp->readBlocked)
		{
			rsetPtr = &rset;
			FD_ZERO(&rset);
			FD_SET(tcp->sockfd, &rset);
		}
		else
		{
			DEBUG_WARN( "%s: weird we're blocked but the underlying is not read or write blocked !\n", __FUNCTION__);
			USleep(10);
			continue;
		}

		tv.tv_sec = 0;
		tv.tv_usec = 100 * 1000;

		status = _select(tcp->sockfd + 1, rsetPtr, wsetPtr, NULL, &tv);
#endif
		if (status < 0)
			return -1;
	}
	while (TRUE);

	/* make sure the output buffer is empty */
	commitedBytes = 0;
	while ((nchunks = ringbuffer_peek(&tcp->xmitBuffer, chunks, ringbuffer_used(&tcp->xmitBuffer))))
	{
		int i;

		for (i = 0; i < nchunks; i++)
		{
			while (chunks[i].size)
			{
				status = BIO_write(tcp->socketBio, chunks[i].data, chunks[i].size);

				if (status > 0)
				{
					chunks[i].size -= status;
					chunks[i].data += status;
					commitedBytes += status;
					continue;
				}

				if (!BIO_should_retry(tcp->socketBio))
					goto out_fail;

#ifdef HAVE_POLL_H
				pollfds.fd = tcp->sockfd;
				pollfds.events = POLLIN;
				pollfds.revents = 0;

				do
				{
					status = poll(&pollfds, 1, 100);
				}
				while ((status < 0) && (errno == EINTR));
#else
				FD_ZERO(&rset);
				FD_SET(tcp->sockfd, &rset);
				tv.tv_sec = 0;
				tv.tv_usec = 100 * 1000;

				status = _select(tcp->sockfd + 1, &rset, NULL, NULL, &tv);
#endif
				if (status < 0)
					goto out_fail;
			}

		}
	}

	ringbuffer_commit_read_bytes(&tcp->xmitBuffer, commitedBytes);
	return length;

out_fail:
	ringbuffer_commit_read_bytes(&tcp->xmitBuffer, commitedBytes);
	return -1;
}
示例#21
0
int FDSelect::waitReadWrite(unsigned long timeoutInMs, bool retry) {
	return _select(&fds, &fds, timeoutInMs, retry);
}
示例#22
0
文件: tls.c 项目: dcatonR1/FreeRDP
int tls_do_handshake(rdpTls* tls, BOOL clientMode)
{
	CryptoCert cert;
	int verify_status;

	do
	{
#ifdef HAVE_POLL_H
		int fd;
		int status;
		struct pollfd pollfds;
#elif !defined(_WIN32)
		int fd;
		int status;
		fd_set rset;
		struct timeval tv;
#else
		HANDLE event;
		DWORD status;
#endif
		status = BIO_do_handshake(tls->bio);

		if (status == 1)
			break;

		if (!BIO_should_retry(tls->bio))
			return -1;

#ifndef _WIN32
		/* we select() only for read even if we should test both read and write
		 * depending of what have blocked */
		fd = BIO_get_fd(tls->bio, NULL);

		if (fd < 0)
		{
			WLog_ERR(TAG, "unable to retrieve BIO fd");
			return -1;
		}

#else
		BIO_get_event(tls->bio, &event);

		if (!event)
		{
			WLog_ERR(TAG, "unable to retrieve BIO event");
			return -1;
		}

#endif
#ifdef HAVE_POLL_H
		pollfds.fd = fd;
		pollfds.events = POLLIN;
		pollfds.revents = 0;

		do
		{
			status = poll(&pollfds, 1, 10 * 1000);
		}
		while ((status < 0) && (errno == EINTR));

#elif !defined(_WIN32)
		FD_ZERO(&rset);
		FD_SET(fd, &rset);
		tv.tv_sec = 0;
		tv.tv_usec = 10 * 1000; /* 10ms */
		status = _select(fd + 1, &rset, NULL, NULL, &tv);
#else
		status = WaitForSingleObject(event, 10);
#endif
#ifndef _WIN32

		if (status < 0)
		{
			WLog_ERR(TAG, "error during select()");
			return -1;
		}

#else

		if ((status != WAIT_OBJECT_0) && (status != WAIT_TIMEOUT))
		{
			WLog_ERR(TAG, "error during WaitForSingleObject(): 0x%04X", status);
			return -1;
		}

#endif
	}
	while (TRUE);

	cert = tls_get_certificate(tls, clientMode);

	if (!cert)
	{
		WLog_ERR(TAG, "tls_get_certificate failed to return the server certificate.");
		return -1;
	}

	tls->Bindings = tls_get_channel_bindings(cert->px509);

	if (!tls->Bindings)
	{
		WLog_ERR(TAG, "unable to retrieve bindings");
		verify_status = -1;
		goto out;
	}

	if (!crypto_cert_get_public_key(cert, &tls->PublicKey, &tls->PublicKeyLength))
	{
		WLog_ERR(TAG,
		         "crypto_cert_get_public_key failed to return the server public key.");
		verify_status = -1;
		goto out;
	}

	/* server-side NLA needs public keys (keys from us, the server) but no certificate verify */
	verify_status = 1;

	if (clientMode)
	{
		verify_status = tls_verify_certificate(tls, cert, tls->hostname, tls->port);

		if (verify_status < 1)
		{
			WLog_ERR(TAG, "certificate not trusted, aborting.");
			tls_send_alert(tls);
			verify_status = 0;
		}
	}

out:
	tls_free_certificate(cert);
	return verify_status;
}
示例#23
0
void OptionButton::select(int p_idx) {

	_select(p_idx, false);
}
示例#24
0
文件: tcp.c 项目: andrejza/FreeRDP
BOOL tcp_connect(rdpTcp* tcp, const char* hostname, int port, int timeout)
{
	int status;
	UINT32 option_value;
	socklen_t option_len;

	if (!hostname)
		return FALSE;

	if (hostname[0] == '/')
		tcp->ipcSocket = TRUE;

	if (tcp->ipcSocket)
	{
		tcp->sockfd = freerdp_uds_connect(hostname);

		if (tcp->sockfd < 0)
			return FALSE;

		tcp->socketBio = BIO_new(BIO_s_simple_socket());

		if (!tcp->socketBio)
			return FALSE;

		BIO_set_fd(tcp->socketBio, tcp->sockfd, BIO_CLOSE);
	}
	else
	{
#ifdef HAVE_POLL_H
		struct pollfd pollfds;
#else
		fd_set cfds;
		struct timeval tv;
#endif

#ifdef NO_IPV6
		tcp->socketBio = BIO_new(BIO_s_connect());

		if (!tcp->socketBio)
			return FALSE;

		if (BIO_set_conn_hostname(tcp->socketBio, hostname) < 0 || BIO_set_conn_int_port(tcp->socketBio, &port) < 0)
			return FALSE;

		BIO_set_nbio(tcp->socketBio, 1);

		status = BIO_do_connect(tcp->socketBio);

		if ((status <= 0) && !BIO_should_retry(tcp->socketBio))
			return FALSE;

		tcp->sockfd = BIO_get_fd(tcp->socketBio, NULL);

		if (tcp->sockfd < 0)
			return FALSE;
#else /* NO_IPV6 */
		struct addrinfo hints = {0};
		struct addrinfo *result;
		struct addrinfo *tmp;
		char port_str[11];

		//ZeroMemory(&hints, sizeof(struct addrinfo));
		hints.ai_family = AF_UNSPEC;    /* Allow IPv4 or IPv6 */
		hints.ai_socktype = SOCK_STREAM;
		/*
		 * FIXME: the following is a nasty workaround. Find a cleaner way:
		 * Either set port manually afterwards or get it passed as string?
		 */
		sprintf_s(port_str, 11, "%u", port);

		status = getaddrinfo(hostname, port_str, &hints, &result);
		if (status) {
			fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(status));
			return FALSE;
		}

		/* For now prefer IPv4 over IPv6. */
		tmp = result;
		if (tmp->ai_family == AF_INET6 && tmp->ai_next != 0)
		{
			while ((tmp = tmp->ai_next))
			{
				if (tmp->ai_family == AF_INET)
					break;
			}
			if (!tmp)
				tmp = result;
		}
		tcp->sockfd = socket(tmp->ai_family, tmp->ai_socktype, tmp->ai_protocol);

		if (tcp->sockfd  < 0) {
			freeaddrinfo(result);
			return FALSE;
		}

		if (connect(tcp->sockfd, tmp->ai_addr, tmp->ai_addrlen) < 0) {
			fprintf(stderr, "connect: %s\n", strerror(errno));
			freeaddrinfo(result);
			return FALSE;
		}
		freeaddrinfo(result);
		tcp->socketBio = BIO_new_socket(tcp->sockfd, BIO_NOCLOSE);

		/* TODO: make sure the handshake is done by querying the bio */
		//		if (BIO_should_retry(tcp->socketBio))
		//          return FALSE;
#endif /* NO_IPV6 */

		if (status <= 0)
		{
#ifdef HAVE_POLL_H
			pollfds.fd = tcp->sockfd;
			pollfds.events = POLLOUT;
			pollfds.revents = 0;
			do
			{
				status = poll(&pollfds, 1, timeout * 1000);
			}
			while ((status < 0) && (errno == EINTR));
#else
			FD_ZERO(&cfds);
			FD_SET(tcp->sockfd, &cfds);

			tv.tv_sec = timeout;
			tv.tv_usec = 0;

			status = _select(tcp->sockfd + 1, NULL, &cfds, NULL, &tv);
#endif
			if (status == 0)
			{
				return FALSE; /* timeout */
			}
		}

		(void)BIO_set_close(tcp->socketBio, BIO_NOCLOSE);
		BIO_free(tcp->socketBio);

		tcp->socketBio = BIO_new(BIO_s_simple_socket());

		if (!tcp->socketBio)
			return FALSE;

		BIO_set_fd(tcp->socketBio, tcp->sockfd, BIO_CLOSE);
	}

	SetEventFileDescriptor(tcp->event, tcp->sockfd);

	tcp_get_ip_address(tcp);
	tcp_get_mac_address(tcp);

	option_value = 1;
	option_len = sizeof(option_value);

	if (!tcp->ipcSocket)
	{
		if (setsockopt(tcp->sockfd, IPPROTO_TCP, TCP_NODELAY, (void*) &option_value, option_len) < 0)
			WLog_ERR(TAG,  "unable to set TCP_NODELAY");
	}

	/* receive buffer must be a least 32 K */
	if (getsockopt(tcp->sockfd, SOL_SOCKET, SO_RCVBUF, (void*) &option_value, &option_len) == 0)
	{
		if (option_value < (1024 * 32))
		{
			option_value = 1024 * 32;
			option_len = sizeof(option_value);

			if (setsockopt(tcp->sockfd, SOL_SOCKET, SO_RCVBUF, (void*) &option_value, option_len) < 0)
			{
				WLog_ERR(TAG,  "unable to set receive buffer len");
				return FALSE;
			}
		}
	}

	if (!tcp->ipcSocket)
	{
		if (!tcp_set_keep_alive_mode(tcp))
			return FALSE;
	}

	tcp->bufferedBio = BIO_new(BIO_s_buffered_socket());

	if (!tcp->bufferedBio)
		return FALSE;

	tcp->bufferedBio->ptr = tcp;

	tcp->bufferedBio = BIO_push(tcp->bufferedBio, tcp->socketBio);

	return TRUE;
}
示例#25
0
	Iterator select(size_t rank) const
	{
		return _select(_root, rank);
	}
示例#26
0
文件: tcp.c 项目: Distrotech/FreeRDP
int freerdp_tcp_connect_multi(char** hostnames, UINT32* ports, int count, int port, int timeout)
{
	int index;
	int sindex;
	int status;
	int flags;
	int maxfds;
	fd_set cfds;
	int sockfd = -1;
	int* sockfds;
	char port_str[16];
	socklen_t optlen;
	struct timeval tv;
	struct addrinfo hints;
	struct addrinfo* addr;
	struct addrinfo* result;
	struct addrinfo** addrs;
	struct addrinfo** results;

	sindex = -1;

	sprintf_s(port_str, sizeof(port_str) - 1, "%u", port);

	sockfds = (int*) calloc(count, sizeof(int));
	addrs = (struct addrinfo**) calloc(count, sizeof(struct addrinfo*));
	results = (struct addrinfo**) calloc(count, sizeof(struct addrinfo*));

	for (index = 0; index < count; index++)
	{
		ZeroMemory(&hints, sizeof(hints));
		hints.ai_family = AF_UNSPEC;
		hints.ai_socktype = SOCK_STREAM;

		if (ports)
			sprintf_s(port_str, sizeof(port_str) - 1, "%u", ports[index]);

		status = getaddrinfo(hostnames[index], port_str, &hints, &result);

		if (status)
		{
			continue;
		}

		addr = result;

		if ((addr->ai_family == AF_INET6) && (addr->ai_next != 0))
		{
			while ((addr = addr->ai_next))
			{
				if (addr->ai_family == AF_INET)
					break;
			}

			if (!addr)
				addr = result;
		}

		sockfds[index] = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);

		if (sockfds[index] < 0)
		{
			freeaddrinfo(result);
			sockfds[index] = 0;
			continue;
		}

		addrs[index] = addr;
		results[index] = result;
	}

	maxfds = 0;
	FD_ZERO(&cfds);

	for (index = 0; index < count; index++)
	{
		if (!sockfds[index])
			continue;

		sockfd = sockfds[index];
		addr = addrs[index];

		/* set socket in non-blocking mode */

		flags = fcntl(sockfd, F_GETFL);

		if (flags < 0)
		{
			sockfds[index] = 0;
			continue;
		}

		fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);

		/* non-blocking tcp connect */

		status = connect(sockfd, addr->ai_addr, addr->ai_addrlen);

		if (status >= 0)
		{
			/* connection success */
			break;
		}

		if (errno != EINPROGRESS)
		{
			sockfds[index] = 0;
			continue;
		}

		FD_SET(sockfd, &cfds);

		if (sockfd > maxfds)
			maxfds = sockfd;
	}

	tv.tv_sec = timeout;
	tv.tv_usec = 0;

	status = _select(maxfds + 1, NULL, &cfds, NULL, &tv);

	for (index = 0; index < count; index++)
	{
		if (!sockfds[index])
			continue;

		sockfd = sockfds[index];

		if (FD_ISSET(sockfd, &cfds))
		{
			status = 0;
			optlen = sizeof(status);

			if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, (void*) &status, &optlen) < 0)
			{
				sockfds[index] = 0;
				continue;
			}

			if (status != 0)
			{
				sockfds[index] = 0;
				continue;
			}

			/* set socket in blocking mode */

			flags = fcntl(sockfd, F_GETFL);

			if (flags < 0)
			{
				sockfds[index] = 0;
				continue;
			}

			fcntl(sockfd, F_SETFL, flags & ~O_NONBLOCK);

			sindex = index;
			break;
		}
	}

	if (sindex >= 0)
	{
		sockfd = sockfds[sindex];
	}

	for (index = 0; index < count; index++)
	{
		if (results[index])
			freeaddrinfo(results[index]);
	}

	free(addrs);
	free(results);
	free(sockfds);

	return sockfd;
}
示例#27
0
int
rcmd_af(char **ahost, int rport, const char *locuser, const char *remuser,
	const char *cmd, int *fd2p, int af)
{
	struct addrinfo hints, *res, *ai;
	struct sockaddr_storage from;
	fd_set reads;
	sigset_t oldmask, newmask;
	pid_t pid;
	int s, aport, lport, timo, error;
	char c, *p;
	int refused, nres;
	char num[8];
	static char canonnamebuf[MAXDNAME];	/* is it proper here? */

	/* call rcmdsh() with specified remote shell if appropriate. */
	if (!issetugid() && (p = getenv("RSH"))) {
		struct servent *sp = getservbyname("shell", "tcp");

		if (sp && sp->s_port == rport)
			return (rcmdsh(ahost, rport, locuser, remuser,
			    cmd, p));
	}

	/* use rsh(1) if non-root and remote port is shell. */
	if (geteuid()) {
		struct servent *sp = getservbyname("shell", "tcp");

		if (sp && sp->s_port == rport)
			return (rcmdsh(ahost, rport, locuser, remuser,
			    cmd, NULL));
	}

	pid = getpid();

	memset(&hints, 0, sizeof(hints));
	hints.ai_flags = AI_CANONNAME;
	hints.ai_family = af;
	hints.ai_socktype = SOCK_STREAM;
	hints.ai_protocol = 0;
	snprintf(num, sizeof(num), "%d", ntohs(rport));
	error = getaddrinfo(*ahost, num, &hints, &res);
	if (error) {
		fprintf(stderr, "rcmd: getaddrinfo: %s\n",
			gai_strerror(error));
		if (error == EAI_SYSTEM)
			fprintf(stderr, "rcmd: getaddrinfo: %s\n",
				strerror(errno));
		return (-1);
	}

	if (res->ai_canonname &&
	    strlen(res->ai_canonname) + 1 < sizeof(canonnamebuf)) {
		strncpy(canonnamebuf, res->ai_canonname, sizeof(canonnamebuf));
		*ahost = canonnamebuf;
	}
	nres = 0;
	for (ai = res; ai; ai = ai->ai_next)
		nres++;
	ai = res;
	refused = 0;
	sigemptyset(&newmask);
	sigaddset(&newmask, SIGURG);
	_sigprocmask(SIG_BLOCK, (const sigset_t *)&newmask, &oldmask);
	for (timo = 1, lport = IPPORT_RESERVED - 1;;) {
		s = rresvport_af(&lport, ai->ai_family);
		if (s < 0) {
			if (errno != EAGAIN && ai->ai_next) {
				ai = ai->ai_next;
				continue;
			}
			if (errno == EAGAIN)
				fprintf(stderr,
				    "rcmd: socket: All ports in use\n");
			else
				fprintf(stderr, "rcmd: socket: %s\n",
				    strerror(errno));
			freeaddrinfo(res);
			_sigprocmask(SIG_SETMASK, (const sigset_t *)&oldmask,
			    NULL);
			return (-1);
		}
		_fcntl(s, F_SETOWN, pid);
		if (_connect(s, ai->ai_addr, ai->ai_addrlen) >= 0)
			break;
		_close(s);
		if (errno == EADDRINUSE) {
			lport--;
			continue;
		}
		if (errno == ECONNREFUSED)
			refused = 1;
		if (ai->ai_next == NULL && (!refused || timo > 16)) {
			fprintf(stderr, "%s: %s\n", *ahost, strerror(errno));
			freeaddrinfo(res);
			_sigprocmask(SIG_SETMASK, (const sigset_t *)&oldmask,
			    NULL);
			return (-1);
		}
		if (nres > 1) {
			int oerrno = errno;

			getnameinfo(ai->ai_addr, ai->ai_addrlen, paddr,
			    sizeof(paddr), NULL, 0, NI_NUMERICHOST);
			fprintf(stderr, "connect to address %s: ", paddr);
			errno = oerrno;
			perror(0);
		}
		if ((ai = ai->ai_next) == NULL) {
			/* refused && timo <= 16 */
			struct timespec time_to_sleep, time_remaining;

			time_to_sleep.tv_sec = timo;
			time_to_sleep.tv_nsec = 0;
			_nanosleep(&time_to_sleep, &time_remaining);
			timo *= 2;
			ai = res;
			refused = 0;
		}
		if (nres > 1) {
			getnameinfo(ai->ai_addr, ai->ai_addrlen, paddr,
			    sizeof(paddr), NULL, 0, NI_NUMERICHOST);
			fprintf(stderr, "Trying %s...\n", paddr);
		}
	}
	lport--;
	if (fd2p == 0) {
		_write(s, "", 1);
		lport = 0;
	} else {
		int s2 = rresvport_af(&lport, ai->ai_family), s3;
		socklen_t len = ai->ai_addrlen;
		int nfds;

		if (s2 < 0)
			goto bad;
		_listen(s2, 1);
		snprintf(num, sizeof(num), "%d", lport);
		if (_write(s, num, strlen(num)+1) != strlen(num)+1) {
			fprintf(stderr,
			    "rcmd: write (setting up stderr): %s\n",
			    strerror(errno));
			_close(s2);
			goto bad;
		}
		nfds = max(s, s2)+1;
		if(nfds > FD_SETSIZE) {
			fprintf(stderr, "rcmd: too many files\n");
			_close(s2);
			goto bad;
		}
again:
		FD_ZERO(&reads);
		FD_SET(s, &reads);
		FD_SET(s2, &reads);
		errno = 0;
		if (_select(nfds, &reads, 0, 0, 0) < 1 || !FD_ISSET(s2, &reads)){
			if (errno != 0)
				fprintf(stderr,
				    "rcmd: select (setting up stderr): %s\n",
				    strerror(errno));
			else
				fprintf(stderr,
				"select: protocol failure in circuit setup\n");
			_close(s2);
			goto bad;
		}
		s3 = _accept(s2, (struct sockaddr *)&from, &len);
		switch (from.ss_family) {
		case AF_INET:
			aport = ntohs(((struct sockaddr_in *)&from)->sin_port);
			break;
#ifdef INET6
		case AF_INET6:
			aport = ntohs(((struct sockaddr_in6 *)&from)->sin6_port);
			break;
#endif
		default:
			aport = 0;	/* error */
			break;
		}
		/*
		 * XXX careful for ftp bounce attacks. If discovered, shut them
		 * down and check for the real auxiliary channel to connect.
		 */
		if (aport == 20) {
			_close(s3);
			goto again;
		}
		_close(s2);
		if (s3 < 0) {
			fprintf(stderr,
			    "rcmd: accept: %s\n", strerror(errno));
			lport = 0;
			goto bad;
		}
		*fd2p = s3;
		if (aport >= IPPORT_RESERVED || aport < IPPORT_RESERVED / 2) {
			fprintf(stderr,
			    "socket: protocol failure in circuit setup.\n");
			goto bad2;
		}
	}
	_write(s, locuser, strlen(locuser)+1);
	_write(s, remuser, strlen(remuser)+1);
	_write(s, cmd, strlen(cmd)+1);
	if (_read(s, &c, 1) != 1) {
		fprintf(stderr,
		    "rcmd: %s: %s\n", *ahost, strerror(errno));
		goto bad2;
	}
	if (c != 0) {
		while (_read(s, &c, 1) == 1) {
			_write(STDERR_FILENO, &c, 1);
			if (c == '\n')
				break;
		}
		goto bad2;
	}
	_sigprocmask(SIG_SETMASK, (const sigset_t *)&oldmask, NULL);
	freeaddrinfo(res);
	return (s);
bad2:
	if (lport)
		_close(*fd2p);
bad:
	_close(s);
	_sigprocmask(SIG_SETMASK, (const sigset_t *)&oldmask, NULL);
	freeaddrinfo(res);
	return (-1);
}
示例#28
0
bool TileMapEditor::forward_input_event(const InputEvent& p_event) {

	if (!node || !node->get_tileset().is_valid() || !node->is_visible())
		return false;

	Matrix32 xform = CanvasItemEditor::get_singleton()->get_canvas_transform() * node->get_global_transform();
	Matrix32 xform_inv = xform.affine_inverse();

	switch(p_event.type) {

		case InputEvent::MOUSE_BUTTON: {

			const InputEventMouseButton &mb=p_event.mouse_button;

			if (mb.button_index==BUTTON_LEFT) {

				if (mb.pressed) {

					if (Input::get_singleton()->is_key_pressed(KEY_SPACE))
						return false; //drag

					if (tool==TOOL_NONE) {

						if (mb.mod.shift) {

							if (mb.mod.control)
								tool=TOOL_RECTANGLE_PAINT;
							else
								tool=TOOL_LINE_PAINT;

							selection_active=false;
							rectangle_begin=over_tile;

							return true;
						}

						if (mb.mod.control) {

							tool=TOOL_PICKING;
							_pick_tile(over_tile);

							return true;
						}

						tool=TOOL_PAINTING;
					}

					if (tool==TOOL_PAINTING) {

						int id = get_selected_tile();

						if (id!=TileMap::INVALID_CELL) {

							tool=TOOL_PAINTING;

							paint_undo.clear();
							paint_undo[over_tile]=_get_op_from_cell(over_tile);

							_set_cell(over_tile, id, flip_h, flip_v, transpose);
						}
					} else if (tool==TOOL_PICKING) {

						_pick_tile(over_tile);
					} else if (tool==TOOL_SELECTING) {

						selection_active=true;
						rectangle_begin=over_tile;
					}

					return true;

				} else {

					if (tool!=TOOL_NONE) {

						if (tool==TOOL_PAINTING) {

							int id=get_selected_tile();

							if (id!=TileMap::INVALID_CELL && paint_undo.size()) {

								undo_redo->create_action(TTR("Paint TileMap"));
								for (Map<Point2i,CellOp>::Element *E=paint_undo.front();E;E=E->next()) {

									Point2 p=E->key();
									undo_redo->add_do_method(node,"set_cellv",p,id,flip_h,flip_v,transpose);
									undo_redo->add_undo_method(node,"set_cellv",p,E->get().idx,E->get().xf,E->get().yf,E->get().tr);
								}
								undo_redo->commit_action();

								paint_undo.clear();
							}
						} else if (tool==TOOL_LINE_PAINT) {

							int id=get_selected_tile();

							if (id!=TileMap::INVALID_CELL) {

								undo_redo->create_action("Line Draw");
								for (Map<Point2i,CellOp>::Element *E=paint_undo.front();E;E=E->next()) {

									_set_cell(E->key(), id, flip_h, flip_v, transpose, true);
								}
								undo_redo->commit_action();

								paint_undo.clear();

								canvas_item_editor->update();
							}
						} else if (tool==TOOL_RECTANGLE_PAINT) {

							int id=get_selected_tile();

							if (id!=TileMap::INVALID_CELL) {

								undo_redo->create_action("Rectangle Paint");
								for (int i=rectangle.pos.y;i<=rectangle.pos.y+rectangle.size.y;i++) {
									for (int j=rectangle.pos.x;j<=rectangle.pos.x+rectangle.size.x;j++) {

										_set_cell(Point2i(j, i), id, flip_h, flip_v, transpose, true);
									}
								}
								undo_redo->commit_action();

								canvas_item_editor->update();
							}
						} else if (tool==TOOL_DUPLICATING) {

							Point2 ofs = over_tile-rectangle.pos;

							undo_redo->create_action(TTR("Duplicate"));
							for (List<TileData>::Element *E=copydata.front();E;E=E->next()) {

								_set_cell(E->get().pos+ofs,E->get().cell,E->get().flip_h,E->get().flip_v,E->get().transpose,true);
							}
							undo_redo->commit_action();

							copydata.clear();

							canvas_item_editor->update();

						} else if (tool==TOOL_SELECTING) {

							canvas_item_editor->update();

						} else if (tool==TOOL_BUCKET) {

							DVector<Vector2> points = _bucket_fill(over_tile);

							if (points.size() == 0)
								return false;

							Dictionary op;
							op["id"] = get_selected_tile();
							op["flip_h"] = flip_h;
							op["flip_v"] = flip_v;
							op["transpose"] = transpose;

							undo_redo->create_action("Bucket Fill");

							undo_redo->add_do_method(this, "_fill_points", points, op);
							undo_redo->add_undo_method(this, "_erase_points", points);

							undo_redo->commit_action();
						}

						tool=TOOL_NONE;

						return true;
					}
				}
			} else if (mb.button_index==BUTTON_RIGHT) {

				if (mb.pressed) {

					if (tool==TOOL_SELECTING || selection_active) {

						tool=TOOL_NONE;
						selection_active=false;

						canvas_item_editor->update();

						return true;
					}

					if (tool==TOOL_DUPLICATING) {

						tool=TOOL_NONE;
						copydata.clear();

						canvas_item_editor->update();

						return true;
					}

					if (tool==TOOL_NONE) {

						paint_undo.clear();

						Point2 local = node->world_to_map(xform_inv.xform(Point2(mb.x, mb.y)));

						if (mb.mod.shift) {

							if (mb.mod.control)
								tool=TOOL_RECTANGLE_ERASE;
							else
								tool=TOOL_LINE_ERASE;

							selection_active=false;
							rectangle_begin=local;
						} else {

							tool=TOOL_ERASING;

							paint_undo[local]=_get_op_from_cell(local);
							_set_cell(local, TileMap::INVALID_CELL);
						}

						return true;
					}

				} else {
					if (tool==TOOL_ERASING || tool==TOOL_RECTANGLE_ERASE || tool==TOOL_LINE_ERASE) {

						if (paint_undo.size()) {
							undo_redo->create_action(TTR("Erase TileMap"));
							for (Map<Point2i,CellOp>::Element *E=paint_undo.front();E;E=E->next()) {

								Point2 p=E->key();
								undo_redo->add_do_method(node,"set_cellv",p,TileMap::INVALID_CELL,false,false,false);
								undo_redo->add_undo_method(node,"set_cellv",p,E->get().idx,E->get().xf,E->get().yf,E->get().tr);
							}

							undo_redo->commit_action();
							paint_undo.clear();
						}

						if (tool==TOOL_RECTANGLE_ERASE || tool==TOOL_LINE_ERASE) {
							canvas_item_editor->update();
						}

						tool=TOOL_NONE;

						return true;
					}
				}
			}
		} break;
		case InputEvent::MOUSE_MOTION: {

			const InputEventMouseMotion &mm=p_event.mouse_motion;

			Point2i new_over_tile = node->world_to_map(xform_inv.xform(Point2(mm.x,mm.y)));

			if (new_over_tile!=over_tile) {

				over_tile=new_over_tile;
				canvas_item_editor->update();
			}

			if (tool==TOOL_PAINTING) {

				int id = get_selected_tile();
				if (id!=TileMap::INVALID_CELL) {

					if (!paint_undo.has(over_tile)) {
						paint_undo[over_tile]=_get_op_from_cell(over_tile);
					}

					_set_cell(over_tile, id, flip_h, flip_v, transpose);

					return true;
				}
			}

			if (tool==TOOL_SELECTING) {

				_select(rectangle_begin, over_tile);

				return true;
			}

			if (tool==TOOL_LINE_PAINT || tool==TOOL_LINE_ERASE) {

				int id = get_selected_tile();
				bool erasing = (tool==TOOL_LINE_ERASE);

				if (erasing && paint_undo.size()) {

					for (Map<Point2i, CellOp>::Element *E=paint_undo.front();E;E=E->next()) {

						_set_cell(E->key(), E->get().idx, E->get().xf, E->get().yf, E->get().tr);
					}
				}

				paint_undo.clear();

				if (id!=TileMap::INVALID_CELL) {

					Vector<Point2i> points = line(rectangle_begin.x, over_tile.x, rectangle_begin.y, over_tile.y);

					for (int i=0;i<points.size();i++) {

						paint_undo[points[i]]=_get_op_from_cell(points[i]);

						if (erasing)
							_set_cell(points[i], TileMap::INVALID_CELL);
					}

					canvas_item_editor->update();
				}

				return true;
			}
			if (tool==TOOL_RECTANGLE_PAINT || tool==TOOL_RECTANGLE_ERASE) {

				_select(rectangle_begin, over_tile);

				if (tool==TOOL_RECTANGLE_ERASE) {

					if (paint_undo.size()) {

						for (Map<Point2i, CellOp>::Element *E=paint_undo.front();E;E=E->next()) {

							_set_cell(E->key(), E->get().idx, E->get().xf, E->get().yf, E->get().tr);
						}
					}

					paint_undo.clear();

					for (int i=rectangle.pos.y;i<=rectangle.pos.y+rectangle.size.y;i++) {
						for (int j=rectangle.pos.x;j<=rectangle.pos.x+rectangle.size.x;j++) {

							Point2i tile = Point2i(j, i);
							paint_undo[tile]=_get_op_from_cell(tile);

							_set_cell(tile, TileMap::INVALID_CELL);
						}
					}
				}

				return true;
			}
			if (tool==TOOL_ERASING) {

				if (!paint_undo.has(over_tile)) {
					paint_undo[over_tile]=_get_op_from_cell(over_tile);
				}

				_set_cell(over_tile, TileMap::INVALID_CELL);

				return true;
			}
			if (tool==TOOL_PICKING && Input::get_singleton()->is_mouse_button_pressed(BUTTON_LEFT)) {

				_pick_tile(over_tile);

				return true;
			}
		} break;
		case InputEvent::KEY: {

			const InputEventKey &k = p_event.key;

			if (!k.pressed)
				break;

			if (k.scancode==KEY_ESCAPE) {

				if (tool==TOOL_DUPLICATING)
					copydata.clear();
				else if (tool==TOOL_SELECTING || selection_active)
					selection_active=false;

				tool=TOOL_NONE;

				canvas_item_editor->update();

				return true;
			}

			if (tool!=TOOL_NONE || !mouse_over)
				return false;

			if (k.scancode==KEY_DELETE) {

				_menu_option(OPTION_ERASE_SELECTION);

				return true;
			}

			if (k.mod.command) {

				if (k.scancode==KEY_F) {

					search_box->select_all();
					search_box->grab_focus();

					return true;
				}
				if (k.scancode==KEY_B) {

					tool=TOOL_SELECTING;
					selection_active=false;

					canvas_item_editor->update();

					return true;
				}
				if (k.scancode==KEY_D) {

					_update_copydata();

					if (selection_active) {
						tool=TOOL_DUPLICATING;

						canvas_item_editor->update();

						return true;
					}
				}
			} else {

				if (k.scancode==KEY_A) {

					flip_h=!flip_h;
					mirror_x->set_pressed(flip_h);
					canvas_item_editor->update();
					return true;
				}
				if (k.scancode==KEY_S) {

					flip_v=!flip_v;
					mirror_y->set_pressed(flip_v);
					canvas_item_editor->update();
					return true;
				}
			}
		} break;
	}

	return false;
}
示例#29
0
/*
 * __rpc_get_time_offset()
 *
 * This function uses a nis_server structure to contact the a remote
 * machine (as named in that structure) and returns the offset in time
 * between that machine and this one. This offset is returned in seconds
 * and may be positive or negative.
 *
 * The first time through, a lot of fiddling is done with the netconfig
 * stuff to find a suitable transport. The function is very aggressive
 * about choosing UDP or at worst TCP if it can. This is because
 * those transports support both the RCPBIND call and the internet
 * time service.
 *
 * Once through, *uaddr is set to the universal address of
 * the machine and *netid is set to the local netid for the transport
 * that uaddr goes with. On the second call, the netconfig stuff
 * is skipped and the uaddr/netid pair are used to fetch the netconfig
 * structure and to then contact the machine for the time.
 *
 * td = "server" - "client"
 */
int
__rpc_get_time_offset(struct timeval *td,	/* Time difference			*/
		      nis_server *srv,		/* NIS Server description 		*/
		      char *thost,		/* if no server, this is the timehost	*/
		      char **uaddr,		/* known universal address		*/
		      struct sockaddr_in *netid)/* known network identifier		*/
{
	CLIENT			*clnt; 		/* Client handle 	*/
	endpoint		*ep,		/* useful endpoints	*/
				*useep = NULL;	/* endpoint of xp	*/
	char			*useua = NULL;	/* uaddr of selected xp	*/
	int			epl, i;		/* counters		*/
	enum clnt_stat		status;		/* result of clnt_call	*/
	u_long			thetime, delta;
	int			needfree = 0;
	struct timeval		tv;
	int			time_valid;
	int			udp_ep = -1, tcp_ep = -1;
	int			a1, a2, a3, a4;
	char			ut[64], ipuaddr[64];
	endpoint		teps[32];
	nis_server		tsrv;
	void			(*oldsig)() = NULL; /* old alarm handler */
	struct sockaddr_in	sin;
	socklen_t		len;
	int			s = RPC_ANYSOCK;
	int			type = 0;

	td->tv_sec = 0;
	td->tv_usec = 0;

	/*
	 * First check to see if we need to find and address for this
	 * server.
	 */
	if (*uaddr == NULL) {
		if ((srv != NULL) && (thost != NULL)) {
			msg("both timehost and srv pointer used!");
			return (0);
		}
		if (! srv) {
			srv = get_server(netid, thost, &tsrv, teps, 32);
			if (srv == NULL) {
				msg("unable to contruct server data.");
				return (0);
			}
			needfree = 1;	/* need to free data in endpoints */
		}

		ep = srv->ep.ep_val;
		epl = srv->ep.ep_len;

		/* Identify the TCP and UDP endpoints */
		for (i = 0;
			(i < epl) && ((udp_ep == -1) || (tcp_ep == -1)); i++) {
			if (strcasecmp(ep[i].proto, "udp") == 0)
				udp_ep = i;
			if (strcasecmp(ep[i].proto, "tcp") == 0)
				tcp_ep = i;
		}

		/* Check to see if it is UDP or TCP */
		if (tcp_ep > -1) {
			useep = &ep[tcp_ep];
			useua = ep[tcp_ep].uaddr;
			type = SOCK_STREAM;
		} else if (udp_ep > -1) {
			useep = &ep[udp_ep];
			useua = ep[udp_ep].uaddr;
			type = SOCK_DGRAM;
		}

		if (useep == NULL) {
			msg("no acceptable transport endpoints.");
			if (needfree)
				free_eps(teps, tsrv.ep.ep_len);
			return (0);
		}
	}

	/*
	 * Create a sockaddr from the uaddr.
	 */
	if (*uaddr != NULL)
		useua = *uaddr;

	/* Fixup test for NIS+ */
	sscanf(useua, "%d.%d.%d.%d.", &a1, &a2, &a3, &a4);
	sprintf(ipuaddr, "%d.%d.%d.%d.0.111", a1, a2, a3, a4);
	useua = &ipuaddr[0];

	bzero((char *)&sin, sizeof(sin));
	if (uaddr_to_sockaddr(useua, &sin)) {
		msg("unable to translate uaddr to sockaddr.");
		if (needfree)
			free_eps(teps, tsrv.ep.ep_len);
		return (0);
	}

	/*
	 * Create the client handle to rpcbind. Note we always try
	 * version 3 since that is the earliest version that supports
	 * the RPCB_GETTIME call. Also it is the version that comes
	 * standard with SVR4. Since most everyone supports TCP/IP
	 * we could consider trying the rtime call first.
	 */
	clnt = clnttcp_create(&sin, RPCBPROG, RPCBVERS, &s, 0, 0);
	if (clnt == NULL) {
		msg("unable to create client handle to rpcbind.");
		if (needfree)
			free_eps(teps, tsrv.ep.ep_len);
		return (0);
	}

	tv.tv_sec = 5;
	tv.tv_usec = 0;
	time_valid = 0;
	status = clnt_call(clnt, RPCBPROC_GETTIME, (xdrproc_t)xdr_void, NULL,
					(xdrproc_t)xdr_u_long, &thetime, tv);
	/*
	 * The only error we check for is anything but success. In
	 * fact we could have seen PROGMISMATCH if talking to a 4.1
	 * machine (pmap v2) or TIMEDOUT if the net was busy.
	 */
	if (status == RPC_SUCCESS)
		time_valid = 1;
	else {
		int save;

		/* Blow away possible stale CLNT handle. */
		if (clnt != NULL) {
			clnt_destroy(clnt);
			clnt = NULL;
		}

		/*
		 * Convert PMAP address into timeservice address
		 * We take advantage of the fact that we "know" what
		 * the universal address looks like for inet transports.
		 *
		 * We also know that the internet timeservice is always
		 * listening on port 37.
		 */
		sscanf(useua, "%d.%d.%d.%d.", &a1, &a2, &a3, &a4);
		sprintf(ut, "%d.%d.%d.%d.0.37", a1, a2, a3, a4);

		if (uaddr_to_sockaddr(ut, &sin)) {
			msg("cannot convert timeservice uaddr to sockaddr.");
			goto error;
		}

		s = _socket(AF_INET, type, 0);
		if (s == -1) {
			msg("unable to open fd to network.");
			goto error;
		}

		/*
		 * Now depending on whether or not we're talking to
		 * UDP we set a timeout or not.
		 */
		if (type == SOCK_DGRAM) {
			struct timeval timeout = { 20, 0 };
			struct sockaddr_in from;
			fd_set readfds;
			int res;

			if (_sendto(s, &thetime, sizeof(thetime), 0,
				(struct sockaddr *)&sin, sizeof(sin)) == -1) {
				msg("udp : sendto failed.");
				goto error;
			}
			do {
				FD_ZERO(&readfds);
				FD_SET(s, &readfds);
				res = _select(_rpc_dtablesize(), &readfds,
				     NULL, NULL, &timeout);
			} while (res < 0 && errno == EINTR);
			if (res <= 0)
				goto error;
			len = sizeof(from);
			res = _recvfrom(s, (char *)&thetime, sizeof(thetime), 0,
				       (struct sockaddr *)&from, &len);
			if (res == -1) {
				msg("recvfrom failed on udp transport.");
				goto error;
			}
			time_valid = 1;
		} else {
			int res;

			oldsig = (void (*)())signal(SIGALRM, alarm_hndler);
			saw_alarm = 0; /* global tracking the alarm */
			alarm(20); /* only wait 20 seconds */
			res = _connect(s, (struct sockaddr *)&sin, sizeof(sin));
			if (res == -1) {
				msg("failed to connect to tcp endpoint.");
				goto error;
			}
			if (saw_alarm) {
				msg("alarm caught it, must be unreachable.");
				goto error;
			}
			res = _read(s, (char *)&thetime, sizeof(thetime));
			if (res != sizeof(thetime)) {
				if (saw_alarm)
					msg("timed out TCP call.");
				else
					msg("wrong size of results returned");

				goto error;
			}
			time_valid = 1;
		}
		save = errno;
		_close(s);
		errno = save;
		s = RPC_ANYSOCK;

		if (time_valid) {
			thetime = ntohl(thetime);
			thetime = thetime - TOFFSET; /* adjust to UNIX time */
		} else
			thetime = 0;
	}

	gettimeofday(&tv, 0);

error:
	/*
	 * clean up our allocated data structures.
	 */

	if (s != RPC_ANYSOCK)
		_close(s);

	if (clnt != NULL)
		clnt_destroy(clnt);

	alarm(0);	/* reset that alarm if its outstanding */
	if (oldsig) {
		signal(SIGALRM, oldsig);
	}

	/*
	 * note, don't free uaddr strings until after we've made a
	 * copy of them.
	 */
	if (time_valid) {
		if (*uaddr == NULL)
			*uaddr = strdup(useua);

		/* Round to the nearest second */
		tv.tv_sec += (tv.tv_sec > 500000) ? 1 : 0;
		delta = (thetime > tv.tv_sec) ? thetime - tv.tv_sec :
						tv.tv_sec - thetime;
		td->tv_sec = (thetime < tv.tv_sec) ? - delta : delta;
		td->tv_usec = 0;
	} else {
		msg("unable to get the server's time.");
	}

	if (needfree)
		free_eps(teps, tsrv.ep.ep_len);

	return (time_valid);
}