about summary refs log tree commit diff
path: root/resolv
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2000-07-19 22:03:58 +0000
committerUlrich Drepper <drepper@redhat.com>2000-07-19 22:03:58 +0000
commite685e07dfa9de08cd0b671e293b94efe116349fa (patch)
tree3c283589ea027f9b4ef9062366e9729e87efd46a /resolv
parent80ec4993cc416058f6f8e98ce32bd729e9be1150 (diff)
downloadglibc-e685e07dfa9de08cd0b671e293b94efe116349fa.tar.gz
glibc-e685e07dfa9de08cd0b671e293b94efe116349fa.tar.xz
glibc-e685e07dfa9de08cd0b671e293b94efe116349fa.zip
Update.
2000-07-18  Mark Kettenis  <kettenis@gnu.org>

	Update resolver code to BIND 8.2.3-T5B.

	* resolv/Versions [GLIBC_2.2] (libc): Add __res_init and
	__res_nclose.
	[GLIBC_2.2] (libresolv): Add __dn_expand, __ns_samename,
	__res_mkquery, __res_nsend, __res_query, __res_querydomain and
	__res_search.
	* resolv/Banner: BIND-8.2.3-T5B.

	* resolv/base64.c: Update from BIND 8.2.3-T5B.
	* resolv/herror.c: Likewise.
	* resolv/inet_addr.c: Likewise.
	* resolv/inet_net_ntop.c: Likewise.
	* resolv/inet_net_pton.c: Likewise.
	* resolv/inet_neta.c: Likewise.
	* resolv/inet_ntop.c: Likewise.
	* resolv/nsap_addr.c: Likewise.
	* resolv/inet_pton.c: Likewise.  Reject a few more more invalid
	IPv6 addresses (ISC bug #520).

	* resolv/ns_name.c: Avoid emitting RCS ID in object file.
	* resolv/ns_parse.c: Likewise.
	* resolv/ns_netint.c: Likewise.
	* resolv/ns_samedomain.c: Likewise.
	* resolv/ns_ttl.c: Likewise.
	* resolv/ns_print.c: Update from BIND 8.2.3-T5B.  Avoid emitting
	RCS ID in object file.

	* resolv/res_debug.c: Update from BIND 8.2.3-T5B.
	* resolv/res_mkquery.c: Likewise.
	* resolv/res_query.c: Likewise.
	* resolv/res_init.c: Likewise.
	(res_setoptions): Mark internal.
	* resolv/res_send.c: Likewise.
	[_LIBC]: Fully reinstate the code that avoids the FD_SETSIZE limit
	by using poll instead.
	* resolv/res_comp.c: Likewise.
	[SHLIB_COMPAT (libresolv, GLIBC_2_0, GLIBC_2_2)]: Make dn_expand a
	weak alias for __dn_expand.
	* resolv/res_data.c: Likewise.
	(res_close) [_LIBC]: Don't call res_nclose if RES_INIT isn't set
	in _res.options.  Avoids a potential security risk by avoiding a
	close (0).
	[SHLIB_COMPAT (libresolv, GLIBC_2_0, GLIBC_2_2)]: Make
	res_mkquery, res_query, res_querydomain adn res_search weak
	aliases for __res_mkquery, __res_query, __res_querydomain and
	__res_search.
	* resolv/res_libc.c: (_res): Don't initialize.  Fix res_close
	instead to avoid close(0).
	(res_init): Always use the static resolver context.
	[SHLIB_COMPAT (libc, GLIBC_2.0, GLIBC_2_2)]: Make res_init a weak
	alias for __res_init.

	* resolv/resolv.h: Update from BIND 8.2.3-T5B.  Move definition of
	RES_SET_H_ERRNO and accompanying comment to...
	* include/resolv.h: ... here.

	* resolv/arpa/namser.h: Update from BIND 8.2.3-T5B.
	* resolv/arpa/nameser_compat.h: Likewise.
Diffstat (limited to 'resolv')
-rw-r--r--resolv/Banner2
-rw-r--r--resolv/Versions9
-rw-r--r--resolv/arpa/nameser.h13
-rw-r--r--resolv/arpa/nameser_compat.h3
-rw-r--r--resolv/base64.c56
-rw-r--r--resolv/herror.c69
-rw-r--r--resolv/inet_addr.c79
-rw-r--r--resolv/inet_net_ntop.c8
-rw-r--r--resolv/inet_net_pton.c16
-rw-r--r--resolv/inet_neta.c4
-rw-r--r--resolv/inet_ntop.c27
-rw-r--r--resolv/inet_pton.c31
-rw-r--r--resolv/ns_name.c92
-rw-r--r--resolv/ns_netint.c4
-rw-r--r--resolv/ns_parse.c4
-rw-r--r--resolv/ns_print.c37
-rw-r--r--resolv/ns_samedomain.c4
-rw-r--r--resolv/ns_ttl.c5
-rw-r--r--resolv/nsap_addr.c8
-rw-r--r--resolv/res_comp.c30
-rw-r--r--resolv/res_data.c35
-rw-r--r--resolv/res_debug.c54
-rw-r--r--resolv/res_init.c47
-rw-r--r--resolv/res_libc.c56
-rw-r--r--resolv/res_mkquery.c10
-rw-r--r--resolv/res_query.c41
-rw-r--r--resolv/res_send.c1069
-rw-r--r--resolv/resolv.h273
28 files changed, 1077 insertions, 1009 deletions
diff --git a/resolv/Banner b/resolv/Banner
index d05a4e3ee7..e585ed8532 100644
--- a/resolv/Banner
+++ b/resolv/Banner
@@ -1 +1 @@
-BIND-8.2.2-5
+BIND-8.2.3-T5B
diff --git a/resolv/Versions b/resolv/Versions
index 98fa762a75..0f9255d08b 100644
--- a/resolv/Versions
+++ b/resolv/Versions
@@ -20,7 +20,7 @@ libc {
   }
   GLIBC_2.2 {
     # r*
-    __res_state; __res_ninit;
+    __res_state; __res_init; __res_nclose; __res_ninit;
   }
 }
 
@@ -51,8 +51,11 @@ libresolv {
     __ns_name_unpack; __ns_name_ntop;
   }
   GLIBC_2.2 {
-    __res_nmkquery; __res_nquery; __res_nquerydomain; __res_nsearch;
-    __ns_get16; __res_hostalias;
+    __dn_expand;
+    __ns_get16; __ns_samename;
+    __res_hostalias; __res_mkquery; __res_nmkquery; __res_nquery;
+    __res_nquerydomain; __res_nsearch; __res_nsend; __res_query;
+    __res_querydomain; __res_search;
 }
 
 libnss_dns {
diff --git a/resolv/arpa/nameser.h b/resolv/arpa/nameser.h
index 6655f3b8d2..6ae1bc61ea 100644
--- a/resolv/arpa/nameser.h
+++ b/resolv/arpa/nameser.h
@@ -45,7 +45,7 @@
  */
 
 /*
- *	$Id$
+ *	$BINDId: nameser.h,v 8.37 2000/03/30 21:16:49 vixie Exp $
  */
 
 #ifndef _ARPA_NAMESER_H_
@@ -53,9 +53,13 @@
 
 #define BIND_4_COMPAT
 
-#include <features.h>
 #include <sys/param.h>
-#include <sys/types.h>
+#if (!defined(BSD)) || (BSD < 199306)
+# include <sys/bitypes.h>
+#else
+# include <sys/types.h>
+#endif
+#include <sys/cdefs.h>
 
 /*
  * Revision information.  This is the release date in YYYYMMDD format.
@@ -481,6 +485,7 @@ typedef enum __ns_cert_types {
 #define	ns_name_compress	__ns_name_compress
 #define	ns_name_uncompress	__ns_name_uncompress
 #define	ns_name_skip		__ns_name_skip
+#define	ns_name_rollback	__ns_name_rollback
 #define	ns_sign			__ns_sign
 #define	ns_sign_tcp		__ns_sign_tcp
 #define	ns_sign_tcp_init	__ns_sign_tcp_init
@@ -522,6 +527,8 @@ int		ns_name_uncompress __P((const u_char *, const u_char *,
 int		ns_name_compress __P((const char *, u_char *, size_t,
 				      const u_char **, const u_char **));
 int		ns_name_skip __P((const u_char **, const u_char *));
+void		ns_name_rollback __P((const u_char *, const u_char **,
+				      const u_char **));
 int		ns_sign __P((u_char *, int *, int, int, void *,
 			     const u_char *, int, u_char *, int *, time_t));
 int		ns_sign_tcp __P((u_char *, int *, int, int,
diff --git a/resolv/arpa/nameser_compat.h b/resolv/arpa/nameser_compat.h
index f67f5b3a67..43bcd3affe 100644
--- a/resolv/arpa/nameser_compat.h
+++ b/resolv/arpa/nameser_compat.h
@@ -28,7 +28,7 @@
 
 /*
  *      from nameser.h	8.1 (Berkeley) 6/2/93
- *	$Id$
+ *	$BINDId: nameser_compat.h,v 8.11 1999/01/02 08:00:58 vixie Exp $
  */
 
 #ifndef _ARPA_NAMESER_COMPAT_
@@ -36,7 +36,6 @@
 
 #define	__BIND		19950621	/* (DEAD) interface version stamp. */
 
-/* glibc always has byte order info in <endian.h> */
 #include <endian.h>
 
 /*
diff --git a/resolv/base64.c b/resolv/base64.c
index 4e7e2a06d5..b7c7d1c1b8 100644
--- a/resolv/base64.c
+++ b/resolv/base64.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996 by Internet Software Consortium.
+ * Copyright (c) 1996-1999 by Internet Software Consortium.
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -40,9 +40,14 @@
  * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
  */
 
+#if !defined(LINT) && !defined(CODECENTER)
+static const char rcsid[] = "$BINDId: base64.c,v 8.7 1999/10/13 16:39:33 vixie Exp $";
+#endif /* not lint */
+
 #include <sys/types.h>
 #include <sys/param.h>
 #include <sys/socket.h>
+
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <arpa/nameser.h>
@@ -50,13 +55,8 @@
 #include <ctype.h>
 #include <resolv.h>
 #include <stdio.h>
-
-#if defined(BSD) && (BSD >= 199103) && defined(AF_INET6)
-# include <stdlib.h>
-# include <string.h>
-#else
-# include "../conf/portability.h"
-#endif
+#include <stdlib.h>
+#include <string.h>
 
 #define Assert(Cond) if (!(Cond)) abort()
 
@@ -112,9 +112,9 @@ static const char Pad64 = '=';
    end of the data is performed using the '=' character.
 
    Since all base64 input is an integral number of octets, only the
-         -------------------------------------------------
+         -------------------------------------------------                       
    following cases can arise:
-
+   
        (1) the final quantum of encoding input is an integral
            multiple of 24 bits; here, the final unit of encoded
 	   output will be an integral multiple of 4 characters
@@ -128,12 +128,7 @@ static const char Pad64 = '=';
    */
 
 int
-b64_ntop(src, srclength, target, targsize)
-	u_char const *src;
-	size_t srclength;
-	char *target;
-	size_t targsize;
-{
+b64_ntop(u_char const *src, size_t srclength, char *target, size_t targsize) {
 	size_t datalength = 0;
 	u_char input[3];
 	u_char output[4];
@@ -161,14 +156,14 @@ b64_ntop(src, srclength, target, targsize)
 		target[datalength++] = Base64[output[2]];
 		target[datalength++] = Base64[output[3]];
 	}
-
+    
 	/* Now we worry about padding. */
 	if (0 != srclength) {
 		/* Get what's left. */
 		input[0] = input[1] = input[2] = '\0';
 		for (i = 0; i < srclength; i++)
 			input[i] = *src++;
-
+	
 		output[0] = input[0] >> 2;
 		output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
 		output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
@@ -204,8 +199,7 @@ b64_pton(src, target, targsize)
 	u_char *target;
 	size_t targsize;
 {
-	size_t tarindex;
-	int state, ch;
+	int tarindex, state, ch;
 	char *pos;
 
 	state = 0;
@@ -225,7 +219,7 @@ b64_pton(src, target, targsize)
 		switch (state) {
 		case 0:
 			if (target) {
-				if (tarindex >= targsize)
+				if ((size_t)tarindex >= targsize)
 					return (-1);
 				target[tarindex] = (pos - Base64) << 2;
 			}
@@ -233,7 +227,7 @@ b64_pton(src, target, targsize)
 			break;
 		case 1:
 			if (target) {
-				if (tarindex + 1 >= targsize)
+				if ((size_t)tarindex + 1 >= targsize)
 					return (-1);
 				target[tarindex]   |=  (pos - Base64) >> 4;
 				target[tarindex+1]  = ((pos - Base64) & 0x0f)
@@ -244,7 +238,7 @@ b64_pton(src, target, targsize)
 			break;
 		case 2:
 			if (target) {
-				if (tarindex + 1 >= targsize)
+				if ((size_t)tarindex + 1 >= targsize)
 					return (-1);
 				target[tarindex]   |=  (pos - Base64) >> 2;
 				target[tarindex+1]  = ((pos - Base64) & 0x03)
@@ -255,7 +249,7 @@ b64_pton(src, target, targsize)
 			break;
 		case 3:
 			if (target) {
-				if (tarindex >= targsize)
+				if ((size_t)tarindex >= targsize)
 					return (-1);
 				target[tarindex] |= (pos - Base64);
 			}
@@ -281,12 +275,7 @@ b64_pton(src, target, targsize)
 
 		case 2:		/* Valid, means one byte of info */
 			/* Skip any number of spaces. */
-#ifdef _LIBC
-			/* To avoid warnings.  */
-			for ( ; ch != '\0'; ch = *src++)
-#else
-			for (NULL; ch != '\0'; ch = *src++)
-#endif
+			for ((void)NULL; ch != '\0'; ch = *src++)
 				if (!isspace(ch))
 					break;
 			/* Make sure there is another trailing = sign. */
@@ -301,12 +290,7 @@ b64_pton(src, target, targsize)
 			 * We know this char is an =.  Is there anything but
 			 * whitespace after it?
 			 */
-#ifdef _LIBC
-			/* To avoid warnings.  */
-			for ( ; ch != '\0'; ch = *src++)
-#else
-			for (NULL; ch != '\0'; ch = *src++)
-#endif
+			for ((void)NULL; ch != '\0'; ch = *src++)
 				if (!isspace(ch))
 					return (-1);
 
diff --git a/resolv/herror.c b/resolv/herror.c
index 8ba0ebef62..d53a0b5b0e 100644
--- a/resolv/herror.c
+++ b/resolv/herror.c
@@ -1,9 +1,7 @@
 /*
- * ++Copyright++ 1987, 1993
- * -
  * Copyright (c) 1987, 1993
  *    The Regents of the University of California.  All rights reserved.
- *
+ * 
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -15,7 +13,7 @@
  * 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
@@ -27,44 +25,43 @@
  * 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.
- * -
- * Portions Copyright (c) 1993 by Digital Equipment Corporation.
+ */
+
+/*
+ * Portions Copyright (c) 1996-1999 by Internet Software Consortium.
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies, and that
- * the name of Digital Equipment Corporation not be used in advertising or
- * publicity pertaining to distribution of the document or software without
- * specific, written prior permission.
+ * copyright notice and this permission notice appear in all copies.
  *
- * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
- * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
- * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
  * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  * SOFTWARE.
- * -
- * --Copyright--
  */
 
 #if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)herror.c	8.1 (Berkeley) 6/4/93";
-static char rcsid[] = "$Id$";
+static const char sccsid[] = "@(#)herror.c	8.1 (Berkeley) 6/4/93";
+static const char rcsid[] = "$BINDId: herror.c,v 8.11 1999/10/13 16:39:39 vixie Exp $";
 #endif /* LIBC_SCCS and not lint */
 
 #include <sys/types.h>
 #include <sys/param.h>
 #include <sys/uio.h>
+
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+
 #include <netdb.h>
+#include <resolv.h>
+#include <string.h>
+#include <unistd.h>
+
 #include <libintl.h>
-#if defined(BSD) && (BSD >= 199103)
-# include <unistd.h>
-# include <string.h>
-#else
-# include "../conf/portability.h"
-#endif
 
 const char *h_errlist[] = {
 	N_("Resolver Error 0 (no error)"),
@@ -75,23 +72,17 @@ const char *h_errlist[] = {
 };
 int	h_nerr = { sizeof h_errlist / sizeof h_errlist[0] };
 
-#ifndef h_errno
-extern int	h_errno;
-#endif
-
 /*
  * herror --
  *	print the error indicated by the h_errno value.
  */
 void
-herror(s)
-	const char *s;
-{
-	struct iovec iov[4];
-	register struct iovec *v = iov;
+herror(const char *s) {
+	struct iovec iov[4], *v = iov;
+	extern int * __h_errno();
 
-	if (s && *s) {
-		v->iov_base = (char *)s;
+	if (s != NULL && *s != '\0') {
+		v->iov_base = (/*noconst*/ char *)s;
 		v->iov_len = strlen(s);
 		v++;
 		v->iov_base = ": ";
@@ -106,10 +97,12 @@ herror(s)
 	__writev(STDERR_FILENO, iov, (v - iov) + 1);
 }
 
+/*
+ * hstrerror --
+ *	return the string associated with a given "host" errno value.
+ */
 const char *
-hstrerror(err)
-	int err;
-{
+hstrerror(int err) {
 	if (err < 0)
 		return _("Resolver internal error");
 	else if (err < h_nerr)
diff --git a/resolv/inet_addr.c b/resolv/inet_addr.c
index 48373b2060..59e160e435 100644
--- a/resolv/inet_addr.c
+++ b/resolv/inet_addr.c
@@ -1,9 +1,7 @@
 /*
- * ++Copyright++ 1983, 1990, 1993
- * -
  * Copyright (c) 1983, 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:
@@ -15,7 +13,7 @@
  * 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
@@ -27,16 +25,18 @@
  * 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.
- * -
+ */
+
+/*
  * Portions Copyright (c) 1993 by Digital Equipment Corporation.
- *
+ * 
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
  * copyright notice and this permission notice appear in all copies, and that
  * the name of Digital Equipment Corporation not be used in advertising or
  * publicity pertaining to distribution of the document or software without
  * specific, written prior permission.
- *
+ * 
  * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
  * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
  * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
@@ -45,20 +45,38 @@
  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
  * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  * SOFTWARE.
- * -
- * --Copyright--
+ */
+
+/*
+ * Portions Copyright (c) 1996-1999 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
  */
 
 #if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)inet_addr.c	8.1 (Berkeley) 6/17/93";
-static char rcsid[] = "$Id$";
+static const char sccsid[] = "@(#)inet_addr.c	8.1 (Berkeley) 6/17/93";
+static const char rcsid[] = "$BINDId: inet_addr.c,v 8.11 1999/10/13 16:39:25 vixie Exp $";
 #endif /* LIBC_SCCS and not lint */
 
 #include <sys/types.h>
 #include <sys/param.h>
+
 #include <netinet/in.h>
 #include <arpa/inet.h>
+
 #include <ctype.h>
+
 #ifdef _LIBC
 # include <endian.h>
 # include <stdint.h>
@@ -66,18 +84,13 @@ static char rcsid[] = "$Id$";
 # include <limits.h>
 # include <errno.h>
 #endif
-#include "../conf/portability.h"
-
-/* these are compatibility routines, not needed on recent BSD releases */
 
 /*
  * Ascii internet address interpretation routine.
  * The value returned is in network order.
  */
 in_addr_t
-inet_addr(cp)
-	register const char *cp;
-{
+inet_addr(const char *cp) {
 	struct in_addr val;
 
 	if (__inet_aton(cp, &val))
@@ -85,7 +98,7 @@ inet_addr(cp)
 	return (INADDR_NONE);
 }
 
-/*
+/* 
  * Check whether "cp" is a valid ascii representation
  * of an Internet address and convert to a binary address.
  * Returns 1 if the address is valid, 0 if not.
@@ -93,21 +106,18 @@ inet_addr(cp)
  * cannot distinguish between failure and a local broadcast address.
  */
 in_addr_t
-__inet_aton(cp, addr)
-	const char *cp;
-	struct in_addr *addr;
-{
+__inet_aton(const char *cp, struct in_addr *addr) {
 	static const in_addr_t max[4] = { 0xffffffff, 0xffffff, 0xffff, 0xff };
-	register in_addr_t val;
+	in_addr_t val;
 #ifndef _LIBC
-	register int base;
+	int base;
 #endif
-	register char c;
+	char c;
 	union iaddr {
 	  uint8_t bytes[4];
 	  uint32_t word;
 	} res;
-	register uint8_t *pp = res.bytes;
+	uint8_t *pp = res.bytes;
 	int digit;
 
 #ifdef _LIBC
@@ -140,23 +150,28 @@ __inet_aton(cp, addr)
 		}
 		c = *cp;
 #else
-		base = 10;
+		val = 0; base = 10; digit = 0;
 		if (c == '0') {
 			c = *++cp;
 			if (c == 'x' || c == 'X')
 				base = 16, c = *++cp;
-			else
+			else {
 				base = 8;
+				digit = 1 ;
+			}
 		}
-		val = 0;
 		for (;;) {
 			if (isascii(c) && isdigit(c)) {
+				if (base == 8 && (c == '8' || c == '9'))
+					return (0);
 				val = (val * base) + (c - '0');
 				c = *++cp;
+				digit = 1;
 			} else if (base == 16 && isascii(c) && isxdigit(c)) {
 				val = (val << 4) |
 					(c + 10 - (islower(c) ? 'a' : 'A'));
 				c = *++cp;
+				digit = 1;
 			} else
 				break;
 		}
@@ -168,8 +183,7 @@ __inet_aton(cp, addr)
 			 *	a.b.c	(with c treated as 16 bits)
 			 *	a.b	(with b treated as 24 bits)
 			 */
-			if (pp > res.bytes + 3
-			    || val > 0xff)
+			if (pp > res.bytes + 3 || val > 0xff)
 				goto ret_0;
 			*pp++ = val;
 			c = *++cp;
@@ -181,7 +195,6 @@ __inet_aton(cp, addr)
 	 */
 	if (c != '\0' && (!isascii(c) || !isspace(c)))
 		goto ret_0;
-
 	/*
 	 * Did we get a valid digit?
 	 */
@@ -193,7 +206,7 @@ __inet_aton(cp, addr)
 	if (val > max[pp - res.bytes])
 	  goto ret_0;
 
-	if (addr)
+	if (addr != NULL)
 		addr->s_addr = res.word | htonl (val);
 
 #ifdef _LIBC
diff --git a/resolv/inet_net_ntop.c b/resolv/inet_net_ntop.c
index d012c537cf..ac7160532e 100644
--- a/resolv/inet_net_ntop.c
+++ b/resolv/inet_net_ntop.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996 by Internet Software Consortium.
+ * Copyright (c) 1996,1999 by Internet Software Consortium.
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -16,7 +16,7 @@
  */
 
 #if defined(LIBC_SCCS) && !defined(lint)
-static const char rcsid[] = "$Id$";
+static const char rcsid[] = "$BINDId: inet_net_ntop.c,v 1.6 1999/01/08 19:23:42 vixie Exp $";
 #endif
 
 #include <sys/types.h>
@@ -74,7 +74,7 @@ inet_net_ntop(af, src, bits, dst, size)
  *	pointer to dst, or NULL if an error occurred (check errno).
  * note:
  *	network byte order assumed.  this means 192.5.5.240/28 has
- *	0x11110000 in its fourth octet.
+ *	0b11110000 in its fourth octet.
  * author:
  *	Paul Vixie (ISC), July 1996
  */
@@ -98,7 +98,7 @@ inet_net_ntop_ipv4(src, bits, dst, size)
 		if (size < sizeof "0")
 			goto emsgsize;
 		*dst++ = '0';
-		--size;
+		size--;
 		*dst = '\0';
 	}
 
diff --git a/resolv/inet_net_pton.c b/resolv/inet_net_pton.c
index 50ab9f8934..a7e597ab92 100644
--- a/resolv/inet_net_pton.c
+++ b/resolv/inet_net_pton.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996 by Internet Software Consortium.
+ * Copyright (c) 1996,1999 by Internet Software Consortium.
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -16,7 +16,7 @@
  */
 
 #if defined(LIBC_SCCS) && !defined(lint)
-static const char rcsid[] = "$Id$";
+static const char rcsid[] = "$BINDId: inet_net_pton.c,v 1.11 1999/01/08 19:23:44 vixie Exp $";
 #endif
 
 #include <sys/types.h>
@@ -81,7 +81,7 @@ inet_net_pton(af, src, dst, size)
  *	not an IPv4 network specification.
  * note:
  *	network byte order assumed.  this means 192.5.5.240/28 has
- *	0x11110000 in its fourth octet.
+ *	0b11110000 in its fourth octet.
  * author:
  *	Paul Vixie (ISC), June 1996
  */
@@ -101,7 +101,7 @@ inet_net_pton_ipv4(src, dst, size)
 		/* Hexadecimal: Eat nybble string. */
 		if (size <= 0)
 			goto emsgsize;
-		*dst = 0, dirty = 0;
+		dirty = 0;
 		tmp = 0;	/* To calm down gcc.  */
 		src++;	/* skip x or X. */
 		while (isxdigit((ch = *src++))) {
@@ -109,9 +109,9 @@ inet_net_pton_ipv4(src, dst, size)
 			n = (const char *) __rawmemchr(xdigits, ch) - xdigits;
 			assert(n >= 0 && n <= 15);
 			if (dirty == 0)
-				tmp = n << 4;
+				tmp = n;
 			else
-				tmp |= n;
+				tmp = (tmp << 4) | n;
 			if (++dirty == 2) {
 				if (size-- <= 0)
 					goto emsgsize;
@@ -119,10 +119,10 @@ inet_net_pton_ipv4(src, dst, size)
 				dirty = 0;
 			}
 		}
-		if (dirty) {
+		if (dirty) {  /* Odd trailing nybble? */
 			if (size-- <= 0)
 				goto emsgsize;
-			*dst = (u_char) tmp;
+			*dst++ = (u_char) (tmp << 4);
 		}
 	} else if (isascii(ch) && isdigit(ch)) {
 		/* Decimal: eat dotted digit string. */
diff --git a/resolv/inet_neta.c b/resolv/inet_neta.c
index 5633ed124f..349e6bd880 100644
--- a/resolv/inet_neta.c
+++ b/resolv/inet_neta.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996 by Internet Software Consortium.
+ * Copyright (c) 1996,1999 by Internet Software Consortium.
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -16,7 +16,7 @@
  */
 
 #if defined(LIBC_SCCS) && !defined(lint)
-static const char rcsid[] = "$Id$";
+static const char rcsid[] = "$BINDId: inet_neta.c,v 1.6 1999/01/08 19:23:45 vixie Exp $";
 #endif
 
 #include <sys/types.h>
diff --git a/resolv/inet_ntop.c b/resolv/inet_ntop.c
index a95f684945..f99a69ba75 100644
--- a/resolv/inet_ntop.c
+++ b/resolv/inet_ntop.c
@@ -1,4 +1,5 @@
-/* Copyright (c) 1996 by Internet Software Consortium.
+/*
+ * Copyright (c) 1996-1999 by Internet Software Consortium.
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -15,19 +16,20 @@
  */
 
 #if defined(LIBC_SCCS) && !defined(lint)
-static char rcsid[] = "$Id$";
+static const char rcsid[] = "$BINDId: inet_ntop.c,v 1.8 1999/10/13 16:39:28 vixie Exp $";
 #endif /* LIBC_SCCS and not lint */
 
 #include <sys/param.h>
 #include <sys/types.h>
 #include <sys/socket.h>
+
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <arpa/nameser.h>
-#include <string.h>
+
 #include <errno.h>
 #include <stdio.h>
-#include "../conf/portability.h"
+#include <string.h>
 
 #ifdef SPRINTF_CHAR
 # define SPRINTF(x) strlen(sprintf/**/x)
@@ -40,9 +42,9 @@ static char rcsid[] = "$Id$";
  * sizeof(int) < 4.  sizeof(int) > 4 is fine; all the world's not a VAX.
  */
 
-static const char *inet_ntop4 __P((const u_char *src, char *dst, socklen_t size))
+static const char *inet_ntop4 (const u_char *src, char *dst, socklen_t size)
      internal_function;
-static const char *inet_ntop6 __P((const u_char *src, char *dst, socklen_t size))
+static const char *inet_ntop6 (const u_char *src, char *dst, socklen_t size)
      internal_function;
 
 /* char *
@@ -74,7 +76,7 @@ inet_ntop(af, src, dst, size)
 
 /* const char *
  * inet_ntop4(src, dst, size)
- *	format an IPv4 address, more or less like inet_ntoa()
+ *	format an IPv4 address
  * return:
  *	`dst' (as a const)
  * notes:
@@ -122,7 +124,7 @@ inet_ntop6(src, dst, size)
 	 */
 	char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp;
 	struct { int base, len; } best, cur;
-	u_int words[IN6ADDRSZ / INT16SZ];
+	u_int words[NS_IN6ADDRSZ / NS_INT16SZ];
 	int i;
 
 	/*
@@ -131,11 +133,11 @@ inet_ntop6(src, dst, size)
 	 *	Find the longest run of 0x00's in src[] for :: shorthanding.
 	 */
 	memset(words, '\0', sizeof words);
-	for (i = 0; i < IN6ADDRSZ; i += 2)
+	for (i = 0; i < NS_IN6ADDRSZ; i += 2)
 		words[i / 2] = (src[i] << 8) | src[i + 1];
 	best.base = -1;
 	cur.base = -1;
-	for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) {
+	for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) {
 		if (words[i] == 0) {
 			if (cur.base == -1)
 				cur.base = i, cur.len = 1;
@@ -160,7 +162,7 @@ inet_ntop6(src, dst, size)
 	 * Format the result.
 	 */
 	tp = tmp;
-	for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) {
+	for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) {
 		/* Are we inside the best run of 0x00's? */
 		if (best.base != -1 && i >= best.base &&
 		    i < (best.base + best.len)) {
@@ -182,7 +184,8 @@ inet_ntop6(src, dst, size)
 		tp += SPRINTF((tp, "%x", words[i]));
 	}
 	/* Was it a trailing run of 0x00's? */
-	if (best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ))
+	if (best.base != -1 && (best.base + best.len) == 
+	    (NS_IN6ADDRSZ / NS_INT16SZ))
 		*tp++ = ':';
 	*tp++ = '\0';
 
diff --git a/resolv/inet_pton.c b/resolv/inet_pton.c
index 4dcbad95c4..264278be0d 100644
--- a/resolv/inet_pton.c
+++ b/resolv/inet_pton.c
@@ -1,4 +1,5 @@
-/* Copyright (c) 1996 by Internet Software Consortium.
+/*
+ * Copyright (c) 1996,1999 by Internet Software Consortium.
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -15,7 +16,7 @@
  */
 
 #if defined(LIBC_SCCS) && !defined(lint)
-static char rcsid[] = "$Id$";
+static const char rcsid[] = "$BINDId: inet_pton.c,v 1.7 1999/10/13 16:39:28 vixie Exp $";
 #endif /* LIBC_SCCS and not lint */
 
 #include <sys/param.h>
@@ -27,7 +28,6 @@ static char rcsid[] = "$Id$";
 #include <ctype.h>
 #include <string.h>
 #include <errno.h>
-#include <conf/portability.h>
 
 /*
  * WARNING: Don't even consider trying to compile this on a system where
@@ -83,7 +83,7 @@ inet_pton4(src, dst)
 	u_char *dst;
 {
 	int saw_digit, octets, ch;
-	u_char tmp[INADDRSZ], *tp;
+	u_char tmp[NS_INADDRSZ], *tp;
 
 	saw_digit = 0;
 	octets = 0;
@@ -111,8 +111,7 @@ inet_pton4(src, dst)
 	}
 	if (octets < 4)
 		return (0);
-
-	memcpy(dst, tmp, INADDRSZ);
+	memcpy(dst, tmp, NS_INADDRSZ);
 	return (1);
 }
 
@@ -136,13 +135,13 @@ inet_pton6(src, dst)
 	u_char *dst;
 {
 	static const char xdigits[] = "0123456789abcdef";
-	u_char tmp[IN6ADDRSZ], *tp, *endp, *colonp;
+	u_char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp;
 	const char *curtok;
 	int ch, saw_xdigit;
 	u_int val;
 
-	tp = memset(tmp, '\0', IN6ADDRSZ);
-	endp = tp + IN6ADDRSZ;
+	tp = memset(tmp, '\0', NS_IN6ADDRSZ);
+	endp = tp + NS_IN6ADDRSZ;
 	colonp = NULL;
 	/* Leading :: requires some special handling. */
 	if (*src == ':')
@@ -170,8 +169,10 @@ inet_pton6(src, dst)
 					return (0);
 				colonp = tp;
 				continue;
+			} else if (*src == '\0') {
+				return (0);
 			}
-			if (tp + INT16SZ > endp)
+			if (tp + NS_INT16SZ > endp)
 				return (0);
 			*tp++ = (u_char) (val >> 8) & 0xff;
 			*tp++ = (u_char) val & 0xff;
@@ -179,16 +180,16 @@ inet_pton6(src, dst)
 			val = 0;
 			continue;
 		}
-		if (ch == '.' && ((tp + INADDRSZ) <= endp) &&
+		if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) &&
 		    inet_pton4(curtok, tp) > 0) {
-			tp += INADDRSZ;
+			tp += NS_INADDRSZ;
 			saw_xdigit = 0;
 			break;	/* '\0' was seen by inet_pton4(). */
 		}
 		return (0);
 	}
 	if (saw_xdigit) {
-		if (tp + INT16SZ > endp)
+		if (tp + NS_INT16SZ > endp)
 			return (0);
 		*tp++ = (u_char) (val >> 8) & 0xff;
 		*tp++ = (u_char) val & 0xff;
@@ -201,6 +202,8 @@ inet_pton6(src, dst)
 		const int n = tp - colonp;
 		int i;
 
+		if (tp == endp)
+			return (0);
 		for (i = 1; i <= n; i++) {
 			endp[- i] = colonp[n - i];
 			colonp[n - i] = 0;
@@ -209,6 +212,6 @@ inet_pton6(src, dst)
 	}
 	if (tp != endp)
 		return (0);
-	memcpy(dst, tmp, IN6ADDRSZ);
+	memcpy(dst, tmp, NS_IN6ADDRSZ);
 	return (1);
 }
diff --git a/resolv/ns_name.c b/resolv/ns_name.c
index b75f731c44..cb6393527f 100644
--- a/resolv/ns_name.c
+++ b/resolv/ns_name.c
@@ -15,8 +15,8 @@
  * SOFTWARE.
  */
 
-#ifndef lint
-static const char rcsid[] = "$Id$";
+#if !defined(_LIBC) && !defined(lint)
+static const char rcsid[] = "$BINDId: ns_name.c,v 8.15 2000/03/30 22:53:46 vixie Exp $";
 #endif
 
 #include <sys/types.h>
@@ -375,7 +375,7 @@ ns_name_pack(const u_char *src, u_char *dst, int dstsiz,
 	u_char *dstp;
 	const u_char **cpp, **lpp, *eob, *msg;
 	const u_char *srcp;
-	int n, l;
+	int n, l, first = 1;
 
 	srcp = src;
 	dstp = dst;
@@ -424,9 +424,10 @@ ns_name_pack(const u_char *src, u_char *dst, int dstsiz,
 			}
 			/* Not found, save it. */
 			if (lastdnptr != NULL && cpp < lastdnptr - 1 &&
-			    (dstp - msg) < 0x4000) {
+			    (dstp - msg) < 0x4000 && first) {
 				*cpp++ = dstp;
 				*cpp = NULL;
+				first = 0;
 			}
 		}
 		/* copy label to buffer */
@@ -499,6 +500,23 @@ ns_name_compress(const char *src, u_char *dst, size_t dstsiz,
 }
 
 /*
+ * Reset dnptrs so that there are no active references to pointers at or
+ * after src.
+ */
+void
+ns_name_rollback(const u_char *src, const u_char **dnptrs,
+		 const u_char **lastdnptr)
+{
+	while (dnptrs < lastdnptr && *dnptrs != NULL) {
+		if (*dnptrs >= src) {
+			*dnptrs = NULL;
+			break;
+		}
+		dnptrs++;
+	}
+}
+
+/*
  * ns_name_skip(ptrptr, eom)
  *	Advance *ptrptr to skip over the compressed name it points at.
  * return:
@@ -600,36 +618,48 @@ dn_find(const u_char *domain, const u_char *msg,
 	u_int n;
 
 	for (cpp = dnptrs; cpp < lastdnptr; cpp++) {
-		dn = domain;
-		sp = cp = *cpp;
-		while ((n = *cp++) != 0) {
-			/*
-			 * check for indirection
-			 */
-			switch (n & NS_CMPRSFLGS) {
-			case 0:			/* normal case, n == len */
-				if (n != *dn++)
-					goto next;
-				for ((void)NULL; n > 0; n--)
-					if (mklower(*dn++) != mklower(*cp++))
+		sp = *cpp;
+		/*
+		 * terminate search on:
+		 * root label
+		 * compression pointer
+		 * unusable offset
+		 */
+		while (*sp != 0 && (*sp & NS_CMPRSFLGS) == 0 &&
+		       (sp - msg) < 0x4000) {
+			dn = domain;
+			cp = sp;
+			while ((n = *cp++) != 0) {
+				/*
+				 * check for indirection
+				 */
+				switch (n & NS_CMPRSFLGS) {
+				case 0:		/* normal case, n == len */
+					if (n != *dn++)
 						goto next;
-				/* Is next root for both ? */
-				if (*dn == '\0' && *cp == '\0')
-					return (sp - msg);
-				if (*dn)
-					continue;
-				goto next;
-
-			case NS_CMPRSFLGS:	/* indirection */
-				cp = msg + (((n & 0x3f) << 8) | *cp);
-				break;
-
-			default:	/* illegal type */
-				__set_errno (EMSGSIZE);
-				return (-1);
+					for ((void)NULL; n > 0; n--)
+						if (mklower(*dn++) !=
+						    mklower(*cp++))
+							goto next;
+					/* Is next root for both ? */
+					if (*dn == '\0' && *cp == '\0')
+						return (sp - msg);
+					if (*dn)
+						continue;
+					goto next;
+
+				case NS_CMPRSFLGS:	/* indirection */
+					cp = msg + (((n & 0x3f) << 8) | *cp);
+					break;
+
+				default:	/* illegal type */
+					__set_errno (EMSGSIZE);
+					return (-1);
+				}
 			}
+ next:
+			sp += *sp + 1;
 		}
- next: ;
 	}
 	__set_errno (ENOENT);
 	return (-1);
diff --git a/resolv/ns_netint.c b/resolv/ns_netint.c
index 9dcf91cf50..ff24128cd6 100644
--- a/resolv/ns_netint.c
+++ b/resolv/ns_netint.c
@@ -15,8 +15,8 @@
  * SOFTWARE.
  */
 
-#ifndef lint
-static const char rcsid[] = "$Id$";
+#if !defined(_LIBC) && !defined(lint)
+static const char rcsid[] = "$BINDId: ns_netint.c,v 8.4 1999/10/13 16:39:35 vixie Exp $";
 #endif
 
 /* Import. */
diff --git a/resolv/ns_parse.c b/resolv/ns_parse.c
index 7bbdc41cdf..d305eae535 100644
--- a/resolv/ns_parse.c
+++ b/resolv/ns_parse.c
@@ -15,8 +15,8 @@
  * SOFTWARE.
  */
 
-#ifndef lint
-static const char rcsid[] = "$Id$";
+#if !defined(_LIBC) && !defined(lint)
+static const char rcsid[] = "$BINDId: ns_parse.c,v 8.13 1999/10/13 16:39:35 vixie Exp $";
 #endif
 
 /* Import. */
diff --git a/resolv/ns_print.c b/resolv/ns_print.c
index cce3fb611d..7a2ef70efc 100644
--- a/resolv/ns_print.c
+++ b/resolv/ns_print.c
@@ -15,11 +15,12 @@
  * SOFTWARE.
  */
 
-#ifndef lint
-static const char rcsid[] = "$Id$";
+#if !defined(_LIBC) && !defined(lint)
+static const char rcsid[] = "$BINDId: ns_print.c,v 8.18 2000/02/29 05:48:12 vixie Exp $";
 #endif
 
 /* Import. */
+
 #include <sys/types.h>
 #include <sys/socket.h>
 
@@ -27,6 +28,7 @@ static const char rcsid[] = "$Id$";
 #include <arpa/nameser.h>
 #include <arpa/inet.h>
 
+#include <assert.h>
 #include <errno.h>
 #include <resolv.h>
 #include <string.h>
@@ -53,6 +55,7 @@ static int	addtab(size_t len, size_t target, int spaced,
 		       char **buf, size_t *buflen);
 
 /* Proto. */
+
 #ifndef _LIBC
 u_int16_t       dst_s_dns_key_id(const u_char *, const int);
 #endif
@@ -122,9 +125,10 @@ ns_sprintrrf(const u_char *msg, size_t msglen,
 			T(addstr("@\t\t\t", 4, &buf, &buflen));
 		} else {
 			T(addstr(name, len, &buf, &buflen));
-			/* Origin not used and no trailing dot? */
-			if ((!origin || !origin[0] || name[len] == '\0') &&
-			    name[len - 1] != '.') {
+			/* Origin not used or not root, and no trailing dot? */
+			if (((origin == NULL || origin[0] == '\0') ||
+			    (origin[0] != '.' && origin[1] != '\0' &&
+			    name[len] == '\0')) && name[len - 1] != '.') {
 				T(addstr(".", 1, &buf, &buflen));
 				len++;
 			}
@@ -480,6 +484,7 @@ ns_sprintrrf(const u_char *msg, size_t msglen,
 		n = SPRINTF((tmp, " ; key_tag= %u", key_id));
 		T(addstr(tmp, n, &buf, &buflen));
 #endif /* !_LIBC */
+
 		break;
 	    }
 
@@ -749,20 +754,22 @@ addname(const u_char *msg, size_t msglen,
 	if (n < 0)
 		goto enospc;	/* Guess. */
 	newlen = prune_origin(*buf, origin);
-	if ((origin == NULL || origin[0] == '\0' || (*buf)[newlen] == '\0') &&
-	    (newlen == 0 || (*buf)[newlen - 1] != '.')) {
-		/* No trailing dot. */
-		if (newlen + 2 > *buflen)
-			goto enospc;	/* No room for ".\0". */
-		(*buf)[newlen++] = '.';
-		(*buf)[newlen] = '\0';
-	}
 	if (newlen == 0) {
 		/* Use "@" instead of name. */
 		if (newlen + 2 > *buflen)
 			goto enospc;        /* No room for "@\0". */
 		(*buf)[newlen++] = '@';
 		(*buf)[newlen] = '\0';
+	} else {
+		if (((origin == NULL || origin[0] == '\0') ||
+		    (origin[0] != '.' && origin[1] != '\0' &&
+		    (*buf)[newlen] == '\0')) && (*buf)[newlen - 1] != '.') {
+			/* No trailing dot. */
+			if (newlen + 2 > *buflen)
+				goto enospc;	/* No room for ".\0". */
+			(*buf)[newlen++] = '.';
+			(*buf)[newlen] = '\0';
+		}
 	}
 	*pp += n;
 	addlen(newlen, buf, buflen);
@@ -777,9 +784,7 @@ addname(const u_char *msg, size_t msglen,
 
 static void
 addlen(size_t len, char **buf, size_t *buflen) {
-#if 0
-	INSIST(len <= *buflen);
-#endif
+	assert(len <= *buflen);
 	*buf += len;
 	*buflen -= len;
 }
diff --git a/resolv/ns_samedomain.c b/resolv/ns_samedomain.c
index bac5a639e7..1fb1c552d0 100644
--- a/resolv/ns_samedomain.c
+++ b/resolv/ns_samedomain.c
@@ -15,8 +15,8 @@
  * SOFTWARE.
  */
 
-#ifndef lint
-static const char rcsid[] = "$Id$";
+#if !defined(_LIBC) && !defined(lint)
+static const char rcsid[] = "$BINDId: ns_samedomain.c,v 8.9 1999/10/15 21:06:51 vixie Exp $";
 #endif
 
 #include <sys/types.h>
diff --git a/resolv/ns_ttl.c b/resolv/ns_ttl.c
index 6be2b0d7a7..c5d5af2f10 100644
--- a/resolv/ns_ttl.c
+++ b/resolv/ns_ttl.c
@@ -15,11 +15,12 @@
  * SOFTWARE.
  */
 
-#ifndef lint
-static const char rcsid[] = "$Id$";
+#if !defined(_LIBC) && !defined(lint)
+static const char rcsid[] = "$BINDId: ns_ttl.c,v 8.8 1999/10/13 16:39:36 vixie Exp $";
 #endif
 
 /* Import. */
+
 #include <arpa/nameser.h>
 
 #include <ctype.h>
diff --git a/resolv/nsap_addr.c b/resolv/nsap_addr.c
index c1c9a61d35..b3f2f77caf 100644
--- a/resolv/nsap_addr.c
+++ b/resolv/nsap_addr.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996 by Internet Software Consortium.
+ * Copyright (c) 1996-1999 by Internet Software Consortium.
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -16,15 +16,17 @@
  */
 
 #if defined(LIBC_SCCS) && !defined(lint)
-static char rcsid[] = "$Id$";
+static const char rcsid[] = "$BINDId: nsap_addr.c,v 8.10 1999/10/13 16:39:28 vixie Exp $";
 #endif /* LIBC_SCCS and not lint */
 
 #include <sys/types.h>
 #include <sys/param.h>
 #include <sys/socket.h>
+
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <arpa/nameser.h>
+
 #include <ctype.h>
 #include <resolv.h>
 
@@ -38,7 +40,7 @@ inet_nsap_addr(const char *ascii, u_char *binary, int maxlen) {
 	u_char c, nib;
 	u_int len = 0;
 
-	while ((c = *ascii++) != '\0' && (int) len < maxlen) {
+	while ((c = *ascii++) != '\0' && len < (u_int)maxlen) {
 		if (c == '.' || c == '+' || c == '/')
 			continue;
 		if (!isascii(c))
diff --git a/resolv/res_comp.c b/resolv/res_comp.c
index e6f54ce06a..f227c4d163 100644
--- a/resolv/res_comp.c
+++ b/resolv/res_comp.c
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 1985, 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:
@@ -13,7 +13,7 @@
  * 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
@@ -25,16 +25,18 @@
  * 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.
- * -
+ */
+
+/*
  * Portions Copyright (c) 1993 by Digital Equipment Corporation.
- *
+ * 
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
  * copyright notice and this permission notice appear in all copies, and that
  * the name of Digital Equipment Corporation not be used in advertising or
  * publicity pertaining to distribution of the document or software without
  * specific, written prior permission.
- *
+ * 
  * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
  * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
  * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
@@ -64,23 +66,19 @@
 
 #if defined(LIBC_SCCS) && !defined(lint)
 static const char sccsid[] = "@(#)res_comp.c	8.1 (Berkeley) 6/4/93";
-static const char rcsid[] = "$Id$";
+static const char rcsid[] = "$BINDId: res_comp.c,v 8.15 1999/10/13 16:39:39 vixie Exp $";
 #endif /* LIBC_SCCS and not lint */
 
 #include <sys/types.h>
 #include <sys/param.h>
 #include <netinet/in.h>
 #include <arpa/nameser.h>
-
 #include <ctype.h>
-#include <errno.h>
 #include <resolv.h>
 #include <stdio.h>
-
 #include <string.h>
 #include <unistd.h>
 
-
 /*
  * Expand compressed domain name 'comp_dn' to full domain name.
  * 'msg' is a pointer to the begining of the message,
@@ -157,7 +155,7 @@ res_hnok(const char *dn) {
 		int nch = *dn++;
 
 		if (periodchar(ch)) {
-			/* NULL */;
+			(void)NULL;
 		} else if (periodchar(pch)) {
 			if (!borderchar(ch))
 				return (0);
@@ -198,7 +196,7 @@ res_mailok(const char *dn) {
 
 	/* "." is a valid missing representation */
 	if (*dn == '\0')
-		return(1);
+		return (1);
 
 	/* otherwise <label>.<hostname> */
 	while ((ch = *dn++) != '\0') {
@@ -246,3 +244,11 @@ u_int32_t _getlong(const u_char *src) { return (ns_get32(src)); }
 u_int16_t _getshort(const u_char *src) { return (ns_get16(src)); }
 #endif /*__ultrix__*/
 #endif /*BIND_4_COMPAT*/
+
+
+#include <shlib-compat.h>
+
+#if SHLIB_COMPAT(libresolv, GLIBC_2_0, GLIBC_2_2)
+# undef dn_expand
+weak_alias (__dn_expand, dn_expand);
+#endif
diff --git a/resolv/res_data.c b/resolv/res_data.c
index a9f5a2ad67..c8aa5c52b9 100644
--- a/resolv/res_data.c
+++ b/resolv/res_data.c
@@ -16,7 +16,7 @@
  */
 
 #if defined(LIBC_SCCS) && !defined(lint)
-static const char rcsid[] = "$Id$";
+static const char rcsid[] = "$BINDId: res_data.c,v 8.17 1999/10/13 17:11:31 vixie Exp $";
 #endif /* LIBC_SCCS and not lint */
 
 #include <sys/types.h>
@@ -31,6 +31,9 @@ static const char rcsid[] = "$Id$";
 #include <ctype.h>
 #include <netdb.h>
 #include <resolv.h>
+#ifdef BIND_UPDATE
+#include <res_update.h>
+#endif
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -67,11 +70,10 @@ const char *_res_sectioncodes[] = {
 #endif
 
 #ifndef __BIND_NOSTATIC
-
 #ifdef _LIBC
 extern struct __res_state _res;
 #else
-/* The declaration has been moved to res_libc.c.  */
+/* The definition has been moved to res_libc.c.  */
 struct __res_state _res
 # if defined(__BIND_RES_TEXT)
 	= { RES_TIMEOUT, }	/* Motorola, et al. */
@@ -85,7 +87,7 @@ int  res_ourserver_p(const res_state, const struct sockaddr_in *);
 void res_pquery(const res_state, const u_char *, int, FILE *);
 
 #ifndef _LIBC
-/* Moved to res_libc.c since res_init should go into libc.so but the
+/* Moved to res_libc.c since res_init() should go into libc.so but the
    rest of this file not.  */
 int
 res_init(void) {
@@ -231,6 +233,17 @@ res_sendsigned(const u_char *buf, int buflen, ns_tsig_key *key,
 
 void
 res_close(void) {
+#ifdef _LIBC
+  	/*
+	 * Some stupid programs out there call res_close() before res_init().
+	 * Since _res._vcsock isn't explicitly initialized, these means that
+	 * we could do a close(0), which might lead to some security problems.
+	 * Therefore we check if res_init() was called before by looking at
+	 * the RES_INIT bit in _res.options.  If it hasn't been set we bail out
+	 * early.  */
+	if ((_res.options & RES_INIT) == 0)
+	  return;
+#endif
 	res_nclose(&_res);
 }
 
@@ -302,3 +315,17 @@ local_hostname_length(const char *hostname) {
 #endif /*ultrix*/
 
 #endif
+
+
+#include <shlib-compat.h>
+
+#if SHLIB_COMPAT(libresolv, GLIBC_2_0, GLIBC_2_2)
+# undef res_mkquery
+# undef res_query
+# undef res_querydomain
+# undef res_search
+weak_alias (__res_mkquery, res_mkquery);
+weak_alias (__res_query, res_query);
+weak_alias (__res_querydomain, res_querydomain);
+weak_alias (__res_search, res_search);
+#endif
diff --git a/resolv/res_debug.c b/resolv/res_debug.c
index 2df1c5bbdc..f4e9169cba 100644
--- a/resolv/res_debug.c
+++ b/resolv/res_debug.c
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 1985
  *    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:
@@ -13,7 +13,7 @@
  * 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
@@ -29,14 +29,14 @@
 
 /*
  * Portions Copyright (c) 1993 by Digital Equipment Corporation.
- *
+ * 
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
  * copyright notice and this permission notice appear in all copies, and that
  * the name of Digital Equipment Corporation not be used in advertising or
  * publicity pertaining to distribution of the document or software without
  * specific, written prior permission.
- *
+ * 
  * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
  * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
  * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
@@ -91,7 +91,7 @@
 
 #if defined(LIBC_SCCS) && !defined(lint)
 static const char sccsid[] = "@(#)res_debug.c	8.1 (Berkeley) 6/4/93";
-static const char rcsid[] = "$Id$";
+static const char rcsid[] = "$BINDId: res_debug.c,v 8.34 2000/02/29 05:30:55 vixie Exp $";
 #endif /* LIBC_SCCS and not lint */
 
 #include <sys/types.h>
@@ -141,7 +141,8 @@ do_section(const res_state statp,
 	   int pflag, FILE *file)
 {
 	int n, sflag, rrnum;
-	char buf[2048];	/* XXX need to malloc */
+	static int buflen = 2048;
+	char *buf;
 	ns_opcode opcode;
 	ns_rr rr;
 
@@ -152,6 +153,12 @@ do_section(const res_state statp,
 	if (statp->pfcode && !sflag)
 		return;
 
+	buf = malloc(buflen);
+	if (buf == NULL) {
+		fprintf(file, ";; memory allocation failure\n");
+		return;
+	}
+
 	opcode = (ns_opcode) ns_msg_getflag(*handle, ns_f_opcode);
 	rrnum = 0;
 	for (;;) {
@@ -162,7 +169,7 @@ do_section(const res_state statp,
 			else if (rrnum > 0 && sflag != 0 &&
 				 (statp->pfcode & RES_PRF_HEAD1))
 				putc('\n', file);
-			return;
+			goto cleanup;
 		}
 		if (rrnum == 0 && sflag != 0 && (statp->pfcode & RES_PRF_HEAD1))
 			fprintf(file, ";; %s SECTION:\n",
@@ -174,17 +181,32 @@ do_section(const res_state statp,
 				p_class(ns_rr_class(rr)));
 		else {
 			n = ns_sprintrr(handle, &rr, NULL, NULL,
-					buf, sizeof buf);
+					buf, buflen);
 			if (n < 0) {
+				if (errno == ENOSPC) {
+					free(buf);
+					buf = NULL;
+					if (buflen < 131072)
+						buf = malloc(buflen += 1024);
+					if (buf == NULL) {
+						fprintf(file,
+				              ";; memory allocation failure\n");
+					      return;
+					}
+					continue;
+				}
 				fprintf(file, ";; ns_sprintrr: %s\n",
 					strerror(errno));
-				return;
+				goto cleanup;
 			}
 			fputs(buf, file);
 			fputc('\n', file);
 		}
 		rrnum++;
 	}
+ cleanup:
+	if (buf != NULL)
+		free(buf);
 }
 
 /*
@@ -465,13 +487,8 @@ const char *
 sym_ntos(const struct res_sym *syms, int number, int *success) {
 	static char unname[20];
 
-#ifdef _LIBC
-	/* Changed to prevent warning. --drepper@gnu  */
-	for (; syms->name != 0; syms++) {
-#else
 	for ((void)NULL; syms->name != 0; syms++) {
-#endif
-	  if (number == syms->number) {
+		if (number == syms->number) {
 			if (success)
 				*success = 1;
 			return (syms->name);
@@ -488,12 +505,7 @@ const char *
 sym_ntop(const struct res_sym *syms, int number, int *success) {
 	static char unname[20];
 
-#ifdef _LIBC
-	/* Changed to prevent warning. --drepper@gnu  */
-	for (; syms->name != 0; syms++) {
-#else
 	for ((void)NULL; syms->name != 0; syms++) {
-#endif
 		if (number == syms->number) {
 			if (success)
 				*success = 1;
@@ -1012,7 +1024,7 @@ p_secstodate (u_long secs) {
 	struct tm *time;
 	
 #ifdef HAVE_TIME_R
-	struct time timebuf;
+	struct tm timebuf;
 	
 	time = gmtime_r(&clock, &timebuf);
 #else
diff --git a/resolv/res_init.c b/resolv/res_init.c
index bf6cf7f7b1..c483645ed7 100644
--- a/resolv/res_init.c
+++ b/resolv/res_init.c
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 1985, 1989, 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:
@@ -13,7 +13,7 @@
  * 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
@@ -29,14 +29,14 @@
 
 /*
  * Portions Copyright (c) 1993 by Digital Equipment Corporation.
- *
+ * 
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
  * copyright notice and this permission notice appear in all copies, and that
  * the name of Digital Equipment Corporation not be used in advertising or
  * publicity pertaining to distribution of the document or software without
  * specific, written prior permission.
- *
+ * 
  * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
  * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
  * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
@@ -66,7 +66,7 @@
 
 #if defined(LIBC_SCCS) && !defined(lint)
 static const char sccsid[] = "@(#)res_init.c	8.1 (Berkeley) 6/7/93";
-static const char rcsid[] = "$Id$";
+static const char rcsid[] = "$BINDId: res_init.c,v 8.16 2000/05/09 07:10:12 vixie Exp $";
 #endif /* LIBC_SCCS and not lint */
 
 #include <sys/types.h>
@@ -88,13 +88,11 @@ static const char rcsid[] = "$Id$";
 /* Options.  Should all be left alone. */
 #define RESOLVSORT
 #define RFC1535
-#undef DEBUG
+/* #undef DEBUG */
 
-static void
-res_setoptions (res_state statp, const char *options, const char *source)
+static void res_setoptions (res_state, const char *, const char *)
      internal_function;
 
-
 #ifdef RESOLVSORT
 static const char sort_mask[] = "/&";
 #define ISSORTMASK(ch) (strchr(sort_mask, ch) != NULL)
@@ -172,10 +170,11 @@ __res_vinit(res_state statp, int preinit) {
 	statp->nscount = 1;
 	statp->ndots = 1;
 	statp->pfcode = 0;
-	statp->_sock = -1;
+	statp->_vcsock = -1;
 	statp->_flags = 0;
 	statp->qhook = NULL;
 	statp->rhook = NULL;
+	statp->_u._ext.nscount = 0;
 
 	/* Allow user to override the local domain definition */
 	if ((cp = __secure_getenv("LOCALDOMAIN")) != NULL) {
@@ -391,8 +390,7 @@ __res_vinit(res_state statp, int preinit) {
 
 static void
 internal_function
-res_setoptions(res_state statp, const char *options, const char *source)
-{
+res_setoptions(res_state statp, const char *options, const char *source) {
 	const char *cp = options;
 	int i;
 
@@ -476,3 +474,28 @@ res_randomid(void) {
 	__gettimeofday(&now, NULL);
 	return (0xffff & (now.tv_sec ^ now.tv_usec ^ __getpid()));
 }
+
+/*
+ * This routine is for closing the socket if a virtual circuit is used and
+ * the program wants to close it.  This provides support for endhostent()
+ * which expects to close the socket.
+ *
+ * This routine is not expected to be user visible.
+ */
+void
+res_nclose(res_state statp) {
+	int ns;
+
+	if (statp->_vcsock >= 0) { 
+		(void) close(statp->_vcsock);
+		statp->_vcsock = -1;
+		statp->_flags &= ~(RES_F_VC | RES_F_CONN);
+	}
+	for (ns = 0; ns < statp->_u._ext.nscount; ns++) {
+		if (statp->_u._ext.nssocks[ns] != -1) {
+			(void) close(statp->_u._ext.nssocks[ns]);
+			statp->_u._ext.nssocks[ns] = -1;
+		}
+	}
+	statp->_u._ext.nscount = 0;
+}
diff --git a/resolv/res_libc.c b/resolv/res_libc.c
index fc5cc691ba..fde5f5c151 100644
--- a/resolv/res_libc.c
+++ b/resolv/res_libc.c
@@ -15,34 +15,29 @@
  * SOFTWARE.
  */
 
-/* Define some functions that go int libc.so.  */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static const char rcsid[] = "$Id$";
-#endif /* LIBC_SCCS and not lint */
-
 #include <sys/types.h>
-#include <sys/param.h>
-#include <sys/socket.h>
-#include <sys/time.h>
-
 #include <netinet/in.h>
-#include <arpa/inet.h>
 #include <arpa/nameser.h>
-
-#include <ctype.h>
-#include <netdb.h>
 #include <resolv.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
 
+#undef _res
+
+/* The resolver state for use by single-threaded programs.  */
+struct __res_state _res;
 
-/* This is the old res_init function.  It has been moved from
-   res_data.c to this file since res_init should go into libc.so but
-   the rest of res_data not.  */
+/* This function is used to access the resolver state in
+   single-threaded programs.  */
+struct __res_state *
+weak_const_function
+__res_state (void)
+{
+  return &_res;
+}
+
 
+/* The following bit is copied from res_data.c (where it is #ifdef'ed
+   out) since res_init() should go into libc.so but the rest of that
+   file should not.  */
 
 int
 res_init(void) {
@@ -83,18 +78,11 @@ res_init(void) {
 
 	return (__res_vinit(&_res, 1));
 }
+
 
-/* We need a resolver context - in unthreaded apps, this weak function
-   provides it.  */
-
-#undef _res
-
-struct __res_state _res = { _sock : -1 };
-
+#include <shlib-compat.h>
 
-struct __res_state *
-weak_const_function
-__res_state(void)
-{
-  return &_res;
-}
+#if SHLIB_COMPAT(libc, GLIBC_2_0, GLIBC_2_2)
+# undef res_init
+weak_alias (__res_init, res_init);
+#endif
diff --git a/resolv/res_mkquery.c b/resolv/res_mkquery.c
index dba2c80e26..05b94bd79e 100644
--- a/resolv/res_mkquery.c
+++ b/resolv/res_mkquery.c
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 1985, 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:
@@ -13,7 +13,7 @@
  * 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
@@ -29,14 +29,14 @@
 
 /*
  * Portions Copyright (c) 1993 by Digital Equipment Corporation.
- *
+ * 
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
  * copyright notice and this permission notice appear in all copies, and that
  * the name of Digital Equipment Corporation not be used in advertising or
  * publicity pertaining to distribution of the document or software without
  * specific, written prior permission.
- *
+ * 
  * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
  * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
  * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
@@ -66,7 +66,7 @@
 
 #if defined(LIBC_SCCS) && !defined(lint)
 static const char sccsid[] = "@(#)res_mkquery.c	8.1 (Berkeley) 6/4/93";
-static const char rcsid[] = "$Id$";
+static const char rcsid[] = "$BINDId: res_mkquery.c,v 8.12 1999/10/13 16:39:40 vixie Exp $";
 #endif /* LIBC_SCCS and not lint */
 
 #include <sys/types.h>
diff --git a/resolv/res_query.c b/resolv/res_query.c
index deebf4c62b..00a5e3eec3 100644
--- a/resolv/res_query.c
+++ b/resolv/res_query.c
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 1988, 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:
@@ -13,7 +13,7 @@
  * 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
@@ -29,14 +29,14 @@
 
 /*
  * Portions Copyright (c) 1993 by Digital Equipment Corporation.
- *
+ * 
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
  * copyright notice and this permission notice appear in all copies, and that
  * the name of Digital Equipment Corporation not be used in advertising or
  * publicity pertaining to distribution of the document or software without
  * specific, written prior permission.
- *
+ * 
  * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
  * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
  * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
@@ -66,7 +66,7 @@
 
 #if defined(LIBC_SCCS) && !defined(lint)
 static const char sccsid[] = "@(#)res_query.c	8.1 (Berkeley) 6/4/93";
-static const char rcsid[] = "$Id$";
+static const char rcsid[] = "$BINDId: res_query.c,v 8.20 2000/02/29 05:39:12 vixie Exp $";
 #endif /* LIBC_SCCS and not lint */
 
 #include <sys/types.h>
@@ -184,8 +184,9 @@ res_nsearch(res_state statp,
 	HEADER *hp = (HEADER *) answer;
 	char tmp[NS_MAXDNAME];
 	u_int dots;
-	int trailing_dot, ret;
+	int trailing_dot, ret, saved_herrno;
 	int got_nodata = 0, got_servfail = 0, root_on_list = 0;
+	int tried_as_is = 0;
 
 	__set_errno (0);
 	RES_SET_H_ERRNO(statp, HOST_NOT_FOUND);  /* True if we never query. */
@@ -202,12 +203,19 @@ res_nsearch(res_state statp,
 		return (res_nquery(statp, cp, class, type, answer, anslen));
 
 	/*
-	 * If there are enough dots in the name, do no searching.
-	 * (The threshold can be set with the "ndots" option.)
+	 * If there are enough dots in the name, let's just give it a
+	 * try 'as is'. The threshold can be set with the "ndots" option.
+	 * Also, query 'as is', if there is a trailing dot in the name.
 	 */
-	if (dots >= statp->ndots || trailing_dot)
-		return (res_nquerydomain(statp, name, NULL, class, type,
-					 answer, anslen));
+	saved_herrno = -1;
+	if (dots >= statp->ndots || trailing_dot) {
+		ret = res_nquerydomain(statp, name, NULL, class, type,
+					 answer, anslen);
+		if (ret > 0 || trailing_dot)
+			return (ret);
+		saved_herrno = h_errno;
+		tried_as_is++;
+	}
 
 	/*
 	 * We do at least one level of search if
@@ -279,10 +287,11 @@ res_nsearch(res_state statp,
 	}
 
 	/*
-	 * If the name has any dots at all, and "." is not on the search
-	 * list, then try an as-is query now.
+	 * If the name has any dots at all, and no earlier 'as-is' query 
+	 * for the name, and "." is not on the search list, then try an as-is
+	 * query now.
 	 */
-	if (statp->ndots) {
+	if (statp->ndots && !(tried_as_is || root_on_list)) {
 		ret = res_nquerydomain(statp, name, NULL, class, type,
 				       answer, anslen);
 		if (ret > 0)
@@ -296,7 +305,9 @@ res_nsearch(res_state statp,
 	 * else send back meaningless H_ERRNO, that being the one from
 	 * the last DNSRCH we did.
 	 */
-	if (got_nodata)
+	if (saved_herrno != -1)
+		RES_SET_H_ERRNO(statp, saved_herrno);
+	else if (got_nodata)
 		RES_SET_H_ERRNO(statp, NO_DATA);
 	else if (got_servfail)
 		RES_SET_H_ERRNO(statp, TRY_AGAIN);
diff --git a/resolv/res_send.c b/resolv/res_send.c
index d3dc2ba8e1..bf500b1df7 100644
--- a/resolv/res_send.c
+++ b/resolv/res_send.c
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 1985, 1989, 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:
@@ -13,7 +13,7 @@
  * 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
@@ -29,14 +29,14 @@
 
 /*
  * Portions Copyright (c) 1993 by Digital Equipment Corporation.
- *
+ * 
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
  * copyright notice and this permission notice appear in all copies, and that
  * the name of Digital Equipment Corporation not be used in advertising or
  * publicity pertaining to distribution of the document or software without
  * specific, written prior permission.
- *
+ * 
  * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
  * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
  * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
@@ -66,7 +66,7 @@
 
 #if defined(LIBC_SCCS) && !defined(lint)
 static const char sccsid[] = "@(#)res_send.c	8.1 (Berkeley) 6/4/93";
-static const char rcsid[] = "$Id$";
+static const char rcsid[] = "$BINDId: res_send.c,v 8.38 2000/03/30 20:16:51 vixie Exp $";
 #endif /* LIBC_SCCS and not lint */
 
 /*
@@ -78,6 +78,9 @@ static const char rcsid[] = "$Id$";
 #include <sys/time.h>
 #include <sys/socket.h>
 #include <sys/uio.h>
+#ifdef _LIBC
+#include <sys/poll.h>
+#endif
 
 #include <netinet/in.h>
 #include <arpa/nameser.h>
@@ -92,32 +95,36 @@ static const char rcsid[] = "$Id$";
 #include <string.h>
 #include <unistd.h>
 
-#include <sys/poll.h>
+#ifndef _LIBC
+#include <isc/eventlib.h>
+#else
 
-/* Options.  Leave them on. */
-/* #undef DEBUG */
-#include "res_debug.h"
+/* From ev_streams.c.  */
+   
+static inline struct iovec
+evConsIovec(void *buf, size_t cnt) {
+	struct iovec ret;
 
-#ifdef NEED_PSELECT
-static int		pselect(int, void *, void *, void *,
-				struct timespec *,
-				const sigset_t *);
-#endif
+	memset(&ret, 0xf5, sizeof ret);
+	ret.iov_base = buf;
+	ret.iov_len = cnt;
+	return (ret);
+}
 
-#define	CHECK_SRVR_ADDR
+/* From ev_timers.c.  */
 
-/* From bind lib/isc/ev_timers.c:  */
 #define BILLION 1000000000
-static struct timespec
+
+static inline struct timespec
 evTimeSpec(struct timeval tv) {
-	struct timespec ts;
+        struct timespec ts;
 
-	ts.tv_sec = tv.tv_sec;
-	ts.tv_nsec = tv.tv_usec * 1000;
-	return (ts);
+        ts.tv_sec = tv.tv_sec;
+        ts.tv_nsec = tv.tv_usec * 1000;
+        return (ts);
 }
 
-static struct timespec
+static inline struct timespec
 evConsTime(time_t sec, long nsec) {
 	struct timespec x;
 
@@ -126,7 +133,7 @@ evConsTime(time_t sec, long nsec) {
 	return (x);
 }
 
-static struct timespec
+static inline struct timespec
 evAddTime(struct timespec addend1, struct timespec addend2) {
 	struct timespec x;
 
@@ -139,7 +146,7 @@ evAddTime(struct timespec addend1, struct timespec addend2) {
 	return (x);
 }
 
-static struct timespec
+static inline struct timespec
 evSubTime(struct timespec minuend, struct timespec subtrahend) {
 	struct timespec x;
 
@@ -153,7 +160,7 @@ evSubTime(struct timespec minuend, struct timespec subtrahend) {
 	return (x);
 }
 
-static int
+static inline int
 evCmpTime(struct timespec a, struct timespec b) {
 	long x = a.tv_sec - b.tv_sec;
 
@@ -162,7 +169,7 @@ evCmpTime(struct timespec a, struct timespec b) {
 	return (x < 0L ? (-1) : x > 0L ? (1) : (0));
 }
 
-static struct timespec
+static inline struct timespec
 evNowTime() {
 	struct timeval now;
 
@@ -170,41 +177,44 @@ evNowTime() {
 		return (evConsTime(0, 0));
 	return (evTimeSpec(now));
 }
-/* End of code from bind lib/isc/ev_timers.c.  */
 
-#ifdef DEBUG
-    static void
-    Aerror(const res_state statp, FILE *file, const char *string, int error,
-	   struct sockaddr_in address)
-    {
-	int save = errno;
+#endif
 
-	if ((statp->options & RES_DEBUG) != 0) {
-		char tmp[sizeof "255.255.255.255"];
+/* Options.  Leave them on. */
+/* #undef DEBUG */
+#include "res_debug.h"
 
-		fprintf(file, "res_send: %s ([%s].%u): %s\n",
-			string,
-			inet_ntop(address.sin_family, &address.sin_addr,
-				  tmp, sizeof tmp),
-			ntohs(address.sin_port),
-			strerror(error));
-	}
-	__set_errno (save);
-    }
-    static void
-    Perror(const res_state statp, FILE *file, const char *string, int error) {
-	int save = errno;
+#define EXT(res) ((res)->_u._ext)
 
-	if ((statp->options & RES_DEBUG) != 0)
-		fprintf(file, "res_send: %s: %s\n",
-			string, strerror(error));
-	__set_errno (save);
-    }
+#ifndef _LIBC
+static const int highestFD = FD_SETSIZE - 1;
 #endif
 
-static int cmpsock(struct sockaddr_in *a1, struct sockaddr_in *a2);
+/* Forward. */
+
+static int		send_vc(res_state, const u_char *, int,
+				u_char *, int, int *, int);
+static int		send_dg(res_state, const u_char *, int,
+				u_char *, int, int *, int,
+				int *, int *);
+#ifdef DEBUG
+static void		Aerror(const res_state, FILE *, const char *, int,
+			       struct sockaddr_in);
+static void		Perror(const res_state, FILE *, const char *, int);
+#endif
+static int		sock_eq(struct sockaddr_in *, struct sockaddr_in *);
+#ifdef NEED_PSELECT
+static int		pselect(int, void *, void *, void *,
+				struct timespec *,
+				const sigset_t *);
+#endif
+
+/* Reachover. */
+
 void res_pquery(const res_state, const u_char *, int, FILE *);
 
+/* Public. */
+
 /* int
  * res_isourserver(ina)
  *	looks up "ina" in _res.ns_addr_list[]
@@ -220,7 +230,7 @@ res_ourserver_p(const res_state statp, const struct sockaddr_in *inp) {
 	int ns;
 
 	ina = *inp;
-	for (ns = 0;  ns < statp->nscount;  ns++) {
+	for (ns = 0; ns < statp->nscount; ns++) {
 		const struct sockaddr_in *srv = &statp->nsaddr_list[ns];
 
 		if (srv->sin_family == ina.sin_family &&
@@ -295,8 +305,8 @@ res_queriesmatch(const u_char *buf1, const u_char *eom1,
 	 * Only header section present in replies to
 	 * dynamic update packets.
 	 */
-	if ( (((HEADER *)buf1)->opcode == ns_o_update) &&
-	     (((HEADER *)buf2)->opcode == ns_o_update) )
+	if ((((HEADER *)buf1)->opcode == ns_o_update) &&
+	    (((HEADER *)buf2)->opcode == ns_o_update))
 		return (1);
 
 	if (qdcount != ntohs(((HEADER*)buf2)->qdcount))
@@ -323,12 +333,12 @@ int
 res_nsend(res_state statp,
 	  const u_char *buf, int buflen, u_char *ans, int anssiz)
 {
-	HEADER *hp = (HEADER *) buf;
-	HEADER *anhp = (HEADER *) ans;
-	int gotsomewhere, connreset, terrno, try, v_circuit, resplen, ns, n;
-	u_int badns;	/* XXX NSMAX can't exceed #/bits in this variable */
-	static int highestFD = FD_SETSIZE - 1;
+	int gotsomewhere, terrno, try, v_circuit, resplen, ns, n;
 
+	if (statp->nscount == 0) {
+		__set_errno (ESRCH);
+		return (-1);
+	}
 	if (anssiz < HFIXEDSZ) {
 		__set_errno (EINVAL);
 		return (-1);
@@ -337,14 +347,46 @@ res_nsend(res_state statp,
 		(stdout, ";; res_send()\n"), buf, buflen);
 	v_circuit = (statp->options & RES_USEVC) || buflen > PACKETSZ;
 	gotsomewhere = 0;
-	connreset = 0;
 	terrno = ETIMEDOUT;
-	badns = 0;
 
 	/*
-	 * Some callers want to even out the load on their resolver list.
+	 * If the ns_addr_list in the resolver context has changed, then
+	 * invalidate our cached copy and the associated timing data.
 	 */
-	if (statp->nscount > 0 && (statp->options & RES_ROTATE) != 0) {
+	if (EXT(statp).nscount != 0) {
+		int needclose = 0;
+
+		if (EXT(statp).nscount != statp->nscount)
+			needclose++;
+		else
+			for (ns = 0; ns < statp->nscount; ns++)
+				if (!sock_eq(&statp->nsaddr_list[ns],
+					     &EXT(statp).nsaddrs[ns])) {
+					needclose++;
+					break;
+				}
+		if (needclose)
+			res_nclose(statp);
+	}
+
+	/*
+	 * Maybe initialize our private copy of the ns_addr_list.
+	 */
+	if (EXT(statp).nscount == 0) {
+		for (ns = 0; ns < statp->nscount; ns++) {
+			EXT(statp).nsaddrs[ns] = statp->nsaddr_list[ns];
+			EXT(statp).nstimes[ns] = RES_MAXTIME;
+			EXT(statp).nssocks[ns] = -1;
+		}
+		EXT(statp).nscount = statp->nscount;
+	}
+
+	/*
+	 * Some resolvers want to even out the load on their nameservers.
+	 * Note that RES_BLAST overrides RES_ROTATE.
+	 */
+	if ((statp->options & RES_ROTATE) != 0 &&
+	    (statp->options & RES_BLAST) == 0) {
 		struct sockaddr_in ina;
 		int lastns = statp->nscount - 1;
 
@@ -355,17 +397,12 @@ res_nsend(res_state statp,
 	}
 
 	/*
-	 * Send request, RETRY times, or until successful
+	 * Send request, RETRY times, or until successful.
 	 */
 	for (try = 0; try < statp->retry; try++) {
 	    for (ns = 0; ns < statp->nscount; ns++) {
 		struct sockaddr_in *nsap = &statp->nsaddr_list[ns];
  same_ns:
-		if (badns & (1 << ns)) {
-			res_nclose(statp);
-			goto next_ns;
-		}
-
 		if (statp->qhook) {
 			int done = 0, loops = 0;
 
@@ -401,474 +438,45 @@ res_nsend(res_state statp,
 			ns + 1, inet_ntoa(nsap->sin_addr)));
 
 		if (v_circuit) {
-			int truncated;
-			struct iovec iov[2];
-			u_short len;
-			u_char *cp;
-
 			/* Use VC; at most one attempt per server. */
 			try = statp->retry;
-			truncated = 0;
-
-			/* Are we still talking to whom we want to talk to? */
-			if (statp->_sock >= 0 &&
-			    (statp->_flags & RES_F_VC) != 0) {
-				struct sockaddr_in peer;
-				int size = sizeof(peer);
-
-				if (getpeername(statp->_sock,
-						(struct sockaddr *)&peer,
-						&size) < 0) {
-					res_nclose(statp);
-					statp->_flags &= ~RES_F_VC;
-				} else if (!cmpsock(&peer, nsap)) {
-					res_nclose(statp);
-					statp->_flags &= ~RES_F_VC;
-				}
-			}
-
-			if (statp->_sock < 0 ||
-			    (statp->_flags & RES_F_VC) == 0) {
-				if (statp->_sock >= 0)
-					res_nclose(statp);
-
-				statp->_sock = socket(PF_INET,
-						       SOCK_STREAM, 0);
-				if (statp->_sock < 0 ||
-				    statp->_sock > highestFD) {
-					terrno = errno;
-					Perror(statp, stderr,
-					       "socket(vc)", errno);
-					return (-1);
-				}
-				__set_errno (0);
-				if (connect(statp->_sock,
-					    (struct sockaddr *)nsap,
-					    sizeof *nsap) < 0) {
-					terrno = errno;
-					Aerror(statp, stderr, "connect/vc",
-					       errno, *nsap);
-					badns |= (1 << ns);
-					res_nclose(statp);
-					goto next_ns;
-				}
-				statp->_flags |= RES_F_VC;
-			}
-			/*
-			 * Send length & message
-			 */
-			putshort((u_short)buflen, (u_char*)&len);
-			iov[0].iov_base = (caddr_t)&len;
-			iov[0].iov_len = INT16SZ;
-			iov[1].iov_base = (caddr_t)buf;
-			iov[1].iov_len = buflen;
-			if (writev(statp->_sock, iov, 2) !=
-			    (INT16SZ + buflen)) {
-				terrno = errno;
-				Perror(statp, stderr, "write failed", errno);
-				badns |= (1 << ns);
-				res_nclose(statp);
+			n = send_vc(statp, buf, buflen, ans, anssiz, &terrno,
+				    ns);
+			if (n < 0)
+				return (-1);
+			if (n == 0)
 				goto next_ns;
-			}
-			/*
-			 * Receive length & response
-			 */
- read_len:
-			cp = ans;
-			len = INT16SZ;
-			while ((n = read(statp->_sock,
-					 (char *)cp, (int)len)) > 0) {
-				cp += n;
-				if ((len -= n) <= 0)
-					break;
-			}
-			if (n <= 0) {
-				terrno = errno;
-				Perror(statp, stderr, "read failed", errno);
-				res_nclose(statp);
-				/*
-				 * A long running process might get its TCP
-				 * connection reset if the remote server was
-				 * restarted.  Requery the server instead of
-				 * trying a new one.  When there is only one
-				 * server, this means that a query might work
-				 * instead of failing.  We only allow one reset
-				 * per query to prevent looping.
-				 */
-				if (terrno == ECONNRESET && !connreset) {
-					connreset = 1;
-					res_nclose(statp);
-					goto same_ns;
-				}
-				res_nclose(statp);
-				goto next_ns;
-			}
-			resplen = ns_get16(ans);
-			if (resplen > anssiz) {
-				Dprint(statp->options & RES_DEBUG,
-				       (stdout, ";; response truncated\n")
-				       );
-				truncated = 1;
-				len = anssiz;
-			} else
-				len = resplen;
-			if (len < HFIXEDSZ) {
-				/*
-				 * Undersized message.
-				 */
-				Dprint(statp->options & RES_DEBUG,
-				       (stdout, ";; undersized: %d\n", len));
-				terrno = EMSGSIZE;
-				badns |= (1 << ns);
-				res_nclose(statp);
-				goto next_ns;
-			}
-			cp = ans;
-			while (len != 0 &&
-			       (n = read(statp->_sock, (char *)cp, (int)len))
-			       > 0) {
-				cp += n;
-				len -= n;
-			}
-			if (n <= 0) {
-				terrno = errno;
-				Perror(statp, stderr, "read(vc)", errno);
-				res_nclose(statp);
-				goto next_ns;
-			}
-			if (truncated) {
-				/*
-				 * Flush rest of answer
-				 * so connection stays in synch.
-				 */
-				anhp->tc = 1;
-				len = resplen - anssiz;
-				while (len != 0) {
-					char junk[PACKETSZ];
-
-					n = ((size_t)len > sizeof(junk)
-					     ? sizeof(junk)
-					     : len);
-					n = read(statp->_sock, junk, n);
-					if (n > 0)
-						len -= n;
-					else
-						break;
-				}
-			}
-			/*
-			 * The calling applicating has bailed out of
-			 * a previous call and failed to arrange to have
-			 * the circuit closed or the server has got
-			 * itself confused. Anyway drop the packet and
-			 * wait for the correct one.
-			 */
-			if (hp->id != anhp->id) {
-				DprintQ((statp->options & RES_DEBUG) ||
-					(statp->pfcode & RES_PRF_REPLY),
-					(stdout, ";; old answer (unexpected):\n"),
-					ans, (resplen>anssiz)?anssiz:resplen);
-				goto read_len;
-			}
+			resplen = n;
 		} else {
-			/*
-			 * Use datagrams.
-			 */
-			struct timespec start, timeout, finish;
-#ifdef _LIBC
-			struct pollfd pfd[1];
-			int ptimeout;
-#else			
-			fd_set dsmask;
-#endif
-			struct sockaddr_in from;
-			int fromlen, seconds;
-
-			if (statp->_sock < 0 ||
-			    (statp->_flags & RES_F_VC) != 0) {
-				if ((statp->_flags & RES_F_VC) != 0)
-					res_nclose(statp);
-				statp->_sock = socket(PF_INET, SOCK_DGRAM, 0);
-				if (statp->_sock < 0 ||
-				    statp->_sock > highestFD) {
-#ifndef CAN_RECONNECT
- bad_dg_sock:
-#endif
-					terrno = errno;
-					Perror(statp, stderr,
-					       "socket(dg)", errno);
-					return (-1);
-				}
-				statp->_flags &= ~RES_F_CONN;
-			}
-#ifndef CANNOT_CONNECT_DGRAM
-			/*
-			 * On a 4.3BSD+ machine (client and server,
-			 * actually), sending to a nameserver datagram
-			 * port with no nameserver will cause an
-			 * ICMP port unreachable message to be returned.
-			 * If our datagram socket is "connected" to the
-			 * server, we get an ECONNREFUSED error on the next
-			 * socket operation, and select returns if the
-			 * error message is received.  We can thus detect
-			 * the absence of a nameserver without timing out.
-			 * If we have sent queries to at least two servers,
-			 * however, we don't want to remain connected,
-			 * as we wish to receive answers from the first
-			 * server to respond.
-			 */
-			if (statp->nscount == 1 || (try == 0 && ns == 0)) {
-				/*
-				 * Connect only if we are sure we won't
-				 * receive a response from another server.
-				 */
-				if ((statp->_flags & RES_F_CONN) == 0) {
-					if (connect(statp->_sock,
-						    (struct sockaddr *)nsap,
-						    sizeof *nsap) < 0) {
-						Aerror(statp, stderr,
-						       "connect(dg)",
-						       errno, *nsap);
-						badns |= (1 << ns);
-						res_nclose(statp);
-						goto next_ns;
-					}
-					statp->_flags |= RES_F_CONN;
-				}
-                              if (send(statp->_sock, (char*)buf, buflen, 0)
-				  != buflen) {
-					Perror(statp, stderr, "send", errno);
-					badns |= (1 << ns);
-					res_nclose(statp);
-					goto next_ns;
-				}
-			} else {
-				/*
-				 * Disconnect if we want to listen
-				 * for responses from more than one server.
-				 */
-				if ((statp->_flags & RES_F_CONN) != 0) {
-#ifdef CAN_RECONNECT
-					struct sockaddr_in no_addr;
-
-					no_addr.sin_family = AF_INET;
-					no_addr.sin_addr.s_addr = INADDR_ANY;
-					no_addr.sin_port = 0;
-					(void) connect(statp->_sock,
-						       (struct sockaddr *)
-						        &no_addr,
-						       sizeof no_addr);
-#else
-					struct sockaddr_in local_addr;
-					int len, result, s1;
-
-					len = sizeof(local_addr);
-					s1 = socket(PF_INET, SOCK_DGRAM, 0);
-					result = getsockname(statp->_sock,
-						(struct sockaddr *)&local_addr,
-							     &len);
-					if (s1 < 0)
-						goto bad_dg_sock;
-					(void) dup2(s1, statp->_sock);
-					(void) close(s1);
-					if (result == 0) {
-						/*
-						 * Attempt to rebind to old
-						 * port.  Note connected socket
-						 * has an sin_addr set.
-						 */
-						local_addr.sin_addr.s_addr =
-							htonl(0);
-						(void)bind(statp->_sock,
-							   (struct sockaddr *)
-							   &local_addr, len);
-					}
-					Dprint(statp->options & RES_DEBUG,
-					       (stdout, ";; new DG socket\n"))
-#endif /* CAN_RECONNECT */
-					statp->_flags &= ~RES_F_CONN;
-					__set_errno (0);
-				}
-#endif /* !CANNOT_CONNECT_DGRAM */
-				if (sendto(statp->_sock,
-					   (char*)buf, buflen, 0,
-					   (struct sockaddr *)nsap,
-					   sizeof *nsap)
-				    != buflen) {
-					Aerror(statp, stderr, "sendto", errno, *nsap);
-					badns |= (1 << ns);
-					res_nclose(statp);
-					goto next_ns;
-				}
-#ifndef CANNOT_CONNECT_DGRAM
-			}
-#endif /* !CANNOT_CONNECT_DGRAM */
-
-			if (statp->_sock < 0 || statp->_sock > highestFD) {
-				Perror(statp, stderr,
-				       "fd out-of-bounds", EMFILE);
-				res_nclose(statp);
+			/* Use datagrams. */
+			n = send_dg(statp, buf, buflen, ans, anssiz, &terrno,
+				    ns, &v_circuit, &gotsomewhere);
+			if (n < 0)
+				return (-1);
+			if (n == 0)
 				goto next_ns;
-			}
-
-			/*
-			 * Wait for reply
-			 */
-			seconds = (statp->retrans << try);
-			if (try > 0)
-				seconds /= statp->nscount;
-			if (seconds <= 0)
-				seconds = 1;
-
-			start = evNowTime();
-			timeout = evConsTime(seconds, 0);
-			finish = evAddTime(start, timeout);
- wait:
-#ifdef _LIBC
-			/* Convert struct timespec in milliseconds.  */
-			ptimeout = timeout.tv_sec * 1000
-			  + timeout.tv_nsec / 1000000;
-			
-			pfd[0].fd = statp->_sock;
-			pfd[0].events = POLLIN;
-			n = __poll (pfd, 1, ptimeout);
-#else
-			FD_ZERO(&dsmask);
-			FD_SET(statp->_sock, &dsmask);
-			n = pselect(statp->_sock + 1,
-				    &dsmask, NULL, NULL,
-				    &timeout, NULL);
-#endif
-			if (n == 0) {
-				Dprint(statp->options & RES_DEBUG,
-				       (stdout, ";; timeout\n"));
-				gotsomewhere = 1;
-				goto next_ns;
-			}
-			if (n < 0) {
-				if (errno == EINTR) {
-					struct timespec now;
-
-					now = evNowTime();
-					if (evCmpTime(finish, now) >= 0) {
-						timeout = evSubTime(finish,
-								    now);
-						goto wait;
-					}
-				}
-#ifdef _LIBC
-				Perror(statp, stderr, "poll", errno);
-#else
-				Perror(statp, stderr, "select", errno);
-#endif
-				res_nclose(statp);
-				goto next_ns;
-			}
-			__set_errno (0);
-			fromlen = sizeof(struct sockaddr_in);
-			resplen = recvfrom(statp->_sock, (char*)ans, anssiz,0,
-					   (struct sockaddr *)&from, &fromlen);
-			if (resplen <= 0) {
-				Perror(statp, stderr, "recvfrom", errno);
-				res_nclose(statp);
-				goto next_ns;
-			}
-			gotsomewhere = 1;
-			if (resplen < HFIXEDSZ) {
-				/*
-				 * Undersized message.
-				 */
-				Dprint(statp->options & RES_DEBUG,
-				       (stdout, ";; undersized: %d\n",
-					resplen));
-				terrno = EMSGSIZE;
-				badns |= (1 << ns);
-				res_nclose(statp);
-				goto next_ns;
-			}
-			if (hp->id != anhp->id) {
-				/*
-				 * response from old query, ignore it.
-				 * XXX - potential security hazard could
-				 *	 be detected here.
-				 */
-				DprintQ((statp->options & RES_DEBUG) ||
-					(statp->pfcode & RES_PRF_REPLY),
-					(stdout, ";; old answer:\n"),
-					ans, (resplen>anssiz)?anssiz:resplen);
-				goto wait;
-			}
-#ifdef CHECK_SRVR_ADDR
-			if (!(statp->options & RES_INSECURE1) &&
-			    !res_ourserver_p(statp, &from)) {
-				/*
-				 * response from wrong server? ignore it.
-				 * XXX - potential security hazard could
-				 *	 be detected here.
-				 */
-				DprintQ((statp->options & RES_DEBUG) ||
-					(statp->pfcode & RES_PRF_REPLY),
-					(stdout, ";; not our server:\n"),
-					ans, (resplen>anssiz)?anssiz:resplen);
-				goto wait;
-			}
-#endif
-			if (!(statp->options & RES_INSECURE2) &&
-			    !res_queriesmatch(buf, buf + buflen,
-					      ans, ans + anssiz)) {
-				/*
-				 * response contains wrong query? ignore it.
-				 * XXX - potential security hazard could
-				 *	 be detected here.
-				 */
-				DprintQ((statp->options & RES_DEBUG) ||
-					(statp->pfcode & RES_PRF_REPLY),
-					(stdout, ";; wrong query name:\n"),
-					ans, (resplen>anssiz)?anssiz:resplen);
-				goto wait;
-			}
-			if (anhp->rcode == SERVFAIL ||
-			    anhp->rcode == NOTIMP ||
-			    anhp->rcode == REFUSED) {
-				DprintQ(statp->options & RES_DEBUG,
-					(stdout, "server rejected query:\n"),
-					ans, (resplen>anssiz)?anssiz:resplen);
-				badns |= (1 << ns);
-				res_nclose(statp);
-				/* don't retry if called from dig */
-				if (!statp->pfcode)
-					goto next_ns;
-			}
-			if (!(statp->options & RES_IGNTC) && anhp->tc) {
-				/*
-				 * get rest of answer;
-				 * use TCP with same server.
-				 */
-				Dprint(statp->options & RES_DEBUG,
-				       (stdout, ";; truncated answer\n"));
-				v_circuit = 1;
-				res_nclose(statp);
+			if (v_circuit)
 				goto same_ns;
-			}
-		} /*if vc/dg*/
+			resplen = n;
+		}
+
 		Dprint((statp->options & RES_DEBUG) ||
 		       ((statp->pfcode & RES_PRF_REPLY) &&
 			(statp->pfcode & RES_PRF_HEAD1)),
 		       (stdout, ";; got answer:\n"));
+
 		DprintQ((statp->options & RES_DEBUG) ||
 			(statp->pfcode & RES_PRF_REPLY),
 			(stdout, ""),
-			ans, (resplen>anssiz)?anssiz:resplen);
+			ans, (resplen > anssiz) ? anssiz : resplen);
+
 		/*
-		 * If using virtual circuits, we assume that the first server
-		 * is preferred over the rest (i.e. it is on the local
-		 * machine) and only keep that one open.
 		 * If we have temporarily opened a virtual circuit,
 		 * or if we haven't been asked to keep a socket open,
 		 * close the socket.
 		 */
-		if ((v_circuit && (!(statp->options & RES_USEVC) || ns != 0)) ||
-		    !(statp->options & RES_STAYOPEN)) {
+		if ((v_circuit && (statp->options & RES_USEVC) == 0) ||
+		    (statp->options & RES_STAYOPEN) == 0) {
 			res_nclose(statp);
 		}
 		if (statp->rhook) {
@@ -915,25 +523,411 @@ res_nsend(res_state statp,
 	return (-1);
 }
 
-/*
- * This routine is for closing the socket if a virtual circuit is used and
- * the program wants to close it.  This provides support for endhostent()
- * which expects to close the socket.
- *
- * This routine is not expected to be user visible.
- */
-void
-res_nclose(res_state statp) {
-	if (statp->_sock >= 0) {
-		(void) close(statp->_sock);
-		statp->_sock = -1;
-		statp->_flags &= ~(RES_F_VC | RES_F_CONN);
+/* Private */
+
+static int
+send_vc(res_state statp,
+	const u_char *buf, int buflen, u_char *ans, int anssiz,
+	int *terrno, int ns)
+{
+	const HEADER *hp = (HEADER *) buf;
+	HEADER *anhp = (HEADER *) ans;
+	struct sockaddr_in *nsap = &statp->nsaddr_list[ns];
+	int truncating, connreset, resplen, n;
+	struct iovec iov[2];
+	u_short len;
+	u_char *cp;
+
+	connreset = 0;
+ same_ns:
+	truncating = 0;
+
+	/* Are we still talking to whom we want to talk to? */
+	if (statp->_vcsock >= 0 && (statp->_flags & RES_F_VC) != 0) {
+		struct sockaddr_in peer;
+		int size = sizeof peer;
+
+		if (getpeername(statp->_vcsock,
+				(struct sockaddr *)&peer, &size) < 0 ||
+		    !sock_eq(&peer, nsap)) {
+			res_nclose(statp);
+			statp->_flags &= ~RES_F_VC;
+		}
+	}
+
+	if (statp->_vcsock < 0 || (statp->_flags & RES_F_VC) == 0) {
+		if (statp->_vcsock >= 0)
+			res_nclose(statp);
+
+		statp->_vcsock = socket(PF_INET, SOCK_STREAM, 0);
+#ifndef _LIBC
+		if (statp->_vcsock > highestFD) {
+			res_nclose(statp);
+			__set_errno (ENOTSOCK);
+		}
+#endif
+		if (statp->_vcsock < 0) {
+			*terrno = errno;
+			Perror(statp, stderr, "socket(vc)", errno);
+			return (-1);
+		}
+		__set_errno (0);
+		if (connect(statp->_vcsock, (struct sockaddr *)nsap,
+			    sizeof *nsap) < 0) {
+			*terrno = errno;
+			Aerror(statp, stderr, "connect/vc", errno, *nsap);
+			res_nclose(statp);
+			return (0);
+		}
+		statp->_flags |= RES_F_VC;
 	}
+
+	/*
+	 * Send length & message
+	 */
+	putshort((u_short)buflen, (u_char*)&len);
+	iov[0] = evConsIovec(&len, INT16SZ);
+	iov[1] = evConsIovec((void*)buf, buflen);
+	if (writev(statp->_vcsock, iov, 2) != (INT16SZ + buflen)) {
+		*terrno = errno;
+		Perror(statp, stderr, "write failed", errno);
+		res_nclose(statp);
+		return (0);
+	}
+	/*
+	 * Receive length & response
+	 */
+ read_len:
+	cp = ans;
+	len = INT16SZ;
+	while ((n = read(statp->_vcsock, (char *)cp, (int)len)) > 0) {
+		cp += n;
+		if ((len -= n) <= 0)
+			break;
+	}
+	if (n <= 0) {
+		*terrno = errno;
+		Perror(statp, stderr, "read failed", errno);
+		res_nclose(statp);
+		/*
+		 * A long running process might get its TCP
+		 * connection reset if the remote server was
+		 * restarted.  Requery the server instead of
+		 * trying a new one.  When there is only one
+		 * server, this means that a query might work
+		 * instead of failing.  We only allow one reset
+		 * per query to prevent looping.
+		 */
+		if (*terrno == ECONNRESET && !connreset) {
+			connreset = 1;
+			res_nclose(statp);
+			goto same_ns;
+		}
+		res_nclose(statp);
+		return (0);
+	}
+	resplen = ns_get16(ans);
+	if (resplen > anssiz) {
+		Dprint(statp->options & RES_DEBUG,
+		       (stdout, ";; response truncated\n")
+		       );
+		truncating = 1;
+		len = anssiz;
+	} else
+		len = resplen;
+	if (len < HFIXEDSZ) {
+		/*
+		 * Undersized message.
+		 */
+		Dprint(statp->options & RES_DEBUG,
+		       (stdout, ";; undersized: %d\n", len));
+		*terrno = EMSGSIZE;
+		res_nclose(statp);
+		return (0);
+	}
+	cp = ans;
+	while (len != 0 && (n = read(statp->_vcsock, (char *)cp, (int)len)) > 0){
+		cp += n;
+		len -= n;
+	}
+	if (n <= 0) {
+		*terrno = errno;
+		Perror(statp, stderr, "read(vc)", errno);
+		res_nclose(statp);
+		return (0);
+	}
+	if (truncating) {
+		/*
+		 * Flush rest of answer so connection stays in synch.
+		 */
+		anhp->tc = 1;
+		len = resplen - anssiz;
+		while (len != 0) {
+			char junk[PACKETSZ];
+
+			n = read(statp->_vcsock, junk,
+				 (len > sizeof junk) ? sizeof junk : len);
+			if (n > 0)
+				len -= n;
+			else
+				break;
+		}
+	}
+	/*
+	 * If the calling applicating has bailed out of
+	 * a previous call and failed to arrange to have
+	 * the circuit closed or the server has got
+	 * itself confused, then drop the packet and
+	 * wait for the correct one.
+	 */
+	if (hp->id != anhp->id) {
+		DprintQ((statp->options & RES_DEBUG) ||
+			(statp->pfcode & RES_PRF_REPLY),
+			(stdout, ";; old answer (unexpected):\n"),
+			ans, (resplen > anssiz) ? anssiz: resplen);
+		goto read_len;
+	}
+
+	/*
+	 * All is well, or the error is fatal.  Signal that the
+	 * next nameserver ought not be tried.
+	 */
+	return (resplen);
 }
 
-/* Private */
 static int
-cmpsock(struct sockaddr_in *a1, struct sockaddr_in *a2) {
+send_dg(res_state statp,
+	const u_char *buf, int buflen, u_char *ans, int anssiz,
+	int *terrno, int ns, int *v_circuit, int *gotsomewhere)
+{
+	const HEADER *hp = (HEADER *) buf;
+	HEADER *anhp = (HEADER *) ans;
+	const struct sockaddr_in *nsap = &statp->nsaddr_list[ns];
+	struct timespec now, timeout, finish;
+#ifdef _LIBC
+	struct pollfd pfd[1];
+        int ptimeout;
+#else
+	fd_set dsmask;
+#endif
+	struct sockaddr_in from;
+	int fromlen, resplen, seconds, n, s;
+
+	if (EXT(statp).nssocks[ns] == -1) {
+		EXT(statp).nssocks[ns] = socket(PF_INET, SOCK_DGRAM, 0);
+#ifndef _LIBC
+		if (EXT(statp).nssocks[ns] > highestFD) {
+			res_nclose(statp);
+			__set_errno (ENOTSOCK);
+		}
+#endif
+		if (EXT(statp).nssocks[ns] < 0) {
+			*terrno = errno;
+			Perror(statp, stderr, "socket(dg)", errno);
+			return (-1);
+		}
+#ifndef CANNOT_CONNECT_DGRAM
+		/*
+		 * On a 4.3BSD+ machine (client and server,
+		 * actually), sending to a nameserver datagram
+		 * port with no nameserver will cause an
+		 * ICMP port unreachable message to be returned.
+		 * If our datagram socket is "connected" to the
+		 * server, we get an ECONNREFUSED error on the next
+		 * socket operation, and select returns if the
+		 * error message is received.  We can thus detect
+		 * the absence of a nameserver without timing out.
+		 */
+		if (connect(EXT(statp).nssocks[ns], (struct sockaddr *)nsap,
+			    sizeof *nsap) < 0) {
+			Aerror(statp, stderr, "connect(dg)", errno, *nsap);
+			res_nclose(statp);
+			return (0);
+		}
+#endif /* !CANNOT_CONNECT_DGRAM */
+		Dprint(statp->options & RES_DEBUG,
+		       (stdout, ";; new DG socket\n"))
+	}
+	s = EXT(statp).nssocks[ns];
+#ifndef CANNOT_CONNECT_DGRAM
+	if (send(s, (char*)buf, buflen, 0) != buflen) {
+		Perror(statp, stderr, "send", errno);
+		res_nclose(statp);
+		return (0);
+	}
+#else /* !CANNOT_CONNECT_DGRAM */
+	if (sendto(s, (char*)buf, buflen, 0,
+		   (struct sockaddr *)nsap, sizeof *nsap) != buflen)
+	{
+		Aerror(statp, stderr, "sendto", errno, *nsap);
+		res_nclose(statp);
+		return (0);
+	}
+#endif /* !CANNOT_CONNECT_DGRAM */
+
+	/*
+	 * Wait for reply.
+	 */
+	seconds = (statp->retrans << ns);
+	if (ns > 0)
+		seconds /= statp->nscount;
+	if (seconds <= 0)
+		seconds = 1;
+	now = evNowTime();
+	timeout = evConsTime(seconds, 0);
+	finish = evAddTime(now, timeout);
+ wait:
+#ifdef _LIBC
+        /* Convert struct timespec in milliseconds.  */
+	ptimeout = timeout.tv_sec * 1000 + timeout.tv_nsec / 1000000;
+
+	pfd[0].fd = s;
+	pfd[0].events = POLLIN;
+	n = __poll (pfd, 1, ptimeout);
+#else
+	FD_ZERO(&dsmask);
+	FD_SET(s, &dsmask);
+	n = pselect(s + 1, &dsmask, NULL, NULL, &timeout, NULL);
+#endif
+	if (n == 0) {
+		Dprint(statp->options & RES_DEBUG, (stdout, ";; timeout\n"));
+		*gotsomewhere = 1;
+		return (0);
+	}
+	if (n < 0) {
+		if (errno == EINTR) {
+			now = evNowTime();
+			if (evCmpTime(finish, now) > 0) {
+				timeout = evSubTime(finish, now);
+				goto wait;
+			}
+		}
+		Perror(statp, stderr, "select", errno);
+		res_nclose(statp);
+		return (0);
+	}
+	__set_errno (0);
+	fromlen = sizeof(struct sockaddr_in);
+	resplen = recvfrom(s, (char*)ans, anssiz,0,
+			   (struct sockaddr *)&from, &fromlen);
+	if (resplen <= 0) {
+		Perror(statp, stderr, "recvfrom", errno);
+		res_nclose(statp);
+		return (0);
+	}
+	*gotsomewhere = 1;
+	if (resplen < HFIXEDSZ) {
+		/*
+		 * Undersized message.
+		 */
+		Dprint(statp->options & RES_DEBUG,
+		       (stdout, ";; undersized: %d\n",
+			resplen));
+		*terrno = EMSGSIZE;
+		res_nclose(statp);
+		return (0);
+	}
+	if (hp->id != anhp->id) {
+		/*
+		 * response from old query, ignore it.
+		 * XXX - potential security hazard could
+		 *	 be detected here.
+		 */
+		DprintQ((statp->options & RES_DEBUG) ||
+			(statp->pfcode & RES_PRF_REPLY),
+			(stdout, ";; old answer:\n"),
+			ans, (resplen > anssiz) ? anssiz : resplen);
+		goto wait;
+	}
+	if (!(statp->options & RES_INSECURE1) &&
+	    !res_ourserver_p(statp, &from)) {
+		/*
+		 * response from wrong server? ignore it.
+		 * XXX - potential security hazard could
+		 *	 be detected here.
+		 */
+		DprintQ((statp->options & RES_DEBUG) ||
+			(statp->pfcode & RES_PRF_REPLY),
+			(stdout, ";; not our server:\n"),
+			ans, (resplen > anssiz) ? anssiz : resplen);
+		goto wait;
+	}
+	if (!(statp->options & RES_INSECURE2) &&
+	    !res_queriesmatch(buf, buf + buflen,
+			      ans, ans + anssiz)) {
+		/*
+		 * response contains wrong query? ignore it.
+		 * XXX - potential security hazard could
+		 *	 be detected here.
+		 */
+		DprintQ((statp->options & RES_DEBUG) ||
+			(statp->pfcode & RES_PRF_REPLY),
+			(stdout, ";; wrong query name:\n"),
+			ans, (resplen > anssiz) ? anssiz : resplen);
+		goto wait;
+	}
+	if (anhp->rcode == SERVFAIL ||
+	    anhp->rcode == NOTIMP ||
+	    anhp->rcode == REFUSED) {
+		DprintQ(statp->options & RES_DEBUG,
+			(stdout, "server rejected query:\n"),
+			ans, (resplen > anssiz) ? anssiz : resplen);
+		res_nclose(statp);
+		/* don't retry if called from dig */
+		if (!statp->pfcode)
+			return (0);
+	}
+	if (!(statp->options & RES_IGNTC) && anhp->tc) {
+		/*
+		 * To get the rest of answer,
+		 * use TCP with same server.
+		 */
+		Dprint(statp->options & RES_DEBUG,
+		       (stdout, ";; truncated answer\n"));
+		*v_circuit = 1;
+		res_nclose(statp);
+		return (1);
+	}
+	/*
+	 * All is well, or the error is fatal.  Signal that the
+	 * next nameserver ought not be tried.
+	 */
+	return (resplen);
+}
+
+#ifdef DEBUG
+static void
+Aerror(const res_state statp, FILE *file, const char *string, int error,
+       struct sockaddr_in address)
+{
+	int save = errno;
+
+	if ((statp->options & RES_DEBUG) != 0) {
+		char tmp[sizeof "255.255.255.255"];
+
+		fprintf(file, "res_send: %s ([%s].%u): %s\n",
+			string,
+			inet_ntop(address.sin_family, &address.sin_addr,
+				  tmp, sizeof tmp),
+			ntohs(address.sin_port),
+			strerror(error));
+	}
+	__set_errno (save);
+}
+
+static void
+Perror(const res_state statp, FILE *file, const char *string, int error) {
+	int save = errno;
+
+	if ((statp->options & RES_DEBUG) != 0)
+		fprintf(file, "res_send: %s: %s\n",
+			string, strerror(error));
+	__set_errno (save);
+}
+#endif
+
+static int
+sock_eq(struct sockaddr_in *a1, struct sockaddr_in *a2) {
 	return ((a1->sin_family == a2->sin_family) &&
 		(a1->sin_port == a2->sin_port) &&
 		(a1->sin_addr.s_addr == a2->sin_addr.s_addr));
@@ -943,8 +937,7 @@ cmpsock(struct sockaddr_in *a1, struct sockaddr_in *a2) {
 /* XXX needs to move to the porting library. */
 static int
 pselect(int nfds, void *rfds, void *wfds, void *efds,
-	struct timespec *tsp,
-	const sigset_t *sigmask)
+	struct timespec *tsp, const sigset_t *sigmask)
 {
 	struct timeval tv, *tvp;
 	sigset_t sigs;
diff --git a/resolv/resolv.h b/resolv/resolv.h
index 426ac7a2ed..058c631279 100644
--- a/resolv/resolv.h
+++ b/resolv/resolv.h
@@ -1,9 +1,7 @@
 /*
- * ++Copyright++ 1983, 1987, 1989, 1993
- * -
- * Copyright (c) 1983, 1987, 1989, 1993
+ * Copyright (c) 1983, 1987, 1989
  *    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:
@@ -15,7 +13,7 @@
  * 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
@@ -27,26 +25,6 @@
  * 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.
- * -
- * Portions Copyright (c) 1993 by Digital Equipment Corporation.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies, and that
- * the name of Digital Equipment Corporation not be used in advertising or
- * publicity pertaining to distribution of the document or software without
- * specific, written prior permission.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
- * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
- * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
- * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
- * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
- * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- * SOFTWARE.
- * -
- * --Copyright--
  */
 
 /*
@@ -68,13 +46,11 @@
 
 /*
  *	@(#)resolv.h	8.1 (Berkeley) 6/2/93
- *	$Id$
+ *	$BINDId: resolv.h,v 8.31 2000/03/30 20:16:50 vixie Exp $
  */
 
-#ifndef _RESOLV_H
-#define	_RESOLV_H 1
-
-#include <features.h>
+#ifndef _RESOLV_H_
+#define	_RESOLV_H_
 
 #include <sys/param.h>
 #if (!defined(BSD)) || (BSD < 199306)
@@ -82,8 +58,11 @@
 #else
 # include <sys/types.h>
 #endif
+#include <sys/cdefs.h>
 #include <stdio.h>
+
 #include <netinet/in.h>
+#include <arpa/nameser.h>
 
 /*
  * Revision information.  This is the release date in YYYYMMDD format.
@@ -96,37 +75,9 @@
 #define	__RES	19991006
 
 /*
- * This used to be defined in res_query.c, now it's in herror.c.
- * [XXX no it's not.  It's in irs/irs_data.c]
- * It was
- * never extern'd by any *.h file before it was placed here.  For thread
- * aware programs, the last h_errno value set is stored in res->h_errno.
- *
- * XXX:	There doesn't seem to be a good reason for exposing RES_SET_H_ERRNO
- *	(and __h_errno_set) to the public via <resolv.h>.
- * XXX:	__h_errno_set is really part of IRS, not part of the resolver.
- *	If somebody wants to build and use a resolver that doesn't use IRS,
- *	what do they do?  Perhaps something like
- *		#ifdef WANT_IRS
- *		# define RES_SET_H_ERRNO(r,x) __h_errno_set(r,x)
- *		#else
- *		# define RES_SET_H_ERRNO(r,x) (h_errno = (r)->res_h_errno = (x))
- *		#endif
- */
-#define RES_SET_H_ERRNO(r,x)			\
-  do						\
-    {						\
-      (r)->res_h_errno = x;			\
-      __set_h_errno(x);				\
-    }						\
-  while (0)
-
-struct __res_state; /* forward */
-
-/*
  * Resolver configuration file.
  * Normally not present, but may contain the address of the
- * initial name server(s) to query and the domain search list.
+ * inital name server(s) to query and the domain search list.
  */
 
 #ifndef _PATH_RESCONF
@@ -136,19 +87,19 @@ struct __res_state; /* forward */
 typedef enum { res_goahead, res_nextns, res_modified, res_done, res_error }
 	res_sendhookact;
 
-typedef res_sendhookact (*res_send_qhook) (struct sockaddr_in * const *ns,
-					   const u_char **query,
-					   int *querylen,
-					   u_char *ans,
-					   int anssiz,
-					   int *resplen);
+typedef res_sendhookact (*res_send_qhook)__P((struct sockaddr_in * const *ns,
+					      const u_char **query,
+					      int *querylen,
+					      u_char *ans,
+					      int anssiz,
+					      int *resplen));
 
-typedef res_sendhookact (*res_send_rhook) (const struct sockaddr_in *ns,
-					   const u_char *query,
-					   int querylen,
-					   u_char *ans,
-					   int anssiz,
-					   int *resplen);
+typedef res_sendhookact (*res_send_rhook)__P((const struct sockaddr_in *ns,
+					      const u_char *query,
+					      int querylen,
+					      u_char *ans,
+					      int anssiz,
+					      int *resplen));
 
 struct res_sym {
 	int	number;		/* Identifying number, like T_MX */
@@ -170,9 +121,10 @@ struct res_sym {
 #define	RES_MAXRETRANS		30	/* only for resolv.conf/RES_OPTIONS */
 #define	RES_MAXRETRY		5	/* only for resolv.conf/RES_OPTIONS */
 #define	RES_DFLRETRY		2	/* Default #/tries. */
+#define	RES_MAXTIME		65535	/* Infinity, in milliseconds. */
 
 struct __res_state {
-	int	retrans;		/* retransmission time interval */
+	int	retrans;	 	/* retransmition time interval */
 	int	retry;			/* number of times to retransmit */
 	u_long	options;		/* option flags - see below. */
 	int	nscount;		/* number of name servers */
@@ -193,9 +145,17 @@ struct __res_state {
 	res_send_qhook qhook;		/* query hook */
 	res_send_rhook rhook;		/* response hook */
 	int	res_h_errno;		/* last one set for this context */
-	int	_sock;			/* PRIVATE: for res_send i/o */
+	int	_vcsock;		/* PRIVATE: for res_send VC i/o */
 	u_int	_flags;			/* PRIVATE: see below */
-	char	pad[52];		/* On an i386 this means 512b total. */
+	union {
+		char	pad[52];	/* On an i386 this means 512b total. */
+		struct {
+			u_int16_t		nscount;
+			u_int16_t		nstimes[MAXNS];	/* ms. */
+			int			nssocks[MAXNS];
+			struct sockaddr_in	nsaddrs[MAXNS];
+		} _ext;
+	} _u;
 };
 
 typedef struct __res_state *res_state;
@@ -229,6 +189,7 @@ typedef struct __res_state *res_state;
 #define RES_ROTATE	0x00004000	/* rotate ns list after each query */
 #define	RES_NOCHECKNAME	0x00008000	/* do not check names for sanity. */
 #define	RES_KEEPTSIG	0x00010000	/* do not strip TSIG records */
+#define	RES_BLAST	0x00020000	/* blast all recursive servers */
 
 #define RES_DEFAULT	(RES_RECURSE | RES_DEFNAMES | RES_DNSRCH)
 
@@ -237,7 +198,7 @@ typedef struct __res_state *res_state;
  */
 #define RES_PRF_STATS	0x00000001
 #define RES_PRF_UPDATE	0x00000002
-#define RES_PRF_CLASS	0x00000004
+#define RES_PRF_CLASS   0x00000004
 #define RES_PRF_CMD	0x00000008
 #define RES_PRF_QUES	0x00000010
 #define RES_PRF_ANS	0x00000020
@@ -253,46 +214,51 @@ typedef struct __res_state *res_state;
 /*			0x00008000	*/
 
 /* Things involving an internal (static) resolver context. */
-#if defined _REENTRANT || defined _LIBC_REENTRANT
+#if !defined _LIBC || defined _LIBC_REENTRANT
 extern struct __res_state *__res_state(void) __attribute__ ((__const__));
-# if defined __RES_PTHREAD_INTERNAL
-extern struct __res_state _res;
-# else
-#  define _res (*__res_state())
-# endif
+#define _res (*__res_state())
 #else
+#ifndef __BIND_NOSTATIC
 extern struct __res_state _res;
 #endif
+#endif
 
+#ifndef __BIND_NOSTATIC
 #define fp_nquery		__fp_nquery
 #define fp_query		__fp_query
 #define hostalias		__hostalias
 #define p_query			__p_query
 #define res_close		__res_close
+#define res_init		__res_init
 #define res_isourserver		__res_isourserver
+#define res_mkquery		__res_mkquery
+#define res_query		__res_query
+#define res_querydomain		__res_querydomain
+#define res_search		__res_search
 #define res_send		__res_send
 
 __BEGIN_DECLS
-void		fp_nquery (const u_char *, int, FILE *) __THROW;
-void		fp_query (const u_char *, FILE *) __THROW;
-const char *	hostalias (const char *) __THROW;
-void		p_query (const u_char *) __THROW;
-void		res_close (void) __THROW;
-int		res_init (void) __THROW;
-int		res_isourserver (const struct sockaddr_in *) __THROW;
-int		res_mkquery (int, const char *, int, int, const u_char *,
-			     int, const u_char *, u_char *, int) __THROW;
-int		res_query (const char *, int, int, u_char *, int) __THROW;
-int		res_querydomain (const char *, const char *, int, int,
-				 u_char *, int) __THROW;
-int		res_search (const char *, int, int, u_char *, int) __THROW;
-int		res_send (const u_char *, int, u_char *, int) __THROW;
+void		fp_nquery __P((const u_char *, int, FILE *));
+void		fp_query __P((const u_char *, FILE *));
+const char *	hostalias __P((const char *));
+void		p_query __P((const u_char *));
+void		res_close __P((void));
+int		res_init __P((void));
+int		res_isourserver __P((const struct sockaddr_in *));
+int		res_mkquery __P((int, const char *, int, int, const u_char *,
+				 int, const u_char *, u_char *, int));
+int		res_query __P((const char *, int, int, u_char *, int));
+int		res_querydomain __P((const char *, const char *, int, int,
+				     u_char *, int));
+int		res_search __P((const char *, int, int, u_char *, int));
+int		res_send __P((const u_char *, int, u_char *, int));
 __END_DECLS
+#endif
 
-#if !defined(SHARED_LIBBIND) || defined(_LIBC)
+#if !defined(SHARED_LIBBIND) || defined(LIB)
 /*
  * If libbind is a shared object (well, DLL anyway)
- * these externs break the linker when resolv.h is
+ * these externs break the linker when resolv.h is 
  * included by a lib client (like named)
  * Make them go away if a client is including this
  *
@@ -308,6 +274,7 @@ extern const struct res_sym __p_rcode_syms[];
 #define b64_pton		__b64_pton
 #define dn_comp			__dn_comp
 #define dn_count_labels		__dn_count_labels
+#define dn_expand		__dn_expand
 #define dn_skipname		__dn_skipname
 #define fp_resstat		__fp_resstat
 #define loc_aton		__loc_aton
@@ -326,7 +293,6 @@ extern const struct res_sym __p_rcode_syms[];
 #define putlong			__putlong
 #define putshort		__putshort
 #define res_dnok		__res_dnok
-#define res_findzonecut		__res_findzonecut
 #define res_hnok		__res_hnok
 #define res_hostalias		__res_hostalias
 #define res_mailok		__res_mailok
@@ -347,63 +313,62 @@ extern const struct res_sym __p_rcode_syms[];
 #define sym_ntos		__sym_ntos
 #define sym_ston		__sym_ston
 __BEGIN_DECLS
-int		res_hnok (const char *) __THROW;
-int		res_ownok (const char *) __THROW;
-int		res_mailok (const char *) __THROW;
-int		res_dnok (const char *) __THROW;
-int		sym_ston (const struct res_sym *, const char *, int *) __THROW;
-const char *	sym_ntos (const struct res_sym *, int, int *) __THROW;
-const char *	sym_ntop (const struct res_sym *, int, int *) __THROW;
-int		b64_ntop (u_char const *, size_t, char *, size_t) __THROW;
-int		b64_pton (char const *, u_char *, size_t) __THROW;
-int		loc_aton (const char *__ascii, u_char *__binary) __THROW;
-const char *	loc_ntoa (const u_char *__binary, char *__ascii) __THROW;
-int		dn_skipname (const u_char *, const u_char *) __THROW;
-void		putlong (u_int32_t, u_char *) __THROW;
-void		putshort (u_int16_t, u_char *) __THROW;
-const char *	p_class (int) __THROW;
-const char *	p_time (u_int32_t) __THROW;
-const char *	p_type (int) __THROW;
-const char *	p_rcode (int) __THROW;
-const u_char *	p_cdnname (const u_char *, const u_char *, int, FILE *)
-     __THROW;
-const u_char *	p_cdname (const u_char *, const u_char *, FILE *) __THROW;
-const u_char *	p_fqnname (const u_char *cp, const u_char *msg,
-			   int, char *, int) __THROW;
-const u_char *	p_fqname (const u_char *, const u_char *, FILE *) __THROW;
-const char *	p_option (u_long option) __THROW;
-char *		p_secstodate (u_long) __THROW;
-int		dn_count_labels (const char *) __THROW;
-int		dn_comp (const char *, u_char *, int,
-			     u_char **, u_char **) __THROW;
-int		dn_expand (const u_char *, const u_char *, const u_char *,
-			   char *, int) __THROW;
-u_int		res_randomid (void) __THROW;
-int		res_nameinquery (const char *, int, int,
-				 const u_char *, const u_char *) __THROW;
-int		res_queriesmatch (const u_char *, const u_char *,
-				  const u_char *, const u_char *) __THROW;
-const char *	p_section (int section, int opcode) __THROW;
+int		res_hnok __P((const char *));
+int		res_ownok __P((const char *));
+int		res_mailok __P((const char *));
+int		res_dnok __P((const char *));
+int		sym_ston __P((const struct res_sym *, const char *, int *));
+const char *	sym_ntos __P((const struct res_sym *, int, int *));
+const char *	sym_ntop __P((const struct res_sym *, int, int *));
+int		b64_ntop __P((u_char const *, size_t, char *, size_t));
+int		b64_pton __P((char const *, u_char *, size_t));
+int		loc_aton __P((const char *ascii, u_char *binary));
+const char *	loc_ntoa __P((const u_char *binary, char *ascii));
+int		dn_skipname __P((const u_char *, const u_char *));
+void		putlong __P((u_int32_t, u_char *));
+void		putshort __P((u_int16_t, u_char *));
+const char *	p_class __P((int));
+const char *	p_time __P((u_int32_t));
+const char *	p_type __P((int));
+const char *	p_rcode __P((int));
+const u_char *	p_cdnname __P((const u_char *, const u_char *, int, FILE *));
+const u_char *	p_cdname __P((const u_char *, const u_char *, FILE *));
+const u_char *	p_fqnname __P((const u_char *cp, const u_char *msg,
+			       int, char *, int));
+const u_char *	p_fqname __P((const u_char *, const u_char *, FILE *));
+const char *	p_option __P((u_long option));
+char *		p_secstodate __P((u_long));
+int		dn_count_labels __P((const char *));
+int		dn_comp __P((const char *, u_char *, int,
+			     u_char **, u_char **));
+int		dn_expand __P((const u_char *, const u_char *, const u_char *,
+			       char *, int));
+u_int		res_randomid __P((void));
+int		res_nameinquery __P((const char *, int, int,
+				     const u_char *, const u_char *));
+int		res_queriesmatch __P((const u_char *, const u_char *,
+				      const u_char *, const u_char *));
+const char *	p_section __P((int section, int opcode));
 /* Things involving a resolver context. */
-int		res_ninit (res_state) __THROW;
-int		res_nisourserver (const res_state,
-				  const struct sockaddr_in *) __THROW;
-void		fp_resstat (const res_state, FILE *) __THROW;
-void		res_npquery (const res_state, const u_char *, int, FILE *) __THROW;
-const char *	res_hostalias (const res_state, const char *,
-			       char *, size_t) __THROW;
-int		res_nquery (res_state,
-			    const char *, int, int, u_char *, int) __THROW;
-int		res_nsearch (res_state, const char *, int,
-			     int, u_char *, int) __THROW;
-int		res_nquerydomain (res_state,
-				  const char *, const char *, int, int,
-				  u_char *, int) __THROW;
-int		res_nmkquery (res_state,
-			      int, const char *, int, int, const u_char *,
-			      int, const u_char *, u_char *, int) __THROW;
-int		res_nsend (res_state, const u_char *, int, u_char *, int) __THROW;
-void		res_nclose (res_state) __THROW;
+int		res_ninit __P((res_state));
+int		res_nisourserver __P((const res_state,
+				      const struct sockaddr_in *));
+void		fp_resstat __P((const res_state, FILE *));
+void		res_npquery __P((const res_state, const u_char *, int, FILE *));
+const char *	res_hostalias __P((const res_state, const char *,
+				   char *, size_t));
+int		res_nquery __P((res_state,
+				const char *, int, int, u_char *, int));
+int		res_nsearch __P((res_state, const char *, int,
+				 int, u_char *, int));
+int		res_nquerydomain __P((res_state,
+				      const char *, const char *, int, int,
+				      u_char *, int));
+int		res_nmkquery __P((res_state,
+				  int, const char *, int, int, const u_char *,
+				  int, const u_char *, u_char *, int));
+int		res_nsend __P((res_state, const u_char *, int, u_char *, int));
+void		res_nclose __P((res_state));
 __END_DECLS
 
 #endif /* !_RESOLV_H_ */