diff options
-rw-r--r-- | Makefile | 29 | ||||
-rw-r--r-- | README | 32 | ||||
-rw-r--r-- | TODO | 5 | ||||
-rw-r--r-- | config.h | 11 | ||||
-rw-r--r-- | data.h | 46 | ||||
-rw-r--r-- | debian/changelog | 36 | ||||
-rw-r--r-- | debian/control | 18 | ||||
-rw-r--r-- | debian/copyright | 7 | ||||
-rwxr-xr-x | debian/rules | 46 | ||||
-rw-r--r-- | ip_del_list | 45 | ||||
-rwxr-xr-x | make_ip_del.pl | 22 | ||||
-rwxr-xr-x | make_tld_serv.pl | 13 | ||||
-rw-r--r-- | mkpasswd.1 | 20 | ||||
-rw-r--r-- | mkpasswd.c | 21 | ||||
-rw-r--r-- | po/Makefile | 50 | ||||
-rw-r--r-- | po/it.po | 146 | ||||
-rw-r--r-- | tld_serv_list | 119 | ||||
-rw-r--r-- | whois.1 | 90 | ||||
-rw-r--r-- | whois.c | 424 | ||||
-rw-r--r-- | whois.h | 73 |
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) + @@ -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> + @@ -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" + @@ -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 @@ -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. + @@ -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); +} + @@ -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 *,...); + |