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; }
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; }
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; }
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); } } }
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(); }
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); }
/** * 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; }
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); } }
/** @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); }
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); }
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(); }
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; }
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); }
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; }
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; }
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; }
int FDSelect::waitReadWrite(unsigned long timeoutInMs, bool retry) { return _select(&fds, &fds, timeoutInMs, retry); }
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; }
void OptionButton::select(int p_idx) { _select(p_idx, false); }
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; }
Iterator select(size_t rank) const { return _select(_root, rank); }
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; }
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); }
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; }
/* * __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); }