tech-misc archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

fix whois recursion



Whois recursion is not working as it should.
The problem is that the whois client is looking for "Whois Server:" but
many registrars have "WHOIS server:" due to a change in policy from
ICANN so the whois client won't find that and only show data from the
first whois server. Attached is a diff that fixes this plus it uses a
linked list to see what servers have been connected to previously and
stops recursion if the one its going to connect to has already been
connected to. Since it checks for loops WHOIS_RECURSE is set every time
and not just the first time whois is called with WHOIS_RECURSE.
ok to commit this?

Niclas Rosenvik
--- whois.c.orig	2019-09-29 12:47:48.832789132 +0000
+++ whois.c	2019-10-30 08:33:25.547150346 +0000
@@ -77,7 +77,7 @@
 #define	SNICHOST	"whois.6bone.net"
 
 #define	WHOIS_PORT	"whois"
-#define	WHOIS_SERVER_ID	"Whois Server:"
+#define	WHOIS_SERVER_ID	"whois server:"
 
 #define WHOIS_RECURSE		0x01
 #define WHOIS_QUICK		0x02
@@ -86,15 +86,22 @@
 static const char *ip_whois[] =
     { LNICHOST, RNICHOST, PNICHOST, FNICHOST, BNICHOST, NULL };
 
+typedef struct whoishost {
+	struct whoishost *prev;
+	const char *server;
+} whoishost;
+
 static void usage(void) __dead;
-static int whois(const char *, const char *, const char *, int);
+static int whois(const char *, const char *, const char *, whoishost *, int);
 static const char *choose_server(const char *, const char *);
+static int find_previous_server(const char *, whoishost *);
 
 int
 main(int argc, char *argv[])
 {
 	int ch, flags, rval;
 	const char *host, *name, *country;
+	whoishost wh;
 
 #ifdef SOCKS
 	SOCKSinit(argv[0]);
@@ -162,14 +169,16 @@
 
 	if (host == NULL && country == NULL && !(flags & WHOIS_QUICK))
 		flags |= WHOIS_RECURSE;
-	for (name = *argv; (name = *argv) != NULL; argv++)
-		rval += whois(name, host ? host : choose_server(name, country),
-		    port_whois, flags);
+	for (name = *argv; (name = *argv) != NULL; argv++) {
+	  	wh.prev = NULL;
+		wh.server = host ? host : choose_server(name, country);
+		rval += whois(name, wh.server, port_whois, &wh, flags);
+	}
 	return rval;
 }
 
 static int
-whois(const char *query, const char *server, const char *port, int flags)
+whois(const char *query, const char *server, const char *port, whoishost *wh, int flags)
 {
 	FILE *sfi, *sfo;
 	char *buf, *p, *nhost, *nbuf = NULL;
@@ -177,6 +186,7 @@
 	int i, s, error;
 	const char *reason = NULL, *fmt;
 	struct addrinfo hints, *res, *ai;
+	whoishost whs;
 
 	(void)memset(&hints, 0, sizeof(hints));
 	hints.ai_flags = 0;
@@ -245,6 +255,9 @@
 		if (nhost != NULL || !(flags & WHOIS_RECURSE))
 			continue;
 
+		for (p = buf; *p != '\0'; p++)
+			*p = tolower((unsigned char)*p);
+
 		if ((p = strstr(buf, WHOIS_SERVER_ID))) {
 			p += sizeof(WHOIS_SERVER_ID) - 1;
 			while (isblank((unsigned char)*p))
@@ -256,8 +269,6 @@
 				nhost[len] = '\0';
 			}
 		} else if (strcmp(server, ANICHOST) == 0) {
-			for (p = buf; *p != '\0'; p++)
-				*p = tolower((unsigned char)*p);
 			for (i = 0; ip_whois[i] != NULL; i++) {
 				if (strstr(buf, ip_whois[i]) != NULL) {
 					nhost = strdup(ip_whois[i]);
@@ -272,7 +283,11 @@
 		free(nbuf);
 
 	if (nhost != NULL) {
-		error = whois(query, nhost, port, 0);
+		if (find_previous_server(nhost, wh)) {
+		    whs.prev = wh;
+		    whs.server = nhost;
+		    error = whois(query, nhost, port, &whs, WHOIS_RECURSE);
+		}
 		free(nhost);
 	}
 	freeaddrinfo(res);
@@ -319,6 +334,16 @@
 	return (server);
 }
 
+static int
+find_previous_server(const char *server, whoishost *wh)
+{
+	if (wh == NULL)
+		return 1;
+	if (strcmp(server, wh->server))
+		return find_previous_server(server, wh->prev);
+	return 0;
+}
+
 static void
 usage(void)
 {


Home | Main Index | Thread Index | Old Index