Software Package:       
	bind

Release/Version:
	8.2.3-REL

Retrieved from:
	 ftp://ftp.isc.org/isc/bind

Bug reports:
	This software package is maintained by the software contributor,
	not BSDI.  Please send any bug reports to both support@BSDI.COM
	and bind-bugs@isc.org

Comments:

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Modifications to this version made by BSDI:

Added the file "makefile" to do man page formatting and provide the 
standard BSDI targets.

Index: src/Makefile
===================================================================
RCS file: /master/contrib/bind/src/Makefile,v
retrieving revision 1.6
diff -c -r1.6 Makefile
*** src/Makefile	2001/02/19 18:36:13	1.6
--- src/Makefile	2001/02/19 22:56:36
***************
*** 16,22 ****
  # $Id: Makefile,v 8.52 2000/11/21 12:54:37 marka Exp $
  
  TOP=
! SUBDIRS= include port lib bin
  
  SH=sh
  
--- 16,22 ----
  # $Id: Makefile,v 8.52 2000/11/21 12:54:37 marka Exp $
  
  TOP=
! SUBDIRS= bin
  
  SH=sh
  
Index: src/bin/Makefile
===================================================================
RCS file: /master/contrib/bind/src/bin/Makefile,v
retrieving revision 1.4
diff -c -r1.4 Makefile
*** src/bin/Makefile	2001/02/19 18:36:14	1.4
--- src/bin/Makefile	2001/02/19 22:57:37
***************
*** 27,33 ****
  O=o
  A=a
  INCL = ${TOP}/include
! LIBBIND = ${TOP}/lib/libbind.${A}
  LIBPORT = ${TOP}/port/libport.${A}
  PORTINCL = ${TOP}/port/${SYSTYPE}/include
  LEX = lex -I
--- 27,33 ----
  O=o
  A=a
  INCL = ${TOP}/include
! LIBBIND =
  LIBPORT = ${TOP}/port/libport.${A}
  PORTINCL = ${TOP}/port/${SYSTYPE}/include
  LEX = lex -I
***************
*** 53,59 ****
  	"DESTRUN=${DESTRUN}" "DESTHELP=${DESTHELP}" \
  	"RANLIB=${RANLIB}" "AR=${AR}" "ARPREF=${ARPREF}" "ARSUFF=${ARSUFF}" \
  	"INCL=../${INCL}" "PORTINCL=../${PORTINCL}" "EXE=${EXE}" \
! 	"LIBBIND=../${LIBBIND}" "LIBPORT=../${LIBPORT}" \
  	"INSTALL=${INSTALL}" "TOP=../${TOP}" \
  	"VER=${VER}" "STRIP=${STRIP}" "PS=${PS}" "INSTALL_LIB=${INSTALL_LIB}" \
  	"INSTALL_EXEC=${INSTALL_EXEC}" "BOUNDS=${BOUNDS}"
--- 53,59 ----
  	"DESTRUN=${DESTRUN}" "DESTHELP=${DESTHELP}" \
  	"RANLIB=${RANLIB}" "AR=${AR}" "ARPREF=${ARPREF}" "ARSUFF=${ARSUFF}" \
  	"INCL=../${INCL}" "PORTINCL=../${PORTINCL}" "EXE=${EXE}" \
! 	"LIBBIND=" "LIBPORT=../${LIBPORT}" \
  	"INSTALL=${INSTALL}" "TOP=../${TOP}" \
  	"VER=${VER}" "STRIP=${STRIP}" "PS=${PS}" "INSTALL_LIB=${INSTALL_LIB}" \
  	"INSTALL_EXEC=${INSTALL_EXEC}" "BOUNDS=${BOUNDS}"
Index: src/include/netdb.h
===================================================================
RCS file: /master/contrib/bind/src/include/netdb.h,v
retrieving revision 1.7
diff -c -r1.7 netdb.h
*** src/include/netdb.h	2001/02/19 18:36:27	1.7
--- src/include/netdb.h	2001/02/19 22:59:21
***************
*** 212,218 ****
  #define	AI_PASSIVE	0x00000001
  #define	AI_CANONNAME	0x00000002
  #define AI_NUMERICHOST	0x00000004
! #define	AI_MASK		0x00000007
  
  /*
   * Flag values for getipnodebyname()
--- 212,219 ----
  #define	AI_PASSIVE	0x00000001
  #define	AI_CANONNAME	0x00000002
  #define AI_NUMERICHOST	0x00000004
! #define	AI_MASK \
!     (AI_PASSIVE | AI_CANONNAME | AI_NUMERICHOST | AI_ADDRCONFIG)
  
  /*
   * Flag values for getipnodebyname()
***************
*** 236,241 ****
--- 237,249 ----
  #define	NI_NAMEREQD	0x00000004
  #define	NI_NUMERICSERV	0x00000008
  #define	NI_DGRAM	0x00000010
+ #define	NI_WITHSCOPEID	0x00000020
+ 
+ /*
+  * Scope delimit character
+  */
+ #define SCOPE_DELIMITER	'%'
+ 
  
  
  #ifdef _REENTRANT
Index: src/include/arpa/inet.h
===================================================================
RCS file: /master/contrib/bind/src/include/arpa/inet.h,v
retrieving revision 1.4
diff -c -r1.4 inet.h
*** src/include/arpa/inet.h	2001/02/19 18:36:27	1.4
--- src/include/arpa/inet.h	2001/02/19 22:58:39
***************
*** 71,93 ****
  #endif
  #include <sys/cdefs.h>
  
- #define	inet_addr		__inet_addr
- #define	inet_aton		__inet_aton
- #define	inet_lnaof		__inet_lnaof
- #define	inet_makeaddr		__inet_makeaddr
- #define	inet_neta		__inet_neta
- #define	inet_netof		__inet_netof
- #define	inet_network		__inet_network
- #define	inet_net_ntop		__inet_net_ntop
- #define	inet_net_pton		__inet_net_pton
- #define	inet_cidr_ntop		__inet_cidr_ntop
- #define	inet_cidr_pton		__inet_cidr_pton
- #define	inet_ntoa		__inet_ntoa
- #define	inet_pton		__inet_pton
- #define	inet_ntop		__inet_ntop
- #define	inet_nsap_addr		__inet_nsap_addr
- #define	inet_nsap_ntoa		__inet_nsap_ntoa
- 
  __BEGIN_DECLS
  unsigned long	 inet_addr __P((const char *));
  int		 inet_aton __P((const char *, struct in_addr *));
--- 71,76 ----
Index: src/lib/dst/dst_api.c
===================================================================
RCS file: /master/contrib/bind/src/lib/dst/dst_api.c,v
retrieving revision 1.5
diff -c -r1.5 dst_api.c
*** src/lib/dst/dst_api.c	2001/02/19 18:36:32	1.5
--- src/lib/dst/dst_api.c	2001/02/19 22:51:38
***************
*** 1,6 ****
--- 1,7 ----
  #ifndef LINT
  static const char rcsid[] = "$Header: /proj/cvs/isc/bind8/src/lib/dst/dst_api.c,v 1.16 2000/11/13 04:09:23 vixie Exp $";
  #endif
+ static char *bsdi_pad="";	/* XXX BSDI hack to make shlib align */
  
  /*
   * Portions Copyright (c) 1995-1998 by Trusted Information Systems, Inc.
Index: src/lib/irs/getaddrinfo.c
===================================================================
RCS file: /master/contrib/bind/src/lib/irs/getaddrinfo.c,v
retrieving revision 1.6
diff -c -r1.6 getaddrinfo.c
*** src/lib/irs/getaddrinfo.c	2001/02/19 18:36:34	1.6
--- src/lib/irs/getaddrinfo.c	2001/02/19 23:00:07
***************
*** 18,23 ****
--- 18,24 ----
  #include <arpa/nameser.h>
  #include <resolv.h>
  #include <arpa/inet.h>
+ #include <unistd.h>
  #include <port_after.h>
  
  #define SA(addr)	((struct sockaddr *)(addr))
***************
*** 37,42 ****
--- 38,44 ----
      int socktype, int port);
  static int add_ipv6(const char *hostname, int flags, struct addrinfo **aip,
      int socktype, int port);
+ static int skip_ipv6(void);
  static void set_order(int, int (**)());
  
  #define FOUND_IPV4	0x1
***************
*** 174,180 ****
  			ai_list = ai;
  		}
  
! 		if (family == AF_INET6 || family == 0) {
  			ai = ai_alloc(AF_INET6, sizeof(struct sockaddr_in6));
  			if (ai == NULL) {
  				freeaddrinfo(ai_list);
--- 176,182 ----
  			ai_list = ai;
  		}
  
! 		if ((family == AF_INET6 || family == 0) && !skip_ipv6()) {
  			ai = ai_alloc(AF_INET6, sizeof(struct sockaddr_in6));
  			if (ai == NULL) {
  				freeaddrinfo(ai_list);
***************
*** 286,300 ****
  		order = getenv("NET_ORDER");
  		found = 0;
  		while (order != NULL) {
! 			/* We ignore any unknown names.  */
  			tok = strsep(&order, ":");
  			if (strcasecmp(tok, "inet6") == 0) {
! 				if ((found & FOUND_IPV6) == 0)
  					*net_order++ = add_ipv6;
  				found |= FOUND_IPV6;
  			} else if (strcasecmp(tok, "inet") == 0 ||
  			    strcasecmp(tok, "inet4") == 0) {
! 				if ((found & FOUND_IPV4) == 0)
  					*net_order++ = add_ipv4;
  				found |= FOUND_IPV4;
  			}
--- 288,307 ----
  		order = getenv("NET_ORDER");
  		found = 0;
  		while (order != NULL) {
! 			int skip = 0;
  			tok = strsep(&order, ":");
+ 			if (*tok == '-') {
+ 				skip = 1;
+ 				tok++;
+ 			}
+ 			/* We ignore any unknown names.  */
  			if (strcasecmp(tok, "inet6") == 0) {
! 				if (!skip && (found & FOUND_IPV6) == 0)
  					*net_order++ = add_ipv6;
  				found |= FOUND_IPV6;
  			} else if (strcasecmp(tok, "inet") == 0 ||
  			    strcasecmp(tok, "inet4") == 0) {
! 				if (!skip && (found & FOUND_IPV4) == 0)
  					*net_order++ = add_ipv4;
  				found |= FOUND_IPV4;
  			}
***************
*** 303,309 ****
  		/* Add in anything that we didn't find */
  		if ((found & FOUND_IPV4) == 0)
  			*net_order++ = add_ipv4;
! 		if ((found & FOUND_IPV6) == 0)
  			*net_order++ = add_ipv6;
  	}
  	*net_order = NULL;
--- 310,316 ----
  		/* Add in anything that we didn't find */
  		if ((found & FOUND_IPV4) == 0)
  			*net_order++ = add_ipv4;
! 		if ((found & FOUND_IPV6) == 0 && !skip_ipv6())
  			*net_order++ = add_ipv6;
  	}
  	*net_order = NULL;
***************
*** 354,359 ****
--- 361,400 ----
  		}
  	}
  	return(0);
+ }
+ 
+ /*
+  * Determine whether or not it is worth asking for IPv6 addresses,
+  * due to the potential delays in querying for AAAA records.
+  * If the kernel isn't built with IPv6 (socket(AF_INET6, ...)  will
+  * fail), don't bother and remember that fact.  If the kernel is
+  * built with IPv6 but no IPv6 addresses are configured (i.e., the
+  * bind() fails), don't bother, but don't remember that because
+  * interfaces could get configured by the time we're called again.
+  * In all cases, if the user has explicitly asked for IPv6 addresses
+  * by setting NET_ORDER in the enviornment, then return them.
+  */
+ static int
+ skip_ipv6()
+ {
+ 	int s, ret = 0;
+ 	struct sockaddr_in6 sa6;
+ 	static int no6sock = 0;
+ 
+ 	if (getenv("NET_ORDER") != NULL)
+ 		return(0);
+ 
+ 	if (no6sock || (s = socket(AF_INET6, SOCK_STREAM, 0)) < 0) {
+ 		no6sock = 1;
+ 		return(1);
+ 	}
+ 
+ 	memset(&sa6, 0, sizeof(sa6));
+ 	sa6.sin6_family = AF_INET6;
+ 	sa6.sin6_len = sizeof(sa6);
+ 	ret = bind(s, (struct sockaddr *)&sa6, sizeof(sa6));
+ 	(void) close(s);
+ 	return((ret < 0) ? 1 : 0);
  }
  
  static char v6_loop[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
Index: src/lib/irs/gethostent.c
===================================================================
RCS file: /master/contrib/bind/src/lib/irs/gethostent.c,v
retrieving revision 1.4
diff -c -r1.4 gethostent.c
*** src/lib/irs/gethostent.c	2001/02/19 18:36:34	1.4
--- src/lib/irs/gethostent.c	2001/02/19 22:58:36
***************
*** 815,820 ****
--- 815,821 ----
  		return (NULL);
  	}
  	pvt = net_data->ho_data;
+ #ifndef __bsdi__
  	/*
  	 * Unlike its forebear(inet_aton), our friendly inet_pton() is strict
  	 * in its interpretation of its input, and it will only return "1" if
***************
*** 823,829 ****
  	 *
  	 * This means "telnet 0xdeadbeef" and "telnet 127.1" are dead now.
  	 */
! 	if (inet_pton(af, name, pvt->addr) != 1) {
  		RES_SET_H_ERRNO(net_data->res, HOST_NOT_FOUND);
  		return (NULL);
  	}
--- 824,839 ----
  	 *
  	 * This means "telnet 0xdeadbeef" and "telnet 127.1" are dead now.
  	 */
! 	if (inet_pton(af, name, pvt->addr) != 1) { 
! #else
! 	/* BSDI XXX
! 	 * We put this back to inet_aton -- we really want the old behavior
! 	 * Long live 127.1...
! 	 */
! 	if ((af != AF_INET ||
! 	    inet_aton(name, (struct in_addr *)pvt->addr) != 1) &&
! 	    inet_pton(af, name, pvt->addr) != 1) {
! #endif
  		RES_SET_H_ERRNO(net_data->res, HOST_NOT_FOUND);
  		return (NULL);
  	}
Index: src/lib/irs/getnameinfo.c
===================================================================
RCS file: /master/contrib/bind/src/lib/irs/getnameinfo.c,v
retrieving revision 1.9
diff -c -r1.9 getnameinfo.c
*** src/lib/irs/getnameinfo.c	2001/02/19 18:36:34	1.9
--- src/lib/irs/getnameinfo.c	2001/02/19 23:10:04
***************
*** 1,11 ****
  /*
-  * Issues to be discussed:
-  * - Thread safe-ness must be checked
-  * - Return values.  There seems to be no standard for return value (RFC2133)
-  *   but INRIA implementation returns EAI_xxx defined for getaddrinfo().
-  */
- 
- /*
   * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
   * All rights reserved.
   * 
--- 1,4 ----
***************
*** 17,27 ****
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in the
   *    documentation and/or other materials provided with the distribution.
!  * 3. All advertising materials mentioning features or use of this software
!  *    must display the following acknowledgement:
!  *    This product includes software developed by WIDE Project and
!  *    its contributors.
!  * 4. Neither the name of the project nor the names of its contributors
   *    may be used to endorse or promote products derived from this software
   *    without specific prior written permission.
   * 
--- 10,16 ----
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in the
   *    documentation and/or other materials provided with the distribution.
!  * 3. Neither the name of the project nor the names of its contributors
   *    may be used to endorse or promote products derived from this software
   *    without specific prior written permission.
   * 
***************
*** 38,79 ****
   * SUCH DAMAGE.
   */
  
  #include <port_before.h>
  
  #include <sys/types.h>
  #include <sys/socket.h>
! 
  #include <netinet/in.h>
- #include <arpa/nameser.h>
  #include <arpa/inet.h>
! 
  #include <netdb.h>
  #include <resolv.h>
  #include <string.h>
  
  #include <port_after.h>
  
  #define SUCCESS 0
  #define ANY 0
  #define YES 1
  #define NO  0
  
- /*
-  * Note that a_off will be dynamically adjusted so that to be consistent
-  * with the definition of sockaddr_in{,6}.
-  * The value presented below is just a guess.
-  */
  static struct afd {
  	int a_af;
  	int a_addrlen;
  	int a_socklen;
  	int a_off;
  } afdl [] = {
- 	/* first entry is linked last... */
- 	{PF_INET, sizeof(struct in_addr), sizeof(struct sockaddr_in),
- 		4 /*XXX*/},
  	{PF_INET6, sizeof(struct in6_addr), sizeof(struct sockaddr_in6),
! 		8 /*XXX*/},
  	{0, 0, 0},
  };
  
--- 27,81 ----
   * SUCH DAMAGE.
   */
  
+ /*
+  * Issues to be discussed:
+  * - Thread safe-ness must be checked
+  * - Return values.  There seems to be no standard for return value (RFC2553)
+  *   but INRIA implementation returns EAI_xxx defined for getaddrinfo().
+  * - RFC2553 says that we should raise error on short buffer.  X/Open says
+  *   we need to truncate the result.  We obey RFC2553 (and X/Open should be
+  *   modified).
+  * - What is "local" in NI_FQDN?
+  * - NI_NAMEREQD and NI_NUMERICHOST conflict with each other.
+  * - (KAME extension) NI_WITHSCOPEID when called with global address,
+  *   and sin6_scope_id filled
+  */
+ 
  #include <port_before.h>
  
  #include <sys/types.h>
  #include <sys/socket.h>
! #include <net/if.h>
  #include <netinet/in.h>
  #include <arpa/inet.h>
! #include <arpa/nameser.h>
  #include <netdb.h>
  #include <resolv.h>
  #include <string.h>
+ #include <stddef.h>
+ #include <errno.h>
  
  #include <port_after.h>
  
+ #ifdef NEED_ADDRINFO_H
+ #include "addrinfo.h"
+ #endif
+ 
  #define SUCCESS 0
  #define ANY 0
  #define YES 1
  #define NO  0
  
  static struct afd {
  	int a_af;
  	int a_addrlen;
  	int a_socklen;
  	int a_off;
  } afdl [] = {
  	{PF_INET6, sizeof(struct in6_addr), sizeof(struct sockaddr_in6),
! 		offsetof(struct sockaddr_in6, sin6_addr)},
! 	{PF_INET, sizeof(struct in_addr), sizeof(struct sockaddr_in),
! 		offsetof(struct sockaddr_in, sin_addr)},
  	{0, 0, 0},
  };
  
***************
*** 83,88 ****
--- 85,94 ----
  	u_short	si_port;
  };
  
+ static int ip6_parsenumeric __P((const struct sockaddr *, char *, char *,
+ 				 int, int));
+ static int ip6_sa2str __P((struct sockaddr_in6 *, char *, size_t, int));
+ 
  #define ENI_NOSOCKET 	0
  #define ENI_NOSERVNAME	1
  #define ENI_NOHOSTNAME	2
***************
*** 105,151 ****
  	struct servent *sp;
  	struct hostent *hp;
  	u_short port;
- #ifdef HAVE_SA_LEN
- 	int len;
- #endif
  	int family, i;
! 	char *addr, *p;
! 	u_char pfx;
! 	static int firsttime = 1;
! 	static char numserv[512];
! 	static char numaddr[512];
! 
! 
! 	/* dynamically adjust a_off */
! 	if (firsttime) {
! 		struct afd *p;
! 		u_char *q;
! 		struct sockaddr_in sin;
! 		struct sockaddr_in6 sin6;
! 
! 		for (p = &afdl[0]; p->a_af; p++) {
! 			switch (p->a_af) {
! 			case PF_INET:
! 				q = (u_char *)&sin.sin_addr.s_addr;
! 				p->a_off = q - (u_char *)&sin;
! 				break;
! 			case PF_INET6:
! 				q = (u_char *)&sin6.sin6_addr.s6_addr;
! 				p->a_off = q - (u_char *)&sin6;
! 				break;
! 			default:
! 				break;
! 			}
! 		}
! 		firsttime = 0;
! 	}
  
  	if (sa == NULL)
  		return ENI_NOSOCKET;
  
! #ifdef HAVE_SA_LEN
! 	len = sa->sa_len;
! 	if (len != salen) return ENI_SALEN;
  #endif
  	
  	family = sa->sa_family;
--- 111,129 ----
  	struct servent *sp;
  	struct hostent *hp;
  	u_short port;
  	int family, i;
! 	char *addr;
! 	u_int32_t v4a;
! 	int h_error;
! 	char numserv[512];
! 	char numaddr[512];
  
  	if (sa == NULL)
  		return ENI_NOSOCKET;
  
! #ifdef HAVE_SA_LEN	/*XXX*/
! 	if (sa->sa_len != salen)
! 		return ENI_SALEN;
  #endif
  	
  	family = sa->sa_family;
***************
*** 157,225 ****
  	return ENI_FAMILY;
  	
   found:
! 	if (salen != afd->a_socklen) return ENI_SALEN;
  	
  	port = ((struct sockinet *)sa)->si_port; /* network byte order */
  	addr = (char *)sa + afd->a_off;
  
  	if (serv == NULL || servlen == 0) {
! 		/* what we should do? */
! 	} else if (flags & NI_NUMERICSERV) {
! 		snprintf(numserv, sizeof(numserv), "%d", ntohs(port));
! 		if (strlen(numserv) > servlen)
! 			return ENI_MEMORY;
! 		strcpy(serv, numserv);
  	} else {
! 		sp = getservbyport(port, (flags & NI_DGRAM) ? "udp" : "tcp");
  		if (sp) {
  			if (strlen(sp->s_name) + 1 > servlen)
  				return ENI_MEMORY;
  			strcpy(serv, sp->s_name);
! 		} else
! 			return ENI_NOSERVNAME;
  	}
  
  	switch (sa->sa_family) {
  	case AF_INET:
! 		if (ntohl(*(u_long *)addr) >> IN_CLASSA_NSHIFT == 0)
  			flags |= NI_NUMERICHOST;			
  		break;
  	case AF_INET6:
! 		pfx = *addr;
! 		if (pfx == 0 || pfx == 0xfe || pfx == 0xff)
! 			flags |= NI_NUMERICHOST;
  		break;
  	}
  	if (host == NULL || hostlen == 0) {
! 		/* what should we do? */
  	} else if (flags & NI_NUMERICHOST) {
! 		if (inet_ntop(afd->a_af, addr, numaddr, sizeof(numaddr))
! 		    == NULL)
! 			return ENI_SYSTEM;
! 		if (strlen(numaddr) + 1 > hostlen)
! 			return ENI_MEMORY;
! 		strcpy(host, numaddr);
  	} else {
  		hp = gethostbyaddr(addr, afd->a_addrlen, afd->a_af);
  
  		if (hp) {
  			if (flags & NI_NOFQDN) {
  				p = strchr(hp->h_name, '.');
! 				if (p) *p = '\0';
  			}
! 			if (strlen(hp->h_name) + 1 > hostlen)
  				return ENI_MEMORY;
  			strcpy(host, hp->h_name);
  		} else {
  			if (flags & NI_NAMEREQD)
  				return ENI_NOHOSTNAME;
! 			if (inet_ntop(afd->a_af, addr, numaddr, sizeof(numaddr))
! 			    == NULL)
! 				return ENI_NOHOSTNAME;
! 			if (strlen(numaddr) + 1 > hostlen)
! 				return ENI_MEMORY;
! 			strcpy(host, numaddr);
  		}
  	}
  	return SUCCESS;
  }
--- 135,387 ----
  	return ENI_FAMILY;
  	
   found:
! 	if (salen != afd->a_socklen)
! 		return ENI_SALEN;
  	
  	port = ((struct sockinet *)sa)->si_port; /* network byte order */
  	addr = (char *)sa + afd->a_off;
  
  	if (serv == NULL || servlen == 0) {
! 		/*
! 		 * do nothing in this case.
! 		 * in case you are wondering if "&&" is more correct than
! 		 * "||" here: RFC2553 says that serv == NULL OR servlen == 0
! 		 * means that the caller does not want the result.
! 		 */
  	} else {
! 		if (flags & NI_NUMERICSERV)
! 			sp = NULL;
! 		else {
! 			sp = getservbyport(port,
! 				(flags & NI_DGRAM) ? "udp" : "tcp");
! 		}
  		if (sp) {
  			if (strlen(sp->s_name) + 1 > servlen)
  				return ENI_MEMORY;
  			strcpy(serv, sp->s_name);
! 		} else {
! 			snprintf(numserv, sizeof(numserv), "%d", ntohs(port));
! 			if (strlen(numserv) + 1> servlen)
! 				return ENI_MEMORY;
! 			strcpy(serv, numserv);
! 		}
  	}
  
  	switch (sa->sa_family) {
  	case AF_INET:
! 		v4a = (u_int32_t)
! 			ntohl(((struct sockaddr_in *)sa)->sin_addr.s_addr);
! 		v4a >>= IN_CLASSA_NSHIFT;
! 		if (v4a == 0)
  			flags |= NI_NUMERICHOST;			
  		break;
  	case AF_INET6:
! 	    {
! 		struct sockaddr_in6 *sin6;
! 		sin6 = (struct sockaddr_in6 *)sa;
! 		switch (sin6->sin6_addr.s6_addr[0]) {
! 		case 0x00:
! 			if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr))
! 				;
! 			else if (IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr))
! 				;
! 			else
! 				flags |= NI_NUMERICHOST;
! 			break;
! 		default:
! 			if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
! 				flags |= NI_NUMERICHOST;
! 			}
! 			else if (IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr))
! 				flags |= NI_NUMERICHOST;
! 			break;
! 		}
! 	    }
  		break;
  	}
  	if (host == NULL || hostlen == 0) {
! 		/*
! 		 * do nothing in this case.
! 		 * in case you are wondering if "&&" is more correct than
! 		 * "||" here: RFC2553 says that host == NULL OR hostlen == 0
! 		 * means that the caller does not want the result.
! 		 */
  	} else if (flags & NI_NUMERICHOST) {
! 		int numaddrlen;
! 
! 		/* NUMERICHOST and NAMEREQD conflicts with each other */
! 		if (flags & NI_NAMEREQD)
! 			return ENI_NOHOSTNAME;
! 
! 		switch(afd->a_af) {
! 		case AF_INET6:
! 		{
! 			int error;
! 
! 			if ((error = ip6_parsenumeric(sa, addr, host,
! 						      hostlen, flags)) != 0)
! 				return(error);
! 			break;
! 		}
! 		default:
! 			if (inet_ntop(afd->a_af, addr, numaddr, sizeof(numaddr))
! 			    == NULL)
! 				return ENI_SYSTEM;
! 			numaddrlen = strlen(numaddr);
! 			if (numaddrlen + 1 > hostlen) /* don't forget terminator */
! 				return ENI_MEMORY;
! 			strcpy(host, numaddr);
! 			break;
! 		}
  	} else {
+ #ifdef USE_GETIPNODEBY
+ 		hp = getipnodebyaddr(addr, afd->a_addrlen, afd->a_af, &h_error);
+ #else
  		hp = gethostbyaddr(addr, afd->a_addrlen, afd->a_af);
+ 		h_error = h_errno;
+ #endif
  
  		if (hp) {
+ #if 0
+ 			/*
+ 			 * commented out, since "for local host" is not
+ 			 * implemented here - see RFC2553 p30
+ 			 */
  			if (flags & NI_NOFQDN) {
  				p = strchr(hp->h_name, '.');
! 				if (p)
! 					*p = '\0';
  			}
! #endif
! 			if (strlen(hp->h_name) + 1 > hostlen) {
! #ifdef USE_GETIPNODEBY
! 				freehostent(hp);
! #endif
  				return ENI_MEMORY;
+ 			}
  			strcpy(host, hp->h_name);
+ #ifdef USE_GETIPNODEBY
+ 			freehostent(hp);
+ #endif
  		} else {
  			if (flags & NI_NAMEREQD)
  				return ENI_NOHOSTNAME;
! 			switch(afd->a_af) {
! 			case AF_INET6:
! 			{
! 				int error;
! 
! 				if ((error = ip6_parsenumeric(sa, addr, host,
! 							      hostlen,
! 							      flags)) != 0)
! 					return(error);
! 				break;
! 			}
! 			default:
! 				if (inet_ntop(afd->a_af, addr, host,
! 				    hostlen) == NULL)
! 					return ENI_SYSTEM;
! 				break;
! 			}
  		}
  	}
  	return SUCCESS;
+ }
+ 
+ static int
+ ip6_parsenumeric(sa, addr, host, hostlen, flags)
+ 	const struct sockaddr *sa;
+ 	char *addr, *host;
+ 	int flags, hostlen;
+ {
+ 	int numaddrlen;
+ 	char numaddr[512];
+ 
+ 	if (inet_ntop(AF_INET6, addr, numaddr, sizeof(numaddr))
+ 	    == NULL)
+ 		return ENI_SYSTEM;
+ 
+ 	numaddrlen = strlen(numaddr);
+ 	if (numaddrlen + 1 > hostlen) /* don't forget terminator */
+ 		return ENI_MEMORY;
+ 	strcpy(host, numaddr);
+ 
+ #ifdef NI_WITHSCOPEID
+ 	if (
+ #ifdef DONT_OPAQUE_SCOPEID
+ 	    (IN6_IS_ADDR_LINKLOCAL((struct in6_addr *)addr) ||
+ 	     IN6_IS_ADDR_MULTICAST((struct in6_addr *)addr)) &&
+ #endif
+ 	    ((struct sockaddr_in6 *)sa)->sin6_scope_id) {
+ #ifndef ALWAYS_WITHSCOPE
+ 		if (flags & NI_WITHSCOPEID)
+ #endif /* !ALWAYS_WITHSCOPE */
+ 		{
+ 			char scopebuf[MAXHOSTNAMELEN];
+ 			int scopelen;
+ 
+ 			/* ip6_sa2str never fails */
+ 			scopelen = ip6_sa2str((struct sockaddr_in6 *)sa,
+ 					      scopebuf, sizeof(scopebuf),
+ 					      0);
+ 			if (scopelen + 1 + numaddrlen + 1 > hostlen)
+ 				return ENI_MEMORY;
+ #if 0
+ 			/*
+ 			 * construct <scopeid><delim><numeric-addr>
+ 			 */
+ 			/*
+ 			 * Shift the host string to allocate
+ 			 * space for the scope ID part.
+ 			 */
+ 			memmove(host + scopelen + 1, host,
+ 				numaddrlen);
+ 			/* copy the scope ID and the delimiter */
+ 			memcpy(host, scopebuf, scopelen);
+ 			host[scopelen] = SCOPE_DELIMITER;
+ 			host[scopelen + 1 + numaddrlen] = '\0';
+ #else
+ 			/*
+ 			 * construct <numeric-addr><delim><scopeid>
+ 			 */
+ 			memcpy(host + numaddrlen + 1, scopebuf,
+ 			       scopelen);
+ 			host[numaddrlen] = SCOPE_DELIMITER;
+ 			host[numaddrlen + 1 + scopelen] = '\0';
+ #endif
+ 		}
+ 	}
+ #endif /* NI_WITHSCOPEID */
+ 
+ 	return 0;
+ }
+ 
+ /* ARGSUSED */
+ static int
+ ip6_sa2str(sa6, buf, bufsiz, flags)
+ 	struct sockaddr_in6 *sa6;
+ 	char *buf;
+ 	size_t bufsiz;
+ 	int flags;
+ {
+ 	unsigned int ifindex = (unsigned int)sa6->sin6_scope_id;
+ 	struct in6_addr *a6 = &sa6->sin6_addr;
+ 
+ #ifdef notyet
+ 	if (flags & NI_NUMERICSCOPE) {
+ 		return(snprintf(buf, bufsiz, "%d", sa6->sin6_scope_id));
+ 	}
+ #endif
+  
+ 	/* if_indextoname() does not take buffer size.  not a good api... */
+ 	if ((IN6_IS_ADDR_LINKLOCAL(a6) || IN6_IS_ADDR_MC_LINKLOCAL(a6)) &&
+ 	    bufsiz >= IF_NAMESIZE) {
+ 		char *p = if_indextoname(ifindex, buf);
+ 		if (p) {
+ 			return(strlen(p));
+ 		}
+ 	}
+ 
+ 	/* last resort */
+ 	return(snprintf(buf, bufsiz, "%u", sa6->sin6_scope_id));
  }
Index: src/lib/irs/hesiod.c
===================================================================
RCS file: /master/contrib/bind/src/lib/irs/hesiod.c,v
retrieving revision 1.3
diff -c -r1.3 hesiod.c
*** src/lib/irs/hesiod.c	2001/02/19 18:36:34	1.3
--- src/lib/irs/hesiod.c	2001/02/19 22:58:39
***************
*** 83,88 ****
--- 83,89 ----
  		return (-1);
  	}
  
+ 	ctx->res = NULL;
  	ctx->LHS = NULL;
  	ctx->RHS = NULL;
  	ctx->res = NULL;
Index: src/lib/irs/irs_data.c
===================================================================
RCS file: /master/contrib/bind/src/lib/irs/irs_data.c,v
retrieving revision 1.8
diff -c -r1.8 irs_data.c
*** src/lib/irs/irs_data.c	2001/02/19 18:36:35	1.8
--- src/lib/irs/irs_data.c	2001/02/19 23:07:59
***************
*** 65,106 ****
  
  void
  net_data_destroy(void *p) {
! 	struct net_data *net_data = p;
  
! 	res_nclose(net_data->res);
! 	if (net_data->gr != NULL) {
! 		(*net_data->gr->close)(net_data->gr);
! 		net_data->gr = NULL;
  	}
! 	if (net_data->pw != NULL) {
! 		(*net_data->pw->close)(net_data->pw);
! 		net_data->pw = NULL;
  	}
! 	if (net_data->sv != NULL) {
! 		(*net_data->sv->close)(net_data->sv);
! 		net_data->sv = NULL;
  	}
! 	if (net_data->pr != NULL) {
! 		(*net_data->pr->close)(net_data->pr);
! 		net_data->pr = NULL;
  	}
! 	if (net_data->ho != NULL) {
! 		(*net_data->ho->close)(net_data->ho);
! 		net_data->ho = NULL;
  	}
! 	if (net_data->nw != NULL) {
! 		(*net_data->nw->close)(net_data->nw);
! 		net_data->nw = NULL;
  	}
! 	if (net_data->ng != NULL) {
! 		(*net_data->ng->close)(net_data->ng);
! 		net_data->ng = NULL;
  	}
  
! 	(*net_data->irs->close)(net_data->irs);
! 	memput(net_data, sizeof *net_data);
  }
  
  /* applications that need a specific config file other than
   * _PATH_IRS_CONF should call net_data_init directly rather than letting
   *   the various wrapper functions make the first call. - brister
--- 65,114 ----
  
  void
  net_data_destroy(void *p) {
! 	struct net_data *ndp = p;
  
! 	res_nclose(ndp->res);
! 	if (ndp->gr != NULL) {
! 		(*ndp->gr->close)(ndp->gr);
! 		ndp->gr = NULL;
  	}
! 	if (ndp->pw != NULL) {
! 		(*ndp->pw->close)(ndp->pw);
! 		ndp->pw = NULL;
  	}
! 	if (ndp->sv != NULL) {
! 		(*ndp->sv->close)(ndp->sv);
! 		ndp->sv = NULL;
  	}
! 	if (ndp->pr != NULL) {
! 		(*ndp->pr->close)(ndp->pr);
! 		ndp->pr = NULL;
  	}
! 	if (ndp->ho != NULL) {
! 		(*ndp->ho->close)(ndp->ho);
! 		ndp->ho = NULL;
  	}
! 	if (ndp->nw != NULL) {
! 		(*ndp->nw->close)(ndp->nw);
! 		ndp->nw = NULL;
  	}
! 	if (ndp->ng != NULL) {
! 		(*ndp->ng->close)(ndp->ng);
! 		ndp->ng = NULL;
  	}
  
! 	(*ndp->irs->close)(ndp->irs);
! 	memput(ndp, sizeof *ndp);
  }
  
+ #ifdef DO_PTHREADS
+ static pthread_once_t net_data_init_once_control = PTHREAD_ONCE_INIT;
+ static void
+ net_data_init_once(void) {
+ 	pthread_key_create(&key, net_data_destroy);
+ }
+ #endif
+ 
  /* applications that need a specific config file other than
   * _PATH_IRS_CONF should call net_data_init directly rather than letting
   *   the various wrapper functions make the first call. - brister
***************
*** 108,176 ****
  
  struct net_data *
  net_data_init(const char *conf_file) {
! #ifdef	DO_PTHREADS
! 	static pthread_mutex_t keylock = PTHREAD_MUTEX_INITIALIZER;
! 	struct net_data *net_data;
  
! 	if (!once) {
! 		pthread_mutex_lock(&keylock);
! 		if (!once++)
! 			pthread_key_create(&key, net_data_destroy);
! 		pthread_mutex_unlock(&keylock);
! 	}
! 	net_data = pthread_getspecific(key);
  #endif
  
! 	if (net_data == NULL) {
! 		net_data = net_data_create(conf_file);
! 		if (net_data == NULL)
  			return (NULL);
  #ifdef	DO_PTHREADS
! 		pthread_setspecific(key, net_data);
  #endif
  	}
  
! 	return (net_data);
  }
  
  struct net_data *
  net_data_create(const char *conf_file) {
! 	struct net_data *net_data;
  
! 	net_data = memget(sizeof (struct net_data));
! 	if (net_data == NULL)
  		return (NULL);
! 	memset(net_data, 0, sizeof (struct net_data));
  
! 	if ((net_data->irs = irs_gen_acc("", conf_file)) == NULL)
  		return (NULL);
  #ifndef DO_PTHREADS
! 	(*net_data->irs->res_set)(net_data->irs, &_res, NULL);
  #endif
  
! 	net_data->res = (*net_data->irs->res_get)(net_data->irs);
! 	if (net_data->res == NULL)
  		return (NULL);
  
! 	if (res_ninit(net_data->res) == -1)
  		return (NULL);
  
! 	return (net_data);
  }
  
  
  
  void
! net_data_minimize(struct net_data *net_data) {
! 	res_nclose(net_data->res);
  }
  
  struct __res_state *
  __res_state(void) {
  	/* NULL param here means use the default config file. */
! 	struct net_data *net_data = net_data_init(NULL);
! 	if (net_data && net_data->res)
! 		return (net_data->res);
  
  	return (&_res);
  }
--- 116,182 ----
  
  struct net_data *
  net_data_init(const char *conf_file) {
! 	struct net_data *ndp;
  
! #ifdef	DO_PTHREADS
! 	pthread_once(&net_data_init_once_control, net_data_init_once);
! 	ndp = pthread_getspecific(key);
! #else
! 	ndp = net_data;
  #endif
  
! 	if (ndp == NULL) {
! 		ndp = net_data_create(conf_file);
! 		if (ndp == NULL)
  			return (NULL);
  #ifdef	DO_PTHREADS
! 		pthread_setspecific(key, ndp);
! #else
! 		net_data = ndp;
  #endif
  	}
  
! 	return (ndp);
  }
  
  struct net_data *
  net_data_create(const char *conf_file) {
! 	struct net_data *ndp;
  
! 	ndp = memget(sizeof (struct net_data));
! 	if (ndp == NULL)
  		return (NULL);
! 	memset(ndp, 0, sizeof (struct net_data));
  
! 	if ((ndp->irs = irs_gen_acc("", conf_file)) == NULL)
  		return (NULL);
  #ifndef DO_PTHREADS
! 	(*ndp->irs->res_set)(ndp->irs, &_res, NULL);
  #endif
  
! 	ndp->res = (*ndp->irs->res_get)(ndp->irs);
! 	if (ndp->res == NULL)
  		return (NULL);
  
! 	if (res_ninit(ndp->res) == -1)
  		return (NULL);
  
! 	return (ndp);
  }
  
  
  
  void
! net_data_minimize(struct net_data *ndp) {
! 	res_nclose(ndp->res);
  }
  
  struct __res_state *
  __res_state(void) {
  	/* NULL param here means use the default config file. */
! 	struct net_data *ndp = net_data_init(NULL);
! 	if (ndp && ndp->res)
! 		return (ndp->res);
  
  	return (&_res);
  }
***************
*** 178,186 ****
  int *
  __h_errno(void) {
  	/* NULL param here means use the default config file. */
! 	struct net_data *net_data = net_data_init(NULL);
! 	if (net_data && net_data->res)
! 		return (&net_data->res->res_h_errno);
  	return (&h_errno);
  }
  
--- 184,192 ----
  int *
  __h_errno(void) {
  	/* NULL param here means use the default config file. */
! 	struct net_data *ndp = net_data_init(NULL);
! 	if (ndp && ndp->res)
! 		return (&ndp->res->res_h_errno);
  	return (&h_errno);
  }
  
Index: src/lib/resolv/herror.c
===================================================================
RCS file: /master/contrib/bind/src/lib/resolv/herror.c,v
retrieving revision 1.4
diff -c -r1.4 herror.c
*** src/lib/resolv/herror.c	2001/02/19 18:36:38	1.4
--- src/lib/resolv/herror.c	2001/02/19 22:58:39
***************
*** 71,76 ****
--- 71,77 ----
  #include "port_after.h"
  #undef	h_errno
  
+ #ifndef BSDI_LIBC
  const char *h_errlist[] = {
  	"Resolver Error 0 (no error)",
  	"Unknown host",				/* 1 HOST_NOT_FOUND */
***************
*** 79,84 ****
--- 80,89 ----
  	"No address associated with name",	/* 4 NO_ADDRESS */
  };
  int	h_nerr = { sizeof h_errlist / sizeof h_errlist[0] };
+ #else
+ extern char *h_errlist[];
+ extern int  h_nerr;
+ #endif
  
  int	h_errno;
  
Index: src/port/bsdos/Makefile.set
===================================================================
RCS file: /master/contrib/bind/src/port/bsdos/Makefile.set,v
retrieving revision 1.3
diff -c -r1.3 Makefile.set
*** src/port/bsdos/Makefile.set	2001/02/19 18:36:43	1.3
--- src/port/bsdos/Makefile.set	2001/02/19 22:58:39
***************
*** 1,4 ****
! 'CC=shlicc'
  'CDEBUG=-O -g'
  'DESTBIN=/usr/bin'
  'DESTSBIN=/usr/sbin'
--- 1,4 ----
! 'CC=cc'
  'CDEBUG=-O -g'
  'DESTBIN=/usr/bin'
  'DESTSBIN=/usr/sbin'
Index: src/port/bsdos/include/port_before.h
===================================================================
RCS file: /master/contrib/bind/src/port/bsdos/include/port_before.h,v
retrieving revision 1.2
diff -c -r1.2 port_before.h
*** src/port/bsdos/include/port_before.h	2001/02/19 18:36:43	1.2
--- src/port/bsdos/include/port_before.h	2001/02/19 22:58:39
***************
*** 1,4 ****
! #undef WANT_IRS_NIS
  #define WANT_IRS_PW
  #define WANT_IRS_GR
  #define SIG_FN void
--- 1,4 ----
! #define WANT_IRS_NIS
  #define WANT_IRS_PW
  #define WANT_IRS_GR
  #define SIG_FN void
***************
*** 47,53 ****
  #define NGR_R_SET_RETURN void
  #undef NGR_R_SET_RESULT /*empty*/
  #define NGR_R_END_RETURN void
! #undef NGR_R_END_RESULT  /*empty*/
  #define NGR_R_ARGS char *buf, int buflen
  #undef NGR_R_ENT_ARGS /*empty*/
  #define NGR_R_COPY buf, buflen
--- 47,53 ----
  #define NGR_R_SET_RETURN void
  #undef NGR_R_SET_RESULT /*empty*/
  #define NGR_R_END_RETURN void
! #define NGR_R_END_RESULT(x) /*empty*/
  #define NGR_R_ARGS char *buf, int buflen
  #undef NGR_R_ENT_ARGS /*empty*/
  #define NGR_R_COPY buf, buflen
Index: src/port/bsdos/include/sys/bitypes.h
===================================================================
RCS file: /master/contrib/bind/src/port/bsdos/include/sys/bitypes.h,v
retrieving revision 1.5
diff -c -r1.5 bitypes.h
*** src/port/bsdos/include/sys/bitypes.h	2001/02/19 18:36:44	1.5
--- src/port/bsdos/include/sys/bitypes.h	2001/02/19 22:56:19
***************
*** 15,38 ****
   * SOFTWARE.
   */
  
! #ifndef __BIT_TYPES_DEFINED__
! #define __BIT_TYPES_DEFINED__
! 
! #ifndef _TYPES_STD32_H_
! 	/*
! 	 * Basic integral types.  Omit the typedef if
! 	 * not possible for a machine/compiler combination.
! 	 */
! 	typedef /*signed*/ char            int8_t;
! 	typedef unsigned char            u_int8_t;
! 	typedef short                     int16_t;
! 	typedef unsigned short          u_int16_t;
! 	typedef int                       int32_t;
! 	typedef unsigned int            u_int32_t;
! 
! # if 0	/* don't fight with these unless you need them */
! 	typedef long long                 int64_t;
! 	typedef unsigned long long      u_int64_t;
! # endif
! #endif
! #endif	/* __BIT_TYPES_DEFINED__ */
--- 15,18 ----
   * SOFTWARE.
   */
  
! #include <machine/types.h>

Index: src/lib/irs/getgrent_r.c
===================================================================
RCS file: /master/contrib/bind/src/lib/irs/getgrent_r.c,v
retrieving revision 1.1.1.1
diff -c -2 -r1.1.1.1 getgrent_r.c
*** getgrent_r.c	1999/04/20 21:33:11	1.1.1.1
--- getgrent_r.c	2001/05/07 21:22:05
***************
*** 51,55 ****
  	if (ge == NULL) {
  		*result = NULL;
! 		return (-1);
  	}
  
--- 51,55 ----
  	if (ge == NULL) {
  		*result = NULL;
! 		return (0);	/* ??? */
  	}
  
***************
*** 88,92 ****
  	if (ge == NULL) {
  		*result = NULL;
! 		return (-1);
  	}
  
--- 88,92 ----
  	if (ge == NULL) {
  		*result = NULL;
! 		return (0);	/* ??? */
  	}
  
***************
*** 131,135 ****
  
  GROUP_R_SET_RETURN
! setgrent_r(GROUP_R_ENT_ARGS) {
  
  	setgrent();
--- 131,140 ----
  
  GROUP_R_SET_RETURN
! #ifdef GROUP_R_ENT_ARGS
! setgrent_r(GROUP_R_ENT_ARGS)
! #else
! setgrent_r(void)
! #endif
! {
  
  	setgrent();
***************
*** 140,144 ****
  
  GROUP_R_END_RETURN
! endgrent_r(GROUP_R_ENT_ARGS) {
  
  	endgrent();
--- 145,154 ----
  
  GROUP_R_END_RETURN
! #ifdef GROUP_R_ENT_ARGS
! endgrent_r(GROUP_R_ENT_ARGS)
! #else
! endgrent_r(void)
! #endif
! {
  
  	endgrent();
***************
*** 181,186 ****
  	
  	if (len > buflen) {
! 		errno = ERANGE;
! 		return (-1);
  	}
  
--- 191,195 ----
  	
  	if (len > buflen) {
! 		return (ERANGE);
  	}
  
Index: src/lib/irs/getpwent_r.c
===================================================================
RCS file: /master/contrib/bind/src/lib/irs/getpwent_r.c,v
retrieving revision 1.1.1.1
diff -c -2 -r1.1.1.1 getpwent_r.c
*** getpwent_r.c	1999/04/20 21:33:12	1.1.1.1
--- getpwent_r.c	2001/05/07 21:18:10
***************
*** 51,55 ****
  	if (pw == NULL) {
  		*result = NULL;
! 		return (-1);
  	}
  
--- 51,55 ----
  	if (pw == NULL) {
  		*result = NULL;
! 		return (0);	/* ??? */
  	}
  
***************
*** 88,92 ****
  	if (pw == NULL) {
  		*result = NULL;
! 		return (-1);
  	}
  
--- 88,92 ----
  	if (pw == NULL) {
  		*result = NULL;
! 		return (0);	/* ??? */
  	}
  
***************
*** 143,147 ****
  
  PASS_R_SET_RETURN
! setpwent_r(PASS_R_ENT_ARGS) {
  
  	setpwent();
--- 143,152 ----
  
  PASS_R_SET_RETURN
! #ifdef PASS_R_ENT_ARGS
! setpwent_r(PASS_R_ENT_ARGS)
! #else
! setpwent_r(void)
! #endif
! {
  
  	setpwent();
***************
*** 152,156 ****
  
  PASS_R_END_RETURN
! endpwent_r(PASS_R_ENT_ARGS) {
  
  	endpwent();
--- 157,166 ----
  
  PASS_R_END_RETURN
! #ifdef PASS_R_ENT_ARGS
! endpwent_r(PASS_R_ENT_ARGS)
! #else
! endpwent_r(void)
! #endif
! {
  
  	endpwent();
***************
*** 192,197 ****
  	
  	if (len > buflen) {
! 		errno = ERANGE;
! 		return (-1);
  	}
  
--- 202,206 ----
  	
  	if (len > buflen) {
! 		return (ERANGE);
  	}
  

# NOTE: The following diffs are all from KAME
Index: src/include/resolv.h
===================================================================
RCS file: /master/contrib/bind/src/include/resolv.h,v
retrieving revision 1.6
diff -c -r1.6 resolv.h
*** src/include/resolv.h	2001/05/16 19:50:19	1.6
--- src/include/resolv.h	2001/07/11 14:53:35
***************
*** 156,162 ****
  };
  
  struct __res_state_ext {
! 	union __res_sockaddr_union nsaddr_list[MAXNS];
  	struct sort_list {
  		int	af;
  		union {
--- 156,162 ----
  };
  
  struct __res_state_ext {
! 	union __res_sockaddr_union nsaddrs[MAXNS];
  	struct sort_list {
  		int	af;
  		union {
***************
*** 190,203 ****
  	int	res_h_errno;		/* last one set for this context */
  	int	_vcsock;		/* PRIVATE: for res_send VC i/o */
  	u_int	_flags;			/* PRIVATE: see below */
- 	struct __res_state_ext *ext;	/* extension for IPv6 */
  	union {
! 		char	pad[48];	/* On an i386 this means 512b total. */
  		struct {
  			u_int16_t		nscount;
  			u_int16_t		nstimes[MAXNS];	/* ms. */
  			int			nssocks[MAXNS];
  			struct sockaddr_in	nsaddrs[MAXNS];
  		} _ext;
  	} _u;
  };
--- 190,203 ----
  	int	res_h_errno;		/* last one set for this context */
  	int	_vcsock;		/* PRIVATE: for res_send VC i/o */
  	u_int	_flags;			/* PRIVATE: see below */
  	union {
! 		char	pad[52];	/* On an i386 this means 512b total. */
  		struct {
  			u_int16_t		nscount;
  			u_int16_t		nstimes[MAXNS];	/* ms. */
  			int			nssocks[MAXNS];
  			struct sockaddr_in	nsaddrs[MAXNS];
+ 			struct __res_state_ext *ext; /* extension for IPv6 */
  		} _ext;
  	} _u;
  };
***************
*** 209,215 ****
   */
  #define	RES_F_VC	0x00000001	/* socket is TCP */
  #define	RES_F_CONN	0x00000002	/* socket is connected */
! #define	RES_F_V6	0x00010000	/* socket is IPv6 */
  
  /* res_findzonecut() options */
  #define	RES_EXHAUSTIVE	0x00000001	/* always do all queries */
--- 209,215 ----
   */
  #define	RES_F_VC	0x00000001	/* socket is TCP */
  #define	RES_F_CONN	0x00000002	/* socket is connected */
! #define RES_F_EDNS0ERR	0x00000004	/* EDNS0 caused errors */	
  
  /* res_findzonecut() options */
  #define	RES_EXHAUSTIVE	0x00000001	/* always do all queries */
***************
*** 368,373 ****
--- 368,374 ----
  #define sym_ntop		__sym_ntop
  #define sym_ntos		__sym_ntos
  #define sym_ston		__sym_ston
+ #define res_ndestroy		__res_ndestroy
  __BEGIN_DECLS
  int		res_hnok __P((const char *));
  int		res_ownok __P((const char *));
***************
*** 429,434 ****
--- 430,436 ----
  int		res_findzonecut __P((res_state, const char *, ns_class, int,
  				     char *, size_t, struct in_addr *, int));
  void		res_nclose __P((res_state));
+ void		res_ndestroy __P((res_state));
  __END_DECLS
  
  #endif /* !_RESOLV_H_ */
Index: src/lib/irs/dns_ho.c
===================================================================
RCS file: /master/contrib/bind/src/lib/irs/dns_ho.c,v
retrieving revision 1.4
diff -c -r1.4 dns_ho.c
*** src/lib/irs/dns_ho.c	2001/04/10 20:36:10	1.4
--- src/lib/irs/dns_ho.c	2001/07/11 14:53:31
***************
*** 1023,1029 ****
  	struct pvt *pvt = (struct pvt *)this->private;
  
  	if (pvt->res && pvt->free_res) {
! 		res_nclose(pvt->res);
  		(*pvt->free_res)(pvt->res);
  	}
  
--- 1023,1029 ----
  	struct pvt *pvt = (struct pvt *)this->private;
  
  	if (pvt->res && pvt->free_res) {
! 		res_ndestroy(pvt->res);
  		(*pvt->free_res)(pvt->res);
  	}
  
Index: src/lib/resolv/res_init.c
===================================================================
RCS file: /master/contrib/bind/src/lib/resolv/res_init.c,v
retrieving revision 1.5
diff -c -r1.5 res_init.c
*** src/lib/resolv/res_init.c	2001/04/10 20:36:15	1.5
--- src/lib/resolv/res_init.c	2001/07/11 14:53:35
***************
*** 90,95 ****
--- 90,96 ----
  #include <stdlib.h>
  #include <string.h>
  #include <unistd.h>
+ #include <netdb.h>
  
  #include "port_after.h"
  
***************
*** 182,192 ****
  	statp->qhook = NULL;
  	statp->rhook = NULL;
  	statp->_u._ext.nscount = 0;
! 	if (statp->ext == NULL) {
! 		statp->ext = malloc(sizeof(*statp->ext));  
! 		memset(statp->ext, 0, sizeof(*statp->ext));
! 		if (statp->ext != NULL)
! 			statp->ext->nsaddr.sin = statp->nsaddr;
  	}
  
  	/* Allow user to override the local domain definition */
--- 183,194 ----
  	statp->qhook = NULL;
  	statp->rhook = NULL;
  	statp->_u._ext.nscount = 0;
! 	if (statp->_u._ext.ext == NULL) {
! 	    statp->_u._ext.ext = malloc(sizeof(*statp->_u._ext.ext));
! 	    if (statp->_u._ext.ext != NULL) {
! 	        memset(statp->_u._ext.ext, 0, sizeof(*statp->_u._ext.ext));
! 		statp->_u._ext.ext->nsaddrs[0].sin = statp->nsaddr;
! 	    }
  	}
  
  	/* Allow user to override the local domain definition */
***************
*** 290,298 ****
  		}
  		/* read nameservers to query */
  		if (MATCH(buf, "nameserver") && nserv < MAXNS) {
! 		    struct in_addr a;
! 		    struct in6_addr a6;
! 		    struct sockaddr_in6 *sin6;
  
  		    cp = buf + sizeof("nameserver") - 1;
  		    while (*cp == ' ' || *cp == '\t')
--- 292,301 ----
  		}
  		/* read nameservers to query */
  		if (MATCH(buf, "nameserver") && nserv < MAXNS) {
! 		    struct addrinfo hints, *ai;
! 		    char sbuf[NI_MAXSERV];
! 		    const size_t minsiz =
! 		        sizeof(statp->_u._ext.ext->nsaddrs[0]);
  
  		    cp = buf + sizeof("nameserver") - 1;
  		    while (*cp == ' ' || *cp == '\t')
***************
*** 301,323 ****
  			n = strlen(cp);
  			if (cp[n - 1] == '\n')
  			    cp[n - 1] = '\0';
! 			if (inet_pton(AF_INET6, cp, &a6)) {
! 			    if (statp->ext != NULL) {
! 				sin6 = &statp->ext->nsaddr_list[nserv].sin6;
! 				memset(sin6, 0, sizeof(*sin6));
! 				sin6->sin6_addr = a6;
! 				sin6->sin6_family = AF_INET6;
! 				sin6->sin6_port = htons(NAMESERVER_PORT);
! 				nserv++;
  			    }
! 			} else if (inet_aton(cp, &a)) {
! 			    statp->nsaddr_list[nserv].sin_addr = a;
! 			    statp->nsaddr_list[nserv].sin_family = AF_INET;
! 			    statp->nsaddr_list[nserv].sin_port =
! 				    htons(NAMESERVER_PORT);
! 			    if (statp->ext != NULL)
! 				statp->ext->nsaddr_list[nserv].sin =
! 					statp->nsaddr_list[nserv];
  			    nserv++;
  			}
  		    }
--- 304,327 ----
  			n = strlen(cp);
  			if (cp[n - 1] == '\n')
  			    cp[n - 1] = '\0';
! 			memset(&hints, 0, sizeof(hints));
! 			hints.ai_family = PF_UNSPEC;
! 			hints.ai_socktype = SOCK_DGRAM;	/*dummy*/
! 			hints.ai_flags = AI_NUMERICHOST;
! 			snprintf(sbuf, sizeof(sbuf), "%u", NAMESERVER_PORT);
! 			if (getaddrinfo(cp, sbuf, &hints, &ai) == 0 &&
! 			    ai->ai_addrlen <= minsiz) {
! 			    if (statp->_u._ext.ext != NULL) {
! 				memcpy(&statp->_u._ext.ext->nsaddrs[nserv],
! 				    ai->ai_addr, ai->ai_addrlen);
  			    }
! 			    if (ai->ai_addrlen <=
! 			        sizeof(statp->nsaddr_list[nserv])) {
! 				memcpy(&statp->nsaddr_list[nserv],
! 				    ai->ai_addr, ai->ai_addrlen);
! 			    } else
! 				statp->nsaddr_list[nserv].sin_family = 0;
! 			    freeaddrinfo(ai);
  			    nserv++;
  			}
  		    }
***************
*** 550,553 ****
--- 554,566 ----
  		}
  	}
  	statp->_u._ext.nscount = 0;
+ }
+ 
+ void
+ res_ndestroy(res_state statp) {
+ 	res_nclose(statp);
+ 	if (statp->_u._ext.ext != NULL)
+ 		free(statp->_u._ext.ext);
+ 	statp->options &= ~RES_INIT;
+ 	statp->_u._ext.ext = NULL;
  }
Index: src/lib/resolv/res_query.c
===================================================================
RCS file: /master/contrib/bind/src/lib/resolv/res_query.c,v
retrieving revision 1.4
diff -c -r1.4 res_query.c
*** src/lib/resolv/res_query.c	2001/04/10 20:36:15	1.4
--- src/lib/resolv/res_query.c	2001/07/11 14:53:35
***************
*** 97,106 ****
  #define MAXPACKET	1024
  #endif
  
- #ifdef RES_USE_EDNS0
- extern int res_opt __P((int, u_char *, int, int));
- #endif
- 
  /*
   * Formulate a normal query, send, and await answer.
   * Returned answer is placed in supplied buffer "answer".
--- 97,102 ----
***************
*** 121,127 ****
--- 117,127 ----
  	u_char buf[MAXPACKET];
  	HEADER *hp = (HEADER *) answer;
  	int n;
+ 	u_int oflags;
  
+ 	oflags = statp->_flags;
+ 
+ again:
  	hp->rcode = NOERROR;	/* default */
  
  #ifdef DEBUG
***************
*** 132,138 ****
  	n = res_nmkquery(statp, QUERY, name, class, type, NULL, 0, NULL,
  			 buf, sizeof(buf));
  #ifdef RES_USE_EDNS0
! 	if (n > 0 && (statp->options & RES_USE_EDNS0) != 0)
  		n = res_nopt(statp, n, buf, sizeof(buf), anslen);
  #endif
  	if (n <= 0) {
--- 132,139 ----
  	n = res_nmkquery(statp, QUERY, name, class, type, NULL, 0, NULL,
  			 buf, sizeof(buf));
  #ifdef RES_USE_EDNS0
! 	if (n > 0 && (statp->options & RES_USE_EDNS0) != 0 &&
! 	    (statp->_flags & RES_F_EDNS0ERR) == 0)
  		n = res_nopt(statp, n, buf, sizeof(buf), anslen);
  #endif
  	if (n <= 0) {
***************
*** 145,150 ****
--- 146,161 ----
  	}
  	n = res_nsend(statp, buf, n, answer, anslen);
  	if (n < 0) {
+ #ifdef RES_USE_EDNS0
+ 		/* if the query choked with EDNS0, retry without EDNS0 */
+ 		if ((statp->options & RES_USE_EDNS0) != 0 &&
+ 		    ((oflags ^ statp->_flags) & RES_F_EDNS0ERR) != 0) {
+ 			statp->_flags |= RES_F_EDNS0ERR;
+ 			if (statp->options & RES_DEBUG)
+ 				printf(";; res_nquery: retry without EDNS0\n");
+ 			goto again;
+ 		}
+ #endif
  #ifdef DEBUG
  		if (statp->options & RES_DEBUG)
  			printf(";; res_query: send error\n");
Index: src/lib/resolv/res_send.c
===================================================================
RCS file: /master/contrib/bind/src/lib/resolv/res_send.c,v
retrieving revision 1.5
diff -c -r1.5 res_send.c
*** src/lib/resolv/res_send.c	2001/04/10 20:36:15	1.5
--- src/lib/resolv/res_send.c	2001/07/11 14:53:35
***************
*** 113,133 ****
  
  /* Forward. */
  
  static int		send_vc(res_state, const u_char *, int,
  				u_char *, int, int *, int);
  static int		send_dg(res_state, const u_char *, int,
  				u_char *, int, int *, int,
  				int *, int *);
  static void		Aerror(const res_state, FILE *, const char *, int,
! 			       struct sockaddr *);
  static void		Perror(const res_state, FILE *, const char *, int);
! static int		sock_eq(struct sockaddr_in *, struct sockaddr_in *);
  #ifdef NEED_PSELECT
  static int		pselect(int, void *, void *, void *,
  				struct timespec *,
  				const sigset_t *);
  #endif
  
  /* Public. */
  
  /* int
--- 113,140 ----
  
  /* Forward. */
  
+ static int		get_salen __P((const struct sockaddr *));
+ static struct sockaddr * get_nsaddr __P((res_state, size_t));
  static int		send_vc(res_state, const u_char *, int,
  				u_char *, int, int *, int);
  static int		send_dg(res_state, const u_char *, int,
  				u_char *, int, int *, int,
  				int *, int *);
  static void		Aerror(const res_state, FILE *, const char *, int,
! 			       const struct sockaddr *, int);
  static void		Perror(const res_state, FILE *, const char *, int);
! static int		sock_eq(struct sockaddr *, struct sockaddr *);
  #ifdef NEED_PSELECT
  static int		pselect(int, void *, void *, void *,
  				struct timespec *,
  				const sigset_t *);
  #endif
+ void res_pquery(const res_state, const u_char *, int, FILE *);
  
+ #ifdef INET6
+ static const int niflags = NI_NUMERICHOST | NI_NUMERICSERV;
+ #endif
+ 
  /* Public. */
  
  /* int
***************
*** 149,158 ****
  	case AF_INET:
  		inp = (struct sockaddr_in *)sa;
  		for (ns = 0;  ns < statp->nscount;  ns++) {
! 			if (statp->ext != NULL)
! 				srv = &statp->ext->nsaddr_list[ns].sin;
! 			else
! 				srv = &statp->nsaddr_list[ns];
  			if (srv->sin_family == inp->sin_family &&
  			    srv->sin_port == inp->sin_port &&
  			    (srv->sin_addr.s_addr == INADDR_ANY ||
--- 156,162 ----
  	case AF_INET:
  		inp = (struct sockaddr_in *)sa;
  		for (ns = 0;  ns < statp->nscount;  ns++) {
! 			srv = (struct sockaddr_in *)get_nsaddr(statp, ns);
  			if (srv->sin_family == inp->sin_family &&
  			    srv->sin_port == inp->sin_port &&
  			    (srv->sin_addr.s_addr == INADDR_ANY ||
***************
*** 161,175 ****
  		}
  		break;
  	case AF_INET6:
! 		if (statp->ext == NULL)
  			break;
  		in6p = (struct sockaddr_in6 *)sa;
  		for (ns = 0;  ns < statp->nscount;  ns++) {
! 			srv6 = &statp->ext->nsaddr_list[ns].sin6;
  			if (srv6->sin6_family == in6p->sin6_family &&
  			    srv6->sin6_port == in6p->sin6_port &&
  			    (IN6_IS_ADDR_UNSPECIFIED(&srv6->sin6_addr) ||
! 			     IN6_ARE_ADDR_EQUAL(&srv6->sin6_addr, &in6p->sin6_addr)))
  				return (1);
  		}
  		break;
--- 165,180 ----
  		}
  		break;
  	case AF_INET6:
! 		if (EXT(statp).ext == NULL)
  			break;
  		in6p = (struct sockaddr_in6 *)sa;
  		for (ns = 0;  ns < statp->nscount;  ns++) {
! 			srv6 = (struct sockaddr_in6 *)get_nsaddr(statp, ns);
  			if (srv6->sin6_family == in6p->sin6_family &&
  			    srv6->sin6_port == in6p->sin6_port &&
  			    (IN6_IS_ADDR_UNSPECIFIED(&srv6->sin6_addr) ||
! 			     IN6_ARE_ADDR_EQUAL(&srv6->sin6_addr,
! 						&in6p->sin6_addr)))
  				return (1);
  		}
  		break;
***************
*** 271,277 ****
  	  const u_char *buf, int buflen, u_char *ans, int anssiz)
  {
  	int gotsomewhere, terrno, try, v_circuit, resplen, ns, n;
! 	char abuf[INET6_ADDRSTRLEN];
  
  	if (statp->nscount == 0) {
  		errno = ESRCH;
--- 276,282 ----
  	  const u_char *buf, int buflen, u_char *ans, int anssiz)
  {
  	int gotsomewhere, terrno, try, v_circuit, resplen, ns, n;
! 	char abuf[NI_MAXHOST];
  
  	if (statp->nscount == 0) {
  		errno = ESRCH;
***************
*** 293,308 ****
  	 */
  	if (EXT(statp).nscount != 0) {
  		int needclose = 0;
  
  		if (EXT(statp).nscount != statp->nscount)
  			needclose++;
  		else
! 			for (ns = 0; ns < statp->nscount; ns++)
! 				if (!sock_eq(&statp->nsaddr_list[ns],
! 					     &EXT(statp).nsaddrs[ns])) {
  					needclose++;
  					break;
  				}
  		if (needclose) {
  			res_nclose(statp);
  			EXT(statp).nscount = 0;
--- 298,335 ----
  	 */
  	if (EXT(statp).nscount != 0) {
  		int needclose = 0;
+ #ifdef INET6
+ 		struct sockaddr_storage peer;
+ #else
+ 		struct sockaddr peer;
+ #endif
+ 		int peerlen;
  
  		if (EXT(statp).nscount != statp->nscount)
  			needclose++;
  		else
! 			for (ns = 0; ns < statp->nscount; ns++) {
! 				if (statp->nsaddr_list[ns].sin_family &&
! 				    !sock_eq((struct sockaddr *)&statp->nsaddr_list[ns],
! 					     (struct sockaddr *)&EXT(statp).ext->nsaddrs[ns])) {
! 					needclose++;
! 					break;
! 				}
! 
! 				if (EXT(statp).nssocks[ns] == -1)
! 					continue;
! 				peerlen = sizeof(peer);
! 				if (getsockname(EXT(statp).nssocks[ns],
! 				    (struct sockaddr *)&peer, &peerlen) < 0) {
! 					needclose++;
! 					break;
! 				}
! 				if (!sock_eq((struct sockaddr *)&peer,
! 				    get_nsaddr(statp, ns))) {
  					needclose++;
  					break;
  				}
+ 			}
  		if (needclose) {
  			res_nclose(statp);
  			EXT(statp).nscount = 0;
***************
*** 314,322 ****
  	 */
  	if (EXT(statp).nscount == 0) {
  		for (ns = 0; ns < statp->nscount; ns++) {
- 			EXT(statp).nsaddrs[ns] = statp->nsaddr_list[ns];
  			EXT(statp).nstimes[ns] = RES_MAXTIME;
  			EXT(statp).nssocks[ns] = -1;
  		}
  		EXT(statp).nscount = statp->nscount;
  	}
--- 341,352 ----
  	 */
  	if (EXT(statp).nscount == 0) {
  		for (ns = 0; ns < statp->nscount; ns++) {
  			EXT(statp).nstimes[ns] = RES_MAXTIME;
  			EXT(statp).nssocks[ns] = -1;
+ 
+ 			if (!statp->nsaddr_list[ns].sin_family)
+ 				continue;
+ 			EXT(statp).ext->nsaddrs[ns].sin = statp->nsaddr_list[ns];
  		}
  		EXT(statp).nscount = statp->nscount;
  	}
***************
*** 327,351 ****
  	 */
  	if ((statp->options & RES_ROTATE) != 0 &&
  	    (statp->options & RES_BLAST) == 0) {
! 		union __res_sockaddr_union una;
  		int lastns = statp->nscount - 1;
  		int fd;
  
! 		una.sin = statp->nsaddr_list[0];
  		fd = EXT(statp).nssocks[0];
  		for (ns = 0; ns < lastns; ns++) {
  			statp->nsaddr_list[ns] = statp->nsaddr_list[ns + 1];
  			EXT(statp).nssocks[ns] = EXT(statp).nssocks[ns + 1];
  		}
! 		statp->nsaddr_list[lastns] = una.sin;
! 		if (statp->ext != NULL) {
! 			una = statp->ext->nsaddr_list[0];
! 			for (ns = 0; ns < lastns; ns++)
! 				statp->ext->nsaddr_list[ns] =
! 					statp->ext->nsaddr_list[ns + 1];
! 			statp->ext->nsaddr_list[lastns] = una;
  		}
  		EXT(statp).nssocks[lastns] = fd;
  	}
  
  	/*
--- 357,400 ----
  	 */
  	if ((statp->options & RES_ROTATE) != 0 &&
  	    (statp->options & RES_BLAST) == 0) {
! #ifdef INET6
! 		union __res_sockaddr_union inu;
! 		int inalen;
! #endif
! 		struct sockaddr_in ina;
  		int lastns = statp->nscount - 1;
  		int fd;
+ 		u_int16_t nstime;
  
! #ifdef INET6
! 		if (EXT(statp).ext != NULL)
! 			inu = EXT(statp).ext->nsaddrs[0];
! 		ina = statp->nsaddr_list[0];
  		fd = EXT(statp).nssocks[0];
+ 		nstime = EXT(statp).nstimes[0];
  		for (ns = 0; ns < lastns; ns++) {
+ 			if (EXT(statp).ext != NULL)
+                                 EXT(statp).ext->nsaddrs[ns] = 
+ 					EXT(statp).ext->nsaddrs[ns + 1];
  			statp->nsaddr_list[ns] = statp->nsaddr_list[ns + 1];
  			EXT(statp).nssocks[ns] = EXT(statp).nssocks[ns + 1];
+ 			EXT(statp).nstimes[ns] = EXT(statp).nstimes[ns + 1];
  		}
! 		if (EXT(statp).ext != NULL)
! 			EXT(statp).ext->nsaddrs[lastns] = inu;
! 		statp->nsaddr_list[lastns] = ina;
! 		EXT(statp).nssocks[lastns] = fd;
! 		EXT(statp).nstimes[lastns] = nstime;
! #else
! 		ina.sin = statp->nsaddr_list[0];
! 		fd = EXT(statp).nssocks[0];
! 		for (ns = 0; ns < lastns; ns++) {
! 			statp->nsaddr_list[ns] = statp->nsaddr_list[ns + 1];
! 			EXT(statp).nssocks[ns] = EXT(statp).nssocks[ns + 1];
  		}
+ 		statp->nsaddr_list[lastns] = ina.sin;
  		EXT(statp).nssocks[lastns] = fd;
+ #endif
  	}
  
  	/*
***************
*** 354,378 ****
  	for (try = 0; try < statp->retry; try++) {
  	    for (ns = 0; ns < statp->nscount; ns++) {
  		struct sockaddr *nsap;
! 		int salen;
! 		if (statp->ext != NULL)
! 			nsap = (struct sockaddr *)&statp->ext->nsaddr_list[ns];
! 		else
! 			nsap = (struct sockaddr *)&statp->nsaddr_list[ns];
! #ifdef HAVE_SA_LEN
! 		/* there are people do not set sa_len.  be forgibing to them */
! 		if (nsap->sa_len)
! 			salen = nsap->sa_len;
! 		else {
! 			salen = nsap->sa_family == AF_INET6
! 				? sizeof(struct sockaddr_in6)
! 				: sizeof(struct sockaddr_in);
! 		}
! #else
! 		salen = nsap->sa_family == AF_INET6
! 			? sizeof(struct sockaddr_in6)
! 			: sizeof(struct sockaddr_in);
! #endif
   same_ns:
  		if (statp->qhook) {
  			int done = 0, loops = 0;
--- 403,411 ----
  	for (try = 0; try < statp->retry; try++) {
  	    for (ns = 0; ns < statp->nscount; ns++) {
  		struct sockaddr *nsap;
! 		int nsaplen;
! 		nsap = get_nsaddr(statp, ns);
! 		nsaplen = get_salen(nsap);
   same_ns:
  		if (statp->qhook) {
  			int done = 0, loops = 0;
***************
*** 380,387 ****
  			do {
  				res_sendhookact act;
  
! 				act = (*statp->qhook)(&nsap,
! 						      &buf, &buflen,
  						      ans, anssiz, &resplen);
  				switch (act) {
  				case res_goahead:
--- 413,419 ----
  			do {
  				res_sendhookact act;
  
! 				act = (*statp->qhook)(&nsap, &buf, &buflen,
  						      ans, anssiz, &resplen);
  				switch (act) {
  				case res_goahead:
***************
*** 405,415 ****
  			} while (!done);
  		}
  
  		Dprint(((statp->options & RES_DEBUG) &&
! 			getnameinfo(nsap, salen, abuf, sizeof(abuf),
! 				    NULL, 0, NI_NUMERICHOST) == 0),
  		       (stdout, ";; Querying server (# %d) address = %s\n",
  			ns + 1, abuf));
  
  		if (v_circuit) {
  			/* Use VC; at most one attempt per server. */
--- 437,455 ----
  			} while (!done);
  		}
  
+ #ifdef INET6
  		Dprint(((statp->options & RES_DEBUG) &&
! 			getnameinfo(nsap, nsaplen, abuf, sizeof(abuf),
! 				    NULL, 0, niflags) == 0),
  		       (stdout, ";; Querying server (# %d) address = %s\n",
  			ns + 1, abuf));
+ #else
+ 		Dprint(statp->options & RES_DEBUG,
+  		       (stdout, ";; Querying server (# %d) address = %s\n",
+ 			ns + 1,
+ 			inet_ntoa(((struct sockaddr_in *)nsap)->sin_addr)));
+ #endif
+ 
  
  		if (v_circuit) {
  			/* Use VC; at most one attempt per server. */
***************
*** 459,466 ****
  			do {
  				res_sendhookact act;
  
! 				act = (*statp->rhook)(nsap,
! 						      buf, buflen,
  						      ans, anssiz, &resplen);
  				switch (act) {
  				case res_goahead:
--- 499,505 ----
  			do {
  				res_sendhookact act;
  
! 				act = (*statp->rhook)(nsap, buf, buflen,
  						      ans, anssiz, &resplen);
  				switch (act) {
  				case res_goahead:
***************
*** 504,543 ****
  /* Private */
  
  static int
  send_vc(res_state statp,
  	const u_char *buf, int buflen, u_char *ans, int anssiz,
  	int *terrno, int ns)
  {
  	const HEADER *hp = (HEADER *) buf;
  	HEADER *anhp = (HEADER *) ans;
! 	struct sockaddr *nsap = (struct sockaddr *)&statp->nsaddr_list[ns];
  	int truncating, connreset, resplen, n;
  	struct iovec iov[2];
  	u_short len;
  	u_char *cp;
  
  	connreset = 0;
   same_ns:
  	truncating = 0;
  
  	/* Are we still talking to whom we want to talk to? */
  	if (statp->_vcsock >= 0 && (statp->_flags & RES_F_VC) != 0) {
! 		union __res_sockaddr_union peer;
  		int size = sizeof peer;
  
  		if (getpeername(statp->_vcsock,
  				(struct sockaddr *)&peer, &size) < 0 ||
! 		    !sock_eq((struct sockaddr_in *)&peer,
! 				(struct sockaddr_in *)nsap)) {
  			res_nclose(statp);
! 			statp->_flags &= ~(RES_F_VC | RES_F_V6);
  		}
  	}
  
  	if (statp->_vcsock < 0 || (statp->_flags & RES_F_VC) == 0) {
- 		int salen = nsap->sa_family == AF_INET6
- 		    ? sizeof(struct sockaddr_in6)
- 		    : sizeof(struct sockaddr_in);
  		if (statp->_vcsock >= 0)
  			res_nclose(statp);
  
--- 543,637 ----
  /* Private */
  
  static int
+ get_salen(sa)
+ 	const struct sockaddr *sa;
+ {
+ 
+ #ifdef HAVE_SA_LEN
+ 	/* there are people do not set sa_len.  be forgibing to them */
+ 	if (sa->sa_len)
+ 		return sa->sa_len;
+ #endif
+ 
+ 	if (sa->sa_family == AF_INET)
+ 		return sizeof(struct sockaddr_in);
+ #ifdef INET6
+ 	else if (sa->sa_family == AF_INET)
+ 		return sizeof(struct sockaddr_in6);
+ #endif
+ 	else
+ 		return 0;	/* unknown, die on connect */
+ }
+ 
+ /*
+  * pick appropriate nsaddr_list for use.  see res_init() for initialization.
+  */
+ static struct sockaddr *
+ get_nsaddr(statp, n)
+ 	res_state statp;
+ 	size_t n;
+ {
+ 
+ #ifdef INET6
+ 	if (!statp->nsaddr_list[n].sin_family && EXT(statp).ext) {
+ 		/*
+ 		 * - EXT(statp).ext->nsaddrs[n] holds an address that is larger
+ 		 *   than struct sockaddr, and
+ 		 * - user code did not update statp->nsaddr_list[n].
+ 		 */
+ 		return (struct sockaddr *)(void *)&EXT(statp).ext->nsaddrs[n];
+ 	} else {
+ 		/*
+ 		 * - user code updated statp->nsaddr_list[n], or
+ 		 * - statp->nsaddr_list[n] has the same content as
+ 		 *   EXT(statp).ext->nsaddrs[n].
+ 		 */
+ 		return (struct sockaddr *)(void *)&statp->nsaddr_list[n];
+ 	}
+ #else
+ 	return (struct sockaddr *)(void *)&statp.nsaddr_list[n];
+ #endif
+ }
+ 
+ static int
  send_vc(res_state statp,
  	const u_char *buf, int buflen, u_char *ans, int anssiz,
  	int *terrno, int ns)
  {
  	const HEADER *hp = (HEADER *) buf;
  	HEADER *anhp = (HEADER *) ans;
! 	struct sockaddr *nsap;
! 	int nsaplen;
  	int truncating, connreset, resplen, n;
  	struct iovec iov[2];
  	u_short len;
  	u_char *cp;
  
+ 	nsap = get_nsaddr(statp, ns);
+ 	nsaplen = get_salen(nsap);
+ 
  	connreset = 0;
   same_ns:
  	truncating = 0;
  
  	/* Are we still talking to whom we want to talk to? */
  	if (statp->_vcsock >= 0 && (statp->_flags & RES_F_VC) != 0) {
! #ifdef INET6
! 		struct sockaddr_storage peer;
! #else
! 		struct sockaddr_in peer;
! #endif
  		int size = sizeof peer;
  
  		if (getpeername(statp->_vcsock,
  				(struct sockaddr *)&peer, &size) < 0 ||
! 		    !sock_eq((struct sockaddr *)&peer, nsap)) {
  			res_nclose(statp);
! 			statp->_flags &= ~RES_F_VC;
  		}
  	}
  
  	if (statp->_vcsock < 0 || (statp->_flags & RES_F_VC) == 0) {
  		if (statp->_vcsock >= 0)
  			res_nclose(statp);
  
***************
*** 552,566 ****
  			return (-1);
  		}
  		errno = 0;
! 		if (connect(statp->_vcsock, nsap, salen) < 0) {
  			*terrno = errno;
! 			Aerror(statp, stderr, "connect/vc", errno, nsap);
  			res_nclose(statp);
  			return (0);
  		}
  		statp->_flags |= RES_F_VC;
- 		if (nsap->sa_family == AF_INET6)
- 			statp->_flags |= RES_F_V6;
  	}
  
  	/*
--- 646,659 ----
  			return (-1);
  		}
  		errno = 0;
! 		if (connect(statp->_vcsock, nsap, nsaplen) < 0) {
  			*terrno = errno;
! 			Aerror(statp, stderr, "connect/vc", errno, nsap,
! 			    nsaplen);
  			res_nclose(statp);
  			return (0);
  		}
  		statp->_flags |= RES_F_VC;
  	}
  
  	/*
***************
*** 683,703 ****
  {
  	const HEADER *hp = (HEADER *) buf;
  	HEADER *anhp = (HEADER *) ans;
! 	const struct sockaddr *nsap = (struct sockaddr *)&statp->nsaddr_list[ns];
  	struct timespec now, timeout, finish;
  	fd_set dsmask;
! 	union __res_sockaddr_union from;
  	int fromlen, resplen, seconds, n, s;
- 	int salen;
- 
- 	if (statp->_vcsock >= 0 &&
- 	    (statp->_flags & RES_F_V6) !=
- 	     (nsap->sa_family == AF_INET6 ? RES_F_V6 : 0))
- 		res_nclose(statp);
  
! 	salen = nsap->sa_family == AF_INET6 ? sizeof(struct sockaddr_in6)
! 	    : sizeof(struct sockaddr_in);
! 
  	if (EXT(statp).nssocks[ns] == -1) {
  		EXT(statp).nssocks[ns] = socket(nsap->sa_family, SOCK_DGRAM, 0);
  		if (EXT(statp).nssocks[ns] > highestFD) {
--- 776,794 ----
  {
  	const HEADER *hp = (HEADER *) buf;
  	HEADER *anhp = (HEADER *) ans;
! 	const struct sockaddr *nsap;
! 	int nsaplen;
  	struct timespec now, timeout, finish;
  	fd_set dsmask;
! #ifdef INET6
! 	struct sockaddr_storage from;
! #else
! 	struct sockaddr_in from;
! #endif
  	int fromlen, resplen, seconds, n, s;
  
! 	nsap = get_nsaddr(statp, ns);
! 	nsaplen = get_salen(nsap);
  	if (EXT(statp).nssocks[ns] == -1) {
  		EXT(statp).nssocks[ns] = socket(nsap->sa_family, SOCK_DGRAM, 0);
  		if (EXT(statp).nssocks[ns] > highestFD) {
***************
*** 709,716 ****
  			Perror(statp, stderr, "socket(dg)", errno);
  			return (-1);
  		}
- 		if (nsap->sa_family == AF_INET6)
- 			statp->_flags |= RES_F_V6;
  #ifndef CANNOT_CONNECT_DGRAM
  		/*
  		 * On a 4.3BSD+ machine (client and server,
--- 800,805 ----
***************
*** 723,732 ****
  		 * error message is received.  We can thus detect
  		 * the absence of a nameserver without timing out.
  		 */
! 		if (connect(EXT(statp).nssocks[ns], (struct sockaddr *)nsap,
! 			    salen) < 0) {
! 			Aerror(statp, stderr, "connect(dg)", errno,
! 			    (struct sockaddr *)nsap);
  			res_nclose(statp);
  			return (0);
  		}
--- 812,820 ----
  		 * error message is received.  We can thus detect
  		 * the absence of a nameserver without timing out.
  		 */
! 		if (connect(EXT(statp).nssocks[ns], nsap, nsaplen) < 0) {
! 			Aerror(statp, stderr, "connect(dg)", errno, nsap,
! 			    nsaplen);
  			res_nclose(statp);
  			return (0);
  		}
***************
*** 742,751 ****
  		return (0);
  	}
  #else /* !CANNOT_CONNECT_DGRAM */
! 	if (sendto(s, (char*)buf, buflen, 0,
! 		   (struct sockaddr *)nsap, salen) != buflen)
  	{
! 		Aerror(statp, stderr, "sendto", errno, nsap);
  		res_nclose(statp);
  		return (0);
  	}
--- 830,838 ----
  		return (0);
  	}
  #else /* !CANNOT_CONNECT_DGRAM */
! 	if (sendto(s, (char*)buf, buflen, 0, nsap, nsaplen) != buflen)
  	{
! 		Aerror(statp, stderr, "sendto", errno, nsap, nsaplen);
  		res_nclose(statp);
  		return (0);
  	}
***************
*** 831,836 ****
--- 918,939 ----
  			ans, (resplen > anssiz) ? anssiz : resplen);
  		goto wait;
  	}
+ #ifdef RES_USE_EDNS0
+ 	if (anhp->rcode == FORMERR && (statp->options & RES_USE_EDNS0) != 0) {
+ 		/*
+ 		 * Do not retry if the server do not understand EDNS0.
+ 		 * The case has to be captured here, as FORMERR packet do not
+ 		 * carry query section, hence res_queriesmatch() returns 0.
+ 		 */
+ 		DprintQ(statp->options & RES_DEBUG,
+ 			(stdout, "server rejected query with EDNS0:\n"),
+ 			ans, (resplen > anssiz) ? anssiz : resplen);
+ 		/* record the error */
+ 		statp->_flags |= RES_F_EDNS0ERR;
+ 		res_nclose(statp);
+ 		return (0);
+ 	}
+ #endif
  	if (!(statp->options & RES_INSECURE2) &&
  	    !res_queriesmatch(buf, buf + buflen,
  			      ans, ans + anssiz)) {
***************
*** 876,906 ****
  
  static void
  Aerror(const res_state statp, FILE *file, const char *string, int error,
!        struct sockaddr *address)
  {
  	int save = errno;
  
  	if ((statp->options & RES_DEBUG) != 0) {
! 		char abuf[INET6_ADDRSTRLEN], pbuf[32];
! 		int salen;
! #ifdef HAVE_SA_LEN
! 		/* there are people do not set sa_len.  be forgibing to them */
! 		if (address->sa_len)
! 			salen = address->sa_len;
! 		else {
! 			salen = address->sa_family == AF_INET6
! 				? sizeof(struct sockaddr_in6)
! 				: sizeof(struct sockaddr_in);
  		}
  #else
! 		salen = address->sa_family == AF_INET6
! 			? sizeof(struct sockaddr_in6)
! 			: sizeof(struct sockaddr_in);
  #endif
- 		getnameinfo(address, salen, abuf, sizeof(abuf),
- 			    pbuf, sizeof(pbuf), NI_NUMERICHOST|NI_NUMERICSERV);
  		fprintf(file, "res_send: %s ([%s].%s): %s\n",
! 			string, abuf, pbuf, strerror(error));
  	}
  	errno = save;
  }
--- 979,1012 ----
  
  static void
  Aerror(const res_state statp, FILE *file, const char *string, int error,
!        const struct sockaddr *address, int alen)
  {
  	int save = errno;
+ #ifdef INET6
+ 	char hbuf[NI_MAXHOST];
+ 	char sbuf[NI_MAXSERV];
+ #else
+ 	char hbuf[sizeof "255.255.255.255"];
+ 	char sbuf[sizeof "65535"];
+ #endif
  
  	if ((statp->options & RES_DEBUG) != 0) {
! #ifdef INET6
! 		if (getnameinfo(address, alen, hbuf, sizeof(hbuf),
! 		    sbuf, sizeof(sbuf), niflags)) {
! 			strncpy(hbuf, "?", sizeof(hbuf) - 1);
! 			hbuf[sizeof(hbuf) - 1] = '\0';
! 			strncpy(sbuf, "?", sizeof(sbuf) - 1);
! 			sbuf[sizeof(sbuf) - 1] = '\0';
  		}
  #else
! 		inet_ntop(AF_INET, &((struct sockaddr_in *)address)->sin_addr,
! 		    hbuf, sizeof hbuf),
! 		snprintf(sbuf, sizeof(sbuf), "%u",
! 		    ntohs(((struct sockaddr_in *)address)->sin_por));
  #endif
  		fprintf(file, "res_send: %s ([%s].%s): %s\n",
! 			string, hbuf, sbuf, strerror(error));
  	}
  	errno = save;
  }
***************
*** 916,925 ****
  }
  
  static int
! sock_eq(struct sockaddr_in *a1, struct sockaddr_in *a2) {
! 	return ((a1->sin_family == a2->sin_family) &&
! 		(a1->sin_port == a2->sin_port) &&
! 		(a1->sin_addr.s_addr == a2->sin_addr.s_addr));
  }
  
  #ifdef NEED_PSELECT
--- 1022,1052 ----
  }
  
  static int
! sock_eq(struct sockaddr *a, struct sockaddr *b) {
! 	struct sockaddr_in *a4, *b4;
! #ifdef INET6
! 	struct sockaddr_in6 *a6, *b6;
! #endif
! 
! 	if (a->sa_family != b->sa_family)
! 		return 0;
! 	switch (a->sa_family) {
! 	case AF_INET:
! 		a4 = (struct sockaddr_in *)a;
! 		b4 = (struct sockaddr_in *)b;
! 		return a4->sin_port == b4->sin_port &&
! 		    a4->sin_addr.s_addr == b4->sin_addr.s_addr;
! #ifdef INET6
! 	case AF_INET6:
! 		a6 = (struct sockaddr_in6 *)a;
! 		b6 = (struct sockaddr_in6 *)b;
! 		return a6->sin6_port == b6->sin6_port &&
! 		    a6->sin6_scope_id == b6->sin6_scope_id &&
! 		    IN6_ARE_ADDR_EQUAL(&a6->sin6_addr, &b6->sin6_addr);
! #endif
! 	default:
! 		return 0;
! 	}
  }
  
  #ifdef NEED_PSELECT
Index: src/lib/resolv/res_update.c
===================================================================
RCS file: /master/contrib/bind/src/lib/resolv/res_update.c,v
retrieving revision 1.5
diff -c -r1.5 res_update.c
*** src/lib/resolv/res_update.c	2001/04/10 20:36:15	1.5
--- src/lib/resolv/res_update.c	2001/07/11 14:53:31
***************
*** 165,172 ****
  			goto done;
  
  		/* Temporarily replace the resolver's nameserver set. */
! 		nscount = nscopy(nsaddrs, statp->ext->nsaddr_list, statp->nscount);
! 		statp->nscount = nscopy(statp->ext->nsaddr_list,
  					zptr->z_nsaddrs, zptr->z_nscount);
  
  		/* Send the update and remember the result. */
--- 165,172 ----
  			goto done;
  
  		/* Temporarily replace the resolver's nameserver set. */
! 		nscount = nscopy(nsaddrs, statp->_u._ext.ext->nsaddrs, statp->nscount);
! 		statp->nscount = nscopy(statp->_u._ext.ext->nsaddrs,
  					zptr->z_nsaddrs, zptr->z_nscount);
  
  		/* Send the update and remember the result. */
***************
*** 184,190 ****
  			nzones++;
  
  		/* Restore resolver's nameserver set. */
! 		statp->nscount = nscopy(statp->ext->nsaddr_list, nsaddrs, nscount);
  		nscount = 0;
  	}
   done:
--- 184,190 ----
  			nzones++;
  
  		/* Restore resolver's nameserver set. */
! 		statp->nscount = nscopy(statp->_u._ext.ext->nsaddrs, nsaddrs, nscount);		
  		nscount = 0;
  	}
   done:
***************
*** 196,202 ****
  		free(zptr);
  	}
  	if (nscount != 0)
! 		statp->nscount = nscopy(statp->ext->nsaddr_list, nsaddrs, nscount);
  
  	return (nzones);
  }
--- 196,202 ----
  		free(zptr);
  	}
  	if (nscount != 0)
! 		statp->nscount = nscopy(statp->_u._ext.ext->nsaddrs, nsaddrs, nscount);
  
  	return (nzones);
  }
Index: irs_data.c
===================================================================
RCS file: /master/contrib/bind/src/lib/irs/irs_data.c,v
retrieving revision 1.9
diff -c -r1.9 irs_data.c
*** irs_data.c	2001/02/20 23:15:01	1.9
--- irs_data.c	2001/09/04 17:36:28
***************
*** 193,199 ****
  void
  __h_errno_set(struct __res_state *res, int err) {
  
! 	h_errno = res->res_h_errno = err;
  }
  
  #endif /*__BIND_NOSTATIC*/
--- 193,199 ----
  void
  __h_errno_set(struct __res_state *res, int err) {
  
! 	*__h_errno() = res->res_h_errno = err;
  }
  
  #endif /*__BIND_NOSTATIC*/
