Index: misc/host/.cvsignore diff -u misc/host/.cvsignore:1.4 misc/host/.cvsignore:1.5 --- misc/host/.cvsignore:1.4 Sun Mar 30 18:36:40 2003 +++ misc/host/.cvsignore Wed Jun 4 02:45:17 2003 @@ -1,6 +1,7 @@ .depend host host.0 +host.1.gz mxlookup nscheck nslookup Index: misc/host/Makefile diff -u misc/host/Makefile:1.14 misc/host/Makefile:1.16 --- misc/host/Makefile:1.14 Tue May 27 15:38:36 2003 +++ misc/host/Makefile Wed Jun 4 21:01:45 2003 @@ -1,5 +1,5 @@ # -#ident "@(#)host:HOST-20030527:Makefile,v 1.14 2003/05/27 19:38:36 woods Exp" +#ident "@(#)host:HOST-20030604:Makefile,v 1.16 2003/06/05 01:01:45 woods Exp" # # from: @(#)Makefile e07@nikhef.nl (Eric Wassenaar) 991515 @@ -86,6 +86,10 @@ # Either install a pure BIND resolver library and link host against it # to avoid this, or enable the HOST_RES_SEND option. # +# WARNING: HOST_RES_SEND does not work with properly with BIND-8 +# because the libbind definition of res_send (actually __res_send) is +# sucked in by other pre-linked dependencies in libbind. +# #if defined(BIND_4_9) || newer && You still want to use the special host res_send() #CONFIGDEFS = -DHOST_RES_SEND #endif @@ -201,9 +205,11 @@ # # GNU LibC (i.e. all variants of GNU/Linux) has a horrible mis-mash of # half-baked header files and mangled resolver subroutines, at least -# as of 2.3.x. E.g. there's a __NAMESER define in -# indicating it to be BIND-8 compatible, but there is no implementation -# of getipnodebyname() in sight. +# as of 2.3.x. E.g. there's an __RES define in and a +# __NAMESER define in indicating it to be BIND-8 +# compatible, but there is no implementation of getipnodebyname() in +# sight. Even worse gethostbyaddr() is totally broken and doesn't +# return multiple PTRs. PLEASE build & link with BIND-8.4.0 or newer! # ---------------------------------------------------------------------- #if defined(SCO) && default @@ -212,6 +218,9 @@ #if defined(NEED_LIBRESOLV) || (sunos5.x) || defined(__LINUX__) || defined(__GLIBC__) #RES_LIB = -lresolv #endif +#if (RedHat-8.x) && defined(__GLIBC__) +#RES_LIB = -static -I/usr/lib/debug -lresolv +#endif #if defined(LOCAL_LIBBIND) || (sunos5.x < 5.9) #RES_LIB = -L/usr/local/bind/lib -lbind #endif @@ -234,10 +243,16 @@ # host may often be invoked by "root" -- it's safest to static-link it # +# Note on at least RedHat-8.0 it is necessary to link statically, +# UNLESS you are using libbind from BIND-8.4.0 or newer, as you should +# be doing. +# # Unfortunately SunOS-5.9 has only libresolv.so !!! # -#if defined(NEED_LIBRESOLV) && !defined(sunos5.x) +#if defined(NEED_LIBRESOLV) && !defined(sunos5.x) && !(BIND-8.4.x) LDFLAGS = -static $(GNULDWARNFLAGS) +#else +#LDFLAGS = $(GNULDWARNFLAGS) #endif # ---------------------------------------------------------------------- @@ -319,7 +334,7 @@ .PHONY: clobber clobber: clean - rm -f $(PROG) $(UTIL_PROGS) $(MANCAT) host.0 .depend + rm -f $(PROG) $(UTIL_PROGS) $(MANCAT) host.0 host.1.gz .depend # You might need this rule if your default Make rules are too old and # broken and don't include $(CPPFLAGS)... @@ -330,7 +345,7 @@ .sh: @rm -f $@ - sed -e 's,@BINDIR@,$(BINDIR),g' -e 's,@CONFDIR@,$(CONFDIR),g' < $@.sh > $@ + sed -e 's,@CONFDIR@,$(CONFDIR),g' < $@.sh > $@ chmod +x $@ # ---------------------------------------------------------------------- Index: misc/host/Makefile.BSD diff -u misc/host/Makefile.BSD:1.7 misc/host/Makefile.BSD:1.8 --- misc/host/Makefile.BSD:1.7 Fri May 16 20:51:59 2003 +++ misc/host/Makefile.BSD Wed Jun 4 02:44:53 2003 @@ -5,9 +5,10 @@ # # make -f Makefile.BSD __NetBSD__=1 __GNUC__=2 __GNULD__=2 # -#ident "@(#)newsyslog:HOST-20030527:Makefile.BSD,v 1.7 2003/05/17 00:51:59 woods Exp" +#ident "@(#)newsyslog:HOST-20030604:Makefile.BSD,v 1.8 2003/06/04 06:44:53 woods Exp" # +.include # are we running in the full NetBSD build environment? .if defined(MAKE) && defined(MACHINE) && defined(MACHINE_ARCH) && defined(TOOLDIR) && defined(USETOOLS) @@ -164,7 +165,7 @@ .sh: @rm -f $@ - sed -e 's,@BINDIR@,$(BINDIR),g' -e 's,@CONFDIR@,$(CONFDIR),g' < ${.CURDIR}/$@.sh > $@ + sed -e 's,@CONFDIR@,$(CONFDIR),g' < ${.CURDIR}/$@.sh > $@ chmod +x $@ .if !target(clobber) Index: misc/host/RELEASE_NOTES diff -u misc/host/RELEASE_NOTES:1.8 misc/host/RELEASE_NOTES:1.9 --- misc/host/RELEASE_NOTES:1.8 Tue May 27 15:38:56 2003 +++ misc/host/RELEASE_NOTES Wed Jun 4 21:14:12 2003 @@ -1,6 +1,6 @@ # -*-indented-text-*- # -#ident "@(#)host:HOST-20030527:RELEASE_NOTES,v 1.8 2003/05/27 19:38:56 woods Exp" +#ident "@(#)host:HOST-20030604:RELEASE_NOTES,v 1.9 2003/06/05 01:14:12 woods Exp" # URL: ftp://ftp.weird.com/pub/local/host.tar.gz @@ -20,6 +20,16 @@ # ---------------------------------------------------------------------- # Description of important user-visible changes per release # ---------------------------------------------------------------------- + +2003/06/04 + + - bug fixes for zone transfer read timeout handling. + + - more minor portability fixes for FreeBSD. + + - more portability fixes for GNU/Linux/GNU LibC, though not much + more can be done without some way of forcing use of libbind + from BIND-8.4.0 or newer. 2003/05/27 Index: misc/host/ToDo diff -u misc/host/ToDo:1.1 misc/host/ToDo:1.2 --- misc/host/ToDo:1.1 Fri May 16 21:04:43 2003 +++ misc/host/ToDo Wed Jun 4 21:13:50 2003 @@ -1,2 +1,16 @@ - check that the names in the answer records match the names we asked for (taking CNAMEs into account where they're allowed). + +- allow for setting the (stream) read timeout (conn_timeout) at runtime. + +- use setservbyname() to get the local NAMESERVER_PORT value. + +- allow runtime specification of destination port in server with ':PORT' + +- allow runtime specification of source port with '-O' + +- clean up the host_res_*() mess. + +- build a regression test suite. + +- think about using autobuild. Index: misc/host/addr.c diff -u misc/host/addr.c:1.6 misc/host/addr.c:1.8 --- misc/host/addr.c:1.6 Fri May 16 20:57:32 2003 +++ misc/host/addr.c Wed Jun 4 16:08:07 2003 @@ -17,7 +17,7 @@ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ -#ident "@(#)host:HOST-20030527:addr.c,v 1.6 2003/05/17 00:57:32 woods Exp" +#ident "@(#)host:HOST-20030604:addr.c,v 1.8 2003/06/04 20:08:07 woods Exp" #if 0 static char Version[] = "@(#)addr.c e07@nikhef.nl (Eric Wassenaar) 990605"; @@ -50,7 +50,7 @@ unsigned int matched = 0; char *hname; char hnamebuf[MAXDNAME + 1]; -#if defined(__NAMESER) && ((__NAMESER - 0) >= 19991006) +#if defined(HAVE_GETIPNODEBYNAME) int my_h_errno; #endif @@ -117,7 +117,7 @@ free((ptr_t *) inaddr); -#if defined(__NAMESER) && ((__NAMESER - 0) >= 19991006) +#if defined(HAVE_FREEHOSTENT) freehostent(hp); #endif @@ -145,7 +145,7 @@ register unsigned int i; char *iname, inamebuf[MAXDNAME + 1]; unsigned int matched = 0; -#if defined(__NAMESER) && ((__NAMESER - 0) >= 19991006) +#if defined(HAVE_GETIPNODEBYADDR) int my_h_errno; #endif @@ -216,7 +216,7 @@ name, iname); } -#if defined(__NAMESER) && ((__NAMESER - 0) >= 19991006) +#if defined(HAVE_FREEHOSTENT) freehostent(hp); #endif @@ -244,7 +244,7 @@ char *aname, *anamebuf = NULL; unsigned int naliases = 0; unsigned int matched = 0; -#if defined(__NAMESER) && ((__NAMESER - 0) >= 19991006) +#if defined(HAVE_GETIPNODEBYADDR) int my_h_errno; #endif @@ -260,7 +260,7 @@ * * XXX also need to deal properly with IPv6 too.... */ -#if defined(__NAMESER) && ((__NAMESER - 0) >= 19991006) +#if defined(HAVE_GETIPNODEBYADDR) if (!(hp = getipnodebyaddr((void *) &inaddr, sizeof(inaddr), AF_INET, &my_h_errno))) { set_h_errno(my_h_errno); ns_error(iname, T_PTR, C_IN, server); @@ -330,7 +330,7 @@ free((ptr_t *) anamebuf); -#if defined(__NAMESER) && ((__NAMESER - 0) >= 19991006) +#if defined(HAVE_FREEHOSTENT) freehostent(hp); #endif @@ -359,7 +359,7 @@ struct in_addr inaddr; char *iname, inamebuf[MAXDNAME+1]; unsigned int matched = 0; -#if defined(__NAMESER) && ((__NAMESER - 0) >= 19991006) +#if defined(HAVE_GETIPNODEBYNAME) int my_h_errno; #endif @@ -375,7 +375,7 @@ * * XXX also need to deal properly with IPv6 too.... */ -#if defined(__NAMESER) && ((__NAMESER - 0) >= 19991006) +#if defined(HAVE_GETIPNODEBYNAME) if (!(hp = getipnodebyname(name, AF_INET, AI_ALL | AI_V4MAPPED, &my_h_errno))) { set_h_errno(my_h_errno); ns_error(name, T_A, C_IN, server); @@ -415,7 +415,7 @@ pr_error("address %s does not belong to hostname %s", iname, name); } -#if defined(__NAMESER) && ((__NAMESER - 0) > 19991006) +#if defined(HAVE_FREEHOSTENT) freehostent(hp); #endif Index: misc/host/conf.h diff -u misc/host/conf.h:1.5 misc/host/conf.h:1.6 --- misc/host/conf.h:1.5 Sat Apr 5 22:11:07 2003 +++ misc/host/conf.h Wed Jun 4 21:07:37 2003 @@ -4,7 +4,7 @@ ** @(#)conf.h e07@nikhef.nl (Eric Wassenaar) 961013 */ -#ident "@(#)host:HOST-20030527:conf.h,v 1.5 2003/04/06 03:11:07 woods Exp" +#ident "@(#)host:HOST-20030604:conf.h,v 1.6 2003/06/05 01:07:37 woods Exp" /* * The root domain for the internet reversed mapping zones. @@ -62,13 +62,13 @@ #define MAXCHAIN 10 /* maximum count of recursive chain lookups */ #define MAXNSNAME 16 /* maximum count of nameservers per zone */ -#define MAXIPADDR 10 /* maximum count of addresses per nameserver */ +#define MAXIPADDR MAXADDRS /* maximum count of addresses per nameserver */ /* - * Default timeout values. + * Default retry & timeout values. */ #define DEF_RETRIES 2 /* number of datagram retries per nameserver */ #define DEF_RETRANS 5 /* timeout (seconds) between datagram retries */ -#define CONNTIMEOUT 5 /* connect timeout (value _res.retrans used) */ -#define READTIMEOUT 60 /* read timeout (seconds) during stream I/O */ + +#define DEF_STRM_TMOUT 120 /* read timeout (seconds) for stream I/O */ Index: misc/host/defs.h diff -u misc/host/defs.h:1.19 misc/host/defs.h:1.20 --- misc/host/defs.h:1.19 Wed Apr 9 02:10:41 2003 +++ misc/host/defs.h Wed Jun 4 21:13:16 2003 @@ -4,7 +4,7 @@ ** @(#)defs.h e07@nikhef.nl (Eric Wassenaar) 991529 */ -#ident "@(#)host:HOST-20030527:defs.h,v 1.19 2003/04/09 06:10:41 woods Exp" +#ident "@(#)host:HOST-20030604:defs.h,v 1.20 2003/06/05 01:13:16 woods Exp" /* ** Internal modules of the host utility @@ -146,6 +146,7 @@ int cache_open __P((char *, bool_t)); int cache_close __P((bool_t)); int cache_write __P((char *, size_t)); +int cache_read_anslen __P((void)); int cache_read __P((char *, size_t)); void cache_perror __P((char *, char *)); @@ -162,8 +163,8 @@ int host_res_connect __P((int, struct sockaddr_in *, socklen_t)); int host_res_write __P((int, struct sockaddr_in *, char *, const char *, size_t)); int host_res_read __P((int, struct sockaddr_in *, char *, char *, size_t)); +int host_res_read_anslen __P((int, struct sockaddr_in *, char *)); int host_res_read_stream __P((int, struct sockaddr_in *, char *, char *, size_t)); -int recv_sock __P((int, char *, size_t)); void host_res_perror __P((struct sockaddr_in *, char *, char *)); Index: misc/host/file.c diff -u misc/host/file.c:1.12 misc/host/file.c:1.13 --- misc/host/file.c:1.12 Thu Apr 3 23:10:49 2003 +++ misc/host/file.c Wed Jun 4 21:13:16 2003 @@ -17,7 +17,7 @@ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ -#ident "@(#)host:HOST-20030527:file.c,v 1.12 2003/04/04 04:10:49 woods Exp" +#ident "@(#)host:HOST-20030604:file.c,v 1.13 2003/06/05 01:13:16 woods Exp" #if 0 static char Version[] = "@(#)file.c e07@nikhef.nl (Eric Wassenaar) 991529"; @@ -298,6 +298,39 @@ ** ------------------------------------------------------------- ** ** Returns: +** Expected length of (untruncated) answer. +** -1 in case of failure (error message is issued). +** +*/ +int +cache_read_anslen() +{ + char *buffer; + size_t buflen; + register int n; + u_short len; + + buffer = (char *) &len; + buflen = INT16SZ; + n = cache_read(buffer, buflen); + if (n < 0 || n != (int) buflen) { + cache_perror("cache_read_anslen(): recv_sock(): error reading answer's length", tempcache); + return (-1); + } +#if 0 /* why not? */ + len = ntohs(len); +#else + len = ns_get16((u_char *) &len); +#endif + + return ((int) len); +} + + /* +** CACHE_READ -- Read an answer buffer from the local disk cache +** ------------------------------------------------------------- +** +** Returns: ** Length of (untruncated) answer if successfully read. ** -1 in case of failure (error message is issued). ** @@ -338,7 +371,7 @@ if (buflen != 0) { if (errno == 0) set_errno(EIO); - cache_perror("Cannot read answer length", cachefile); + cache_perror("Cannot read full answer", cachefile); return (-1); } Index: misc/host/host.h diff -u misc/host/host.h:1.12 misc/host/host.h:1.14 --- misc/host/host.h:1.12 Fri May 16 20:56:20 2003 +++ misc/host/host.h Wed Jun 4 21:01:03 2003 @@ -4,7 +4,7 @@ ** from: @(#)host.h e07@nikhef.nl (Eric Wassenaar) 991529 */ -#ident "@(#)host:HOST-20030527:host.h,v 1.12 2003/05/17 00:56:20 woods Exp" +#ident "@(#)host:HOST-20030604:host.h,v 1.14 2003/06/05 01:01:03 woods Exp" #if defined(apollo) && defined(lint) # define __attribute(x) /* XXX ??? */ @@ -26,7 +26,7 @@ # define __USE_FIXED_PROTOTYPES__ #endif -#if defined(BSD) || defined(__bsdi__) || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) +#if defined(BSD) || defined(__bsdi__) || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__linux__) # ifndef TIME_WITH_SYS_TIME # define TIME_WITH_SYS_TIME 1 # endif @@ -120,13 +120,14 @@ # define PACKETSZ 512 /* UDP packet RFC 1035 §2.3.4 */ #endif -#define MAXINT8 255 /* 2^8 */ -#define MAXINT16 65535 /* 2^16 */ +#define MAXINT16 65536 /* 2^16 */ -#if PACKETSZ > MAXINT16 -# define MAXPACKET PACKETSZ -#else -# define MAXPACKET MAXINT16 /* maximum TCP answer length... RFC 1035 §4.2.2 */ +#if !defined(MAXPACKET) +# if PACKETSZ > MAXINT16 +# define MAXPACKET PACKETSZ +# else +# define MAXPACKET MAXINT16 /* maximum TCP answer length... RFC 1035 §4.2.2 */ +# endif #endif #ifndef HFIXEDSZ Index: misc/host/info.c diff -u misc/host/info.c:1.14 misc/host/info.c:1.15 --- misc/host/info.c:1.14 Sat Apr 5 22:12:45 2003 +++ misc/host/info.c Wed Jun 4 16:10:56 2003 @@ -17,7 +17,7 @@ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ -#ident "@(#)host:HOST-20030527:info.c,v 1.14 2003/04/06 03:12:45 woods Exp" +#ident "@(#)host:HOST-20030604:info.c,v 1.15 2003/06/04 20:10:56 woods Exp" #if 0 static char Version[] = "@(#)info.c e07@nikhef.nl (Eric Wassenaar) 991527"; @@ -313,7 +313,7 @@ return (-1); } - if ((n = res_send((qbuf_t *) &query, n, (qbuf_t *) answerbuf, sizeof(querybuf_t))) < 0) { + if ((n = res_send((qbuf_t *) &query, n, (qbuf_t *) answerbuf, sizeof(*answerbuf))) < 0) { if (debug) printf("%sres_send failed\n", debug_prefix); set_h_errno(TRY_AGAIN); Index: misc/host/list.c diff -u misc/host/list.c:1.19 misc/host/list.c:1.20 --- misc/host/list.c:1.19 Sat Apr 5 22:14:29 2003 +++ misc/host/list.c Wed Jun 4 21:13:16 2003 @@ -17,7 +17,7 @@ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ -#ident "@(#)host:HOST-20030527:list.c,v 1.19 2003/04/06 03:14:29 woods Exp" +#ident "@(#)host:HOST-20030604:list.c,v 1.20 2003/06/05 01:13:16 woods Exp" #if 0 static char Version[] = "@(#)list.c e07@nikhef.nl (Eric Wassenaar) 991529"; @@ -1516,9 +1516,7 @@ register int n; int nrecords = 0; /* number of records processed */ int npackets = 0; /* number of packets received */ - u_short len; - char *buffer; - size_t buflen; + int len; /* clear global counts */ soacount = 0; /* count of SOA records */ @@ -1600,52 +1598,17 @@ */ if (loading) { - /* - * XXX this sould probably be something like cache_read_anslen() in file.c - */ - buffer = (char *) &len; - buflen = INT16SZ; - n = cache_read(buffer, buflen); - if (n < 0 || n != (int) buflen) { + if ((len = cache_read_anslen()) < 0) { (void) cache_close(FALSE); set_h_errno(TRY_AGAIN); return (FALSE); } -#if 0 /* why not? */ - len = ntohs(len); -#else - len = ns_get16((u_char *) &len); -#endif - /* - * XXX end of what should be cache_read_anslen() - */ } else { - /* - * XXX this sould probably be something like host_res_read_anslen() in send.c - */ - buffer = (char *) &len; - buflen = INT16SZ; - /* set stream timeout for recv_sock() */ - timeout = READTIMEOUT; - - while (buflen > 0 && (n = recv_sock(sock, buffer, buflen)) > 0) { - buffer += n; - buflen -= n; - } - if (buflen != 0) { - host_res_perror(&ns_sin, host, "recv_sock(): error reading answer length"); + if ((len = host_res_read_anslen(sock, &ns_sin, host)) < 0) { (void) host_res_close(sock); set_h_errno(TRY_AGAIN); return (FALSE); } -#if 0 /* why not? */ - len = ntohs(len); -#else - len = ns_get16((u_char *) &len); -#endif - /* - * XXX end of what should be cache_read_anslen() - */ } /* @@ -1665,9 +1628,7 @@ if (debug > 2) printf("%sexpecting an answer of %d bytes\n", debug_prefix, len); - if (!(answer = (answer) ? - realloc(answer, len) : /* XXX is realloc() really cheaper? */ - malloc(len))) { + if (!(answer = (answer) ? realloc(answer, (size_t) len) : malloc((size_t) len))) { sys_error("unable to allocate %s byte buffer to hold %s for %s from %s", dtoa(len), pr_type(T_AXFR), name, host); if (loading) @@ -1679,9 +1640,9 @@ } if (loading) - n = cache_read(answer, len); + n = cache_read(answer, (size_t) len); else - n = host_res_read_stream(sock, &ns_sin, host, answer, len); + n = host_res_read_stream(sock, &ns_sin, host, answer, (size_t) len); if (n < 0) { /* host_res_perror() already called */ Index: misc/host/main.c diff -u misc/host/main.c:1.17 misc/host/main.c:1.18 --- misc/host/main.c:1.17 Fri May 16 20:59:21 2003 +++ misc/host/main.c Wed Jun 4 16:11:43 2003 @@ -39,7 +39,7 @@ * re-distribute your own modifications to others. */ -#ident "@(#)host:HOST-20030527:main.c,v 1.17 2003/05/17 00:59:21 woods Exp" +#ident "@(#)host:HOST-20030604:main.c,v 1.18 2003/06/04 20:11:43 woods Exp" #if 0 static char Version[] = "@(#)main.c e07@nikhef.nl (Eric Wassenaar) 991529"; @@ -692,17 +692,18 @@ case 'V' : #if defined(__NAMESER) && !defined(HOST_RES_SEND) - printf("Host version %s, BIND-8 resolver API version: %d\n", version, __NAMESER); + printf("Host version %s, BIND-8 resolver version %d, API version: %d\n", version, __RES, __NAMESER); #elif defined(__BIND) && !defined(HOST_RES_SEND) - printf("Host version %s, BIND-4 resolver API version: %d\n", version, __BIND); + printf("Host version %s, BIND-4 resolver version %d, API version: %d\n", version, __RES, __BIND); #elif defined(BIND_4_8) && !defined(HOST_RES_SEND) - printf("Host version %s, BIND 4.8.x resolver\n", version); + printf("Host version %s, BIND 4.8.x resolver version %d\n", version, __RES); #elif defined(__NAMESER) && defined(HOST_RES_SEND) - printf("Host version %s, using private res_send() with BIND-8 resolver API version %d\n", version, __NAMESER); +# include "ERROR: -DHOST_RES_SEND will not work with BIND-8" + printf("Host version %s, using private res_send() with BIND-8 resolver version %d, API version %d\n", version, __RES, __NAMESER); #elif defined(__BIND) && defined(HOST_RES_SEND) - printf("Host version %s, using private res_send() with BIND-4 resolver API version %d\n", version, __BIND); + printf("Host version %s, using private res_send() with BIND-4 resolver version %d, API version %d\n", version, __RES, __BIND); #elif defined(BIND_4_8) && defined(HOST_RES_SEND) - printf("Host version %s, using private res_send() with BIND 4.8.x resolver\n", version); + printf("Host version %s, using private res_send() with BIND 4.8.x resolver version %d\n", version, __RES); #elif defined(HOST_RES_SEND) printf("Host version %s, using private res_send() with very old or non-BIND headers\n", version); #else @@ -760,7 +761,7 @@ /* * Set default preferred server for zone listings, if not specified. */ - if (listmode && !checkmode && !prefserver) { + if (listmode && !checkmode && !prefserver && !servername) { if (!(prefserver = myhostname())) fprintf(stderr, "Nameserver selection will be random, use -P for more control\n"); } Index: misc/host/mxlookup.sh diff -u misc/host/mxlookup.sh:1.1 misc/host/mxlookup.sh:1.2 --- misc/host/mxlookup.sh:1.1 Fri Jan 11 17:28:47 2002 +++ misc/host/mxlookup.sh Wed Jun 4 02:30:27 2003 @@ -1,4 +1,4 @@ -#!/bin/sh - +#! /bin/sh # # @(#)mxlookup e07@nikhef.nl (Eric Wassenaar) 950108 # @@ -6,7 +6,7 @@ # Version: 09-OCT-1994 # Revision: 08-JAN-1995, Make sure servers come from NS records # -#ident "@(#)host:HOST-20030527:mxlookup.sh,v 1.1 2002/01/11 22:28:47 woods Exp" +#ident "@(#)host:HOST-20030604:mxlookup.sh,v 1.2 2003/06/04 06:30:27 woods Exp" # # This utility looks up the MX and A records for a given domain name # at each of the authoritative servers for the zone it belongs to. @@ -21,19 +21,6 @@ # NS records of the zone to which the given domain name belongs. # The -r option disables nameserver recursion at the contacted servers. -exec=echo -exec= - -# ---------------------------------------------------------------------- -# Setup environment. -# ---------------------------------------------------------------------- - -# This is where the ``host'' executable lives. -# -BINDIR=@DESTBIN@ - -PATH=${BINDIR}:/bin:/usr/bin ; export PATH - # ---------------------------------------------------------------------- # Internal vriables. # ---------------------------------------------------------------------- @@ -58,6 +45,7 @@ type="" recurse= verbose= +exec= skip= for i Index: misc/host/nslookup.sh diff -u misc/host/nslookup.sh:1.1 misc/host/nslookup.sh:1.2 --- misc/host/nslookup.sh:1.1 Fri Jan 11 17:28:47 2002 +++ misc/host/nslookup.sh Wed Jun 4 02:30:36 2003 @@ -1,4 +1,4 @@ -#! /bin/sh - +#! /bin/sh # # @(#)nslookup e07@nikhef.nl (Eric Wassenaar) 940919 # @@ -6,23 +6,13 @@ # Version: 19-SEP-1994 # Revision: # -#ident "@(#)host:HOST-20030527:nslookup.sh,v 1.1 2002/01/11 22:28:47 woods Exp" +#ident "@(#)host:HOST-20030604:nslookup.sh,v 1.2 2003/06/04 06:30:36 woods Exp" # # This utility emulates nslookup as a wrapper to host. # It performs most, but not all, functions. exec=echo exec= - -# ---------------------------------------------------------------------- -# Setup environment. -# ---------------------------------------------------------------------- - -# This is where the ``host'' executable lives. -# -BINDIR=@DESTBIN@ - -PATH=${BINDIR}:/bin:/usr/bin:/usr/ucb ; export PATH cmd=`basename $0` Index: misc/host/port.h diff -u misc/host/port.h:1.15 misc/host/port.h:1.16 --- misc/host/port.h:1.15 Fri May 16 21:02:49 2003 +++ misc/host/port.h Wed Jun 4 21:00:07 2003 @@ -3,7 +3,7 @@ ** */ -#ident "@(#)host:HOST-20030527:port.h,v 1.15 2003/05/17 01:02:49 woods Exp" +#ident "@(#)host:HOST-20030604:port.h,v 1.16 2003/06/05 01:00:07 woods Exp" /* * from: @(#)port.h e07@nikhef.nl (Eric Wassenaar) 991328 */ @@ -73,23 +73,15 @@ */ /* - * GNU LibC has a horrible mis-mash of half-baked header files and mangled - * resolver subroutines, at least as of 2.3.x. E.g. there's a __NAMESER define - * in indicating it to be BIND-8 compatible, but there's no - * getipnodebyname() in sight. If we remove the __NAMESER definition then - * we'll just fall back to assuming BIND-4 compatability, and that does, for - * now, seem to be true enough. - */ -#if defined(__NAMESER) && defined(__GLIBC__) -# undef __NAMESER /* bloody lying bastards! */ -#endif - -/* * Every other conceivable version of the BIND-based resolvers should have one * or both of __BIND and/or __NAMESER defined to define their API version. */ #if !defined(__BIND) && !defined(__NAMESER) -# define BIND_4_8 1 +# define BIND_4_8 1 /* XXX this should be ``#include "ERROR!!!"''*/ +#endif + +#if !defined(__RES) +# define __RES 0 /* XXX this should be ``#include "ERROR!!!"''*/ #endif /* @@ -135,6 +127,7 @@ # define STDERR_FILENO 2 #endif +/* XXX should this use __RES instead of __NAMESER? In addition to? */ #if !defined(HAVE_INET_ATON) && \ ((defined(__BIND) && (__BIND - 0) >= 19950621) || \ (defined(__NAMESER) && (__NAMESER - 0) >= 19961001) || \ @@ -148,10 +141,20 @@ * * FreeBSD added getipnodeby*() separately, obtaining them from KAME, but * without adjusting their resolver API version number (leaving it at the - * BIND-8.1.2 level) + * BIND-8.1.2 level of 19961001) + * + * GNU LibC has a horrible mis-mash of half-baked header files and mangled + * resolver subroutines, at least as of 2.3.x. E.g. there's a __NAMESER define + * in indicating it to be BIND-8.2.2 compatible (19991006), but + * there's no getipnodebyname() in sight. __RES is also defined as 19991006. + * Even worse the GLIBC implementation of gethostbyaddr() is totally broken and + * does not return multiple PTRs. + * + * PLEASE always build and link against BIND-8.4.0 or newer! */ -#if defined(__NAMESER) && ((__NAMESER - 0) >= 19991006 || \ - defined(__FreeBSD__) && (__NAMESER - 0) >= 19961001) +#if defined(__NAMESER) && (!defined(__GLIBC__) || ((__RES - 0) > 19991006)) && \ + ((__NAMESER - 0) >= 19991006 || \ + (defined(__FreeBSD__) && (__NAMESER - 0) >= 19961001)) # define HAVE_GETIPNODEBYNAME 1 # define HAVE_GETIPNODEBYADDR 1 # define HAVE_FREEHOSTENT 1 @@ -164,11 +167,13 @@ * resolver with non-DNS lookup methods (especially if the target system 'host' * will be run on uses such foreign schemes -- host is intended to be used only * with the DNS) + * + * NOTE: -DHOST_RES_SEND will not usually work with newer BIND-8 libbind. */ #if !defined(HOST_RES_SEND) && \ (!defined(__BIND) || (__BIND - 0) < 19950621) && \ (!defined(__NAMESER) || (__NAMESER - 0) < 19961001) -# define HOST_RES_SEND 1 /* use the special host res_send() */ +# define HOST_RES_SEND 1 /* use the special host res_send() */ #endif /* @@ -217,7 +222,13 @@ typedef u_char nbuf_t; #endif -#if !defined(__NAMESER) && !defined(__GLIBC__) +/* + * I'm not sure when GNU LibC first got ns_*t*(), but for certain 2.1 with + * __BIND at 19960801 doesn't have them. + */ +#if !defined(__NAMESER) && \ + (!defined(__GLIBC__) || \ + (defined(__GLIBC__) && defined(__BIND) && (__BIND - 0) <= 19960801)) # define ns_get16(src) _getshort(src) # define ns_get32(src) _getlong(src) # define ns_put16(src, dst) __putshort((unsigned short) src, dst) @@ -235,20 +246,34 @@ /* * FreeBSD (and Darwin in its image) is a bit brain-dead in the way they do - * this and still follow the ancient 4.4BSD style of using the fact that - * _BSD_SOCKLEN_T_ is NOT defined in order to typedef socklen_t at the earliest - * point it's needed. However they leave no means for applications to know if - * the typedef has already been done. + * their multiple typedef avoidance -- i.e. they still follow the ancient + * 4.4BSD style of using the fact that _BSD_SOCKLEN_T_ is NOT defined in order + * to typedef socklen_t at the earliest point it's needed. However they leave + * no means for applications to know if the typedef has already been done. + * + * The most elegant way to protect typedefs is to prefix the type name with + * "__" for the typedef and then use a CPP #define to map the true unprefixed + * name to the actual typedef name. This way the presence of the type name as + * a #define tells us that the typedef for it has already been done. + * + * All the other schemes are just inelegant hacks, but at least they're better + * than having to know the details of individual OS library implementations! * * FYI: In NetBSD socklen_t came into use just before 1.3J: * * (__NetBSD_Version__ - 0) > 103100000 + * + * Not sure when GNU LibC added socklen_t, but it's in 2.1 at least. */ #if (defined(__FreeBSD__) || defined(__darwin__)) && defined(_BSD_SOCKLEN_T_) # include "ERROR: something's wrong with the #includes above!" #endif /* Sigh, standards are such wonderful things.... */ -#if !defined(socklen_t) && !defined(__FreeBSD__) && !defined(__darwin__) && !defined(_SOCKLEN_T) && !defined(__socklen_t_defined) +#if !defined(socklen_t) && \ + !defined(__FreeBSD__) && !defined(__darwin__) && \ + !defined(_SOCKLEN_T) && !defined(__socklen_t_defined) && \ + (!defined(__GLIBC__) || (__GLIBC__ - 0) < 2) && \ + (!defined(__GLIBC_MINOR__) || (__GLIBC_MINOR__ - 0) < 1) # if (/* SunOS-4 gcc */defined(__sun__) && !defined(__svr4__)) || \ (/* SunOS-4 cc */defined(sun) && defined(unix) && !defined(__svr4__)) || \ (/* 4.3BSD */defined(BSD) && ((BSD - 0) > 0) && ((BSD - 0) < 199506)) @@ -273,7 +298,8 @@ * is now a size_t width integer, but the returned type is only a ssize_t width * integer.... Standards. Sigh. * - * Perhaps the defined(__sun__) shouldn't be there on the _SOCKLEN_T line.... + * Perhaps the "defined(__sun__)" shouldn't be there on the line with + * !defined(_SOCKLEN_T) -- I need a pure SysVr4 system to check on. */ #if !defined(sock_buflen_t) /* silly dreamer! */ # if (/* SunOS-4 gcc */defined(__sun__) && !defined(__svr4__)) || \ Index: misc/host/rblookup.sh diff -u misc/host/rblookup.sh:1.5 misc/host/rblookup.sh:1.6 --- misc/host/rblookup.sh:1.5 Wed May 21 17:35:58 2003 +++ misc/host/rblookup.sh Wed Jun 4 02:30:47 2003 @@ -1,6 +1,6 @@ #! /bin/sh # -#ident "@(#)host:HOST-20030527:rblookup.sh,v 1.5 2003/05/21 21:35:58 woods Exp" +#ident "@(#)host:HOST-20030604:rblookup.sh,v 1.6 2003/06/04 06:30:47 woods Exp" # # rblookup - Lookup a dotted quad IP address, or hostname in one of many # Reverse/Realtime DNS-based Lists @@ -57,12 +57,7 @@ # Setup environment. # ---------------------------------------------------------------------- -# This is where the ``host'' executable lives. -# -BINDIR=@BINDIR@ CONFDIR=@CONFIDR@ - -PATH=${BINDIR}:/bin:/usr/bin ; export PATH # ---------------------------------------------------------------------- # Internal vriables. Index: misc/host/send.c diff -u misc/host/send.c:1.15 misc/host/send.c:1.16 --- misc/host/send.c:1.15 Fri May 16 20:53:24 2003 +++ misc/host/send.c Wed Jun 4 21:13:16 2003 @@ -17,7 +17,7 @@ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ -#ident "@(#)host:HOST-20030527:send.c,v 1.15 2003/05/17 00:53:24 woods Exp" +#ident "@(#)host:HOST-20030604:send.c,v 1.16 2003/06/05 01:13:16 woods Exp" #if 0 static char Version[] = "@(#)send.c e07@nikhef.nl (Eric Wassenaar) 991331"; @@ -32,11 +32,19 @@ int minport = 0; /* first source port in explicit range */ int maxport = 0; /* last source port in explicit range */ -static unsigned int conn_timeout; /* connection read timeout */ - static struct sockaddr_in from; /* address of inbound packet */ static struct sockaddr *from_sa = (struct sockaddr *) &from; +static unsigned int conn_timeout; /* connection read timeout */ + +static int recv_sock __P((int, char *, size_t)); + +/* + * The first part of this file is our private res_send() implementation. + * + * Note that the remainder of this file is unprotected by the following #ifdef + * and contains generic functions for interacting with a remote nameserver. + */ #ifdef HOST_RES_SEND static int srvsock = -1; /* socket descriptor */ @@ -90,7 +98,7 @@ return (-1); if (bitset(RES_DEBUG, _res.options)) { - printf("%sres_send()\n", debug_prefix); + printf("%sres_send(query, %d, answer, %d) called:\n", debug_prefix, querylen, anslen); pr_query(query, querylen, stdout); } @@ -154,7 +162,7 @@ } } if (n <= 0) { - switch (errno) { + switch (errno) { /* EINVAL (answer was 0 bytes) ??? */ case ECONNREFUSED: case ENETDOWN: case ENETUNREACH: @@ -232,7 +240,6 @@ ** Note that connect() is the call that is allowed to fail ** under normal circumstances. All other failures generate ** an unconditional error message. -** Note that truncation is handled within host_res_read(). */ static int @@ -246,6 +253,7 @@ char *host = NULL; /* name of server is unknown */ const HEADER *qp = (const HEADER *) query; const HEADER *bp = (const HEADER *) answer; + int len; register int n; /* @@ -275,10 +283,31 @@ } /* - * Read the answer buffer. + * Read the answer's lengh. */ -wait: - if ((n = host_res_read(srvsock, addr, host, (char *) answer, (size_t) anslen)) < 0) { + if ((len = host_res_read_anslen(srvsock, addr, host)) < 0) { + (void) host_res_close(srvsock); + return (-1); + } + + /* + * Terminate if length is zero. + */ + if (len == 0) { + set_errno(EINVAL); + host_res_perror(addr, host, "answer has length of zero"); + (void) host_res_close(srvsock); + return (-1); + } + + if (bitset(RES_DEBUG, _res.options)) + printf("%sexpecting an answer of %d bytes\n", debug_prefix, len); + + /* + * Read the answer into the 'answer' buffer. + */ + reread: + if ((n = host_res_read_stream(srvsock, addr, host, (char *) answer, (size_t) len)) < 0) { (void) host_res_close(srvsock); return (-1); } @@ -291,7 +320,7 @@ printf("%sunexpected answer:\n", debug_prefix); pr_query(answer, ((size_t) n > anslen) ? (int) anslen : n, stdout); } - goto wait; + return (-1); } /* @@ -412,7 +441,10 @@ return (n); } -#endif /*HOST_RES_SEND*/ +#endif /* HOST_RES_SEND */ +/* + * remainder of file contains generic client functions + */ /* ** HOST_RES_SOCKET -- Obtain a socket and set additional parameters @@ -502,13 +534,25 @@ ** Returns: ** 0 if close() was successful. ** -1 in case of failure. +** +** NOTE: errno is always left unchanged to accomodate the silly way error +** handling works in this module. */ - int host_res_close(sock) input int sock; { - return close(sock); + int ret; + int save_errno = errno; + + ret = close(sock); + + if (bitset(RES_DEBUG, _res.options) && ret < 0) + printf("%shost_res_close(): close() failed: %s\n", debug_prefix, strerror(errno)); + + set_errno(save_errno); + + return (ret); } /* @@ -663,134 +707,50 @@ } /* -** HOST_RES_READ -- Read the answer buffer via a datagram socket -** ------------------------------------------------------- +** HOST_RES_READ_ANSLEN -- Read the answer length via a stream socket +** ------------------------------------------------------------------ ** ** Returns: -** Length of (untruncated) answer if successfully received. +** Expected length of (untruncated) answer. ** -1 in case of failure (error message is issued). ** -** The answer is read in two steps: first a single word which -** gives the length of the buffer, followed by the buffer itself. -** If the answer is too long to fit into the supplied buffer, -** only the portion that fits will be stored, the residu will be -** flushed, and the truncation flag will be set. -** -** Note: The returned length is that of the *un*truncated answer, -** however, and not the amount of data that is actually available. -** This may give the caller a hint about new buffer reallocation. -** -** Note: This function is currently not used if HOST_RES_SEND is not -** defined, though all of it's companions are used in list.c. */ - int -host_res_read(sock, addr, host, buf, bufsize) +host_res_read_anslen(sock, addr, host) input int sock; /* socket FD to read from */ input struct sockaddr_in *addr; /* the server address to connect to */ input char *host; /* name of server to connect to */ - output char *buf; /* location of buffer to store answer */ - input size_t bufsize; /* maximum size of answer buffer */ { - u_short len; char *buffer; - socklen_t buflen; - size_t reslen; /* residue length.... */ + size_t buflen; register int n; + u_short len; - /* set stream timeout for recv_sock() */ - conn_timeout = READTIMEOUT; - - /* - * Read the length of answer buffer. - */ buffer = (char *) &len; buflen = INT16SZ; + /* set stream timeout for recv_sock() */ + conn_timeout = DEF_STRM_TMOUT; while (buflen > 0 && (n = recv_sock(sock, buffer, buflen)) > 0) { buffer += n; buflen -= n; } if (buflen != 0) { - host_res_perror(addr, host, "recv_sock(): error reading answer length"); + host_res_perror(addr, host, "host_res_read_anslen(): recv_sock(): error reading answer's length"); return (-1); } - - /* - * Terminate if length is zero. - */ -#if 0 +#if 0 /* why not? */ len = ntohs(len); #else len = ns_get16((u_char *) &len); #endif - if (len == 0) { - errno = EINVAL; - host_res_perror(addr, host, "answer has length of zero"); - return (0); - } - /* - * Check for truncation. - * Do not chop the returned length (len) in case of buffer overflow. - */ - reslen = 0; - if (len > bufsize) { - if (bitset(RES_DEBUG, _res.options)) { - printf("%sanswer length %u bytes, bufsize only %lu bytes\n", - debug_prefix, (unsigned int) len, (unsigned long) bufsize); - } - reslen = len - bufsize; - } - - /* - * Read the answer itself. - * Don't read more than we can fit in the supplied buffer. - */ - buffer = buf; - buflen = (reslen > 0) ? bufsize : len; - - while (buflen > 0 && (n = recv_sock(sock, buffer, buflen)) > 0) { - buffer += n; - buflen -= n; - } - if (buflen != 0) { - host_res_perror(addr, host, "recv_sock(): error reading answer"); - return (-1); - } - - /* - * If we're truncating then discard the residue to keep connection in sync. - */ - if (reslen > 0) { - HEADER *bp = (HEADER *) buf; - char junkresbuf[PACKETSZ]; - - buffer = junkresbuf; - buflen = (reslen < sizeof(junkresbuf)) ? reslen : sizeof(junkresbuf); - - while (reslen > 0 && (n = recv_sock(sock, buffer, buflen)) > 0) { - reslen -= n; - buflen = (reslen < sizeof(junkresbuf)) ? reslen : sizeof(junkresbuf); - } - if (reslen != 0) { - host_res_perror(addr, host, "read residu"); - return (-1); - } - if (bitset(RES_DEBUG, _res.options)) { - printf("%sresponse truncated to %lu bytes\n", - debug_prefix, (unsigned long) bufsize); - } - /* set truncation flag */ - bp->tc = 1; - } - - return (len); + return ((int) len); } /* ** HOST_RES_READ_STREAM -- Read the answer buffer via a stream socket -** -------------------------------------------------------------- +** ------------------------------------------------------------------ ** ** Returns: ** Length of (untruncated) answer if successfully received. @@ -810,7 +770,7 @@ register int n; /* set stream timeout for recv_sock() */ - conn_timeout = READTIMEOUT; + conn_timeout = DEF_STRM_TMOUT; /* * Read more of the answer itself. @@ -824,7 +784,7 @@ buflen -= n; } if (buflen != 0) { - host_res_perror(addr, host, "recv_sock(): error reading answer"); + host_res_perror(addr, host, "host_res_read_stream(): recv_sock(): error reading whole answer"); return (-1); } @@ -845,7 +805,7 @@ ** Sets ``from'' to the address of the packet sender. */ -int +static int recv_sock(sock, buffer, buflen) input int sock; /* socket FD to read from */ output char *buffer; /* current buffer address */ @@ -858,8 +818,10 @@ wait.tv_sec = conn_timeout; wait.tv_usec = 0; -rewait: - /* FD_ZERO(&fds); */ + rewait: +#if 0 + FD_ZERO(&fds); +#endif memset((char *) &fds, (int) '\0', sizeof(fds)); FD_SET(sock, &fds); @@ -871,7 +833,7 @@ set_errno(ETIMEDOUT); if (n <= 0) return (-1); -reread: + reread: /* fake an error if nothing was actually read */ fromlen = sizeof(from); n = recvfrom(sock, buffer, (sock_buflen_t) buflen, 0, from_sa, &fromlen); .