gno/me compatibility

This commit is contained in:
Kelvin Sherlock 2012-07-09 23:10:15 -04:00
parent 236facc747
commit 75e8d1b64d
3 changed files with 576 additions and 2 deletions

118
bin/whois/sysexits.h Normal file
View File

@ -0,0 +1,118 @@
/*
* Copyright (c) 1987, 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
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)sysexits.h 8.1 (Berkeley) 6/2/93
*/
#ifndef _SYSEXITS_H_
#define _SYSEXITS_H_
/*
* SYSEXITS.H -- Exit status codes for system programs.
*
* This include file attempts to categorize possible error
* exit statuses for system programs, notably delivermail
* and the Berkeley network.
*
* Error numbers begin at EX__BASE to reduce the possibility of
* clashing with other exit statuses that random programs may
* already return. The meaning of the codes is approximately
* as follows:
*
* EX_USAGE -- The command was used incorrectly, e.g., with
* the wrong number of arguments, a bad flag, a bad
* syntax in a parameter, or whatever.
* EX_DATAERR -- The input data was incorrect in some way.
* This should only be used for user's data & not
* system files.
* EX_NOINPUT -- An input file (not a system file) did not
* exist or was not readable. This could also include
* errors like "No message" to a mailer (if it cared
* to catch it).
* EX_NOUSER -- The user specified did not exist. This might
* be used for mail addresses or remote logins.
* EX_NOHOST -- The host specified did not exist. This is used
* in mail addresses or network requests.
* EX_UNAVAILABLE -- A service is unavailable. This can occur
* if a support program or file does not exist. This
* can also be used as a catchall message when something
* you wanted to do doesn't work, but you don't know
* why.
* EX_SOFTWARE -- An internal software error has been detected.
* This should be limited to non-operating system related
* errors as possible.
* EX_OSERR -- An operating system error has been detected.
* This is intended to be used for such things as "cannot
* fork", "cannot create pipe", or the like. It includes
* things like getuid returning a user that does not
* exist in the passwd file.
* EX_OSFILE -- Some system file (e.g., /etc/passwd, /etc/utmp,
* etc.) does not exist, cannot be opened, or has some
* sort of error (e.g., syntax error).
* EX_CANTCREAT -- A (user specified) output file cannot be
* created.
* EX_IOERR -- An error occurred while doing I/O on some file.
* EX_TEMPFAIL -- temporary failure, indicating something that
* is not really an error. In sendmail, this means
* that a mailer (e.g.) could not create a connection,
* and the request should be reattempted later.
* EX_PROTOCOL -- the remote system returned something that
* was "not possible" during a protocol exchange.
* EX_NOPERM -- You did not have sufficient permission to
* perform the operation. This is not intended for
* file system problems, which should use NOINPUT or
* CANTCREAT, but rather for higher level permissions.
*/
#define EX_OK 0 /* successful termination */
#define EX__BASE 64 /* base value for error messages */
#define EX_USAGE 64 /* command line usage error */
#define EX_DATAERR 65 /* data format error */
#define EX_NOINPUT 66 /* cannot open input */
#define EX_NOUSER 67 /* addressee unknown */
#define EX_NOHOST 68 /* host name unknown */
#define EX_UNAVAILABLE 69 /* service unavailable */
#define EX_SOFTWARE 70 /* internal software error */
#define EX_OSERR 71 /* system error (e.g., can't fork) */
#define EX_OSFILE 72 /* critical OS file missing */
#define EX_CANTCREAT 73 /* can't create (user) output file */
#define EX_IOERR 74 /* input/output error */
#define EX_TEMPFAIL 75 /* temp failure; user is invited to retry */
#define EX_PROTOCOL 76 /* remote error in protocol */
#define EX_NOPERM 77 /* permission denied */
#define EX_CONFIG 78 /* configuration error */
#define EX__MAX 78 /* maximum listed value */
#endif /* !_SYSEXITS_H_ */

246
bin/whois/whois.1G Normal file
View File

@ -0,0 +1,246 @@
.\" Copyright (c) 1985, 1990, 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
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\" 3. All advertising materials mentioning features or use of this software
.\" must display the following acknowledgement:
.\" This product includes software developed by the University of
.\" California, Berkeley and its contributors.
.\" 4. Neither the name of the University nor the names of its contributors
.\" may be used to endorse or promote products derived from this software
.\" without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" From: @(#)whois.1 8.1 (Berkeley) 6/6/93
.\" $FreeBSD: src/usr.bin/whois/whois.1,v 1.32 2004/06/14 17:30:46 bms Exp $
.\"
.TH WHOIS 1 "June 14, 2004" "" "Commands and Applications"
.SH NAME
.BR whois
\- Internet domain name and network number directory service
.SH SYNOPSIS
.BR whois
.RB [ -aAbdgiIlmQrR6 ]
[
.BI -c country-code
|
.BI -h host
]
[
.BI -p port
]
.BR name ...
.SH DESCRIPTION
The
.BR whois
utility looks up records in the databases maintained by several
Network Information Centers
(NICs).
.LP
The options are as follows:
.RS
.B -6
Use the IPv6 Resource Center (6bone) database.
It contains network names and addresses for the IPv6 network.
.B -A
Use the Asia/Pacific Network Information Center (APNIC) database.
It contains network numbers used in East Asia, Australia,
New Zealand, and the Pacific islands.
.B -a
Use the American Registry for Internet Numbers (ARIN) database.
It contains network numbers used in those parts of the world covered
neither by APNIC nor by RIPE.
.LP
(Hint: All point of contact handles in the ARIN
whois database end with "-ARIN".)
.LP
.B -b
Use the Network Abuse Clearinghouse database.
It contains addresses to which network abuse should be reported,
indexed by domain name.
.BI -c country-code
This is the equivalent of using the
.B -h
option with an argument of
"
.IR country-code .whois-servers.net
".
.B -d
Use the US Department of Defense
database.
It contains points of contact for subdomains of
.IR MIL .
.B -g
Use the US non-military federal government database, which contains points of
contact for subdomains of
.IR .GOV .
.BI -h host
Use the specified host instead of the default variant.
Either a host name or an IP address may be specified.
.LP
By default
.BR whois
constructs the name of a whois server to use from the top-level domain
(TLD) of the supplied (single) argument, and appending
".whois-servers.net".
This effectively allows a suitable whois server to be selected
automatically for a large number of TLDs.
.LP
In the event that an IP
address is specified, the whois server will default to the American
Registry for Internet Numbers (ARIN).
If a query to ARIN
references APNIC, LACNIC, or RIPE,
that server will be queried also, provided that the
.B -Q
option is not specified.
.LP
If the query is not a domain name or IP address,
.BR whois
will fall back to
.IR whois.crsnic.net .
.B -I
Use the Internet Assigned Numbers Authority (IANA) database.
It contains network information for top-level domains.
.B -i
Use the Network Solutions Registry for Internet Numbers
.RI ( whois.networksolutions.com )
database.
It contains network numbers and domain contact information for most of
.IR .COM , .NET , .ORG and .EDU
domains.
.LP
.BR NOTE !
The registration of these domains is now done
by a number of independent and competing registrars.
This database holds no information on domains registered by organizations
other than Network Solutions, Inc.
Also, note that the
InterNIC
database
.RI ( whois.internic.net )
is no longer handled by Network Solutions, Inc.
For details, see
.IR http://www.internic.net/ .
.LP
(Hint: Contact information, identified by the term
.IR handle ,
can be looked up by prefixing "handle" to the NIC
handle in the query.)
.B -l
Use the Latin American and Caribbean IP address Regional Registry
(LACNIC) database.
It contains network numbers used in much of Latin America and the
Caribbean.
.B -m
Use the Route Arbiter Database (RADB) database.
It contains route policy specifications for a large
number of operators' networks.
.BI -p port
Connect to the whois server on
.BR port .
If this option is not specified,
.BR whois
defaults to port 43.
.B -Q
Do a quick lookup. This means that
.BR whois
will not attempt to lookup the name in the authoritative whois
server (if one is listed).
This option has no effect when combined with any other options.
.B -R
Use the Russia Network Information Center (RIPN) database.
It contains network numbers and domain contact information
for subdomains of
.IR .RU .
This option is deprecated; use the
.BR -c
option with an argument of "RU"
instead.
.B -r
Use the R\(aaeseaux IP Europ\(aaeens
(RIPE) database.
It contains network numbers and domain contact information
for Europe.
.RE
.LP
The operands specified to
.BR whois
are treated independently and may be used
as queries on different whois servers.
.SH EXAMPLES
Most types of data, such as domain names and IP
addresses, can be used as arguments to
.BR whois
without any options, and
.BR whois
will choose the correct whois server to query.
Some exceptions, where
.BR whois
will not be able to handle data correctly, are detailed below.
.LP
To obtain contact information about an
administrator located in the Russian
TLD domain
"RU",
use the
.BR -c
option as shown in the following example, where
.I CONTACT-ID
is substituted with the actual contact identifier.
.LP
.nf
whois \-c RU CONTACT-ID
\.fi
.LP
(Note: This example is specific to the TLD
"RU", but other TLDs
can be queried by using a similar syntax.)
.LP
The following example demonstrates how to obtain information about an
IPv6
address or hostname using the
.BR -6
option, which directs the query to 6bone.
.LP
.nf
whois \-6 IPv6-IP-Address
\.fi
.LP
The following example demonstrates how to query
a whois server using a non-standard port, where
``query-data'' is the query to be sent to
``whois.example.com''
on port ``rwhois''
(written numerically as 4321).
.LP
.nf
whois \-h whois.example.com \-p rwhois query-data
.fi
.SH SEE ALSO
Ken Harrenstien and Vic White,
.IR NICNAME/WHOIS
, 1 March 1982 RFC 812
.SH HISTORY
The
.BR whois
command appeared in BSD 4.3

View File

@ -30,6 +30,9 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifdef __ORCAC__
#pragma optimize 79
#endif
#ifndef lint
static const char copyright[] =
@ -44,9 +47,11 @@ static char sccsid[] = "@(#)whois.c 8.1 (Berkeley) 6/6/93";
#endif
#include <sys/cdefs.h>
#ifndef __GNO__
#ifndef __APPLE__
__FBSDID("$FreeBSD: src/usr.bin/whois/whois.c,v 1.41 2004/08/25 15:34:44 mbr Exp $");
#endif
#endif
#include <sys/types.h>
#include <sys/socket.h>
@ -62,6 +67,17 @@ __FBSDID("$FreeBSD: src/usr.bin/whois/whois.c,v 1.41 2004/08/25 15:34:44 mbr Exp
#include <sysexits.h>
#include <unistd.h>
#ifdef __GNO__
#include <gno/gno.h>
#undef getc
#undef putc
#undef getchar
#undef putchar
#endif
#define ABUSEHOST "whois.abuse.net"
#define NICHOST "whois.crsnic.net"
#define INICHOST "whois.networksolutions.com"
@ -91,22 +107,141 @@ const char *ip_whois[] = { LNICHOST, RNICHOST, PNICHOST, BNICHOST, NULL };
const char *port = DEFAULT_PORT;
static char *choose_server(char *);
#ifndef __GNO__
static struct addrinfo *gethostinfo(char const *host, int exit_on_error);
#endif
#ifndef __GNO__
#ifdef __APPLE__
static void s_asprintf(char **ret, const char *format, ...) __attribute__((__format__(printf, 2, 3)));
#else
static void s_asprintf(char **ret, const char *format, ...) __printflike(2, 3);
#endif
#endif
static void usage(void);
static void whois(const char *, const char *, int);
#ifdef __GNO__
/*
* Find the first occurrence of find in s, where the search is limited to the
* first slen characters of s.
*/
char *
strnstr(const char *s, const char *find, size_t slen)
{
char c, sc;
size_t len;
if ((c = *find++) != '\0') {
len = strlen(find);
do {
do {
if (slen-- < 1 || (sc = *s++) == '\0')
return (NULL);
} while (sc != c);
if (len > slen)
return (NULL);
} while (strncmp(s, find, len) != 0);
s--;
}
return ((char *)s);
}
// not yet in the standard library.
size_t
strnlen(const char *s, size_t maxlen)
{
size_t len;
for (len = 0; len < maxlen; len++, s++) {
if (!*s)
break;
}
return (len);
}
char *
strndup(const char *str, size_t n)
{
size_t len;
char *copy;
len = strnlen(str, n);
if ((copy = malloc(len + 1)) == NULL)
return (NULL);
memcpy(copy, str, len);
copy[len] = '\0';
return (copy);
}
char *
stpcpy(char * to, const char * from)
{
for (; (*to = *from); ++from, ++to);
return(to);
}
char *xstrndup(const char *s1, size_t n)
{
char *rv;
rv = strndup(s1, n);
if (!rv)
{
err(EX_OSERR, "strndup()");
}
return rv;
}
char *xstrdup(const char *s1)
{
char *rv;
rv = strdup(s1);
if (!rv)
{
err(EX_OSERR, "strdup()");
}
return rv;
}
char *xstrdup2(const char *s1, const char *s2)
{
int l1, l2;
char *rv;
char *tmp;
l1 = strlen(s1);
l2 = strlen(s2);
rv = (char *)malloc(l1 + l2 + 1);
if (!rv)
{
err(EX_OSERR, "malloc()");
}
tmp = stpcpy(rv, s1);
tmp = stpcpy(tmp, s2);
return rv;
}
#endif
int
main(int argc, char *argv[])
main(int argc, char **argv)
{
const char *country, *host;
char *qnichost;
int ch, flags, use_qnichost;
#ifdef __GNO__
REPORT_STACK();
#endif
#ifdef SOCKS
SOCKSinit(argv[0]);
#endif
@ -190,7 +325,11 @@ main(int argc, char *argv[])
}
while (argc-- > 0) {
if (country != NULL) {
#ifdef __GNO__
qnichost = xstrdup2(country, QNICHOST_TAIL);
#else
s_asprintf(&qnichost, "%s%s", country, QNICHOST_TAIL);
#endif
whois(*argv, qnichost, flags);
} else if (use_qnichost)
if ((qnichost = choose_server(*argv)) != NULL)
@ -222,7 +361,11 @@ choose_server(char *domain)
if (strlen(domain) > sizeof("-NORID")-1 &&
strcasecmp(domain + strlen(domain) - sizeof("-NORID") + 1,
"-NORID") == 0) {
#ifdef __GNO__
retval = xstrdup(NORIDHOST);
#else
s_asprintf(&retval, "%s", NORIDHOST);
#endif
return (retval);
}
while (pos > domain && *pos != '.')
@ -230,12 +373,22 @@ choose_server(char *domain)
if (pos <= domain)
return (NULL);
if (isdigit((unsigned char)*++pos))
#ifdef __GNO__
retval = xstrdup(ANICHOST);
#else
s_asprintf(&retval, "%s", ANICHOST);
#endif
else
#ifdef __GNO__
retval = xstrdup2(pos, QNICHOST_TAIL);
#else
s_asprintf(&retval, "%s%s", pos, QNICHOST_TAIL);
#endif
return (retval);
}
#ifndef __GNO__
static struct addrinfo *
gethostinfo(char const *host, int exit_on_error)
{
@ -255,7 +408,9 @@ gethostinfo(char const *host, int exit_on_error)
}
return (res);
}
#endif
#ifndef __GNO__
/*
* Wrapper for asprintf(3) that exits on error.
*/
@ -272,15 +427,51 @@ s_asprintf(char **ret, const char *format, ...)
va_end(ap);
}
#endif
static void
whois(const char *query, const char *hostname, int flags)
{
FILE *sfi, *sfo;
struct addrinfo *hostres, *res;
char *buf, *host, *nhost, *p;
int i, s;
size_t c, len;
#ifdef __GNO__
// no getaddrinfo (yet)
// take from old whois.
struct hostent *hp;
struct servent *sp;
struct sockaddr_in sin;
hp = gethostbyname(hostname);
if (hp == NULL)
{
err(EX_OSERR, "gethostbyname(%s)", hostname);
}
s = socket(hp->h_addrtype, SOCK_STREAM, 0);
if (s < 0)
{
err(EX_OSERR, "socket()");
}
bzero((caddr_t)&sin, sizeof (sin));
bcopy(hp->h_addr, (char *)&sin.sin_addr, hp->h_length);
sp = getservbyname("whois", "tcp");
if (sp == NULL) {
(void)fprintf(stderr, "whois: whois/tcp: unknown service\n");
exit(1);
}
sin.sin_port = sp->s_port;
if (connect(s, (struct __SOCKADDR *)&sin, sizeof(sin)) < 0)
{
err(EX_OSERR, "connect()");
}
#else
struct addrinfo *hostres, *res;
hostres = gethostinfo(hostname, 1);
for (res = hostres; res; res = res->ai_next) {
s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
@ -294,8 +485,15 @@ whois(const char *query, const char *hostname, int flags)
if (res == NULL)
err(EX_OSERR, "connect()");
#endif
#ifdef __GNO__
sfi = fdopen(s, "rb");
sfo = fdopen(s, "wb");
#else
sfi = fdopen(s, "r");
sfo = fdopen(s, "w");
#endif
if (sfi == NULL || sfo == NULL)
err(EX_OSERR, "fdopen()");
if (strcmp(hostname, GERMNICHOST) == 0) {
@ -320,8 +518,12 @@ whois(const char *query, const char *hostname, int flags)
break;
}
}
#ifdef __GNO__
nhost = xstrndup(host, (int)(buf + len - host));
#else
s_asprintf(&nhost, "%.*s",
(int)(buf + len - host), host);
#endif
} else if ((host =
strnstr(buf, WHOIS_ORG_SERVER_ID, len)) != NULL) {
host += sizeof(WHOIS_ORG_SERVER_ID) - 1;
@ -331,16 +533,24 @@ whois(const char *query, const char *hostname, int flags)
break;
}
}
#ifdef __GNO__
nhost = xstrndup(host, (int)(buf + len - host));
#else
s_asprintf(&nhost, "%.*s",
(int)(buf + len - host), host);
#endif
} else if (strcmp(hostname, ANICHOST) == 0) {
for (c = 0; c <= len; c++)
buf[c] = tolower((int)buf[c]);
for (i = 0; ip_whois[i] != NULL; i++) {
if (strnstr(buf, ip_whois[i], len) !=
NULL) {
#ifdef __GNO__
nhost = xstrdup(ip_whois[i]);
#else
s_asprintf(&nhost, "%s",
ip_whois[i]);
#endif
break;
}
}