summaryrefslogtreecommitdiff
path: root/whois.c
diff options
context:
space:
mode:
authorMarco d'Itri <md@linux.it>2019-06-28 01:38:17 +0200
committerMarco d'Itri <md@linux.it>2019-06-28 01:38:17 +0200
commitb49ba5ecc0f66dc53a7e1b0eb26d3a01da1c89e6 (patch)
tree28e20430705ea35e78d9e57d165ec1a93d621396 /whois.c
parenta0c0bf7144effbc90bdb8f782c8411c8604eeffc (diff)
downloadwhois-b49ba5ecc0f66dc53a7e1b0eb26d3a01da1c89e6.tar.gz
Implement -I to use referrals from whois.iana.org
Closes: #774603
Diffstat (limited to 'whois.c')
-rw-r--r--whois.c54
1 files changed, 53 insertions, 1 deletions
diff --git a/whois.c b/whois.c
index c5df6f4..608153b 100644
--- a/whois.c
+++ b/whois.c
@@ -159,7 +159,7 @@ int main(int argc, char *argv[])
argv = merge_args(getenv("WHOIS_OPTIONS"), argv, &argc);
while ((ch = GETOPT_LONGISH(argc, argv,
- "abBcdFg:Gh:Hi:KlLmMp:q:rRs:t:T:v:V:x",
+ "abBcdFg:Gh:Hi:IKlLmMp:q:rRs:t:T:v:V:x",
longopts, &longindex)) > 0) {
/* RIPE flags */
if (strchr(ripeflags, ch)) {
@@ -221,6 +221,9 @@ int main(int argc, char *argv[])
case 'H':
hide_discl = HIDE_NOT_STARTED; /* enable disclaimers hiding */
break;
+ case 'I':
+ server = strdup("\x0E");
+ break;
case 'p':
port = strdup(optarg);
break;
@@ -372,6 +375,13 @@ int handle_query(const char *hserver, const char *hport,
server = guess_server(p);
free(p);
goto retry;
+ case 0x0E:
+ if (verb)
+ printf(_("Using server %s.\n"), "whois.iana.org");
+ sockfd = openconn("whois.iana.org", NULL);
+ free(server);
+ server = query_iana(sockfd, query);
+ break;
default:
break;
}
@@ -921,6 +931,47 @@ char *query_afilias(const int sock, const char *query)
return referral_server;
}
+char *query_iana(const int sock, const char *query)
+{
+ char *temp, *p, buf[2000];
+ FILE *fi;
+ char *referral_server = NULL;
+ int state = 0;
+
+ temp = malloc(strlen(query) + 2 + 1);
+ strcpy(temp, query);
+ strcat(temp, "\r\n");
+
+ fi = fdopen(sock, "r");
+ if (write(sock, temp, strlen(temp)) < 0)
+ err_sys("write");
+ free(temp);
+
+ while (fgets(buf, sizeof(buf), fi)) {
+ /* If multiple attributes are returned then use the first result.
+ This is not supposed to happen. */
+ if (state == 0 && strneq(buf, "refer:", 6)) {
+ for (p = buf; *p != ':'; p++); /* skip until colon */
+ for (p++; *p == ' '; p++); /* skip colon and spaces */
+ referral_server = strdup(p);
+ if ((p = strpbrk(referral_server, "\r\n ")))
+ *p = '\0';
+ state = 2;
+ }
+
+ if ((p = strpbrk(buf, "\r\n")))
+ *p = '\0';
+ recode_fputs(buf, stdout);
+ fputc('\n', stdout);
+ }
+
+ if (ferror(fi))
+ err_sys("fgets");
+ fclose(fi);
+
+ return referral_server;
+}
+
int openconn(const char *server, const char *port)
{
int fd = -1;
@@ -1437,6 +1488,7 @@ void NORETURN usage(int error)
"Usage: whois [OPTION]... OBJECT...\n\n"
"-h HOST, --host HOST connect to server HOST\n"
"-p PORT, --port PORT connect to PORT\n"
+"-I query whois.iana.org and follow its referral\n"
"-H hide legal disclaimers\n"
));
fprintf((EXIT_SUCCESS == error) ? stdout : stderr, _(