From 75e8d1b64d2de00f0a35c0e2fc05fb0c89312069 Mon Sep 17 00:00:00 2001 From: Kelvin Sherlock Date: Mon, 9 Jul 2012 23:10:15 -0400 Subject: [PATCH] gno/me compatibility --- bin/whois/sysexits.h | 118 +++++++++++++++++++++ bin/whois/whois.1G | 246 +++++++++++++++++++++++++++++++++++++++++++ bin/whois/whois.c | 214 ++++++++++++++++++++++++++++++++++++- 3 files changed, 576 insertions(+), 2 deletions(-) create mode 100644 bin/whois/sysexits.h create mode 100644 bin/whois/whois.1G diff --git a/bin/whois/sysexits.h b/bin/whois/sysexits.h new file mode 100644 index 0000000..464cb11 --- /dev/null +++ b/bin/whois/sysexits.h @@ -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_ */ diff --git a/bin/whois/whois.1G b/bin/whois/whois.1G new file mode 100644 index 0000000..add50dc --- /dev/null +++ b/bin/whois/whois.1G @@ -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 diff --git a/bin/whois/whois.c b/bin/whois/whois.c index 1ee8959..70d8937 100644 --- a/bin/whois/whois.c +++ b/bin/whois/whois.c @@ -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 +#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 #include @@ -62,6 +67,17 @@ __FBSDID("$FreeBSD: src/usr.bin/whois/whois.c,v 1.41 2004/08/25 15:34:44 mbr Exp #include #include +#ifdef __GNO__ + +#include + +#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; } }