christos@netbsd.org suggested we replace whois
with one that is KNF, has ipv6, better error handling, and recursion. I settled on OpenBSDs. Christos found some nits and had me commit as is. Christos will follow up with fixes shortly.
This commit is contained in:
parent
fbacec1288
commit
df042318ea
@ -1,4 +1,5 @@
|
||||
.\" $NetBSD: whois.1,v 1.20 2003/08/07 11:17:19 agc Exp $
|
||||
.\" $NetBSD: whois.1,v 1.21 2003/10/09 14:21:49 jrf Exp $
|
||||
.\" $OpenBSD: whois.1,v 1.22 2003/09/02 18:50:07 jmc Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 1985, 1990, 1993
|
||||
.\" The Regents of the University of California. All rights reserved.
|
||||
@ -29,257 +30,275 @@
|
||||
.\"
|
||||
.\" @(#)whois.1 8.2 (Berkeley) 6/20/94
|
||||
.\"
|
||||
.Dd January 12, 2002
|
||||
.Dd January 6, 2003
|
||||
.Dt WHOIS 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm whois
|
||||
.Nd TCP/IP Internet directory service, RIPE version
|
||||
.Nd Internet domain name and network number directory service
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl 46aFSrR
|
||||
.Op Fl h Ar host
|
||||
.Nm whois
|
||||
.Op Fl aAdgilmQrR6
|
||||
.Oo
|
||||
.Fl c Ar country-code | Fl h Ar host
|
||||
.Oc
|
||||
.Op Fl p Ar port
|
||||
.Op Fl i Ar attributes
|
||||
.Op Fl s Ar sources
|
||||
.Op Fl T Ns Ar \ types
|
||||
.Op Fl L | m | M
|
||||
.Ar identifier
|
||||
.Nm
|
||||
.Fl t Ar type
|
||||
.Nm
|
||||
.Fl v Ar type
|
||||
.Ar name Op Ar ...
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
program is a client implementation of the WHOIS protocol for querying
|
||||
databases and directory services on the Internet.
|
||||
Most often, it is used to query the domain name contact and administration
|
||||
databases of Internet Domain Name Registrars.
|
||||
utility looks up records in the databases maintained by several
|
||||
Network Information Centers
|
||||
.Pq Tn NICs .
|
||||
.Pp
|
||||
The WHOIS protocol does not specify very much of the format of
|
||||
either the query or the servers' response.
|
||||
In essence, the protocol calls for a
|
||||
.Tn NETASCII
|
||||
word or phrase to be sent on a
|
||||
.Tn TCP
|
||||
connection to a
|
||||
.Tn WHOIS
|
||||
server, which then sends some amount of
|
||||
.Tn NETASCII
|
||||
in response on the same connection,
|
||||
closing the connection when it has finished sending.
|
||||
Necessarily, both the format and the content of the response will be server-dependent
|
||||
.Po
|
||||
e.g. what you get back depends on who you ask, and what you ask
|
||||
.Pc .
|
||||
.Pp
|
||||
By default,
|
||||
.Nm
|
||||
will send the query to
|
||||
.Qq whois.internic.net .
|
||||
.Pp
|
||||
When
|
||||
.Nm
|
||||
is used to query an Internet domain name registrar's database, the
|
||||
.Ar identifier
|
||||
can be either a name
|
||||
.Po
|
||||
e.g.
|
||||
.Qq Karrenberg
|
||||
.Pc ,
|
||||
a
|
||||
.Tn NIC-handle
|
||||
.Po
|
||||
e.g.
|
||||
.Qq DK58
|
||||
.Pc ,
|
||||
an IP network number
|
||||
.Po
|
||||
e.g.
|
||||
.Qq 192.87.45.0/24
|
||||
.Pc ,
|
||||
or a domain name
|
||||
.Po
|
||||
e.g.
|
||||
.Qq ripe.net
|
||||
.Pc .
|
||||
.Sh OPTIONS
|
||||
.Bl -tag -width indent
|
||||
.It Fl h Ar host
|
||||
Query a host other than the default.
|
||||
.It Fl p Ar port
|
||||
Connect to a
|
||||
.Tn TCP
|
||||
port other than 43 (the default).
|
||||
.El
|
||||
.Pp
|
||||
By default,
|
||||
.Nm
|
||||
will attempt to connect to a WHOIS server with both IPv6 and IPv4,
|
||||
in that order.
|
||||
To force one or the other transport:
|
||||
.Bl -tag -width indent
|
||||
.It Fl 4
|
||||
connect with IPv4/TCP only.
|
||||
.It Fl 6
|
||||
connect with IPv6/TCP only.
|
||||
.El
|
||||
.Ss RIPE specific extensions
|
||||
This version of
|
||||
.Nm
|
||||
implements protocol extensions compatible with a version of the RIPE
|
||||
database WHOIS server that supports classless IP addresses.
|
||||
All IP network numbers are considered classless IP network numbers of
|
||||
the form prefix/length, like 192.87.45.0/24 for a class C sized network
|
||||
number and 128.86.0.0/16 for a class B sized network number.
|
||||
Any length can be given.
|
||||
If no length is given, the server assumes a host lookup (i.e. length 32).
|
||||
.Pp
|
||||
By default, the server will return the first less specific network
|
||||
number, which can be an exact match if available in the database.
|
||||
.Bl -tag -width indent
|
||||
The options are as follows:
|
||||
.Bl -tag -width Ds
|
||||
.It Fl a
|
||||
This causes the server to include information from
|
||||
non-RIPE WHOIS databases in the reply.
|
||||
Currently these are the public parts of the US NIC and NSFNET databases.
|
||||
Please note that the RIPE NCC does not maintain these databases.
|
||||
The information is included for for your convenience only.
|
||||
.It Fl F
|
||||
fast output.
|
||||
Force the WHOIS server to not reformat the output.
|
||||
This can save time for large objects.
|
||||
The output of the RIPE WHOIS server will be in two letter short form.
|
||||
This option implies -r.
|
||||
.It Fl L
|
||||
lookup all less specific networks.
|
||||
Has effect only when looking up IP network numbers.
|
||||
.It Fl m
|
||||
lookup first level more specific networks.
|
||||
Has effect only when looking up IP network numbers.
|
||||
.It Fl M
|
||||
lookup all more specific networks.
|
||||
Has effect only when looking up IP network numbers.
|
||||
.It Fl r
|
||||
non-recursive lookup.
|
||||
This will cause the server to not lookup referenced objects.
|
||||
.It Fl R
|
||||
suppress referrals.
|
||||
Forces local copy of a domain object to be shown even if it contains referral.
|
||||
.It Fl i Ar attributes
|
||||
attributes is a comma separated list of attributes.
|
||||
the WHOIS server will return all objects that match the search keys
|
||||
in one of these attributes.
|
||||
.It Fl s Ar sources
|
||||
sources is a comma separated list of database sources.
|
||||
The WHOIS server will only search the databases that match the
|
||||
specified sources.
|
||||
.It Fl S
|
||||
requests the server to leave out "syntactic sugar" that may normally
|
||||
be inserted in some database objects.
|
||||
.It Fl t Ar type
|
||||
requests the server to send a template for an object with type "type".
|
||||
.It Fl v Ar type
|
||||
requests the server to send a verbose template for an object with type "type".
|
||||
.It Fl T Ar types
|
||||
types is a comma separated list of object types.
|
||||
requests the server to only send back objects that match one of the "types".
|
||||
.El
|
||||
.Sh EXAMPLES
|
||||
.Bd -literal -offset indent
|
||||
$ whois karrenberg
|
||||
person: Daniel Karrenberg
|
||||
address: RIPE Network Coordination Centre
|
||||
address: Kruislaan 409
|
||||
address: NL-1098 SJ Amsterdam
|
||||
address: Netherlands
|
||||
phone: +31 20 5925065
|
||||
fax-no: +31 20 5925155
|
||||
e-mail: dfk@ripe.net
|
||||
nic-hdl: DK58
|
||||
changed: dfk@ripe.net 920407
|
||||
changed: ripe-dbm@ripe.net 920407
|
||||
source: RIPE
|
||||
$ whois -h whois.ripe.net -r 192.87.45.0/24
|
||||
inetnum: 192.87.45.0
|
||||
netname: RIPE-NCC
|
||||
descr: RIPE Network Coordination Centre
|
||||
descr: Amsterdam, Netherlands
|
||||
country: NL
|
||||
admin-c: Daniel Karrenberg
|
||||
tech-c: Marten Terpstra
|
||||
connect: RIPE NSF WCW
|
||||
aut-sys: AS3333
|
||||
ias-int: 192.87.45.80 AS1104
|
||||
ias-int: 192.87.45.6 AS2122
|
||||
ias-int: 192.87.45.254 AS2600
|
||||
rev-srv: ns.ripe.net
|
||||
rev-srv: ns.eu.net
|
||||
notify: ops@ripe.net
|
||||
changed: tony@ripe.net 940110
|
||||
source: RIPE
|
||||
.Ed
|
||||
.Ss Other Useful WHOIS Servers
|
||||
Herewith follows an incomplete list of other potentially useful
|
||||
WHOIS servers on the Internet.
|
||||
Use the American Registry for Internet Numbers
|
||||
.Pq Tn ARIN
|
||||
database.
|
||||
It contains network numbers used in those parts of the world
|
||||
covered neither by
|
||||
.Tn APNIC
|
||||
nor by
|
||||
.Tn RIPE .
|
||||
.Pp
|
||||
For information about IP address allocations,
|
||||
the registrars who handle those allocations are:
|
||||
.Bl -tag -width indent
|
||||
.It whois.arin.net
|
||||
American Registry for Internet Numbers.
|
||||
.It whois.apnic.net
|
||||
Asia-Pacific Network Information Center.
|
||||
.It whois.ripe.net
|
||||
Reseaux IP Europeens - Network Coordination Center.
|
||||
.El
|
||||
.Pp
|
||||
Internet domain names can now be registered through many different
|
||||
competing registrars, many of whom (but probably not all of whom)
|
||||
operate WHOIS servers:
|
||||
.Bl -tag -width indent
|
||||
.It whois.networksolutions.com
|
||||
Network Solutions, operators of the InterNIC.
|
||||
.It whois.ripe.net
|
||||
RIPE domains, assignments, \*[Am] routing info.
|
||||
.It whois.ra.net
|
||||
Merit/IRR routing info.
|
||||
.It whois.geektools.com
|
||||
recursing proxies that query internic.net.
|
||||
.It whois.fucknsi.com
|
||||
a meta-WHOIS server that attempts to query all the registrars.
|
||||
.It whois.opensrs.net
|
||||
same as above, but also authoritative for OpenSRS domain names.
|
||||
.El
|
||||
.Sh RIPE VERSION
|
||||
This is the RIPE version of the WHOIS client program.
|
||||
For questions refer to
|
||||
.Aq ncc@ripe.net .
|
||||
For more information about the RIPE database please also refer to
|
||||
.Aq ncc@ripe.net .
|
||||
.Sh SEE ALSO
|
||||
.Xr networks 5 ,
|
||||
.Xr bind 8 ,
|
||||
.Pa http://www.domainbuyersguide.com/
|
||||
.Rs
|
||||
.%R RFC
|
||||
.%N 812
|
||||
.%D March 1982
|
||||
.%T "NICNAME/WHOIS"
|
||||
.%O (Obsolete)
|
||||
.Re
|
||||
.Rs
|
||||
.%R RFC
|
||||
.%N 954
|
||||
.%D October 1985
|
||||
.%T "NICNAME/WHOIS"
|
||||
.Re
|
||||
.Sh BUGS
|
||||
Most of the extra flags are ONLY supported by the RIPE whois server,
|
||||
or copies of the same version of the software.
|
||||
Usage of these flags may cause errors on other whois servers.
|
||||
(Hint: All point of contact handles in the
|
||||
.Tn ARIN
|
||||
whois database end with
|
||||
.Qq Li -ARIN . )
|
||||
.It Fl A
|
||||
Use the Asia/Pacific Network Information Center
|
||||
.Pq Tn APNIC
|
||||
database.
|
||||
It contains network numbers used in East Asia, Australia,
|
||||
New Zealand, and the Pacific islands.
|
||||
.It Fl c Ar country-code
|
||||
This is the equivalent of using the
|
||||
.Fl h
|
||||
option with an argument of
|
||||
.Qq Ar country-code Ns Li .whois-servers.net .
|
||||
.It Fl d
|
||||
Use the US Department of Defense database.
|
||||
It contains points of contact for subdomains of
|
||||
.Tn \&.MIL .
|
||||
.It Fl g
|
||||
Use the US non-military federal government database, which contains points of
|
||||
contact for subdomains of
|
||||
.Tn \&.GOV .
|
||||
.It Fl h Ar host
|
||||
Use the specified host instead of the default NIC
|
||||
(whois.crsnic.net).
|
||||
Either a host name or an IP address may be specified.
|
||||
.Pp
|
||||
By default
|
||||
.Nm
|
||||
uses
|
||||
.Xr getaddrinfo 3
|
||||
functions, thus search order depends on the function.
|
||||
constructs the name of a whois server to use from the top-level domain
|
||||
.Pq Tn TLD
|
||||
of the supplied (single) argument, and appending
|
||||
.Qq Li .whois-servers.net .
|
||||
This effectively allows a suitable whois server to be selected
|
||||
automatically for a large number of
|
||||
.Tn TLDs .
|
||||
.Pp
|
||||
In the event that an IP
|
||||
address is specified, the whois server will default to the American
|
||||
Registry for Internet Numbers
|
||||
.Pq Tn ARIN .
|
||||
If a query to
|
||||
.Tn ARIN
|
||||
references
|
||||
.Tn APNIC , LACNIC ,
|
||||
or
|
||||
.Tn RIPE ,
|
||||
that server will be queried also, provided that the
|
||||
.Fl Q
|
||||
option is not specified.
|
||||
.Pp
|
||||
If the query is not a domain name or IP address,
|
||||
.Nm
|
||||
will fall back to
|
||||
.Pa whois.crsnic.net .
|
||||
.It Fl i
|
||||
Use the Network Solutions Registry for Internet Numbers
|
||||
.Pq Tn whois.networksolutions.com
|
||||
database.
|
||||
Historically, it contained network numbers and domain contact information
|
||||
for most of
|
||||
.Tn \&.COM ,
|
||||
.Tn \&.NET ,
|
||||
.Tn \&.ORG
|
||||
and
|
||||
.Tn \&.EDU
|
||||
domains.
|
||||
However, the registration of these domains is now done by a number of
|
||||
independent and competing registrars and this database holds no information
|
||||
on the domains registered by organizations other than Network Solutions, Inc.
|
||||
Also, note that the
|
||||
.Tn InterNIC
|
||||
database
|
||||
.Pq Pa whois.internic.net
|
||||
is no longer handled by Network Solutions, Inc.
|
||||
For details, see
|
||||
.Pa http://www.internic.net/ .
|
||||
.Pp
|
||||
(Hint: Contact information, identified by the term
|
||||
.Em handle ,
|
||||
can be looked up by prefixing
|
||||
.Qq Li \&!
|
||||
or
|
||||
.Qq Li handle\ \&
|
||||
to the
|
||||
.Tn NIC
|
||||
handle in the query.)
|
||||
.It Fl l
|
||||
Use the Latin American and Caribbean IP address Regional Registry
|
||||
.Pq Tn LACNIC
|
||||
database.
|
||||
It contains network numbers used in much of Latin America and the
|
||||
Caribbean.
|
||||
.It Fl m
|
||||
Use the Route Arbiter Database
|
||||
.Pq Tn RADB
|
||||
database.
|
||||
It contains route policy specifications for a large
|
||||
number of operators' networks.
|
||||
.It Fl p Ar port
|
||||
Connect to the whois server on
|
||||
.Ar port .
|
||||
If this option is not specified,
|
||||
.Nm
|
||||
defaults to the
|
||||
.Dq whois
|
||||
port listed in
|
||||
.Pa /etc/services
|
||||
(port 43).
|
||||
.It Fl Q
|
||||
Do a quick lookup.
|
||||
This means that
|
||||
.Nm
|
||||
will not attempt to lookup the name in the authoratative whois
|
||||
server (if one is listed) nor will it contact InterNic if a lookup
|
||||
fails.
|
||||
This flag has no effect when combined with any other flag.
|
||||
.It Fl r
|
||||
Use the R\(aaeseaux IP Europ\(aaeens
|
||||
.Pq Tn RIPE
|
||||
database.
|
||||
It contains network numbers and domain contact information for Europe.
|
||||
.It Fl R
|
||||
Use the Russia Network Information Center
|
||||
.Pq Tn RIPN
|
||||
database.
|
||||
It contains network numbers and domain contact information
|
||||
for subdomains of
|
||||
.Tn \&.RU .
|
||||
This option is deprecated; use the
|
||||
.Fl c
|
||||
option with an argument of
|
||||
.Qq Li RU
|
||||
instead.
|
||||
.It Fl 6
|
||||
Use the IPv6 Resource Center
|
||||
.Pq Tn 6bone
|
||||
database.
|
||||
It contains network names and addresses for the IPv6 network.
|
||||
.El
|
||||
.Pp
|
||||
The default action, unless directed otherwise with a special
|
||||
.Ar name ,
|
||||
is to do a very broad search, looking for matches to
|
||||
.Ar name
|
||||
in all types of records and most fields (name, nicknames, hostname, net
|
||||
address, etc.) in the database.
|
||||
For more information as to what
|
||||
.Ar name
|
||||
operands have special meaning, and how to guide the search, use
|
||||
the special name
|
||||
.Dq help .
|
||||
.Ss Special cases
|
||||
Queries beginning with an exclamation point
|
||||
.Ql \&!
|
||||
are assumed to be
|
||||
.Tn NSI
|
||||
contact handles.
|
||||
Unless a host or domain is specified on the command line,
|
||||
.Pq Tn whois.networksolutions.com
|
||||
will be used as the
|
||||
.Nm
|
||||
database.
|
||||
.Pp
|
||||
Similarly, queries beginning with
|
||||
.Dq COCO-
|
||||
are assumed to be
|
||||
.Tn CORE
|
||||
contact handles.
|
||||
Unless a host or domain is specified on the command line,
|
||||
.Pq Tn whois.corenic.net
|
||||
will be used as the
|
||||
.Nm
|
||||
database.
|
||||
.Sh EXAMPLES
|
||||
Most types of data, such as domain names and
|
||||
.Tn IP
|
||||
addresses, can be used as arguments to
|
||||
.Nm
|
||||
without any options, and
|
||||
.Nm
|
||||
will choose the correct whois server to query.
|
||||
Some exceptions, where
|
||||
.Nm
|
||||
will not be able to handle data correctly, are detailed below.
|
||||
.Pp
|
||||
To obtain contact information about an
|
||||
administrator located in the Russian
|
||||
.Tn TLD
|
||||
domain
|
||||
.Qq Li RU ,
|
||||
use the
|
||||
.Fl c
|
||||
option as shown in the following example, where
|
||||
.Ar CONTACT-ID
|
||||
is substituted with the actual contact identifier.
|
||||
.Pp
|
||||
.Dl "whois -c RU CONTACT-ID"
|
||||
.Pp
|
||||
(Note: This example is specific to the
|
||||
.Tn TLD
|
||||
.Qq Li RU ,
|
||||
but other
|
||||
.Tn TLDs
|
||||
can be queried by using a similar syntax.)
|
||||
.Pp
|
||||
The following example demonstrates how to obtain information about an
|
||||
.Tn IPv6
|
||||
address or hostname using the
|
||||
.Fl 6
|
||||
option, which directs the query to
|
||||
.Tn 6bone .
|
||||
.Pp
|
||||
.Dl "whois -6 IPv6-IP-Address"
|
||||
.Pp
|
||||
The following example demonstrates how to query
|
||||
a whois server using a non-standard port, where
|
||||
.Dq Li query-data
|
||||
is the query to be sent to
|
||||
.Dq Li whois.example.com
|
||||
on port
|
||||
.Dq Li rwhois
|
||||
(written numerically as 4321).
|
||||
.Pp
|
||||
.Dl "whois -h whois.example.com -p rwhois query-data"
|
||||
.Sh SEE ALSO
|
||||
.Rs
|
||||
.%A Ken Harrenstien
|
||||
.%A Vic White
|
||||
.%T NICNAME/WHOIS
|
||||
.%D 1 March 1982
|
||||
.%O RFC 812
|
||||
.Re
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
command appeared in
|
||||
.Bx 4.3 .
|
||||
|
@ -1,21 +1,9 @@
|
||||
/* $NetBSD: whois.c,v 1.21 2003/08/07 11:17:20 agc Exp $ */
|
||||
/* $NetBSD: whois.c,v 1.22 2003/10/09 14:21:49 jrf Exp $ */
|
||||
/* $OpenBSD: whois.c,v 1.28 2003/09/18 22:16:15 fgsch Exp $ */
|
||||
|
||||
/*
|
||||
* RIPE version marten@ripe.net
|
||||
* many changes & networkupdate by david@ripe.net
|
||||
* cosmetics by steven@dante.org.uk -- gcc stopped complaining mostly,
|
||||
* code is still messy, though.
|
||||
*
|
||||
* 1.15 94/09/07
|
||||
*
|
||||
* 1.2 9705/02
|
||||
* "-v" option added; ambrose@ripe.net
|
||||
* "whois.ripe.net" replaced by "bsdbase.ripe.net"; ambrose@ripe.net
|
||||
* "bsdbase.ripe.net" replaced by "joshua.ripe.net"; marek@ripe.net
|
||||
* "joshua.ripe.net" replaced by "whois.ripe.net"; roman@ripe.net 981105
|
||||
*
|
||||
* Copyright (c) 1980 Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 1980, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@ -42,550 +30,281 @@
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
#ifndef lint
|
||||
__COPYRIGHT("@(#) Copyright (c) 1980, 1993\n\
|
||||
The Regents of the University of California. All rights reserved.\n");
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef RIPE
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)whois.c 8.1 (Berkeley) 6/6/93";
|
||||
static const char sccsid[] = "@(#)whois.c 8.1 (Berkeley) 6/6/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: whois.c,v 1.21 2003/08/07 11:17:20 agc Exp $");
|
||||
__RCSID("$NetBSD: whois.c,v 1.22 2003/10/09 14:21:49 jrf Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
#endif /* not RIPE */
|
||||
|
||||
#ifdef RIPE
|
||||
#ifndef lint
|
||||
char sccsid[] =
|
||||
"@(#)whois.c 5.11 (Berkeley) 3/2/91 - RIPE 1.15 94/09/07 marten@ripe.net";
|
||||
#endif /* not lint */
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: whois.c,v 1.21 2003/08/07 11:17:20 agc Exp $");
|
||||
#endif
|
||||
|
||||
#endif /* RIPE */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/param.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <err.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <err.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <pwd.h>
|
||||
#include <signal.h>
|
||||
|
||||
#define index(s,c) strchr((const char*)(s),(int)(c))
|
||||
#define rindex(s,c) strrchr((const char*)(s),(int)(c))
|
||||
#define bzero(s,n) memset((void*)s,0,(size_t)n)
|
||||
#define NICHOST "whois.crsnic.net"
|
||||
#define INICHOST "whois.networksolutions.com"
|
||||
#define CNICHOST "whois.corenic.net"
|
||||
#define DNICHOST "whois.nic.mil"
|
||||
#define GNICHOST "whois.nic.gov"
|
||||
#define ANICHOST "whois.arin.net"
|
||||
#define RNICHOST "whois.ripe.net"
|
||||
#define PNICHOST "whois.apnic.net"
|
||||
#define RUNICHOST "whois.ripn.net"
|
||||
#define MNICHOST "whois.ra.net"
|
||||
#define LNICHOST "whois.lacnic.net"
|
||||
#define SNICHOST "whois.6bone.net"
|
||||
#define BNICHOST "whois.registro.br"
|
||||
#define QNICHOST_TAIL ".whois-servers.net"
|
||||
|
||||
#ifdef HASMEMMOVE
|
||||
# define bcopy(s,d,n) memmove((void*)(d),(void*)(s),(size_t)(n))
|
||||
#else
|
||||
# define bcopy(s,d,n) memcpy((void*)(d),(void*)(s),(size_t)(n))
|
||||
#endif /* HASMEMMOVE */
|
||||
#define WHOIS_PORT "whois"
|
||||
#define WHOIS_SERVER_ID "Whois Server:"
|
||||
|
||||
/*
|
||||
#define WHOIS_RECURSE 0x01
|
||||
#define WHOIS_QUICK 0x02
|
||||
|
||||
# the following defines can be used but are not fully functional anymore...
|
||||
#
|
||||
# CLEVER- Use a educated guess of the whereabouts of the nearest server
|
||||
# This is done by taking the top-level domain of the current
|
||||
# machine, and looking for a CNAME record for a server with name
|
||||
# <top-level-domain>-whois.ripe.net
|
||||
# If this machine does not exsist or the current machine's top-level
|
||||
# domain could not be found,it will fall back to whois.ripe.net
|
||||
# the default for this RIPE version of whois
|
||||
# The CLEVER option implies the RIPE option.
|
||||
const char *port = WHOIS_PORT;
|
||||
const char *ip_whois[] = { LNICHOST, RNICHOST, PNICHOST, BNICHOST, NULL };
|
||||
|
||||
# TOPDOMAIN=\"<top-level-domain>\"
|
||||
# - This option will fix the default host to be
|
||||
# <top-level-domain>-whois.ripe.net, which may point to a secondary
|
||||
# server inside your top-level domain. If there is no such secondary
|
||||
# server, it will point to whois.ripe.net, the default. This option
|
||||
# overrules the CLEVER option.
|
||||
# The TOPDOMAIN option implies the RIPE option.
|
||||
|
||||
*/
|
||||
|
||||
#if defined(TOPDOMAIN) || defined(CLEVER)
|
||||
#ifndef RIPE
|
||||
#define RIPE
|
||||
#endif /* !RIPE */
|
||||
#endif /* TOPDOMAIN || CLEVER */
|
||||
|
||||
#define NICHOST "whois.internic.net"
|
||||
|
||||
int main(int, char **);
|
||||
static void usage(void);
|
||||
static void closesocket(int, int);
|
||||
static void termhandler(int);
|
||||
|
||||
void
|
||||
usage(void)
|
||||
{
|
||||
#ifdef RIPE
|
||||
#ifdef NETWORKUPDATE
|
||||
(void)fprintf(stderr, "\nUsage: networkupdate [-46] [-h hostname] [-p port]");
|
||||
#else
|
||||
(void)fprintf(stderr, "\nUsage: whois [-46aFLmMrSvR] [-h hostname] [-s sources] [-T types] [-i attr] keys\n");
|
||||
(void)fprintf(stderr, " whois -t type");
|
||||
(void)fprintf(stderr, " whois -v type");
|
||||
#endif
|
||||
#else
|
||||
(void)fprintf(stderr, "\nUsage: whois [-46] [-h hostname] [-p port] name ...");
|
||||
#endif
|
||||
(void)fprintf(stderr, "\n\nWhere:\n\n");
|
||||
(void)fprintf(stderr, "-4 Use IPv4 Only\n");
|
||||
(void)fprintf(stderr, "-6 Use IPv6 Only\n");
|
||||
#ifdef RIPE
|
||||
#ifndef NETWORKUPDATE
|
||||
(void)fprintf(stderr, "-a search all databases\n");
|
||||
(void)fprintf(stderr, "-F fast raw output\n");
|
||||
#endif
|
||||
#endif
|
||||
(void)fprintf(stderr, "-h hostname search alternate server\n");
|
||||
#ifdef RIPE
|
||||
#ifndef NETWORKUPDATE
|
||||
(void)fprintf(stderr, "-i [attr][[,attr] ... ] do an inverse lookup for specified attributes\n");
|
||||
(void)fprintf(stderr, "-L find all Less specific matches\n");
|
||||
(void)fprintf(stderr, "-m find first level more specific matches\n");
|
||||
(void)fprintf(stderr, "-M find all More specific matches\n");
|
||||
#endif
|
||||
#endif
|
||||
(void)fprintf(stderr, "-p port port to connect to\n");
|
||||
#ifdef RIPE
|
||||
#ifndef NETWORKUPDATE
|
||||
(void)fprintf(stderr, "-r turn off recursive lookups\n");
|
||||
(void)fprintf(stderr, "-s source[[,source] ... ] search databases with source 'source'\n");
|
||||
(void)fprintf(stderr, "-S tell server to leave out 'syntactic sugar'\n");
|
||||
(void)fprintf(stderr, "-t type requests template for object of type 'type'\n");
|
||||
(void)fprintf(stderr, "-v type requests verbose template for object of type 'type'\n");
|
||||
(void)fprintf(stderr, "-R force to show local copy of the domain object even if it contains referral\n");
|
||||
(void)fprintf(stderr, "-T type[[,type] ... ] only look for objects of type 'type'\n\n");
|
||||
(void)fprintf(stderr, "Please note that most of these flags are NOT understood by\n");
|
||||
(void)fprintf(stderr, "non RIPE whois servers\n");
|
||||
#endif
|
||||
#endif
|
||||
(void)fprintf(stderr, "\n");
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int s;
|
||||
|
||||
void
|
||||
closesocket(int s, int child)
|
||||
{
|
||||
/* printf("close connection child=%i\n", child); */
|
||||
|
||||
close(s);
|
||||
|
||||
#ifdef NETWORKUPDATE
|
||||
if (child==0) {
|
||||
kill(getppid(), SIGTERM);
|
||||
}
|
||||
#endif
|
||||
|
||||
exit(0);
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
termhandler(int sig)
|
||||
{
|
||||
closesocket(s,1);
|
||||
}
|
||||
|
||||
|
||||
#ifdef RIPE
|
||||
#define occurs(str,pat) ((int) strstr((str),(pat)))
|
||||
#endif
|
||||
static __dead void usage(void);
|
||||
static int whois(const char *, const char *, const char *, int);
|
||||
static char *choose_server(const char *, const char *);
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
extern char *optarg;
|
||||
extern int optind;
|
||||
FILE *sfi;
|
||||
FILE *sfo;
|
||||
int ch;
|
||||
struct addrinfo *dst, hints;
|
||||
int af=PF_UNSPEC;
|
||||
int error;
|
||||
char *host, *whoishost;
|
||||
int optp=0;
|
||||
char *optport="whois";
|
||||
#ifdef DEBUG
|
||||
int verb=1;
|
||||
#else /*DEBUG */
|
||||
int verb=0;
|
||||
int ch, flags, rval;
|
||||
char *host, *name, *country, *server;
|
||||
|
||||
#ifdef SOCKS
|
||||
SOCKSinit(argv[0]);
|
||||
#endif
|
||||
#ifdef RIPE
|
||||
int opthost=0;
|
||||
#ifndef NETWORKUPDATE
|
||||
/* normal whois client */
|
||||
char *string;
|
||||
int alldatabases=0;
|
||||
int optsource=0, optrecur=0, optfast=0, opttempl=0, optverbose=0;
|
||||
int optobjtype=0, optsugar=0, optinverselookup=0, optgetupdates=0;
|
||||
int optL=0, optm=0, optM=0, optchanged=0, optnonreferral=0;
|
||||
char *source=NULL, *templ=NULL, *verbose=NULL, *objtype=NULL,
|
||||
*inverselookup=NULL, *getupdates=NULL;
|
||||
#else /* NETWORKUPDATE */
|
||||
/* networkupdate client */
|
||||
int prev;
|
||||
char domainname[64]; /* that's what sys/param.h says */
|
||||
struct passwd *passwdentry;
|
||||
int child;
|
||||
#endif
|
||||
#ifdef CLEVER
|
||||
int myerror;
|
||||
char *mytoplevel;
|
||||
char *myhost;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef TOPDOMAIN
|
||||
char topdomain[] = TOPDOMAIN "-whois.ripe.net";
|
||||
host = topdomain;
|
||||
#else
|
||||
host = NICHOST;
|
||||
#endif
|
||||
|
||||
#ifdef RIPE
|
||||
#ifdef NETWORKUPDATE
|
||||
while ((ch = getopt(argc, argv, "46h:p:")) != -1)
|
||||
#else
|
||||
while ((ch = getopt(argc, argv, "46acFg:h:i:LmMp:rs:SRt:T:v:")) != -1)
|
||||
#endif
|
||||
#else
|
||||
while ((ch = getopt(argc, argv, "46h:p:")) != -1)
|
||||
#endif
|
||||
switch((char)ch) {
|
||||
case '4':
|
||||
af = PF_INET;
|
||||
break;
|
||||
case '6':
|
||||
af = PF_INET6;
|
||||
break;
|
||||
case 'h':
|
||||
host = optarg;
|
||||
opthost = 1;
|
||||
break;
|
||||
case 'p':
|
||||
optport=optarg;
|
||||
optp =1;
|
||||
break;
|
||||
#ifdef RIPE
|
||||
#ifndef NETWORKUPDATE
|
||||
case 'a':
|
||||
alldatabases=1;
|
||||
break;
|
||||
case 'c':
|
||||
optchanged=1;
|
||||
break;
|
||||
case 'F':
|
||||
optfast = 1;
|
||||
break;
|
||||
case 'g':
|
||||
getupdates=optarg;
|
||||
optgetupdates=1;
|
||||
break;
|
||||
case 'i':
|
||||
inverselookup=optarg;
|
||||
optinverselookup = 1;
|
||||
break;
|
||||
case 'L':
|
||||
if (optM || optm) {
|
||||
fprintf(stderr, "Only one of -L, -m or -M allowed\n\n");
|
||||
usage();
|
||||
}
|
||||
optL=1;
|
||||
break;
|
||||
case 'm':
|
||||
if (optM || optL) {
|
||||
fprintf(stderr, "Only one of -L, -m or -M allowed\n\n");
|
||||
usage();
|
||||
}
|
||||
optm=1;
|
||||
break;
|
||||
case 'M':
|
||||
if (optL || optm) {
|
||||
fprintf(stderr, "Only one of -L, -m or -M allowed\n\n");
|
||||
usage();
|
||||
}
|
||||
optM=1;
|
||||
break;
|
||||
|
||||
case 's':
|
||||
source = optarg;
|
||||
optsource=1;
|
||||
break;
|
||||
case 'S':
|
||||
optsugar=1;
|
||||
break;
|
||||
case 'R':
|
||||
optnonreferral=1;
|
||||
break;
|
||||
case 'r':
|
||||
optrecur=1;
|
||||
break;
|
||||
case 't':
|
||||
templ=optarg;
|
||||
opttempl=1;
|
||||
break;
|
||||
case 'v':
|
||||
verbose=optarg;
|
||||
optverbose=1;
|
||||
break;
|
||||
case 'T':
|
||||
objtype=optarg;
|
||||
optobjtype=1;
|
||||
break;
|
||||
|
||||
#endif
|
||||
#endif
|
||||
case '?':
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
country = host = server = NULL;
|
||||
flags = rval = 0;
|
||||
while ((ch = getopt(argc, argv, "aAc:dgh:ilmp:qQrR6")) != -1)
|
||||
switch(ch) {
|
||||
case 'a':
|
||||
host = ANICHOST;
|
||||
break;
|
||||
case 'A':
|
||||
host = PNICHOST;
|
||||
break;
|
||||
case 'c':
|
||||
country = optarg;
|
||||
break;
|
||||
case 'd':
|
||||
host = DNICHOST;
|
||||
break;
|
||||
case 'g':
|
||||
host = GNICHOST;
|
||||
break;
|
||||
case 'h':
|
||||
host = optarg;
|
||||
break;
|
||||
case 'i':
|
||||
host = INICHOST;
|
||||
break;
|
||||
case 'l':
|
||||
host = LNICHOST;
|
||||
break;
|
||||
case 'm':
|
||||
host = MNICHOST;
|
||||
break;
|
||||
case 'p':
|
||||
port = optarg;
|
||||
break;
|
||||
case 'q':
|
||||
/* deprecated, now the default */
|
||||
break;
|
||||
case 'Q':
|
||||
flags |= WHOIS_QUICK;
|
||||
break;
|
||||
case 'r':
|
||||
host = RNICHOST;
|
||||
break;
|
||||
case 'R':
|
||||
host = RUNICHOST;
|
||||
break;
|
||||
case '6':
|
||||
host = SNICHOST;
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
#ifdef RIPE
|
||||
#ifdef NETWORKUPDATE
|
||||
if (argc>0)
|
||||
usage();
|
||||
#else
|
||||
if ((argc<=0) && !opttempl && !optverbose && !optgetupdates && (!(opttempl && optgetupdates)))
|
||||
usage();
|
||||
#endif
|
||||
#else
|
||||
if (argc<=0)
|
||||
usage();
|
||||
#endif
|
||||
if (!argc || (country != NULL && host != NULL))
|
||||
usage();
|
||||
|
||||
if (!opthost) {
|
||||
|
||||
#ifdef CLEVER
|
||||
whoishost=(char *)calloc(MAXHOSTNAMELEN, sizeof(char));
|
||||
if (!whoishost)
|
||||
err(1, "malloc");
|
||||
myhost =(char *)calloc(MAXHOSTNAMELEN, sizeof(char));
|
||||
if (!myhost)
|
||||
err(1, "malloc");
|
||||
myerror = gethostname(myhost, MAXHOSTNAMELEN);
|
||||
if (myerror >= 0) {
|
||||
if (occurs(myhost, ".")) {
|
||||
mytoplevel = rindex(myhost,'.');
|
||||
mytoplevel++;
|
||||
(void) snprintf(whoishost, MAXHOSTNAMELEN, "%s-whois.ripe.net",
|
||||
mytoplevel);
|
||||
if (verb) fprintf(stderr, "Clever guess: %s\n", whoishost);
|
||||
}
|
||||
}
|
||||
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_flags = AI_CANONNAME;
|
||||
hints.ai_family = af;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
hints.ai_protocol = 0;
|
||||
error = getaddrinfo(host, optport, &hints, &dst);
|
||||
if ((error) && (verb))
|
||||
fprintf(stderr,"No such host: %s\n", whoishost);
|
||||
if (error) {
|
||||
#endif
|
||||
|
||||
whoishost=NICHOST;
|
||||
|
||||
if (verb)
|
||||
fprintf(stderr, "Default host: %s\n\n", whoishost);
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_flags = AI_CANONNAME;
|
||||
hints.ai_family = af;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
hints.ai_protocol = 0;
|
||||
error = getaddrinfo(host, optport , &hints, &dst);
|
||||
if (error) {
|
||||
fprintf(stderr,"No such host: %s\n", whoishost);
|
||||
if (verb) fprintf(stderr, "Now I give up ...\n");
|
||||
perror("Unknown host");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
#ifdef CLEVER
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
if (verb)
|
||||
fprintf(stderr, "Trying: %s\n\n", host);
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_flags = AI_CANONNAME;
|
||||
hints.ai_family = af;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
hints.ai_protocol = 0;
|
||||
error = getaddrinfo(host, optport, &hints, &dst);
|
||||
if (error) {
|
||||
(void)fprintf(stderr, "whois: %s: ", host);
|
||||
perror("Unknown host");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
for (/*nothing*/; dst; dst = dst->ai_next) {
|
||||
s = socket(dst->ai_family, dst->ai_socktype, dst->ai_protocol);
|
||||
if (s < 0)
|
||||
continue;
|
||||
if (connect(s, dst->ai_addr, dst->ai_addrlen) < 0) {
|
||||
close(s);
|
||||
if (verb) (void)fprintf(stderr, "whois: connect miss\n");
|
||||
continue;
|
||||
}
|
||||
/*okay*/
|
||||
break;
|
||||
}
|
||||
if (dst == NULL) {
|
||||
perror("whois: connect");
|
||||
exit(1);
|
||||
}
|
||||
if (verb) (void)fprintf(stderr, "whois: connect success\n");
|
||||
|
||||
#ifndef NETWORKUPDATE
|
||||
sfi = fdopen(s, "r");
|
||||
sfo = fdopen(s, "w");
|
||||
if (sfi == NULL || sfo == NULL) {
|
||||
perror("whois: fdopen");
|
||||
(void)close(s);
|
||||
exit(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
signal(SIGTERM, termhandler);
|
||||
|
||||
#ifdef RIPE
|
||||
#ifdef NETWORKUPDATE
|
||||
|
||||
if ((child=fork())==0) {
|
||||
|
||||
sfo = fdopen(s, "w");
|
||||
if (sfo == NULL) {
|
||||
perror("whois: fdopen");
|
||||
(void)close(s);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (gethostname(domainname, sizeof(domainname))) {
|
||||
fprintf(stderr, "error when doing gethostname()");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
passwdentry=getpwuid(getuid());
|
||||
|
||||
fprintf(sfo, "-Vnc2.0 -U %s %s\n", passwdentry->pw_name, domainname);
|
||||
fflush(sfo);
|
||||
|
||||
prev='\0';
|
||||
|
||||
while ((ch=getchar()) != EOF) {
|
||||
|
||||
fputc(ch, sfo);
|
||||
|
||||
if (ch=='\n') fflush(sfo);
|
||||
if (feof(sfo)) closesocket(s, child);
|
||||
if ((ch=='.') && (prev=='\n')) closesocket(s, child);
|
||||
if (!isspace(ch) || ((!isspace(prev)) && (ch=='\n'))) prev=ch;
|
||||
}
|
||||
|
||||
closesocket(s, child);
|
||||
|
||||
}
|
||||
|
||||
sfi = fdopen(s, "r");
|
||||
if (sfi == NULL) {
|
||||
perror("whois: fdopen");
|
||||
(void)close(s);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
if (alldatabases)
|
||||
(void)fprintf(sfo, "-a ");
|
||||
if (optchanged)
|
||||
(void)fprintf(sfo, "-c ");
|
||||
if (optfast)
|
||||
(void)fprintf(sfo, "-F ");
|
||||
if (optgetupdates)
|
||||
(void)fprintf(sfo, "-g %s ", getupdates);
|
||||
if (optinverselookup)
|
||||
(void)fprintf(sfo, "-i %s ", inverselookup);
|
||||
if (optL)
|
||||
(void)fprintf(sfo, "-L ");
|
||||
if (optm)
|
||||
(void)fprintf(sfo, "-m ");
|
||||
if (optM)
|
||||
(void)fprintf(sfo, "-M ");
|
||||
if (optrecur)
|
||||
(void)fprintf(sfo, "-r ");
|
||||
if (optsource)
|
||||
(void)fprintf(sfo, "-s %s ", source);
|
||||
if (optsugar)
|
||||
(void)fprintf(sfo, "-S ");
|
||||
if (optnonreferral)
|
||||
(void)fprintf(sfo, "-R ");
|
||||
if (opttempl)
|
||||
(void)fprintf(sfo, "-t %s ", templ);
|
||||
if (optverbose)
|
||||
(void)fprintf(sfo, "-v %s ", verbose);
|
||||
if (optobjtype)
|
||||
(void)fprintf(sfo, "-T %s ", objtype);
|
||||
|
||||
/* we can only send the -V when we are sure that we are dealing with
|
||||
a RIPE whois server :-( */
|
||||
|
||||
whoishost = strdup(host);
|
||||
if (!whoishost)
|
||||
err(1, "malloc");
|
||||
for (string=whoishost;(*string=(char)tolower(*string));string++);
|
||||
|
||||
if (strstr(whoishost, "ripe.net") ||
|
||||
strstr(whoishost, "ra.net") ||
|
||||
strstr(whoishost, "apnic.net") ||
|
||||
strstr(whoishost, "mci.net") ||
|
||||
strstr(whoishost, "isi.edu") ||
|
||||
strstr(whoishost, "garr.it") ||
|
||||
strstr(whoishost, "ans.net") ||
|
||||
alldatabases || optfast || optgetupdates || optinverselookup ||
|
||||
optL || optm || optM || optrecur || optsugar || optsource ||
|
||||
opttempl || optverbose || optobjtype)
|
||||
(void)fprintf(sfo, "-VwC2.0 ");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef NETWORKUPDATE
|
||||
while (argc-- > 1)
|
||||
(void)fprintf(sfo, "%s ", *argv++);
|
||||
if (*argv) (void)fputs(*argv, sfo);
|
||||
(void)fputs("\r\n", sfo);
|
||||
(void)fflush(sfo);
|
||||
#endif
|
||||
|
||||
while ((ch = getc(sfi)) != EOF)
|
||||
putchar(ch);
|
||||
|
||||
closesocket(s, 1);
|
||||
|
||||
exit(0);
|
||||
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, flags);
|
||||
exit(rval);
|
||||
}
|
||||
|
||||
static int
|
||||
whois(const char *query, const char *server, const char *port, int flags)
|
||||
{
|
||||
FILE *sfi, *sfo;
|
||||
char *buf, *p, *nhost, *nbuf = NULL;
|
||||
size_t len;
|
||||
int i, s, error;
|
||||
const char *reason = NULL;
|
||||
struct addrinfo hints, *res, *ai;
|
||||
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_flags = 0;
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
error = getaddrinfo(server, port, &hints, &res);
|
||||
if (error) {
|
||||
warnx("%s: %s", server, gai_strerror(error));
|
||||
return (1);
|
||||
}
|
||||
|
||||
for (s = -1, ai = res; ai != NULL; ai = ai->ai_next) {
|
||||
s = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
|
||||
if (s < 0) {
|
||||
reason = "socket";
|
||||
continue;
|
||||
}
|
||||
if (connect(s, ai->ai_addr, ai->ai_addrlen) < 0) {
|
||||
reason = "connect";
|
||||
close(s);
|
||||
s = -1;
|
||||
continue;
|
||||
}
|
||||
break; /*okay*/
|
||||
}
|
||||
if (s < 0) {
|
||||
if (reason)
|
||||
warn("%s: %s", server, reason);
|
||||
else
|
||||
warn("unknown error in connection attempt");
|
||||
freeaddrinfo(res);
|
||||
return (1);
|
||||
}
|
||||
|
||||
sfi = fdopen(s, "r");
|
||||
sfo = fdopen(s, "w");
|
||||
if (sfi == NULL || sfo == NULL)
|
||||
err(1, "fdopen");
|
||||
(void)fprintf(sfo, "%s\r\n", query);
|
||||
(void)fflush(sfo);
|
||||
nhost = NULL;
|
||||
while ((buf = fgetln(sfi, &len)) != NULL) {
|
||||
p = buf + len - 1;
|
||||
if (isspace((unsigned char)*p)) {
|
||||
do
|
||||
*p = '\0';
|
||||
while (p > buf && isspace((unsigned char)*--p));
|
||||
} else {
|
||||
if ((nbuf = malloc(len + 1)) == NULL)
|
||||
err(1, "malloc");
|
||||
memcpy(nbuf, buf, len);
|
||||
nbuf[len] = '\0';
|
||||
buf = nbuf;
|
||||
}
|
||||
(void)puts(buf);
|
||||
|
||||
if (nhost != NULL || !(flags & WHOIS_RECURSE))
|
||||
continue;
|
||||
|
||||
if ((p = strstr(buf, WHOIS_SERVER_ID))) {
|
||||
p += sizeof(WHOIS_SERVER_ID) - 1;
|
||||
while (isblank(*p))
|
||||
p++;
|
||||
if ((len = strcspn(p, " \t\n\r"))) {
|
||||
if ((nhost = malloc(len + 1)) == NULL)
|
||||
err(1, "malloc");
|
||||
memcpy(nhost, p, len);
|
||||
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]);
|
||||
if (nhost == NULL)
|
||||
err(1, "strdup");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (nbuf != NULL)
|
||||
free(nbuf);
|
||||
|
||||
if (nhost != NULL) {
|
||||
error = whois(query, nhost, port, 0);
|
||||
free(nhost);
|
||||
}
|
||||
freeaddrinfo(res);
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* If no country is specified determine the top level domain from the query.
|
||||
* If the TLD is a number, query ARIN, otherwise, use TLD.whois-server.net.
|
||||
* If the domain does not contain '.', check to see if it is an NSI handle
|
||||
* (starts with '!') or a CORE handle (COCO-[0-9]+ or COHO-[0-9]+).
|
||||
* Fall back to NICHOST for the non-handle case.
|
||||
*/
|
||||
static char *
|
||||
choose_server(const char *name, const char *country)
|
||||
{
|
||||
static char *server;
|
||||
const char *qhead;
|
||||
char *ep;
|
||||
size_t len;
|
||||
|
||||
if (country != NULL)
|
||||
qhead = country;
|
||||
else if ((qhead = strrchr(name, '.')) == NULL) {
|
||||
if (*name == '!')
|
||||
return (INICHOST);
|
||||
else if ((strncasecmp(name, "COCO-", 5) == 0 ||
|
||||
strncasecmp(name, "COHO-", 5) == 0) &&
|
||||
strtol(name + 5, &ep, 10) > 0 && *ep == '\0')
|
||||
return (CNICHOST);
|
||||
else
|
||||
return (NICHOST);
|
||||
} else if (isdigit(*(++qhead)))
|
||||
return (ANICHOST);
|
||||
len = strlen(qhead) + sizeof(QNICHOST_TAIL);
|
||||
if ((server = realloc(server, len)) == NULL)
|
||||
err(1, "realloc");
|
||||
strlcpy(server, qhead, len);
|
||||
strlcat(server, QNICHOST_TAIL, len);
|
||||
return (server);
|
||||
}
|
||||
|
||||
static __dead void
|
||||
usage(void)
|
||||
{
|
||||
extern char *__progname;
|
||||
|
||||
(void)fprintf(stderr,
|
||||
"usage: %s [-aAdgilmQrR6] [-c country-code | -h hostname] "
|
||||
"[-p port] name ...\n", __progname);
|
||||
exit(1);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user