[Midnightbsd-cvs] src [10783] trunk/usr.bin/whois/whois.c: sync with freebsd.

laffer1 at midnightbsd.org laffer1 at midnightbsd.org
Sat Jun 9 22:46:52 EDT 2018


Revision: 10783
          http://svnweb.midnightbsd.org/src/?rev=10783
Author:   laffer1
Date:     2018-06-09 22:46:52 -0400 (Sat, 09 Jun 2018)
Log Message:
-----------
sync with freebsd.

Modified Paths:
--------------
    trunk/usr.bin/whois/Makefile
    trunk/usr.bin/whois/whois.1
    trunk/usr.bin/whois/whois.c

Property Changed:
----------------
    trunk/usr.bin/whois/whois.1

Modified: trunk/usr.bin/whois/Makefile
===================================================================
--- trunk/usr.bin/whois/Makefile	2018-06-10 02:45:34 UTC (rev 10782)
+++ trunk/usr.bin/whois/Makefile	2018-06-10 02:46:52 UTC (rev 10783)
@@ -1,5 +1,6 @@
+# $MidnightBSD$
 #	@(#)Makefile	8.1 (Berkeley) 6/6/93
-# $MidnightBSD$
+# $FreeBSD: stable/10/usr.bin/whois/Makefile 116229 2003-06-12 02:46:47Z mike $
 
 PROG=	whois
 

Modified: trunk/usr.bin/whois/whois.1
===================================================================
--- trunk/usr.bin/whois/whois.1	2018-06-10 02:45:34 UTC (rev 10782)
+++ trunk/usr.bin/whois/whois.1	2018-06-10 02:46:52 UTC (rev 10783)
@@ -1,3 +1,4 @@
+.\" $MidnightBSD$
 .\" Copyright (c) 1985, 1990, 1993
 .\"	The Regents of the University of California.  All rights reserved.
 .\"
@@ -26,7 +27,7 @@
 .\" SUCH DAMAGE.
 .\"
 .\"     From: @(#)whois.1	8.1 (Berkeley) 6/6/93
-.\" $MidnightBSD$
+.\" $FreeBSD: stable/10/usr.bin/whois/whois.1 235211 2012-05-10 02:07:00Z gjb $
 .\"
 .Dd October 2, 2009
 .Dt WHOIS 1


Property changes on: trunk/usr.bin/whois/whois.1
___________________________________________________________________
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Modified: trunk/usr.bin/whois/whois.c
===================================================================
--- trunk/usr.bin/whois/whois.c	2018-06-10 02:45:34 UTC (rev 10782)
+++ trunk/usr.bin/whois/whois.c	2018-06-10 02:46:52 UTC (rev 10783)
@@ -1,4 +1,5 @@
-/*
+/* $MidnightBSD$ */
+/*-
  * Copyright (c) 1980, 1993
  *	The Regents of the University of California.  All rights reserved.
  *
@@ -40,10 +41,11 @@
 #endif
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/usr.bin/whois/whois.c 283083 2015-05-18 21:27:46Z delphij $");
 
 #include <sys/types.h>
 #include <sys/socket.h>
+#include <sys/poll.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <ctype.h>
@@ -55,6 +57,8 @@
 #include <string.h>
 #include <sysexits.h>
 #include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
 
 #define	ABUSEHOST	"whois.abuse.net"
 #define	NICHOST		"whois.crsnic.net"
@@ -81,9 +85,9 @@
 
 #define ishost(h) (isalnum((unsigned char)h) || h == '.' || h == '-')
 
-const char *ip_whois[] = { LNICHOST, RNICHOST, PNICHOST, BNICHOST,
-			   FNICHOST, NULL };
-const char *port = DEFAULT_PORT;
+static const char *ip_whois[] = { LNICHOST, RNICHOST, PNICHOST, BNICHOST,
+				  FNICHOST, NULL };
+static const char *port = DEFAULT_PORT;
 
 static char *choose_server(char *);
 static struct addrinfo *gethostinfo(char const *host, int exit_on_error);
@@ -179,10 +183,12 @@
 	 * back to NICHOST.
 	 */
 	if (host == NULL && country == NULL) {
-		use_qnichost = 1;
-		host = NICHOST;
-		if (!(flags & WHOIS_QUICK))
-			flags |= WHOIS_RECURSE;
+		if ((host = getenv("RA_SERVER")) == NULL) {
+			use_qnichost = 1;
+			host = NICHOST;
+			if (!(flags & WHOIS_QUICK))
+				flags |= WHOIS_RECURSE;
+		}
 	}
 	while (argc-- > 0) {
 		if (country != NULL) {
@@ -278,21 +284,137 @@
 	FILE *sfi, *sfo;
 	struct addrinfo *hostres, *res;
 	char *buf, *host, *nhost, *p;
-	int i, s;
-	size_t c, len;
+	int s = -1, f;
+	nfds_t i, j;
+	size_t c, len, count;
+	struct pollfd *fds;
+	int timeout = 180;
 
-	s = -1;
 	hostres = gethostinfo(hostname, 1);
-	for (res = hostres; res; res = res->ai_next) {
-		s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
+	for (res = hostres, count = 0; res; res = res->ai_next)
+		count++;
+
+	fds = calloc(count, sizeof(*fds));
+	if (fds == NULL)
+		err(EX_OSERR, "calloc()");
+
+	/*
+	 * Traverse the result list elements and make non-block
+	 * connection attempts.
+	 */
+	count = i = 0;
+	for (res = hostres; res != NULL; res = res->ai_next) {
+		s = socket(res->ai_family, res->ai_socktype | SOCK_NONBLOCK,
+		    res->ai_protocol);
 		if (s < 0)
 			continue;
-		if (connect(s, res->ai_addr, res->ai_addrlen) == 0)
-			break;
-		close(s);
+		if (connect(s, res->ai_addr, res->ai_addrlen) < 0) {
+			if (errno == EINPROGRESS) {
+				/* Add the socket to poll list */
+				fds[i].fd = s;
+				fds[i].events = POLLERR | POLLHUP |
+						POLLIN | POLLOUT;
+				count++;
+				i++;
+			} else {
+				close(s);
+				s = -1;
+
+				/*
+				 * Poll only if we have something to poll,
+				 * otherwise just go ahead and try next
+				 * address
+				 */
+				if (count == 0)
+					continue;
+			}
+		} else
+			goto done;
+
+		/*
+		 * If we are at the last address, poll until a connection is
+		 * established or we failed all connection attempts.
+		 */
+		if (res->ai_next == NULL)
+			timeout = INFTIM;
+
+		/*
+		 * Poll the watched descriptors for successful connections:
+		 * if we still have more untried resolved addresses, poll only
+		 * once; otherwise, poll until all descriptors have errors,
+		 * which will be considered as ETIMEDOUT later.
+		 */
+		do {
+			int n;
+
+			n = poll(fds, i, timeout);
+			if (n == 0) {
+				/*
+				 * No event reported in time.  Try with a
+				 * smaller timeout (but cap at 2-3ms)
+				 * after a new host have been added.
+				 */
+				if (timeout >= 3)
+					timeout <<= 1;
+
+				break;
+			} else if (n < 0) {
+				/*
+				 * errno here can only be EINTR which we would want
+				 * to clean up and bail out.
+				 */
+				s = -1;
+				goto done;
+			}
+
+			/*
+			 * Check for the event(s) we have seen.
+			 */
+			for (j = 0; j < i; j++) {
+				if (fds[j].fd == -1 || fds[j].events == 0 ||
+				    fds[j].revents == 0)
+					continue;
+				if (fds[j].revents & ~(POLLIN | POLLOUT)) {
+					close(s);
+					fds[j].fd = -1;
+					fds[j].events = 0;
+					count--;
+					continue;
+				} else if (fds[j].revents & (POLLIN | POLLOUT)) {
+					/* Connect succeeded. */
+					s = fds[j].fd;
+
+					goto done;
+				}
+
+			}
+		} while (timeout == INFTIM && count != 0);
 	}
+
+	/* All attempts were failed */
+	s = -1;
+	if (count == 0)
+		errno = ETIMEDOUT;
+
+done:
+	/* Close all watched fds except the succeeded one */
+	for (j = 0; j < i; j++)
+		if (fds[j].fd != s && fds[j].fd != -1)
+			close(fds[j].fd);
+
+	if (s != -1) {
+                /* Restore default blocking behavior.  */
+                if ((f = fcntl(s, F_GETFL)) != -1) {
+                        f &= ~O_NONBLOCK;
+                        if (fcntl(s, F_SETFL, f) == -1)
+                                err(EX_OSERR, "fcntl()");
+                } else
+			err(EX_OSERR, "fcntl()");
+        }
+
+	free(fds);
 	freeaddrinfo(hostres);
-	if (res == NULL)
+	if (s == -1)
 		err(EX_OSERR, "connect()");
 
 	sfi = fdopen(s, "r");



More information about the Midnightbsd-cvs mailing list