Initial commit

This commit is contained in:
Carsten Sonne Larsen 2016-07-13 23:51:58 +02:00
commit d3ce5c1c86
19 changed files with 3504 additions and 0 deletions

35
Makefile Normal file
View File

@ -0,0 +1,35 @@
# Portable Makefile generated by configure
all: whois
CC = m68k-amigaos-gcc
CFLAGS = -O2 -m68000 -noixemul -Iinclude -Wall -Werror
LDFLAGS = -s -liberty -lm -lgcc
config.h: getaddrinfo.h
touch config.h
version.h: config.h
touch version.h
whois.o: whois.c config.h version.h
error.o: error.c config.h
getaddrinfo.o: getaddrinfo.c config.h getaddrinfo.h
sgetln.o: sgetln.c config.h
strnstr.o: strnstr.c
wasprint.o: wasprint.c config.h
whois: whois.o error.o getaddrinfo.o sgetln.o strnstr.o wasprint.o
${CC} ${CFLAGS} -o whois whois.o error.o getaddrinfo.o sgetln.o strnstr.o wasprint.o ${LDFLAGS}
clean:
rm -f whois.o error.o getaddrinfo.o sgetln.o strnstr.o wasprint.o whois
depend:
@echo Dependencies already done

72
config.h Normal file
View File

@ -0,0 +1,72 @@
/*
* Written by Carsten Larsen.
* Public domain.
*/
#ifndef WHOIS_CONFIG_H
#define WHOIS_CONFIG_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netdb.h>
#if defined(__AMIGA__)
#include <clib/amitcp_protos.h>
#include <amitcp/socketbasetags.h>
#define IPTR ULONG
#endif
#if defined(__AROS__)
#include <errno.h>
#define HAVE_ADDRINFO
#define INTELCPU
#define Socket socket
#define Connect connect
#define Send send
#endif
#include "getaddrinfo.h"
#define OPEN_VER_ERROR "Cannot open %s (%d.0)\n"
#define DOSLIB_NAME "dos.library"
#define DOSLIB_REV 33L
#define BSDLIB_NAME "bsdsocket.library"
#define BSDLIB_REV 03L
#include <clib/exec_protos.h>
extern struct Library *DOSBase;
extern struct Library *SocketBase;
extern int errno;
const char *getprogname(void);
void setprogname(const char *progname);
void err0(int eval, const char *text);
void errx0(int eval, const char *text);
void errx2(int eval, const char *fmt, const void *arg1, const void *arg2);
void warn2(const char *fmt, const void *arg1, const void *arg2);
void warnx0(const char *text);
void warnx1(const char *fmt, const void *arg1);
void warnx2(const char *fmt, const void *arg1, const void *arg2);
void cpy1(char **dest, const char *src);
void cpy2(char **dest, const char *src1, const char *src2);
void cpy1pad(char **dest, int minlen, const char *src);
char *strnstr(const char *s, const char *find, size_t slen);
char* sgetln(int sd, size_t *len);
#ifndef EX_USAGE
#define EX_USAGE 64
#endif
#endif

116
configure vendored Normal file
View File

@ -0,0 +1,116 @@
#!/bin/sh
#
# Copyright (c) 2015 Carsten Larsen
# 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.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
#
set -e
EXEC='whois'
HDRS='
config.h
getaddrinfo.h
version.h
'
SRCS='
whois.c
error.c
getaddrinfo.c
sgetln.c
strnstr.c
wasprint.c
'
if make -v 2>&1 | grep GNU > /dev/null 2>&1 ; then
echo "make is GNU make."
VALID=true
#else
# echo "Wrong version of make."
# VALID=false
fi
if $VALID ; then
(
echo '# Portable Makefile generated by configure'
echo ''
echo "all: $EXEC"
echo ''
if [ -n "$1" ] && [ $1 = "AMIGA" ] ; then
echo 'CC = m68k-amigaos-gcc'
echo "CFLAGS = -O2 -m68000 -noixemul -Iinclude -Wall -Werror"
echo "LDFLAGS = -s -liberty -lm -lgcc"
elif [ -n "$1" ] && [ $1 = "AROS" ] ; then
echo 'CC = gcc'
echo "CFLAGS = -O2 -Iinclude -Wall -Werror"
echo "LDFLAGS = -lm"
else
echo "CFLAGS = -O2 -Wall -Werror"
echo "LDFLAGS = -s -lm"
fi
echo ''
for f in ${HDRS}
do
b=`basename $f .h`
i=`sed -n -e '/#include.*"/{
s/"$//
s/.*"//
p
}' $f | sort -u`
if [ "x${i}" != "x" ] ; then
echo "${b}.h: " ${i}
echo " touch ${b}.h"
echo
fi
done
l=""
for f in ${SRCS}
do
b=`basename $f .c`
i=`sed -n -e '/#include.*"/{
s/"$//
s/.*"//
p
}' $f | sort -u`
echo "${b}.o: ${b}.c" ${i}
echo
l="${l} ${b}.o"
done
echo
echo "$EXEC: ${l}"
echo " \${CC} \${CFLAGS} -o $EXEC ${l} \${LDFLAGS}"
echo
echo "clean:"
echo " rm -f ${l} $EXEC"
echo
echo "depend:"
echo " @echo Dependencies already done"
) > Makefile
echo "Makefile generated"
fi

268
doc/whois.1 Normal file
View File

@ -0,0 +1,268 @@
.\" 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.
.\" 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$
.\"
.Dd October 2, 2009
.Dt WHOIS 1
.Os
.Sh NAME
.Nm whois
.Nd "Internet domain name and network number directory service"
.Sh SYNOPSIS
.Nm
.Op Fl aAbfgiIklmQrR
.Op Fl c Ar country-code | Fl h Ar host
.Op Fl p Ar port
.Ar name ...
.Sh DESCRIPTION
The
.Nm
utility looks up records in the databases maintained by several
Network Information Centers
.Pq Tn NICs .
.Pp
The options are as follows:
.Bl -tag -width indent
.It Fl a
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 , AfriNIC , LACNIC ,
nor by
.Tn RIPE .
.Pp
(Hint: All point of contact handles in the
.Tn ARIN
whois database end with
.Qq Li -ARIN . )
.Pp
.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 b
Use the Network Abuse Clearinghouse database.
It contains addresses to which network abuse should be reported,
indexed by domain name.
.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 f
Use the African Network Information Centre
.Pq Tn AfriNIC
database.
It contains network numbers used in Africa and the islands of the
western Indian Ocean.
.It Fl g
Use the US non-military federal government database, which contains points of
contact for subdomains of
.Pa .GOV .
.It Fl h Ar host
Use the specified host instead of the default variant.
Either a host name or an IP address may be specified.
.Pp
By default
.Nm
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 , AfriNIC , 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 Pa whois.networksolutions.com
database.
It contains network numbers and domain contact information for most of
.Pa .COM , .NET , .ORG
and
.Pa .EDU
domains.
.Pp
.Sy NOTE !
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 "handle "
to the
.Tn NIC
handle in the query.)
.It Fl I
Use the Internet Assigned Numbers Authority
.Pq Tn IANA
database.
It contains network information for top-level domains.
.It Fl k
Use the National Internet Development Agency of Korea's
.Pq Tn KRNIC
database.
It contains network numbers and domain contact information
for Korea.
.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 port 43.
.It Fl Q
Do a quick lookup.
This means that
.Nm
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.
.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
.Pa .RU .
This option is deprecated; use the
.Fl c
option with an argument of
.Qq Li RU
instead.
.El
.Pp
The operands specified to
.Nm
are treated independently and may be used
as queries on different whois servers.
.Sh EXIT STATUS
.Ex -std
.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 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 .

146
doc/whois.guide Normal file
View File

@ -0,0 +1,146 @@
@database whois.guide
@author Carsten Larsen
@(c) Carsten Larsen
@$VER: whois.guide 1.37 (21.11.2015)
@node Main "whois manual"
@title "whois manual"
NAME
whois -- Internet domain name and network number directory service
SYNOPSIS
whois [-aAbfgiIklmQrR] [-c country-code | -h host] [-p port] name ...
DESCRIPTION
The whois utility looks up records in the databases maintained by several
Network Information Centers (NICs).
The options are as follows:
-a Use the American Registry for Internet Numbers (ARIN) database.
It contains network numbers used in those parts of the world cov-
ered neither by APNIC, AfriNIC, LACNIC, nor by RIPE.
(Hint: All point of contact handles in the ARIN whois database
end with "-ARIN".)
-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 Use the Network Abuse Clearinghouse database. It contains
addresses to which network abuse should be reported, indexed by
domain name.
-c country-code
This is the equivalent of using the -h option with an argument of
"country-code.whois-servers.net".
-f Use the African Network Information Centre (AfriNIC) database.
It contains network numbers used in Africa and the islands of the
western Indian Ocean.
-g Use the US non-military federal government database, which con-
tains points of contact for subdomains of .GOV.
-h host
Use the specified host instead of the default variant. Either a
host name or an IP address may be specified.
By default whois constructs the name of a whois server to use
from the top-level domain (TLD) of the supplied (single) argu-
ment, and appending ".whois-servers.net". This effectively
allows a suitable whois server to be selected automatically for a
large number of TLDs.
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, AfriNIC, LACNIC, or
RIPE, that server will be queried also, provided that the -Q
option is not specified.
If the query is not a domain name or IP address, whois will fall
back to whois.crsnic.net.
-i Use the Network Solutions Registry for Internet Numbers
(whois.networksolutions.com) database. It contains network num-
bers and domain contact information for most of .COM, .NET, .ORG
and .EDU domains.
NOTE! 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 InterNIC data-
base (whois.internic.net) is no longer handled by Network Solu-
tions, Inc. For details, see http://www.internic.net/.
(Hint: Contact information, identified by the term handle, can be
looked up by prefixing "handle " to the NIC handle in the query.)
-I Use the Internet Assigned Numbers Authority (IANA) database. It
contains network information for top-level domains.
-k Use the National Internet Development Agency of Korea's (KRNIC)
database. It contains network numbers and domain contact infor-
mation for Korea.
-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.
-m Use the Route Arbiter Database (RADB) database. It contains
route policy specifications for a large number of operators' net-
works.
-p port
Connect to the whois server on port. If this option is not spec-
ified, whois defaults to port 43.
-Q Do a quick lookup. This means that 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.
-r Use the R'eseaux IP Europ'eens (RIPE) database. It contains net-
work numbers and domain contact information for Europe.
-R Use the Russia Network Information Center (RIPN) database. It
contains network numbers and domain contact information for sub-
domains of .RU. This option is deprecated; use the -c option
with an argument of "RU" instead.
The operands specified to whois are treated independently and may be used
as queries on different whois servers.
EXIT STATUS
The whois utility exits 0 on success, and >0 if an error occurs.
EXAMPLES
Most types of data, such as domain names and IP addresses, can be used as
arguments to whois without any options, and whois will choose the correct
whois server to query. Some exceptions, where whois will not be able to
handle data correctly, are detailed below.
To obtain contact information about an administrator located in the Rus-
sian TLD domain "RU", use the -c option as shown in the following exam-
ple, where CONTACT-ID is substituted with the actual contact identifier.
whois -c RU CONTACT-ID
(Note: This example is specific to the TLD "RU", but other TLDs can be
queried by using a similar syntax.)
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).
whois -h whois.example.com -p rwhois query-data
SEE ALSO
Ken Harrenstien and Vic White, NICNAME/WHOIS, 1 March 1982, RFC 812.
HISTORY
The whois command appeared in 4.3BSD.
October 2, 2009
@endnode

140
doc/whois.txt Normal file
View File

@ -0,0 +1,140 @@
WHOIS(1) BSD General Commands Manual WHOIS(1)
NAME
whois -- Internet domain name and network number directory service
SYNOPSIS
whois [-aAbfgiIklmQrR] [-c country-code | -h host] [-p port] name ...
DESCRIPTION
The whois utility looks up records in the databases maintained by several
Network Information Centers (NICs).
The options are as follows:
-a Use the American Registry for Internet Numbers (ARIN) database.
It contains network numbers used in those parts of the world cov-
ered neither by APNIC, AfriNIC, LACNIC, nor by RIPE.
(Hint: All point of contact handles in the ARIN whois database
end with "-ARIN".)
-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 Use the Network Abuse Clearinghouse database. It contains
addresses to which network abuse should be reported, indexed by
domain name.
-c country-code
This is the equivalent of using the -h option with an argument of
"country-code.whois-servers.net".
-f Use the African Network Information Centre (AfriNIC) database.
It contains network numbers used in Africa and the islands of the
western Indian Ocean.
-g Use the US non-military federal government database, which con-
tains points of contact for subdomains of .GOV.
-h host
Use the specified host instead of the default variant. Either a
host name or an IP address may be specified.
By default whois constructs the name of a whois server to use
from the top-level domain (TLD) of the supplied (single) argu-
ment, and appending ".whois-servers.net". This effectively
allows a suitable whois server to be selected automatically for a
large number of TLDs.
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, AfriNIC, LACNIC, or
RIPE, that server will be queried also, provided that the -Q
option is not specified.
If the query is not a domain name or IP address, whois will fall
back to whois.crsnic.net.
-i Use the Network Solutions Registry for Internet Numbers
(whois.networksolutions.com) database. It contains network num-
bers and domain contact information for most of .COM, .NET, .ORG
and .EDU domains.
NOTE! 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 InterNIC data-
base (whois.internic.net) is no longer handled by Network Solu-
tions, Inc. For details, see http://www.internic.net/.
(Hint: Contact information, identified by the term handle, can be
looked up by prefixing "handle " to the NIC handle in the query.)
-I Use the Internet Assigned Numbers Authority (IANA) database. It
contains network information for top-level domains.
-k Use the National Internet Development Agency of Korea's (KRNIC)
database. It contains network numbers and domain contact infor-
mation for Korea.
-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.
-m Use the Route Arbiter Database (RADB) database. It contains
route policy specifications for a large number of operators' net-
works.
-p port
Connect to the whois server on port. If this option is not spec-
ified, whois defaults to port 43.
-Q Do a quick lookup. This means that 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.
-r Use the R'eseaux IP Europ'eens (RIPE) database. It contains net-
work numbers and domain contact information for Europe.
-R Use the Russia Network Information Center (RIPN) database. It
contains network numbers and domain contact information for sub-
domains of .RU. This option is deprecated; use the -c option
with an argument of "RU" instead.
The operands specified to whois are treated independently and may be used
as queries on different whois servers.
EXIT STATUS
The whois utility exits 0 on success, and >0 if an error occurs.
EXAMPLES
Most types of data, such as domain names and IP addresses, can be used as
arguments to whois without any options, and whois will choose the correct
whois server to query. Some exceptions, where whois will not be able to
handle data correctly, are detailed below.
To obtain contact information about an administrator located in the Rus-
sian TLD domain "RU", use the -c option as shown in the following exam-
ple, where CONTACT-ID is substituted with the actual contact identifier.
whois -c RU CONTACT-ID
(Note: This example is specific to the TLD "RU", but other TLDs can be
queried by using a similar syntax.)
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).
whois -h whois.example.com -p rwhois query-data
SEE ALSO
Ken Harrenstien and Vic White, NICNAME/WHOIS, 1 March 1982, RFC 812.
HISTORY
The whois command appeared in 4.3BSD.
BSD October 2, 2009 BSD

80
error.c Normal file
View File

@ -0,0 +1,80 @@
/*
* Written by Carsten Larsen.
* Public domain.
*/
#include "config.h"
void err0(int eval, const char *text) {
int errno2 = errno;
fprintf(stderr, "%s: ", getprogname());
if (text != NULL) {
fprintf(stderr, "%s", text);
fprintf(stderr, ": ");
}
fprintf(stderr, "%s\n", strerror(errno2));
exit(eval);
}
void errx0(int eval, const char *text) {
fprintf(stderr, "%s: ", getprogname());
if (text != NULL)
fprintf(stderr, "%s", text);
fprintf(stderr, "\n");
exit(eval);
}
void errx2(int eval, const char *fmt, const void *arg1, const void *arg2) {
fprintf(stderr, "%s: ", getprogname());
if (fmt != NULL)
fprintf(stderr, fmt, arg1, arg2);
fprintf(stderr, "\n");
exit(eval);
}
void warn2(const char *fmt, const void *arg1, const void *arg2) {
int errno2 = errno;
fprintf(stderr, "%s: ", getprogname());
if (fmt != NULL) {
fprintf(stderr, fmt, arg1, arg2);
fprintf(stderr, ": ");
}
fprintf(stderr, "%s\n", strerror(errno2));
}
void warnx0(const char *text) {
fprintf(stderr, "%s: ", getprogname());
if (text != NULL)
fprintf(stderr, "%s", text);
fprintf(stderr, "\n");
}
void warnx1(const char *fmt, const void *arg1)
{
fprintf(stderr, "%s: ", getprogname());
if (fmt != NULL)
fprintf(stderr, fmt, arg1);
fprintf(stderr, "\n");
}
void warnx2(const char *fmt, const void *arg1, const void *arg2) {
fprintf(stderr, "%s: ", getprogname());
if (fmt != NULL)
fprintf(stderr, fmt, arg1, arg2);
fprintf(stderr, "\n");
}

507
getaddrinfo.c Normal file
View File

@ -0,0 +1,507 @@
/*
* Copyright (c) 2015 Carsten Larsen
* Copyright (c) 2001, 02 Motoyuki Kasahara
*
* 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. Neither the name of the project 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 PROJECT 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 PROJECT 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.
*/
/*
* This program provides getaddrinfo() and getnameinfo() described in
* RFC2133, 2553 and 3493. These functions are mainly used for IPv6
* application to resolve hostname or address.
*
* This program is designed to be working on traditional IPv4 systems
* which don't have those functions. Therefore, this implementation
* supports IPv4 only.
*
* This program is useful for application which should support both IPv6
* and traditional IPv4 systems. Use genuine getaddrinfo() and getnameinfo()
* provided by system if the system supports IPv6. Otherwise, use this
* implementation.
*
* This program also provides freeaddrinfo() and gai_strerror().
*
* Restriction:
* getaddrinfo() and getnameinfo() of this program are NOT thread
* safe, unless the cpp macro ENABLE_PTHREAD is defined.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <memory.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include "config.h"
#include "getaddrinfo.h"
#ifdef ENABLE_NLS
#include <libintl.h>
#endif
#ifdef ENABLE_NLS
#define _(string) gettext(string)
#ifdef gettext_noop
#define N_(string) gettext_noop(string)
#else
#define N_(string) (string)
#endif
#else
#define gettext(string) (string)
#define _(string) (string)
#define N_(string) (string)
#endif
/*
* Error messages for gai_strerror().
*/
static char *eai_errlist[] = {
N_("Success"),
/* EAI_ADDRFAMILY */
N_("Address family for hostname not supported"),
/* EAI_AGAIN */
N_("Temporary failure in name resolution"),
/* EAI_BADFLAGS */
N_("Invalid value for ai_flags"),
/* EAI_FAIL */
N_("Non-recoverable failure in name resolution"),
/* EAI_FAMILY */
N_("ai_family not supported"),
/* EAI_MEMORY */
N_("Memory allocation failure"),
/* EAI_NONAME */
N_("hostname nor servname provided, or not known"),
/* EAI_OVERFLOW */
N_("An argument buffer overflowed"),
/* EAI_SERVICE */
N_("servname not supported for ai_socktype"),
/* EAI_SOCKTYPE */
N_("ai_socktype not supported"),
/* EAI_SYSTEM */
N_("System error returned in errno")
};
/*
* Default hints for getaddrinfo().
*/
static struct addrinfo default_hints = {
0, PF_UNSPEC, 0, 0, 0, NULL, NULL, NULL
};
/*
* Mutex.
*/
struct SignalSemaphore GetaddrinfoSemaphore;
/*
* Declaration of static functions.
*/
#ifdef __STDC__
static int is_integer(const char *);
static int is_address(const char *);
static int itoa_length(int);
#else
static int is_integer();
static int is_address();
static int itoa_length();
#endif
/*
* gai_strerror().
*/
const char *
gai_strerror(ecode)
int ecode;
{
if (ecode < 0 || ecode > EAI_SYSTEM)
return _("Unknown error");
return gettext(eai_errlist[ecode]);
}
/*
* freeaddrinfo().
*/
void
freeaddrinfo(ai)
struct addrinfo *ai;
{
struct addrinfo *next_ai;
while (ai != NULL) {
if (ai->ai_canonname != NULL)
free(ai->ai_canonname);
if (ai->ai_addr != NULL)
free(ai->ai_addr);
next_ai = ai->ai_next;
free(ai);
ai = next_ai;
}
}
/*
* Return 1 if the string `s' represents an integer.
*/
static int
is_integer(s)
const char *s;
{
if (*s == '-' || *s == '+')
s++;
if (*s < '0' || '9' < *s)
return 0;
s++;
while ('0' <= *s && *s <= '9')
s++;
return (*s == '\0');
}
/*
* Return 1 if the string `s' represents an IPv4 address.
* Unlike inet_addr(), it doesn't permit malformed nortation such
* as "192.168".
*/
static int
is_address(s)
const char *s;
{
const static char delimiters[] = {'.', '.', '.', '\0'};
int i, j;
int octet;
for (i = 0; i < 4; i++) {
if (*s == '0' && *(s + 1) != delimiters[i])
return 0;
for (j = 0, octet = 0; '0' <= *s && *s <= '9' && j < 3; s++, j++)
octet = octet * 10 + (*s - '0');
if (j == 0 || octet > 255 || *s != delimiters[i])
return 0;
s++;
}
return 1;
}
/*
* Calcurate length of the string `s', where `s' is set by
* sprintf(s, "%d", n).
*/
static int
itoa_length(n)
int n;
{
int result = 1;
if (n < 0) {
n = -n;
result++;
}
while (n >= 10) {
result++;
n /= 10;
}
return result;
}
/*
* getaddrinfo().
*/
int
getaddrinfo(nodename, servname, hints, res)
const char *nodename;
const char *servname;
const struct addrinfo *hints;
struct addrinfo **res;
{
struct addrinfo *head_res = NULL;
struct addrinfo *tail_res = NULL;
struct addrinfo *new_res;
struct sockaddr_in *sa_in;
struct in_addr **addr_list;
struct in_addr *addr_list_buf[2];
struct in_addr addr_buf;
struct in_addr **ap;
struct servent *servent;
struct hostent *hostent;
const char *canonname = NULL;
in_port_t port;
int saved_h_errno;
int result = 0;
ObtainSemaphore(&GetaddrinfoSemaphore);
saved_h_errno = h_errno;
if (nodename == NULL && servname == NULL) {
result = EAI_NONAME;
goto end;
}
if (hints != NULL) {
if (hints->ai_family != PF_INET && hints->ai_family != PF_UNSPEC) {
result = EAI_FAMILY;
goto end;
}
if (hints->ai_socktype != SOCK_DGRAM
&& hints->ai_socktype != SOCK_STREAM
&& hints->ai_socktype != 0) {
result = EAI_SOCKTYPE;
goto end;
}
} else {
hints = &default_hints;
}
if (servname != NULL) {
if (is_integer(servname))
port = htons(atoi(servname));
else {
if (hints->ai_flags & AI_NUMERICSERV) {
result = EAI_NONAME;
goto end;
}
if (hints->ai_socktype == SOCK_DGRAM)
servent = getservbyname((char*)servname, (char*)"udp");
else if (hints->ai_socktype == SOCK_STREAM)
servent = getservbyname((char*)servname, (char*)"tcp");
else if (hints->ai_socktype == 0)
servent = getservbyname((char*)servname, (char*)"tcp");
else {
result = EAI_SOCKTYPE;
goto end;
}
if (servent == NULL) {
result = EAI_SERVICE;
goto end;
}
port = servent->s_port;
}
} else {
port = htons(0);
}
if (nodename != NULL) {
if (is_address(nodename)) {
addr_buf.s_addr = inet_addr(nodename);
addr_list_buf[0] = &addr_buf;
addr_list_buf[1] = NULL;
addr_list = addr_list_buf;
if (hints->ai_flags & AI_CANONNAME
&& !(hints->ai_flags & AI_NUMERICHOST)) {
hostent = gethostbyaddr((char *)&addr_buf,
sizeof(struct in_addr), AF_INET);
if (hostent != NULL)
canonname = hostent->h_name;
else
canonname = nodename;
}
} else {
if (hints->ai_flags & AI_NUMERICHOST) {
result = EAI_NONAME;
goto end;
}
hostent = gethostbyname(nodename);
if (hostent == NULL) {
switch (h_errno) {
case HOST_NOT_FOUND:
case NO_DATA:
result = EAI_NONAME;
goto end;
case TRY_AGAIN:
result = EAI_AGAIN;
goto end;
default:
result = EAI_FAIL;
goto end;
}
}
addr_list = (struct in_addr **)hostent->h_addr_list;
if (hints->ai_flags & AI_CANONNAME)
canonname = hostent->h_name;
}
} else {
if (hints->ai_flags & AI_PASSIVE)
addr_buf.s_addr = htonl(INADDR_ANY);
else
addr_buf.s_addr = htonl(0x7F000001);
addr_list_buf[0] = &addr_buf;
addr_list_buf[1] = NULL;
addr_list = addr_list_buf;
}
for (ap = addr_list; *ap != NULL; ap++) {
new_res = (struct addrinfo *)malloc(sizeof(struct addrinfo));
if (new_res == NULL) {
if (head_res != NULL)
freeaddrinfo(head_res);
result = EAI_MEMORY;
goto end;
}
new_res->ai_family = PF_INET;
new_res->ai_socktype = hints->ai_socktype;
new_res->ai_protocol = hints->ai_protocol;
new_res->ai_addr = NULL;
new_res->ai_addrlen = sizeof(struct sockaddr_in);
new_res->ai_canonname = NULL;
new_res->ai_next = NULL;
new_res->ai_addr = (struct sockaddr *)
malloc(sizeof(struct sockaddr_in));
if (new_res->ai_addr == NULL) {
free(new_res);
if (head_res != NULL)
freeaddrinfo(head_res);
result = EAI_MEMORY;
goto end;
}
sa_in = (struct sockaddr_in *)new_res->ai_addr;
memset(sa_in, 0, sizeof(struct sockaddr_in));
sa_in->sin_family = PF_INET;
sa_in->sin_port = port;
memcpy(&sa_in->sin_addr, *ap, sizeof(struct in_addr));
if (head_res == NULL)
head_res = new_res;
else
tail_res->ai_next = new_res;
tail_res = new_res;
}
if (canonname != NULL && head_res != NULL) {
head_res->ai_canonname = (char *)malloc(strlen(canonname) + 1);
if (head_res->ai_canonname != NULL)
strcpy(head_res->ai_canonname, canonname);
}
*res = head_res;
end:
h_errno = saved_h_errno;
ReleaseSemaphore(&GetaddrinfoSemaphore);
return result;
}
int getnameinfo(const struct sockaddr *sa, socklen_t salen, char *node, socklen_t nodelen, char *serv, socklen_t servlen, int flags) {
const struct sockaddr_in *sa_in = (const struct sockaddr_in *)sa;
struct hostent *hostent;
struct servent *servent;
char *ntoa_address;
int saved_h_errno;
int result = 0;
ObtainSemaphore(&GetaddrinfoSemaphore);
saved_h_errno = h_errno;
if (sa_in->sin_family != PF_INET) {
result = EAI_FAMILY;
goto end;
} else if (node == NULL && serv == NULL) {
result = EAI_NONAME;
goto end;
}
if (serv != NULL && servlen > 0) {
if (flags & NI_NUMERICSERV)
servent = NULL;
else if (flags & NI_DGRAM)
servent = getservbyport(sa_in->sin_port, "udp");
else
servent = getservbyport(sa_in->sin_port, "tcp");
if (servent != NULL) {
if (servlen <= strlen(servent->s_name)) {
result = EAI_OVERFLOW;
goto end;
}
strcpy(serv, servent->s_name);
} else {
if (servlen <= itoa_length(ntohs(sa_in->sin_port))) {
result = EAI_OVERFLOW;
goto end;
}
sprintf(serv, "%d", ntohs(sa_in->sin_port));
}
}
if (node != NULL && nodelen > 0) {
if (flags & NI_NUMERICHOST)
hostent = NULL;
else {
hostent = gethostbyaddr((char *)&sa_in->sin_addr,
sizeof(struct in_addr), AF_INET);
}
if (hostent != NULL) {
if (nodelen <= strlen(hostent->h_name)) {
result = EAI_OVERFLOW;
goto end;
}
strcpy(node, hostent->h_name);
} else {
if (flags & NI_NAMEREQD) {
result = EAI_NONAME;
goto end;
}
ntoa_address = inet_ntoa(sa_in->sin_addr);
if (nodelen <= strlen(ntoa_address)) {
result = EAI_OVERFLOW;
goto end;
}
strcpy(node, ntoa_address);
}
}
end:
h_errno = saved_h_errno;
ReleaseSemaphore(&GetaddrinfoSemaphore);
return result;
}

226
getaddrinfo.h Normal file
View File

@ -0,0 +1,226 @@
/*
* Copyright (c) 2015 Carsten Larsen
* Copyright (c) 2001, 02 Motoyuki Kasahara
*
* 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. Neither the name of the project 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 PROJECT 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 PROJECT 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.
*/
#ifndef INET_GETADDRINFO_H
#define INET_GETADDRINFO_H
#include <sys/types.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
/********************************************************************/
/*
* Undefine all the macros.
* <netdb.h> might defines some of them.
*/
#ifdef EAI_ADDRFAMILY
#undef EAI_ADDRFAMILY
#endif
#ifdef EAI_AGAIN
#undef EAI_AGAIN
#endif
#ifdef EAI_BADFLAGS
#undef EAI_BADFLAGS
#endif
#ifdef EAI_FAIL
#undef EAI_FAIL
#endif
#ifdef EAI_FAMILY
#undef EAI_FAMILY
#endif
#ifdef EAI_MEMORY
#undef EAI_MEMORY
#endif
#ifdef EAI_NONAME
#undef EAI_NONAME
#endif
#ifdef EAI_OVERFLOW
#undef EAI_OVERFLOW
#endif
#ifdef EAI_SERVICE
#undef EAI_SERVICE
#endif
#ifdef EAI_SOCKTYPE
#undef EAI_SOCKTYPE
#endif
#ifdef EAI_SYSTEM
#undef EAI_SYSTEM
#endif
#ifdef AI_PASSIVE
#undef AI_PASSIVE
#endif
#ifdef AI_CANONNAME
#undef AI_CANONNAME
#endif
#ifdef AI_NUMERICHOST
#undef AI_NUMERICHOST
#endif
#ifdef AI_NUMERICSERV
#undef AI_NUMERICSERV
#endif
#ifdef AI_V4MAPPED
#undef AI_V4MAPPED
#endif
#ifdef AI_ALL
#undef AI_ALL
#endif
#ifdef AI_ADDRCONFIG
#undef AI_ADDRCONFIG
#endif
#ifdef AI_DEFAULT
#undef AI_DEFAULT
#endif
#ifdef NI_NOFQDN
#undef NI_NOFQDN
#endif
#ifdef NI_NUMERICHOST
#undef NI_NUMERICHOST
#endif
#ifdef NI_NAMEREQD
#undef NI_NAMEREQD
#endif
#ifdef NI_NUMERICSERV
#undef NI_NUMERICSERV
#endif
#ifdef NI_NUMERICSCOPE
#undef NI_NUMERICSCOPE
#endif
#ifdef NI_DGRAM
#undef NI_DGRAM
#endif
#ifdef NI_MAXHOST
#undef NI_MAXHOST
#endif
#ifdef NI_MAXSERV
#undef NI_MAXSERV
#endif
/*
* Fake struct and function names.
* <netdb.h> might declares all or some of them.
*/
/*
#if defined(HAVE_GETADDRINFO) || defined(HAVE_GETNAMEINFO)
#define addrinfo my_addrinfo
#define gai_strerror my_gai_strerror
#define freeaddrinfo my_freeaddrinfo
#define getaddrinfo my_getaddrinfo
#define getnameinfo my_getnameinfo
#endif
*/
/********************************************************************/
/*
* Error codes.
*/
#define EAI_ADDRFAMILY 1
#define EAI_AGAIN 2
#define EAI_BADFLAGS 3
#define EAI_FAIL 4
#define EAI_FAMILY 5
#define EAI_MEMORY 6
#define EAI_NONAME 7
#define EAI_OVERFLOW 8
#define EAI_SERVICE 9
#define EAI_SOCKTYPE 10
#define EAI_SYSTEM 11
/*
* Flags for getaddrinfo().
*/
#define AI_ADDRCONFIG 0x0001
#define AI_ALL 0x0002
#define AI_CANONNAME 0x0004
#define AI_NUMERICHOST 0x0008
#define AI_NUMERICSERV 0x0010
#define AI_PASSIVE 0x0020
#define AI_V4MAPPED 0x0040
#define AI_DEFAULT (AI_V4MAPPED | AI_ADDRCONFIG)
/*
* Flags for getnameinfo().
*/
#define NI_DGRAM 0x0001
#define NI_NAMEREQD 0x0002
#define NI_NOFQDN 0x0004
#define NI_NUMERICHOST 0x0008
#define NI_NUMERICSCOPE 0x0010
#define NI_NUMERICSERV 0x0020
/*
* Maximum length of FQDN and servie name for getnameinfo().
*/
#define NI_MAXHOST 1025
#define NI_MAXSERV 32
/*
* Address families and Protocol families.
*/
#ifndef AF_UNSPEC
#define AF_UNSPEC AF_INET
#endif
#ifndef PF_UNSPEC
#define PF_UNSPEC PF_INET
#endif
//#include <stdint.h>
//typedef uint32_t socklen_t
typedef unsigned int socklen_t;
#ifndef HAVE_ADDRINFO
/* Structure to contain information about address of a service provider. */
struct addrinfo
{
int ai_flags; /* Input flags. */
int ai_family; /* Protocol family for socket. */
int ai_socktype; /* Socket type. */
int ai_protocol; /* Protocol for socket. */
socklen_t ai_addrlen; /* Length of socket address. */
struct sockaddr *ai_addr; /* Socket address for socket. */
char *ai_canonname; /* Canonical name for service location. */
struct addrinfo *ai_next; /* Pointer to next in list. */
};
#endif
typedef u_int16_t in_port_t;
typedef unsigned int sa_family_t;
#include <exec/types.h>
extern struct SignalSemaphore GetaddrinfoSemaphore;
const char* gai_strerror(int);
void freeaddrinfo(struct addrinfo *);
int getaddrinfo(const char *, const char *, const struct addrinfo *, struct addrinfo **);
int getnameinfo(const struct sockaddr *, socklen_t, char *, socklen_t, char *, socklen_t, int);
#endif

View File

@ -0,0 +1,116 @@
/*
* Copyright (c) 2015 Carsten Larsen
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
*
*/
#ifndef _SOCKET_AMITCP_H
#define _SOCKET_AMITCP_H
//--------------------------------------------------------------------------//
#define AMITCP_BASE_NAME SocketBase
#include "inline/amitcp.h"
//--------------------------------------------------------------------------//
#define socket Socket
#define bind Bind
#define listen Listen
#define accept Accept
#define connect Connect
#define send Send
#define sendto SendTo
#define sendmsg SendMsg
#define recv Recv
#define recvfrom RecvFrom
#define recvmsg RecvMsg
#define select Select
#define shutdown ShutDown
#define setsockopt SetSockOpt
#define getsockopt GetSockOpt
#define getsockname GetSockName
#define getpeername GetPeerName
#define inet_addr Inet_Addr
#define inet_network Inet_Network
#define inet_ntoa Inet_NtoA
#define gethostbyname GetHostByName
#define gethostbyaddr GetHostByAddr
#define getnetbyname GetNetByName
#define getnetbyaddr GetNetByAddr
#define getservbyname GetServByName
#define getservbyport GetServByPort
#define getprotobyname GetProtoByName
#define getprotobynumber GetProtoByNumber
#define getdtablesize GetDTableSize
#define gethostname GetHostName
#define gethostid GetHostId
#define vsyslog SyslogA
#define syslog Syslog
//--------------------------------------------------------------------------//
#define Accept TCP_Accept
#define Bind TCP_Bind
#define CloseSocket TCP_CloseSocket
#define Connect TCP_Connect
#define Dup2Socket TCP_Dup2Socket
#define Errno TCP_Errno
#define GetDTableSize TCP_GetDTableSize
#define GetHostByAddr TCP_GetHostByAddr
#define GetHostByName TCP_GetHostByName
#define GetHostId TCP_GetHostId
#define GetHostName TCP_GetHostName
#define GetNetByAddr TCP_GetNetByAddr
#define GetNetByName TCP_GetNetByName
#define GetPeerName TCP_GetPeerName
#define GetProtoByName TCP_GetProtoByName
#define GetProtoByNumber TCP_GetProtoByNumber
#define GetServByName TCP_GetServByName
#define GetServByPort TCP_GetServByPort
#define GetSockName TCP_GetSockName
#define GetSockOpt TCP_GetSockOpt
#define GetSocketEvents TCP_GetSocketEvents
#define Inet_Addr TCP_Inet_Addr
#define Inet_LnaOf TCP_Inet_LnaOf
#define Inet_MakeAddr TCP_Inet_MakeAddr
#define Inet_NetOf TCP_Inet_NetOf
#define Inet_Network TCP_Inet_Network
#define Inet_NtoA(x) TCP_Inet_NtoA((x).s_addr)
#define IoctlSocket TCP_IoctlSocket
#define Listen TCP_Listen
#define ObtainSocket TCP_ObtainSocket
#define Recv TCP_Recv
#define RecvFrom TCP_RecvFrom
#define RecvMsg TCP_RecvMsg
#define ReleaseCopyOfSocket TCP_ReleaseCopyOfSocket
#define ReleaseSocket TCP_ReleaseSocket
#define Send TCP_Send
#define SendMsg TCP_SendMsg
#define SendTo TCP_SendTo
#define SetErrnoPtr TCP_SetErrnoPtr
#define SetSockOpt TCP_SetSockOpt
#define SetSocketSignals TCP_SetSocketSignals
#define ShutDown TCP_ShutDown
#define Socket TCP_Socket
#define SocketBaseTagList TCP_SocketBaseTagList
#define SocketBaseTags TCP_SocketBaseTags
#define SyslogA TCP_SyslogA
#define WaitSelect TCP_WaitSelect
#define Select(n,r,w,e,t) TCP_WaitSelect(n,r,w,e,t,0)
//--------------------------------------------------------------------------//
#endif

203
include/inline/amitcp.h Normal file
View File

@ -0,0 +1,203 @@
/* Automatically generated header! Do not edit! */
#ifndef _INLINE_AMITCP_H
#define _INLINE_AMITCP_H
#ifndef __INLINE_MACROS_H
#include <inline/macros.h>
#endif /* !__INLINE_MACROS_H */
#ifndef AMITCP_BASE_NAME
#define AMITCP_BASE_NAME lss->lx_BsdSocketBase
#endif /* !AMITCP_BASE_NAME */
#define TCP_Accept(s, addr, addrlen) \
LP3(0x30, LONG, TCP_Accept, LONG, s, d0, struct sockaddr *, addr, a0, int *, addrlen, a1, \
, AMITCP_BASE_NAME)
#define TCP_Bind(s, name, namelen) \
LP3(0x24, LONG, TCP_Bind, LONG, s, d0, const struct sockaddr *, name, a0, LONG, namelen, d1, \
, AMITCP_BASE_NAME)
#define TCP_CloseSocket(d) \
LP1(0x78, LONG, TCP_CloseSocket, LONG, d, d0, \
, AMITCP_BASE_NAME)
#define TCP_Connect(s, name, namelen) \
LP3(0x36, LONG, TCP_Connect, LONG, s, d0, const struct sockaddr *, name, a0, LONG, namelen, d1, \
, AMITCP_BASE_NAME)
#define TCP_Dup2Socket(fd1, fd2) \
LP2(0x108, LONG, TCP_Dup2Socket, LONG, fd1, d0, LONG, fd2, d1, \
, AMITCP_BASE_NAME)
#define TCP_Errno() \
LP0(0xa2, LONG, TCP_Errno, \
, AMITCP_BASE_NAME)
#define TCP_GetDTableSize() \
LP0(0x8a, LONG, TCP_GetDTableSize, \
, AMITCP_BASE_NAME)
#define TCP_GetHostByAddr(addr, len, type) \
LP3(0xd8, struct hostent *, TCP_GetHostByAddr, const UBYTE *, addr, a0, LONG, len, d0, LONG, type, d1, \
, AMITCP_BASE_NAME)
#define TCP_GetHostByName(name) \
LP1(0xd2, struct hostent *, TCP_GetHostByName, const UBYTE *, name, a0, \
, AMITCP_BASE_NAME)
#define TCP_GetHostId() \
LP0(0x120, ULONG, TCP_GetHostId, \
, AMITCP_BASE_NAME)
#define TCP_GetHostName(hostname, size) \
LP2(0x11a, LONG, TCP_GetHostName, STRPTR, hostname, a0, LONG, size, d0, \
, AMITCP_BASE_NAME)
#define TCP_GetNetByAddr(net, type) \
LP2(0xe4, struct netent *, TCP_GetNetByAddr, LONG, net, d0, LONG, type, d1, \
, AMITCP_BASE_NAME)
#define TCP_GetNetByName(name) \
LP1(0xde, struct netent *, TCP_GetNetByName, const UBYTE *, name, a0, \
, AMITCP_BASE_NAME)
#define TCP_GetPeerName(s, hostname, namelen) \
LP3(0x6c, LONG, TCP_GetPeerName, LONG, s, d0, struct sockaddr *, hostname, a0, int *, namelen, a1, \
, AMITCP_BASE_NAME)
#define TCP_GetProtoByName(name) \
LP1(0xf6, struct protoent *, TCP_GetProtoByName, const UBYTE *, name, a0, \
, AMITCP_BASE_NAME)
#define TCP_GetProtoByNumber(proto) \
LP1(0xfc, struct protoent *, TCP_GetProtoByNumber, LONG, proto, d0, \
, AMITCP_BASE_NAME)
#define TCP_GetServByName(name, proto) \
LP2(0xea, struct servent *, TCP_GetServByName, const UBYTE *, name, a0, const UBYTE *, proto, a1, \
, AMITCP_BASE_NAME)
#define TCP_GetServByPort(port, proto) \
LP2(0xf0, struct servent *, TCP_GetServByPort, LONG, port, d0, const UBYTE *, proto, a0, \
, AMITCP_BASE_NAME)
#define TCP_GetSockName(s, hostname, namelen) \
LP3(0x66, LONG, TCP_GetSockName, LONG, s, d0, struct sockaddr *, hostname, a0, int *, namelen, a1, \
, AMITCP_BASE_NAME)
#define TCP_GetSockOpt(s, level, optname, optval, optlen) \
LP5(0x60, LONG, TCP_GetSockOpt, LONG, s, d0, LONG, level, d1, LONG, optname, d2, void *, optval, a0, int *, optlen, a1, \
, AMITCP_BASE_NAME)
#define TCP_GetSocketEvents(eventmaskp) \
LP1(0x12c, LONG, TCP_GetSocketEvents, ULONG *, eventmaskp, a0, \
, AMITCP_BASE_NAME)
#define TCP_Inet_Addr(cp) \
LP1(0xb4, ULONG, TCP_Inet_Addr, const UBYTE *, cp, a0, \
, AMITCP_BASE_NAME)
#define TCP_Inet_LnaOf(in) \
LP1(0xba, ULONG, TCP_Inet_LnaOf, LONG, in, d0, \
, AMITCP_BASE_NAME)
#define TCP_Inet_MakeAddr(net, host) \
LP2(0xc6, ULONG, TCP_Inet_MakeAddr, ULONG, net, d0, ULONG, host, d1, \
, AMITCP_BASE_NAME)
#define TCP_Inet_NetOf(in) \
LP1(0xc0, ULONG, TCP_Inet_NetOf, LONG, in, d0, \
, AMITCP_BASE_NAME)
#define TCP_Inet_Network(cp) \
LP1(0xcc, ULONG, TCP_Inet_Network, const UBYTE *, cp, a0, \
, AMITCP_BASE_NAME)
#define TCP_Inet_NtoA(in) \
LP1(0xae, char *, TCP_Inet_NtoA, ULONG, in, d0, \
, AMITCP_BASE_NAME)
#define TCP_IoctlSocket(d, request, argp) \
LP3(0x72, LONG, TCP_IoctlSocket, LONG, d, d0, ULONG, request, d1, char *, argp, a0, \
, AMITCP_BASE_NAME)
#define TCP_Listen(s, backlog) \
LP2(0x2a, LONG, TCP_Listen, LONG, s, d0, LONG, backlog, d1, \
, AMITCP_BASE_NAME)
#define TCP_ObtainSocket(id, domain, type, protocol) \
LP4(0x90, LONG, TCP_ObtainSocket, LONG, id, d0, LONG, domain, d1, LONG, type, d2, LONG, protocol, d3, \
, AMITCP_BASE_NAME)
#define TCP_Recv(s, buf, len, flags) \
LP4(0x4e, LONG, TCP_Recv, LONG, s, d0, UBYTE *, buf, a0, LONG, len, d1, LONG, flags, d2, \
, AMITCP_BASE_NAME)
#define TCP_RecvFrom(s, buf, len, flags, from, fromlen) \
LP6(0x48, LONG, TCP_RecvFrom, LONG, s, d0, UBYTE *, buf, a0, LONG, len, d1, LONG, flags, d2, struct sockaddr *, from, a1, int *, fromlen, a2, \
, AMITCP_BASE_NAME)
#define TCP_RecvMsg(s, msg, flags) \
LP3(0x114, LONG, TCP_RecvMsg, LONG, s, d0, struct msghdr *, msg, a0, LONG, flags, d1, \
, AMITCP_BASE_NAME)
#define TCP_ReleaseCopyOfSocket(fd, id) \
LP2(0x9c, LONG, TCP_ReleaseCopyOfSocket, LONG, fd, d0, LONG, id, d1, \
, AMITCP_BASE_NAME)
#define TCP_ReleaseSocket(fd, id) \
LP2(0x96, LONG, TCP_ReleaseSocket, LONG, fd, d0, LONG, id, d1, \
, AMITCP_BASE_NAME)
#define TCP_Send(s, msg, len, flags) \
LP4(0x42, LONG, TCP_Send, LONG, s, d0, const UBYTE *, msg, a0, LONG, len, d1, LONG, flags, d2, \
, AMITCP_BASE_NAME)
#define TCP_SendMsg(s, msg, flags) \
LP3(0x10e, LONG, TCP_SendMsg, LONG, s, d0, const struct msghdr *, msg, a0, LONG, flags, d1, \
, AMITCP_BASE_NAME)
#define TCP_SendTo(s, msg, len, flags, to, tolen) \
LP6(0x3c, LONG, TCP_SendTo, LONG, s, d0, const UBYTE *, msg, a0, LONG, len, d1, LONG, flags, d2, const struct sockaddr *, to, a1, LONG, tolen, d3, \
, AMITCP_BASE_NAME)
#define TCP_SetErrnoPtr(errno_p, size) \
LP2(0xa8, LONG, TCP_SetErrnoPtr, void *, errno_p, a0, LONG, size, d0, \
, AMITCP_BASE_NAME)
#define TCP_SetSockOpt(s, level, optname, optval, optlen) \
LP5(0x5a, LONG, TCP_SetSockOpt, LONG, s, d0, LONG, level, d1, LONG, optname, d2, const void *, optval, a0, LONG, optlen, d3, \
, AMITCP_BASE_NAME)
#define TCP_SetSocketSignals(SIGINTR, SIGIO, SIGURG) \
LP3NR(0x84, TCP_SetSocketSignals, ULONG, SIGINTR, d0, ULONG, SIGIO, d1, ULONG, SIGURG, d2, \
, AMITCP_BASE_NAME)
#define TCP_ShutDown(s, how) \
LP2(0x54, LONG, TCP_ShutDown, LONG, s, d0, LONG, how, d1, \
, AMITCP_BASE_NAME)
#define TCP_Socket(domain, type, protocol) \
LP3(0x1e, LONG, TCP_Socket, LONG, domain, d0, LONG, type, d1, LONG, protocol, d2, \
, AMITCP_BASE_NAME)
#define TCP_SocketBaseTagList(taglist) \
LP1(0x126, LONG, TCP_SocketBaseTagList, struct TagItem *, taglist, a0, \
, AMITCP_BASE_NAME)
#ifndef NO_INLINE_STDARG
#define TCP_SocketBaseTags(tags...) \
({ULONG _tags[] = { tags }; TCP_SocketBaseTagList((struct TagItem *)_tags);})
#endif
#define TCP_SyslogA(level, format, ap) \
LP3NR(0x102, TCP_SyslogA, ULONG, level, d0, const char *, format, a0, va_list, ap, a1, \
, AMITCP_BASE_NAME)
#define TCP_WaitSelect(nfds, readfds, writefds, execptfds, timeout, maskp) \
LP6(0x7e, LONG, TCP_WaitSelect, LONG, nfds, d0, fd_set *, readfds, a0, fd_set *, writefds, a1, fd_set *, execptfds, a2, struct timeval *, timeout, a3, ULONG *, maskp, d1, \
, AMITCP_BASE_NAME)
#endif /* !_INLINE_AMITCP_H */

31
sgetln.c Normal file
View File

@ -0,0 +1,31 @@
/*
* Written by Carsten Larsen.
* Public domain.
*/
#include "config.h"
char sgetln_buf[512];
char* sgetln(int sd, size_t *len) {
int res;
char in;
char *p;
int count = 0;
memset(&sgetln_buf, 0, sizeof(sgetln_buf));
p = (char*)&sgetln_buf;
while((res = recv(sd, &in, sizeof(char), 0))) {
*p++ = in;
count++;
if (in == '\n' || count == sizeof(sgetln_buf) - 1) {
*len = count;
return (char*)&sgetln_buf;
}
}
*len = 0;
return NULL;
}

67
strnstr.c Normal file
View File

@ -0,0 +1,67 @@
/*-
* Copyright (c) 2001 Mike Barcroft <mike@FreeBSD.org>
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Chris Torek.
*
* 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. 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.
*/
#if 0
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)strstr.c 8.1 (Berkeley) 6/4/93";
#endif /* LIBC_SCCS and not lint */
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#endif
#include <string.h>
/*
* 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);
}

103
version.h Normal file
View File

@ -0,0 +1,103 @@
/*
* Written by Carsten Larsen.
* Public domain.
*/
#ifndef WHOIS_VERSION_H
#define WHOIS_VERSION_H
#include "config.h"
#define PACKAGE_NAME "whois"
#define PACKAGE_VERSION "1.37"
#define PACKAGE_DATE "28.11.2015"
#define EMPTYSTRING ""
#define SPACE " "
// -----------------------------------------------------
// --------- Processor architecture definitions --------
// -----------------------------------------------------
#ifdef mc68000
#define ACPU "68000+"
#endif
#ifdef mc68020
#ifdef ACPU
#undef ACPU
#endif
#define ACPU "68020"
#endif
#ifdef mc68030
#ifdef ACPU
#undef ACPU
#endif
#define ACPU "68030"
#endif
#ifdef mc68040
#ifdef ACPU
#undef ACPU
#endif
#define ACPU "68040"
#endif
#ifdef mc68060
#ifdef ACPU
#undef ACPU
#endif
#define ACPU "68060"
#endif
#if defined(INTELCPU) || defined(i386) || defined(i486) || \
defined(intel) || defined(x86) || defined(i86pc) || \
defined(__i386__) || defined(_M_IX86)
#ifdef ACPU
#undef ACPU
#endif
#define ACPU "i386"
#endif
#ifdef __powerpc__
#define ACPU "PowerPC"
#endif
#if defined(__x86_64__)
#ifdef ACPU
#undef ACPU
#endif
#define ACPU "amd64"
#endif
#ifdef WITHTEST
#define ATEST SPACE "TEST"
#else
#define ATEST EMPTYSTRING
#endif
#if defined(ACPU) && defined(__HAVE_68881__)
#define AFPU SPACE "FPU"
#else
#define AFPU EMPTYSTRING
#endif
#ifndef ACPU
#define ACPU EMPTYSTRING
#endif
// -----------------------------------------------------
// --------- Package version string definition ---------
// -----------------------------------------------------
#define PACKAGE_COMMENT ACPU AFPU
#define PACKAGE_VERSION_STRING \
"\0$VER:" SPACE \
PACKAGE_NAME SPACE \
PACKAGE_VERSION SPACE \
PACKAGE_DATE SPACE \
PACKAGE_COMMENT
#endif

84
wasprint.c Normal file
View File

@ -0,0 +1,84 @@
/*
* Written by Carsten Larsen.
* Public domain.
*/
#include "config.h"
void cpy1(char **dest, const char *src)
{
char *nbuf;
int len = strlen(src);
if ((nbuf = malloc(len + 1)) == NULL)
err0(1, "malloc");
memcpy(nbuf, src, len);
nbuf[len] = '\0';
*dest = nbuf;
}
void cpy2(char **dest, const char *src1, const char *src2)
{
char *nbuf;
int len = strlen(src1) + strlen(src2);
if ((nbuf = malloc(len + 1)) == NULL)
err0(1, "malloc");
memcpy(nbuf, src1, len);
nbuf[len] = '\0';
strcat(nbuf, src2); // TODO: Change to fast copy
*dest = nbuf;
}
void cpy1pad(char **dest, int minlen, const char *src)
{
char *nbuf;
int alloclen, pad;
int len = strlen(src);
if (len < minlen) {
alloclen = minlen;
pad = minlen - len;
} else {
alloclen = len;
pad = 0;
}
if ((nbuf = malloc(alloclen + 1)) == NULL)
err0(1, "malloc");
while (pad-- > 0) {
*nbuf++ = ' ';
}
memcpy(nbuf, src, len);
nbuf[len] = '\0';
*dest = nbuf;
}
/****************************************************************************/
#ifdef __AMIGA__
int isblank(int c)
{
return c == '\t' || c == ' ' ;
}
int isspace(int c)
{
return c == '\t' ||
c == '\r' ||
c == '\n' ||
c == '\v' ||
c == '\f' ||
c == ' ';
}
#endif
/****************************************************************************/

457
whois.c Normal file
View File

@ -0,0 +1,457 @@
/* $AmigaOS: whois_amiga.c,v 1.37 2015/11/21 18:25:49 Exp $ */
/*-
* 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
* 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.
* 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.
*/
#include "config.h"
const char copyright[] =
"@(#) Copyright (c) 1980, 1993\n"
"The Regents of the University of California. All rights reserved.\n";
const char sccsid[] =
"@(#)whois.c 8.1 (Berkeley) 6/6/93";
#include "version.h"
const char *vers = PACKAGE_VERSION_STRING;
#include <sys/cdefs.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <ctype.h>
#include <err.h>
#include <netdb.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#define ABUSEHOST "whois.abuse.net"
#define NICHOST "whois.crsnic.net"
#define INICHOST "whois.networksolutions.com"
#define GNICHOST "whois.nic.gov"
#define ANICHOST "whois.arin.net"
#define LNICHOST "whois.lacnic.net"
#define KNICHOST "whois.krnic.net"
#define RNICHOST "whois.ripe.net"
#define PNICHOST "whois.apnic.net"
#define MNICHOST "whois.ra.net"
#define QNICHOST_TAIL ".whois-servers.net"
#define BNICHOST "whois.registro.br"
#define NORIDHOST "whois.norid.no"
#define IANAHOST "whois.iana.org"
#define GERMNICHOST "de.whois-servers.net"
#define FNICHOST "whois.afrinic.net"
#ifdef __AMIGA__
#define DEFAULT_PORT "whois"
#endif
#ifdef __AROS__
#define DEFAULT_PORT "43"
#endif
#define WHOIS_SERVER_ID "Whois Server: "
#define WHOIS_ORG_SERVER_ID "Registrant Street1:Whois Server:"
#define WHOIS_RECURSE 0x01
#define WHOIS_QUICK 0x02
#define ishost(h) (isalnum((unsigned char)h) || h == '.' || h == '-')
static const char *ip_whois[] = { LNICHOST, RNICHOST, PNICHOST, BNICHOST,
FNICHOST, NULL
};
static const char *port = DEFAULT_PORT;
static char *choose_server(char *);
static void usage(void);
static void whois(const char *, const char *, int);
#ifdef __AMIGA__
int h_errno = 0;
#endif
/****************************************************************************/
char *progname_storage = NULL;
const char *getprogname(void) {
return (const char*)progname_storage;
}
void setprogname(const char *progname) {
if (progname == NULL) {
return;
}
if (progname_storage != NULL) {
free(progname_storage);
}
progname_storage = malloc(strlen(progname));
strcpy(progname_storage, progname);
}
/****************************************************************************/
struct Library *DOSBase = NULL;
struct Library *SocketBase = NULL;
void close_libs()
{
if (DOSBase != NULL) {
CloseLibrary(DOSBase);
DOSBase = NULL;
}
if (SocketBase != NULL) {
CloseLibrary(SocketBase);
SocketBase = NULL;
}
if (progname_storage != NULL) {
free(progname_storage);
}
}
int open_libs()
{
atexit(close_libs);
InitSemaphore(&GetaddrinfoSemaphore);
if(!(DOSBase = OpenLibrary((STRPTR)DOSLIB_NAME, DOSLIB_REV))) {
warnx2(OPEN_VER_ERROR, DOSLIB_NAME, (void*)DOSLIB_REV);
return 5;
}
if(!(SocketBase = OpenLibrary((STRPTR)BSDLIB_NAME, BSDLIB_REV))) {
warnx2(OPEN_VER_ERROR, BSDLIB_NAME, (void*)BSDLIB_REV);
return 5;
} else {
SocketBaseTags(
SBTM_SETVAL(SBTC_ERRNOPTR(sizeof(errno))), (IPTR) &errno,
SBTM_SETVAL(SBTC_HERRNOLONGPTR), (IPTR) &h_errno,
SBTM_SETVAL(SBTC_LOGTAGPTR), (IPTR) &progname_storage,
TAG_DONE );
}
return 0;
}
/****************************************************************************/
int
main(int argc, char *argv[])
{
const char *country, *host;
char *qnichost;
int ch, flags, use_qnichost;
if (argc > 0) {
setprogname(argv[0]);
open_libs();
} else {
return -1;
}
country = host = qnichost = NULL;
flags = use_qnichost = 0;
while ((ch = getopt(argc, argv, "aAbc:fgh:iIklmp:QrR6")) != -1) {
switch (ch) {
case 'a':
host = ANICHOST;
break;
case 'A':
host = PNICHOST;
break;
case 'b':
host = ABUSEHOST;
break;
case 'c':
country = optarg;
break;
case 'f':
host = FNICHOST;
break;
case 'g':
host = GNICHOST;
break;
case 'h':
host = optarg;
break;
case 'i':
host = INICHOST;
break;
case 'I':
host = IANAHOST;
break;
case 'k':
host = KNICHOST;
break;
case 'l':
host = LNICHOST;
break;
case 'm':
host = MNICHOST;
break;
case 'p':
port = optarg;
break;
case 'Q':
flags |= WHOIS_QUICK;
break;
case 'r':
host = RNICHOST;
break;
case 'R':
warnx0("-R is deprecated; use '-c ru' instead");
country = "ru";
break;
/* Remove in FreeBSD 10 */
case '6':
errx0(EX_USAGE, "-6 is deprecated; use -[aAflr] instead");
break;
case '?':
default:
usage();
/* NOTREACHED */
}
}
argc -= optind;
argv += optind;
if (!argc || (country != NULL && host != NULL))
usage();
/*
* If no host or 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 '.', fall
* back to NICHOST.
*/
if (host == NULL && country == NULL) {
if ((host = getenv("RA_SERVER")) == NULL) {
use_qnichost = 1;
host = NICHOST;
if (!(flags & WHOIS_QUICK))
flags |= WHOIS_RECURSE;
}
}
while (argc-- > 0) {
if (country != NULL) {
cpy2(&qnichost, country, QNICHOST_TAIL);
whois(*argv, qnichost, flags);
} else if (use_qnichost)
if ((qnichost = choose_server(*argv)) != NULL)
whois(*argv, qnichost, flags);
if (qnichost == NULL)
whois(*argv, host, flags);
free(qnichost);
qnichost = NULL;
argv++;
}
exit(0);
}
/*
* This function will remove any trailing periods from domain, after which it
* returns a pointer to newly allocated memory containing the whois server to
* be queried, or a NULL if the correct server couldn't be determined. The
* caller must remember to free(3) the allocated memory.
*/
static char *
choose_server(char *domain)
{
char *pos, *retval;
if (strchr(domain, ':')) {
cpy1(&retval, ANICHOST);
return (retval);
}
for (pos = strchr(domain, '\0'); pos > domain && *--pos == '.';)
*pos = '\0';
if (*domain == '\0')
errx0(EX_USAGE, "can't search for a null string");
if (strlen(domain) > sizeof("-NORID")-1 &&
strcasecmp(domain + strlen(domain) - sizeof("-NORID") + 1,
"-NORID") == 0) {
cpy1(&retval, NORIDHOST);
return (retval);
}
while (pos > domain && *pos != '.')
--pos;
if (pos <= domain)
return (NULL);
if (isdigit((unsigned char)*++pos))
cpy1(&retval, ANICHOST);
else
cpy2(&retval, pos, QNICHOST_TAIL);
return (retval);
}
static void
whois(const char *query, const char *hostname, int flags)
{
const short BUFSIZE = 256;
char message[BUFSIZE];
struct addrinfo *hostres;
char *buf, *host, *nhost, *p, *tbuf;
size_t c, len;
int i, s, error;
const char *reason = NULL;
struct addrinfo hints, *ai;
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_flags = 0;
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
error = getaddrinfo(hostname, port, &hints, &hostres);
if (error) {
warnx2("%s: %s", hostname, gai_strerror(error));
return;
}
for (s = -1, ai = hostres; ai != NULL; ai = ai->ai_next) {
s = Socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
if (s < 0) {
error = errno;
reason = "socket";
continue;
}
if (Connect(s, ai->ai_addr, ai->ai_addrlen) < 0) {
error = errno;
reason = "connect";
CloseSocket(s);
s = -1;
continue;
}
break;
}
if (s < 0) {
if (reason) {
errno = error;
warn2("%s: %s", hostname, reason);
} else {
warnx0("Unknown error in connection attempt");
}
freeaddrinfo(hostres);
return;
}
if (strcmp(hostname, GERMNICHOST) == 0) {
snprintf(message, BUFSIZE, "-T dn,ace -C US-ASCII %s\r\n", query);
} else if (strcmp(hostname, "dk" QNICHOST_TAIL) == 0) {
snprintf(message, BUFSIZE, "--show-handles %s\r\n", query);
} else if (isdigit(query[0])) {
snprintf(message, BUFSIZE, "n + %s\r\n", query);
} else {
snprintf(message, BUFSIZE, "%s\r\n", query);
}
if(Send(s, message, strlen(message), 0) < 0) {
err0(1, "send failed");
}
nhost = NULL;
while ((buf = sgetln(s, &len)) != NULL) {
while (len > 0 && isspace(buf[len - 1]))
buf[--len] = '\0';
cpy1pad(&tbuf, len, buf);
printf("%s\n", tbuf);
free(tbuf);
if ((flags & WHOIS_RECURSE) && nhost == NULL) {
host = strnstr(buf, WHOIS_SERVER_ID, len);
if (host != NULL) {
host += sizeof(WHOIS_SERVER_ID) - 1;
for (p = host; p < buf + len; p++) {
if (!ishost(*p)) {
*p = '\0';
break;
}
}
cpy1pad(&nhost, (int)(buf + len - host), host);
} else if ((host =
strnstr(buf, WHOIS_ORG_SERVER_ID, len)) != NULL) {
host += sizeof(WHOIS_ORG_SERVER_ID) - 1;
for (p = host; p < buf + len; p++) {
if (!ishost(*p)) {
*p = '\0';
break;
}
}
cpy1pad(&nhost, (int)(buf + len - host), host);
} else if (strcmp(hostname, ANICHOST) == 0) {
for (c = 0; c <= len; c++)
buf[c] = tolower((unsigned char)buf[c]);
for (i = 0; ip_whois[i] != NULL; i++) {
if (strnstr(buf, ip_whois[i], len) !=
NULL) {
cpy1(&nhost, ip_whois[i]);
break;
}
}
}
}
}
CloseSocket(s);
if (nhost != NULL) {
whois(query, nhost, 0);
free(nhost);
}
}
static void
usage(void)
{
fprintf(stderr,
"usage: whois [-aAbfgiIklmQrR6] [-c country-code | -h hostname] "
"[-p port] name ...\n");
exit(EX_USAGE);
}

487
whois_freebsd.c Normal file
View File

@ -0,0 +1,487 @@
/*-
* 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
* 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.
* 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.
*/
#ifndef lint
static const char copyright[] =
"@(#) Copyright (c) 1980, 1993\n\
The Regents of the University of California. All rights reserved.\n";
#endif /* not lint */
#if 0
#ifndef lint
static char sccsid[] = "@(#)whois.c 8.1 (Berkeley) 6/6/93";
#endif /* not lint */
#endif
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/poll.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <ctype.h>
#include <err.h>
#include <netdb.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sysexits.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#define ABUSEHOST "whois.abuse.net"
#define NICHOST "whois.crsnic.net"
#define INICHOST "whois.networksolutions.com"
#define GNICHOST "whois.nic.gov"
#define ANICHOST "whois.arin.net"
#define LNICHOST "whois.lacnic.net"
#define KNICHOST "whois.krnic.net"
#define RNICHOST "whois.ripe.net"
#define PNICHOST "whois.apnic.net"
#define MNICHOST "whois.ra.net"
#define QNICHOST_TAIL ".whois-servers.net"
#define BNICHOST "whois.registro.br"
#define NORIDHOST "whois.norid.no"
#define IANAHOST "whois.iana.org"
#define GERMNICHOST "de.whois-servers.net"
#define FNICHOST "whois.afrinic.net"
#define DEFAULT_PORT "whois"
#define WHOIS_SERVER_ID "Whois Server: "
#define WHOIS_ORG_SERVER_ID "Registrant Street1:Whois Server:"
#define WHOIS_RECURSE 0x01
#define WHOIS_QUICK 0x02
#define ishost(h) (isalnum((unsigned char)h) || h == '.' || h == '-')
static const char *ip_whois[] = { LNICHOST, RNICHOST, PNICHOST, BNICHOST,
FNICHOST, NULL };
static const char *port = DEFAULT_PORT;
static char *choose_server(char *);
static struct addrinfo *gethostinfo(char const *host, int exit_on_error);
static void s_asprintf(char **ret, const char *format, ...) __printflike(2, 3);
static void usage(void);
static void whois(const char *, const char *, int);
int
main(int argc, char *argv[])
{
const char *country, *host;
char *qnichost;
int ch, flags, use_qnichost;
#ifdef SOCKS
SOCKSinit(argv[0]);
#endif
country = host = qnichost = NULL;
flags = use_qnichost = 0;
while ((ch = getopt(argc, argv, "aAbc:fgh:iIklmp:QrR6")) != -1) {
switch (ch) {
case 'a':
host = ANICHOST;
break;
case 'A':
host = PNICHOST;
break;
case 'b':
host = ABUSEHOST;
break;
case 'c':
country = optarg;
break;
case 'f':
host = FNICHOST;
break;
case 'g':
host = GNICHOST;
break;
case 'h':
host = optarg;
break;
case 'i':
host = INICHOST;
break;
case 'I':
host = IANAHOST;
break;
case 'k':
host = KNICHOST;
break;
case 'l':
host = LNICHOST;
break;
case 'm':
host = MNICHOST;
break;
case 'p':
port = optarg;
break;
case 'Q':
flags |= WHOIS_QUICK;
break;
case 'r':
host = RNICHOST;
break;
case 'R':
warnx("-R is deprecated; use '-c ru' instead");
country = "ru";
break;
/* Remove in FreeBSD 10 */
case '6':
errx(EX_USAGE,
"-6 is deprecated; use -[aAflr] instead");
break;
case '?':
default:
usage();
/* NOTREACHED */
}
}
argc -= optind;
argv += optind;
if (!argc || (country != NULL && host != NULL))
usage();
/*
* If no host or 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 '.', fall
* back to NICHOST.
*/
if (host == NULL && country == NULL) {
if ((host = getenv("RA_SERVER")) == NULL) {
use_qnichost = 1;
host = NICHOST;
if (!(flags & WHOIS_QUICK))
flags |= WHOIS_RECURSE;
}
}
while (argc-- > 0) {
if (country != NULL) {
s_asprintf(&qnichost, "%s%s", country, QNICHOST_TAIL);
whois(*argv, qnichost, flags);
} else if (use_qnichost)
if ((qnichost = choose_server(*argv)) != NULL)
whois(*argv, qnichost, flags);
if (qnichost == NULL)
whois(*argv, host, flags);
free(qnichost);
qnichost = NULL;
argv++;
}
exit(0);
}
/*
* This function will remove any trailing periods from domain, after which it
* returns a pointer to newly allocated memory containing the whois server to
* be queried, or a NULL if the correct server couldn't be determined. The
* caller must remember to free(3) the allocated memory.
*/
static char *
choose_server(char *domain)
{
char *pos, *retval;
if (strchr(domain, ':')) {
s_asprintf(&retval, "%s", ANICHOST);
return (retval);
}
for (pos = strchr(domain, '\0'); pos > domain && *--pos == '.';)
*pos = '\0';
if (*domain == '\0')
errx(EX_USAGE, "can't search for a null string");
if (strlen(domain) > sizeof("-NORID")-1 &&
strcasecmp(domain + strlen(domain) - sizeof("-NORID") + 1,
"-NORID") == 0) {
s_asprintf(&retval, "%s", NORIDHOST);
return (retval);
}
while (pos > domain && *pos != '.')
--pos;
if (pos <= domain)
return (NULL);
if (isdigit((unsigned char)*++pos))
s_asprintf(&retval, "%s", ANICHOST);
else
s_asprintf(&retval, "%s%s", pos, QNICHOST_TAIL);
return (retval);
}
static struct addrinfo *
gethostinfo(char const *host, int exit_on_error)
{
struct addrinfo hints, *res;
int error;
memset(&hints, 0, sizeof(hints));
hints.ai_flags = 0;
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
error = getaddrinfo(host, port, &hints, &res);
if (error) {
warnx("%s: %s", host, gai_strerror(error));
if (exit_on_error)
exit(EX_NOHOST);
return (NULL);
}
return (res);
}
/*
* Wrapper for asprintf(3) that exits on error.
*/
static void
s_asprintf(char **ret, const char *format, ...)
{
va_list ap;
va_start(ap, format);
if (vasprintf(ret, format, ap) == -1) {
va_end(ap);
err(EX_OSERR, "vasprintf()");
}
va_end(ap);
}
static void
whois(const char *query, const char *hostname, int flags)
{
FILE *sfi, *sfo;
struct addrinfo *hostres, *res;
char *buf, *host, *nhost, *p;
int s = -1, f;
nfds_t i, j;
size_t c, len, count;
struct pollfd *fds;
int timeout = 180;
hostres = gethostinfo(hostname, 1);
for (res = hostres, count = 0; res; res = res->ai_next)
count++;
fds = calloc(count, sizeof(*fds));
if (fds == NULL)
err(EX_OSERR, "calloc()");
/*
* Traverse the result list elements and make non-block
* connection attempts.
*/
count = i = 0;
for (res = hostres; res != NULL; res = res->ai_next) {
s = socket(res->ai_family, res->ai_socktype | SOCK_NONBLOCK,
res->ai_protocol);
if (s < 0)
continue;
if (connect(s, res->ai_addr, res->ai_addrlen) < 0) {
if (errno == EINPROGRESS) {
/* Add the socket to poll list */
fds[i].fd = s;
fds[i].events = POLLERR | POLLHUP |
POLLIN | POLLOUT;
count++;
i++;
} else {
close(s);
s = -1;
/*
* Poll only if we have something to poll,
* otherwise just go ahead and try next
* address
*/
if (count == 0)
continue;
}
} else
goto done;
/*
* If we are at the last address, poll until a connection is
* established or we failed all connection attempts.
*/
if (res->ai_next == NULL)
timeout = INFTIM;
/*
* Poll the watched descriptors for successful connections:
* if we still have more untried resolved addresses, poll only
* once; otherwise, poll until all descriptors have errors,
* which will be considered as ETIMEDOUT later.
*/
do {
int n;
n = poll(fds, i, timeout);
if (n == 0) {
/*
* No event reported in time. Try with a
* smaller timeout (but cap at 2-3ms)
* after a new host have been added.
*/
if (timeout >= 3)
timeout <<= 1;
break;
} else if (n < 0) {
/*
* errno here can only be EINTR which we would want
* to clean up and bail out.
*/
s = -1;
goto done;
}
/*
* Check for the event(s) we have seen.
*/
for (j = 0; j < i; j++) {
if (fds[j].fd == -1 || fds[j].events == 0 ||
fds[j].revents == 0)
continue;
if (fds[j].revents & ~(POLLIN | POLLOUT)) {
close(s);
fds[j].fd = -1;
fds[j].events = 0;
count--;
continue;
} else if (fds[j].revents & (POLLIN | POLLOUT)) {
/* Connect succeeded. */
s = fds[j].fd;
goto done;
}
}
} while (timeout == INFTIM && count != 0);
}
/* All attempts were failed */
s = -1;
if (count == 0)
errno = ETIMEDOUT;
done:
/* Close all watched fds except the succeeded one */
for (j = 0; j < i; j++)
if (fds[j].fd != s && fds[j].fd != -1)
close(fds[j].fd);
if (s != -1) {
/* Restore default blocking behavior. */
if ((f = fcntl(s, F_GETFL)) != -1) {
f &= ~O_NONBLOCK;
if (fcntl(s, F_SETFL, f) == -1)
err(EX_OSERR, "fcntl()");
} else
err(EX_OSERR, "fcntl()");
}
free(fds);
freeaddrinfo(hostres);
if (s == -1)
err(EX_OSERR, "connect()");
sfi = fdopen(s, "r");
sfo = fdopen(s, "w");
if (sfi == NULL || sfo == NULL)
err(EX_OSERR, "fdopen()");
if (strcmp(hostname, GERMNICHOST) == 0) {
fprintf(sfo, "-T dn,ace -C US-ASCII %s\r\n", query);
} else if (strcmp(hostname, "dk" QNICHOST_TAIL) == 0) {
fprintf(sfo, "--show-handles %s\r\n", query);
} else {
fprintf(sfo, "%s\r\n", query);
}
fflush(sfo);
nhost = NULL;
while ((buf = fgetln(sfi, &len)) != NULL) {
while (len > 0 && isspace((unsigned char)buf[len - 1]))
buf[--len] = '\0';
printf("%.*s\n", (int)len, buf);
if ((flags & WHOIS_RECURSE) && nhost == NULL) {
host = strnstr(buf, WHOIS_SERVER_ID, len);
if (host != NULL) {
host += sizeof(WHOIS_SERVER_ID) - 1;
for (p = host; p < buf + len; p++) {
if (!ishost(*p)) {
*p = '\0';
break;
}
}
s_asprintf(&nhost, "%.*s",
(int)(buf + len - host), host);
} else if ((host =
strnstr(buf, WHOIS_ORG_SERVER_ID, len)) != NULL) {
host += sizeof(WHOIS_ORG_SERVER_ID) - 1;
for (p = host; p < buf + len; p++) {
if (!ishost(*p)) {
*p = '\0';
break;
}
}
s_asprintf(&nhost, "%.*s",
(int)(buf + len - host), host);
} else if (strcmp(hostname, ANICHOST) == 0) {
for (c = 0; c <= len; c++)
buf[c] = tolower((unsigned char)buf[c]);
for (i = 0; ip_whois[i] != NULL; i++) {
if (strnstr(buf, ip_whois[i], len) !=
NULL) {
s_asprintf(&nhost, "%s",
ip_whois[i]);
break;
}
}
}
}
}
if (nhost != NULL) {
whois(query, nhost, 0);
free(nhost);
}
}
static void
usage(void)
{
fprintf(stderr,
"usage: whois [-aAbfgiIklmQrR6] [-c country-code | -h hostname] "
"[-p port] name ...\n");
exit(EX_USAGE);
}

329
whois_netbsd.c Normal file
View File

@ -0,0 +1,329 @@
/* $NetBSD: whois.c,v 1.36 2013/02/20 09:27:52 ws Exp $ */
/* $OpenBSD: whois.c,v 1.28 2003/09/18 22:16:15 fgsch Exp $ */
/*
* 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
* 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. 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.
*/
#include <sys/cdefs.h>
#ifndef lint
__COPYRIGHT("@(#) Copyright (c) 1980, 1993\
The Regents of the University of California. All rights reserved.");
#endif /* not lint */
#ifndef lint
#if 0
static const char sccsid[] = "@(#)whois.c 8.1 (Berkeley) 6/6/93";
#else
__RCSID("$NetBSD: whois.c,v 1.36 2013/02/20 09:27:52 ws Exp $");
#endif
#endif /* not lint */
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <ctype.h>
#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#define ANICHOST "whois.arin.net"
#define BNICHOST "whois.registro.br"
#define CNICHOST "whois.corenic.net"
#define DNICHOST "whois.nic.mil"
#define FNICHOST "whois.afrinic.net"
#define GNICHOST "whois.nic.gov"
#define INICHOST "whois.networksolutions.com"
#define LNICHOST "whois.lacnic.net"
#define MNICHOST "whois.ra.net"
#define NICHOST "whois.crsnic.net"
#define PNICHOST "whois.apnic.net"
#define QNICHOST_TAIL ".whois-servers.net"
#define RNICHOST "whois.ripe.net"
#define RUNICHOST "whois.ripn.net"
#define SNICHOST "whois.6bone.net"
#define WHOIS_PORT "whois"
#define WHOIS_SERVER_ID "Whois Server:"
#define WHOIS_RECURSE 0x01
#define WHOIS_QUICK 0x02
static const char *port_whois = WHOIS_PORT;
static const char *ip_whois[] =
{ LNICHOST, RNICHOST, PNICHOST, FNICHOST, BNICHOST, NULL };
static void usage(void) __dead;
static int whois(const char *, const char *, const char *, int);
static const char *choose_server(const char *, const char *);
int
main(int argc, char *argv[])
{
int ch, flags, rval;
const char *host, *name, *country;
#ifdef SOCKS
SOCKSinit(argv[0]);
#endif
country = host = NULL;
flags = rval = 0;
while ((ch = getopt(argc, argv, "6Aac:dfgh:ilmp:qQRr")) != -1)
switch(ch) {
case 'a':
host = ANICHOST;
break;
case 'A':
host = PNICHOST;
break;
case 'c':
country = optarg;
break;
case 'd':
host = DNICHOST;
break;
case 'f':
host = FNICHOST;
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_whois = 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;
if (!argc || (country != NULL && host != NULL))
usage();
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_whois, flags);
return 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, *fmt;
struct addrinfo hints, *res, *ai;
(void)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) {
error = errno;
reason = "socket";
continue;
}
if (connect(s, ai->ai_addr, ai->ai_addrlen) < 0) {
error = errno;
reason = "connect";
close(s);
s = -1;
continue;
}
break; /*okay*/
}
if (s < 0) {
if (reason) {
errno = error;
warn("%s: %s", server, reason);
} else
warnx("Unknown error in connection attempt");
freeaddrinfo(res);
return (1);
}
if (strcmp(server, "whois.denic.de") == 0 ||
strcmp(server, "de.whois-servers.net") == 0)
fmt = "-T dn,ace -C ISO-8859-1 ";
else
fmt = "";
sfi = fdopen(s, "r");
sfo = fdopen(s, "w");
if (sfi == NULL || sfo == NULL)
err(1, "fdopen");
(void)fprintf(sfo, "%s%s\r\n", fmt, 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");
(void)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((unsigned char)*p))
p++;
if ((len = strcspn(p, " \t\n\r"))) {
if ((nhost = malloc(len + 1)) == NULL)
err(1, "malloc");
(void)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);
(void)fclose(sfi);
(void)fclose(sfo);
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 const char *
choose_server(const char *name, const char *country)
{
static char *server;
char *nserver;
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((unsigned char)*(++qhead)))
return (ANICHOST);
len = strlen(qhead) + sizeof(QNICHOST_TAIL);
if ((nserver = realloc(server, len)) == NULL)
err(1, "realloc");
server = nserver;
(void)strlcpy(server, qhead, len);
(void)strlcat(server, QNICHOST_TAIL, len);
return (server);
}
static void
usage(void)
{
(void)fprintf(stderr,
"usage: %s [-6AadgilmQRr] [-c country-code | -h hostname] "
"[-p port] name ...\n", getprogname());
exit(1);
}

37
workman.sh Normal file
View File

@ -0,0 +1,37 @@
#! /bin/sh
# This file is in the public domain, so clarified as of
# 2009-05-17 by Arthur David Olson.
# Modified by Carsten Larsen
# Tell groff not to emit SGR escape sequences (ANSI color escapes).
GROFF_NO_SGR=1
export GROFF_NO_SGR
#GROFF_SGR=1
#export GROFF_SGR
echo ".am TH
.hy 0
.na
..
.rm }H
.rm }F" | nroff -Tascii -man - ${1+"$@"} | perl -ne '
binmode STDIN, '\'':encoding(ascii)'\'';
binmode STDOUT, '\'':encoding(iso-8859-15)'\'';
chomp;
s/.\010//g;
s/\s*$//;
if (/^$/) {
$sawblank = 1;
next;
} else {
if ($sawblank && $didprint) {
print "\n";
$sawblank = 0;
}
print "$_\n";
$didprint = 1;
}
'