summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile29
-rw-r--r--README32
-rw-r--r--TODO5
-rw-r--r--config.h11
-rw-r--r--data.h46
-rw-r--r--debian/changelog36
-rw-r--r--debian/control18
-rw-r--r--debian/copyright7
-rwxr-xr-xdebian/rules46
-rw-r--r--ip_del_list45
-rwxr-xr-xmake_ip_del.pl22
-rwxr-xr-xmake_tld_serv.pl13
-rw-r--r--mkpasswd.120
-rw-r--r--mkpasswd.c21
-rw-r--r--po/Makefile50
-rw-r--r--po/it.po146
-rw-r--r--tld_serv_list119
-rw-r--r--whois.190
-rw-r--r--whois.c424
-rw-r--r--whois.h73
20 files changed, 1253 insertions, 0 deletions
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..35bccca
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,29 @@
+OPTS=-O2
+
+all: whois #pos
+
+whois: whois.c whois.h config.h data.h ip_del.h tld_serv.h
+ $(CC) $(OPTS) whois.c -o whois
+
+mkpasswd:
+ $(CC) $(OPTS) mkpasswd.c -o mkpasswd -lcrypt
+
+ip_del.h: ip_del_list make_ip_del.pl
+ ./make_ip_del.pl < ip_del_list > ip_del.h
+
+tld_serv.h: tld_serv_list make_tld_serv.pl
+ ./make_tld_serv.pl < tld_serv_list > tld_serv.h
+
+distclean: clean
+ rm -f po/whois.pot
+
+clean:
+ rm -f tld_serv.h ip_del.h whois mkpasswd
+ rm -f po/*.mo
+
+test:
+ open -- sh -c "while nc -l -p 43 127.0.0.1; do echo END; done"
+
+pos:
+ cd po && $(MAKE)
+
diff --git a/README b/README
new file mode 100644
index 0000000..361e58f
--- /dev/null
+++ b/README
@@ -0,0 +1,32 @@
+Why another whois client? Because the ripe client is a mess of hacks and
+#ifdefs and more complex programs lack features or are bloated.
+
+Notes on the data files:
+- domain names MUST be lowercase and MUST begin with "." or "-".
+- first match wins (for both domains and netblocks)
+- elements in tld_serv_list are matched against the end of the query
+
+
+Delegation data has been gathered by me.
+TLD whois data has been borrowed from various sources, mostly the whois
+proxy at www.geektools.org and the awhois script by Greg Woods.
+
+Please send me any information you have regarding domains and netblocks
+not correctly handled by the program.
+
+Please also try to compile after defining HAVE_GETADDRINFO and send me
+working #defines for your flavour of UNIX.
+
+The home of the program is http://www.linux.it/~md/software/
+
+
+Other information sources:
+- RIPE-187 and RIPE-189 (from ftp://ftp.ripe.net/ripe/docs/ or
+ http://www.ripe.net/docs/)
+- Greg Woods' awhois script (from ftp.weird.com)
+- home of the 6bone client: http://www.ip.qwest.net/~david/software/
+
+
+Marco d'Itri
+<md@linux.it>
+
diff --git a/TODO b/TODO
new file mode 100644
index 0000000..9790dbd
--- /dev/null
+++ b/TODO
@@ -0,0 +1,5 @@
+Still to sort:
+*NETBLK-RIPE* *NET-RIPE* *APNIC* *AUNIC-AU* [a-z][a-z][0-9][0-9][0-9]jp
+
+Is MNT-* a standard of some registry?
+
diff --git a/config.h b/config.h
new file mode 100644
index 0000000..1addf97
--- /dev/null
+++ b/config.h
@@ -0,0 +1,11 @@
+/* Configurable features */
+
+/* 6bone referto: support */
+#define EXT_6BONE
+
+/* Suppress lame Internic disclaimer */
+#define HIDE_DISCL
+
+/* program version */
+#define VERSION "4.3"
+
diff --git a/data.h b/data.h
new file mode 100644
index 0000000..8ff202e
--- /dev/null
+++ b/data.h
@@ -0,0 +1,46 @@
+const char *ripeflags="acFLmMrRS";
+const char *ripeflagsp="gisTtv";
+
+const char *ripe_servers[] = {
+ "whois.ripe.net",
+ "whois.ra.net",
+ "whois.apnic.net",
+ "whois.mci.net",
+ "whois.isi.edu",
+ "whois.nic.it",
+ "whois.6bone.net",
+ "whois.ans.net",
+ NULL
+};
+
+const char *gtlds[] = {
+ ".com",
+ ".net",
+ ".org",
+ ".edu",
+ NULL
+};
+
+const char *arin_nets[] = {
+ "net-",
+ "netblk-",
+ "asn-",
+ NULL,
+};
+
+struct ip_del {
+ unsigned long int net;
+ unsigned long int mask;
+ const char *serv;
+};
+
+struct ip_del ip_assign[] = {
+#include "ip_del.h"
+ { 0, 0, NULL }
+};
+
+const char *tld_serv[] = {
+#include "tld_serv.h"
+ NULL, NULL
+};
+
diff --git a/debian/changelog b/debian/changelog
new file mode 100644
index 0000000..c6dc8cd
--- /dev/null
+++ b/debian/changelog
@@ -0,0 +1,36 @@
+whois (4.3.1) unstable; urgency=low
+
+ * CRSNIC code parsed the wrong field (closes: #48590).
+
+ -- Marco d'Itri <md@linux.it> Thu, 28 Oct 1999 22:21:55 +0200
+
+whois (4.3) unstable; urgency=low
+
+ * Corrected CRSNIC server hostname (closes: #48197).
+ * Updated delegation lists.
+
+ -- Marco d'Itri <md@linux.it> Tue, 26 Oct 1999 11:43:38 +0200
+
+whois (4.2) unstable; urgency=low
+
+ * Added support for the CRSNIC registry of GTLDs.
+
+ -- Marco d'Itri <md@linux.it> Wed, 20 Oct 1999 20:19:06 +0200
+
+whois (4.1) unstable; urgency=low
+
+ * Fixed $LANG parsing (closes: #47233).
+
+ -- Marco d'Itri <md@linux.it> Thu, 14 Oct 1999 22:23:13 +0200
+
+whois (4.0) unstable; urgency=low
+
+ * Initial Release of the new code: I rewrote the program from scratch.
+ * cryptpw become mkpasswd and now has a man page (closes: #46855).
+
+ -- Marco d'Itri <md@linux.it> Sun, 3 Oct 1999 19:43:35 +0200
+
+Local variables:
+mode: debian-changelog
+add-log-mailing-address: "md@linux.it"
+End:
diff --git a/debian/control b/debian/control
new file mode 100644
index 0000000..c991cf7
--- /dev/null
+++ b/debian/control
@@ -0,0 +1,18 @@
+Source: whois
+Section: net
+Priority: important
+Maintainer: Marco d'Itri <md@linux.it>
+Standards-Version: 3.0.1
+
+Package: whois
+Architecture: any
+Depends: ${shlibs:Depends}
+Replaces: bsdmainutils (<= 4.5.1), bsdutils (<< 3.0-0)
+Description: whois client
+ This is a new whois (RFC 954) client rewritten from scratch by me.
+ It is derived from and compatible with the usual BSD and RIPE whois(1)
+ programs.
+ It is intelligent and can automatically select the appropriate whois
+ server for most queries.
+ .
+ The package also contains mkpasswd, a simple front end to crypt(3).
diff --git a/debian/copyright b/debian/copyright
new file mode 100644
index 0000000..f4406bd
--- /dev/null
+++ b/debian/copyright
@@ -0,0 +1,7 @@
+This package was debianized by Marco d'Itri <md@linux.it> on
+Sun Oct 3 19:46:30 CEST 1999.
+
+It was written by Marco d'Itri.
+
+Copyright: GPL.
+
diff --git a/debian/rules b/debian/rules
new file mode 100755
index 0000000..3dd1cb4
--- /dev/null
+++ b/debian/rules
@@ -0,0 +1,46 @@
+#!/usr/bin/make -f
+# Original version Copyright by Ian Jackson.
+
+SHELL+= -e
+
+#export DH_VERBOSE=1
+
+build:
+ $(checkdir)
+ make whois mkpasswd OPTS="-O2 -g"
+ touch build
+
+clean:
+ $(checkdir)
+ -rm -f build
+ -make distclean
+ -cd debian && rm -rf tmp files* substvars *debhelper
+
+binary-arch: checkroot build
+ $(checkdir)
+ -rm -rf debian/tmp
+
+ dh_installdirs usr/bin
+ install whois mkpasswd debian/tmp/usr/bin/
+ cd po && make install BASEDIR=../debian/tmp
+ dh_installmanpages
+ dh_installdocs README TODO
+ dh_installchangelogs
+ dh_strip
+ dh_compress
+ dh_fixperms
+ dh_shlibdeps
+ dh_gencontrol
+ dh_installdeb
+ dh_builddeb
+
+define checkdir
+ test -f debian/rules
+endef
+
+binary: binary-arch
+
+checkroot:
+ test root = "`whoami`"
+
+.PHONY: binary binary-arch binary-indep clean checkroot
diff --git a/ip_del_list b/ip_del_list
new file mode 100644
index 0000000..2246596
--- /dev/null
+++ b/ip_del_list
@@ -0,0 +1,45 @@
+24.192.0.0/14 apnic
+24.132.0.0/14 ripe
+61.0.0.0/8 apnic
+62.0.0.0/8 ripe
+0.0.0.0/2 arin # all other A classes are managed by ARIN
+## The B class space is a mess :-(
+#? 139. 20-29
+145.224.0.0/12 ripe
+141.0.0.0/10 ripe
+141.64.0.0/11 ripe # unsure
+149.192.0.0/10 ripe # unsure
+#? 149. 202-251
+150.254.0.0/16 ripe
+151.0.0.0/8 ripe
+160.216.0.0/14 ripe
+160.220.0.0/8 ripe
+163.128.0.0/12 ripe
+164.40.0.0/16 ripe
+164.0.0.0/6 ripe
+169.208.0.0/12 apnic
+171.16.0.0/12 ripe
+## The C class space is cleanly delegated and the data here should be complete
+192.71.0.0/16 ripe
+192.72.1.1/24 arin
+192.72.1.2/24 arin
+192.72.1.253/24 arin
+192.72.1.254/24 arin
+192.72.0.0/16 whois.seed.net.tw # NETBLK-SEED-NETS
+192.106.144.0/20 ripe
+192.162.0.0/16 ripe
+192.164.0.0/14 ripe
+192.0.0.0/8 arin # the swamp
+193.0.0.0/8 ripe
+194.0.0.0/7 ripe
+196.0.0.0/6 arin
+200.0.0.0/7 arin
+203.0.0.0/10 aunic
+202.0.0.0/7 apnic
+204.0.0.0/6 arin
+208.0.0.0/7 arin
+210.0.0.0/7 apnic
+212.0.0.0/7 ripe
+214.0.0.0/7 arin # DoD
+216.0.0.0/8 arin
+## Are class D networks listed somewhere?
diff --git a/make_ip_del.pl b/make_ip_del.pl
new file mode 100755
index 0000000..91ca390
--- /dev/null
+++ b/make_ip_del.pl
@@ -0,0 +1,22 @@
+#!/usr/bin/perl -w
+
+use strict;
+
+while (<>) {
+ chomp;
+ s/^\s*(.*)\s*$/$1/;
+ s/\s*#.*$//;
+ next if /^$/;
+ die "format error: $_" unless (/^([\d\.]+)\/(\d+)\s+([\w\.]+)$/);
+ my $m=$2; my $s=$3;
+ my ($i1, $i2, $i3, $i4)=split(/\./, $1);
+ print "{ ".(($i1<<24)+($i2<<16)+($i3<<8)+$i4)."UL, ".
+ (~(0xffffffff>>$m))."UL, \"";
+ if ($s =~ /\./) {
+ print "$s";
+ } else {
+ print "whois.$s.net";
+ }
+ print "\" },\n";
+}
+
diff --git a/make_tld_serv.pl b/make_tld_serv.pl
new file mode 100755
index 0000000..8e76ce3
--- /dev/null
+++ b/make_tld_serv.pl
@@ -0,0 +1,13 @@
+#!/usr/bin/perl -w
+
+use strict;
+
+while (<>) {
+ chomp;
+ s/^\s*(.*)\s*$/$1/;
+ s/\s*#.*$//;
+ next if /^$/;
+ die "format error: $_" unless (/^([\w\d\.-]+)\s+([\w\d\.-]+)$/);
+ print " \"$1\",\t\"$2\",\n";
+}
+
diff --git a/mkpasswd.1 b/mkpasswd.1
new file mode 100644
index 0000000..05aadab
--- /dev/null
+++ b/mkpasswd.1
@@ -0,0 +1,20 @@
+.TH WHOIS 1 "7 October 1999" "Marco d'Itri" "Debian GNU/Linux"
+.SH NAME
+mkpasswd \- Very dumb front end to crypt(3)
+.SH SYNOPSIS
+.B mkpasswd
+.BR PASSWORD
+.BR SALT
+.PP
+.SH DESCRIPTION
+.B mkpasswd
+encrypts the given password with the
+.BR crypt(3)
+libc function using the given salt.
+.SH "SEE ALSO"
+.IR crypt(3)
+.SH AUTHOR
+.B mkpasswd
+and this man page were written by Marco d'Itri <md@linux.it>
+and put in the public domain.
+
diff --git a/mkpasswd.c b/mkpasswd.c
new file mode 100644
index 0000000..86be388
--- /dev/null
+++ b/mkpasswd.c
@@ -0,0 +1,21 @@
+/* mkpasswd.c - written by Marco d'Itri <md@linux.it>, 1999/10/3.
+ * Silly little program for encrypting passwords
+ * It is so dumb that I will just place it in the public domain
+ */
+
+#define _XOPEN_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+int main(int argc, char *argv[])
+{
+ if (argc != 3) {
+ puts("Usage: mkpasswd PASSWORD SALT\n");
+ exit(1);
+ }
+ printf("%s", crypt(argv[1], argv[2]));
+ exit(0);
+}
+
diff --git a/po/Makefile b/po/Makefile
new file mode 100644
index 0000000..b903022
--- /dev/null
+++ b/po/Makefile
@@ -0,0 +1,50 @@
+INSTALL= /usr/bin/install -c
+INSTALLNLSDIR=$(BASEDIR)/usr/share/locale
+
+PACKAGE = whois
+
+CATALOGS = it.mo
+
+POTFILES=../whois.c
+
+all: $(PACKAGE).pot $(CATALOGS)
+
+$(PACKAGE).pot: $(POTFILES)
+ xgettext --default-domain=$(PACKAGE) \
+ --add-comments --keyword=_ --keyword=N_ $(POTFILES)
+ if cmp -s $(PACKAGE).po $(PACKAGE).pot; then \
+ rm -f $(PACKAGE).po; \
+ else \
+ mv $(PACKAGE).po $(PACKAGE).pot; \
+ fi
+
+update-po: $(PACKAGE).pot
+ for cat in $(CATALOGS); do \
+ lang=`echo $$cat | sed 's/.mo$$//'`; \
+ mv $$lang.po $$lang.old.po; \
+ echo "$$lang:"; \
+ if msgmerge $$lang.old.po $(PACKAGE).pot -o $$lang.po; then \
+ rm -f $$lang.old.po; \
+ else \
+ echo "msgmerge for $$cat failed!"; \
+ rm -f $$lang.po; mv $$lang.old.po $$lang.po; \
+ fi; \
+ done
+
+%.mo: %.po
+ msgfmt --statistics --check --verbose --output-file=$@ $<
+
+clean:
+ rm -f *.mo
+
+distclean: clean
+ rm -f whois.pot
+
+install: $(CATALOGS)
+ for n in $(CATALOGS); do \
+ l=`basename $$n .mo`; \
+ $(INSTALL) -m 755 -d $(INSTALLNLSDIR)/$$l; \
+ $(INSTALL) -m 755 -d $(INSTALLNLSDIR)/$$l/LC_MESSAGES; \
+ $(INSTALL) -m 644 $$n $(INSTALLNLSDIR)/$$l/LC_MESSAGES/$(PACKAGE).mo; \
+ done
+
diff --git a/po/it.po b/po/it.po
new file mode 100644
index 0000000..560eeb1
--- /dev/null
+++ b/po/it.po
@@ -0,0 +1,146 @@
+# Traduzione di whois.pot.
+# Copyright (C) 1999 Marco d'Itri
+# Marco d'Itri <md@linux.it>, 1999.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: whois 3.0\n"
+"POT-Creation-Date: 1999-10-26 12:19+0200\n"
+"PO-Revision-Date: 1999-10-26 12:19+02:00\n"
+"Last-Translator: Marco d'Itri <md@linux.it>\n"
+"Language-Team: Italian <it@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=iso-8859-1\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: ../whois.c:95
+msgid "Connecting to whois.crsnic.net.\n"
+msgstr "Mi sto connettendo a whois.crsnic.net.\n"
+
+#: ../whois.c:103
+#, c-format
+msgid ""
+"\n"
+"Detected CRSNIC referral to %s.\n"
+"\n"
+msgstr ""
+"\n"
+"Trovato un riferimento CRSNIC a %s.\n"
+"\n"
+
+#: ../whois.c:113
+#, c-format
+msgid "Using default server %s.\n"
+msgstr "Uso il server predefinito %s.\n"
+
+#: ../whois.c:115
+#, c-format
+msgid "Using server %s.\n"
+msgstr "Uso il server %s.\n"
+
+#: ../whois.c:120
+#, c-format
+msgid ""
+"Query string: \"%s\"\n"
+"\n"
+msgstr ""
+"Richiesta: \"%s\"\n"
+"\n"
+
+#: ../whois.c:156
+msgid ""
+"I don't know where this IP has been delegated.\n"
+"I'll try ARIN and hope for the best...\n"
+msgstr ""
+"Non so a chi è stato delegato questo IP.\n"
+"Proverò con ARIN sperando per il meglio...\n"
+
+#: ../whois.c:173
+msgid "I guess it's a netblock name but I don't know where to look it up.\n"
+msgstr "Credo che sia il nome di un netblock ma non so dove cercarlo.\n"
+
+#: ../whois.c:180
+msgid "I guess it's a domain but I don't know where to look it up.\n"
+msgstr "Credo che sia un dominio ma non so dove cercarlo.\n"
+
+#: ../whois.c:239
+#, c-format
+msgid "Detected referral to %s on %s.\n"
+msgstr "Trovato un riferimento a %s su %s.\n"
+
+#: ../whois.c:252
+msgid ""
+"Catastrophic error: INTERNIC changed the disclaimer text.\n"
+"Please upgrade this program.\n"
+msgstr ""
+"Errore catastrofico: INTERNIC ha cambiato il testo di avvertenze.\n"
+"Aggiorna questo programma.\n"
+
+#: ../whois.c:313
+#, c-format
+msgid "Host %s not found."
+msgstr "Host %s non trovato."
+
+#: ../whois.c:322
+#, c-format
+msgid "%s/tcp: unknown service"
+msgstr "%s/tcp: servizio sconosciuto"
+
+#: ../whois.c:339
+#, c-format
+msgid "Interrupted by signal %d..."
+msgstr "Interrotto dal segnale %d..."
+
+#: ../whois.c:379
+msgid ""
+"Usage: whois [OPTION]... OBJECT...\n"
+"\n"
+"-a search all databases\n"
+"-C first query CRSNIC to find GTLD registrar\n"
+"-F fast raw output (implies -r)\n"
+"-g SOURCE:FIRST-LAST find updates from SOURCE from serial FIRST to LAST\n"
+"-h HOST connect to server HOST\n"
+"-i ATTR[,ATTR]... do an inverse lookup for specified ATTRibutes\n"
+"-L find all Less specific matches\n"
+"-M find all More specific matches\n"
+"-m find first level more specific matches\n"
+"-r turn off recursive lookups\n"
+"-p PORT connect to PORT\n"
+"-R force to show local copy of the domain object even\n"
+" if it contains referral\n"
+"-S tell server to leave out syntactic sugar\n"
+"-s SOURCE[,SOURCE]... search the database from SOURCE\n"
+"-T TYPE[,TYPE]... only look for objects of TYPE\n"
+"-t TYPE requests template for object of TYPE ('all' for a "
+"list)\n"
+"-v TYPE requests verbose template for object of TYPE\n"
+"-V explain what is being done\n"
+"\n"
+"Version "
+msgstr ""
+"Uso: whois [OPZIONE]... OGGETTO...\n"
+"\n"
+"-a cerca tutti i database\n"
+"-C interroga prima CRSNIC per trovare il registro di "
+"GTLD\n"
+"-F output grezzo veloce (implica -r)\n"
+"-g SOURCE:FIRST-LAST trova gli aggiornamenti di SOURCE dal seriale F a L\n"
+"-h HOST si connette al server HOST\n"
+"-i ATTR[,ATTR]... fa una ricerca inversa per l'ATTRibuto specificato\n"
+"-L trova le corrispondenze meno specifiche\n"
+"-M trova le corrispondenze più specifiche\n"
+"-m trova le corrispondenze di primo livello più "
+"specifiche\n"
+"-r disabilita le ricerche ricorsive\n"
+"-p PORTA si connette alla PORTA\n"
+"-R mostra la copia locale dell'oggetto domain anche se\n"
+" contiene un riferimento\n"
+"-S dice al server di non usare lo zucchero sintattico\n"
+"-s SOURCE[,SOURCE]... cerca il database da SOURCE\n"
+"-T TIPO[,TIPO]... cerca solo oggetti del TIPO\n"
+"-t TIPO chiede il template per un oggetto del TIPO ('all' per una "
+"lista)\n"
+"-v TIPO chiede il template prolisso per un oggetto del TIPO\n"
+"-V spiega cosa sta facendo\n"
+"\n"
+"Versione "
diff --git a/tld_serv_list b/tld_serv_list
new file mode 100644
index 0000000..04ef828
--- /dev/null
+++ b/tld_serv_list
@@ -0,0 +1,119 @@
+.gb.com whois.nomination.net
+.gb.net whois.nomination.net
+.uk.net whois.nomination.net
+.uk.net whois.nomination.net
+.com whois.internic.net
+.net whois.internic.net
+.org whois.internic.net
+.edu whois.internic.net
+.gov whois.nic.gov
+.int whois.isi.edu
+.mil whois.nic.mil
+.ac whois.nic.ac
+.ad whois.ripe.net
+.al whois.ripe.net
+.am whois.amnic.net
+.as whois.nic.as
+.at whois.univie.ac.at # CNAME whois.ripe.net
+.net.au whois.connect.com.au
+.au whois.aunic.net
+.az whois.ripe.net
+.ba whois.ripe.net
+.be whois.ripe.net
+.bg whois.ripe.net
+.br whois.nic.br
+.by whois.ripe.net
+.ca whois.cdnnet.ca
+.cc whois.nic.cc
+.ch whois.nic.ch
+.ck whois.ck-nic.org.ck
+.ac.cn whois.cnc.ac.cn
+.cn whois.cnnic.net.cn
+.uk.co whois.uk.co
+.co whois.ripe.net
+.cy whois.ripe.net
+.cz whois.ripe.net
+.de whois.ripe.net
+.dk whois.ripe.net
+.dz whois.ripe.net
+.ee whois.ripe.net
+.eg whois.ripe.net
+.es whois.ripe.net
+.fi whois.ripe.net
+.fo whois.ripe.net
+.fr whois.nic.fr
+.ga whois.ripe.net
+.gb whois.ripe.net
+.ge whois.ripe.net
+.gl whois.ripe.net
+.gm whois.ripe.net
+.gr whois.ripe.net
+.gs whois.adamsnames.tc
+.hk whois.apnic.net
+.hm whois.nic.hm
+.hr whois.ripe.net
+.hu whois.ripe.net
+.id whois.idnic.net.id
+.ie whois.ripe.net
+.il whois.ripe.net
+.in whois.ncst.ernet.in
+.is whois.ripe.net
+.it whois.nic.it
+.jo whois.ripe.net
+.jp whois.nic.ad.jp
+.kr whois.krnic.net
+.kz whois.domain.kz
+.li whois.nic.li
+.lk whois.nic.lk
+.lt whois.ripe.net
+.lu whois.ripe.net
+.lv whois.ripe.net
+.ma whois.ripe.net
+.mc whois.ripe.net
+.md whois.ripe.net
+.mk whois.ripe.net
+.mm whois.nic.mm
+.ms whois.adamsnames.tc
+.mt whois.ripe.net
+.mx whois.nic.mx
+.ng pgebrehiwot.iat.cnr.it
+.nl www.domain-registry.nl
+.no whois.ripe.net
+.nu whois.nic.nu
+.nz tardis.patho.gen.nz
+.pe whois.rcp.net.pe
+.pl whois.ripe.net
+.pk whois.pknic.net.pk
+.pt whois.dns.pt
+.ro whois.nic.ro
+.ru whois.ripn.net
+.se whois.nic-se.se
+.sg whois.nic.net.sg
+.sh whois.nic.sh
+.si whois.ripe.net
+.sk whois.ripe.net
+.sm whois.ripe.net
+.su whois.ripe.net
+.tc whois.adamsnames.tc
+.tf whois.adamsnames.tc
+.th whois.thnic.net
+.tj whois.nic.tj
+.tm whois.nic.tm
+.tn whois.ripe.net
+.to whois.tonic.to
+.tr whois.metu.edu.tr
+.tw whois.twnic.net
+.ua whois.ripe.net
+.ac.uk whois.ja.net
+.uk whois.nic.uk
+.us whois.isi.edu
+.va whois.ripe.net
+.yu whois.ripe.net
+.za whois.frd.ac.za
+-arin whois.arin.net
+-ripe whois.ripe.net
+-ap whois.apnic.net
+-dom whois.internic.net
+-org whois.internic.net
+-hst whois.internic.net
+-6bone whois.6bone.net
diff --git a/whois.1 b/whois.1
new file mode 100644
index 0000000..6d4a6e0
--- /dev/null
+++ b/whois.1
@@ -0,0 +1,90 @@
+.TH WHOIS 1 "8 October 1999" "Marco d'Itri" "Debian GNU/Linux"
+.SH NAME
+whois \- client for the whois directory service
+.SH SYNOPSIS
+.B whois
+[
+.BR \-h
+.I HOST
+] [
+.BR \-p
+.I PORT
+] [
+.BR -aCFLMmrRSV
+] [
+.BR \-g
+.I SOURCE:FIRST-LAST
+] [
+.BR \-i
+.I ATTR
+] [
+.BR \-S
+.I SOURCE
+] [
+.BR \-T
+.I TYPE
+]
+.I object
+
+.B whois
+[
+.I -t
+|
+.I -v
+|
+.I -i
+]
+.I template
+.PP
+.SH DESCRIPTION
+.B whois
+searches for an object in a
+.I RFC-812
+database.
+
+This version of the whois client tries to guess the right server to
+ask for the specified object. If no guess can be made it will connect
+to whois.internic.net for domains, whois.arin.net for IPv4 addresses
+and whois.6bone.net for IPv6 addresses.
+.PP
+.SH OPTIONS
+.TP 8
+.B \-h HOST
+Connect to HOST.
+.TP 8
+.B \-p PORT
+Connect to PORT.
+.TP 8
+.B \-C
+First query
+.I www.crsnic.net
+to find the registrar for a GTLD subdomain. This option overrides
+.I \-h.
+.TP 8
+.B \-V
+Be verbose.
+.TP 8
+Other options are flags understood by RIPE-like servers.
+.SH "SEE ALSO"
+.I RFC 812:
+NICNAME/WHOIS
+.PP
+.I RIPE-157, RIPE-189:
+RIPE NCC Database Documentation
+.PP
+Detailed help on available flags can be found in
+.I RIPE-157
+or in the help file, which can be downloaded with the command:
+.IP
+.B whois -h whois.ripe.net HELP
+.SH HISTORY
+This program closely tracks the user interface of the whois client
+developed at RIPE by Ambrose Magee and others on the base of the
+original BSD client.
+I also added support for the protocol extensions developed by David
+Kessens of QWest for the 6bone server.
+.SH AUTHOR
+.B Whois
+and this man page were written by Marco d'Itri <md@linux.it>
+and are licensed under the GPL.
+
diff --git a/whois.c b/whois.c
new file mode 100644
index 0000000..f4f63ef
--- /dev/null
+++ b/whois.c
@@ -0,0 +1,424 @@
+/* Copyright 1999 by Marco d'Itri <md@linux.it>.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/* System library */
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <string.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <errno.h>
+#include <signal.h>
+
+#include "config.h"
+#include "whois.h"
+#include "data.h"
+
+int sockfd, verb = 0;
+
+
+int main(int argc, char *argv[])
+{
+ int ch, nopar = 0, optC = 0;
+ const char *server = NULL;
+ char *p, qstring[256] = "\0", fstring[64] = "\0", *port = NULL,
+ defaultserv[] = "whois.internic.net";
+
+#ifdef ENABLE_NLS
+ setlocale(LC_MESSAGES, "");
+ bindtextdomain(NLS_CAT_NAME, LOCALEDIR);
+ textdomain(NLS_CAT_NAME);
+#endif
+
+ while ((ch = GETOPT(argc, argv, "acCFg:h:i:LmMp:rRs:St:T:v:V")) > 0) {
+ /* RIPE flags */
+ if (strchr(ripeflags, ch)) {
+ for (p = fstring; *p != '\0'; p++);
+ sprintf(p--, "-%c ", ch);
+ continue;
+ }
+ if (strchr(ripeflagsp, ch)) {
+ for (p = fstring; *p != '\0'; p++);
+ sprintf(p--, "-%c %s ", ch, optarg);
+ if (ch == 't' || ch == 'v')
+ nopar = 1;
+ continue;
+ }
+ /* program flags */
+ switch (ch) {
+ case 'h':
+ server = optarg;
+ break;
+ case 'p':
+ port = optarg;
+ break;
+ case 'C':
+ optC = 1;
+ break;
+ case 'V':
+ verb = 1;
+ break;
+ default:
+ usage();
+ }
+ }
+ argc -= optind;
+ argv += optind;
+
+ if (argc == 0 && !nopar) /* there is no parameter */
+ usage();
+
+ /* parse other parameters */
+ if (!nopar) {
+ strcpy(qstring, *argv++);
+ argc--;
+ while (argc-- > 0) {
+ strcat(qstring, " ");
+ strcat(qstring, *argv);
+ }
+ }
+
+ if (optC && domfind(qstring, gtlds)) {
+ if (verb)
+ printf(_("Connecting to whois.crsnic.net.\n"));
+ sockfd = openconn("whois.crsnic.net", "43");
+ server = query_crsnic(sockfd, qstring);
+ if (verb && server)
+ printf(_("\nDetected CRSNIC referral to %s.\n\n"), server);
+ closeconn(sockfd);
+ }
+
+ if (!server) {
+ if (!(server = whichwhois(qstring))) {
+ server = defaultserv;
+ if (verb)
+ printf(_("Using default server %s.\n"), server);
+ } else if (verb)
+ printf(_("Using server %s.\n"), server);
+ }
+
+ p = queryformat(server, fstring, qstring);
+ if (verb)
+ printf(_("Query string: \"%s\"\n\n"), p);
+ strcat(p, "\r\n");
+
+ signal(SIGTERM, sighandler);
+ signal(SIGINT, sighandler);
+
+ sockfd = openconn(server, port);
+ do_query(sockfd, p);
+ closeconn(sockfd);
+
+ exit(0);
+}
+
+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, ':'))
+ return "whois.6bone.net";
+
+ /* no dot and no hyphen means it's a internic NIC handle or an AS (?) */
+ if (!strpbrk(s, ".-"))
+ return "whois.internic.net";
+
+ /* smells like an IP? */
+ if ((ip = myinet_aton(s))) {
+ for (i = 0; ip_assign[i].serv; i++)
+ if ((ip & ip_assign[i].mask) == ip_assign[i].net)
+ return ip_assign[i].serv;
+ if (verb)
+ printf(_("I don't know where this IP has been delegated.\n"
+ "I'll try ARIN and hope for the best...\n"));
+ return "whois.arin.net";
+ }
+
+ /* check TLD list */
+ for (i = 0; tld_serv[i]; i += 2)
+ if (domcmp(s, tld_serv[i]))
+ return tld_serv[i + 1];
+
+ /* no dot but hyphen, check for ARIN netblock names */
+ if (!strchr(s, '.')) {
+ for (i = 0; arin_nets[i]; i++)
+ if (!strncmp(s, arin_nets[i], strlen(arin_nets[i])))
+ return "whois.arin.net";
+ /* could be one of *NETBLK-RIPE* *NET-RIPE* *APNIC* *AUNIC-AU* */
+ if (verb)
+ printf(_("I guess it's a netblock name but I don't know where to"
+ " look it up.\n"));
+ return "whois.arin.net";
+ }
+
+ /* has dot and hypen and it's not in tld_serv[], WTF is it? */
+ if (verb)
+ printf(_("I guess it's a domain but I don't know where to look it"
+ " up.\n"));
+
+ return NULL;
+}
+
+char *queryformat(const char *server, const char *flags, const char *query)
+{
+ char *buf;
+ int i;
+
+ buf = malloc(QUERYBUFSIZE);
+ strcpy(buf, flags);
+ for (i = 0; ripe_servers[i]; i++)
+ if (strcmp(server, ripe_servers[i]) == 0)
+ strcat(buf, VERSION " ");
+ strcat(buf, query);
+ if (strcmp(server, "whois.nic.ad.jp") == 0) {
+ char *lang = getenv("LANG"); /* not a perfect check, but... */
+ if (lang && (strncmp(getenv("LANG"), "ja", 2) != 0))
+ strcat(buf, "/e"); /* ask for english text */
+ }
+ return buf;
+}
+
+void do_query(const int sock, const char *query)
+{
+ char buf[100];
+ FILE *fi;
+#ifdef HIDE_DISCL
+ int hide = 0;
+#endif
+
+ fi = fdopen(sock, "r");
+ if (write(sock, query, strlen(query)) < 0)
+ err_sys("write");
+ while (fgets(buf, 100, fi)) { /* XXX errors? */
+#ifdef HIDE_DISCL
+ if (hide == 1 &&
+ strncmp(buf, DISCL_END, sizeof(DISCL_END) - 1) == 0) {
+ hide = 2; /* stop hiding */
+ continue;
+ }
+ if (hide == 0 &&
+ strncmp(buf, DISCL_BEGIN, sizeof(DISCL_BEGIN) - 1) == 0) {
+ hide = 1; /* start hiding */
+ continue;
+ }
+#endif
+#ifdef EXT_6BONE
+ /* % referto: whois -h whois.arin.net -p 43 as 1 */
+ if (strncmp(buf, "% referto:", 10) == 0) {
+ char nh[256], np[16], nq[1024];
+
+ if (sscanf(buf, REFERTO_FORMAT, nh, np, nq) == 3) {
+ int fd;
+
+ if (verb)
+ printf(_("Detected referral to %s on %s.\n"), nq, nh);
+ strcat(nq, "\r\n");
+ fd = openconn(nh, np);
+ do_query(sockfd, nq);
+ closeconn(fd);
+ continue;
+ }
+ }
+#endif
+ printf("%s", buf);
+ }
+#ifdef HIDE_DISCL
+ if (hide == 1)
+ err_quit(_("Catastrophic error: INTERNIC changed the disclaimer text.\n"
+ "Please upgrade this program.\n"));
+#endif
+}
+
+const char *query_crsnic(const int sock, const char *query)
+{
+ char *temp, buf[100], *ret = NULL;
+ FILE *fi;
+
+ temp = malloc(strlen(query) + 5 + 2 + 1);
+ memcpy(temp, "dump ", 5);
+ strcpy(temp + 5, query);
+ strcat(temp, "\r\n");
+
+ fi = fdopen(sock, "r");
+ if (write(sock, temp, strlen(temp)) < 0)
+ err_sys("write");
+ while (fgets(buf, 100, fi)) {
+ if (strncmp(buf, " (2)", 6) == 0) {
+ char *p, *q;
+
+ for (p = buf; *p != ':'; p++); /* skip until colon */
+ for (p++; *p == ' '; p++); /* skip colon and spaces */
+ q = ret = malloc(strlen(p));
+ for (; *p != '\n' && *p != '\r'; *q++ = *p++); /* copy data */
+ *q = '\0';
+ }
+ printf("%s", buf);
+ }
+
+ free(temp);
+ return ret;
+}
+
+int openconn(const char *server, const char *port)
+{
+ int s;
+#ifdef HAVE_GETADDRINFO
+ struct addrinfo hints, *res, *ressave;
+#else
+ struct hostent *hostinfo;
+ struct servent *servinfo;
+ struct sockaddr_in saddr;
+#endif
+
+#ifdef HAVE_GETADDRINFO
+ memset(&hints, 0, sizeof(struct addrinfo));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
+
+ if ((s = getaddrinfo(server, port ? port : "whois", &hints, &res)) != 0)
+ err_quit("getaddrinfo: %s", gai_strerror(s));
+ ressave = res;
+
+ do {
+ if ((s = socket(res->ai_family, res->ai_socktype, res->ai_protocol))<0)
+ continue; /* ignore */
+ if (connect(s, res->ai_addr, res->ai_addrlen) == 0)
+ break; /* success */
+ close(s);
+ } while ((res = res->ai_next)); /* Thank you, W. Richard Stevens. */
+
+ if (!res)
+ err_sys("connect");
+ freeaddrinfo(ressave);
+#else
+ if ((hostinfo = gethostbyname(server)) == NULL)
+ err_quit(_("Host %s not found."), server);
+ saddr.sin_addr = *(struct in_addr *) hostinfo->h_addr;
+ if ((s = socket(PF_INET, SOCK_STREAM, IPPROTO_IP)) < 0)
+ err_sys("socket");
+ saddr.sin_family = AF_INET;
+ if (!port) {
+ saddr.sin_port = htons(43);
+ } else if ((saddr.sin_port = htons(atoi(port))) == 0) {
+ if ((servinfo = getservbyname(port, "tcp")) == NULL)
+ err_quit(_("%s/tcp: unknown service"), port);
+ saddr.sin_port = servinfo->s_port;
+ }
+ if (connect(s, &saddr, sizeof(saddr)) < 0)
+ err_sys("connect");
+#endif
+ return (s);
+}
+
+void closeconn(const int fd)
+{
+ close(fd);
+}
+
+void sighandler(int signum)
+{
+ closeconn(sockfd);
+ err_quit(_("Interrupted by signal %d..."), signum);
+}
+
+int domcmp(const char *dom, const char *tld)
+{
+ const char *p, *q;
+
+ if (!(p = rindex(dom, *tld)))
+ return 0;
+ q = tld;
+ while (tolower(*p) == *q)
+ if (!(*p++ && *q++))
+ return 1;
+ return 0;
+}
+
+int domfind(const char *dom, const char *tldlist[])
+{
+ int i;
+
+ for (i = 0; tldlist[i]; i++)
+ if (domcmp(dom, tldlist[i]))
+ return 1;
+ return 0;
+}
+
+unsigned long myinet_aton(const char *s)
+{
+ int a, b, c, d;
+
+ if (!s)
+ return 0;
+ if (sscanf(s, "%d.%d.%d.%d", &a, &b, &c, &d) != 4)
+ return 0;
+ return (a << 24) + (b << 16) + (c << 8) + d;
+}
+
+void usage(void)
+{
+ fprintf(stderr, _(
+"Usage: whois [OPTION]... OBJECT...\n\n"
+"-a search all databases\n"
+"-C first query CRSNIC to find GTLD registrar\n"
+"-F fast raw output (implies -r)\n"
+"-g SOURCE:FIRST-LAST find updates from SOURCE from serial FIRST to LAST\n"
+"-h HOST connect to server HOST\n"
+"-i ATTR[,ATTR]... do an inverse lookup for specified ATTRibutes\n"
+"-L find all Less specific matches\n"
+"-M find all More specific matches\n"
+"-m find first level more specific matches\n"
+"-r turn off recursive lookups\n"
+"-p PORT connect to PORT\n"
+"-R force to show local copy of the domain object even\n"
+" if it contains referral\n"
+"-S tell server to leave out syntactic sugar\n"
+"-s SOURCE[,SOURCE]... search the database from SOURCE\n"
+"-T TYPE[,TYPE]... only look for objects of TYPE\n"
+"-t TYPE requests template for object of TYPE ('all' for a list)\n"
+"-v TYPE requests verbose template for object of TYPE\n"
+"-V explain what is being done\n\n"
+"Version " VERSION ". Please report bugs to <md@linux.it>.\n"
+ ));
+ exit(1);
+}
+
+
+/* Error routines */
+void err_sys(const char *fmt,...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ vfprintf(stderr, fmt, ap);
+ fprintf(stderr, ": %s\n", strerror(errno));
+ va_end(ap);
+ exit(2);
+}
+
+void err_quit(const char *fmt,...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ vfprintf(stderr, fmt, ap);
+ fputs("\n", stderr);
+ va_end(ap);
+ exit(2);
+}
+
diff --git a/whois.h b/whois.h
new file mode 100644
index 0000000..86e3556
--- /dev/null
+++ b/whois.h
@@ -0,0 +1,73 @@
+/* Identification string */
+/* #define IDSTRING "-VMd" VERSION */
+#define IDSTRING "-VwC2.0"
+
+/* Size of the buffer where the query is built */
+#define QUERYBUFSIZE 1024
+
+/* Protocol data which could change */
+/* First and last lines of the Internic disclaimer */
+#define DISCL_BEGIN "The Data in"
+#define DISCL_END "this query"
+
+/* 6bone referto: extension */
+#define REFERTO_FORMAT "%% referto: whois -h %255s -p %15s %1023[^\n\r]"
+
+
+/* system features */
+#ifdef linux
+# define HAVE_GNU_GETOPT
+# define ENABLE_NLS
+# if __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 1
+# define HAVE_GETADDRINFO
+# endif
+#endif
+
+#ifdef ENABLE_NLS
+# define NLS_CAT_NAME "whois"
+# ifndef LOCALEDIR
+# define LOCALEDIR "/usr/share/locale"
+# endif
+#endif
+
+
+/* NLS stuff */
+#ifdef ENABLE_NLS
+# include <libintl.h>
+# include <locale.h>
+# define _(a) (gettext (a))
+# ifdef gettext_noop
+# define N_(a) gettext_noop (a)
+# else
+# define N_(a) (a)
+# endif
+#else
+# define _(a) (a)
+# define N_(a) a
+#endif
+
+
+/* If needed, disable GNU getopt "features" */
+#ifdef HAVE_GNU_GETOPT
+# define GETOPT(argc, argv, str) getopt((argc), (argv), "+" str)
+#else
+# define GETOPT(argc, argv, str) getopt((argc), (argv), (str))
+#endif
+
+
+/* prototypes */
+const char *whichwhois(const char *);
+char *queryformat(const char *, const char *, const char *);
+void do_query(const int, const char *);
+const char *query_crsnic(const int, const char *);
+int openconn(const char *, const char *);
+void closeconn(const int);
+void usage(void);
+void sighandler(int);
+unsigned long myinet_aton(const char *);
+int domcmp(const char *, const char *);
+int domfind(const char *, const char *[]);
+
+void err_quit(const char *,...);
+void err_sys(const char *,...);
+