summaryrefslogtreecommitdiff
path: root/whois.c
diff options
context:
space:
mode:
authorMarco d'Itri <md@linux.it>2001-10-17 20:57:26 +0200
committerMarco d'Itri <md@linux.it>2013-03-30 02:31:28 +0100
commit1b665ec34c3e6d7e1ed3df15d29740c5327f7cc1 (patch)
tree404c54c05a6b97b36cb8338c0888ca1af9bd80e6 /whois.c
parenta8b3b04bf490c419c3be5d55fd26e092edccfb8f (diff)
downloadwhois-1b665ec34c3e6d7e1ed3df15d29740c5327f7cc1.tar.gz
Imported Debian version 4.5.14v4.5.14
Diffstat (limited to 'whois.c')
-rw-r--r--whois.c137
1 files changed, 119 insertions, 18 deletions
diff --git a/whois.c b/whois.c
index ab7d159..70cbc23 100644
--- a/whois.c
+++ b/whois.c
@@ -14,6 +14,9 @@
#ifdef HAVE_GETOPT_LONG
#include <getopt.h>
#endif
+#ifdef HAVE_REGEXEC
+#include <regex.h>
+#endif
#include <string.h>
#include <ctype.h>
#include <sys/types.h>
@@ -23,6 +26,8 @@
#include <errno.h>
#include <signal.h>
+#undef ENABLE_NLS
+
/* Application-specific */
#include "data.h"
#include "whois.h"
@@ -67,12 +72,12 @@ int main(int argc, char *argv[])
longopts, 0)) > 0) {
/* RIPE flags */
if (strchr(ripeflags, ch)) {
- for (p = fstring; *p != '\0'; p++);
+ for (p = fstring; *p; p++);
sprintf(p--, "-%c ", ch);
continue;
}
if (strchr(ripeflagsp, ch)) {
- for (p = fstring; *p != '\0'; p++);
+ for (p = fstring; *p; p++);
sprintf(p--, "-%c %s ", ch, optarg);
if (ch == 't' || ch == 'v' || ch == 'q')
nopar = 1;
@@ -82,7 +87,7 @@ int main(int argc, char *argv[])
switch (ch) {
case 'h':
server = q = malloc(strlen(optarg) + 1);
- for (p = optarg; *p != '\0' && *p != ':'; *q++ = tolower(*p++));
+ for (p = optarg; *p && *p != ':'; *q++ = tolower(*p++));
if (*p == ':')
port = p + 1;
*q = '\0';
@@ -133,8 +138,23 @@ int main(int argc, char *argv[])
}
}
+ /* -v or -t has been used */
+ if (!server && !*qstring)
+ server = "whois.ripe.net";
+
+#ifdef CONFIG_FILE
if (!server) {
- server = whichwhois(qstring);
+ server = match_config_file(qstring);
+ if (verb && server)
+ printf(_("Using server %s.\n"), server);
+ }
+#endif
+
+ if (!server) {
+ char *p;
+ p = normalize_domain(qstring);
+ server = whichwhois(p);
+ free(p);
switch (server[0]) {
case 0:
if (!(server = getenv("WHOIS_SERVER")))
@@ -180,20 +200,86 @@ int main(int argc, char *argv[])
sockfd = openconn(server, port);
do_query(sockfd, p);
- closeconn(sockfd);
exit(0);
}
+#ifdef CONFIG_FILE
+const char *match_config_file(const char *s)
+{
+ FILE *fp;
+ char buf[512];
+ static const char delim[] = " \t";
+#ifdef HAVE_REGEXEC
+ regex_t re;
+#endif
+
+ if ((fp = fopen(CONFIG_FILE, "r")) == NULL) {
+ if (errno != ENOENT)
+ err_sys("Cannot open " CONFIG_FILE);
+ return NULL;
+ }
+
+ while (fgets(buf, sizeof(buf), fp) != NULL) {
+ char *p;
+ const char *pattern, *server;
+#ifdef HAVE_REGEXEC
+ int i;
+#endif
+
+ for (p = buf; *p; p++)
+ if (*p == '\n')
+ *p = '\0';
+
+ p = buf;
+ while (*p == ' ' || *p == '\t') /* eat leading blanks */
+ p++;
+ if (!*p)
+ continue; /* skip empty lines */
+ if (*p == '#')
+ continue; /* skip comments */
+
+ pattern = strtok(p, delim);
+ server = strtok(NULL, delim);
+ if (!pattern || !server)
+ err_quit(_("Cannot parse this line: %s"), p);
+ p = strtok(NULL, delim);
+ if (p)
+ err_quit(_("Cannot parse this line: %s"), p);
+
+#ifdef HAVE_REGEXEC
+ i = regcomp(&re, pattern, REG_EXTENDED|REG_ICASE|REG_NOSUB);
+ if (i != 0) {
+ char m[1024];
+ regerror(i, &re, m, sizeof(m));
+ err_quit("Invalid regular expression '%s': %s", pattern, m);
+ }
+
+ i = regexec(&re, s, 0, NULL, 0);
+ if (i == 0) {
+ regfree(&re);
+ return strdup(server);
+ }
+ if (i != REG_NOMATCH) {
+ char m[1024];
+ regerror(i, &re, m, sizeof(m));
+ err_quit("regexec: %s", m);
+ }
+ regfree(&re);
+#else
+ if (domcmp(s, pattern))
+ return strdup(server);
+#endif
+ }
+ return NULL;
+}
+#endif
+
const char *whichwhois(const char *s)
{
unsigned long ip;
unsigned int i;
- /* -v or -t has been used */
- if (*s == '\0')
- return "whois.ripe.net";
-
/* IPv6 address */
if (strchr(s, ':')) {
if (strncasecmp(s, "2001:2", 6) == 0) /* XXX ugly hack! */
@@ -214,7 +300,7 @@ const char *whichwhois(const char *s)
if (!strpbrk(s, ".-")) {
const char *p;
- for (p = s; *p != '\0'; p++); /* go to the end of s */
+ for (p = s; *p; p++); /* go to the end of s */
if (strncasecmp(s, "as", 2) == 0 && /* it's an AS */
((s[2] >= '0' && s[2] <= '9') || s[2] == ' '))
return whereas(atoi(s + 2), as_assign);
@@ -265,7 +351,7 @@ const char *whereas(int asn, struct as_del aslist[])
{
int i;
- if (asn > 16383)
+ if (asn > 23551)
puts(_("Unknown AS number. Please upgrade this program."));
for (i = 0; aslist[i].serv; i++)
if (asn >= aslist[i].first && asn <= aslist[i].last)
@@ -294,7 +380,7 @@ char *queryformat(const char *server, const char *flags, const char *query)
isripe = 1;
break;
}
- if (*flags != '\0') {
+ if (*flags) {
if (!isripe && strcmp(server, "whois.corenic.net") != 0)
puts(_("Warning: RIPE flags ignored for a traditional server."));
else
@@ -364,7 +450,6 @@ void do_query(const int sock, const char *query)
strcat(nq, "\r\n");
fd = openconn(nh, np);
do_query(fd, nq);
- closeconn(fd);
continue;
}
}
@@ -375,6 +460,7 @@ void do_query(const int sock, const char *query)
}
if (ferror(fi))
err_sys("fgets");
+ fclose(fi);
if (hide == 1)
err_quit(_("Catastrophic error: disclaimer text has been changed.\n"
@@ -385,6 +471,7 @@ const char *query_crsnic(const int sock, const char *query)
{
char *temp, buf[2000], *ret = NULL;
FILE *fi;
+ int state = 0;
temp = malloc(strlen(query) + 1 + 2 + 1);
*temp = '=';
@@ -397,7 +484,9 @@ const char *query_crsnic(const int sock, const char *query)
while (fgets(buf, sizeof(buf), fi)) {
/* If there are multiple matches only the server of the first record
is queried */
- if (strncmp(buf, " Whois Server:", 16) == 0 && !ret) {
+ if (state == 0 && strncmp(buf, " Domain Name:", 15) == 0)
+ state = 1;
+ if (state == 1 && strncmp(buf, " Whois Server:", 16) == 0) {
char *p, *q;
for (p = buf; *p != ':'; p++); /* skip until colon */
@@ -405,6 +494,7 @@ const char *query_crsnic(const int sock, const char *query)
ret = malloc(strlen(p) + 1);
for (q = ret; *p != '\n' && *p != '\r'; *q++ = *p++); /*copy data*/
*q = '\0';
+ state = 2;
}
fputs(buf, stdout);
}
@@ -463,7 +553,7 @@ int openconn(const char *server, const char *port)
if (connect(fd, (struct sockaddr *)&saddr, sizeof(saddr)) < 0)
err_sys("connect");
#endif
- return (fd);
+ return fd;
}
void closeconn(const int fd)
@@ -482,16 +572,27 @@ int domcmp(const char *dom, const char *tld)
{
const char *p, *q;
- for (p = dom; *p != '\0'; p++); p--; /* move to the last char */
- for (q = tld; *q != '\0'; q++); q--;
+ for (p = dom; *p; p++); p--; /* move to the last char */
+ for (q = tld; *q; q++); q--;
while (p >= dom && q >= tld && tolower(*p) == *q) { /* compare backwards */
- if (q == tld) /* start of the second word? */
+ if (q == tld) /* start of the second word? */
return 1;
p--; q--;
}
return 0;
}
+char *normalize_domain(const char *dom)
+{
+ char *p, *ret;
+
+ ret = strdup(dom);
+ for (p = ret; *p; p++); p--; /* move to the last char */
+ for (; *p == '.' || p == ret; p--) /* eat trailing dots */
+ *p = '\0';
+ return ret;
+}
+
unsigned long myinet_aton(const char *s)
{
int a, b, c, d;