about summary refs log tree commit diff
path: root/resolv
diff options
context:
space:
mode:
Diffstat (limited to 'resolv')
-rw-r--r--resolv/Banner2
-rw-r--r--resolv/Makefile11
-rw-r--r--resolv/Versions7
-rw-r--r--resolv/arpa/nameser.h670
-rw-r--r--resolv/arpa/nameser_compat.h184
-rw-r--r--resolv/gethnamaddr.c20
-rw-r--r--resolv/ns_name.c636
-rw-r--r--resolv/ns_netint.c52
-rw-r--r--resolv/ns_parse.c194
-rw-r--r--resolv/ns_print.c818
-rw-r--r--resolv/ns_samedomain.c202
-rw-r--r--resolv/ns_ttl.c154
-rw-r--r--resolv/nsap_addr.c34
-rw-r--r--resolv/nss_dns/dns-host.c19
-rw-r--r--resolv/nss_dns/dns-network.c14
-rw-r--r--resolv/res_comp.c792
-rw-r--r--resolv/res_data.c335
-rw-r--r--resolv/res_debug.c1234
-rw-r--r--resolv/res_debug.h34
-rw-r--r--resolv/res_init.c436
-rw-r--r--resolv/res_libc.c98
-rw-r--r--resolv/res_mkquery.c81
-rw-r--r--resolv/res_query.c261
-rw-r--r--resolv/res_send.c759
-rw-r--r--resolv/resolv.h299
25 files changed, 4469 insertions, 2877 deletions
diff --git a/resolv/Banner b/resolv/Banner
index 5d1fdeb336..d05a4e3ee7 100644
--- a/resolv/Banner
+++ b/resolv/Banner
@@ -1 +1 @@
-BIND-4.9.7-REL
+BIND-8.2.2-5
diff --git a/resolv/Makefile b/resolv/Makefile
index 71a66fe0f0..c8dc54a80c 100644
--- a/resolv/Makefile
+++ b/resolv/Makefile
@@ -1,4 +1,4 @@
-# Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+# Copyright (C) 1994,95,96,97,98,1999 Free Software Foundation, Inc.
 # This file is part of the GNU C Library.
 
 # The GNU C Library is free software; you can redistribute it and/or
@@ -23,9 +23,10 @@ subdir	:= resolv
 
 headers	:= resolv.h netdb.h arpa/nameser.h sys/bitypes.h
 distribute := ../conf/portability.h mapv4v6addr.h mapv4v6hostent.h \
-	      Banner res_hconf.h
+	      Banner res_hconf.h res_debug.h
 
-routines := herror inet_addr inet_ntop inet_pton nsap_addr res_init res_hconf
+routines := herror inet_addr inet_ntop inet_pton nsap_addr res_init \
+	    res_hconf res_libc
 
 tests = tst-aton
 
@@ -35,7 +36,9 @@ extra-libs := libresolv libnss_dns
 extra-libs-others = $(extra-libs)
 libresolv-routines := gethnamaddr res_comp res_debug	\
 		      res_data res_mkquery res_query res_send		\
-		      inet_net_ntop inet_net_pton inet_neta base64
+		      inet_net_ntop inet_net_pton inet_neta base64	\
+		      ns_parse ns_name ns_netint ns_ttl ns_print	\
+		      ns_samedomain
 
 subdir-dirs = nss_dns
 vpath %.c nss_dns
diff --git a/resolv/Versions b/resolv/Versions
index 9bf6a39b6a..3448c9281b 100644
--- a/resolv/Versions
+++ b/resolv/Versions
@@ -18,6 +18,10 @@ libc {
     # r*
     res_init;
   }
+  GLIBC_2.2 {
+    # r*
+    __res_state; __res_ninit;
+  }
 }
 
 libresolv {
@@ -46,6 +50,9 @@ libresolv {
     # Needed in libnss_dns.
     __ns_name_unpack; __ns_name_ntop;
   }
+  GLIBC_2.2 {
+    __res_nmkquery; __res_nquery; __res_nquerydomain; __res_nsearch;
+    __ns_get16;
 }
 
 libnss_dns {
diff --git a/resolv/arpa/nameser.h b/resolv/arpa/nameser.h
index 8866d90897..6655f3b8d2 100644
--- a/resolv/arpa/nameser.h
+++ b/resolv/arpa/nameser.h
@@ -1,9 +1,7 @@
 /*
- * ++Copyright++ 1983, 1989, 1993
- * -
  * Copyright (c) 1983, 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:
@@ -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,320 +25,524 @@
  * 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.
+ */
+
+/*
+ * 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.
- * -
- * Portions Copyright (c) 1995 by International Business Machines, Inc.
- *
- * International Business Machines, Inc. (hereinafter called IBM) grants
- * permission under its copyrights to use, copy, modify, and distribute this
- * Software with or without fee, provided that the above copyright notice and
- * all paragraphs of this notice appear in all copies, and that the name of IBM
- * not be used in connection with the marketing of any product incorporating
- * the Software or modifications thereof, without specific, written prior
- * permission.
- *
- * To the extent it has a right to do so, IBM grants an immunity from suit
- * under its patents, if any, for the use, sale or manufacture of products to
- * the extent that such products are used for performing Domain Name System
- * dynamic updates in TCP/IP networks by means of the Software.  No immunity is
- * granted for any product per se or for any other function of any product.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
- * PARTICULAR PURPOSE.  IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL,
- * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING
- * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN
- * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
- * --Copyright--
  */
 
 /*
- *      @(#)nameser.h	8.1 (Berkeley) 6/2/93
  *	$Id$
  */
 
-#ifndef _ARPA_NAMESER_H
-#define	_ARPA_NAMESER_H 1
+#ifndef _ARPA_NAMESER_H_
+#define _ARPA_NAMESER_H_
+
+#define BIND_4_COMPAT
 
 #include <features.h>
 #include <sys/param.h>
 #include <sys/types.h>
 
 /*
- * revision information.  this is the release date in YYYYMMDD format.
- * it can change every day so the right thing to do with it is use it
- * in preprocessor commands such as "#if (__BIND > 19931104)".  do not
- * compare for equality; rather, use it to determine whether your resolver
- * is new enough to contain a certain feature.
+ * Revision information.  This is the release date in YYYYMMDD format.
+ * It can change every day so the right thing to do with it is use it
+ * in preprocessor commands such as "#if (__NAMESER > 19931104)".  Do not
+ * compare for equality; rather, use it to determine whether your libbind.a
+ * contains a new enough lib/nameser/ to support the feature you need.
  */
 
-#define __BIND		19960801	/* interface version stamp */
+#define __NAMESER	19991006	/* New interface version stamp. */
 
 /*
- * Define constants based on rfc883
+ * Define constants based on RFC 883, RFC 1034, RFC 1035
  */
-#define PACKETSZ	512		/* maximum packet size */
-#define MAXDNAME	1025		/* maximum domain name */
-#define MAXCDNAME	255		/* maximum compressed domain name */
-#define MAXLABEL	63		/* maximum length of domain label */
-#define HFIXEDSZ	12		/* #/bytes of fixed data in header */
-#define QFIXEDSZ	4		/* #/bytes of fixed data in query */
-#define RRFIXEDSZ	10		/* #/bytes of fixed data in r record */
-#define INT32SZ		4		/* for systems without 32-bit ints */
-#define INT16SZ		2		/* for systems without 16-bit ints */
-#define INADDRSZ	4		/* IPv4 T_A */
-#define IN6ADDRSZ	16		/* IPv6 T_AAAA */
+#define NS_PACKETSZ	512	/* maximum packet size */
+#define NS_MAXDNAME	1025	/* maximum domain name */
+#define NS_MAXCDNAME	255	/* maximum compressed domain name */
+#define NS_MAXLABEL	63	/* maximum length of domain label */
+#define NS_HFIXEDSZ	12	/* #/bytes of fixed data in header */
+#define NS_QFIXEDSZ	4	/* #/bytes of fixed data in query */
+#define NS_RRFIXEDSZ	10	/* #/bytes of fixed data in r record */
+#define NS_INT32SZ	4	/* #/bytes of data in a u_int32_t */
+#define NS_INT16SZ	2	/* #/bytes of data in a u_int16_t */
+#define NS_INT8SZ	1	/* #/bytes of data in a u_int8_t */
+#define NS_INADDRSZ	4	/* IPv4 T_A */
+#define NS_IN6ADDRSZ	16	/* IPv6 T_AAAA */
+#define NS_CMPRSFLGS	0xc0	/* Flag bits indicating name compression. */
+#define NS_DEFAULTPORT	53	/* For both TCP and UDP. */
 
 /*
- * Internet nameserver port number
+ * These can be expanded with synonyms, just keep ns_parse.c:ns_parserecord()
+ * in synch with it.
  */
-#define NAMESERVER_PORT	53
+typedef enum __ns_sect {
+	ns_s_qd = 0,		/* Query: Question. */
+	ns_s_zn = 0,		/* Update: Zone. */
+	ns_s_an = 1,		/* Query: Answer. */
+	ns_s_pr = 1,		/* Update: Prerequisites. */
+	ns_s_ns = 2,		/* Query: Name servers. */
+	ns_s_ud = 2,		/* Update: Update. */
+	ns_s_ar = 3,		/* Query|Update: Additional records. */
+	ns_s_max = 4
+} ns_sect;
 
 /*
- * Currently defined opcodes
+ * This is a message handle.  It is caller allocated and has no dynamic data.
+ * This structure is intended to be opaque to all but ns_parse.c, thus the
+ * leading _'s on the member names.  Use the accessor functions, not the _'s.
  */
-#define QUERY		0x0		/* standard query */
-#define IQUERY		0x1		/* inverse query */
-#define STATUS		0x2		/* nameserver status query */
-/*#define xxx		0x3*/		/* 0x3 reserved */
-#define NS_NOTIFY_OP	0x4		/* notify secondary of SOA change */
+typedef struct __ns_msg {
+	const u_char	*_msg, *_eom;
+	u_int16_t	_id, _flags, _counts[ns_s_max];
+	const u_char	*_sections[ns_s_max];
+	ns_sect		_sect;
+	int		_rrnum;
+	const u_char	*_ptr;
+} ns_msg;
+
+/* Private data structure - do not use from outside library. */
+struct _ns_flagdata {  int mask, shift;  };
+extern struct _ns_flagdata _ns_flagdata[];
+
+/* Accessor macros - this is part of the public interface. */
+#define ns_msg_getflag(handle, flag) ( \
+			((handle)._flags & _ns_flagdata[flag].mask) \
+			 >> _ns_flagdata[flag].shift \
+			)
+#define ns_msg_id(handle) ((handle)._id + 0)
+#define ns_msg_base(handle) ((handle)._msg + 0)
+#define ns_msg_end(handle) ((handle)._eom + 0)
+#define ns_msg_size(handle) ((handle)._eom - (handle)._msg)
+#define ns_msg_count(handle, section) ((handle)._counts[section] + 0)
+
 /*
- * Currently defined response codes
+ * This is a parsed record.  It is caller allocated and has no dynamic data.
  */
-#define NOERROR		0		/* no error */
-#define FORMERR		1		/* format error */
-#define SERVFAIL	2		/* server failure */
-#define NXDOMAIN	3		/* non existent domain */
-#define NOTIMP		4		/* not implemented */
-#define REFUSED		5		/* query refused */
+typedef	struct __ns_rr {
+	char		name[NS_MAXDNAME];
+	u_int16_t	type;
+	u_int16_t	rr_class;
+	u_int32_t	ttl;
+	u_int16_t	rdlength;
+	const u_char *	rdata;
+} ns_rr;
+
+/* Accessor macros - this is part of the public interface. */
+#define ns_rr_name(rr)	(((rr).name[0] != '\0') ? (rr).name : ".")
+#define ns_rr_type(rr)	((ns_type)((rr).type + 0))
+#define ns_rr_class(rr)	((ns_class)((rr).rr_class + 0))
+#define ns_rr_ttl(rr)	((rr).ttl + 0)
+#define ns_rr_rdlen(rr)	((rr).rdlength + 0)
+#define ns_rr_rdata(rr)	((rr).rdata + 0)
 
 /*
- * Type values for resources and queries
+ * These don't have to be in the same order as in the packet flags word,
+ * and they can even overlap in some cases, but they will need to be kept
+ * in synch with ns_parse.c:ns_flagdata[].
  */
-#define T_A		1		/* host address */
-#define T_NS		2		/* authoritative server */
-#define T_MD		3		/* mail destination */
-#define T_MF		4		/* mail forwarder */
-#define T_CNAME		5		/* canonical name */
-#define T_SOA		6		/* start of authority zone */
-#define T_MB		7		/* mailbox domain name */
-#define T_MG		8		/* mail group member */
-#define T_MR		9		/* mail rename name */
-#define T_NULL		10		/* null resource record */
-#define T_WKS		11		/* well known service */
-#define T_PTR		12		/* domain name pointer */
-#define T_HINFO		13		/* host information */
-#define T_MINFO		14		/* mailbox information */
-#define T_MX		15		/* mail routing information */
-#define T_TXT		16		/* text strings */
-#define T_RP		17		/* responsible person */
-#define T_AFSDB		18		/* AFS cell database */
-#define T_X25		19		/* X_25 calling address */
-#define T_ISDN		20		/* ISDN calling address */
-#define T_RT		21		/* router */
-#define T_NSAP		22		/* NSAP address */
-#define T_NSAP_PTR	23		/* reverse NSAP lookup (deprecated) */
-#define T_SIG		24		/* security signature */
-#define T_KEY		25		/* security key */
-#define T_PX		26		/* X.400 mail mapping */
-#define T_GPOS		27		/* geographical position (withdrawn) */
-#define T_AAAA		28		/* IP6 Address */
-#define T_LOC		29		/* Location Information */
-#define T_NXT		30		/* Next Valid Name in Zone */
-#define T_EID		31		/* Endpoint identifier */
-#define T_NIMLOC	32		/* Nimrod locator */
-#define T_SRV		33		/* Server selection */
-#define T_ATMA		34		/* ATM Address */
-#define T_NAPTR		35		/* Naming Authority PoinTeR */
-	/* non standard */
-#define T_UINFO		100		/* user (finger) information */
-#define T_UID		101		/* user ID */
-#define T_GID		102		/* group ID */
-#define T_UNSPEC	103		/* Unspecified format (binary data) */
-	/* Query type values which do not appear in resource records */
-#define	T_IXFR		251		/* incremental zone transfer */
-#define T_AXFR		252		/* transfer zone of authority */
-#define T_MAILB		253		/* transfer mailbox records */
-#define T_MAILA		254		/* transfer mail agent records */
-#define T_ANY		255		/* wildcard match */
+typedef enum __ns_flag {
+	ns_f_qr,		/* Question/Response. */
+	ns_f_opcode,		/* Operation code. */
+	ns_f_aa,		/* Authoritative Answer. */
+	ns_f_tc,		/* Truncation occurred. */
+	ns_f_rd,		/* Recursion Desired. */
+	ns_f_ra,		/* Recursion Available. */
+	ns_f_z,			/* MBZ. */
+	ns_f_ad,		/* Authentic Data (DNSSEC). */
+	ns_f_cd,		/* Checking Disabled (DNSSEC). */
+	ns_f_rcode,		/* Response code. */
+	ns_f_max
+} ns_flag;
 
 /*
- * Values for class field
+ * Currently defined opcodes.
  */
-
-#define C_IN		1		/* the arpa internet */
-#define C_CHAOS		3		/* for chaos net (MIT) */
-#define C_HS		4		/* for Hesiod name server (MIT) (XXX) */
-	/* Query class values which do not appear in resource records */
-#define C_ANY		255		/* wildcard match */
+typedef enum __ns_opcode {
+	ns_o_query = 0,		/* Standard query. */
+	ns_o_iquery = 1,	/* Inverse query (deprecated/unsupported). */
+	ns_o_status = 2,	/* Name server status query (unsupported). */
+				/* Opcode 3 is undefined/reserved. */
+	ns_o_notify = 4,	/* Zone change notification. */
+	ns_o_update = 5,	/* Zone update message. */
+	ns_o_max = 6
+} ns_opcode;
 
 /*
- * Flags field of the KEY RR rdata
+ * Currently defined response codes.
  */
-#define	KEYFLAG_TYPEMASK	0xC000	/* Mask for "type" bits */
-#define	KEYFLAG_TYPE_AUTH_CONF	0x0000	/* Key usable for both */
-#define	KEYFLAG_TYPE_CONF_ONLY	0x8000	/* Key usable for confidentiality */
-#define	KEYFLAG_TYPE_AUTH_ONLY	0x4000	/* Key usable for authentication */
-#define	KEYFLAG_TYPE_NO_KEY	0xC000	/* No key usable for either; no key */
-/* The type bits can also be interpreted independently, as single bits: */
-#define	KEYFLAG_NO_AUTH		0x8000	/* Key not usable for authentication */
-#define	KEYFLAG_NO_CONF		0x4000	/* Key not usable for confidentiality */
-
-#define	KEYFLAG_EXPERIMENTAL	0x2000	/* Security is *mandatory* if bit=0 */
-#define	KEYFLAG_RESERVED3	0x1000  /* reserved - must be zero */
-#define	KEYFLAG_RESERVED4	0x0800  /* reserved - must be zero */
-#define	KEYFLAG_USERACCOUNT	0x0400	/* key is assoc. with a user acct */
-#define	KEYFLAG_ENTITY		0x0200	/* key is assoc. with entity eg host */
-#define	KEYFLAG_ZONEKEY		0x0100	/* key is zone key for the zone named */
-#define	KEYFLAG_IPSEC		0x0080  /* key is for IPSEC use (host or user)*/
-#define	KEYFLAG_EMAIL		0x0040  /* key is for email (MIME security) */
-#define	KEYFLAG_RESERVED10	0x0020  /* reserved - must be zero */
-#define	KEYFLAG_RESERVED11	0x0010  /* reserved - must be zero */
-#define	KEYFLAG_SIGNATORYMASK	0x000F	/* key can sign DNS RR's of same name */
-
-#define  KEYFLAG_RESERVED_BITMASK ( KEYFLAG_RESERVED3 | \
-				    KEYFLAG_RESERVED4 | \
-				    KEYFLAG_RESERVED10| KEYFLAG_RESERVED11)
+typedef	enum __ns_rcode {
+	ns_r_noerror = 0,	/* No error occurred. */
+	ns_r_formerr = 1,	/* Format error. */
+	ns_r_servfail = 2,	/* Server failure. */
+	ns_r_nxdomain = 3,	/* Name error. */
+	ns_r_notimpl = 4,	/* Unimplemented. */
+	ns_r_refused = 5,	/* Operation refused. */
+	/* these are for BIND_UPDATE */
+	ns_r_yxdomain = 6,	/* Name exists */
+	ns_r_yxrrset = 7,	/* RRset exists */
+	ns_r_nxrrset = 8,	/* RRset does not exist */
+	ns_r_notauth = 9,	/* Not authoritative for zone */
+	ns_r_notzone = 10,	/* Zone of record different from zone section */
+	ns_r_max = 11,
+	/* The following are TSIG extended errors */
+	ns_r_badsig = 16,
+	ns_r_badkey = 17,
+	ns_r_badtime = 18
+} ns_rcode;
 
-/* The Algorithm field of the KEY and SIG RR's is an integer, {1..254} */
-#define	ALGORITHM_MD5RSA	1	/* MD5 with RSA */
-#define	ALGORITHM_EXPIRE_ONLY	253	/* No alg, no security */
-#define	ALGORITHM_PRIVATE_OID	254	/* Key begins with OID indicating alg */
+/* BIND_UPDATE */
+typedef enum __ns_update_operation {
+	ns_uop_delete = 0,
+	ns_uop_add = 1,
+	ns_uop_max = 2
+} ns_update_operation;
 
-/* Signatures */
-					/* Size of a mod or exp in bits */
-#define	MIN_MD5RSA_KEY_PART_BITS	 512
-#define	MAX_MD5RSA_KEY_PART_BITS	2552
-					/* Total of binary mod and exp, bytes */
-#define	MAX_MD5RSA_KEY_BYTES		((MAX_MD5RSA_KEY_PART_BITS+7/8)*2+3)
-					/* Max length of text sig block */
-#define	MAX_KEY_BASE64			(((MAX_MD5RSA_KEY_BYTES+2)/3)*4)
+/*
+ * This structure is used for TSIG authenticated messages
+ */
+struct ns_tsig_key {
+        char name[NS_MAXDNAME], alg[NS_MAXDNAME];
+        unsigned char *data;
+        int len;
+};
+typedef struct ns_tsig_key ns_tsig_key;
 
 /*
- * Status return codes for T_UNSPEC conversion routines
+ * This structure is used for TSIG authenticated TCP messages
  */
-#define CONV_SUCCESS	0
-#define CONV_OVERFLOW	(-1)
-#define CONV_BADFMT	(-2)
-#define CONV_BADCKSUM	(-3)
-#define CONV_BADBUFLEN	(-4)
+struct ns_tcp_tsig_state {
+	int counter;
+	struct dst_key *key;
+	void *ctx;
+	unsigned char sig[NS_PACKETSZ];
+	int siglen;
+};
+typedef struct ns_tcp_tsig_state ns_tcp_tsig_state;
 
-/* glibc always has byte order info in <endian.h> */
-#include <endian.h>
+#define NS_TSIG_FUDGE 300
+#define NS_TSIG_TCP_COUNT 100
+#define NS_TSIG_ALG_HMAC_MD5 "HMAC-MD5.SIG-ALG.REG.INT"
 
-__BEGIN_DECLS
+#define NS_TSIG_ERROR_NO_TSIG -10
+#define NS_TSIG_ERROR_NO_SPACE -11
+#define NS_TSIG_ERROR_FORMERR -12
 
 /*
- * Structure for query header.  The order of the fields is machine- and
- * compiler-dependent, depending on the byte/bit order and the layout
- * of bit fields.  We use bit fields only in int variables, as this
- * is all ANSI requires.  This requires a somewhat confusing rearrangement.
+ * Currently defined type values for resources and queries.
  */
+typedef enum __ns_type {
+	ns_t_invalid = 0,	/* Cookie. */
+	ns_t_a = 1,		/* Host address. */
+	ns_t_ns = 2,		/* Authoritative server. */
+	ns_t_md = 3,		/* Mail destination. */
+	ns_t_mf = 4,		/* Mail forwarder. */
+	ns_t_cname = 5,		/* Canonical name. */
+	ns_t_soa = 6,		/* Start of authority zone. */
+	ns_t_mb = 7,		/* Mailbox domain name. */
+	ns_t_mg = 8,		/* Mail group member. */
+	ns_t_mr = 9,		/* Mail rename name. */
+	ns_t_null = 10,		/* Null resource record. */
+	ns_t_wks = 11,		/* Well known service. */
+	ns_t_ptr = 12,		/* Domain name pointer. */
+	ns_t_hinfo = 13,	/* Host information. */
+	ns_t_minfo = 14,	/* Mailbox information. */
+	ns_t_mx = 15,		/* Mail routing information. */
+	ns_t_txt = 16,		/* Text strings. */
+	ns_t_rp = 17,		/* Responsible person. */
+	ns_t_afsdb = 18,	/* AFS cell database. */
+	ns_t_x25 = 19,		/* X_25 calling address. */
+	ns_t_isdn = 20,		/* ISDN calling address. */
+	ns_t_rt = 21,		/* Router. */
+	ns_t_nsap = 22,		/* NSAP address. */
+	ns_t_nsap_ptr = 23,	/* Reverse NSAP lookup (deprecated). */
+	ns_t_sig = 24,		/* Security signature. */
+	ns_t_key = 25,		/* Security key. */
+	ns_t_px = 26,		/* X.400 mail mapping. */
+	ns_t_gpos = 27,		/* Geographical position (withdrawn). */
+	ns_t_aaaa = 28,		/* Ip6 Address. */
+	ns_t_loc = 29,		/* Location Information. */
+	ns_t_nxt = 30,		/* Next domain (security). */
+	ns_t_eid = 31,		/* Endpoint identifier. */
+	ns_t_nimloc = 32,	/* Nimrod Locator. */
+	ns_t_srv = 33,		/* Server Selection. */
+	ns_t_atma = 34,		/* ATM Address */
+	ns_t_naptr = 35,	/* Naming Authority PoinTeR */
+	ns_t_kx = 36,		/* Key Exchange */
+	ns_t_cert = 37,		/* Certification record */
+	ns_t_a6 = 38,		/* IPv6 address (deprecates AAAA) */
+	ns_t_dname = 39,	/* Non-terminal DNAME (for IPv6) */
+	ns_t_sink = 40,		/* Kitchen sink (experimentatl) */
+	ns_t_opt = 41,		/* EDNS0 option (meta-RR) */
+	ns_t_tsig = 250,	/* Transaction signature. */
+	ns_t_ixfr = 251,	/* Incremental zone transfer. */
+	ns_t_axfr = 252,	/* Transfer zone of authority. */
+	ns_t_mailb = 253,	/* Transfer mailbox records. */
+	ns_t_maila = 254,	/* Transfer mail agent records. */
+	ns_t_any = 255,		/* Wildcard match. */
+	ns_t_zxfr = 256,	/* BIND-specific, nonstandard. */
+	ns_t_max = 65536
+} ns_type;
 
-typedef struct {
-	unsigned	id :16;		/* query identification number */
-#if BYTE_ORDER == BIG_ENDIAN
-			/* fields in third byte */
-	unsigned	qr: 1;		/* response flag */
-	unsigned	opcode: 4;	/* purpose of message */
-	unsigned	aa: 1;		/* authoritative answer */
-	unsigned	tc: 1;		/* truncated message */
-	unsigned	rd: 1;		/* recursion desired */
-			/* fields in fourth byte */
-	unsigned	ra: 1;		/* recursion available */
-	unsigned	unused :1;	/* unused bits (MBZ as of 4.9.3a3) */
-	unsigned	ad: 1;		/* authentic data from named */
-	unsigned	cd: 1;		/* checking disabled by resolver */
-	unsigned	rcode :4;	/* response code */
-#endif
-#if BYTE_ORDER == LITTLE_ENDIAN || BYTE_ORDER == PDP_ENDIAN
-			/* fields in third byte */
-	unsigned	rd :1;		/* recursion desired */
-	unsigned	tc :1;		/* truncated message */
-	unsigned	aa :1;		/* authoritative answer */
-	unsigned	opcode :4;	/* purpose of message */
-	unsigned	qr :1;		/* response flag */
-			/* fields in fourth byte */
-	unsigned	rcode :4;	/* response code */
-	unsigned	cd: 1;		/* checking disabled by resolver */
-	unsigned	ad: 1;		/* authentic data from named */
-	unsigned	unused :1;	/* unused bits (MBZ as of 4.9.3a3) */
-	unsigned	ra :1;		/* recursion available */
-#endif
-			/* remaining bytes */
-	unsigned	qdcount :16;	/* number of question entries */
-	unsigned	ancount :16;	/* number of answer entries */
-	unsigned	nscount :16;	/* number of authority entries */
-	unsigned	arcount :16;	/* number of resource entries */
-} HEADER;
+/* Exclusively a QTYPE? (not also an RTYPE) */
+#define	ns_t_qt_p(t) (ns_t_xfr_p(t) || (t) == ns_t_any || \
+		      (t) == ns_t_mailb || (t) == ns_t_maila)
+/* Some kind of meta-RR? (not a QTYPE, but also not an RTYPE) */
+#define	ns_t_mrr_p(t) ((t) == ns_t_tsig || (t) == ns_t_opt)
+/* Exclusively an RTYPE? (not also a QTYPE or a meta-RR) */
+#define ns_t_rr_p(t) (!ns_t_qt_p(t) && !ns_t_mrr_p(t))
+#define ns_t_udp_p(t) ((t) != ns_t_axfr && (t) != ns_t_zxfr)
+#define ns_t_xfr_p(t) ((t) == ns_t_axfr || (t) == ns_t_ixfr || \
+		       (t) == ns_t_zxfr)
 
 /*
- * Defines for handling compressed domain names
+ * Values for class field
  */
-#define INDIR_MASK	0xc0
+typedef enum __ns_class {
+	ns_c_invalid = 0,	/* Cookie. */
+	ns_c_in = 1,		/* Internet. */
+	ns_c_2 = 2,		/* unallocated/unsupported. */
+	ns_c_chaos = 3,		/* MIT Chaos-net. */
+	ns_c_hs = 4,		/* MIT Hesiod. */
+	/* Query class values which do not appear in resource records */
+	ns_c_none = 254,	/* for prereq. sections in update requests */
+	ns_c_any = 255,		/* Wildcard match. */
+	ns_c_max = 65536
+} ns_class;
+
+/* DNSSEC constants. */
+
+typedef enum __ns_key_types {
+	ns_kt_rsa = 1,		/* key type RSA/MD5 */
+	ns_kt_dh  = 2,		/* Diffie Hellman */
+	ns_kt_dsa = 3,		/* Digital Signature Standard (MANDATORY) */
+	ns_kt_private = 254	/* Private key type starts with OID */
+} ns_key_types;
+
+typedef enum __ns_cert_types {
+	cert_t_pkix = 1,	/* PKIX (X.509v3) */
+	cert_t_spki = 2,	/* SPKI */
+	cert_t_pgp  = 3,	/* PGP */
+	cert_t_url  = 253,	/* URL private type */
+	cert_t_oid  = 254	/* OID private type */
+} ns_cert_types;
+
+/* Flags field of the KEY RR rdata. */
+#define	NS_KEY_TYPEMASK		0xC000	/* Mask for "type" bits */
+#define	NS_KEY_TYPE_AUTH_CONF	0x0000	/* Key usable for both */
+#define	NS_KEY_TYPE_CONF_ONLY	0x8000	/* Key usable for confidentiality */
+#define	NS_KEY_TYPE_AUTH_ONLY	0x4000	/* Key usable for authentication */
+#define	NS_KEY_TYPE_NO_KEY	0xC000	/* No key usable for either; no key */
+/* The type bits can also be interpreted independently, as single bits: */
+#define	NS_KEY_NO_AUTH		0x8000	/* Key unusable for authentication */
+#define	NS_KEY_NO_CONF		0x4000	/* Key unusable for confidentiality */
+#define	NS_KEY_RESERVED2	0x2000	/* Security is *mandatory* if bit=0 */
+#define	NS_KEY_EXTENDED_FLAGS	0x1000	/* reserved - must be zero */
+#define	NS_KEY_RESERVED4	0x0800  /* reserved - must be zero */
+#define	NS_KEY_RESERVED5	0x0400  /* reserved - must be zero */
+#define	NS_KEY_NAME_TYPE	0x0300	/* these bits determine the type */
+#define	NS_KEY_NAME_USER	0x0000	/* key is assoc. with user */
+#define	NS_KEY_NAME_ENTITY	0x0200	/* key is assoc. with entity eg host */
+#define	NS_KEY_NAME_ZONE	0x0100	/* key is zone key */
+#define	NS_KEY_NAME_RESERVED	0x0300	/* reserved meaning */
+#define	NS_KEY_RESERVED8	0x0080  /* reserved - must be zero */
+#define	NS_KEY_RESERVED9	0x0040  /* reserved - must be zero */
+#define	NS_KEY_RESERVED10	0x0020  /* reserved - must be zero */
+#define	NS_KEY_RESERVED11	0x0010  /* reserved - must be zero */
+#define	NS_KEY_SIGNATORYMASK	0x000F	/* key can sign RR's of same name */
+#define	NS_KEY_RESERVED_BITMASK ( NS_KEY_RESERVED2 | \
+				  NS_KEY_RESERVED4 | \
+				  NS_KEY_RESERVED5 | \
+				  NS_KEY_RESERVED8 | \
+				  NS_KEY_RESERVED9 | \
+				  NS_KEY_RESERVED10 | \
+				  NS_KEY_RESERVED11 )
+#define NS_KEY_RESERVED_BITMASK2 0xFFFF /* no bits defined here */
+
+/* The Algorithm field of the KEY and SIG RR's is an integer, {1..254} */
+#define	NS_ALG_MD5RSA		1	/* MD5 with RSA */
+#define	NS_ALG_DH               2	/* Diffie Hellman KEY */
+#define	NS_ALG_DSA              3	/* DSA KEY */
+#define	NS_ALG_DSS              NS_ALG_DSA
+#define	NS_ALG_EXPIRE_ONLY	253	/* No alg, no security */
+#define	NS_ALG_PRIVATE_OID	254	/* Key begins with OID giving alg */
+
+/* Protocol values  */
+/* value 0 is reserved */
+#define NS_KEY_PROT_TLS         1
+#define NS_KEY_PROT_EMAIL       2
+#define NS_KEY_PROT_DNSSEC      3
+#define NS_KEY_PROT_IPSEC       4
+#define NS_KEY_PROT_ANY		255
 
-extern	u_int16_t	_getshort __P((const u_char *));
-extern	u_int32_t	_getlong __P((const u_char *));
+/* Signatures */
+#define	NS_MD5RSA_MIN_BITS	 512	/* Size of a mod or exp in bits */
+#define	NS_MD5RSA_MAX_BITS	2552
+	/* Total of binary mod and exp */
+#define	NS_MD5RSA_MAX_BYTES	((NS_MD5RSA_MAX_BITS+7/8)*2+3)
+	/* Max length of text sig block */
+#define	NS_MD5RSA_MAX_BASE64	(((NS_MD5RSA_MAX_BYTES+2)/3)*4)
+#define NS_MD5RSA_MIN_SIZE	((NS_MD5RSA_MIN_BITS+7)/8)
+#define NS_MD5RSA_MAX_SIZE	((NS_MD5RSA_MAX_BITS+7)/8)
+
+#define NS_DSA_SIG_SIZE         41
+#define NS_DSA_MIN_SIZE         213
+#define NS_DSA_MAX_BYTES        405
+
+/* Offsets into SIG record rdata to find various values */
+#define	NS_SIG_TYPE	0	/* Type flags */
+#define	NS_SIG_ALG	2	/* Algorithm */
+#define	NS_SIG_LABELS	3	/* How many labels in name */
+#define	NS_SIG_OTTL	4	/* Original TTL */
+#define	NS_SIG_EXPIR	8	/* Expiration time */
+#define	NS_SIG_SIGNED	12	/* Signature time */
+#define	NS_SIG_FOOT	16	/* Key footprint */
+#define	NS_SIG_SIGNER	18	/* Domain name of who signed it */
+
+/* How RR types are represented as bit-flags in NXT records */
+#define	NS_NXT_BITS 8
+#define	NS_NXT_BIT_SET(  n,p) (p[(n)/NS_NXT_BITS] |=  (0x80>>((n)%NS_NXT_BITS)))
+#define	NS_NXT_BIT_CLEAR(n,p) (p[(n)/NS_NXT_BITS] &= ~(0x80>>((n)%NS_NXT_BITS)))
+#define	NS_NXT_BIT_ISSET(n,p) (p[(n)/NS_NXT_BITS] &   (0x80>>((n)%NS_NXT_BITS)))
+#define NS_NXT_MAX 127
 
 /*
  * Inline versions of get/put short/long.  Pointer is advanced.
- *
- * These macros demonstrate the property of C whereby it can be
- * portable or it can be elegant but rarely both.
  */
-#define GETSHORT(s, cp) { \
+#define NS_GET16(s, cp) do { \
 	register u_char *t_cp = (u_char *)(cp); \
 	(s) = ((u_int16_t)t_cp[0] << 8) \
 	    | ((u_int16_t)t_cp[1]) \
 	    ; \
-	(cp) += INT16SZ; \
-}
+	(cp) += NS_INT16SZ; \
+} while (0)
 
-#define GETLONG(l, cp) { \
+#define NS_GET32(l, cp) do { \
 	register u_char *t_cp = (u_char *)(cp); \
 	(l) = ((u_int32_t)t_cp[0] << 24) \
 	    | ((u_int32_t)t_cp[1] << 16) \
 	    | ((u_int32_t)t_cp[2] << 8) \
 	    | ((u_int32_t)t_cp[3]) \
 	    ; \
-	(cp) += INT32SZ; \
-}
+	(cp) += NS_INT32SZ; \
+} while (0)
 
-#define PUTSHORT(s, cp) { \
+#define NS_PUT16(s, cp) do { \
 	register u_int16_t t_s = (u_int16_t)(s); \
 	register u_char *t_cp = (u_char *)(cp); \
 	*t_cp++ = t_s >> 8; \
 	*t_cp   = t_s; \
-	(cp) += INT16SZ; \
-}
+	(cp) += NS_INT16SZ; \
+} while (0)
 
-#define PUTLONG(l, cp) { \
+#define NS_PUT32(l, cp) do { \
 	register u_int32_t t_l = (u_int32_t)(l); \
 	register u_char *t_cp = (u_char *)(cp); \
 	*t_cp++ = t_l >> 24; \
 	*t_cp++ = t_l >> 16; \
 	*t_cp++ = t_l >> 8; \
 	*t_cp   = t_l; \
-	(cp) += INT32SZ; \
-}
+	(cp) += NS_INT32SZ; \
+} while (0)
 
+/*
+ * ANSI C identifier hiding for bind's lib/nameser.
+ */
+#define ns_get16		__ns_get16
+#define ns_get32		__ns_get32
+#define ns_put16		__ns_put16
+#define ns_put32		__ns_put32
+#define ns_initparse		__ns_initparse
+#define ns_skiprr		__ns_skiprr
+#define ns_parserr		__ns_parserr
+#define	ns_sprintrr		__ns_sprintrr
+#define	ns_sprintrrf		__ns_sprintrrf
+#define	ns_format_ttl		__ns_format_ttl
+#define	ns_parse_ttl		__ns_parse_ttl
+#define ns_datetosecs		__ns_datetosecs
+#define	ns_name_ntol		__ns_name_ntol
+#define	ns_name_ntop		__ns_name_ntop
+#define	ns_name_pton		__ns_name_pton
+#define	ns_name_unpack		__ns_name_unpack
+#define	ns_name_pack		__ns_name_pack
+#define	ns_name_compress	__ns_name_compress
+#define	ns_name_uncompress	__ns_name_uncompress
+#define	ns_name_skip		__ns_name_skip
+#define	ns_sign			__ns_sign
+#define	ns_sign_tcp		__ns_sign_tcp
+#define	ns_sign_tcp_init	__ns_sign_tcp_init
+#define ns_find_tsig		__ns_find_tsig
+#define	ns_verify		__ns_verify
+#define	ns_verify_tcp		__ns_verify_tcp
+#define	ns_verify_tcp_init	__ns_verify_tcp_init
+#define	ns_samedomain		__ns_samedomain
+#define	ns_subdomain		__ns_subdomain
+#define	ns_makecanon		__ns_makecanon
+#define	ns_samename		__ns_samename
+
+__BEGIN_DECLS
+u_int		ns_get16 __P((const u_char *));
+u_long		ns_get32 __P((const u_char *));
+void		ns_put16 __P((u_int, u_char *));
+void		ns_put32 __P((u_long, u_char *));
+int		ns_initparse __P((const u_char *, int, ns_msg *));
+int		ns_skiprr __P((const u_char *, const u_char *, ns_sect, int));
+int		ns_parserr __P((ns_msg *, ns_sect, int, ns_rr *));
+int		ns_sprintrr __P((const ns_msg *, const ns_rr *,
+				 const char *, const char *, char *, size_t));
+int		ns_sprintrrf __P((const u_char *, size_t, const char *,
+				  ns_class, ns_type, u_long, const u_char *,
+				  size_t, const char *, const char *,
+				  char *, size_t));
+int		ns_format_ttl __P((u_long, char *, size_t));
+int		ns_parse_ttl __P((const char *, u_long *));
+u_int32_t	ns_datetosecs __P((const char *cp, int *errp));
+int		ns_name_ntol __P((const u_char *, u_char *, size_t));
+int		ns_name_ntop __P((const u_char *, char *, size_t));
+int		ns_name_pton __P((const char *, u_char *, size_t));
+int		ns_name_unpack __P((const u_char *, const u_char *,
+				    const u_char *, u_char *, size_t));
+int		ns_name_pack __P((const u_char *, u_char *, int,
+				  const u_char **, const u_char **));
+int		ns_name_uncompress __P((const u_char *, const u_char *,
+					const u_char *, char *, size_t));
+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 *));
+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,
+				 ns_tcp_tsig_state *, int));
+int		ns_sign_tcp_init __P((void *, const u_char *, int,
+					ns_tcp_tsig_state *));
+u_char		*ns_find_tsig __P((u_char *, u_char *));
+int		ns_verify __P((u_char *, int *, void *,
+			       const u_char *, int, u_char *, int *,
+			       time_t *, int));
+int		ns_verify_tcp __P((u_char *, int *, ns_tcp_tsig_state *, int));
+int		ns_verify_tcp_init __P((void *, const u_char *, int,
+					ns_tcp_tsig_state *));
+int		ns_samedomain __P((const char *, const char *));
+int		ns_subdomain __P((const char *, const char *));
+int		ns_makecanon __P((const char *, char *, size_t));
+int		ns_samename __P((const char *, const char *));
 __END_DECLS
 
-#endif /* arpa/nameser.h */
+#ifdef BIND_4_COMPAT
+#include <arpa/nameser_compat.h>
+#endif
+
+#endif /* !_ARPA_NAMESER_H_ */
diff --git a/resolv/arpa/nameser_compat.h b/resolv/arpa/nameser_compat.h
new file mode 100644
index 0000000000..f67f5b3a67
--- /dev/null
+++ b/resolv/arpa/nameser_compat.h
@@ -0,0 +1,184 @@
+/* Copyright (c) 1983, 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:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ *      from nameser.h	8.1 (Berkeley) 6/2/93
+ *	$Id$
+ */
+
+#ifndef _ARPA_NAMESER_COMPAT_
+#define	_ARPA_NAMESER_COMPAT_
+
+#define	__BIND		19950621	/* (DEAD) interface version stamp. */
+
+/* glibc always has byte order info in <endian.h> */
+#include <endian.h>
+
+/*
+ * Structure for query header.  The order of the fields is machine- and
+ * compiler-dependent, depending on the byte/bit order and the layout
+ * of bit fields.  We use bit fields only in int variables, as this
+ * is all ANSI requires.  This requires a somewhat confusing rearrangement.
+ */
+
+typedef struct {
+	unsigned	id :16;		/* query identification number */
+#if BYTE_ORDER == BIG_ENDIAN
+			/* fields in third byte */
+	unsigned	qr: 1;		/* response flag */
+	unsigned	opcode: 4;	/* purpose of message */
+	unsigned	aa: 1;		/* authoritive answer */
+	unsigned	tc: 1;		/* truncated message */
+	unsigned	rd: 1;		/* recursion desired */
+			/* fields in fourth byte */
+	unsigned	ra: 1;		/* recursion available */
+	unsigned	unused :1;	/* unused bits (MBZ as of 4.9.3a3) */
+	unsigned	ad: 1;		/* authentic data from named */
+	unsigned	cd: 1;		/* checking disabled by resolver */
+	unsigned	rcode :4;	/* response code */
+#endif
+#if BYTE_ORDER == LITTLE_ENDIAN || BYTE_ORDER == PDP_ENDIAN
+			/* fields in third byte */
+	unsigned	rd :1;		/* recursion desired */
+	unsigned	tc :1;		/* truncated message */
+	unsigned	aa :1;		/* authoritive answer */
+	unsigned	opcode :4;	/* purpose of message */
+	unsigned	qr :1;		/* response flag */
+			/* fields in fourth byte */
+	unsigned	rcode :4;	/* response code */
+	unsigned	cd: 1;		/* checking disabled by resolver */
+	unsigned	ad: 1;		/* authentic data from named */
+	unsigned	unused :1;	/* unused bits (MBZ as of 4.9.3a3) */
+	unsigned	ra :1;		/* recursion available */
+#endif
+			/* remaining bytes */
+	unsigned	qdcount :16;	/* number of question entries */
+	unsigned	ancount :16;	/* number of answer entries */
+	unsigned	nscount :16;	/* number of authority entries */
+	unsigned	arcount :16;	/* number of resource entries */
+} HEADER;
+
+#define PACKETSZ	NS_PACKETSZ
+#define MAXDNAME	NS_MAXDNAME
+#define MAXCDNAME	NS_MAXCDNAME
+#define MAXLABEL	NS_MAXLABEL
+#define	HFIXEDSZ	NS_HFIXEDSZ
+#define QFIXEDSZ	NS_QFIXEDSZ
+#define RRFIXEDSZ	NS_RRFIXEDSZ
+#define	INT32SZ		NS_INT32SZ
+#define	INT16SZ		NS_INT16SZ
+#define	INADDRSZ	NS_INADDRSZ
+#define	IN6ADDRSZ	NS_IN6ADDRSZ
+#define	INDIR_MASK	NS_CMPRSFLGS
+#define NAMESERVER_PORT	NS_DEFAULTPORT
+
+#define S_ZONE		ns_s_zn
+#define S_PREREQ	ns_s_pr
+#define S_UPDATE	ns_s_ud
+#define S_ADDT		ns_s_ar
+
+#define QUERY		ns_o_query
+#define IQUERY		ns_o_iquery
+#define STATUS		ns_o_status
+#define	NS_NOTIFY_OP	ns_o_notify
+#define	NS_UPDATE_OP	ns_o_update
+
+#define NOERROR		ns_r_noerror
+#define FORMERR		ns_r_formerr
+#define SERVFAIL	ns_r_servfail
+#define NXDOMAIN	ns_r_nxdomain
+#define NOTIMP		ns_r_notimpl
+#define REFUSED		ns_r_refused
+#define YXDOMAIN	ns_r_yxdomain
+#define YXRRSET		ns_r_yxrrset
+#define NXRRSET		ns_r_nxrrset
+#define NOTAUTH		ns_r_notauth
+#define NOTZONE		ns_r_notzone
+/*#define BADSIG		ns_r_badsig*/
+/*#define BADKEY		ns_r_badkey*/
+/*#define BADTIME		ns_r_badtime*/
+
+
+#define DELETE		ns_uop_delete
+#define ADD		ns_uop_add
+
+#define T_A		ns_t_a
+#define T_NS		ns_t_ns
+#define T_MD		ns_t_md
+#define T_MF		ns_t_mf
+#define T_CNAME		ns_t_cname
+#define T_SOA		ns_t_soa
+#define T_MB		ns_t_mb
+#define T_MG		ns_t_mg
+#define T_MR		ns_t_mr
+#define T_NULL		ns_t_null
+#define T_WKS		ns_t_wks
+#define T_PTR		ns_t_ptr
+#define T_HINFO		ns_t_hinfo
+#define T_MINFO		ns_t_minfo
+#define T_MX		ns_t_mx
+#define T_TXT		ns_t_txt
+#define	T_RP		ns_t_rp
+#define T_AFSDB		ns_t_afsdb
+#define T_X25		ns_t_x25
+#define T_ISDN		ns_t_isdn
+#define T_RT		ns_t_rt
+#define T_NSAP		ns_t_nsap
+#define T_NSAP_PTR	ns_t_nsap_ptr
+#define	T_SIG		ns_t_sig
+#define	T_KEY		ns_t_key
+#define	T_PX		ns_t_px
+#define	T_GPOS		ns_t_gpos
+#define	T_AAAA		ns_t_aaaa
+#define	T_LOC		ns_t_loc
+#define	T_NXT		ns_t_nxt
+#define	T_EID		ns_t_eid
+#define	T_NIMLOC	ns_t_nimloc
+#define	T_SRV		ns_t_srv
+#define T_ATMA		ns_t_atma
+#define T_NAPTR		ns_t_naptr
+#define	T_TSIG		ns_t_tsig
+#define	T_IXFR		ns_t_ixfr
+#define T_AXFR		ns_t_axfr
+#define T_MAILB		ns_t_mailb
+#define T_MAILA		ns_t_maila
+#define T_ANY		ns_t_any
+
+#define C_IN		ns_c_in
+#define C_CHAOS		ns_c_chaos
+#define C_HS		ns_c_hs
+/* BIND_UPDATE */
+#define C_NONE		ns_c_none
+#define C_ANY		ns_c_any
+
+#define	GETSHORT		NS_GET16
+#define	GETLONG			NS_GET32
+#define	PUTSHORT		NS_PUT16
+#define	PUTLONG			NS_PUT32
+
+#endif /* _ARPA_NAMESER_COMPAT_ */
diff --git a/resolv/gethnamaddr.c b/resolv/gethnamaddr.c
index 7f1b742c4d..5808d92d7b 100644
--- a/resolv/gethnamaddr.c
+++ b/resolv/gethnamaddr.c
@@ -259,11 +259,11 @@ getanswer(answer, anslen, qname, qtype)
 		}
 		cp += n;			/* name */
 		BOUNDS_CHECK(cp, 3 * INT16SZ + INT32SZ);
-		type = _getshort(cp);
+		type = ns_get16(cp);
  		cp += INT16SZ;			/* type */
-		class = _getshort(cp);
+		class = ns_get16(cp);
  		cp += INT16SZ + INT32SZ;	/* class, TTL */
-		n = _getshort(cp);
+		n = ns_get16(cp);
 		cp += INT16SZ;			/* len */
 		BOUNDS_CHECK(cp, n);
 		erdata = cp + n;
@@ -491,7 +491,7 @@ gethostbyname(name)
 {
 	struct hostent *hp;
 
-	if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
+	if ((_res.options & RES_INIT) == 0 && __res_ninit(&_res) == -1) {
 		__set_h_errno (NETDB_INTERNAL);
 		return (NULL);
        }
@@ -514,7 +514,7 @@ gethostbyname2(name, af)
 	int n, size, type, len;
 	extern struct hostent *_gethtbyname2();
 
-	if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
+	if ((_res.options & RES_INIT) == 0 && __res_ninit(&_res) == -1) {
 		__set_h_errno (NETDB_INTERNAL);
 		return (NULL);
 	}
@@ -613,8 +613,8 @@ gethostbyname2(name, af)
 				break;
 		}
 
-	if ((n = res_search(name, C_IN, type, buf.buf, sizeof(buf.buf))) < 0) {
-		dprintf("res_search failed (%d)\n", n);
+	if ((n = res_nsearch(&_res, name, C_IN, type, buf.buf, sizeof(buf.buf))) < 0) {
+		dprintf("res_nsearch failed (%d)\n", n);
 		if (errno == ECONNREFUSED)
 			return (_gethtbyname2(name, af));
 		return (NULL);
@@ -643,7 +643,7 @@ gethostbyaddr(addr, len, af)
 #endif /*SUNSECURITY*/
 	extern struct hostent *_gethtbyaddr();
 
-	if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
+	if ((_res.options & RES_INIT) == 0 && __res_ninit(&_res) == -1) {
 		__set_h_errno (NETDB_INTERNAL);
 		return (NULL);
 	}
@@ -693,9 +693,9 @@ gethostbyaddr(addr, len, af)
 	default:
 		abort();
 	}
-	n = res_query(qbuf, C_IN, T_PTR, (u_char *)buf.buf, sizeof buf.buf);
+	n = res_nquery(&_res, qbuf, C_IN, T_PTR, (u_char *)buf.buf, sizeof buf.buf);
 	if (n < 0) {
-		dprintf("res_query failed (%d)\n", n);
+		dprintf("res_nquery failed (%d)\n", n);
 		if (errno == ECONNREFUSED)
 			return (_gethtbyaddr(addr, len, af));
 		return (NULL);
diff --git a/resolv/ns_name.c b/resolv/ns_name.c
new file mode 100644
index 0000000000..b75f731c44
--- /dev/null
+++ b/resolv/ns_name.c
@@ -0,0 +1,636 @@
+/*
+ * 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.
+ */
+
+#ifndef lint
+static const char rcsid[] = "$Id$";
+#endif
+
+#include <sys/types.h>
+
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+
+#include <errno.h>
+#include <resolv.h>
+#include <string.h>
+#include <ctype.h>
+
+/* Data. */
+
+static const char	digits[] = "0123456789";
+
+/* Forward. */
+
+static int		special(int);
+static int		printable(int);
+static int		dn_find(const u_char *, const u_char *,
+				const u_char * const *,
+				const u_char * const *);
+
+/* Public. */
+
+/*
+ * ns_name_ntop(src, dst, dstsiz)
+ *	Convert an encoded domain name to printable ascii as per RFC1035.
+ * return:
+ *	Number of bytes written to buffer, or -1 (with errno set)
+ * notes:
+ *	The root is returned as "."
+ *	All other domains are returned in non absolute form
+ */
+int
+ns_name_ntop(const u_char *src, char *dst, size_t dstsiz) {
+	const u_char *cp;
+	char *dn, *eom;
+	u_char c;
+	u_int n;
+
+	cp = src;
+	dn = dst;
+	eom = dst + dstsiz;
+
+	while ((n = *cp++) != 0) {
+		if ((n & NS_CMPRSFLGS) != 0) {
+			/* Some kind of compression pointer. */
+			__set_errno (EMSGSIZE);
+			return (-1);
+		}
+		if (dn != dst) {
+			if (dn >= eom) {
+				__set_errno (EMSGSIZE);
+				return (-1);
+			}
+			*dn++ = '.';
+		}
+		if (dn + n >= eom) {
+			__set_errno (EMSGSIZE);
+			return (-1);
+		}
+		for ((void)NULL; n > 0; n--) {
+			c = *cp++;
+			if (special(c)) {
+				if (dn + 1 >= eom) {
+					__set_errno (EMSGSIZE);
+					return (-1);
+				}
+				*dn++ = '\\';
+				*dn++ = (char)c;
+			} else if (!printable(c)) {
+				if (dn + 3 >= eom) {
+					__set_errno (EMSGSIZE);
+					return (-1);
+				}
+				*dn++ = '\\';
+				*dn++ = digits[c / 100];
+				*dn++ = digits[(c % 100) / 10];
+				*dn++ = digits[c % 10];
+			} else {
+				if (dn >= eom) {
+					__set_errno (EMSGSIZE);
+					return (-1);
+				}
+				*dn++ = (char)c;
+			}
+		}
+	}
+	if (dn == dst) {
+		if (dn >= eom) {
+			__set_errno (EMSGSIZE);
+			return (-1);
+		}
+		*dn++ = '.';
+	}
+	if (dn >= eom) {
+		__set_errno (EMSGSIZE);
+		return (-1);
+	}
+	*dn++ = '\0';
+	return (dn - dst);
+}
+
+/*
+ * ns_name_pton(src, dst, dstsiz)
+ *	Convert a ascii string into an encoded domain name as per RFC1035.
+ * return:
+ *	-1 if it fails
+ *	1 if string was fully qualified
+ *	0 is string was not fully qualified
+ * notes:
+ *	Enforces label and domain length limits.
+ */
+
+int
+ns_name_pton(const char *src, u_char *dst, size_t dstsiz) {
+	u_char *label, *bp, *eom;
+	int c, n, escaped;
+	char *cp;
+
+	escaped = 0;
+	bp = dst;
+	eom = dst + dstsiz;
+	label = bp++;
+
+	while ((c = *src++) != 0) {
+		if (escaped) {
+			if ((cp = strchr(digits, c)) != NULL) {
+				n = (cp - digits) * 100;
+				if ((c = *src++) == 0 ||
+				    (cp = strchr(digits, c)) == NULL) {
+					__set_errno (EMSGSIZE);
+					return (-1);
+				}
+				n += (cp - digits) * 10;
+				if ((c = *src++) == 0 ||
+				    (cp = strchr(digits, c)) == NULL) {
+					__set_errno (EMSGSIZE);
+					return (-1);
+				}
+				n += (cp - digits);
+				if (n > 255) {
+					__set_errno (EMSGSIZE);
+					return (-1);
+				}
+				c = n;
+			}
+			escaped = 0;
+		} else if (c == '\\') {
+			escaped = 1;
+			continue;
+		} else if (c == '.') {
+			c = (bp - label - 1);
+			if ((c & NS_CMPRSFLGS) != 0) {	/* Label too big. */
+				__set_errno (EMSGSIZE);
+				return (-1);
+			}
+			if (label >= eom) {
+				__set_errno (EMSGSIZE);
+				return (-1);
+			}
+			*label = c;
+			/* Fully qualified ? */
+			if (*src == '\0') {
+				if (c != 0) {
+					if (bp >= eom) {
+						__set_errno (EMSGSIZE);
+						return (-1);
+					}
+					*bp++ = '\0';
+				}
+				if ((bp - dst) > MAXCDNAME) {
+					__set_errno (EMSGSIZE);
+					return (-1);
+				}
+				return (1);
+			}
+			if (c == 0 || *src == '.') {
+				__set_errno (EMSGSIZE);
+				return (-1);
+			}
+			label = bp++;
+			continue;
+		}
+		if (bp >= eom) {
+			__set_errno (EMSGSIZE);
+			return (-1);
+		}
+		*bp++ = (u_char)c;
+	}
+	c = (bp - label - 1);
+	if ((c & NS_CMPRSFLGS) != 0) {		/* Label too big. */
+		__set_errno (EMSGSIZE);
+		return (-1);
+	}
+	if (label >= eom) {
+		__set_errno (EMSGSIZE);
+		return (-1);
+	}
+	*label = c;
+	if (c != 0) {
+		if (bp >= eom) {
+			__set_errno (EMSGSIZE);
+			return (-1);
+		}
+		*bp++ = 0;
+	}
+	if ((bp - dst) > MAXCDNAME) {	/* src too big */
+		__set_errno (EMSGSIZE);
+		return (-1);
+	}
+	return (0);
+}
+
+/*
+ * ns_name_ntol(src, dst, dstsiz)
+ *	Convert a network strings labels into all lowercase.
+ * return:
+ *	Number of bytes written to buffer, or -1 (with errno set)
+ * notes:
+ *	Enforces label and domain length limits.
+ */
+
+int
+ns_name_ntol(const u_char *src, u_char *dst, size_t dstsiz) {
+	const u_char *cp;
+	u_char *dn, *eom;
+	u_char c;
+	u_int n;
+
+	cp = src;
+	dn = dst;
+	eom = dst + dstsiz;
+
+	while ((n = *cp++) != 0) {
+		if ((n & NS_CMPRSFLGS) != 0) {
+			/* Some kind of compression pointer. */
+			__set_errno (EMSGSIZE);
+			return (-1);
+		}
+		*dn++ = n;
+		if (dn + n >= eom) {
+			__set_errno (EMSGSIZE);
+			return (-1);
+		}
+		for ((void)NULL; n > 0; n--) {
+			c = *cp++;
+			if (isupper(c))
+				*dn++ = tolower(c);
+			else
+				*dn++ = c;
+		}
+	}
+	*dn++ = '\0';
+	return (dn - dst);
+}
+
+/*
+ * ns_name_unpack(msg, eom, src, dst, dstsiz)
+ *	Unpack a domain name from a message, source may be compressed.
+ * return:
+ *	-1 if it fails, or consumed octets if it succeeds.
+ */
+int
+ns_name_unpack(const u_char *msg, const u_char *eom, const u_char *src,
+	       u_char *dst, size_t dstsiz)
+{
+	const u_char *srcp, *dstlim;
+	u_char *dstp;
+	int n, len, checked;
+
+	len = -1;
+	checked = 0;
+	dstp = dst;
+	srcp = src;
+	dstlim = dst + dstsiz;
+	if (srcp < msg || srcp >= eom) {
+		__set_errno (EMSGSIZE);
+		return (-1);
+	}
+	/* Fetch next label in domain name. */
+	while ((n = *srcp++) != 0) {
+		/* Check for indirection. */
+		switch (n & NS_CMPRSFLGS) {
+		case 0:
+			/* Limit checks. */
+			if (dstp + n + 1 >= dstlim || srcp + n >= eom) {
+				__set_errno (EMSGSIZE);
+				return (-1);
+			}
+			checked += n + 1;
+			*dstp++ = n;
+			memcpy(dstp, srcp, n);
+			dstp += n;
+			srcp += n;
+			break;
+
+		case NS_CMPRSFLGS:
+			if (srcp >= eom) {
+				__set_errno (EMSGSIZE);
+				return (-1);
+			}
+			if (len < 0)
+				len = srcp - src + 1;
+			srcp = msg + (((n & 0x3f) << 8) | (*srcp & 0xff));
+			if (srcp < msg || srcp >= eom) {  /* Out of range. */
+				__set_errno (EMSGSIZE);
+				return (-1);
+			}
+			checked += 2;
+			/*
+			 * Check for loops in the compressed name;
+			 * if we've looked at the whole message,
+			 * there must be a loop.
+			 */
+			if (checked >= eom - msg) {
+				__set_errno (EMSGSIZE);
+				return (-1);
+			}
+			break;
+
+		default:
+			__set_errno (EMSGSIZE);
+			return (-1);			/* flag error */
+		}
+	}
+	*dstp = '\0';
+	if (len < 0)
+		len = srcp - src;
+	return (len);
+}
+
+/*
+ * ns_name_pack(src, dst, dstsiz, dnptrs, lastdnptr)
+ *	Pack domain name 'domain' into 'comp_dn'.
+ * return:
+ *	Size of the compressed name, or -1.
+ * notes:
+ *	'dnptrs' is an array of pointers to previous compressed names.
+ *	dnptrs[0] is a pointer to the beginning of the message. The array
+ *	ends with NULL.
+ *	'lastdnptr' is a pointer to the end of the array pointed to
+ *	by 'dnptrs'.
+ * Side effects:
+ *	The list of pointers in dnptrs is updated for labels inserted into
+ *	the message as we compress the name.  If 'dnptr' is NULL, we don't
+ *	try to compress names. If 'lastdnptr' is NULL, we don't update the
+ *	list.
+ */
+int
+ns_name_pack(const u_char *src, u_char *dst, int dstsiz,
+	     const u_char **dnptrs, const u_char **lastdnptr)
+{
+	u_char *dstp;
+	const u_char **cpp, **lpp, *eob, *msg;
+	const u_char *srcp;
+	int n, l;
+
+	srcp = src;
+	dstp = dst;
+	eob = dstp + dstsiz;
+	lpp = cpp = NULL;
+	if (dnptrs != NULL) {
+		if ((msg = *dnptrs++) != NULL) {
+			for (cpp = dnptrs; *cpp != NULL; cpp++)
+				(void)NULL;
+			lpp = cpp;	/* end of list to search */
+		}
+	} else
+		msg = NULL;
+
+	/* make sure the domain we are about to add is legal */
+	l = 0;
+	do {
+		n = *srcp;
+		if ((n & NS_CMPRSFLGS) != 0) {
+			__set_errno (EMSGSIZE);
+			return (-1);
+		}
+		l += n + 1;
+		if (l > MAXCDNAME) {
+			__set_errno (EMSGSIZE);
+			return (-1);
+		}
+		srcp += n + 1;
+	} while (n != 0);
+
+	/* from here on we need to reset compression pointer array on error */
+	srcp = src;
+	do {
+		/* Look to see if we can use pointers. */
+		n = *srcp;
+		if (n != 0 && msg != NULL) {
+			l = dn_find(srcp, msg, (const u_char * const *)dnptrs,
+				    (const u_char * const *)lpp);
+			if (l >= 0) {
+				if (dstp + 1 >= eob) {
+					goto cleanup;
+				}
+				*dstp++ = (l >> 8) | NS_CMPRSFLGS;
+				*dstp++ = l % 256;
+				return (dstp - dst);
+			}
+			/* Not found, save it. */
+			if (lastdnptr != NULL && cpp < lastdnptr - 1 &&
+			    (dstp - msg) < 0x4000) {
+				*cpp++ = dstp;
+				*cpp = NULL;
+			}
+		}
+		/* copy label to buffer */
+		if (n & NS_CMPRSFLGS) {		/* Should not happen. */
+			goto cleanup;
+		}
+		if (dstp + 1 + n >= eob) {
+			goto cleanup;
+		}
+		memcpy(dstp, srcp, n + 1);
+		srcp += n + 1;
+		dstp += n + 1;
+	} while (n != 0);
+
+	if (dstp > eob) {
+cleanup:
+		if (msg != NULL)
+			*lpp = NULL;
+		__set_errno (EMSGSIZE);
+		return (-1);
+	} 
+	return (dstp - dst);
+}
+
+/*
+ * ns_name_uncompress(msg, eom, src, dst, dstsiz)
+ *	Expand compressed domain name to presentation format.
+ * return:
+ *	Number of bytes read out of `src', or -1 (with errno set).
+ * note:
+ *	Root domain returns as "." not "".
+ */
+int
+ns_name_uncompress(const u_char *msg, const u_char *eom, const u_char *src,
+		   char *dst, size_t dstsiz)
+{
+	u_char tmp[NS_MAXCDNAME];
+	int n;
+	
+	if ((n = ns_name_unpack(msg, eom, src, tmp, sizeof tmp)) == -1)
+		return (-1);
+	if (ns_name_ntop(tmp, dst, dstsiz) == -1)
+		return (-1);
+	return (n);
+}
+
+/*
+ * ns_name_compress(src, dst, dstsiz, dnptrs, lastdnptr)
+ *	Compress a domain name into wire format, using compression pointers.
+ * return:
+ *	Number of bytes consumed in `dst' or -1 (with errno set).
+ * notes:
+ *	'dnptrs' is an array of pointers to previous compressed names.
+ *	dnptrs[0] is a pointer to the beginning of the message.
+ *	The list ends with NULL.  'lastdnptr' is a pointer to the end of the
+ *	array pointed to by 'dnptrs'. Side effect is to update the list of
+ *	pointers for labels inserted into the message as we compress the name.
+ *	If 'dnptr' is NULL, we don't try to compress names. If 'lastdnptr'
+ *	is NULL, we don't update the list.
+ */
+int
+ns_name_compress(const char *src, u_char *dst, size_t dstsiz,
+		 const u_char **dnptrs, const u_char **lastdnptr)
+{
+	u_char tmp[NS_MAXCDNAME];
+
+	if (ns_name_pton(src, tmp, sizeof tmp) == -1)
+		return (-1);
+	return (ns_name_pack(tmp, dst, dstsiz, dnptrs, lastdnptr));
+}
+
+/*
+ * ns_name_skip(ptrptr, eom)
+ *	Advance *ptrptr to skip over the compressed name it points at.
+ * return:
+ *	0 on success, -1 (with errno set) on failure.
+ */
+int
+ns_name_skip(const u_char **ptrptr, const u_char *eom) {
+	const u_char *cp;
+	u_int n;
+
+	cp = *ptrptr;
+	while (cp < eom && (n = *cp++) != 0) {
+		/* Check for indirection. */
+		switch (n & NS_CMPRSFLGS) {
+		case 0:			/* normal case, n == len */
+			cp += n;
+			continue;
+		case NS_CMPRSFLGS:	/* indirection */
+			cp++;
+			break;
+		default:		/* illegal type */
+			__set_errno (EMSGSIZE);
+			return (-1);
+		}
+		break;
+	}
+	if (cp > eom) {
+		__set_errno (EMSGSIZE);
+		return (-1);
+	}
+	*ptrptr = cp;
+	return (0);
+}
+
+/* Private. */
+
+/*
+ * special(ch)
+ *	Thinking in noninternationalized USASCII (per the DNS spec),
+ *	is this characted special ("in need of quoting") ?
+ * return:
+ *	boolean.
+ */
+static int
+special(int ch) {
+	switch (ch) {
+	case 0x22: /* '"' */
+	case 0x2E: /* '.' */
+	case 0x3B: /* ';' */
+	case 0x5C: /* '\\' */
+	/* Special modifiers in zone files. */
+	case 0x40: /* '@' */
+	case 0x24: /* '$' */
+		return (1);
+	default:
+		return (0);
+	}
+}
+
+/*
+ * printable(ch)
+ *	Thinking in noninternationalized USASCII (per the DNS spec),
+ *	is this character visible and not a space when printed ?
+ * return:
+ *	boolean.
+ */
+static int
+printable(int ch) {
+	return (ch > 0x20 && ch < 0x7f);
+}
+
+/*
+ *	Thinking in noninternationalized USASCII (per the DNS spec),
+ *	convert this character to lower case if it's upper case.
+ */
+static int
+mklower(int ch) {
+	if (ch >= 0x41 && ch <= 0x5A)
+		return (ch + 0x20);
+	return (ch);
+}
+
+/*
+ * dn_find(domain, msg, dnptrs, lastdnptr)
+ *	Search for the counted-label name in an array of compressed names.
+ * return:
+ *	offset from msg if found, or -1.
+ * notes:
+ *	dnptrs is the pointer to the first name on the list,
+ *	not the pointer to the start of the message.
+ */
+static int
+dn_find(const u_char *domain, const u_char *msg,
+	const u_char * const *dnptrs,
+	const u_char * const *lastdnptr)
+{
+	const u_char *dn, *cp, *sp;
+	const u_char * const *cpp;
+	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++))
+						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: ;
+	}
+	__set_errno (ENOENT);
+	return (-1);
+}
diff --git a/resolv/ns_netint.c b/resolv/ns_netint.c
new file mode 100644
index 0000000000..9dcf91cf50
--- /dev/null
+++ b/resolv/ns_netint.c
@@ -0,0 +1,52 @@
+/*
+ * 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.
+ */
+
+#ifndef lint
+static const char rcsid[] = "$Id$";
+#endif
+
+/* Import. */
+
+#include <arpa/nameser.h>
+
+/* Public. */
+
+u_int
+ns_get16(const u_char *src) {
+	u_int dst;
+
+	NS_GET16(dst, src);
+	return (dst);
+}
+
+u_long
+ns_get32(const u_char *src) {
+	u_long dst;
+
+	NS_GET32(dst, src);
+	return (dst);
+}
+
+void
+ns_put16(u_int src, u_char *dst) {
+	NS_PUT16(src, dst);
+}
+
+void
+ns_put32(u_long src, u_char *dst) {
+	NS_PUT32(src, dst);
+}
diff --git a/resolv/ns_parse.c b/resolv/ns_parse.c
new file mode 100644
index 0000000000..7bbdc41cdf
--- /dev/null
+++ b/resolv/ns_parse.c
@@ -0,0 +1,194 @@
+/*
+ * 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.
+ */
+
+#ifndef lint
+static const char rcsid[] = "$Id$";
+#endif
+
+/* Import. */
+
+#include <sys/types.h>
+
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+
+#include <errno.h>
+#include <resolv.h>
+#include <string.h>
+
+/* Forward. */
+
+static void	setsection(ns_msg *msg, ns_sect sect);
+
+/* Macros. */
+
+#define RETERR(err) do { __set_errno (err); return (-1); } while (0)
+
+/* Public. */
+
+/* These need to be in the same order as the nres.h:ns_flag enum. */
+struct _ns_flagdata _ns_flagdata[16] = {
+	{ 0x8000, 15 },		/* qr. */
+	{ 0x7800, 11 },		/* opcode. */
+	{ 0x0400, 10 },		/* aa. */
+	{ 0x0200, 9 },		/* tc. */
+	{ 0x0100, 8 },		/* rd. */
+	{ 0x0080, 7 },		/* ra. */
+	{ 0x0040, 6 },		/* z. */
+	{ 0x0020, 5 },		/* ad. */
+	{ 0x0010, 4 },		/* cd. */
+	{ 0x000f, 0 },		/* rcode. */
+	{ 0x0000, 0 },		/* expansion (1/6). */
+	{ 0x0000, 0 },		/* expansion (2/6). */
+	{ 0x0000, 0 },		/* expansion (3/6). */
+	{ 0x0000, 0 },		/* expansion (4/6). */
+	{ 0x0000, 0 },		/* expansion (5/6). */
+	{ 0x0000, 0 },		/* expansion (6/6). */
+};
+
+int
+ns_skiprr(const u_char *ptr, const u_char *eom, ns_sect section, int count) {
+	const u_char *optr = ptr;
+
+	for ((void)NULL; count > 0; count--) {
+		int b, rdlength;
+
+		b = dn_skipname(ptr, eom);
+		if (b < 0)
+			RETERR(EMSGSIZE);
+		ptr += b/*Name*/ + NS_INT16SZ/*Type*/ + NS_INT16SZ/*Class*/;
+		if (section != ns_s_qd) {
+			if (ptr + NS_INT32SZ + NS_INT16SZ > eom)
+				RETERR(EMSGSIZE);
+			ptr += NS_INT32SZ/*TTL*/;
+			NS_GET16(rdlength, ptr);
+			ptr += rdlength/*RData*/;
+		}
+	}
+	if (ptr > eom)
+		RETERR(EMSGSIZE);
+	return (ptr - optr);
+}
+
+int
+ns_initparse(const u_char *msg, int msglen, ns_msg *handle) {
+	const u_char *eom = msg + msglen;
+	int i;
+
+	memset(handle, 0x5e, sizeof *handle);
+	handle->_msg = msg;
+	handle->_eom = eom;
+	if (msg + NS_INT16SZ > eom)
+		RETERR(EMSGSIZE);
+	NS_GET16(handle->_id, msg);
+	if (msg + NS_INT16SZ > eom)
+		RETERR(EMSGSIZE);
+	NS_GET16(handle->_flags, msg);
+	for (i = 0; i < ns_s_max; i++) {
+		if (msg + NS_INT16SZ > eom)
+			RETERR(EMSGSIZE);
+		NS_GET16(handle->_counts[i], msg);
+	}
+	for (i = 0; i < ns_s_max; i++)
+		if (handle->_counts[i] == 0)
+			handle->_sections[i] = NULL;
+		else {
+			int b = ns_skiprr(msg, eom, (ns_sect)i,
+					  handle->_counts[i]);
+
+			if (b < 0)
+				return (-1);
+			handle->_sections[i] = msg;
+			msg += b;
+		}
+	if (msg != eom)
+		RETERR(EMSGSIZE);
+	setsection(handle, ns_s_max);
+	return (0);
+}
+
+int
+ns_parserr(ns_msg *handle, ns_sect section, int rrnum, ns_rr *rr) {
+	int b;
+
+	/* Make section right. */
+	if (section < 0 || section >= ns_s_max)
+		RETERR(ENODEV);
+	if (section != handle->_sect)
+		setsection(handle, section);
+
+	/* Make rrnum right. */
+	if (rrnum == -1)
+		rrnum = handle->_rrnum;
+	if (rrnum < 0 || rrnum >= handle->_counts[(int)section])
+		RETERR(ENODEV);
+	if (rrnum < handle->_rrnum)
+		setsection(handle, section);
+	if (rrnum > handle->_rrnum) {
+		b = ns_skiprr(handle->_ptr, handle->_eom, section,
+			      rrnum - handle->_rrnum);
+
+		if (b < 0)
+			return (-1);
+		handle->_ptr += b;
+		handle->_rrnum = rrnum;
+	}
+
+	/* Do the parse. */
+	b = dn_expand(handle->_msg, handle->_eom,
+		      handle->_ptr, rr->name, NS_MAXDNAME);
+	if (b < 0)
+		return (-1);
+	handle->_ptr += b;
+	if (handle->_ptr + NS_INT16SZ + NS_INT16SZ > handle->_eom)
+		RETERR(EMSGSIZE);
+	NS_GET16(rr->type, handle->_ptr);
+	NS_GET16(rr->rr_class, handle->_ptr);
+	if (section == ns_s_qd) {
+		rr->ttl = 0;
+		rr->rdlength = 0;
+		rr->rdata = NULL;
+	} else {
+		if (handle->_ptr + NS_INT32SZ + NS_INT16SZ > handle->_eom)
+			RETERR(EMSGSIZE);
+		NS_GET32(rr->ttl, handle->_ptr);
+		NS_GET16(rr->rdlength, handle->_ptr);
+		if (handle->_ptr + rr->rdlength > handle->_eom)
+			RETERR(EMSGSIZE);
+		rr->rdata = handle->_ptr;
+		handle->_ptr += rr->rdlength;
+	}
+	if (++handle->_rrnum > handle->_counts[(int)section])
+		setsection(handle, (ns_sect)((int)section + 1));
+
+	/* All done. */
+	return (0);
+}
+
+/* Private. */
+
+static void
+setsection(ns_msg *msg, ns_sect sect) {
+	msg->_sect = sect;
+	if (sect == ns_s_max) {
+		msg->_rrnum = -1;
+		msg->_ptr = NULL;
+	} else {
+		msg->_rrnum = 0;
+		msg->_ptr = msg->_sections[(int)sect];
+	}
+}
diff --git a/resolv/ns_print.c b/resolv/ns_print.c
new file mode 100644
index 0000000000..cce3fb611d
--- /dev/null
+++ b/resolv/ns_print.c
@@ -0,0 +1,818 @@
+/*
+ * 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.
+ */
+
+#ifndef lint
+static const char rcsid[] = "$Id$";
+#endif
+
+/* Import. */
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <arpa/inet.h>
+
+#include <errno.h>
+#include <resolv.h>
+#include <string.h>
+#include <ctype.h>
+
+#ifdef SPRINTF_CHAR
+# define SPRINTF(x) strlen(sprintf/**/x)
+#else
+# define SPRINTF(x) ((size_t)sprintf x)
+#endif
+
+/* Forward. */
+
+static size_t	prune_origin(const char *name, const char *origin);
+static int	charstr(const u_char *rdata, const u_char *edata,
+			char **buf, size_t *buflen);
+static int	addname(const u_char *msg, size_t msglen,
+			const u_char **p, const char *origin,
+			char **buf, size_t *buflen);
+static void	addlen(size_t len, char **buf, size_t *buflen);
+static int	addstr(const char *src, size_t len,
+		       char **buf, size_t *buflen);
+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
+
+/* Macros. */
+
+#define	T(x) \
+	do { \
+		if ((x) < 0) \
+			return (-1); \
+	} while (0)
+
+/* Public. */
+
+/*
+ * int
+ * ns_sprintrr(handle, rr, name_ctx, origin, buf, buflen)
+ *	Convert an RR to presentation format.
+ * return:
+ *	Number of characters written to buf, or -1 (check errno).
+ */
+int
+ns_sprintrr(const ns_msg *handle, const ns_rr *rr,
+	    const char *name_ctx, const char *origin,
+	    char *buf, size_t buflen)
+{
+	int n;
+
+	n = ns_sprintrrf(ns_msg_base(*handle), ns_msg_size(*handle),
+			 ns_rr_name(*rr), ns_rr_class(*rr), ns_rr_type(*rr),
+			 ns_rr_ttl(*rr), ns_rr_rdata(*rr), ns_rr_rdlen(*rr),
+			 name_ctx, origin, buf, buflen);
+	return (n);
+}
+
+/*
+ * int
+ * ns_sprintrrf(msg, msglen, name, class, type, ttl, rdata, rdlen,
+ *	       name_ctx, origin, buf, buflen)
+ *	Convert the fields of an RR into presentation format.
+ * return:
+ *	Number of characters written to buf, or -1 (check errno).
+ */
+int
+ns_sprintrrf(const u_char *msg, size_t msglen,
+	    const char *name, ns_class class, ns_type type,
+	    u_long ttl, const u_char *rdata, size_t rdlen,
+	    const char *name_ctx, const char *origin,
+	    char *buf, size_t buflen)
+{
+	const char *obuf = buf;
+	const u_char *edata = rdata + rdlen;
+	int spaced = 0;
+
+	const char *comment;
+	char tmp[100];
+	int len, x;
+
+	/*
+	 * Owner.
+	 */
+	if (name_ctx != NULL && ns_samename(name_ctx, name) == 1) {
+		T(addstr("\t\t\t", 3, &buf, &buflen));
+	} else {
+		len = prune_origin(name, origin);
+		if (len == 0) {
+			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] != '.') {
+				T(addstr(".", 1, &buf, &buflen));
+				len++;
+			}
+			T(spaced = addtab(len, 24, spaced, &buf, &buflen));
+		}
+	}
+
+	/*
+	 * TTL, Class, Type.
+	 */
+	T(x = ns_format_ttl(ttl, buf, buflen));
+	addlen(x, &buf, &buflen);
+	len = SPRINTF((tmp, " %s %s", p_class(class), p_type(type)));
+	T(addstr(tmp, len, &buf, &buflen));
+	T(spaced = addtab(x + len, 16, spaced, &buf, &buflen));
+
+	/*
+	 * RData.
+	 */
+	switch (type) {
+	case ns_t_a:
+		if (rdlen != NS_INADDRSZ)
+			goto formerr;
+		(void) inet_ntop(AF_INET, rdata, buf, buflen);
+		addlen(strlen(buf), &buf, &buflen);
+		break;
+
+	case ns_t_cname:
+	case ns_t_mb:
+	case ns_t_mg:
+	case ns_t_mr:
+	case ns_t_ns:
+	case ns_t_ptr:
+		T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
+		break;
+
+	case ns_t_hinfo:
+	case ns_t_isdn:
+		/* First word. */
+		T(len = charstr(rdata, edata, &buf, &buflen));
+		if (len == 0)
+			goto formerr;
+		rdata += len;
+		T(addstr(" ", 1, &buf, &buflen));
+
+		    
+		/* Second word, optional in ISDN records. */
+		if (type == ns_t_isdn && rdata == edata)
+			break;
+		    
+		T(len = charstr(rdata, edata, &buf, &buflen));
+		if (len == 0)
+			goto formerr;
+		rdata += len;
+		break;
+
+	case ns_t_soa: {
+		u_long t;
+
+		/* Server name. */
+		T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
+		T(addstr(" ", 1, &buf, &buflen));
+
+		/* Administrator name. */
+		T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
+		T(addstr(" (\n", 3, &buf, &buflen));
+		spaced = 0;
+
+		if ((edata - rdata) != 5*NS_INT32SZ)
+			goto formerr;
+
+		/* Serial number. */
+		t = ns_get32(rdata);  rdata += NS_INT32SZ;
+		T(addstr("\t\t\t\t\t", 5, &buf, &buflen));
+		len = SPRINTF((tmp, "%lu", t));
+		T(addstr(tmp, len, &buf, &buflen));
+		T(spaced = addtab(len, 16, spaced, &buf, &buflen));
+		T(addstr("; serial\n", 9, &buf, &buflen));
+		spaced = 0;
+
+		/* Refresh interval. */
+		t = ns_get32(rdata);  rdata += NS_INT32SZ;
+		T(addstr("\t\t\t\t\t", 5, &buf, &buflen));
+		T(len = ns_format_ttl(t, buf, buflen));
+		addlen(len, &buf, &buflen);
+		T(spaced = addtab(len, 16, spaced, &buf, &buflen));
+		T(addstr("; refresh\n", 10, &buf, &buflen));
+		spaced = 0;
+
+		/* Retry interval. */
+		t = ns_get32(rdata);  rdata += NS_INT32SZ;
+		T(addstr("\t\t\t\t\t", 5, &buf, &buflen));
+		T(len = ns_format_ttl(t, buf, buflen));
+		addlen(len, &buf, &buflen);
+		T(spaced = addtab(len, 16, spaced, &buf, &buflen));
+		T(addstr("; retry\n", 8, &buf, &buflen));
+		spaced = 0;
+
+		/* Expiry. */
+		t = ns_get32(rdata);  rdata += NS_INT32SZ;
+		T(addstr("\t\t\t\t\t", 5, &buf, &buflen));
+		T(len = ns_format_ttl(t, buf, buflen));
+		addlen(len, &buf, &buflen);
+		T(spaced = addtab(len, 16, spaced, &buf, &buflen));
+		T(addstr("; expiry\n", 9, &buf, &buflen));
+		spaced = 0;
+
+		/* Minimum TTL. */
+		t = ns_get32(rdata);  rdata += NS_INT32SZ;
+		T(addstr("\t\t\t\t\t", 5, &buf, &buflen));
+		T(len = ns_format_ttl(t, buf, buflen));
+		addlen(len, &buf, &buflen);
+		T(addstr(" )", 2, &buf, &buflen));
+		T(spaced = addtab(len, 16, spaced, &buf, &buflen));
+		T(addstr("; minimum\n", 10, &buf, &buflen));
+
+		break;
+	    }
+
+	case ns_t_mx:
+	case ns_t_afsdb:
+	case ns_t_rt: {
+		u_int t;
+
+		if (rdlen < NS_INT16SZ)
+			goto formerr;
+
+		/* Priority. */
+		t = ns_get16(rdata);
+		rdata += NS_INT16SZ;
+		len = SPRINTF((tmp, "%u ", t));
+		T(addstr(tmp, len, &buf, &buflen));
+
+		/* Target. */
+		T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
+
+		break;
+	    }
+
+	case ns_t_px: {
+		u_int t;
+
+		if (rdlen < NS_INT16SZ)
+			goto formerr;
+
+		/* Priority. */
+		t = ns_get16(rdata);
+		rdata += NS_INT16SZ;
+		len = SPRINTF((tmp, "%u ", t));
+		T(addstr(tmp, len, &buf, &buflen));
+
+		/* Name1. */
+		T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
+		T(addstr(" ", 1, &buf, &buflen));
+
+		/* Name2. */
+		T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
+
+		break;
+	    }
+
+	case ns_t_x25:
+		T(len = charstr(rdata, edata, &buf, &buflen));
+		if (len == 0)
+			goto formerr;
+		rdata += len;
+		break;
+
+	case ns_t_txt:
+		while (rdata < edata) {
+			T(len = charstr(rdata, edata, &buf, &buflen));
+			if (len == 0)
+				goto formerr;
+			rdata += len;
+			if (rdata < edata)
+				T(addstr(" ", 1, &buf, &buflen));
+		}
+		break;
+
+	case ns_t_nsap: {
+		char t[255*3];
+
+		(void) inet_nsap_ntoa(rdlen, rdata, t);
+		T(addstr(t, strlen(t), &buf, &buflen));
+		break;
+	    }
+
+	case ns_t_aaaa:
+		if (rdlen != NS_IN6ADDRSZ)
+			goto formerr;
+		(void) inet_ntop(AF_INET6, rdata, buf, buflen);
+		addlen(strlen(buf), &buf, &buflen);
+		break;
+
+	case ns_t_loc: {
+		char t[255];
+
+		/* XXX protocol format checking? */
+		(void) loc_ntoa(rdata, t);
+		T(addstr(t, strlen(t), &buf, &buflen));
+		break;
+	    }
+
+	case ns_t_naptr: {
+		u_int order, preference;
+		char t[50];
+
+		if (rdlen < 2*NS_INT16SZ)
+			goto formerr;
+
+		/* Order, Precedence. */
+		order = ns_get16(rdata);	rdata += NS_INT16SZ;
+		preference = ns_get16(rdata);	rdata += NS_INT16SZ;
+		len = SPRINTF((t, "%u %u ", order, preference));
+		T(addstr(t, len, &buf, &buflen));
+
+		/* Flags. */
+		T(len = charstr(rdata, edata, &buf, &buflen));
+		if (len == 0)
+			goto formerr;
+		rdata += len;
+		T(addstr(" ", 1, &buf, &buflen));
+
+		/* Service. */
+		T(len = charstr(rdata, edata, &buf, &buflen));
+		if (len == 0)
+			goto formerr;
+		rdata += len;
+		T(addstr(" ", 1, &buf, &buflen));
+
+		/* Regexp. */
+		T(len = charstr(rdata, edata, &buf, &buflen));
+		if (len < 0)
+			return (-1);
+		if (len == 0)
+			goto formerr;
+		rdata += len;
+		T(addstr(" ", 1, &buf, &buflen));
+
+		/* Server. */
+		T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
+		break;
+	    }
+
+	case ns_t_srv: {
+		u_int priority, weight, port;
+		char t[50];
+
+		if (rdlen < NS_INT16SZ*3)
+			goto formerr;
+
+		/* Priority, Weight, Port. */
+		priority = ns_get16(rdata);  rdata += NS_INT16SZ;
+		weight   = ns_get16(rdata);  rdata += NS_INT16SZ;
+		port     = ns_get16(rdata);  rdata += NS_INT16SZ;
+		len = SPRINTF((t, "%u %u %u ", priority, weight, port));
+		T(addstr(t, len, &buf, &buflen));
+
+		/* Server. */
+		T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
+		break;
+	    }
+
+	case ns_t_minfo:
+	case ns_t_rp:
+		/* Name1. */
+		T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
+		T(addstr(" ", 1, &buf, &buflen));
+
+		/* Name2. */
+		T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
+
+		break;
+
+	case ns_t_wks: {
+		int n, lcnt;
+
+		if (rdlen < NS_INT32SZ + 1)
+			goto formerr;
+
+		/* Address. */
+		(void) inet_ntop(AF_INET, rdata, buf, buflen);
+		addlen(strlen(buf), &buf, &buflen);
+		rdata += NS_INADDRSZ;
+
+		/* Protocol. */
+		len = SPRINTF((tmp, " %u ( ", *rdata));
+		T(addstr(tmp, len, &buf, &buflen));
+		rdata += NS_INT8SZ;
+
+		/* Bit map. */
+		n = 0;
+		lcnt = 0;
+		while (rdata < edata) {
+			u_int c = *rdata++;
+			do {
+				if (c & 0200) {
+					if (lcnt == 0) {
+						T(addstr("\n\t\t\t\t", 5,
+							 &buf, &buflen));
+						lcnt = 10;
+						spaced = 0;
+					}
+					len = SPRINTF((tmp, "%d ", n));
+					T(addstr(tmp, len, &buf, &buflen));
+					lcnt--;
+				}
+				c <<= 1;
+			} while (++n & 07);
+		}
+		T(addstr(")", 1, &buf, &buflen));
+
+		break;
+	    }
+
+	case ns_t_key: {
+#ifndef _LIBC
+		char base64_key[NS_MD5RSA_MAX_BASE64];
+		u_int keyflags, protocol, algorithm, key_id;
+		const char *leader;
+		int n;
+
+		if (rdlen < NS_INT16SZ + NS_INT8SZ + NS_INT8SZ)
+			goto formerr;
+
+		/* Key flags, Protocol, Algorithm. */
+		key_id = dst_s_dns_key_id(rdata, edata-rdata);
+		keyflags = ns_get16(rdata);  rdata += NS_INT16SZ;
+		protocol = *rdata++;
+		algorithm = *rdata++;
+		len = SPRINTF((tmp, "0x%04x %u %u",
+			       keyflags, protocol, algorithm));
+		T(addstr(tmp, len, &buf, &buflen));
+
+		/* Public key data. */
+		len = b64_ntop(rdata, edata - rdata,
+			       base64_key, sizeof base64_key);
+		if (len < 0)
+			goto formerr;
+		if (len > 15) {
+			T(addstr(" (", 2, &buf, &buflen));
+			leader = "\n\t\t";
+			spaced = 0;
+		} else
+			leader = " ";
+		for (n = 0; n < len; n += 48) {
+			T(addstr(leader, strlen(leader), &buf, &buflen));
+			T(addstr(base64_key + n, MIN(len - n, 48),
+				 &buf, &buflen));
+		}
+		if (len > 15)
+			T(addstr(" )", 2, &buf, &buflen));
+		n = SPRINTF((tmp, " ; key_tag= %u", key_id));
+		T(addstr(tmp, n, &buf, &buflen));
+#endif /* !_LIBC */
+		break;
+	    }
+
+	case ns_t_sig: {
+#ifndef _LIBC
+		char base64_key[NS_MD5RSA_MAX_BASE64];
+		u_int type, algorithm, labels, footprint;
+		const char *leader;
+		u_long t;
+		int n;
+
+		if (rdlen < 22)
+			goto formerr;
+
+		/* Type covered, Algorithm, Label count, Original TTL. */
+	        type = ns_get16(rdata);  rdata += NS_INT16SZ;
+		algorithm = *rdata++;
+		labels = *rdata++;
+		t = ns_get32(rdata);  rdata += NS_INT32SZ;
+		len = SPRINTF((tmp, "%s %d %d %lu ",
+			       p_type(type), algorithm, labels, t));
+		T(addstr(tmp, len, &buf, &buflen));
+		if (labels > (u_int)dn_count_labels(name))
+			goto formerr;
+
+		/* Signature expiry. */
+		t = ns_get32(rdata);  rdata += NS_INT32SZ;
+		len = SPRINTF((tmp, "%s ", p_secstodate(t)));
+		T(addstr(tmp, len, &buf, &buflen));
+
+		/* Time signed. */
+		t = ns_get32(rdata);  rdata += NS_INT32SZ;
+		len = SPRINTF((tmp, "%s ", p_secstodate(t)));
+		T(addstr(tmp, len, &buf, &buflen));
+
+		/* Signature Footprint. */
+		footprint = ns_get16(rdata);  rdata += NS_INT16SZ;
+		len = SPRINTF((tmp, "%u ", footprint));
+		T(addstr(tmp, len, &buf, &buflen));
+
+		/* Signer's name. */
+		T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
+
+		/* Signature. */
+		len = b64_ntop(rdata, edata - rdata,
+			       base64_key, sizeof base64_key);
+		if (len > 15) {
+			T(addstr(" (", 2, &buf, &buflen));
+			leader = "\n\t\t";
+			spaced = 0;
+		} else
+			leader = " ";
+		if (len < 0)
+			goto formerr;
+		for (n = 0; n < len; n += 48) {
+			T(addstr(leader, strlen(leader), &buf, &buflen));
+			T(addstr(base64_key + n, MIN(len - n, 48),
+				 &buf, &buflen));
+		}
+		if (len > 15)
+			T(addstr(" )", 2, &buf, &buflen));
+#endif /* !_LIBC */
+		break;
+	    }
+
+	case ns_t_nxt: {
+		int n, c;
+
+		/* Next domain name. */
+		T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
+
+		/* Type bit map. */
+		n = edata - rdata;
+		for (c = 0; c < n*8; c++)
+			if (NS_NXT_BIT_ISSET(c, rdata)) {
+				len = SPRINTF((tmp, " %s", p_type(c)));
+				T(addstr(tmp, len, &buf, &buflen));
+			}
+		break;
+	    }
+
+	case ns_t_cert: {
+		u_int c_type, key_tag, alg;
+		int n, siz;
+		char base64_cert[8192], *leader, tmp[40];
+
+		c_type  = ns_get16(rdata); rdata += NS_INT16SZ;
+		key_tag = ns_get16(rdata); rdata += NS_INT16SZ;
+		alg = (u_int) *rdata++;
+
+		len = SPRINTF((tmp, "%d %d %d ", c_type, key_tag, alg));
+		T(addstr(tmp, len, &buf, &buflen));
+		siz = (edata-rdata)*4/3 + 4; /* "+4" accounts for trailing \0 */
+		if (siz > sizeof(base64_cert) * 3/4) {
+			char *str = "record too long to print";
+			T(addstr(str, strlen(str), &buf, &buflen));
+		}
+		else {
+			len = b64_ntop(rdata, edata-rdata, base64_cert, siz);
+
+			if (len < 0)
+				goto formerr;
+			else if (len > 15) {
+				T(addstr(" (", 2, &buf, &buflen));
+				leader = "\n\t\t";
+				spaced = 0;
+			}
+			else
+				leader = " ";
+	
+			for (n = 0; n < len; n += 48) {
+				T(addstr(leader, strlen(leader),
+					 &buf, &buflen));
+				T(addstr(base64_cert + n, MIN(len - n, 48),
+					 &buf, &buflen));
+			}
+			if (len > 15)
+				T(addstr(" )", 2, &buf, &buflen));
+		}
+		break;
+	    }
+
+	case ns_t_tsig: {
+		/* BEW - need to complete this */
+		int n;
+
+		T(len = addname(msg, msglen, &rdata, origin, &buf, &buflen));
+		T(addstr(" ", 1, &buf, &buflen));
+		rdata += 8; /* time */
+		n = ns_get16(rdata); rdata += INT16SZ;
+		rdata += n; /* sig */
+		n = ns_get16(rdata); rdata += INT16SZ; /* original id */
+		sprintf(buf, "%d", ns_get16(rdata));
+		rdata += INT16SZ;
+		addlen(strlen(buf), &buf, &buflen);
+		break;
+	    }
+
+	default:
+		comment = "unknown RR type";
+		goto hexify;
+	}
+	return (buf - obuf);
+ formerr:
+	comment = "RR format error";
+ hexify: {
+	int n, m;
+	char *p;
+
+	len = SPRINTF((tmp, "\\#(\t\t; %s", comment));
+	T(addstr(tmp, len, &buf, &buflen));
+	while (rdata < edata) {
+		p = tmp;
+		p += SPRINTF((p, "\n\t"));
+		spaced = 0;
+		n = MIN(16, edata - rdata);
+		for (m = 0; m < n; m++)
+			p += SPRINTF((p, "%02x ", rdata[m]));
+		T(addstr(tmp, p - tmp, &buf, &buflen));
+		if (n < 16) {
+			T(addstr(")", 1, &buf, &buflen));
+			T(addtab(p - tmp + 1, 48, spaced, &buf, &buflen));
+		}
+		p = tmp;
+		p += SPRINTF((p, "; "));
+		for (m = 0; m < n; m++)
+			*p++ = (isascii(rdata[m]) && isprint(rdata[m]))
+				? rdata[m]
+				: '.';
+		T(addstr(tmp, p - tmp, &buf, &buflen));
+		rdata += n;
+	}
+	return (buf - obuf);
+    }
+}
+
+/* Private. */
+
+/*
+ * size_t
+ * prune_origin(name, origin)
+ *	Find out if the name is at or under the current origin.
+ * return:
+ *	Number of characters in name before start of origin,
+ *	or length of name if origin does not match.
+ * notes:
+ *	This function should share code with samedomain().
+ */
+static size_t
+prune_origin(const char *name, const char *origin) {
+	const char *oname = name;
+
+	while (*name != '\0') {
+		if (origin != NULL && ns_samename(name, origin) == 1)
+			return (name - oname - (name > oname));
+		while (*name != '\0') {
+			if (*name == '\\') {
+				name++;
+				/* XXX need to handle \nnn form. */
+				if (*name == '\0')
+					break;
+			} else if (*name == '.') {
+				name++;
+				break;
+			}
+			name++;
+		}
+	}
+	return (name - oname);
+}
+
+/*
+ * int
+ * charstr(rdata, edata, buf, buflen)
+ *	Format a <character-string> into the presentation buffer.
+ * return:
+ *	Number of rdata octets consumed
+ *	0 for protocol format error
+ *	-1 for output buffer error
+ * side effects:
+ *	buffer is advanced on success.
+ */
+static int
+charstr(const u_char *rdata, const u_char *edata, char **buf, size_t *buflen) {
+	const u_char *odata = rdata;
+	size_t save_buflen = *buflen;
+	char *save_buf = *buf;
+
+	if (addstr("\"", 1, buf, buflen) < 0)
+		goto enospc;
+	if (rdata < edata) {
+		int n = *rdata;
+
+		if (rdata + 1 + n <= edata) {
+			rdata++;
+			while (n-- > 0) {
+				if (strchr("\n\"\\", *rdata) != NULL)
+					if (addstr("\\", 1, buf, buflen) < 0)
+						goto enospc;
+				if (addstr((const char *)rdata, 1,
+					   buf, buflen) < 0)
+					goto enospc;
+				rdata++;
+			}
+		}
+	}
+	if (addstr("\"", 1, buf, buflen) < 0)
+		goto enospc;
+	return (rdata - odata);
+ enospc:
+	__set_errno (ENOSPC);
+	*buf = save_buf;
+	*buflen = save_buflen;
+	return (-1);
+}
+
+static int
+addname(const u_char *msg, size_t msglen,
+	const u_char **pp, const char *origin,
+	char **buf, size_t *buflen)
+{
+	size_t newlen, save_buflen = *buflen;
+	char *save_buf = *buf;
+	int n;
+
+	n = dn_expand(msg, msg + msglen, *pp, *buf, *buflen);
+	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';
+	}
+	*pp += n;
+	addlen(newlen, buf, buflen);
+	**buf = '\0';
+	return (newlen);
+ enospc:
+	__set_errno (ENOSPC);
+	*buf = save_buf;
+	*buflen = save_buflen;
+	return (-1);
+}
+
+static void
+addlen(size_t len, char **buf, size_t *buflen) {
+#if 0
+	INSIST(len <= *buflen);
+#endif
+	*buf += len;
+	*buflen -= len;
+}
+
+static int
+addstr(const char *src, size_t len, char **buf, size_t *buflen) {
+	if (len >= *buflen) {
+		__set_errno (ENOSPC);
+		return (-1);
+	}
+	memcpy(*buf, src, len);
+	addlen(len, buf, buflen);
+	**buf = '\0';
+	return (0);
+}
+
+static int
+addtab(size_t len, size_t target, int spaced, char **buf, size_t *buflen) {
+	size_t save_buflen = *buflen;
+	char *save_buf = *buf;
+	int t;
+
+	if (spaced || len >= target - 1) {
+		T(addstr("  ", 2, buf, buflen));
+		spaced = 1;
+	} else {
+		for (t = (target - len - 1) / 8; t >= 0; t--)
+			if (addstr("\t", 1, buf, buflen) < 0) {
+				*buflen = save_buflen;
+				*buf = save_buf;
+				return (-1);
+			}
+		spaced = 0;
+	}
+	return (spaced);
+}
diff --git a/resolv/ns_samedomain.c b/resolv/ns_samedomain.c
new file mode 100644
index 0000000000..bac5a639e7
--- /dev/null
+++ b/resolv/ns_samedomain.c
@@ -0,0 +1,202 @@
+/*
+ * Copyright (c) 1995,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.
+ */
+
+#ifndef lint
+static const char rcsid[] = "$Id$";
+#endif
+
+#include <sys/types.h>
+#include <arpa/nameser.h>
+#include <errno.h>
+#include <string.h>
+
+/*
+ * int
+ * ns_samedomain(a, b)
+ *	Check whether a name belongs to a domain.
+ * Inputs:
+ *	a - the domain whose ancestory is being verified
+ *	b - the potential ancestor we're checking against
+ * Return:
+ *	boolean - is a at or below b?
+ * Notes:
+ *	Trailing dots are first removed from name and domain.
+ *	Always compare complete subdomains, not only whether the
+ *	domain name is the trailing string of the given name.
+ *
+ *	"host.foobar.top" lies in "foobar.top" and in "top" and in ""
+ *	but NOT in "bar.top"
+ */
+
+int
+ns_samedomain(const char *a, const char *b) {
+	size_t la, lb;
+	int diff, i, escaped;
+	const char *cp;
+
+	la = strlen(a);
+	lb = strlen(b);
+
+	/* Ignore a trailing label separator (i.e. an unescaped dot) in 'a'. */
+	if (la != 0 && a[la - 1] == '.') {
+		escaped = 0;
+		/* Note this loop doesn't get executed if la==1. */
+		for (i = la - 2; i >= 0; i--)
+			if (a[i] == '\\') {
+				if (escaped)
+					escaped = 0;
+				else
+					escaped = 1;
+			} else
+				break;
+		if (!escaped)
+			la--;
+	}
+
+	/* Ignore a trailing label separator (i.e. an unescaped dot) in 'b'. */
+	if (lb != 0 && b[lb - 1] == '.') {
+		escaped = 0;
+		/* note this loop doesn't get executed if lb==1 */
+		for (i = lb - 2; i >= 0; i--)
+			if (b[i] == '\\') {
+				if (escaped)
+					escaped = 0;
+				else
+					escaped = 1;
+			} else
+				break;
+		if (!escaped)
+			lb--;
+	}
+
+	/* lb == 0 means 'b' is the root domain, so 'a' must be in 'b'. */
+	if (lb == 0)
+		return (1);
+
+	/* 'b' longer than 'a' means 'a' can't be in 'b'. */
+	if (lb > la)
+		return (0);
+
+	/* 'a' and 'b' being equal at this point indicates sameness. */
+	if (lb == la)
+		return (strncasecmp(a, b, lb) == 0);
+
+	/* Ok, we know la > lb. */
+
+	diff = la - lb;
+
+	/*
+	 * If 'a' is only 1 character longer than 'b', then it can't be
+	 * a subdomain of 'b' (because of the need for the '.' label
+	 * separator).
+	 */
+	if (diff < 2)
+		return (0);
+
+	/*
+	 * If the character before the last 'lb' characters of 'b'
+	 * isn't '.', then it can't be a match (this lets us avoid
+	 * having "foobar.com" match "bar.com").
+	 */
+	if (a[diff - 1] != '.')
+		return (0);
+
+	/*
+	 * We're not sure about that '.', however.  It could be escaped
+         * and thus not a really a label separator.
+	 */
+	escaped = 0;
+	for (i = diff - 2; i >= 0; i--)
+		if (a[i] == '\\')
+			if (escaped)
+				escaped = 0;
+			else
+				escaped = 1;
+		else
+			break;
+	if (escaped)
+		return (0);
+	  
+	/* Now compare aligned trailing substring. */
+	cp = a + diff;
+	return (strncasecmp(cp, b, lb) == 0);
+}
+
+/*
+ * int
+ * ns_subdomain(a, b)
+ *	is "a" a subdomain of "b"?
+ */
+int
+ns_subdomain(const char *a, const char *b) {
+	return (ns_samename(a, b) != 1 && ns_samedomain(a, b));
+}
+
+/*
+ * int
+ * ns_makecanon(src, dst, dstsize)
+ *	make a canonical copy of domain name "src"
+ * notes:
+ *	foo -> foo.
+ *	foo. -> foo.
+ *	foo.. -> foo.
+ *	foo\. -> foo\..
+ *	foo\\. -> foo\\.
+ */
+
+int
+ns_makecanon(const char *src, char *dst, size_t dstsize) {
+	size_t n = strlen(src);
+
+	if (n + sizeof "." > dstsize) {
+		__set_errno (EMSGSIZE);
+		return (-1);
+	}
+	strcpy(dst, src);
+	while (n > 0 && dst[n - 1] == '.')		/* Ends in "." */
+		if (n > 1 && dst[n - 2] == '\\' &&	/* Ends in "\." */
+		    (n < 2 || dst[n - 3] != '\\'))	/* But not "\\." */
+			break;
+		else
+			dst[--n] = '\0';
+	dst[n++] = '.';
+	dst[n] = '\0';
+	return (0);
+}
+
+/*
+ * int
+ * ns_samename(a, b)
+ *	determine whether domain name "a" is the same as domain name "b"
+ * return:
+ *	-1 on error
+ *	0 if names differ
+ *	1 if names are the same
+ */
+
+int
+ns_samename(const char *a, const char *b) {
+	char ta[NS_MAXDNAME], tb[NS_MAXDNAME];
+
+	if (ns_makecanon(a, ta, sizeof ta) < 0 ||
+	    ns_makecanon(b, tb, sizeof tb) < 0)
+		return (-1);
+	if (strcasecmp(ta, tb) == 0)
+		return (1);
+	else
+		return (0);
+}
diff --git a/resolv/ns_ttl.c b/resolv/ns_ttl.c
new file mode 100644
index 0000000000..6be2b0d7a7
--- /dev/null
+++ b/resolv/ns_ttl.c
@@ -0,0 +1,154 @@
+/*
+ * 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.
+ */
+
+#ifndef lint
+static const char rcsid[] = "$Id$";
+#endif
+
+/* Import. */
+#include <arpa/nameser.h>
+
+#include <ctype.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+
+#ifdef SPRINTF_CHAR
+# define SPRINTF(x) strlen(sprintf/**/x)
+#else
+# define SPRINTF(x) ((size_t)sprintf x)
+#endif
+
+/* Forward. */
+
+static int	fmt1(int t, char s, char **buf, size_t *buflen);
+
+/* Macros. */
+
+#define T(x) if ((x) < 0) return (-1); else (void)NULL
+
+/* Public. */
+
+int
+ns_format_ttl(u_long src, char *dst, size_t dstlen) {
+	char *odst = dst;
+	int secs, mins, hours, days, weeks, x;
+	char *p;
+
+	secs = src % 60;   src /= 60;
+	mins = src % 60;   src /= 60;
+	hours = src % 24;  src /= 24;
+	days = src % 7;    src /= 7;
+	weeks = src;       src = 0;
+
+	x = 0;
+	if (weeks) {
+		T(fmt1(weeks, 'W', &dst, &dstlen));
+		x++;
+	}
+	if (days) {
+		T(fmt1(days, 'D', &dst, &dstlen));
+		x++;
+	}
+	if (hours) {
+		T(fmt1(hours, 'H', &dst, &dstlen));
+		x++;
+	}
+	if (mins) {
+		T(fmt1(mins, 'M', &dst, &dstlen));
+		x++;
+	}
+	if (secs || !(weeks || days || hours || mins)) {
+		T(fmt1(secs, 'S', &dst, &dstlen));
+		x++;
+	}
+
+	if (x > 1) {
+		int ch;
+
+		for (p = odst; (ch = *p) != '\0'; p++)
+			if (isascii(ch) && isupper(ch))
+				*p = tolower(ch);
+	}
+
+	return (dst - odst);
+}
+
+int
+ns_parse_ttl(const char *src, u_long *dst) {
+	u_long ttl, tmp;
+	int ch, digits, dirty;
+
+	ttl = 0;
+	tmp = 0;
+	digits = 0;
+	dirty = 0;
+	while ((ch = *src++) != '\0') {
+		if (!isascii(ch) || !isprint(ch))
+			goto einval;
+		if (isdigit(ch)) {
+			tmp *= 10;
+			tmp += (ch - '0');
+			digits++;
+			continue;
+		}
+		if (digits == 0)
+			goto einval;
+		if (islower(ch))
+			ch = toupper(ch);
+		switch (ch) {
+		case 'W':  tmp *= 7;
+		case 'D':  tmp *= 24;
+		case 'H':  tmp *= 60;
+		case 'M':  tmp *= 60;
+		case 'S':  break;
+		default:   goto einval;
+		}
+		ttl += tmp;
+		tmp = 0;
+		digits = 0;
+		dirty = 1;
+	}
+	if (digits > 0) {
+		if (dirty)
+			goto einval;
+		else
+			ttl += tmp;
+	}
+	*dst = ttl;
+	return (0);
+
+ einval:
+	__set_errno (EINVAL);
+	return (-1);
+}
+
+/* Private. */
+
+static int
+fmt1(int t, char s, char **buf, size_t *buflen) {
+	char tmp[50];
+	size_t len;
+
+	len = SPRINTF((tmp, "%d%c", t, s));
+	if (len + 1 > *buflen)
+		return (-1);
+	strcpy(*buf, tmp);
+	*buf += len;
+	*buflen -= len;
+	return (0);
+}
diff --git a/resolv/nsap_addr.c b/resolv/nsap_addr.c
index 53a19d59be..c1c9a61d35 100644
--- a/resolv/nsap_addr.c
+++ b/resolv/nsap_addr.c
@@ -28,31 +28,14 @@ static char rcsid[] = "$Id$";
 #include <ctype.h>
 #include <resolv.h>
 
-#include "../conf/portability.h"
-
-#if !defined(isxdigit)	/* XXX - could be a function */
-static int
-isxdigit(c)
-	register int c;
-{
-	return ((c >= '0') && (c <= '9')) || ((c >= 'A') && (c <= 'F'));
-}
-#endif
-
 static char
-xtob(c)
-	register int c;
-{
+xtob(int c) {
 	return (c - (((c >= '0') && (c <= '9')) ? '0' : '7'));
 }
 
 u_int
-inet_nsap_addr(ascii, binary, maxlen)
-	const char *ascii;
-	u_char *binary;
-	int maxlen;
-{
-	register u_char c, nib;
+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) {
@@ -63,7 +46,8 @@ inet_nsap_addr(ascii, binary, maxlen)
 		c = toupper(c);
 		if (isxdigit(c)) {
 			nib = xtob(c);
-			if ((c = *ascii++)) {
+			c = *ascii++;
+			if (c != '\0') {
 				c = toupper(c);
 				if (isxdigit(c)) {
 					*binary++ = (nib << 4) | xtob(c);
@@ -81,12 +65,8 @@ inet_nsap_addr(ascii, binary, maxlen)
 }
 
 char *
-inet_nsap_ntoa(binlen, binary, ascii)
-	int binlen;
-	register const u_char *binary;
-	register char *ascii;
-{
-	register int nib;
+inet_nsap_ntoa(int binlen, const u_char *binary, char *ascii) {
+	int nib;
 	int i;
 	static char tmpbuf[255*3];
 	char *start;
diff --git a/resolv/nss_dns/dns-host.c b/resolv/nss_dns/dns-host.c
index 482cbd3ab4..483e791801 100644
--- a/resolv/nss_dns/dns-host.c
+++ b/resolv/nss_dns/dns-host.c
@@ -133,6 +133,9 @@ _nss_dns_gethostbyname2_r (const char *name, int af, struct hostent *result,
   int size, type, n;
   const char *cp;
 
+  if ((_res.options & RES_INIT) == 0 && __res_ninit (&_res) == -1)
+    return NSS_STATUS_UNAVAIL;
+
   switch (af) {
   case AF_INET:
     size = INADDRSZ;
@@ -159,7 +162,8 @@ _nss_dns_gethostbyname2_r (const char *name, int af, struct hostent *result,
   if (strchr (name, '.') == NULL && (cp = __hostalias (name)) != NULL)
     name = cp;
 
-  n = res_search (name, C_IN, type, host_buffer.buf, sizeof (host_buffer.buf));
+  n = res_nsearch (&_res, name, C_IN, type, host_buffer.buf,
+		   sizeof (host_buffer.buf));
   if (n < 0)
     {
       *h_errnop = h_errno;
@@ -211,6 +215,9 @@ _nss_dns_gethostbyaddr_r (const char *addr, size_t len, int af,
   size_t size;
   int n, status;
 
+  if ((_res.options & RES_INIT) == 0 && __res_ninit (&_res) == -1)
+    return NSS_STATUS_UNAVAIL;
+
   if (af == AF_INET6 && len == IN6ADDRSZ
       && (memcmp (uaddr, mapped, sizeof mapped) == 0
 	  || (memcmp (uaddr, tunnelled, sizeof tunnelled) == 0
@@ -259,8 +266,8 @@ _nss_dns_gethostbyaddr_r (const char *addr, size_t len, int af,
       /* Cannot happen.  */
     }
 
-  n = res_query (qbuf, C_IN, T_PTR, (u_char *)host_buffer.buf,
-		 sizeof host_buffer);
+  n = res_nquery (&_res, qbuf, C_IN, T_PTR, (u_char *)host_buffer.buf,
+		  sizeof host_buffer);
   if (n < 0)
     {
       *h_errnop = h_errno;
@@ -435,11 +442,11 @@ getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype,
 	  continue;
 	}
       cp += n;				/* name */
-      type = _getshort (cp);
+      type = ns_get16 (cp);
       cp += INT16SZ;			/* type */
-      class = _getshort (cp);
+      class = ns_get16 (cp);
       cp += INT16SZ + INT32SZ;		/* class, TTL */
-      n = _getshort (cp);
+      n = ns_get16 (cp);
       cp += INT16SZ;			/* len */
       if (class != C_IN)
 	{
diff --git a/resolv/nss_dns/dns-network.c b/resolv/nss_dns/dns-network.c
index f81341cb39..b194852197 100644
--- a/resolv/nss_dns/dns-network.c
+++ b/resolv/nss_dns/dns-network.c
@@ -113,9 +113,12 @@ _nss_dns_getnetbyname_r (const char *name, struct netent *result,
   int anslen;
   char *qbuf;
 
+  if ((_res.options & RES_INIT) == 0 && __res_ninit (&_res) == -1)
+    return NSS_STATUS_UNAVAIL;
+
   qbuf = strdupa (name);
-  anslen = res_search (qbuf, C_IN, T_PTR, (u_char *) &net_buffer,
-		       sizeof (querybuf));
+  anslen = res_nsearch (&_res, qbuf, C_IN, T_PTR, (u_char *) &net_buffer,
+			sizeof (querybuf));
   if (anslen < 0)
     {
       /* Nothing found.  */
@@ -146,6 +149,9 @@ _nss_dns_getnetbyaddr_r (long net, int type, struct netent *result,
   if (type != AF_INET)
     return NSS_STATUS_UNAVAIL;
 
+  if ((_res.options & RES_INIT) == 0 && __res_ninit (&_res) == -1)
+    return NSS_STATUS_UNAVAIL;
+  
   net2 = (u_int32_t) net;
   for (cnt = 4; net2 != 0; net2 >>= 8)
     net_bytes[--cnt] = net2 & 0xff;
@@ -172,8 +178,8 @@ _nss_dns_getnetbyaddr_r (long net, int type, struct netent *result,
       break;
     }
 
-  anslen = res_query (qbuf, C_IN, T_PTR, (u_char *) &net_buffer,
-		      sizeof (querybuf));
+  anslen = res_nquery (&_res, qbuf, C_IN, T_PTR, (u_char *) &net_buffer,
+		       sizeof (querybuf));
   if (anslen < 0)
     {
       /* Nothing found.  */
diff --git a/resolv/res_comp.c b/resolv/res_comp.c
index 2d90e37794..e6f54ce06a 100644
--- a/resolv/res_comp.c
+++ b/resolv/res_comp.c
@@ -1,6 +1,4 @@
 /*
- * ++Copyright++ 1985, 1993
- * -
  * Copyright (c) 1985, 1993
  *    The Regents of the University of California.  All rights reserved.
  *
@@ -45,13 +43,28 @@
  * 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[] = "@(#)res_comp.c	8.1 (Berkeley) 6/4/93";
-static char rcsid[] = "$Id$";
+static const char sccsid[] = "@(#)res_comp.c	8.1 (Berkeley) 6/4/93";
+static const char rcsid[] = "$Id$";
 #endif /* LIBC_SCCS and not lint */
 
 #include <sys/types.h>
@@ -64,24 +77,9 @@ static char rcsid[] = "$Id$";
 #include <resolv.h>
 #include <stdio.h>
 
-#if defined(BSD) && (BSD >= 199103)
-# include <unistd.h>
-# include <string.h>
-#else
-# include "../conf/portability.h"
-#endif
+#include <string.h>
+#include <unistd.h>
 
-extern int	__ns_name_ntop __P((const u_char *, char *, size_t));
-static int	ns_name_pton __P((const char *, u_char *, size_t));
-extern int	__ns_name_unpack __P((const u_char *, const u_char *,
-				      const u_char *, u_char *, size_t));
-static int	ns_name_pack __P((const u_char *, u_char *, int,
-				  const u_char **, const u_char **));
-static int	ns_name_uncompress __P((const u_char *, const u_char *,
-					const u_char *, char *, size_t));
-static int	ns_name_compress __P((const char *, u_char *, size_t,
-				      const u_char **, const u_char **));
-static int	ns_name_skip __P((const u_char **, const u_char *));
 
 /*
  * Expand compressed domain name 'comp_dn' to full domain name.
@@ -91,12 +89,8 @@ static int	ns_name_skip __P((const u_char **, const u_char *));
  * Return size of compressed name or -1 if there was an error.
  */
 int
-dn_expand(msg, eom, src, dst, dstsiz)
-	const u_char *msg;
-	const u_char *eom;
-	const u_char *src;
-	char *dst;
-	int dstsiz;
+dn_expand(const u_char *msg, const u_char *eom, const u_char *src,
+	  char *dst, int dstsiz)
 {
 	int n = ns_name_uncompress(msg, eom, src, dst, (size_t)dstsiz);
 
@@ -111,12 +105,8 @@ dn_expand(msg, eom, src, dst, dstsiz)
  * 'length' is the size of the array pointed to by 'comp_dn'.
  */
 int
-dn_comp(src, dst, dstsiz, dnptrs, lastdnptr)
-	const char *src;
-	u_char *dst;
-	int dstsiz;
-	u_char **dnptrs;
-	u_char **lastdnptr;
+dn_comp(const char *src, u_char *dst, int dstsiz,
+	u_char **dnptrs, u_char **lastdnptr)
 {
 	return (ns_name_compress(src, dst, (size_t)dstsiz,
 				 (const u_char **)dnptrs,
@@ -127,10 +117,7 @@ dn_comp(src, dst, dstsiz, dnptrs, lastdnptr)
  * Skip over a compressed domain name. Return the size or -1.
  */
 int
-__dn_skipname(ptr, eom)
-	const u_char *ptr;
-	const u_char *eom;
-{
+dn_skipname(const u_char *ptr, const u_char *eom) {
 	const u_char *saveptr = ptr;
 
 	if (ns_name_skip(&ptr, eom) == -1)
@@ -163,9 +150,7 @@ __dn_skipname(ptr, eom)
 #define	domainchar(c) ((c) > 0x20 && (c) < 0x7f)
 
 int
-res_hnok(dn)
-	const char *dn;
-{
+res_hnok(const char *dn) {
 	int ppch = '\0', pch = PERIOD, ch = *dn++;
 
 	while (ch != '\0') {
@@ -193,9 +178,7 @@ res_hnok(dn)
  * but must otherwise be as a host name.
  */
 int
-res_ownok(dn)
-	const char *dn;
-{
+res_ownok(const char *dn) {
 	if (asterchar(dn[0])) {
 		if (periodchar(dn[1]))
 			return (res_hnok(dn+2));
@@ -210,9 +193,7 @@ res_ownok(dn)
  * label, but the rest of the name has to look like a host name.
  */
 int
-res_mailok(dn)
-	const char *dn;
-{
+res_mailok(const char *dn) {
 	int ch, escaped = 0;
 
 	/* "." is a valid missing representation */
@@ -232,7 +213,7 @@ res_mailok(dn)
 	}
 	if (periodchar(ch))
 		return (res_hnok(dn));
-	return(0);
+	return (0);
 }
 
 /*
@@ -240,9 +221,7 @@ res_mailok(dn)
  * recommendations.
  */
 int
-res_dnok(dn)
-	const char *dn;
-{
+res_dnok(const char *dn) {
 	int ch;
 
 	while ((ch = *dn++) != '\0')
@@ -251,700 +230,19 @@ res_dnok(dn)
 	return (1);
 }
 
+#ifdef BIND_4_COMPAT
 /*
- * Routines to insert/extract short/long's.
+ * This module must export the following externally-visible symbols:
+ *	___putlong
+ *	___putshort
+ *	__getlong
+ *	__getshort
+ * Note that one _ comes from C and the others come from us.
  */
-
-u_int16_t
-_getshort(msgp)
-	register const u_char *msgp;
-{
-	register u_int16_t u;
-
-	GETSHORT(u, msgp);
-	return (u);
-}
-
-#ifdef NeXT
-/*
- * nExt machines have some funky library conventions, which we must maintain.
- */
-u_int16_t
-res_getshort(msgp)
-	register const u_char *msgp;
-{
-	return (_getshort(msgp));
-}
-#endif
-
-u_int32_t
-_getlong(msgp)
-	register const u_char *msgp;
-{
-	register u_int32_t u;
-
-	GETLONG(u, msgp);
-	return (u);
-}
-
-void
-#if defined(__STDC__) || defined(__cplusplus)
-__putshort(register u_int16_t s, register u_char *msgp)	/* must match proto */
-#else
-__putshort(s, msgp)
-	register u_int16_t s;
-	register u_char *msgp;
-#endif
-{
-	PUTSHORT(s, msgp);
-}
-
-void
-__putlong(l, msgp)
-	register u_int32_t l;
-	register u_char *msgp;
-{
-	PUTLONG(l, msgp);
-}
-
-/* ++ From BIND 8.1.1. ++ */
-/*
- * Copyright (c) 1996 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.
- */
-
-/*"Id: ns_name.c,v 1.1 1997/12/13 02:41:13 vixie Exp vixie"*/
-
-/*#include "port_before.h"*/
-
-/*#include <sys/types.h>*/
-
-/*#include <netinet/in.h>*/
-/*#include <arpa/nameser.h>*/
-
-/*#include <errno.h>*/
-/*#include <resolv.h>*/
-/*#include <string.h>*/
-
-/*#include "port_after.h"*/
-
-#define NS_CMPRSFLGS	0xc0	/* Flag bits indicating name compression. */
-#define NS_MAXCDNAME	255	/* maximum compressed domain name */
-
-/* Data. */
-
-static const char	digits[] = "0123456789";
-
-/* Forward. */
-
-static int		special(int);
-static int		printable(int);
-static int		dn_find(const u_char *, const u_char *,
-				const u_char * const *,
-				const u_char * const *);
-
-/* Public. */
-
-/*
- * ns_name_ntop(src, dst, dstsiz)
- *	Convert an encoded domain name to printable ascii as per RFC1035.
- * return:
- *	Number of bytes written to buffer, or -1 (with errno set)
- * notes:
- *	The root is returned as "."
- *	All other domains are returned in non absolute form
- */
-int
-__ns_name_ntop(src, dst, dstsiz)
-	const u_char *src;
-	char *dst;
-	size_t dstsiz;
-{
-	const u_char *cp;
-	char *dn, *eom;
-	u_char c;
-	u_int n;
-
-	cp = src;
-	dn = dst;
-	eom = dst + dstsiz;
-
-	while ((n = *cp++) != 0) {
-		if ((n & NS_CMPRSFLGS) != 0) {
-			/* Some kind of compression pointer. */
-			__set_errno (EINVAL);
-			return (-1);
-		}
-		if (dn != dst) {
-			if (dn >= eom) {
-				__set_errno (EMSGSIZE);
-				return (-1);
-			}
-			*dn++ = '.';
-		}
-		if (dn + n >= eom) {
-			__set_errno (EMSGSIZE);
-			return (-1);
-		}
-		for ((void)NULL; n > 0; n--) {
-			c = *cp++;
-			if (special(c)) {
-				if (dn + 1 >= eom) {
-					__set_errno (EMSGSIZE);
-					return (-1);
-				}
-				*dn++ = '\\';
-				*dn++ = (char)c;
-			} else if (!printable(c)) {
-				if (dn + 3 >= eom) {
-					__set_errno (EMSGSIZE);
-					return (-1);
-				}
-				*dn++ = '\\';
-				*dn++ = digits[c / 100];
-				*dn++ = digits[(c % 100) / 10];
-				*dn++ = digits[c % 10];
-			} else {
-				if (dn >= eom) {
-					__set_errno (EMSGSIZE);
-					return (-1);
-				}
-				*dn++ = (char)c;
-			}
-		}
-	}
-	if (dn == dst) {
-		if (dn >= eom) {
-			__set_errno (EMSGSIZE);
-			return (-1);
-		}
-		*dn++ = '.';
-	}
-	if (dn >= eom) {
-		__set_errno (EMSGSIZE);
-		return (-1);
-	}
-	*dn++ = '\0';
-	return (dn - dst);
-}
-
-/*
- * ns_name_pton(src, dst, dstsiz)
- *	Convert a ascii string into an encoded domain name as per RFC1035.
- * return:
- *	-1 if it fails
- *	1 if string was fully qualified
- *	0 is string was not fully qualified
- * notes:
- *	Enforces label and domain length limits.
- */
-
-static int
-ns_name_pton(src, dst, dstsiz)
-	const char *src;
-	u_char *dst;
-	size_t dstsiz;
-{
-	u_char *label, *bp, *eom;
-	int c, n, escaped;
-	char *cp;
-
-	escaped = 0;
-	bp = dst;
-	eom = dst + dstsiz;
-	label = bp++;
-
-	while ((c = *src++) != 0) {
-		if (escaped) {
-			if ((cp = strchr(digits, c)) != NULL) {
-				n = (cp - digits) * 100;
-				if ((c = *src++) == 0 ||
-				    (cp = strchr(digits, c)) == NULL) {
-					__set_errno (EMSGSIZE);
-					return (-1);
-				}
-				n += (cp - digits) * 10;
-				if ((c = *src++) == 0 ||
-				    (cp = strchr(digits, c)) == NULL) {
-					__set_errno (EMSGSIZE);
-					return (-1);
-				}
-				n += (cp - digits);
-				if (n > 255) {
-					__set_errno (EMSGSIZE);
-					return (-1);
-				}
-				c = n;
-			}
-			escaped = 0;
-		} else if (c == '\\') {
-			escaped = 1;
-			continue;
-		} else if (c == '.') {
-			c = (bp - label - 1);
-			if ((c & NS_CMPRSFLGS) != 0) {	/* Label too big. */
-				__set_errno (EMSGSIZE);
-				return (-1);
-			}
-			if (label >= eom) {
-				__set_errno (EMSGSIZE);
-				return (-1);
-			}
-			*label = c;
-			/* Fully qualified ? */
-			if (*src == '\0') {
-				if (c != 0) {
-					if (bp >= eom) {
-						__set_errno (EMSGSIZE);
-						return (-1);
-					}
-					*bp++ = '\0';
-				}
-				if ((bp - dst) > MAXCDNAME) {
-					__set_errno (EMSGSIZE);
-					return (-1);
-				}
-				return (1);
-			}
-			if (c == 0) {
-				__set_errno (EMSGSIZE);
-				return (-1);
-			}
-			label = bp++;
-			continue;
-		}
-		if (bp >= eom) {
-			__set_errno (EMSGSIZE);
-			return (-1);
-		}
-		*bp++ = (u_char)c;
-	}
-	c = (bp - label - 1);
-	if ((c & NS_CMPRSFLGS) != 0) {		/* Label too big. */
-		__set_errno (EMSGSIZE);
-		return (-1);
-	}
-	if (label >= eom) {
-		__set_errno (EMSGSIZE);
-		return (-1);
-	}
-	*label = c;
-	if (c != 0) {
-		if (bp >= eom) {
-			__set_errno (EMSGSIZE);
-			return (-1);
-		}
-		*bp++ = 0;
-	}
-	if ((bp - dst) > MAXCDNAME) {	/* src too big */
-		__set_errno (EMSGSIZE);
-		return (-1);
-	}
-	return (0);
-}
-
-/*
- * ns_name_unpack(msg, eom, src, dst, dstsiz)
- *	Unpack a domain name from a message, source may be compressed.
- * return:
- *	-1 if it fails, or consumed octets if it succeeds.
- */
-int
-__ns_name_unpack(msg, eom, src, dst, dstsiz)
-	const u_char *msg;
-	const u_char *eom;
-	const u_char *src;
-	u_char *dst;
-	size_t dstsiz;
-{
-	const u_char *srcp, *dstlim;
-	u_char *dstp;
-#ifdef _LIBC
-	/* We don't want warnings!  */
-	int n, len, checked;
-#else
-	int n, c, len, checked;
-#endif
-
-	len = -1;
-	checked = 0;
-	dstp = dst;
-	srcp = src;
-	dstlim = dst + dstsiz;
-	if (srcp < msg || srcp >= eom) {
-		__set_errno (EMSGSIZE);
-		return (-1);
-	}
-	/* Fetch next label in domain name. */
-	while ((n = *srcp++) != 0) {
-		/* Check for indirection. */
-		switch (n & NS_CMPRSFLGS) {
-		case 0:
-			/* Limit checks. */
-			if (dstp + n + 1 >= dstlim || srcp + n >= eom) {
-				__set_errno (EMSGSIZE);
-				return (-1);
-			}
-			checked += n + 1;
-			*dstp++ = n;
-			memcpy(dstp, srcp, n);
-			dstp += n;
-			srcp += n;
-			break;
-
-		case NS_CMPRSFLGS:
-			if (srcp >= eom) {
-				__set_errno (EMSGSIZE);
-				return (-1);
-			}
-			if (len < 0)
-				len = srcp - src + 1;
-			srcp = msg + (((n & 0x3f) << 8) | (*srcp & 0xff));
-			if (srcp < msg || srcp >= eom) {  /* Out of range. */
-				__set_errno (EMSGSIZE);
-				return (-1);
-			}
-			checked += 2;
-			/*
-			 * Check for loops in the compressed name;
-			 * if we've looked at the whole message,
-			 * there must be a loop.
-			 */
-			if (checked >= eom - msg) {
-				__set_errno (EMSGSIZE);
-				return (-1);
-			}
-			break;
-
-		default:
-			__set_errno (EMSGSIZE);
-			return (-1);			/* flag error */
-		}
-	}
-	*dstp = '\0';
-	if (len < 0)
-		len = srcp - src;
-	return (len);
-}
-
-/*
- * ns_name_pack(src, dst, dstsiz, dnptrs, lastdnptr)
- *	Pack domain name 'domain' into 'comp_dn'.
- * return:
- *	Size of the compressed name, or -1.
- * notes:
- *	'dnptrs' is an array of pointers to previous compressed names.
- *	dnptrs[0] is a pointer to the beginning of the message. The array
- *	ends with NULL.
- *	'lastdnptr' is a pointer to the end of the array pointed to
- *	by 'dnptrs'.
- * Side effects:
- *	The list of pointers in dnptrs is updated for labels inserted into
- *	the message as we compress the name.  If 'dnptr' is NULL, we don't
- *	try to compress names. If 'lastdnptr' is NULL, we don't update the
- *	list.
- */
-static int
-ns_name_pack(src, dst, dstsiz, dnptrs, lastdnptr)
-	const u_char *src;
-	u_char *dst;
-	int dstsiz;
-	const u_char **dnptrs;
-	const u_char **lastdnptr;
-{
-	u_char *dstp;
-	const u_char **cpp, **lpp, *eob, *msg;
-	const u_char *srcp;
-	int n, l;
-
-	srcp = src;
-	dstp = dst;
-	eob = dstp + dstsiz;
-	lpp = cpp = NULL;
-	if (dnptrs != NULL) {
-		if ((msg = *dnptrs++) != NULL) {
-			for (cpp = dnptrs; *cpp != NULL; cpp++)
-				(void)NULL;
-			lpp = cpp;	/* end of list to search */
-		}
-	} else
-		msg = NULL;
-
-	/* make sure the domain we are about to add is legal */
-	l = 0;
-	do {
-		n = *srcp;
-		if ((n & NS_CMPRSFLGS) != 0) {
-			__set_errno (EMSGSIZE);
-			return (-1);
-		}
-		l += n + 1;
-		if (l > MAXCDNAME) {
-			__set_errno (EMSGSIZE);
-			return (-1);
-		}
-		srcp += n + 1;
-	} while (n != 0);
-
-	srcp = src;
-	do {
-		/* Look to see if we can use pointers. */
-		n = *srcp;
-		if (n != 0 && msg != NULL) {
-			l = dn_find(srcp, msg, (const u_char * const *)dnptrs,
-				    (const u_char * const *)lpp);
-			if (l >= 0) {
-				if (dstp + 1 >= eob) {
-					__set_errno (EMSGSIZE);
-					return (-1);
-				}
-				*dstp++ = (l >> 8) | NS_CMPRSFLGS;
-				*dstp++ = l % 256;
-				return (dstp - dst);
-			}
-			/* Not found, save it. */
-			if (lastdnptr != NULL && cpp < lastdnptr - 1 &&
-			    (dstp - msg) < 0x4000) {
-				*cpp++ = dstp;
-				*cpp = NULL;
-			}
-		}
-		/* copy label to buffer */
-		if (n & NS_CMPRSFLGS) {		/* Should not happen. */
-			__set_errno (EMSGSIZE);
-			return (-1);
-		}
-		if (dstp + 1 + n >= eob) {
-			__set_errno (EMSGSIZE);
-			return (-1);
-		}
-		memcpy(dstp, srcp, n + 1);
-		srcp += n + 1;
-		dstp += n + 1;
-	} while (n != 0);
-
-	if (dstp > eob) {
-		if (msg != NULL)
-			*lpp = NULL;
-		__set_errno (EMSGSIZE);
-		return (-1);
-	}
-	return (dstp - dst);
-}
-
-/*
- * ns_name_uncompress(msg, eom, src, dst, dstsiz)
- *	Expand compressed domain name to presentation format.
- * return:
- *	Number of bytes read out of `src', or -1 (with errno set).
- * note:
- *	Root domain returns as "." not "".
- */
-static int
-ns_name_uncompress(msg, eom, src, dst, dstsiz)
-	const u_char *msg;
-	const u_char *eom;
-	const u_char *src;
-	char *dst;
-	size_t dstsiz;
-{
-	u_char tmp[NS_MAXCDNAME];
-	int n;
-
-	if ((n = __ns_name_unpack(msg, eom, src, tmp, sizeof tmp)) == -1)
-		return (-1);
-	if (__ns_name_ntop(tmp, dst, dstsiz) == -1)
-		return (-1);
-	return (n);
-}
-
-/*
- * ns_name_compress(src, dst, dstsiz, dnptrs, lastdnptr)
- *	Compress a domain name into wire format, using compression pointers.
- * return:
- *	Number of bytes consumed in `dst' or -1 (with errno set).
- * notes:
- *	'dnptrs' is an array of pointers to previous compressed names.
- *	dnptrs[0] is a pointer to the beginning of the message.
- *	The list ends with NULL.  'lastdnptr' is a pointer to the end of the
- *	array pointed to by 'dnptrs'. Side effect is to update the list of
- *	pointers for labels inserted into the message as we compress the name.
- *	If 'dnptr' is NULL, we don't try to compress names. If 'lastdnptr'
- *	is NULL, we don't update the list.
- */
-static int
-ns_name_compress(src, dst, dstsiz, dnptrs, lastdnptr)
-	const char *src;
-	u_char *dst;
-	size_t dstsiz;
-	const u_char **dnptrs;
-	const u_char **lastdnptr;
-{
-	u_char tmp[NS_MAXCDNAME];
-
-	if (ns_name_pton(src, tmp, sizeof tmp) == -1)
-		return (-1);
-	return (ns_name_pack(tmp, dst, dstsiz, dnptrs, lastdnptr));
-}
-
-/*
- * ns_name_skip(ptrptr, eom)
- *	Advance *ptrptr to skip over the compressed name it points at.
- * return:
- *	0 on success, -1 (with errno set) on failure.
- */
-static int
-ns_name_skip(ptrptr, eom)
-	const u_char **ptrptr;
-	const u_char *eom;
-{
-	const u_char *cp;
-	u_int n;
-
-	cp = *ptrptr;
-	while (cp < eom && (n = *cp++) != 0) {
-		/* Check for indirection. */
-		switch (n & NS_CMPRSFLGS) {
-		case 0:			/* normal case, n == len */
-			cp += n;
-			continue;
-		case NS_CMPRSFLGS:	/* indirection */
-			cp++;
-			break;
-		default:		/* illegal type */
-			__set_errno (EMSGSIZE);
-			return (-1);
-		}
-		break;
-	}
-	if (cp > eom) {
-		__set_errno (EMSGSIZE);
-		return (-1);
-	}
-	*ptrptr = cp;
-	return (0);
-}
-
-/* Private. */
-
-/*
- * special(ch)
- *	Thinking in noninternationalized USASCII (per the DNS spec),
- *	is this characted special ("in need of quoting") ?
- * return:
- *	boolean.
- */
-static int
-special(ch)
-	int ch;
-{
-	switch (ch) {
-	case 0x22: /* '"' */
-	case 0x2E: /* '.' */
-	case 0x3B: /* ';' */
-	case 0x5C: /* '\\' */
-	/* Special modifiers in zone files. */
-	case 0x40: /* '@' */
-	case 0x24: /* '$' */
-		return (1);
-	default:
-		return (0);
-	}
-}
-
-/*
- * printable(ch)
- *	Thinking in noninternationalized USASCII (per the DNS spec),
- *	is this character visible and not a space when printed ?
- * return:
- *	boolean.
- */
-static int
-printable(ch)
-	int ch;
-{
-	return (ch > 0x20 && ch < 0x7f);
-}
-
-/*
- *	Thinking in noninternationalized USASCII (per the DNS spec),
- *	convert this character to lower case if it's upper case.
- */
-static int
-mklower(ch)
-	int ch;
-{
-	if (ch >= 0x41 && ch <= 0x5A)
-		return (ch + 0x20);
-	return (ch);
-}
-
-/*
- * dn_find(domain, msg, dnptrs, lastdnptr)
- *	Search for the counted-label name in an array of compressed names.
- * return:
- *	offset from msg if found, or -1.
- * notes:
- *	dnptrs is the pointer to the first name on the list,
- *	not the pointer to the start of the message.
- */
-static int
-dn_find(domain, msg, dnptrs, lastdnptr)
-	const u_char *domain;
-	const u_char *msg;
-	const u_char * const *dnptrs;
-	const u_char * const *lastdnptr;
-{
-	const u_char *dn, *cp, *sp;
-	const u_char * const *cpp;
-	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++))
-						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: ;
-	}
-	__set_errno (ENOENT);
-	return (-1);
-}
-
-/* -- From BIND 8.1.1. -- */
+void __putlong(u_int32_t src, u_char *dst) { ns_put32(src, dst); }
+void __putshort(u_int16_t src, u_char *dst) { ns_put16(src, dst); }
+#ifndef __ultrix__
+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*/
diff --git a/resolv/res_data.c b/resolv/res_data.c
index aa3ecbd77c..a9f5a2ad67 100644
--- a/resolv/res_data.c
+++ b/resolv/res_data.c
@@ -1,76 +1,42 @@
 /*
- * ++Copyright++ 1995
- * -
- * Copyright (c) 1995
- *    The Regents of the University of California.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * -
- * Portions Copyright (c) 1993 by Digital Equipment Corporation.
+ * Copyright (c) 1995-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 rcsid[] = "$Id$";
+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 <stdio.h>
 #include <ctype.h>
+#include <netdb.h>
 #include <resolv.h>
-#if defined(BSD) && (BSD >= 199103)
-# include <unistd.h>
-# include <stdlib.h>
-# include <string.h>
-#else
-# include "../conf/portability.h"
-#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#undef _res
 
 const char *_res_opcodes[] = {
 	"QUERY",
@@ -78,26 +44,7 @@ const char *_res_opcodes[] = {
 	"CQUERYM",
 	"CQUERYU",	/* experimental */
 	"NOTIFY",	/* experimental */
-	"5",
-	"6",
-	"7",
-	"8",
-	"UPDATEA",
-	"UPDATED",
-	"UPDATEDA",
-	"UPDATEM",
-	"UPDATEMA",
-	"ZONEINIT",
-	"ZONEREF",
-};
-
-const char *_res_resultcodes[] = {
-	"NOERROR",
-	"FORMERR",
-	"SERVFAIL",
-	"NXDOMAIN",
-	"NOTIMP",
-	"REFUSED",
+	"UPDATE",
 	"6",
 	"7",
 	"8",
@@ -106,6 +53,252 @@ const char *_res_resultcodes[] = {
 	"11",
 	"12",
 	"13",
-	"14",
-	"NOCHANGE",
+	"ZONEINIT",
+	"ZONEREF",
+};
+
+#ifdef BIND_UPDATE
+const char *_res_sectioncodes[] = {
+	"ZONE",
+	"PREREQUISITES",
+	"UPDATE",
+	"ADDITIONAL",
 };
+#endif
+
+#ifndef __BIND_NOSTATIC
+
+#ifdef _LIBC
+extern struct __res_state _res;
+#else
+/* The declaration has been moved to res_libc.c.  */
+struct __res_state _res
+# if defined(__BIND_RES_TEXT)
+	= { RES_TIMEOUT, }	/* Motorola, et al. */
+# endif
+        ;
+#endif
+
+/* Proto. */
+
+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
+   rest of this file not.  */
+int
+res_init(void) {
+	extern int __res_vinit(res_state, int);
+
+	/*
+	 * These three fields used to be statically initialized.  This made
+	 * it hard to use this code in a shared library.  It is necessary,
+	 * now that we're doing dynamic initialization here, that we preserve
+	 * the old semantics: if an application modifies one of these three
+	 * fields of _res before res_init() is called, res_init() will not
+	 * alter them.  Of course, if an application is setting them to
+	 * _zero_ before calling res_init(), hoping to override what used
+	 * to be the static default, we can't detect it and unexpected results
+	 * will follow.  Zero for any of these fields would make no sense,
+	 * so one can safely assume that the applications were already getting
+	 * unexpected results.
+	 *
+	 * _res.options is tricky since some apps were known to diddle the bits
+	 * before res_init() was first called. We can't replicate that semantic
+	 * with dynamic initialization (they may have turned bits off that are
+	 * set in RES_DEFAULT).  Our solution is to declare such applications
+	 * "broken".  They could fool us by setting RES_INIT but none do (yet).
+	 */
+	if (!_res.retrans)
+		_res.retrans = RES_TIMEOUT;
+	if (!_res.retry)
+		_res.retry = 4;
+	if (!(_res.options & RES_INIT))
+		_res.options = RES_DEFAULT;
+
+	/*
+	 * This one used to initialize implicitly to zero, so unless the app
+	 * has set it to something in particular, we can randomize it now.
+	 */
+	if (!_res.id)
+		_res.id = res_randomid();
+
+	return (__res_vinit(&_res, 1));
+}
+#endif
+
+void
+p_query(const u_char *msg) {
+	fp_query(msg, stdout);
+}
+
+void
+fp_query(const u_char *msg, FILE *file) {
+	fp_nquery(msg, PACKETSZ, file);
+}
+
+void
+fp_nquery(const u_char *msg, int len, FILE *file) {
+	if ((_res.options & RES_INIT) == 0 && res_init() == -1)
+		return;
+
+	res_pquery(&_res, msg, len, file);
+}
+
+int
+res_mkquery(int op,			/* opcode of query */
+	    const char *dname,		/* domain name */
+	    int class, int type,	/* class and type of query */
+	    const u_char *data,		/* resource record data */
+	    int datalen,		/* length of data */
+	    const u_char *newrr_in,	/* new rr for modify or append */
+	    u_char *buf,		/* buffer to put query */
+	    int buflen)			/* size of buffer */
+{
+	if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
+		RES_SET_H_ERRNO(&_res, NETDB_INTERNAL);
+		return (-1);
+	}
+	return (res_nmkquery(&_res, op, dname, class, type,
+			     data, datalen,
+			     newrr_in, buf, buflen));
+}
+
+#ifdef BIND_UPDATE
+int
+res_mkupdate(ns_updrec *rrecp_in, u_char *buf, int buflen) {
+	if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
+		RES_SET_H_ERRNO(&_res, NETDB_INTERNAL);
+		return (-1);
+	}
+
+	return (res_nmkupdate(&_res, rrecp_in, buf, buflen));
+}
+#endif
+
+int
+res_query(const char *name,	/* domain name */
+	  int class, int type,	/* class and type of query */
+	  u_char *answer,	/* buffer to put answer */
+	  int anslen)		/* size of answer buffer */
+{
+	if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
+		RES_SET_H_ERRNO(&_res, NETDB_INTERNAL);
+		return (-1);
+	}
+	return (res_nquery(&_res, name, class, type, answer, anslen));
+}
+
+void
+res_send_setqhook(res_send_qhook hook) {
+	_res.qhook = hook;
+}
+
+void
+res_send_setrhook(res_send_rhook hook) {
+	_res.rhook = hook;
+}
+
+int
+res_isourserver(const struct sockaddr_in *inp) {
+	return (res_ourserver_p(&_res, inp));
+}
+
+int
+res_send(const u_char *buf, int buflen, u_char *ans, int anssiz) {
+	if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
+		/* errno should have been set by res_init() in this case. */
+		return (-1);
+	}
+
+	return (res_nsend(&_res, buf, buflen, ans, anssiz));
+}
+
+#ifndef _LIBC
+int
+res_sendsigned(const u_char *buf, int buflen, ns_tsig_key *key,
+	       u_char *ans, int anssiz)
+{
+	if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
+		/* errno should have been set by res_init() in this case. */
+		return (-1);
+	}
+
+	return (res_nsendsigned(&_res, buf, buflen, key, ans, anssiz));
+}
+#endif
+
+void
+res_close(void) {
+	res_nclose(&_res);
+}
+
+#ifdef BIND_UPDATE
+int
+res_update(ns_updrec *rrecp_in) {
+	if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
+		RES_SET_H_ERRNO(&_res, NETDB_INTERNAL);
+		return (-1);
+	}
+
+	return (res_nupdate(&_res, rrecp_in, NULL));
+}
+#endif
+
+int
+res_search(const char *name,	/* domain name */
+	   int class, int type,	/* class and type of query */
+	   u_char *answer,	/* buffer to put answer */
+	   int anslen)		/* size of answer */
+{
+	if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
+		RES_SET_H_ERRNO(&_res, NETDB_INTERNAL);
+		return (-1);
+	}
+
+	return (res_nsearch(&_res, name, class, type, answer, anslen));
+}
+
+int
+res_querydomain(const char *name,
+		const char *domain,
+		int class, int type,	/* class and type of query */
+		u_char *answer,		/* buffer to put answer */
+		int anslen)		/* size of answer */
+{
+	if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
+		RES_SET_H_ERRNO(&_res, NETDB_INTERNAL);
+		return (-1);
+	}
+
+	return (res_nquerydomain(&_res, name, domain,
+				 class, type,
+				 answer, anslen));
+}
+
+const char *
+hostalias(const char *name) {
+	static char abuf[MAXDNAME];
+
+	return (res_hostalias(&_res, name, abuf, sizeof abuf));
+}
+
+#ifdef ultrix
+int
+local_hostname_length(const char *hostname) {
+	int len_host, len_domain;
+
+	if (!*_res.defdname)
+		res_init();
+	len_host = strlen(hostname);
+	len_domain = strlen(_res.defdname);
+	if (len_host > len_domain &&
+	    !strcasecmp(hostname + len_host - len_domain, _res.defdname) &&
+	    hostname[len_host - len_domain - 1] == '.')
+		return (len_host - len_domain - 1);
+	return (0);
+}
+#endif /*ultrix*/
+
+#endif
diff --git a/resolv/res_debug.c b/resolv/res_debug.c
index dac878d721..2df1c5bbdc 100644
--- a/resolv/res_debug.c
+++ b/resolv/res_debug.c
@@ -1,7 +1,5 @@
 /*
- * ++Copyright++ 1985, 1990, 1993
- * -
- * Copyright (c) 1985, 1990, 1993
+ * Copyright (c) 1985
  *    The Regents of the University of California.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -27,7 +25,9 @@
  * 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
@@ -45,7 +45,9 @@
  * 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.
- * -
+ */
+
+/*
  * Portions Copyright (c) 1995 by International Business Machines, Inc.
  *
  * International Business Machines, Inc. (hereinafter called IBM) grants
@@ -68,202 +70,121 @@
  * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING
  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN
  * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
- * --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[] = "@(#)res_debug.c	8.1 (Berkeley) 6/4/93";
-static char rcsid[] = "$Id$";
+static const char sccsid[] = "@(#)res_debug.c	8.1 (Berkeley) 6/4/93";
+static const char rcsid[] = "$Id$";
 #endif /* LIBC_SCCS and not lint */
 
-#include <sys/param.h>
 #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 <errno.h>
+#include <math.h>
 #include <netdb.h>
 #include <resolv.h>
 #include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
 #include <time.h>
 
-#if defined(BSD) && (BSD >= 199103) && defined(AF_INET6)
-# include <stdlib.h>
-# include <string.h>
+#ifdef SPRINTF_CHAR
+# define SPRINTF(x) strlen(sprintf/**/x)
 #else
-# include "../conf/portability.h"
-#endif
-
-#if defined(USE_OPTIONS_H)
-# include "../conf/options.h"
+# define SPRINTF(x) sprintf x
 #endif
 
 extern const char *_res_opcodes[];
-extern const char *_res_resultcodes[];
+extern const char *_res_sectioncodes[];
 
-/* XXX: we should use getservbyport() instead. */
-static const char *
-dewks(wks)
-	int wks;
-{
-	static char nbuf[20];
-
-	switch (wks) {
-	case 5: return "rje";
-	case 7: return "echo";
-	case 9: return "discard";
-	case 11: return "systat";
-	case 13: return "daytime";
-	case 15: return "netstat";
-	case 17: return "qotd";
-	case 19: return "chargen";
-	case 20: return "ftp-data";
-	case 21: return "ftp";
-	case 23: return "telnet";
-	case 25: return "smtp";
-	case 37: return "time";
-	case 39: return "rlp";
-	case 42: return "name";
-	case 43: return "whois";
-	case 53: return "domain";
-	case 57: return "apts";
-	case 59: return "apfs";
-	case 67: return "bootps";
-	case 68: return "bootpc";
-	case 69: return "tftp";
-	case 77: return "rje";
-	case 79: return "finger";
-	case 87: return "link";
-	case 95: return "supdup";
-	case 100: return "newacct";
-	case 101: return "hostnames";
-	case 102: return "iso-tsap";
-	case 103: return "x400";
-	case 104: return "x400-snd";
-	case 105: return "csnet-ns";
-	case 109: return "pop-2";
-	case 111: return "sunrpc";
-	case 113: return "auth";
-	case 115: return "sftp";
-	case 117: return "uucp-path";
-	case 119: return "nntp";
-	case 121: return "erpc";
-	case 123: return "ntp";
-	case 133: return "statsrv";
-	case 136: return "profile";
-	case 144: return "NeWS";
-	case 161: return "snmp";
-	case 162: return "snmp-trap";
-	case 170: return "print-srv";
-	default: (void) sprintf(nbuf, "%d", wks); return (nbuf);
-	}
-}
+/*
+ * Print the current options.
+ */
+void
+fp_resstat(const res_state statp, FILE *file) {
+	u_long mask;
 
-/* XXX: we should use getprotobynumber() instead. */
-static const char *
-deproto(protonum)
-	int protonum;
-{
-	static char nbuf[20];
-
-	switch (protonum) {
-	case 1: return "icmp";
-	case 2: return "igmp";
-	case 3: return "ggp";
-	case 5: return "st";
-	case 6: return "tcp";
-	case 7: return "ucl";
-	case 8: return "egp";
-	case 9: return "igp";
-	case 11: return "nvp-II";
-	case 12: return "pup";
-	case 16: return "chaos";
-	case 17: return "udp";
-	default: (void) sprintf(nbuf, "%d", protonum); return (nbuf);
-	}
+	fprintf(file, ";; res options:");
+	for (mask = 1;  mask != 0;  mask <<= 1)
+		if (statp->options & mask)
+			fprintf(file, " %s", p_option(mask));
+	putc('\n', file);
 }
 
-static const u_char *
-do_rrset(msg, len, cp, cnt, pflag, file, hs)
-	int cnt, pflag, len;
-	const u_char *cp, *msg;
-	const char *hs;
-	FILE *file;
+static void
+do_section(const res_state statp,
+	   ns_msg *handle, ns_sect section,
+	   int pflag, FILE *file)
 {
-	int n;
-	int sflag;
+	int n, sflag, rrnum;
+	char buf[2048];	/* XXX need to malloc */
+	ns_opcode opcode;
+	ns_rr rr;
 
 	/*
 	 * Print answer records.
 	 */
-	sflag = (_res.pfcode & pflag);
-	if ((n = ntohs(cnt))) {
-		if ((!_res.pfcode) ||
-		    ((sflag) && (_res.pfcode & RES_PRF_HEAD1)))
-			fprintf(file, hs);
-		while (--n >= 0) {
-			if ((!_res.pfcode) || sflag) {
-				cp = p_rr(cp, msg, file);
-			} else {
-				unsigned int dlen;
-				cp += __dn_skipname(cp, cp + MAXCDNAME);
-				cp += INT16SZ;
-				cp += INT16SZ;
-				cp += INT32SZ;
-				dlen = _getshort((u_char*)cp);
-				cp += INT16SZ;
-				cp += dlen;
+	sflag = (statp->pfcode & pflag);
+	if (statp->pfcode && !sflag)
+		return;
+
+	opcode = (ns_opcode) ns_msg_getflag(*handle, ns_f_opcode);
+	rrnum = 0;
+	for (;;) {
+		if (ns_parserr(handle, section, rrnum, &rr)) {
+			if (errno != ENODEV)
+				fprintf(file, ";; ns_parserr: %s\n",
+					strerror(errno));
+			else if (rrnum > 0 && sflag != 0 &&
+				 (statp->pfcode & RES_PRF_HEAD1))
+				putc('\n', file);
+			return;
+		}
+		if (rrnum == 0 && sflag != 0 && (statp->pfcode & RES_PRF_HEAD1))
+			fprintf(file, ";; %s SECTION:\n",
+				p_section(section, opcode));
+		if (section == ns_s_qd)
+			fprintf(file, ";;\t%s, type = %s, class = %s\n",
+				ns_rr_name(rr),
+				p_type(ns_rr_type(rr)),
+				p_class(ns_rr_class(rr)));
+		else {
+			n = ns_sprintrr(handle, &rr, NULL, NULL,
+					buf, sizeof buf);
+			if (n < 0) {
+				fprintf(file, ";; ns_sprintrr: %s\n",
+					strerror(errno));
+				return;
 			}
-			if ((cp - msg) > len)
-				return (NULL);
+			fputs(buf, file);
+			fputc('\n', file);
 		}
-		if ((!_res.pfcode) ||
-		    ((sflag) && (_res.pfcode & RES_PRF_HEAD1)))
-			putc('\n', file);
+		rrnum++;
 	}
-	return (cp);
-}
-
-void
-__p_query(msg)
-	const u_char *msg;
-{
-	__fp_query(msg, stdout);
-}
-
-#ifdef ultrix
-#undef p_query
-/* ultrix 4.0's packaging has some icky packaging.  alias for it here.
- * there is more junk of this kind over in res_comp.c.
- */
-void
-p_query(msg)
-	const u_char *msg;
-{
-	__p_query(msg);
-}
-#endif
-
-/*
- * Print the current options.
- * This is intended to be primarily a debugging routine.
- */
-void
-__fp_resstat(statp, file)
-	struct __res_state *statp;
-	FILE *file;
-{
-	register u_long mask;
-
-	fprintf(file, ";; res options:");
-	if (!statp)
-		statp = &_res;
-	for (mask = 1;  mask != 0;  mask <<= 1)
-		if (statp->options & mask)
-			fprintf(file, " %s", p_option(mask));
-	putc('\n', file);
 }
 
 /*
@@ -271,147 +192,79 @@ __fp_resstat(statp, file)
  * This is intended to be primarily a debugging routine.
  */
 void
-__fp_nquery(msg, len, file)
-	const u_char *msg;
-	int len;
-	FILE *file;
-{
-	register const u_char *cp, *endMark;
-	register const HEADER *hp;
-	register int n;
+res_pquery(const res_state statp, const u_char *msg, int len, FILE *file) {
+	ns_msg handle;
+	int qdcount, ancount, nscount, arcount;
+	u_int opcode, rcode, id;
 
-	if ((_res.options & RES_INIT) == 0 && res_init() == -1)
+	if (ns_initparse(msg, len, &handle) < 0) {
+		fprintf(file, ";; ns_initparse: %s\n", strerror(errno));
 		return;
-
-#define TruncTest(x) if (x > endMark) goto trunc
-#define	ErrorTest(x) if (x == NULL) goto error
+	}
+	opcode = ns_msg_getflag(handle, ns_f_opcode);
+	rcode = ns_msg_getflag(handle, ns_f_rcode);
+	id = ns_msg_id(handle);
+	qdcount = ns_msg_count(handle, ns_s_qd);
+	ancount = ns_msg_count(handle, ns_s_an);
+	nscount = ns_msg_count(handle, ns_s_ns);
+	arcount = ns_msg_count(handle, ns_s_ar);
 
 	/*
 	 * Print header fields.
 	 */
-	hp = (HEADER *)msg;
-	cp = msg + HFIXEDSZ;
-	endMark = msg + len;
-	if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEADX) || hp->rcode) {
-		fprintf(file, ";; ->>HEADER<<- opcode: %s, status: %s, id: %d",
-			_res_opcodes[hp->opcode],
-			_res_resultcodes[hp->rcode],
-			ntohs(hp->id));
-		putc('\n', file);
-	}
-	if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEADX))
+	if ((!statp->pfcode) || (statp->pfcode & RES_PRF_HEADX) || rcode)
+		fprintf(file,
+			";; ->>HEADER<<- opcode: %s, status: %s, id: %d\n",
+			_res_opcodes[opcode], p_rcode(rcode), id);
+	if ((!statp->pfcode) || (statp->pfcode & RES_PRF_HEADX))
 		putc(';', file);
-	if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEAD2)) {
+	if ((!statp->pfcode) || (statp->pfcode & RES_PRF_HEAD2)) {
 		fprintf(file, "; flags:");
-		if (hp->qr)
+		if (ns_msg_getflag(handle, ns_f_qr))
 			fprintf(file, " qr");
-		if (hp->aa)
+		if (ns_msg_getflag(handle, ns_f_aa))
 			fprintf(file, " aa");
-		if (hp->tc)
+		if (ns_msg_getflag(handle, ns_f_tc))
 			fprintf(file, " tc");
-		if (hp->rd)
+		if (ns_msg_getflag(handle, ns_f_rd))
 			fprintf(file, " rd");
-		if (hp->ra)
+		if (ns_msg_getflag(handle, ns_f_ra))
 			fprintf(file, " ra");
-		if (hp->unused)
-			fprintf(file, " UNUSED-BIT-ON");
-		if (hp->ad)
+		if (ns_msg_getflag(handle, ns_f_z))
+			fprintf(file, " ??");
+		if (ns_msg_getflag(handle, ns_f_ad))
 			fprintf(file, " ad");
-		if (hp->cd)
+		if (ns_msg_getflag(handle, ns_f_cd))
 			fprintf(file, " cd");
 	}
-	if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEAD1)) {
-		fprintf(file, "; Ques: %d", ntohs(hp->qdcount));
-		fprintf(file, ", Ans: %d", ntohs(hp->ancount));
-		fprintf(file, ", Auth: %d", ntohs(hp->nscount));
-		fprintf(file, ", Addit: %d", ntohs(hp->arcount));
+	if ((!statp->pfcode) || (statp->pfcode & RES_PRF_HEAD1)) {
+		fprintf(file, "; %s: %d",
+			p_section(ns_s_qd, opcode), qdcount);
+		fprintf(file, ", %s: %d",
+			p_section(ns_s_an, opcode), ancount);
+		fprintf(file, ", %s: %d",
+			p_section(ns_s_ns, opcode), nscount);
+		fprintf(file, ", %s: %d",
+			p_section(ns_s_ar, opcode), arcount);
 	}
-	if ((!_res.pfcode) || (_res.pfcode &
+	if ((!statp->pfcode) || (statp->pfcode & 
 		(RES_PRF_HEADX | RES_PRF_HEAD2 | RES_PRF_HEAD1))) {
 		putc('\n',file);
 	}
 	/*
-	 * Print question records.
+	 * Print the various sections.
 	 */
-	if ((n = ntohs(hp->qdcount))) {
-		if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES))
-			fprintf(file, ";; QUESTIONS:\n");
-		while (--n >= 0) {
-			if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES))
-				fprintf(file, ";;\t");
-			TruncTest(cp);
-			if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES))
-				cp = p_cdnname(cp, msg, len, file);
-			else {
-				int n;
-				char name[MAXDNAME];
-
-				if ((n = dn_expand(msg, msg+len, cp, name,
-						sizeof name)) < 0)
-					cp = NULL;
-				else
-					cp += n;
-			}
-			ErrorTest(cp);
-			TruncTest(cp);
-			if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES))
-				fprintf(file, ", type = %s",
-					__p_type(_getshort((u_char*)cp)));
-			cp += INT16SZ;
-			TruncTest(cp);
-			if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES))
-				fprintf(file, ", class = %s\n",
-					__p_class(_getshort((u_char*)cp)));
-			cp += INT16SZ;
-			if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES))
-				putc('\n', file);
-		}
-	}
-	/*
-	 * Print authoritative answer records
-	 */
-	TruncTest(cp);
-	cp = do_rrset(msg, len, cp, hp->ancount, RES_PRF_ANS, file,
-		      ";; ANSWERS:\n");
-	ErrorTest(cp);
-
-	/*
-	 * print name server records
-	 */
-	TruncTest(cp);
-	cp = do_rrset(msg, len, cp, hp->nscount, RES_PRF_AUTH, file,
-		      ";; AUTHORITY RECORDS:\n");
-	ErrorTest(cp);
-
-	TruncTest(cp);
-	/*
-	 * print additional records
-	 */
-	cp = do_rrset(msg, len, cp, hp->arcount, RES_PRF_ADD, file,
-		      ";; ADDITIONAL RECORDS:\n");
-	ErrorTest(cp);
-	return;
- trunc:
-	fprintf(file, "\n;; ...truncated\n");
-	return;
- error:
-	fprintf(file, "\n;; ...malformed\n");
-}
-
-void
-__fp_query(msg, file)
-	const u_char *msg;
-	FILE *file;
-{
-	fp_nquery(msg, PACKETSZ, file);
+	do_section(statp, &handle, ns_s_qd, RES_PRF_QUES, file);
+	do_section(statp, &handle, ns_s_an, RES_PRF_ANS, file);
+	do_section(statp, &handle, ns_s_ns, RES_PRF_AUTH, file);
+	do_section(statp, &handle, ns_s_ar, RES_PRF_ADD, file);
+	if (qdcount == 0 && ancount == 0 &&
+	    nscount == 0 && arcount == 0)
+		putc('\n', file);
 }
 
 const u_char *
-__p_cdnname(cp, msg, len, file)
-	const u_char *cp, *msg;
-	int len;
-	FILE *file;
-{
+p_cdnname(const u_char *cp, const u_char *msg, int len, FILE *file) {
 	char name[MAXDNAME];
 	int n;
 
@@ -425,19 +278,15 @@ __p_cdnname(cp, msg, len, file)
 }
 
 const u_char *
-__p_cdname(cp, msg, file)
-	const u_char *cp, *msg;
-	FILE *file;
-{
+p_cdname(const u_char *cp, const u_char *msg, FILE *file) {
 	return (p_cdnname(cp, msg, PACKETSZ, file));
 }
 
-
 /* Return a fully-qualified domain name from a compressed name (with
    length supplied).  */
 
 const u_char *
-__p_fqnname(cp, msg, msglen, name, namelen)
+p_fqnname(cp, msg, msglen, name, namelen)
 	const u_char *cp, *msg;
 	int msglen;
 	char *name;
@@ -447,9 +296,9 @@ __p_fqnname(cp, msg, msglen, name, namelen)
 
 	if ((n = dn_expand(msg, cp + msglen, cp, name, namelen)) < 0)
 		return (NULL);
-	newlen = strlen (name);
+	newlen = strlen(name);
 	if (newlen == 0 || name[newlen - 1] != '.') {
-		if (newlen+1 >= namelen)        /* Lack space for final dot */
+		if (newlen + 1 >= namelen)	/* Lack space for final dot */
 			return (NULL);
 		else
 			strcpy(name + newlen, ".");
@@ -457,18 +306,14 @@ __p_fqnname(cp, msg, msglen, name, namelen)
 	return (cp + n);
 }
 
-/* XXX:	the rest of these functions need to become length-limited, too. (vix)
- */
+/* XXX:	the rest of these functions need to become length-limited, too. */
 
 const u_char *
-__p_fqname(cp, msg, file)
-	const u_char *cp, *msg;
-	FILE *file;
-{
+p_fqname(const u_char *cp, const u_char *msg, FILE *file) {
 	char name[MAXDNAME];
 	const u_char *n;
 
-	n = __p_fqnname(cp, msg, MAXCDNAME, name, sizeof name);
+	n = p_fqnname(cp, msg, MAXCDNAME, name, sizeof name);
 	if (n == NULL)
 		return (NULL);
 	fputs(name, file);
@@ -476,398 +321,6 @@ __p_fqname(cp, msg, file)
 }
 
 /*
- * Print resource record fields in human readable form.
- */
-const u_char *
-__p_rr(cp, msg, file)
-	const u_char *cp, *msg;
-	FILE *file;
-{
-	int type, class, dlen, n, c;
-	struct in_addr inaddr;
-	const u_char *cp1, *cp2;
-	u_int32_t tmpttl, t;
-	int lcnt;
-	u_int16_t keyflags;
-	char rrname[MAXDNAME];          /* The fqdn of this RR */
-	char base64_key[MAX_KEY_BASE64];
-
-	if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
-		__set_h_errno (NETDB_INTERNAL);
-		return (NULL);
-	}
-	cp = __p_fqnname(cp, msg, MAXCDNAME, rrname, sizeof rrname);
-	if (!cp)
-		return (NULL);			/* compression error */
-	fputs(rrname, file);
-
-	type = _getshort((u_char*)cp);
-	cp += INT16SZ;
-	class = _getshort((u_char*)cp);
-	cp += INT16SZ;
-	tmpttl = _getlong((u_char*)cp);
-	cp += INT32SZ;
-	dlen = _getshort((u_char*)cp);
-	cp += INT16SZ;
-	cp1 = cp;
-	if ((!_res.pfcode) || (_res.pfcode & RES_PRF_TTLID))
-		fprintf(file, "\t%lu", (u_long)tmpttl);
-	if ((!_res.pfcode) || (_res.pfcode & RES_PRF_CLASS))
-		fprintf(file, "\t%s", __p_class(class));
-	fprintf(file, "\t%s", __p_type(type));
-	/*
-	 * Print type specific data, if appropriate
-	 */
-	switch (type) {
-	case T_A:
-		switch (class) {
-		case C_IN:
-		case C_HS:
-			bcopy(cp, (char *)&inaddr, INADDRSZ);
-			if (dlen == 4) {
-				fprintf(file, "\t%s", inet_ntoa(inaddr));
-				cp += dlen;
-			} else if (dlen == 7) {
-				char *address;
-				u_char protocol;
-				u_short port;
-
-				address = inet_ntoa(inaddr);
-				cp += INADDRSZ;
-				protocol = *(u_char*)cp;
-				cp += sizeof (u_char);
-				port = _getshort((u_char*)cp);
-				cp += INT16SZ;
-				fprintf(file, "\t%s\t; proto %d, port %d",
-					address, protocol, port);
-			}
-			break;
-		default:
-			cp += dlen;
-		}
-		break;
-	case T_CNAME:
-	case T_MB:
-	case T_MG:
-	case T_MR:
-	case T_NS:
-	case T_PTR:
-		putc('\t', file);
-		if ((cp = p_fqname(cp, msg, file)) == NULL)
-			return (NULL);
-		break;
-
-	case T_HINFO:
-	case T_ISDN:
-		cp2 = cp + dlen;
-		(void) fputs("\t\"", file);
-		if ((n = (unsigned char) *cp++) != 0) {
-			for (c = n; c > 0 && cp < cp2; c--) {
-				if (strchr("\n\"\\", *cp))
-					(void) putc('\\', file);
-				(void) putc(*cp++, file);
-			}
-		}
-		putc('"', file);
-		if (cp < cp2 && (n = (unsigned char) *cp++) != 0) {
-			(void) fputs ("\t\"", file);
-			for (c = n; c > 0 && cp < cp2; c--) {
-				if (strchr("\n\"\\", *cp))
-					(void) putc('\\', file);
-				(void) putc(*cp++, file);
-			}
-			putc('"', file);
-		} else if (type == T_HINFO) {
-			(void) fputs("\"?\"", file);
-			fprintf(file, "\n;; *** Warning *** OS-type missing");
-		}
-		break;
-
-	case T_SOA:
-		putc('\t', file);
-		if ((cp = p_fqname(cp, msg, file)) == NULL)
-			return (NULL);
-		putc(' ', file);
-		if ((cp = p_fqname(cp, msg, file)) == NULL)
-			return (NULL);
-		fputs(" (\n", file);
-		t = _getlong((u_char*)cp);  cp += INT32SZ;
-		fprintf(file, "\t\t\t%lu\t; serial\n", (u_long)t);
-		t = _getlong((u_char*)cp);  cp += INT32SZ;
-		fprintf(file, "\t\t\t%lu\t; refresh (%s)\n",
-			(u_long)t, __p_time(t));
-		t = _getlong((u_char*)cp);  cp += INT32SZ;
-		fprintf(file, "\t\t\t%lu\t; retry (%s)\n",
-			(u_long)t, __p_time(t));
-		t = _getlong((u_char*)cp);  cp += INT32SZ;
-		fprintf(file, "\t\t\t%lu\t; expire (%s)\n",
-			(u_long)t, __p_time(t));
-		t = _getlong((u_char*)cp);  cp += INT32SZ;
-		fprintf(file, "\t\t\t%lu )\t; minimum (%s)",
-			(u_long)t, __p_time(t));
-		break;
-
-	case T_MX:
-	case T_AFSDB:
-	case T_RT:
-		fprintf(file, "\t%d ", _getshort((u_char*)cp));
-		cp += INT16SZ;
-		if ((cp = p_fqname(cp, msg, file)) == NULL)
-			return (NULL);
-		break;
-
-	case T_PX:
-		fprintf(file, "\t%d ", _getshort((u_char*)cp));
-		cp += INT16SZ;
-		if ((cp = p_fqname(cp, msg, file)) == NULL)
-			return (NULL);
-		putc(' ', file);
-		if ((cp = p_fqname(cp, msg, file)) == NULL)
-			return (NULL);
-		break;
-
-	case T_X25:
-		cp2 = cp + dlen;
-		(void) fputs("\t\"", file);
-		if ((n = (unsigned char) *cp++) != 0) {
-			for (c = n; c > 0 && cp < cp2; c--) {
-				if (strchr("\n\"\\", *cp))
-					(void) putc('\\', file);
-				(void) putc(*cp++, file);
-			}
-		}
-		putc('"', file);
-		break;
-
-	case T_TXT:
-		(void) putc('\t', file);
-		cp2 = cp1 + dlen;
-		while (cp < cp2) {
-			putc('"', file);
-			if ((n = (unsigned char) *cp++)) {
-				for (c = n; c > 0 && cp < cp2; c--) {
-					if (strchr("\n\"\\", *cp))
-						(void) putc('\\', file);
-					(void) putc(*cp++, file);
-				}
-			}
-			putc('"', file);
-			if (cp < cp2)
-				putc(' ', file);
-		}
-		break;
-
-	case T_NSAP:
-		(void) fprintf(file, "\t%s", inet_nsap_ntoa(dlen, cp, NULL));
-		cp += dlen;
-		break;
-
-	case T_AAAA: {
-		char t[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"];
-
-		fprintf(file, "\t%s", inet_ntop(AF_INET6, cp, t, sizeof t));
-		cp += dlen;
-		break;
-	    }
-
-	case T_LOC: {
-		char t[255];
-
-		(void) fprintf(file, "\t%s", loc_ntoa(cp, t));
-		cp += dlen;
-		break;
-	    }
-
-	case T_NAPTR: {
-		u_int order, preference;
-
-		order = _getshort(cp);  cp += INT16SZ;
-		preference   = _getshort(cp);  cp += INT16SZ;
-		fprintf(file, "\t%u %u ",order, preference);
-		/* Flags */
-		n = *cp++;
-		fprintf(file,"\"%.*s\" ", (int)n, cp);
-		cp += n;
-		/* Service */
-		n = *cp++;
-		fprintf(file,"\"%.*s\" ", (int)n, cp);
-		cp += n;
-		/* Regexp */
-		n = *cp++;
-		fprintf(file,"\"%.*s\" ", (int)n, cp);
-		cp += n;
-		if ((cp = p_fqname(cp, msg, file)) == NULL)
-			return (NULL);
-		break;
-	    }
-
-	case T_SRV: {
-		u_int priority, weight, port;
-
-		priority = _getshort(cp);  cp += INT16SZ;
-		weight   = _getshort(cp);  cp += INT16SZ;
-		port     = _getshort(cp);  cp += INT16SZ;
-		fprintf(file, "\t%u %u %u ", priority, weight, port);
-		if ((cp = p_fqname(cp, msg, file)) == NULL)
-			return (NULL);
-		break;
-	    }
-
-	case T_MINFO:
-	case T_RP:
-		putc('\t', file);
-		if ((cp = p_fqname(cp, msg, file)) == NULL)
-			return (NULL);
-		putc(' ', file);
-		if ((cp = p_fqname(cp, msg, file)) == NULL)
-			return (NULL);
-		break;
-
-	case T_UINFO:
-		putc('\t', file);
-		fputs((char *)cp, file);
-		cp += dlen;
-		break;
-
-	case T_UID:
-	case T_GID:
-		if (dlen == 4) {
-			fprintf(file, "\t%u", _getlong((u_char*)cp));
-			cp += INT32SZ;
-		}
-		break;
-
-	case T_WKS:
-		if (dlen < INT32SZ + 1)
-			break;
-		bcopy(cp, (char *)&inaddr, INADDRSZ);
-		cp += INT32SZ;
-		fprintf(file, "\t%s %s ( ",
-			inet_ntoa(inaddr),
-			deproto((int) *cp));
-		cp += sizeof (u_char);
-		n = 0;
-		lcnt = 0;
-		while (cp < cp1 + dlen) {
-			c = *cp++;
-			do {
-				if (c & 0200) {
-					if (lcnt == 0) {
-						fputs("\n\t\t\t", file);
-						lcnt = 5;
-					}
-					fputs(dewks(n), file);
-					putc(' ', file);
-					lcnt--;
-				}
-				c <<= 1;
-			} while (++n & 07);
-		}
-		putc(')', file);
-		break;
-
-	case T_KEY:
-		putc('\t', file);
-		keyflags = _getshort(cp);
-		cp += 2;
-		fprintf(file,"0x%04x", keyflags );      /* flags */
-		fprintf(file," %u", *cp++);     /* protocol */
-		fprintf(file," %u (", *cp++);   /* algorithm */
-
-		n = b64_ntop(cp, (cp1 + dlen) - cp,
-			     base64_key, sizeof base64_key);
-		for (c = 0; c < n; ++c) {
-			if (0 == (c & 0x3F))
-				fprintf(file, "\n\t");
-			putc(base64_key[c], file);  /* public key data */
-		}
-
-		fprintf(file, " )");
-		if (n < 0)
-			fprintf(file, "\t; BAD BASE64");
-		fflush(file);
-		cp = cp1 + dlen;
-		break;
-
-	case T_SIG:
-		type = _getshort((u_char*)cp);
-		cp += INT16SZ;
-		fprintf(file, " %s", p_type(type));
-		fprintf(file, "\t%d", *cp++);   /* algorithm */
-		/* Check label value and print error if wrong. */
-		n = *cp++;
-		c = dn_count_labels (rrname);
-		if (n != c)
-			fprintf(file, "\t; LABELS WRONG (%d should be %d)\n\t",
-				n, c);
-		/* orig ttl */
-		n = _getlong((u_char*)cp);
-		if ((u_int32_t) n != tmpttl)
-			fprintf(file, " %u", n);
-		cp += INT32SZ;
-		/* sig expire */
-		fprintf(file, " (\n\t%s",
-			__p_secstodate(_getlong((u_char*)cp)));
-		cp += INT32SZ;
-		/* time signed */
-		fprintf(file, " %s", __p_secstodate(_getlong((u_char*)cp)));
-		cp += INT32SZ;
-		/* sig footprint */
-		fprintf(file," %u ", _getshort((u_char*)cp));
-		cp += INT16SZ;
-		/* signer's name */
-		cp = p_fqname(cp, msg, file);
-		n = b64_ntop(cp, (cp1 + dlen) - cp,
-			     base64_key, sizeof base64_key);
-		for (c = 0; c < n; c++) {
-			if (0 == (c & 0x3F))
-		  		fprintf (file, "\n\t");
-			putc(base64_key[c], file);              /* signature */
-		}
-		/* Clean up... */
-		fprintf(file, " )");
-		if (n < 0)
-			fprintf(file, "\t; BAD BASE64");
-		fflush(file);
-		cp = cp1+dlen;
-		break;
-
-#ifdef ALLOW_T_UNSPEC
-	case T_UNSPEC:
-		{
-			int NumBytes = 8;
-			u_char *DataPtr;
-			int i;
-
-			if (dlen < NumBytes) NumBytes = dlen;
-			fprintf(file, "\tFirst %d bytes of hex data:",
-				NumBytes);
-			for (i = 0, DataPtr = cp; i < NumBytes; i++, DataPtr++)
-				fprintf(file, " %x", *DataPtr);
-			cp += dlen;
-		}
-		break;
-#endif /* ALLOW_T_UNSPEC */
-
-	default:
-		fprintf(file, "\t?%d?", type);
-		cp += dlen;
-	}
-#if 0
-	fprintf(file, "\t; dlen=%d, ttl %s\n", dlen, __p_time(tmpttl));
-#else
-	putc('\n', file);
-#endif
-	if (cp - cp1 != dlen) {
-		fprintf(file,
-			";; packet size error (found %lu, dlen was %d)\n",
-			(unsigned long) (cp - cp1), dlen);
-		cp = NULL;
-	}
-	return (cp);
-}
-
-/*
  * Names of RR classes and qclasses.  Classes and qclasses are the same, except
  * that C_ANY is a qclass but not a class.  (You can ask for records of class
  * C_ANY, but you can't have any records of that class in the database.)
@@ -878,7 +331,45 @@ const struct res_sym __p_class_syms[] = {
 	{C_HS,		"HS"},
 	{C_HS,		"HESIOD"},
 	{C_ANY,		"ANY"},
-	{C_IN,		(char *)0}
+	{C_NONE,	"NONE"},
+	{C_IN, 		(char *)0}
+};
+
+/*
+ * Names of message sections.
+ */
+const struct res_sym __p_default_section_syms[] = {
+	{ns_s_qd,	"QUERY"},
+	{ns_s_an,	"ANSWER"},
+	{ns_s_ns,	"AUTHORITY"},
+	{ns_s_ar,	"ADDITIONAL"},
+	{0,             (char *)0}
+};
+
+const struct res_sym __p_update_section_syms[] = {
+	{S_ZONE,	"ZONE"},
+	{S_PREREQ,	"PREREQUISITE"},
+	{S_UPDATE,	"UPDATE"},
+	{S_ADDT,	"ADDITIONAL"},
+	{0,             (char *)0}
+};
+
+const struct res_sym __p_key_syms[] = {
+	{NS_ALG_MD5RSA,		"RSA",		"RSA KEY with MD5 hash"},
+	{NS_ALG_DH,		"DH",		"Diffie Hellman"},
+	{NS_ALG_DSA,		"DSA",		"Digital Signature Algorithm"},
+	{NS_ALG_EXPIRE_ONLY,	"EXPIREONLY",	"No algorithm"},
+	{NS_ALG_PRIVATE_OID,	"PRIVATE",	"Algorithm obtained from OID"},
+	{0,			NULL,		NULL}
+};
+
+const struct res_sym __p_cert_syms[] = {
+	{cert_t_pkix,	"PKIX",		"PKIX (X.509v3) Certificate"},
+	{cert_t_spki,	"SPKI",		"SPKI certificate"},
+	{cert_t_pgp,	"PGP",		"PGP certificate"},
+	{cert_t_url,	"URL",		"URL Private"},
+	{cert_t_oid,	"OID",		"OID Private"},
+	{0,		NULL,		NULL}
 };
 
 /*
@@ -887,67 +378,78 @@ const struct res_sym __p_class_syms[] = {
  * T_ANY, but you can't have any records of that type in the database.)
  */
 const struct res_sym __p_type_syms[] = {
-	{T_A,		"A",		"address"},
-	{T_NS,		"NS",		"name server"},
-	{T_MD,		"MD",		"mail destination (deprecated)"},
-	{T_MF,		"MF",		"mail forwarder (deprecated)"},
-	{T_CNAME,	"CNAME",	"canonical name"},
-	{T_SOA,		"SOA",		"start of authority"},
-	{T_MB,		"MB",		"mailbox"},
-	{T_MG,		"MG",		"mail group member"},
-	{T_MR,		"MR",		"mail rename"},
-	{T_NULL,	"NULL",		"null"},
-	{T_WKS,		"WKS",		"well-known service (deprecated)"},
-	{T_PTR,		"PTR",		"domain name pointer"},
-	{T_HINFO,	"HINFO",	"host information"},
-	{T_MINFO,	"MINFO",	"mailbox information"},
-	{T_MX,		"MX",		"mail exchanger"},
-	{T_TXT,		"TXT",		"text"},
-	{T_RP,		"RP",		"responsible person"},
-	{T_AFSDB,	"AFSDB",	"DCE or AFS server"},
-	{T_X25,		"X25",		"X25 address"},
-	{T_ISDN,	"ISDN",		"ISDN address"},
-	{T_RT,		"RT",		"router"},
-	{T_NSAP,	"NSAP",		"nsap address"},
-	{T_NSAP_PTR,	"NSAP_PTR",	"domain name pointer"},
-	{T_SIG,		"SIG",		"signature"},
-	{T_KEY,		"KEY",		"key"},
-	{T_PX,		"PX",		"mapping information"},
-	{T_GPOS,	"GPOS",		"geographical position (withdrawn)"},
-	{T_AAAA,	"AAAA",		"IPv6 address"},
-	{T_LOC,		"LOC",		"location"},
-	{T_NXT,		"NXT",		"next valid name (unimplemented)"},
-	{T_EID,		"EID",		"endpoint identifier (unimplemented)"},
-	{T_NIMLOC,	"NIMLOC",	"NIMROD locator (unimplemented)"},
-	{T_SRV,		"SRV",		"server selection"},
-	{T_ATMA,	"ATMA",		"ATM address (unimplemented)"},
-	{T_IXFR,	"IXFR",		"incremental zone transfer"},
-	{T_AXFR,	"AXFR",		"zone transfer"},
-	{T_MAILB,	"MAILB",	"mailbox-related data (deprecated)"},
-	{T_MAILA,	"MAILA",	"mail agent (deprecated)"},
-	{T_UINFO,	"UINFO",	"user information (nonstandard)"},
-	{T_UID,		"UID",		"user ID (nonstandard)"},
-	{T_GID,		"GID",		"group ID (nonstandard)"},
-	{T_NAPTR,	"NAPTR",	"URN Naming Authority"},
-#ifdef ALLOW_T_UNSPEC
-	{T_UNSPEC,	"UNSPEC",	"unspecified data (nonstandard)"},
-#endif /* ALLOW_T_UNSPEC */
-	{T_ANY,		"ANY",		"\"any\""},
-	{0,		NULL,		NULL}
+	{ns_t_a,	"A",		"address"},
+	{ns_t_ns,	"NS",		"name server"},
+	{ns_t_md,	"MD",		"mail destination (deprecated)"},
+	{ns_t_mf,	"MF",		"mail forwarder (deprecated)"},
+	{ns_t_cname,	"CNAME",	"canonical name"},
+	{ns_t_soa,	"SOA",		"start of authority"},
+	{ns_t_mb,	"MB",		"mailbox"},
+	{ns_t_mg,	"MG",		"mail group member"},
+	{ns_t_mr,	"MR",		"mail rename"},
+	{ns_t_null,	"NULL",		"null"},
+	{ns_t_wks,	"WKS",		"well-known service (deprecated)"},
+	{ns_t_ptr,	"PTR",		"domain name pointer"},
+	{ns_t_hinfo,	"HINFO",	"host information"},
+	{ns_t_minfo,	"MINFO",	"mailbox information"},
+	{ns_t_mx,	"MX",		"mail exchanger"},
+	{ns_t_txt,	"TXT",		"text"},
+	{ns_t_rp,	"RP",		"responsible person"},
+	{ns_t_afsdb,	"AFSDB",	"DCE or AFS server"},
+	{ns_t_x25,	"X25",		"X25 address"},
+	{ns_t_isdn,	"ISDN",		"ISDN address"},
+	{ns_t_rt,	"RT",		"router"},
+	{ns_t_nsap,	"NSAP",		"nsap address"},
+	{ns_t_nsap_ptr,	"NSAP_PTR",	"domain name pointer"},
+	{ns_t_sig,	"SIG",		"signature"},
+	{ns_t_key,	"KEY",		"key"},
+	{ns_t_px,	"PX",		"mapping information"},
+	{ns_t_gpos,	"GPOS",		"geographical position (withdrawn)"},
+	{ns_t_aaaa,	"AAAA",		"IPv6 address"},
+	{ns_t_loc,	"LOC",		"location"},
+	{ns_t_nxt,	"NXT",		"next valid name (unimplemented)"},
+	{ns_t_eid,	"EID",		"endpoint identifier (unimplemented)"},
+	{ns_t_nimloc,	"NIMLOC",	"NIMROD locator (unimplemented)"},
+	{ns_t_srv,	"SRV",		"server selection"},
+	{ns_t_atma,	"ATMA",		"ATM address (unimplemented)"},
+	{ns_t_tsig,	"TSIG",		"transaction signature"},
+	{ns_t_ixfr,	"IXFR",		"incremental zone transfer"},
+	{ns_t_axfr,	"AXFR",		"zone transfer"},
+	{ns_t_zxfr,	"ZXFR",		"compressed zone transfer"},
+	{ns_t_mailb,	"MAILB",	"mailbox-related data (deprecated)"},
+	{ns_t_maila,	"MAILA",	"mail agent (deprecated)"},
+	{ns_t_naptr,	"NAPTR",	"URN Naming Authority"},
+	{ns_t_kx,	"KX",		"Key Exchange"},
+	{ns_t_cert,	"CERT",		"Certificate"},
+	{ns_t_any,	"ANY",		"\"any\""},
+	{0, 		NULL,		NULL}
+};
+
+/*
+ * Names of DNS rcodes.
+ */
+const struct res_sym __p_rcode_syms[] = {
+	{ns_r_noerror,	"NOERROR",		"no error"},
+	{ns_r_formerr,	"FORMERR",		"format error"},
+	{ns_r_servfail,	"SERVFAIL",		"server failed"},
+	{ns_r_nxdomain,	"NXDOMAIN",		"no such domain name"},
+	{ns_r_notimpl,	"NOTIMP",		"not implemented"},
+	{ns_r_refused,	"REFUSED",		"refused"},
+	{ns_r_yxdomain,	"YXDOMAIN",		"domain name exists"},
+	{ns_r_yxrrset,	"YXRRSET",		"rrset exists"},
+	{ns_r_nxrrset,	"NXRRSET",		"rrset doesn't exist"},
+	{ns_r_notauth,	"NOTAUTH",		"not authoritative"},
+	{ns_r_notzone,	"NOTZONE",		"Not in zone"},
+	{ns_r_max,	"",			""},
+	{ns_r_badsig,	"BADSIG",		"bad signature"},
+	{ns_r_badkey,	"BADKEY",		"bad key"},
+	{ns_r_badtime,	"BADTIME",		"bad time"},
+	{0, 		NULL,			NULL}
 };
 
 int
-__sym_ston(syms, name, success)
-	const struct res_sym *syms;
-	char *name;
-	int *success;
-{
-#ifdef _LIBC
-	/* Changed to prevent warning. --drepper@gnu  */
-	for (; syms->name != 0; syms++) {
-#else
-	for (NULL; syms->name != 0; syms++) {
-#endif
+sym_ston(const struct res_sym *syms, const char *name, int *success) {
+	for ((void)NULL; syms->name != 0; syms++) {
 		if (strcasecmp (name, syms->name) == 0) {
 			if (success)
 				*success = 1;
@@ -956,50 +458,41 @@ __sym_ston(syms, name, success)
 	}
 	if (success)
 		*success = 0;
-	return (syms->number);          /* The default value. */
+	return (syms->number);		/* The default value. */
 }
 
 const char *
-__sym_ntos(syms, number, success)
-	const struct res_sym *syms;
-	int number;
-	int *success;
-{
+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 (NULL; syms->name != 0; syms++) {
+	for ((void)NULL; syms->name != 0; syms++) {
 #endif
-		if (number == syms->number) {
+	  if (number == syms->number) {
 			if (success)
 				*success = 1;
 			return (syms->name);
 		}
 	}
 
-	sprintf (unname, "%d", number);
+	sprintf(unname, "%d", number);		/* XXX nonreentrant */
 	if (success)
 		*success = 0;
 	return (unname);
 }
 
-
 const char *
-__sym_ntop(syms, number, success)
-	const struct res_sym *syms;
-	int number;
-	int *success;
-{
+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 (NULL; syms->name != 0; syms++) {
+	for ((void)NULL; syms->name != 0; syms++) {
 #endif
 		if (number == syms->number) {
 			if (success)
@@ -1007,39 +500,51 @@ __sym_ntop(syms, number, success)
 			return (syms->humanname);
 		}
 	}
-	sprintf(unname, "%d", number);
+	sprintf(unname, "%d", number);		/* XXX nonreentrant */
 	if (success)
 		*success = 0;
 	return (unname);
 }
 
 /*
- * Return a string for the type
+ * Return a string for the type.
  */
 const char *
-__p_type(type)
-	int type;
-{
-	return (__sym_ntos (__p_type_syms, type, (int *)0));
+p_type(int type) {
+	return (sym_ntos(__p_type_syms, type, (int *)0));
 }
 
 /*
- * Return a mnemonic for class
+ * Return a string for the type.
  */
 const char *
-__p_class(class)
-	int class;
-{
-	return (__sym_ntos (__p_class_syms, class, (int *)0));
+p_section(int section, int opcode) {
+	const struct res_sym *symbols;
+
+	switch (opcode) {
+	case ns_o_update:
+		symbols = __p_update_section_syms;
+		break;
+	default:
+		symbols = __p_default_section_syms;
+		break;
+	}
+	return (sym_ntos(symbols, section, (int *)0));
+}
+
+/*
+ * Return a mnemonic for class.
+ */
+const char *
+p_class(int class) {
+	return (sym_ntos(__p_class_syms, class, (int *)0));
 }
 
 /*
  * Return a mnemonic for an option
  */
 const char *
-__p_option(option)
-	u_long option;
-{
+p_option(u_long option) {
 	static char nbuf[40];
 
 	switch (option) {
@@ -1055,63 +560,33 @@ __p_option(option)
 	case RES_DNSRCH:	return "dnsrch";
 	case RES_INSECURE1:	return "insecure1";
 	case RES_INSECURE2:	return "insecure2";
+				/* XXX nonreentrant */
 	default:		sprintf(nbuf, "?0x%lx?", (u_long)option);
 				return (nbuf);
 	}
 }
 
 /*
- * Return a mnemonic for a time to live
+ * Return a mnemonic for a time to live.
  */
 const char *
-p_time(value)
-	u_int32_t value;
-{
-	static char nbuf[60];
-	int secs, mins, hours, days;
-	register char *p;
+p_time(u_int32_t value) {
+	static char nbuf[40];		/* XXX nonreentrant */
 
-	if (value == 0) {
-		strcpy(nbuf, "0 secs");
-		return (nbuf);
-	}
-
-	secs = value % 60;
-	value /= 60;
-	mins = value % 60;
-	value /= 60;
-	hours = value % 24;
-	value /= 24;
-	days = value;
-	value = 0;
-
-#define	PLURALIZE(x)	x, (x == 1) ? "" : "s"
-	p = nbuf;
-	if (days) {
-		(void)sprintf(p, "%d day%s", PLURALIZE(days));
-		while (*++p);
-	}
-	if (hours) {
-		if (days)
-			*p++ = ' ';
-		(void)sprintf(p, "%d hour%s", PLURALIZE(hours));
-		while (*++p);
-	}
-	if (mins) {
-		if (days || hours)
-			*p++ = ' ';
-		(void)sprintf(p, "%d min%s", PLURALIZE(mins));
-		while (*++p);
-	}
-	if (secs || ! (days || hours || mins)) {
-		if (days || hours || mins)
-			*p++ = ' ';
-		(void)sprintf(p, "%d sec%s", PLURALIZE(secs));
-	}
+	if (ns_format_ttl(value, nbuf, sizeof nbuf) < 0)
+		sprintf(nbuf, "%u", value);
 	return (nbuf);
 }
 
 /*
+ * Return a string for the rcode.
+ */
+const char *
+p_rcode(int rcode) {
+	return (sym_ntos(__p_rcode_syms, rcode, (int *)0));
+}
+
+/*
  * routines to convert between on-the-wire RR format and zone file format.
  * Does not contain conversion to/from decimal degrees; divide or multiply
  * by 60*60*1000 for that.
@@ -1125,7 +600,7 @@ static const char *
 precsize_ntoa(prec)
 	u_int8_t prec;
 {
-	static char retbuf[sizeof "90000000.00"];
+	static char retbuf[sizeof "90000000.00"];	/* XXX nonreentrant */
 	unsigned long val;
 	int mantissa, exponent;
 
@@ -1143,47 +618,40 @@ static u_int8_t
 precsize_aton(strptr)
 	char **strptr;
 {
+	unsigned int mval = 0, cmval = 0;
 	u_int8_t retval = 0;
 	char *cp;
-	int exponent = 0;
-	int mantissa = 0;
+	int exponent;
+	int mantissa;
 
 	cp = *strptr;
-	while (isdigit(*cp)) {
-		if (mantissa == 0)
-			mantissa = *cp - '0';
-		else
-			exponent++;
-		cp++;
-	}
 
-	if (*cp == '.') {
+	while (isdigit(*cp))
+		mval = mval * 10 + (*cp++ - '0');
+
+	if (*cp == '.') {		/* centimeters */
 		cp++;
 		if (isdigit(*cp)) {
-			if (mantissa == 0)
-				mantissa = *cp - '0';
-			else
-				exponent++;
-			cp++;
-
+			cmval = (*cp++ - '0') * 10;
 			if (isdigit(*cp)) {
-				if (mantissa == 0)
-					mantissa = *cp - '0';
-				else
-					exponent++;
-				cp++;
+				cmval += (*cp++ - '0');
 			}
-			else
-				exponent++;
 		}
 	}
-	else
-		exponent += 2;
+	cmval = (mval * 100) + cmval;
+
+	for (exponent = 0; exponent < 9; exponent++)
+		if (cmval < poweroften[exponent+1])
+			break;
+
+	mantissa = cmval / poweroften[exponent];
+	if (mantissa > 9)
+		mantissa = 9;
 
-	if (mantissa == 0)
-		exponent = 0;
 	retval = (mantissa << 4) | exponent;
+
 	*strptr = cp;
+
 	return (retval);
 }
 
@@ -1193,7 +661,7 @@ latlon2ul(latlonstrptr,which)
 	char **latlonstrptr;
 	int *which;
 {
-	register char *cp;
+	char *cp;
 	u_int32_t retval;
 	int deg = 0, min = 0, secs = 0, secsfrac = 0;
 
@@ -1331,7 +799,7 @@ loc_aton(ascii, binary)
 		altsign = -1;
 		cp++;
 	}
-
+    
 	if (*cp == '+')
 		cp++;
 
@@ -1360,7 +828,7 @@ loc_aton(ascii, binary)
 		goto defaults;
 
 	siz = precsize_aton(&cp);
-
+	
 	while (!isspace(*cp) && (cp < maxcp))	/* if trailing garbage or m */
 		cp++;
 
@@ -1393,7 +861,7 @@ loc_aton(ascii, binary)
 	PUTLONG(latit,bcp);
 	PUTLONG(longit,bcp);
 	PUTLONG(alt,bcp);
-
+    
 	return (16);		/* size of RR in octets */
 }
 
@@ -1404,25 +872,30 @@ loc_ntoa(binary, ascii)
 	char *ascii;
 {
 	static char *error = "?";
-	register const u_char *cp = binary;
+	static char tmpbuf[sizeof
+"1000 60 60.000 N 1000 60 60.000 W -12345678.00m 90000000.00m 90000000.00m 90000000.00m"];
+	const u_char *cp = binary;
 
 	int latdeg, latmin, latsec, latsecfrac;
 	int longdeg, longmin, longsec, longsecfrac;
 	char northsouth, eastwest;
 	int altmeters, altfrac, altsign;
 
-	const int referencealt = 100000 * 100;
+	const u_int32_t referencealt = 100000 * 100;
 
 	int32_t latval, longval, altval;
 	u_int32_t templ;
 	u_int8_t sizeval, hpval, vpval, versionval;
-
+    
 	char *sizestr, *hpstr, *vpstr;
 
 	versionval = *cp++;
 
+	if (ascii == NULL)
+		ascii = tmpbuf;
+
 	if (versionval) {
-		sprintf(ascii, "; error: unknown LOC RR version");
+		(void) sprintf(ascii, "; error: unknown LOC RR version");
 		return (ascii);
 	}
 
@@ -1438,7 +911,7 @@ loc_ntoa(binary, ascii)
 	longval = (templ - ((unsigned)1<<31));
 
 	GETLONG(templ, cp);
-	if (templ < (u_int32_t) referencealt) { /* below WGS 84 spheroid */
+	if (templ < referencealt) { /* below WGS 84 spheroid */
 		altval = referencealt - templ;
 		altsign = -1;
 	} else {
@@ -1503,14 +976,12 @@ loc_ntoa(binary, ascii)
 
 /* Return the number of DNS hierarchy levels in the name. */
 int
-__dn_count_labels(name)
-	char *name;
-{
+dn_count_labels(const char *name) {
 	int i, len, count;
 
 	len = strlen(name);
-
-	for(i = 0, count = 0; i < len; i++) {
+	for (i = 0, count = 0; i < len; i++) {
+		/* XXX need to check for \. or use named's nlabels(). */
 		if (name[i] == '.')
 			count++;
 	}
@@ -1529,23 +1000,28 @@ __dn_count_labels(name)
 }
 
 
-/*
- * Make dates expressed in seconds-since-Jan-1-1970 easy to read.
+/* 
+ * Make dates expressed in seconds-since-Jan-1-1970 easy to read.  
  * SIG records are required to be printed like this, by the Secure DNS RFC.
  */
 char *
-__p_secstodate (secs)
-	unsigned long secs;
-{
-	static char output[15];         /* YYYYMMDDHHMMSS and null */
+p_secstodate (u_long secs) {
+	/* XXX nonreentrant */
+	static char output[15];		/* YYYYMMDDHHMMSS and null */
 	time_t clock = secs;
-	struct tm time;
-
-	__gmtime_r(&clock, &time);
-	time.tm_year += 1900;
-	time.tm_mon += 1;
+	struct tm *time;
+	
+#ifdef HAVE_TIME_R
+	struct time timebuf;
+	
+	time = gmtime_r(&clock, &timebuf);
+#else
+	time = gmtime(&clock);
+#endif
+	time->tm_year += 1900;
+	time->tm_mon += 1;
 	sprintf(output, "%04d%02d%02d%02d%02d%02d",
-		time.tm_year, time.tm_mon, time.tm_mday,
-		time.tm_hour, time.tm_min, time.tm_sec);
+		time->tm_year, time->tm_mon, time->tm_mday,
+		time->tm_hour, time->tm_min, time->tm_sec);
 	return (output);
 }
diff --git a/resolv/res_debug.h b/resolv/res_debug.h
new file mode 100644
index 0000000000..4a0aa99ab4
--- /dev/null
+++ b/resolv/res_debug.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 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.
+ */
+
+#ifndef _RES_DEBUG_H_
+#define _RES_DEBUG_H_
+
+#ifndef DEBUG
+#   define Dprint(cond, args) /*empty*/
+#   define DprintQ(cond, args, query, size) /*empty*/
+#   define Aerror(statp, file, string, error, address) /*empty*/
+#   define Perror(statp, file, string, error) /*empty*/
+#else
+#   define Dprint(cond, args) if (cond) {fprintf args;} else {}
+#   define DprintQ(cond, args, query, size) if (cond) {\
+			fprintf args;\
+			res_pquery(statp, query, size, stdout);\
+		} else {}
+#endif
+
+#endif /* _RES_DEBUG_H_ */ 
diff --git a/resolv/res_init.c b/resolv/res_init.c
index e5520ff65e..bf6cf7f7b1 100644
--- a/resolv/res_init.c
+++ b/resolv/res_init.c
@@ -1,6 +1,4 @@
 /*
- * ++Copyright++ 1985, 1989, 1993
- * -
  * Copyright (c) 1985, 1989, 1993
  *    The Regents of the University of California.  All rights reserved.
  *
@@ -27,7 +25,9 @@
  * 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
@@ -45,68 +45,55 @@
  * 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[] = "@(#)res_init.c	8.1 (Berkeley) 6/7/93";
-static char rcsid[] = "$Id$";
+static const char sccsid[] = "@(#)res_init.c	8.1 (Berkeley) 6/7/93";
+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 <stdio.h>
 #include <ctype.h>
 #include <resolv.h>
-#if defined(BSD) && (BSD >= 199103)
-# include <unistd.h>
-# include <stdlib.h>
-# include <string.h>
-#else
-# include "../conf/portability.h"
-#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
 
-/*-------------------------------------- info about "sortlist" --------------
- * Marc Majka		1994/04/16
- * Allan Nathanson	1994/10/29 (BIND 4.9.3.x)
- *
- * NetInfo resolver configuration directory support.
- *
- * Allow a NetInfo directory to be created in the hierarchy which
- * contains the same information as the resolver configuration file.
- *
- * - The local domain name is stored as the value of the "domain" property.
- * - The Internet address(es) of the name server(s) are stored as values
- *   of the "nameserver" property.
- * - The name server addresses are stored as values of the "nameserver"
- *   property.
- * - The search list for host-name lookup is stored as values of the
- *   "search" property.
- * - The sortlist comprised of IP address netmask pairs are stored as
- *   values of the "sortlist" property. The IP address and optional netmask
- *   should be separated by a slash (/) or ampersand (&) character.
- * - Internal resolver variables can be set from the value of the "options"
- *   property.
- */
-#if defined(NeXT)
-#  include <netinfo/ni.h>
-#  define NI_PATH_RESCONF "/locations/resolver"
-#  define NI_TIMEOUT 10
-static int netinfo_res_init __P((int *haveenv, int *havesearch));
-#endif
+/* Options.  Should all be left alone. */
+#define RESOLVSORT
+#define RFC1535
+#undef DEBUG
 
-#if defined(USE_OPTIONS_H)
-# include "../conf/options.h"
-#endif
+static void
+res_setoptions (res_state statp, const char *options, const char *source)
+     internal_function;
 
-static void res_setoptions __P((char *, char *)) internal_function;
 
 #ifdef RESOLVSORT
 static const char sort_mask[] = "/&";
@@ -122,12 +109,6 @@ static u_int32_t net_mask __P((struct in_addr));
  * Resolver state default settings.
  */
 
-struct __res_state _res
-# if defined(__BIND_RES_TEXT)
-	= { RES_TIMEOUT, }	/* Motorola, et al. */
-# endif
-	;
-
 /*
  * Set up default settings.  If the configuration file exist, the values
  * there will have precedence.  Otherwise, the server address is set to
@@ -138,7 +119,7 @@ struct __res_state _res
  * since it was noted that INADDR_ANY actually meant ``the first interface
  * you "ifconfig"'d at boot time'' and if this was a SLIP or PPP interface,
  * it had to be "up" in order for you to reach your own name server.  It
- * was later decided that since the recommended practice is to always
+ * was later decided that since the recommended practice is to always 
  * install local static routes through 127.0.0.1 for all your network
  * interfaces, that we could solve this problem without a code change.
  *
@@ -150,12 +131,19 @@ struct __res_state _res
  * Return 0 if completes successfully, -1 on error
  */
 int
-res_init()
-{
+res_ninit(res_state statp) {
+	extern int __res_vinit(res_state, int);
+
+	return (__res_vinit(statp, 0));
+}
+
+/* This function has to be reachable by res_data.c but not publically. */
+int
+__res_vinit(res_state statp, int preinit) {
 	register FILE *fp;
 	register char *cp, **pp;
 	register int n;
-	char buf[MAXDNAME];
+	char buf[BUFSIZ];
 	int nserv = 0;    /* number of nameserver records read from file */
 	int haveenv = 0;
 	int havesearch = 0;
@@ -167,54 +155,32 @@ res_init()
 	int dots;
 #endif
 
-	/*
-	 * These three fields used to be statically initialized.  This made
-	 * it hard to use this code in a shared library.  It is necessary,
-	 * now that we're doing dynamic initialization here, that we preserve
-	 * the old semantics: if an application modifies one of these three
-	 * fields of _res before res_init() is called, res_init() will not
-	 * alter them.  Of course, if an application is setting them to
-	 * _zero_ before calling res_init(), hoping to override what used
-	 * to be the static default, we can't detect it and unexpected results
-	 * will follow.  Zero for any of these fields would make no sense,
-	 * so one can safely assume that the applications were already getting
-	 * unexpected results.
-	 *
-	 * _res.options is tricky since some apps were known to diddle the bits
-	 * before res_init() was first called. We can't replicate that semantic
-	 * with dynamic initialization (they may have turned bits off that are
-	 * set in RES_DEFAULT).  Our solution is to declare such applications
-	 * "broken".  They could fool us by setting RES_INIT but none do (yet).
-	 */
-	if (!_res.retrans)
-		_res.retrans = RES_TIMEOUT;
-	if (!_res.retry)
-		_res.retry = 4;
-	if (!(_res.options & RES_INIT))
-		_res.options = RES_DEFAULT;
-
-	/*
-	 * This one used to initialize implicitly to zero, so unless the app
-	 * has set it to something in particular, we can randomize it now.
-	 */
-	if (!_res.id)
-		_res.id = res_randomid();
+	if (!preinit) {
+		statp->retrans = RES_TIMEOUT;
+		statp->retry = RES_DFLRETRY;
+		statp->options = RES_DEFAULT;
+		statp->id = res_randomid();
+	}
 
 #ifdef USELOOPBACK
-	_res.nsaddr.sin_addr = inet_makeaddr(IN_LOOPBACKNET, 1);
-	_res.nscount = 1;
+	statp->nsaddr.sin_addr = inet_makeaddr(IN_LOOPBACKNET, 1);
 #else
-	_res.nsaddr.sin_addr.s_addr = INADDR_ANY;
-	_res.nscount = 0;
+	statp->nsaddr.sin_addr.s_addr = INADDR_ANY;
 #endif
-	_res.nsaddr.sin_family = AF_INET;
-	_res.nsaddr.sin_port = htons(NAMESERVER_PORT);
-	_res.ndots = 1;
-	_res.pfcode = 0;
+	statp->nsaddr.sin_family = AF_INET;
+	statp->nsaddr.sin_port = htons(NAMESERVER_PORT);
+	statp->nscount = 1;
+	statp->ndots = 1;
+	statp->pfcode = 0;
+	statp->_sock = -1;
+	statp->_flags = 0;
+	statp->qhook = NULL;
+	statp->rhook = NULL;
 
 	/* Allow user to override the local domain definition */
 	if ((cp = __secure_getenv("LOCALDOMAIN")) != NULL) {
-		(void)strncpy(_res.defdname, cp, sizeof(_res.defdname) - 1);
+		(void)strncpy(statp->defdname, cp, sizeof(statp->defdname) - 1);
+		statp->defdname[sizeof(statp->defdname) - 1] = '\0';
 		haveenv++;
 
 		/*
@@ -224,10 +190,10 @@ res_init()
 		 * one that they want to use as an individual (even more
 		 * important now that the rfc1535 stuff restricts searches)
 		 */
-		cp = _res.defdname;
-		pp = _res.dnsrch;
+		cp = statp->defdname;
+		pp = statp->dnsrch;
 		*pp++ = cp;
-		for (n = 0; *cp && pp < _res.dnsrch + MAXDNSRCH; cp++) {
+		for (n = 0; *cp && pp < statp->dnsrch + MAXDNSRCH; cp++) {
 			if (*cp == '\n')	/* silly backwards compat */
 				break;
 			else if (*cp == ' ' || *cp == '\t') {
@@ -251,9 +217,6 @@ res_init()
 	(line[sizeof(name) - 1] == ' ' || \
 	 line[sizeof(name) - 1] == '\t'))
 
-#ifdef	NeXT
-	if (netinfo_res_init(&haveenv, &havesearch) == 0)
-#endif
 	if ((fp = fopen(_PATH_RESCONF, "r")) != NULL) {
 	    /* read the config file */
 	    while (fgets_unlocked(buf, sizeof(buf), fp) != NULL) {
@@ -269,8 +232,9 @@ res_init()
 			    cp++;
 		    if ((*cp == '\0') || (*cp == '\n'))
 			    continue;
-		    strncpy(_res.defdname, cp, sizeof(_res.defdname) - 1);
-		    if ((cp = strpbrk(_res.defdname, " \t\n")) != NULL)
+		    strncpy(statp->defdname, cp, sizeof(statp->defdname) - 1);
+		    statp->defdname[sizeof(statp->defdname) - 1] = '\0';
+		    if ((cp = strpbrk(statp->defdname, " \t\n")) != NULL)
 			    *cp = '\0';
 		    havesearch = 0;
 		    continue;
@@ -284,16 +248,18 @@ res_init()
 			    cp++;
 		    if ((*cp == '\0') || (*cp == '\n'))
 			    continue;
-		    strncpy(_res.defdname, cp, sizeof(_res.defdname) - 1);
-		    *__strchrnul (_res.defdname, '\n') = '\0';
+		    strncpy(statp->defdname, cp, sizeof(statp->defdname) - 1);
+		    statp->defdname[sizeof(statp->defdname) - 1] = '\0';
+		    if ((cp = strchr(statp->defdname, '\n')) != NULL)
+			    *cp = '\0';
 		    /*
 		     * Set search list to be blank-separated strings
 		     * on rest of line.
 		     */
-		    cp = _res.defdname;
-		    pp = _res.dnsrch;
+		    cp = statp->defdname;
+		    pp = statp->dnsrch;
 		    *pp++ = cp;
-		    for (n = 0; *cp && pp < _res.dnsrch + MAXDNSRCH; cp++) {
+		    for (n = 0; *cp && pp < statp->dnsrch + MAXDNSRCH; cp++) {
 			    if (*cp == ' ' || *cp == '\t') {
 				    *cp = 0;
 				    n = 1;
@@ -318,9 +284,9 @@ res_init()
 		    while (*cp == ' ' || *cp == '\t')
 			cp++;
 		    if ((*cp != '\0') && (*cp != '\n') && inet_aton(cp, &a)) {
-			_res.nsaddr_list[nserv].sin_addr = a;
-			_res.nsaddr_list[nserv].sin_family = AF_INET;
-			_res.nsaddr_list[nserv].sin_port =
+			statp->nsaddr_list[nserv].sin_addr = a;
+			statp->nsaddr_list[nserv].sin_family = AF_INET;
+			statp->nsaddr_list[nserv].sin_port =
 				htons(NAMESERVER_PORT);
 			nserv++;
 		    }
@@ -343,7 +309,7 @@ res_init()
 			n = *cp;
 			*cp = 0;
 			if (inet_aton(net, &a)) {
-			    _res.sort_list[nsort].addr = a;
+			    statp->sort_list[nsort].addr = a;
 			    if (ISSORTMASK(n)) {
 				*cp++ = n;
 				net = cp;
@@ -353,14 +319,14 @@ res_init()
 				n = *cp;
 				*cp = 0;
 				if (inet_aton(net, &a)) {
-				    _res.sort_list[nsort].mask = a.s_addr;
+				    statp->sort_list[nsort].mask = a.s_addr;
 				} else {
-				    _res.sort_list[nsort].mask =
-					net_mask(_res.sort_list[nsort].addr);
+				    statp->sort_list[nsort].mask = 
+					net_mask(statp->sort_list[nsort].addr);
 				}
 			    } else {
-				_res.sort_list[nsort].mask =
-				    net_mask(_res.sort_list[nsort].addr);
+				statp->sort_list[nsort].mask = 
+				    net_mask(statp->sort_list[nsort].addr);
 			    }
 			    nsort++;
 			}
@@ -370,35 +336,35 @@ res_init()
 		}
 #endif
 		if (MATCH(buf, "options")) {
-		    res_setoptions(buf + sizeof("options") - 1, "conf");
+		    res_setoptions(statp, buf + sizeof("options") - 1, "conf");
 		    continue;
 		}
 	    }
-	    if (nserv > _res.nscount)
-		_res.nscount = nserv;
+	    if (nserv > 1) 
+		statp->nscount = nserv;
 #ifdef RESOLVSORT
-	    _res.nsort = nsort;
+	    statp->nsort = nsort;
 #endif
 	    (void) fclose(fp);
 	}
-	if (_res.defdname[0] == 0 &&
-	    __gethostname(buf, sizeof(_res.defdname) - 1) == 0 &&
+	if (statp->defdname[0] == 0 &&
+	    __gethostname(buf, sizeof(statp->defdname) - 1) == 0 &&
 	    (cp = strchr(buf, '.')) != NULL)
-		strcpy(_res.defdname, cp + 1);
+		strcpy(statp->defdname, cp + 1);
 
 	/* find components of local domain that might be searched */
 	if (havesearch == 0) {
-		pp = _res.dnsrch;
-		*pp++ = _res.defdname;
+		pp = statp->dnsrch;
+		*pp++ = statp->defdname;
 		*pp = NULL;
 
 #ifndef RFC1535
 		dots = 0;
-		for (cp = _res.defdname; *cp; cp++)
+		for (cp = statp->defdname; *cp; cp++)
 			dots += (*cp == '.');
 
-		cp = _res.defdname;
-		while (pp < _res.dnsrch + MAXDFLSRCH) {
+		cp = statp->defdname;
+		while (pp < statp->dnsrch + MAXDFLSRCH) {
 			if (dots < LOCALDOMAINPARTS)
 				break;
 			cp = __rawmemchr(cp, '.') + 1;    /* we know there is one */
@@ -407,32 +373,31 @@ res_init()
 		}
 		*pp = NULL;
 #ifdef DEBUG
-		if (_res.options & RES_DEBUG) {
+		if (statp->options & RES_DEBUG) {
 			printf(";; res_init()... default dnsrch list:\n");
-			for (pp = _res.dnsrch; *pp; pp++)
+			for (pp = statp->dnsrch; *pp; pp++)
 				printf(";;\t%s\n", *pp);
 			printf(";;\t..END..\n");
 		}
-#endif /* DEBUG */
+#endif
 #endif /* !RFC1535 */
 	}
 
 	if ((cp = __secure_getenv("RES_OPTIONS")) != NULL)
-		res_setoptions(cp, "env");
-	_res.options |= RES_INIT;
+		res_setoptions(statp, cp, "env");
+	statp->options |= RES_INIT;
 	return (0);
 }
 
 static void
 internal_function
-res_setoptions(options, source)
-	char *options, *source;
+res_setoptions(res_state statp, const char *options, const char *source)
 {
-	char *cp = options;
+	const char *cp = options;
 	int i;
 
 #ifdef DEBUG
-	if (_res.options & RES_DEBUG)
+	if (statp->options & RES_DEBUG)
 		printf(";; res_setoptions(\"%s\", \"%s\")...\n",
 		       options, source);
 #endif
@@ -444,24 +409,41 @@ res_setoptions(options, source)
 		if (!strncmp(cp, "ndots:", sizeof("ndots:") - 1)) {
 			i = atoi(cp + sizeof("ndots:") - 1);
 			if (i <= RES_MAXNDOTS)
-				_res.ndots = i;
+				statp->ndots = i;
 			else
-				_res.ndots = RES_MAXNDOTS;
+				statp->ndots = RES_MAXNDOTS;
 #ifdef DEBUG
-			if (_res.options & RES_DEBUG)
-				printf(";;\tndots=%d\n", _res.ndots);
+			if (statp->options & RES_DEBUG)
+				printf(";;\tndots=%d\n", statp->ndots);
 #endif
+		} else if (!strncmp(cp, "timeout:", sizeof("timeout:") - 1)) {
+			i = atoi(cp + sizeof("timeout:") - 1);
+			if (i <= RES_MAXRETRANS)
+				statp->retrans = i;
+			else
+				statp->retrans = RES_MAXRETRANS;
+		} else if (!strncmp(cp, "attempts:", sizeof("attempts:") - 1)){
+			i = atoi(cp + sizeof("attempts:") - 1);
+			if (i <= RES_MAXRETRY)
+				statp->retry = i;
+			else
+				statp->retry = RES_MAXRETRY;
 		} else if (!strncmp(cp, "debug", sizeof("debug") - 1)) {
 #ifdef DEBUG
-			if (!(_res.options & RES_DEBUG)) {
+			if (!(statp->options & RES_DEBUG)) {
 				printf(";; res_setoptions(\"%s\", \"%s\")..\n",
 				       options, source);
-				_res.options |= RES_DEBUG;
+				statp->options |= RES_DEBUG;
 			}
 			printf(";;\tdebug\n");
 #endif
 		} else if (!strncmp(cp, "inet6", sizeof("inet6") - 1)) {
-			_res.options |= RES_USE_INET6;
+			statp->options |= RES_USE_INET6;
+		} else if (!strncmp(cp, "rotate", sizeof("rotate") - 1)) {
+			statp->options |= RES_ROTATE;
+		} else if (!strncmp(cp, "no-check-names",
+				    sizeof("no-check-names") - 1)) {
+			statp->options |= RES_NOCHECKNAME;
 		} else {
 			/* XXX - print a warning here? */
 		}
@@ -487,164 +469,8 @@ net_mask(in)		/* XXX - should really use system's version of this */
 }
 #endif
 
-#ifdef	NeXT
-static int
-netinfo_res_init(haveenv, havesearch)
-	int *haveenv;
-	int *havesearch;
-{
-    register	int n;
-    void	*domain, *parent;
-    ni_id	dir;
-    ni_status	status;
-    ni_namelist	nl;
-    int		nserv = 0;
-#ifdef RESOLVSORT
-    int		nsort = 0;
-#endif
-
-    status = ni_open(NULL, ".", &domain);
-    if (status == NI_OK) {
-	ni_setreadtimeout(domain, NI_TIMEOUT);
-	ni_setabort(domain, 1);
-
-	/* climb the NetInfo hierarchy to find a resolver directory */
-	while (status == NI_OK) {
-	    status = ni_pathsearch(domain, &dir, NI_PATH_RESCONF);
-	    if (status == NI_OK) {
-	    /* found a resolver directory */
-
-		if (*haveenv == 0) {
-		    /* get the default domain name */
-		    status = ni_lookupprop(domain, &dir, "domain", &nl);
-		    if (status == NI_OK && nl.ni_namelist_len > 0) {
-			(void)strncpy(_res.defdname,
-				      nl.ni_namelist_val[0],
-				      sizeof(_res.defdname) - 1);
-			_res.defdname[sizeof(_res.defdname) - 1] = '\0';
-			ni_namelist_free(&nl);
-			*havesearch = 0;
-		    }
-
-		    /* get search list */
-		    status = ni_lookupprop(domain, &dir, "search", &nl);
-		    if (status == NI_OK && nl.ni_namelist_len > 0) {
-			(void)strncpy(_res.defdname,
-				      nl.ni_namelist_val[0],
-				      sizeof(_res.defdname) - 1);
-			_res.defdname[sizeof(_res.defdname) - 1] = '\0';
-			/* copy  */
-			for (n = 0;
-			     n < nl.ni_namelist_len && n < MAXDNSRCH;
-			     n++) {
-			     /* duplicate up to MAXDNSRCH servers */
-			     char *cp = nl.ni_namelist_val[n];
-			    _res.dnsrch[n] =
-				strcpy((char *)malloc(strlen(cp) + 1), cp);
-			}
-			ni_namelist_free(&nl);
-			*havesearch = 1;
-		    }
-		}
-
-		/* get list of nameservers */
-		status = ni_lookupprop(domain, &dir, "nameserver", &nl);
-		if (status == NI_OK && nl.ni_namelist_len > 0) {
-		    /* copy up to MAXNS servers */
-		    for (n = 0;
-		         n < nl.ni_namelist_len && nserv < MAXNS;
-			 n++) {
-			struct in_addr a;
-
-			if (inet_aton(nl.ni_namelist_val[n], &a)) {
-			    _res.nsaddr_list[nserv].sin_addr = a;
-			    _res.nsaddr_list[nserv].sin_family = AF_INET;
-			    _res.nsaddr_list[nserv].sin_port =
-				htons(NAMESERVER_PORT);
-			    nserv++;
-			}
-		    }
-		    ni_namelist_free(&nl);
-		}
-
-		if (nserv > _res.nscount)
-		    _res.nscount = nserv;
-
-#ifdef RESOLVSORT
-		/* get sort order */
-		status = ni_lookupprop(domain, &dir, "sortlist", &nl);
-		if (status == NI_OK && nl.ni_namelist_len > 0) {
-
-		    /* copy up to MAXRESOLVSORT address/netmask pairs */
-		    for (n = 0;
-		         n < nl.ni_namelist_len && nsort < MAXRESOLVSORT;
-			 n++) {
-			char ch;
-			char *cp;
-			const char *sp;
-			struct in_addr a;
-
-			cp = NULL;
-			for (sp = sort_mask; *sp; sp++) {
-				char *cp1;
-				cp1 = strchr(nl.ni_namelist_val[n], *sp);
-				if (cp && cp1)
-					cp = (cp < cp1)? cp : cp1;
-				else if (cp1)
-					cp = cp1;
-			}
-			if (cp != NULL) {
-				ch = *cp;
-				*cp = '\0';
-				break;
-			}
-			if (inet_aton(nl.ni_namelist_val[n], &a)) {
-			    _res.sort_list[nsort].addr = a;
-			    if (*cp && ISSORTMASK(ch)) {
-			    	*cp++ = ch;
-			        if (inet_aton(cp, &a)) {
-				    _res.sort_list[nsort].mask = a.s_addr;
-				} else {
-				    _res.sort_list[nsort].mask =
-					net_mask(_res.sort_list[nsort].addr);
-				}
-			    } else {
-				_res.sort_list[nsort].mask =
-				    net_mask(_res.sort_list[nsort].addr);
-			    }
-			    nsort++;
-			}
-		    }
-		    ni_namelist_free(&nl);
-		}
-
-		_res.nsort = nsort;
-#endif
-
-		/* get resolver options */
-		status = ni_lookupprop(domain, &dir, "options", &nl);
-		if (status == NI_OK && nl.ni_namelist_len > 0) {
-		    res_setoptions(nl.ni_namelist_val[0], "conf");
-		    ni_namelist_free(&nl);
-		}
-
-		ni_free(domain);
-		return(1);	/* using DNS configuration from NetInfo */
-	    }
-
-	    status = ni_open(domain, "..", &parent);
-	    ni_free(domain);
-	    if (status == NI_OK)
-		domain = parent;
-	}
-    }
-    return(0);	/* if not using DNS configuration from NetInfo */
-}
-#endif	/* NeXT */
-
 u_int
-res_randomid()
-{
+res_randomid(void) {
 	struct timeval now;
 
 	__gettimeofday(&now, NULL);
diff --git a/resolv/res_libc.c b/resolv/res_libc.c
new file mode 100644
index 0000000000..14d565df0d
--- /dev/null
+++ b/resolv/res_libc.c
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 1995-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.
+ */
+
+/* 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
+
+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.  */
+
+
+int
+res_init(void) {
+	extern int __res_vinit(res_state, int);
+
+	/*
+	 * These three fields used to be statically initialized.  This made
+	 * it hard to use this code in a shared library.  It is necessary,
+	 * now that we're doing dynamic initialization here, that we preserve
+	 * the old semantics: if an application modifies one of these three
+	 * fields of _res before res_init() is called, res_init() will not
+	 * alter them.  Of course, if an application is setting them to
+	 * _zero_ before calling res_init(), hoping to override what used
+	 * to be the static default, we can't detect it and unexpected results
+	 * will follow.  Zero for any of these fields would make no sense,
+	 * so one can safely assume that the applications were already getting
+	 * unexpected results.
+	 *
+	 * _res.options is tricky since some apps were known to diddle the bits
+	 * before res_init() was first called. We can't replicate that semantic
+	 * with dynamic initialization (they may have turned bits off that are
+	 * set in RES_DEFAULT).  Our solution is to declare such applications
+	 * "broken".  They could fool us by setting RES_INIT but none do (yet).
+	 */
+	if (!_res.retrans)
+		_res.retrans = RES_TIMEOUT;
+	if (!_res.retry)
+		_res.retry = 4;
+	if (!(_res.options & RES_INIT))
+		_res.options = RES_DEFAULT;
+
+	/*
+	 * This one used to initialize implicitly to zero, so unless the app
+	 * has set it to something in particular, we can randomize it now.
+	 */
+	if (!_res.id)
+		_res.id = res_randomid();
+
+	return (__res_vinit(&_res, 1));
+}
+
+/* We need a resolver context - in unthreaded apps, this weak function
+   provides it.  */
+
+struct __res_state *
+weak_const_function
+__res_state(void)
+{
+  return &_res;
+}
diff --git a/resolv/res_mkquery.c b/resolv/res_mkquery.c
index 8f3e66fff9..dba2c80e26 100644
--- a/resolv/res_mkquery.c
+++ b/resolv/res_mkquery.c
@@ -1,6 +1,4 @@
 /*
- * ++Copyright++ 1985, 1993
- * -
  * Copyright (c) 1985, 1993
  *    The Regents of the University of California.  All rights reserved.
  *
@@ -27,7 +25,9 @@
  * 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
@@ -45,72 +45,79 @@
  * 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[] = "@(#)res_mkquery.c	8.1 (Berkeley) 6/4/93";
-static char rcsid[] = "$Id$";
+static const char sccsid[] = "@(#)res_mkquery.c	8.1 (Berkeley) 6/4/93";
+static const char rcsid[] = "$Id$";
 #endif /* LIBC_SCCS and not lint */
 
 #include <sys/types.h>
 #include <sys/param.h>
 #include <netinet/in.h>
 #include <arpa/nameser.h>
-
-#include <stdio.h>
 #include <netdb.h>
 #include <resolv.h>
-#if defined(BSD) && (BSD >= 199103)
-# include <string.h>
-#else
-# include "../conf/portability.h"
-#endif
+#include <stdio.h>
+#include <string.h>
 
-#if defined(USE_OPTIONS_H)
-# include <../conf/options.h>
-#endif
+/* Options.  Leave them on. */
+/* #define DEBUG */
+
+extern const char *_res_opcodes[];
 
 /*
  * Form all types of queries.
  * Returns the size of the result or -1.
  */
 int
-res_mkquery(op, dname, class, type, data, datalen, newrr_in, buf, buflen)
-	int op;			/* opcode of query */
-	const char *dname;	/* domain name */
-	int class, type;	/* class and type of query */
-	const u_char *data;	/* resource record data */
-	int datalen;		/* length of data */
-	const u_char *newrr_in;	/* new rr for modify or append */
-	u_char *buf;		/* buffer to put query */
-	int buflen;		/* size of buffer */
+res_nmkquery(res_state statp,
+	     int op,			/* opcode of query */
+	     const char *dname,		/* domain name */
+	     int class, int type,	/* class and type of query */
+	     const u_char *data,	/* resource record data */
+	     int datalen,		/* length of data */
+	     const u_char *newrr_in,	/* new rr for modify or append */
+	     u_char *buf,		/* buffer to put query */
+	     int buflen)		/* size of buffer */
 {
 	register HEADER *hp;
 	register u_char *cp;
 	register int n;
 	u_char *dnptrs[20], **dpp, **lastdnptr;
 
-	if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
-		__set_h_errno (NETDB_INTERNAL);
-		return (-1);
-	}
 #ifdef DEBUG
-	if (_res.options & RES_DEBUG)
-		printf(";; res_mkquery(%d, %s, %d, %d)\n",
-		       op, dname, class, type);
+	if (statp->options & RES_DEBUG)
+		printf(";; res_nmkquery(%s, %s, %s, %s)\n",
+		       _res_opcodes[op], dname, p_class(class), p_type(type));
 #endif
 	/*
 	 * Initialize header fields.
 	 */
 	if ((buf == NULL) || (buflen < HFIXEDSZ))
 		return (-1);
-	bzero(buf, HFIXEDSZ);
+	memset(buf, 0, HFIXEDSZ);
 	hp = (HEADER *) buf;
-	hp->id = htons(++_res.id);
+	hp->id = htons(++statp->id);
 	hp->opcode = op;
-	hp->rd = (_res.options & RES_RECURSE) != 0;
+	hp->rd = (statp->options & RES_RECURSE) != 0;
 	hp->rcode = NOERROR;
 	cp = buf + HFIXEDSZ;
 	buflen -= HFIXEDSZ;
@@ -173,7 +180,7 @@ res_mkquery(op, dname, class, type, data, datalen, newrr_in, buf, buflen)
 		__putshort(datalen, cp);
 		cp += INT16SZ;
 		if (datalen) {
-			bcopy(data, cp, datalen);
+			memcpy(cp, data, datalen);
 			cp += datalen;
 		}
 		hp->ancount = htons(1);
diff --git a/resolv/res_query.c b/resolv/res_query.c
index 80c10344f9..deebf4c62b 100644
--- a/resolv/res_query.c
+++ b/resolv/res_query.c
@@ -1,6 +1,4 @@
 /*
- * ++Copyright++ 1988, 1993
- * -
  * Copyright (c) 1988, 1993
  *    The Regents of the University of California.  All rights reserved.
  *
@@ -27,7 +25,9 @@
  * 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
@@ -45,13 +45,28 @@
  * 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[] = "@(#)res_query.c	8.1 (Berkeley) 6/4/93";
-static char rcsid[] = "$Id$";
+static const char sccsid[] = "@(#)res_query.c	8.1 (Berkeley) 6/4/93";
+static const char rcsid[] = "$Id$";
 #endif /* LIBC_SCCS and not lint */
 
 #include <sys/types.h>
@@ -59,22 +74,16 @@ static char rcsid[] = "$Id$";
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <arpa/nameser.h>
-
-#include <stdio.h>
-#include <netdb.h>
-#include <resolv.h>
 #include <ctype.h>
 #include <errno.h>
-#if defined(BSD) && (BSD >= 199306)
-# include <stdlib.h>
-# include <string.h>
-#else
-# include "../conf/portability.h"
-#endif
+#include <netdb.h>
+#include <resolv.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
 
-#if defined(USE_OPTIONS_H)
-# include <../conf/options.h>
-#endif
+/* Options.  Leave them on. */
+/* #undef DEBUG */
 
 #if PACKETSZ > 1024
 #define MAXPACKET	PACKETSZ
@@ -82,82 +91,75 @@ static char rcsid[] = "$Id$";
 #define MAXPACKET	1024
 #endif
 
-const char *hostalias __P((const char *));
-
-
 /*
  * Formulate a normal query, send, and await answer.
  * Returned answer is placed in supplied buffer "answer".
  * Perform preliminary check of answer, returning success only
  * if no error is indicated and the answer count is nonzero.
  * Return the size of the response on success, -1 on error.
- * Error number is left in h_errno.
+ * Error number is left in H_ERRNO.
  *
  * Caller must parse answer and determine whether it answers the question.
  */
 int
-res_query(name, class, type, answer, anslen)
-	const char *name;	/* domain name */
-	int class, type;	/* class and type of query */
-	u_char *answer;		/* buffer to put answer */
-	int anslen;		/* size of answer buffer */
+res_nquery(res_state statp,
+	   const char *name,	/* domain name */
+	   int class, int type,	/* class and type of query */
+	   u_char *answer,	/* buffer to put answer */
+	   int anslen)		/* size of answer buffer */
 {
 	u_char buf[MAXPACKET];
-	register HEADER *hp = (HEADER *) answer;
+	HEADER *hp = (HEADER *) answer;
 	int n;
 
 	hp->rcode = NOERROR;	/* default */
 
-	if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
-		__set_h_errno (NETDB_INTERNAL);
-		return (-1);
-	}
 #ifdef DEBUG
-	if (_res.options & RES_DEBUG)
+	if (statp->options & RES_DEBUG)
 		printf(";; res_query(%s, %d, %d)\n", name, class, type);
 #endif
 
-	n = res_mkquery(QUERY, name, class, type, NULL, 0, NULL,
-			buf, sizeof(buf));
+	n = res_nmkquery(statp, QUERY, name, class, type, NULL, 0, NULL,
+			 buf, sizeof(buf));
 	if (n <= 0) {
 #ifdef DEBUG
-		if (_res.options & RES_DEBUG)
+		if (statp->options & RES_DEBUG)
 			printf(";; res_query: mkquery failed\n");
 #endif
-		__set_h_errno (NO_RECOVERY);
+		RES_SET_H_ERRNO(statp, NO_RECOVERY);
 		return (n);
 	}
-	n = res_send(buf, n, answer, anslen);
+	n = res_nsend(statp, buf, n, answer, anslen);
 	if (n < 0) {
 #ifdef DEBUG
-		if (_res.options & RES_DEBUG)
+		if (statp->options & RES_DEBUG)
 			printf(";; res_query: send error\n");
 #endif
-		__set_h_errno (TRY_AGAIN);
+		RES_SET_H_ERRNO(statp, TRY_AGAIN);
 		return (n);
 	}
 
 	if (hp->rcode != NOERROR || ntohs(hp->ancount) == 0) {
 #ifdef DEBUG
-		if (_res.options & RES_DEBUG)
+		if (statp->options & RES_DEBUG)
 			printf(";; rcode = %d, ancount=%d\n", hp->rcode,
 			    ntohs(hp->ancount));
 #endif
 		switch (hp->rcode) {
 		case NXDOMAIN:
-			__set_h_errno (HOST_NOT_FOUND);
+			RES_SET_H_ERRNO(statp, HOST_NOT_FOUND);
 			break;
 		case SERVFAIL:
-			__set_h_errno (TRY_AGAIN);
+			RES_SET_H_ERRNO(statp, TRY_AGAIN);
 			break;
 		case NOERROR:
-			__set_h_errno (NO_DATA);
+			RES_SET_H_ERRNO(statp, NO_DATA);
 			break;
 		case FORMERR:
 		case NOTIMP:
 		case REFUSED:
 		default:
-			__set_h_errno (NO_RECOVERY);
+			RES_SET_H_ERRNO(statp, NO_RECOVERY);
 			break;
 		}
 		return (-1);
@@ -169,52 +171,43 @@ res_query(name, class, type, answer, anslen)
  * Formulate a normal query, send, and retrieve answer in supplied buffer.
  * Return the size of the response on success, -1 on error.
  * If enabled, implement search rules until answer or unrecoverable failure
- * is detected.  Error code, if any, is left in h_errno.
+ * is detected.  Error code, if any, is left in H_ERRNO.
  */
 int
-res_search(name, class, type, answer, anslen)
-	const char *name;	/* domain name */
-	int class, type;	/* class and type of query */
-	u_char *answer;		/* buffer to put answer */
-	int anslen;		/* size of answer */
+res_nsearch(res_state statp,
+	    const char *name,	/* domain name */
+	    int class, int type,	/* class and type of query */
+	    u_char *answer,	/* buffer to put answer */
+	    int anslen)		/* size of answer */
 {
-	register const char *cp, * const *domain;
+	const char *cp, * const *domain;
 	HEADER *hp = (HEADER *) answer;
+	char tmp[NS_MAXDNAME];
 	u_int dots;
-	int trailing_dot, ret, saved_herrno;
-	int got_nodata = 0, got_servfail = 0, tried_as_is = 0;
+	int trailing_dot, ret;
+	int got_nodata = 0, got_servfail = 0, root_on_list = 0;
 
-	if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
-		__set_h_errno (NETDB_INTERNAL);
-		return (-1);
-	}
 	__set_errno (0);
-	__set_h_errno (HOST_NOT_FOUND);	/* default, if we never query */
+	RES_SET_H_ERRNO(statp, HOST_NOT_FOUND);  /* True if we never query. */
+
 	dots = 0;
-	for (cp = name; *cp; cp++)
+	for (cp = name; *cp != '\0'; cp++)
 		dots += (*cp == '.');
 	trailing_dot = 0;
 	if (cp > name && *--cp == '.')
 		trailing_dot++;
 
-	/*
-	 * if there aren't any dots, it could be a user-level alias
-	 */
-	if (!dots && (cp = __hostalias(name)) != NULL)
-		return (res_query(cp, class, type, answer, anslen));
+	/* If there aren't any dots, it could be a user-level alias. */
+	if (!dots && (cp = res_hostalias(statp, name, tmp, sizeof tmp))!= NULL)
+		return (res_nquery(statp, cp, class, type, answer, anslen));
 
 	/*
-	 * If there are dots in the name already, let's just give it a try
-	 * 'as is'.  The threshold can be set with the "ndots" option.
+	 * If there are enough dots in the name, do no searching.
+	 * (The threshold can be set with the "ndots" option.)
 	 */
-	saved_herrno = -1;
-	if (dots >= _res.ndots) {
-		ret = res_querydomain(name, NULL, class, type, answer, anslen);
-		if (ret > 0)
-			return (ret);
-		saved_herrno = h_errno;
-		tried_as_is++;
-	}
+	if (dots >= statp->ndots || trailing_dot)
+		return (res_nquerydomain(statp, name, NULL, class, type,
+					 answer, anslen));
 
 	/*
 	 * We do at least one level of search if
@@ -222,16 +215,21 @@ res_search(name, class, type, answer, anslen)
 	 *	- there is at least one dot, there is no trailing dot,
 	 *	  and RES_DNSRCH is set.
 	 */
-	if ((!dots && (_res.options & RES_DEFNAMES)) ||
-	    (dots && !trailing_dot && (_res.options & RES_DNSRCH))) {
+	if ((!dots && (statp->options & RES_DEFNAMES) != 0) ||
+	    (dots && !trailing_dot && (statp->options & RES_DNSRCH) != 0)) {
 		int done = 0;
 
-		for (domain = (const char * const *)_res.dnsrch;
+		for (domain = (const char * const *)statp->dnsrch;
 		     *domain && !done;
 		     domain++) {
 
-			ret = res_querydomain(name, *domain, class, type,
-					      answer, anslen);
+			if (domain[0][0] == '\0' ||
+			    (domain[0][0] == '.' && domain[0][1] == '\0'))
+				root_on_list++;
+
+			ret = res_nquerydomain(statp, name, *domain,
+					       class, type,
+					       answer, anslen);
 			if (ret > 0)
 				return (ret);
 
@@ -249,11 +247,11 @@ res_search(name, class, type, answer, anslen)
 			 * fully-qualified.
 			 */
 			if (errno == ECONNREFUSED) {
-				__set_h_errno (TRY_AGAIN);
+				RES_SET_H_ERRNO(statp, TRY_AGAIN);
 				return (-1);
 			}
 
-			switch (h_errno) {
+			switch (statp->res_h_errno) {
 			case NO_DATA:
 				got_nodata++;
 				/* FALLTHROUGH */
@@ -275,34 +273,33 @@ res_search(name, class, type, answer, anslen)
 			/* if we got here for some reason other than DNSRCH,
 			 * we only wanted one iteration of the loop, so stop.
 			 */
-			if (!(_res.options & RES_DNSRCH))
+			if ((statp->options & RES_DNSRCH) == 0)
 				done++;
 		}
 	}
 
-	/* if we have not already tried the name "as is", do that now.
-	 * note that we do this regardless of how many dots were in the
-	 * name or whether it ends with a dot.
+	/*
+	 * If the name has any dots at all, and "." is not on the search
+	 * list, then try an as-is query now.
 	 */
-	if (!tried_as_is) {
-		ret = res_querydomain(name, NULL, class, type, answer, anslen);
+	if (statp->ndots) {
+		ret = res_nquerydomain(statp, name, NULL, class, type,
+				       answer, anslen);
 		if (ret > 0)
 			return (ret);
 	}
 
 	/* if we got here, we didn't satisfy the search.
-	 * if we did an initial full query, return that query's h_errno
+	 * if we did an initial full query, return that query's H_ERRNO
 	 * (note that we wouldn't be here if that query had succeeded).
 	 * else if we ever got a nodata, send that back as the reason.
-	 * else send back meaningless h_errno, that being the one from
+	 * else send back meaningless H_ERRNO, that being the one from
 	 * the last DNSRCH we did.
 	 */
-	if (saved_herrno != -1)
-		__set_h_errno (saved_herrno);
-	else if (got_nodata)
-		__set_h_errno (NO_DATA);
+	if (got_nodata)
+		RES_SET_H_ERRNO(statp, NO_DATA);
 	else if (got_servfail)
-		__set_h_errno (TRY_AGAIN);
+		RES_SET_H_ERRNO(statp, TRY_AGAIN);
 	return (-1);
 }
 
@@ -311,23 +308,20 @@ res_search(name, class, type, answer, anslen)
  * removing a trailing dot from name if domain is NULL.
  */
 int
-res_querydomain(name, domain, class, type, answer, anslen)
-	const char *name, *domain;
-	int class, type;	/* class and type of query */
-	u_char *answer;		/* buffer to put answer */
-	int anslen;		/* size of answer */
+res_nquerydomain(res_state statp,
+	    const char *name,
+	    const char *domain,
+	    int class, int type,	/* class and type of query */
+	    u_char *answer,		/* buffer to put answer */
+	    int anslen)		/* size of answer */
 {
-	char nbuf[MAXDNAME * 2 + 2];
+	char nbuf[MAXDNAME];
 	const char *longname = nbuf;
-	int n;
+	int n, d;
 
-	if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
-		__set_h_errno (NETDB_INTERNAL);
-		return (-1);
-	}
 #ifdef DEBUG
-	if (_res.options & RES_DEBUG)
-		printf(";; res_querydomain(%s, %s, %d, %d)\n",
+	if (statp->options & RES_DEBUG)
+		printf(";; res_nquerydomain(%s, %s, %d, %d)\n",
 		       name, domain?domain:"<Nil>", class, type);
 #endif
 	if (domain == NULL) {
@@ -335,30 +329,36 @@ res_querydomain(name, domain, class, type, answer, anslen)
 		 * Check for trailing '.';
 		 * copy without '.' if present.
 		 */
-		n = strlen(name) - 1;
-		if (n != (0 - 1) && name[n] == '.'
-		    && n < (int) (sizeof(nbuf) - 1)) {
-			bcopy(name, nbuf, n);
+		n = strlen(name);
+		if (n >= MAXDNAME) {
+			RES_SET_H_ERRNO(statp, NO_RECOVERY);
+			return (-1);
+		}
+		n--;
+		if (n >= 0 && name[n] == '.') {
+			strncpy(nbuf, name, n);
 			nbuf[n] = '\0';
 		} else
 			longname = name;
-	} else
-		sprintf(nbuf, "%.*s.%.*s", MAXDNAME, name, MAXDNAME, domain);
-
-	return (res_query(longname, class, type, answer, anslen));
+	} else {
+		n = strlen(name);
+		d = strlen(domain);
+		if (n + d + 1 >= MAXDNAME) {
+			RES_SET_H_ERRNO(statp, NO_RECOVERY);
+			return (-1);
+		}
+		sprintf(nbuf, "%s.%s", name, domain);
+	}
+	return (res_nquery(statp, longname, class, type, answer, anslen));
 }
 
 const char *
-hostalias(name)
-	register const char *name;
-{
-	register char *cp1, *cp2;
-	FILE *fp;
-	char *file;
+res_hostalias(const res_state statp, const char *name, char *dst, size_t siz) {
+	char *file, *cp1, *cp2;
 	char buf[BUFSIZ];
-	static char abuf[MAXDNAME];
+	FILE *fp;
 
-	if (_res.options & RES_NOALIASES)
+	if (statp->options & RES_NOALIASES)
 		return (NULL);
 	file = __secure_getenv("HOSTALIASES");
 	if (file == NULL || (fp = fopen(file, "r")) == NULL)
@@ -371,17 +371,18 @@ hostalias(name)
 		if (!*cp1)
 			break;
 		*cp1 = '\0';
-		if (!strcasecmp(buf, name)) {
+		if (ns_samename(buf, name) == 1) {
 			while (isspace(*++cp1))
 				;
 			if (!*cp1)
 				break;
 			for (cp2 = cp1 + 1; *cp2 && !isspace(*cp2); ++cp2)
 				;
-			abuf[sizeof(abuf) - 1] = *cp2 = '\0';
-			strncpy(abuf, cp1, sizeof(abuf) - 1);
+			*cp2 = '\0';
+			strncpy(dst, cp1, siz - 1);
+			dst[siz - 1] = '\0';
 			fclose(fp);
-			return (abuf);
+			return (dst);
 		}
 	}
 	fclose(fp);
diff --git a/resolv/res_send.c b/resolv/res_send.c
index e315383fa7..d3dc2ba8e1 100644
--- a/resolv/res_send.c
+++ b/resolv/res_send.c
@@ -1,6 +1,4 @@
 /*
- * ++Copyright++ 1985, 1989, 1993
- * -
  * Copyright (c) 1985, 1989, 1993
  *    The Regents of the University of California.  All rights reserved.
  *
@@ -27,7 +25,9 @@
  * 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
@@ -45,133 +45,165 @@
  * 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[] = "@(#)res_send.c	8.1 (Berkeley) 6/4/93";
-static char rcsid[] = "$Id$";
+static const char sccsid[] = "@(#)res_send.c	8.1 (Berkeley) 6/4/93";
+static const char rcsid[] = "$Id$";
 #endif /* LIBC_SCCS and not lint */
 
-	/* change this to "0"
-	 * if you talk to a lot
-	 * of multi-homed SunOS
-	 * ("broken") name servers.
-	 */
-#define	CHECK_SRVR_ADDR	1	/* XXX - should be in options.h */
-
 /*
  * Send query to name server and wait for reply.
  */
 
 #include <sys/types.h>
 #include <sys/param.h>
-#include <sys/poll.h>
 #include <sys/time.h>
 #include <sys/socket.h>
 #include <sys/uio.h>
+
 #include <netinet/in.h>
 #include <arpa/nameser.h>
 #include <arpa/inet.h>
 
-#include <stdio.h>
-#include <netdb.h>
 #include <errno.h>
+#include <netdb.h>
 #include <resolv.h>
-#if defined(BSD) && (BSD >= 199306)
-# include <stdlib.h>
-# include <string.h>
-# include <unistd.h>
-#else
-# include "../conf/portability.h"
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <sys/poll.h>
+
+/* Options.  Leave them on. */
+/* #undef DEBUG */
+#include "res_debug.h"
+
+#ifdef NEED_PSELECT
+static int		pselect(int, void *, void *, void *,
+				struct timespec *,
+				const sigset_t *);
 #endif
 
-#include <bits/libc-lock.h>
+#define	CHECK_SRVR_ADDR
 
-/* Lock to protect the connection use.  */
-__libc_lock_define_initialized (static, lock)
+/* From bind lib/isc/ev_timers.c:  */
+#define BILLION 1000000000
+static struct timespec
+evTimeSpec(struct timeval tv) {
+	struct timespec ts;
 
-static void res_close_internal (void);
+	ts.tv_sec = tv.tv_sec;
+	ts.tv_nsec = tv.tv_usec * 1000;
+	return (ts);
+}
 
-#if defined(USE_OPTIONS_H)
-# include <../conf/options.h>
-#endif
+static struct timespec
+evConsTime(time_t sec, long nsec) {
+	struct timespec x;
 
-static int s = -1;	/* socket used for communications */
-static int connected = 0;	/* is the socket connected */
-static int vc = 0;	/* is the socket a virtual circuit? */
+	x.tv_sec = sec;
+	x.tv_nsec = nsec;
+	return (x);
+}
 
-/* XXX - this should be done in portability.h */
-#if (defined(BSD) && (BSD >= 199103)) || defined(linux)
-# define CAN_RECONNECT 1
-#else
-# define CAN_RECONNECT 0
-#endif
+static struct timespec
+evAddTime(struct timespec addend1, struct timespec addend2) {
+	struct timespec x;
 
-#ifndef DEBUG
-#   define Dprint(cond, args) /*empty*/
-#   define DprintQ(cond, args, query, size) /*empty*/
-#   define Aerror(file, string, error, address) /*empty*/
-#   define Perror(file, string, error) /*empty*/
-#else
-#   define Dprint(cond, args) if (cond) {fprintf args;} else {}
-#   define DprintQ(cond, args, query, size) if (cond) {\
-			fprintf args;\
-			__fp_nquery(query, size, stdout);\
-		} else {}
+	x.tv_sec = addend1.tv_sec + addend2.tv_sec;
+	x.tv_nsec = addend1.tv_nsec + addend2.tv_nsec;
+	if (x.tv_nsec >= BILLION) {
+		x.tv_sec++;
+		x.tv_nsec -= BILLION;
+	}
+	return (x);
+}
+
+static struct timespec
+evSubTime(struct timespec minuend, struct timespec subtrahend) {
+	struct timespec x;
+
+	x.tv_sec = minuend.tv_sec - subtrahend.tv_sec;
+	if (minuend.tv_nsec >= subtrahend.tv_nsec)
+		x.tv_nsec = minuend.tv_nsec - subtrahend.tv_nsec;
+	else {
+		x.tv_nsec = BILLION - subtrahend.tv_nsec + minuend.tv_nsec;
+		x.tv_sec--;
+	}
+	return (x);
+}
+
+static int
+evCmpTime(struct timespec a, struct timespec b) {
+	long x = a.tv_sec - b.tv_sec;
+
+	if (x == 0L)
+		x = a.tv_nsec - b.tv_nsec;
+	return (x < 0L ? (-1) : x > 0L ? (1) : (0));
+}
+
+static struct timespec
+evNowTime() {
+	struct timeval now;
+
+	if (gettimeofday(&now, NULL) < 0)
+		return (evConsTime(0, 0));
+	return (evTimeSpec(now));
+}
+/* End of code from bind lib/isc/ev_timers.c.  */
+
+#ifdef DEBUG
     static void
-    Aerror(file, string, error, address)
-	FILE *file;
-	char *string;
-	int error;
-	struct sockaddr_in address;
+    Aerror(const res_state statp, FILE *file, const char *string, int error,
+	   struct sockaddr_in address)
     {
 	int save = errno;
 
-	if (_res.options & RES_DEBUG) {
+	if ((statp->options & RES_DEBUG) != 0) {
+		char tmp[sizeof "255.255.255.255"];
+
 		fprintf(file, "res_send: %s ([%s].%u): %s\n",
 			string,
-			inet_ntoa(address.sin_addr),
+			inet_ntop(address.sin_family, &address.sin_addr,
+				  tmp, sizeof tmp),
 			ntohs(address.sin_port),
 			strerror(error));
 	}
 	__set_errno (save);
     }
     static void
-    Perror(file, string, error)
-	FILE *file;
-	char *string;
-	int error;
-    {
+    Perror(const res_state statp, FILE *file, const char *string, int error) {
 	int save = errno;
 
-	if (_res.options & RES_DEBUG) {
+	if ((statp->options & RES_DEBUG) != 0)
 		fprintf(file, "res_send: %s: %s\n",
 			string, strerror(error));
-	}
 	__set_errno (save);
     }
 #endif
 
-static res_send_qhook Qhook = NULL;
-static res_send_rhook Rhook = NULL;
-
-void
-res_send_setqhook(hook)
-	res_send_qhook hook;
-{
-
-	Qhook = hook;
-}
-
-void
-res_send_setrhook(hook)
-	res_send_rhook hook;
-{
-
-	Rhook = hook;
-}
+static int cmpsock(struct sockaddr_in *a1, struct sockaddr_in *a2);
+void res_pquery(const res_state, const u_char *, int, FILE *);
 
 /* int
  * res_isourserver(ina)
@@ -183,33 +215,28 @@ res_send_setrhook(hook)
  *	paul vixie, 29may94
  */
 int
-res_isourserver(inp)
-	const struct sockaddr_in *inp;
-{
+res_ourserver_p(const res_state statp, const struct sockaddr_in *inp) {
 	struct sockaddr_in ina;
-	register int ns, ret;
+	int ns;
 
 	ina = *inp;
-	ret = 0;
-	for (ns = 0;  ns < _res.nscount;  ns++) {
-		register const struct sockaddr_in *srv = &_res.nsaddr_list[ns];
+	for (ns = 0;  ns < statp->nscount;  ns++) {
+		const struct sockaddr_in *srv = &statp->nsaddr_list[ns];
 
 		if (srv->sin_family == ina.sin_family &&
 		    srv->sin_port == ina.sin_port &&
 		    (srv->sin_addr.s_addr == INADDR_ANY ||
-		     srv->sin_addr.s_addr == ina.sin_addr.s_addr)) {
-			ret++;
-			break;
-		}
+		     srv->sin_addr.s_addr == ina.sin_addr.s_addr))
+			return (1);
 	}
-	return (ret);
+	return (0);
 }
 
 /* int
  * res_nameinquery(name, type, class, buf, eom)
  *	look for (name,type,class) in the query section of packet (buf,eom)
  * requires:
- *	buf + HFIXESDZ <= eom
+ *	buf + HFIXEDSZ <= eom
  * returns:
  *	-1 : format error
  *	0  : not found
@@ -218,17 +245,15 @@ res_isourserver(inp)
  *	paul vixie, 29may94
  */
 int
-res_nameinquery(name, type, class, buf, eom)
-	const char *name;
-	register int type, class;
-	const u_char *buf, *eom;
+res_nameinquery(const char *name, int type, int class,
+		const u_char *buf, const u_char *eom)
 {
-	register const u_char *cp = buf + HFIXEDSZ;
+	const u_char *cp = buf + HFIXEDSZ;
 	int qdcount = ntohs(((HEADER*)buf)->qdcount);
 
 	while (qdcount-- > 0) {
 		char tname[MAXDNAME+1];
-		register int n, ttype, tclass;
+		int n, ttype, tclass;
 
 		n = dn_expand(buf, eom, cp, tname, sizeof tname);
 		if (n < 0)
@@ -236,11 +261,10 @@ res_nameinquery(name, type, class, buf, eom)
 		cp += n;
 		if (cp + 2 * INT16SZ > eom)
 			return (-1);
-		ttype = _getshort(cp); cp += INT16SZ;
-		tclass = _getshort(cp); cp += INT16SZ;
-		if (ttype == type &&
-		    tclass == class &&
-		    strcasecmp(tname, name) == 0)
+		ttype = ns_get16(cp); cp += INT16SZ;
+		tclass = ns_get16(cp); cp += INT16SZ;
+		if (ttype == type && tclass == class &&
+		    ns_samename(tname, name) == 1)
 			return (1);
 	}
 	return (0);
@@ -258,21 +282,28 @@ res_nameinquery(name, type, class, buf, eom)
  *	paul vixie, 29may94
  */
 int
-res_queriesmatch(buf1, eom1, buf2, eom2)
-	const u_char *buf1, *eom1;
-	const u_char *buf2, *eom2;
+res_queriesmatch(const u_char *buf1, const u_char *eom1,
+		 const u_char *buf2, const u_char *eom2)
 {
-	register const u_char *cp = buf1 + HFIXEDSZ;
+	const u_char *cp = buf1 + HFIXEDSZ;
 	int qdcount = ntohs(((HEADER*)buf1)->qdcount);
 
 	if (buf1 + HFIXEDSZ > eom1 || buf2 + HFIXEDSZ > eom2)
 		return (-1);
 
+	/*
+	 * Only header section present in replies to
+	 * dynamic update packets.
+	 */
+	if ( (((HEADER *)buf1)->opcode == ns_o_update) &&
+	     (((HEADER *)buf2)->opcode == ns_o_update) )
+		return (1);
+
 	if (qdcount != ntohs(((HEADER*)buf2)->qdcount))
 		return (0);
 	while (qdcount-- > 0) {
 		char tname[MAXDNAME+1];
-		register int n, ttype, tclass;
+		int n, ttype, tclass;
 
 		n = dn_expand(buf1, eom1, cp, tname, sizeof tname);
 		if (n < 0)
@@ -280,8 +311,8 @@ res_queriesmatch(buf1, eom1, buf2, eom2)
 		cp += n;
 		if (cp + 2 * INT16SZ > eom1)
 			return (-1);
-		ttype = _getshort(cp);	cp += INT16SZ;
-		tclass = _getshort(cp); cp += INT16SZ;
+		ttype = ns_get16(cp);	cp += INT16SZ;
+		tclass = ns_get16(cp); cp += INT16SZ;
 		if (!res_nameinquery(tname, ttype, tclass, buf2, eom2))
 			return (0);
 	}
@@ -289,67 +320,69 @@ res_queriesmatch(buf1, eom1, buf2, eom2)
 }
 
 int
-res_send(buf, buflen, ans, anssiz)
-	const u_char *buf;
-	int buflen;
-	u_char *ans;
-	int anssiz;
+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;
-	register int n;
-	u_int badns;	/* XXX NSMAX can't exceed #/bits in this var */
-	int result = -1;
+	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;
 
-	if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
-		/* errno should have been set by res_init() in this case. */
-		return (-1);
-	}
 	if (anssiz < HFIXEDSZ) {
 		__set_errno (EINVAL);
 		return (-1);
 	}
-	DprintQ((_res.options & RES_DEBUG) || (_res.pfcode & RES_PRF_QUERY),
+	DprintQ((statp->options & RES_DEBUG) || (statp->pfcode & RES_PRF_QUERY),
 		(stdout, ";; res_send()\n"), buf, buflen);
-	v_circuit = (_res.options & RES_USEVC) || buflen > PACKETSZ;
+	v_circuit = (statp->options & RES_USEVC) || buflen > PACKETSZ;
 	gotsomewhere = 0;
 	connreset = 0;
 	terrno = ETIMEDOUT;
 	badns = 0;
 
-	__libc_lock_lock (lock);
+	/*
+	 * Some callers want to even out the load on their resolver list.
+	 */
+	if (statp->nscount > 0 && (statp->options & RES_ROTATE) != 0) {
+		struct sockaddr_in ina;
+		int lastns = statp->nscount - 1;
+
+		ina = statp->nsaddr_list[0];
+		for (ns = 0; ns < lastns; ns++)
+			statp->nsaddr_list[ns] = statp->nsaddr_list[ns + 1];
+		statp->nsaddr_list[lastns] = ina;
+	}
 
 	/*
 	 * Send request, RETRY times, or until successful
 	 */
-	for (try = 0; try < _res.retry; try++) {
-	    for (ns = 0; ns < _res.nscount; ns++) {
-		struct sockaddr_in *nsap = &_res.nsaddr_list[ns];
-    same_ns:
+	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_close_internal();
+			res_nclose(statp);
 			goto next_ns;
 		}
 
-		if (Qhook) {
+		if (statp->qhook) {
 			int done = 0, loops = 0;
 
 			do {
 				res_sendhookact act;
 
-				act = (*Qhook)(&nsap, &buf, &buflen,
-					       ans, anssiz, &resplen);
+				act = (*statp->qhook)(&nsap, &buf, &buflen,
+						      ans, anssiz, &resplen);
 				switch (act) {
 				case res_goahead:
 					done = 1;
 					break;
 				case res_nextns:
-					res_close_internal();
+					res_nclose(statp);
 					goto next_ns;
 				case res_done:
-					result = resplen;
-					goto and_out;
+					return (resplen);
 				case res_modified:
 					/* give the hook another try */
 					if (++loops < 42) /*doug adams*/
@@ -358,12 +391,12 @@ res_send(buf, buflen, ans, anssiz)
 				case res_error:
 					/*FALLTHROUGH*/
 				default:
-					goto and_out;
+					return (-1);
 				}
 			} while (!done);
 		}
 
-		Dprint(_res.options & RES_DEBUG,
+		Dprint(statp->options & RES_DEBUG,
 		       (stdout, ";; Querying server (# %d) address = %s\n",
 			ns + 1, inet_ntoa(nsap->sin_addr)));
 
@@ -373,33 +406,53 @@ res_send(buf, buflen, ans, anssiz)
 			u_short len;
 			u_char *cp;
 
-			/*
-			 * Use virtual circuit;
-			 * at most one attempt per server.
-			 */
-			try = _res.retry;
+			/* Use VC; at most one attempt per server. */
+			try = statp->retry;
 			truncated = 0;
-			if ((s < 0) || (!vc)) {
-				if (s >= 0)
-					res_close_internal();
 
-				s = socket(PF_INET, SOCK_STREAM, 0);
-				if (s < 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(stderr, "socket(vc)", errno);
-					goto and_out;
+					Perror(statp, stderr,
+					       "socket(vc)", errno);
+					return (-1);
 				}
 				__set_errno (0);
-				if (connect(s, (struct sockaddr *)nsap,
-					    sizeof(struct sockaddr)) < 0) {
+				if (connect(statp->_sock,
+					    (struct sockaddr *)nsap,
+					    sizeof *nsap) < 0) {
 					terrno = errno;
-					Aerror(stderr, "connect/vc",
+					Aerror(statp, stderr, "connect/vc",
 					       errno, *nsap);
 					badns |= (1 << ns);
-					res_close_internal();
+					res_nclose(statp);
 					goto next_ns;
 				}
-				vc = 1;
+				statp->_flags |= RES_F_VC;
 			}
 			/*
 			 * Send length & message
@@ -409,28 +462,30 @@ res_send(buf, buflen, ans, anssiz)
 			iov[0].iov_len = INT16SZ;
 			iov[1].iov_base = (caddr_t)buf;
 			iov[1].iov_len = buflen;
-			if (writev(s, iov, 2) != (INT16SZ + buflen)) {
+			if (writev(statp->_sock, iov, 2) !=
+			    (INT16SZ + buflen)) {
 				terrno = errno;
-				Perror(stderr, "write failed", errno);
+				Perror(statp, stderr, "write failed", errno);
 				badns |= (1 << ns);
-				res_close_internal();
+				res_nclose(statp);
 				goto next_ns;
 			}
 			/*
 			 * Receive length & response
 			 */
-read_len:
+ read_len:
 			cp = ans;
 			len = INT16SZ;
-			while ((n = read(s, (char *)cp, (int)len)) > 0) {
+			while ((n = read(statp->_sock,
+					 (char *)cp, (int)len)) > 0) {
 				cp += n;
 				if ((len -= n) <= 0)
 					break;
 			}
 			if (n <= 0) {
 				terrno = errno;
-				Perror(stderr, "read failed", errno);
-				res_close_internal();
+				Perror(statp, stderr, "read failed", errno);
+				res_nclose(statp);
 				/*
 				 * A long running process might get its TCP
 				 * connection reset if the remote server was
@@ -442,15 +497,15 @@ read_len:
 				 */
 				if (terrno == ECONNRESET && !connreset) {
 					connreset = 1;
-					res_close_internal();
+					res_nclose(statp);
 					goto same_ns;
 				}
-				res_close_internal();
+				res_nclose(statp);
 				goto next_ns;
 			}
-			resplen = _getshort(ans);
+			resplen = ns_get16(ans);
 			if (resplen > anssiz) {
-				Dprint(_res.options & RES_DEBUG,
+				Dprint(statp->options & RES_DEBUG,
 				       (stdout, ";; response truncated\n")
 				       );
 				truncated = 1;
@@ -461,23 +516,24 @@ read_len:
 				/*
 				 * Undersized message.
 				 */
-				Dprint(_res.options & RES_DEBUG,
+				Dprint(statp->options & RES_DEBUG,
 				       (stdout, ";; undersized: %d\n", len));
 				terrno = EMSGSIZE;
 				badns |= (1 << ns);
-				res_close_internal();
+				res_nclose(statp);
 				goto next_ns;
 			}
 			cp = ans;
 			while (len != 0 &&
-			       (n = read(s, (char *)cp, (int)len)) > 0) {
+			       (n = read(statp->_sock, (char *)cp, (int)len))
+			       > 0) {
 				cp += n;
 				len -= n;
 			}
 			if (n <= 0) {
 				terrno = errno;
-				Perror(stderr, "read(vc)", errno);
-				res_close_internal();
+				Perror(statp, stderr, "read(vc)", errno);
+				res_nclose(statp);
 				goto next_ns;
 			}
 			if (truncated) {
@@ -490,10 +546,11 @@ read_len:
 				while (len != 0) {
 					char junk[PACKETSZ];
 
-					n = ((size_t) len > sizeof(junk)
+					n = ((size_t)len > sizeof(junk)
 					     ? sizeof(junk)
 					     : len);
-					if ((n = read(s, junk, n)) > 0)
+					n = read(statp->_sock, junk, n);
+					if (n > 0)
 						len -= n;
 					else
 						break;
@@ -507,8 +564,8 @@ read_len:
 			 * wait for the correct one.
 			 */
 			if (hp->id != anhp->id) {
-				DprintQ((_res.options & RES_DEBUG) ||
-					(_res.pfcode & RES_PRF_REPLY),
+				DprintQ((statp->options & RES_DEBUG) ||
+					(statp->pfcode & RES_PRF_REPLY),
 					(stdout, ";; old answer (unexpected):\n"),
 					ans, (resplen>anssiz)?anssiz:resplen);
 				goto read_len;
@@ -517,27 +574,34 @@ read_len:
 			/*
 			 * Use datagrams.
 			 */
-			int timeout;
+			struct timespec start, timeout, finish;
+#ifdef _LIBC
 			struct pollfd pfd[1];
+			int ptimeout;
+#else			
+			fd_set dsmask;
+#endif
 			struct sockaddr_in from;
-			socklen_t fromlen;
-			time_t curtime;
-			time_t endtime;
-
-			if ((s < 0) || vc) {
-				if (vc)
-					res_close_internal();
-				s = socket(PF_INET, SOCK_DGRAM, 0);
-				if (s < 0) {
-#if !CAN_RECONNECT
+			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(stderr, "socket(dg)", errno);
-					goto and_out;
+					Perror(statp, stderr,
+					       "socket(dg)", errno);
+					return (-1);
 				}
-				connected = 0;
+				statp->_flags &= ~RES_F_CONN;
 			}
+#ifndef CANNOT_CONNECT_DGRAM
 			/*
 			 * On a 4.3BSD+ machine (client and server,
 			 * actually), sending to a nameserver datagram
@@ -553,28 +617,29 @@ read_len:
 			 * as we wish to receive answers from the first
 			 * server to respond.
 			 */
-			if (_res.nscount == 1 || (try == 0 && ns == 0)) {
+			if (statp->nscount == 1 || (try == 0 && ns == 0)) {
 				/*
 				 * Connect only if we are sure we won't
 				 * receive a response from another server.
 				 */
-				if (!connected) {
-					if (connect(s, (struct sockaddr *)nsap,
-						    sizeof(struct sockaddr)
-						    ) < 0) {
-						Aerror(stderr,
+				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_close_internal();
+						res_nclose(statp);
 						goto next_ns;
 					}
-					connected = 1;
+					statp->_flags |= RES_F_CONN;
 				}
-				if (send(s, (char*)buf, buflen, 0) != buflen) {
-					Perror(stderr, "send", errno);
+                              if (send(statp->_sock, (char*)buf, buflen, 0)
+				  != buflen) {
+					Perror(statp, stderr, "send", errno);
 					badns |= (1 << ns);
-					res_close_internal();
+					res_nclose(statp);
 					goto next_ns;
 				}
 			} else {
@@ -582,90 +647,130 @@ read_len:
 				 * Disconnect if we want to listen
 				 * for responses from more than one server.
 				 */
-				if (connected) {
-#if CAN_RECONNECT
+				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(s,
+					(void) connect(statp->_sock,
 						       (struct sockaddr *)
 						        &no_addr,
-						       sizeof(no_addr));
+						       sizeof no_addr);
 #else
-					int s1 = socket(PF_INET, SOCK_DGRAM,0);
+					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, s);
+					(void) dup2(s1, statp->_sock);
 					(void) close(s1);
-					Dprint(_res.options & RES_DEBUG,
+					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
-					connected = 0;
+#endif /* CAN_RECONNECT */
+					statp->_flags &= ~RES_F_CONN;
 					__set_errno (0);
 				}
-				if (sendto(s, (char*)buf, buflen, 0,
+#endif /* !CANNOT_CONNECT_DGRAM */
+				if (sendto(statp->_sock,
+					   (char*)buf, buflen, 0,
 					   (struct sockaddr *)nsap,
-					   sizeof(struct sockaddr))
+					   sizeof *nsap)
 				    != buflen) {
-					Aerror(stderr, "sendto", errno, *nsap);
+					Aerror(statp, stderr, "sendto", errno, *nsap);
 					badns |= (1 << ns);
-					res_close_internal();
+					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);
+				goto next_ns;
 			}
 
 			/*
 			 * Wait for reply
 			 */
-			curtime = time (NULL);
+			seconds = (statp->retrans << try);
 			if (try > 0)
-				endtime = (_res.retrans << try) / _res.nscount;
-			else {
-				endtime = _res.retrans;
-				if (endtime <= 0)
-					endtime = 1;
-			}
-			endtime += curtime;
-    wait:
-			timeout = MAX (endtime - curtime, 0) * 1000;
-#if 0
-			if (s < 0 || s >= FD_SETSIZE) {
-				Perror(stderr, "s out-of-bounds", EMFILE);
-				res_close_internal();
+				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;
 			}
-#endif
-			pfd[0].fd = s;
-			pfd[0].events = POLLIN;
-			n = __poll(pfd, 1, timeout);
 			if (n < 0) {
 				if (errno == EINTR) {
-					curtime = time (NULL);
-					goto wait;
+					struct timespec now;
+
+					now = evNowTime();
+					if (evCmpTime(finish, now) >= 0) {
+						timeout = evSubTime(finish,
+								    now);
+						goto wait;
+					}
 				}
-				Perror(stderr, "poll", errno);
-				res_close_internal();
-				goto next_ns;
-			}
-			if (n == 0) {
-				/*
-				 * timeout
-				 */
-				Dprint(_res.options & RES_DEBUG,
-				       (stdout, ";; timeout\n"));
-				gotsomewhere = 1;
-				res_close_internal();
+#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(s, (char*)ans, anssiz, 0,
+			resplen = recvfrom(statp->_sock, (char*)ans, anssiz,0,
 					   (struct sockaddr *)&from, &fromlen);
 			if (resplen <= 0) {
-				Perror(stderr, "recvfrom", errno);
-				res_close_internal();
+				Perror(statp, stderr, "recvfrom", errno);
+				res_nclose(statp);
 				goto next_ns;
 			}
 			gotsomewhere = 1;
@@ -673,12 +778,12 @@ read_len:
 				/*
 				 * Undersized message.
 				 */
-				Dprint(_res.options & RES_DEBUG,
+				Dprint(statp->options & RES_DEBUG,
 				       (stdout, ";; undersized: %d\n",
 					resplen));
 				terrno = EMSGSIZE;
 				badns |= (1 << ns);
-				res_close_internal();
+				res_nclose(statp);
 				goto next_ns;
 			}
 			if (hp->id != anhp->id) {
@@ -687,30 +792,28 @@ read_len:
 				 * XXX - potential security hazard could
 				 *	 be detected here.
 				 */
-				DprintQ((_res.options & RES_DEBUG) ||
-					(_res.pfcode & RES_PRF_REPLY),
+				DprintQ((statp->options & RES_DEBUG) ||
+					(statp->pfcode & RES_PRF_REPLY),
 					(stdout, ";; old answer:\n"),
 					ans, (resplen>anssiz)?anssiz:resplen);
-				curtime = time (NULL);
 				goto wait;
 			}
-#if CHECK_SRVR_ADDR
-			if (!(_res.options & RES_INSECURE1) &&
-			    !res_isourserver(&from)) {
+#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((_res.options & RES_DEBUG) ||
-					(_res.pfcode & RES_PRF_REPLY),
+				DprintQ((statp->options & RES_DEBUG) ||
+					(statp->pfcode & RES_PRF_REPLY),
 					(stdout, ";; not our server:\n"),
 					ans, (resplen>anssiz)?anssiz:resplen);
-				curtime = time (NULL);
 				goto wait;
 			}
 #endif
-			if (!(_res.options & RES_INSECURE2) &&
+			if (!(statp->options & RES_INSECURE2) &&
 			    !res_queriesmatch(buf, buf + buflen,
 					      ans, ans + anssiz)) {
 				/*
@@ -718,43 +821,42 @@ read_len:
 				 * XXX - potential security hazard could
 				 *	 be detected here.
 				 */
-				DprintQ((_res.options & RES_DEBUG) ||
-					(_res.pfcode & RES_PRF_REPLY),
+				DprintQ((statp->options & RES_DEBUG) ||
+					(statp->pfcode & RES_PRF_REPLY),
 					(stdout, ";; wrong query name:\n"),
 					ans, (resplen>anssiz)?anssiz:resplen);
-				curtime = time (NULL);
 				goto wait;
 			}
 			if (anhp->rcode == SERVFAIL ||
 			    anhp->rcode == NOTIMP ||
 			    anhp->rcode == REFUSED) {
-				DprintQ(_res.options & RES_DEBUG,
+				DprintQ(statp->options & RES_DEBUG,
 					(stdout, "server rejected query:\n"),
 					ans, (resplen>anssiz)?anssiz:resplen);
 				badns |= (1 << ns);
-				res_close_internal();
+				res_nclose(statp);
 				/* don't retry if called from dig */
-				if (!_res.pfcode)
+				if (!statp->pfcode)
 					goto next_ns;
 			}
-			if (!(_res.options & RES_IGNTC) && anhp->tc) {
+			if (!(statp->options & RES_IGNTC) && anhp->tc) {
 				/*
 				 * get rest of answer;
 				 * use TCP with same server.
 				 */
-				Dprint(_res.options & RES_DEBUG,
+				Dprint(statp->options & RES_DEBUG,
 				       (stdout, ";; truncated answer\n"));
 				v_circuit = 1;
-				res_close_internal();
+				res_nclose(statp);
 				goto same_ns;
 			}
 		} /*if vc/dg*/
-		Dprint((_res.options & RES_DEBUG) ||
-		       ((_res.pfcode & RES_PRF_REPLY) &&
-			(_res.pfcode & RES_PRF_HEAD1)),
+		Dprint((statp->options & RES_DEBUG) ||
+		       ((statp->pfcode & RES_PRF_REPLY) &&
+			(statp->pfcode & RES_PRF_HEAD1)),
 		       (stdout, ";; got answer:\n"));
-		DprintQ((_res.options & RES_DEBUG) ||
-			(_res.pfcode & RES_PRF_REPLY),
+		DprintQ((statp->options & RES_DEBUG) ||
+			(statp->pfcode & RES_PRF_REPLY),
 			(stdout, ""),
 			ans, (resplen>anssiz)?anssiz:resplen);
 		/*
@@ -765,25 +867,25 @@ read_len:
 		 * or if we haven't been asked to keep a socket open,
 		 * close the socket.
 		 */
-		if ((v_circuit && (!(_res.options & RES_USEVC) || ns != 0)) ||
-		    !(_res.options & RES_STAYOPEN)) {
-			res_close_internal();
+		if ((v_circuit && (!(statp->options & RES_USEVC) || ns != 0)) ||
+		    !(statp->options & RES_STAYOPEN)) {
+			res_nclose(statp);
 		}
-		if (Rhook) {
+		if (statp->rhook) {
 			int done = 0, loops = 0;
 
 			do {
 				res_sendhookact act;
 
-				act = (*Rhook)(nsap, buf, buflen,
-					       ans, anssiz, &resplen);
+				act = (*statp->rhook)(nsap, buf, buflen,
+						      ans, anssiz, &resplen);
 				switch (act) {
 				case res_goahead:
 				case res_done:
 					done = 1;
 					break;
 				case res_nextns:
-					res_close_internal();
+					res_nclose(statp);
 					goto next_ns;
 				case res_modified:
 					/* give the hook another try */
@@ -793,29 +895,24 @@ read_len:
 				case res_error:
 					/*FALLTHROUGH*/
 				default:
-					goto and_out;
+					return (-1);
 				}
 			} while (!done);
 
 		}
-		result = resplen;
-		goto and_out;
-    next_ns: ;
+		return (resplen);
+ next_ns: ;
 	   } /*foreach ns*/
 	} /*foreach retry*/
-	res_close_internal();
+	res_nclose(statp);
 	if (!v_circuit) {
 		if (!gotsomewhere)
-			__set_errno (ECONNREFUSED); /* no nameservers found */
+			__set_errno (ECONNREFUSED);	/* no nameservers found */
 		else
-			__set_errno (ETIMEDOUT);    /* no answer obtained */
+			__set_errno (ETIMEDOUT);	/* no answer obtained */
 	} else
 		__set_errno (terrno);
-
- and_out:
-	__libc_lock_unlock (lock);
-
-	return result;
+	return (-1);
 }
 
 /*
@@ -825,44 +922,46 @@ read_len:
  *
  * This routine is not expected to be user visible.
  */
-static void
-res_close_internal()
-{
-	if (s >= 0) {
-		(void) close(s);
-		s = -1;
-		connected = 0;
-		vc = 0;
+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);
 	}
 }
 
-void
-res_close ()
-{
-	__libc_lock_lock (lock);
-	res_close_internal ();
-	__libc_lock_unlock (lock);
+/* Private */
+static int
+cmpsock(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));
 }
 
-#ifdef ultrix
-/* ultrix 4.0 had some icky packaging in its libc.a.  alias for it here.
- * there is more gunk of this kind over in res_debug.c.
- */
-
-void
-_res_close()
+#ifdef NEED_PSELECT
+/* 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)
 {
-	res_close();
-}
+	struct timeval tv, *tvp;
+	sigset_t sigs;
+	int n;
 
-#undef res_send
-int
-res_send(buf, buflen, ans, anssiz)
-	const u_char *buf;
-	int buflen;
-	u_char *ans;
-	int anssiz;
-{
-	return (__res_send(buf, buflen, ans, anssiz));
+	if (tsp) {
+		tvp = &tv;
+		tv = evTimeVal(*tsp);
+	} else
+		tvp = NULL;
+	if (sigmask)
+		sigprocmask(SIG_SETMASK, sigmask, &sigs);
+	n = select(nfds, rfds, wfds, efds, tvp);
+	if (sigmask)
+		sigprocmask(SIG_SETMASK, &sigs, NULL);
+	if (tsp)
+		*tsp = evTimeSpec(tv);
+	return (n);
 }
-#endif /* Ultrix 4.0 hackery */
+#endif
diff --git a/resolv/resolv.h b/resolv/resolv.h
index 58742e90bb..b101262f51 100644
--- a/resolv/resolv.h
+++ b/resolv/resolv.h
@@ -50,6 +50,23 @@
  */
 
 /*
+ * 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.
+ */
+
+/*
  *	@(#)resolv.h	8.1 (Berkeley) 6/2/93
  *	$Id$
  */
@@ -76,7 +93,35 @@
  * is new enough to contain a certain feature.
  */
 
-#define	__RES	19960801
+#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.
@@ -88,6 +133,29 @@
 #define _PATH_RESCONF        "/etc/resolv.conf"
 #endif
 
+typedef enum { res_goahead, res_nextns, res_modified, res_done, res_error }
+	res_sendhookact;
+
+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)__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 */
+	char *	name;		/* Its symbolic name, like "MX" */
+	char *	humanname;	/* Its fun name, like "mail exchanger" */
+};
+
 /*
  * Global defines and variables for resolver stub.
  */
@@ -99,6 +167,9 @@
 #define	RES_TIMEOUT		5	/* min. seconds between retries */
 #define	MAXRESOLVSORT		10	/* number of net to sort on */
 #define	RES_MAXNDOTS		15	/* should reflect bit field size */
+#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. */
 
 struct __res_state {
 	int	retrans;	 	/* retransmission time interval */
@@ -119,9 +190,25 @@ struct __res_state {
 		struct in_addr	addr;
 		u_int32_t	mask;
 	} sort_list[MAXRESOLVSORT];
-	char	pad[72];		/* on an i386 this means 512b total */
+	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 */
+	u_int	_flags;			/* PRIVATE: see below */
+	char	pad[52];		/* On an i386 this means 512b total. */
 };
 
+typedef struct __res_state *res_state;
+
+/*
+ * Resolver flags (used to be discrete per-module statics ints).
+ */
+#define	RES_F_VC	0x00000001	/* socket is TCP */
+#define	RES_F_CONN	0x00000002	/* socket is connected */
+
+/* res_findzonecut() options */
+#define	RES_EXHAUSTIVE	0x00000001	/* always do all queries */
+
 /*
  * Resolver options (keep these in synch with res_debug.c, please)
  */
@@ -139,6 +226,9 @@ struct __res_state {
 #define	RES_INSECURE2	0x00000800	/* type 2 security disabled */
 #define	RES_NOALIASES	0x00001000	/* shuts off HOSTALIASES feature */
 #define	RES_USE_INET6	0x00002000	/* use/map IPv6 in gethostbyname() */
+#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_DEFAULT	(RES_RECURSE | RES_DEFNAMES | RES_DNSRCH)
 
@@ -146,8 +236,8 @@ struct __res_state {
  * Resolver "pfcode" values.  Used by dig.
  */
 #define RES_PRF_STATS	0x00000001
-/*			0x00000002	*/
-#define RES_PRF_CLASS   0x00000004
+#define RES_PRF_UPDATE	0x00000002
+#define RES_PRF_CLASS	0x00000004
 #define RES_PRF_CMD	0x00000008
 #define RES_PRF_QUES	0x00000010
 #define RES_PRF_ANS	0x00000020
@@ -159,133 +249,158 @@ struct __res_state {
 #define RES_PRF_HEADX	0x00000800
 #define RES_PRF_QUERY	0x00001000
 #define RES_PRF_REPLY	0x00002000
-#define RES_PRF_INIT    0x00004000
+#define RES_PRF_INIT	0x00004000
 /*			0x00008000	*/
 
-/* hooks are still experimental as of 4.9.2 */
-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);
+/* Things involving an internal (static) resolver context. */
+#if defined _REENTRANT || defined _LIBC_REENTRANT
+extern struct __res_state *__res_state(void);
+#define _res (*__res_state())
+#else
+extern struct __res_state _res;
+#endif
 
-typedef res_sendhookact (*res_send_rhook) (const struct sockaddr_in *ns,
-					   const u_char *query, int querylen,
-					   u_char *ans, int anssiz,
-					   int *resplen);
+#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_isourserver		__res_isourserver
+#define res_querydomain		__res_querydomain
+#define res_send		__res_send
 
-struct res_sym {
-	int	number;		/* Identifying number, like T_MX */
-	char *	name;		/* Its symbolic name, like "MX" */
-	char *	humanname;	/* Its fun name, like "mail exchanger" */
-};
+__BEGIN_DECLS
+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
 
-extern struct __res_state _res;
+#if !defined(SHARED_LIBBIND) || defined(_LIBC)
+/*
+ * If libbind is a shared object (well, DLL anyway)
+ * 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
+ *
+ */
+extern const struct res_sym __p_key_syms[];
+extern const struct res_sym __p_cert_syms[];
 extern const struct res_sym __p_class_syms[];
 extern const struct res_sym __p_type_syms[];
+extern const struct res_sym __p_rcode_syms[];
+#endif /* SHARED_LIBBIND */
 
-/* Private routines shared between libc/net, named, nslookup and others. */
-#define	res_hnok	__res_hnok
-#define	res_ownok	__res_ownok
-#define	res_mailok	__res_mailok
-#define	res_dnok	__res_dnok
-#define	sym_ston	__sym_ston
-#define	sym_ntos	__sym_ntos
-#define	sym_ntop	__sym_ntop
-#define b64_ntop	__b64_ntop
-#define	b64_pton	__b64_pton
-#define	loc_ntoa	__loc_ntoa
-#define	loc_aton	__loc_aton
-#define	dn_skipname	__dn_skipname
-#define	fp_resstat	__fp_resstat
-#define	fp_query	__fp_query
-#define	fp_nquery	__fp_nquery
-#define	hostalias	__hostalias
-#define	putlong		__putlong
-#define	putshort	__putshort
-#define p_class		__p_class
-#define p_time		__p_time
-#define p_type		__p_type
-#define	p_query		__p_query
-#define	p_cdnname	__p_cdnname
-#define	p_cdname	__p_cdname
-#define	p_fqnname	__p_fqnname
-#define	p_fqname	__p_fqname
-#define	p_rr		__p_rr
-#define	p_option	__p_option
-#define	p_secstodate	__p_secstodate
-#define	dn_count_labels	__dn_count_labels
-#define	dn_comp		__dn_comp
-#define	res_randomid	__res_randomid
-#define	res_send	__res_send
-#define	res_isourserver	__res_isourserver
-#define	res_nameinquery	__res_nameinquery
-#define	res_queriesmatch __res_queriesmatch
-#define	res_close	__res_close
-
-#ifdef BIND_RES_POSIX3
-#define	dn_expand	__dn_expand
-#define	res_init	__res_init
-#define	res_query	__res_query
-#define	res_search	__res_search
-#define	res_querydomain	__res_querydomain
-#define	res_mkquery	__res_mkquery
-#endif
-
+#define b64_ntop		__b64_ntop
+#define b64_pton		__b64_pton
+#define dn_comp			__dn_comp
+#define dn_count_labels		__dn_count_labels
+#define dn_skipname		__dn_skipname
+#define fp_resstat		__fp_resstat
+#define loc_aton		__loc_aton
+#define loc_ntoa		__loc_ntoa
+#define p_cdname		__p_cdname
+#define p_cdnname		__p_cdnname
+#define p_class			__p_class
+#define p_fqname		__p_fqname
+#define p_fqnname		__p_fqnname
+#define p_option		__p_option
+#define p_secstodate		__p_secstodate
+#define p_section		__p_section
+#define p_time			__p_time
+#define p_type			__p_type
+#define p_rcode			__p_rcode
+#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
+#define res_nameinquery		__res_nameinquery
+#define res_nclose		__res_nclose
+#define res_ninit		__res_ninit
+#define res_nmkquery		__res_nmkquery
+#define res_npquery		__res_npquery
+#define res_nquery		__res_nquery
+#define res_nquerydomain	__res_nquerydomain
+#define res_nsearch		__res_nsearch
+#define res_nsend		__res_nsend
+#define res_nisourserver	__res_nisourserver
+#define res_ownok		__res_ownok
+#define res_queriesmatch	__res_queriesmatch
+#define res_randomid		__res_randomid
+#define sym_ntop		__sym_ntop
+#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 *, char *, int *) __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 *, u_char *) __THROW;
-const char *	loc_ntoa (const u_char *, char *) __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		fp_resstat (struct __res_state *, FILE *) __THROW;
-void		fp_query (const u_char *, FILE *) __THROW;
-void		fp_nquery (const u_char *, int, FILE *) __THROW;
-const char *	hostalias (const 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;
-void		p_query (const u_char *) __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 u_char *	p_rr (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 (char *) __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;
-int		res_init (void) __THROW;
 u_int		res_randomid (void) __THROW;
-int		res_query (const char *, int, int, u_char *, int) __THROW;
-int		res_search (const char *, int, int, u_char *, int) __THROW;
-int		res_querydomain (const char *, const char *, int, int,
-				 u_char *, int) __THROW;
-int		res_mkquery (int, const char *, int, int, const u_char *, int,
-			     const u_char *, u_char *, int) __THROW;
-int		res_send (const u_char *, int, u_char *, int) __THROW;
-int		res_isourserver (const struct sockaddr_in *) __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;
-void		res_close (void) __THROW;
+const char *	p_section (int section, int opcode) __THROW;
+/* 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;
 __END_DECLS
 
-#endif /* resolv.h */
+#endif /* !_RESOLV_H_ */