Update.
authorUlrich Drepper <drepper@redhat.com>
Sat, 4 Dec 1999 18:05:55 +0000 (18:05 +0000)
committerUlrich Drepper <drepper@redhat.com>
Sat, 4 Dec 1999 18:05:55 +0000 (18:05 +0000)
1999-12-03  Andreas Jaeger  <aj@suse.de>

* nss/getXXbyYY.c: Include <resolv.h>
(FUNCTION_NAME): Use res_ninit instead of res_init.

* nss/getXXbyYY_r.c [NEED__RES]: Include <resolv.h> for _res
declaration and prototypes.
Remove extra _res declaration.
(INTERNAL): Use thread aware res_ninit function.

* inet/gethstbyad_r.c: Include <resolv.h>.

* resolv/res_data.c: Update from Bind 8.2.2-P5.  Moved res_init to
res_libc.c.  Disabled unneeded functions.

* resolv/res_libc.c: New file.

* Versions.def: Add version GLIBC_2.2 for libpthread.
Add versions GLIBC_2.1 and GLIBC_2.2 for libresolv.

* include/resolv.h: Add internal interfaces.

* resolv/Makefile (routines): Add new files.
(libresolv-routines): Likewise.
(distribute): Likewise.

* resolv/gethnamaddr.c: Use thread safe resolver functions.
* resolv/nss_dns/dns-host.c: Likewise.
* resolv/nss_dns/dns-network.c: Likewise.

* resolv/arpa/nameser.h: Update from Bind 8.2.2-P5.
* resolv/nsap_addr.c: Likewise.
* resolv/res_comp.c: Likewise.
* resolv/res_debug.c: Likewise.
* resolv/res_init.c: Likewise.
* resolv/res_mkquery.c: Likewise.
* resolv/res_query.c: Likewise.
* resolv/res_send.c: Likewise.
* resolv/resolv.h: Likewise.

* resolv/Versions: Add __res_state and __res_ninit with version
GLIBC_2.2 to libc.
Add new interfaces with version GLIBC_2.2 to libresolv.

* resolv/Banner: Update.

* include/arpa/nameser_compat.h: New file.

* resolv/ns_name.c: New file from Bind 8.2.2-P5.
* resolv/ns_netint.c: Likewise.
* resolv/ns_parse.c: Likewise.
* resolv/ns_print.c: Likewise.
* resolv/ns_samedomain.c: Likewise.
* resolv/ns_ttl.c: Likewise.
* resolv/arpa/nameser_compat.h: Likewise.
* resolv/res_debug.h: Likewise.

Some patches are based on work done by Adam D. Bradley
<artdodge@cs.bu.edu>.

* sysdeps/unix/sysv/linux/configure.in: Remove check for ldconfig,
set always use_ldconfig instead.

42 files changed:
ChangeLog
Makefile
Versions.def
configure
include/arpa/nameser_compat.h [new file with mode: 0644]
include/resolv.h
linuxthreads/ChangeLog
linuxthreads/Versions
linuxthreads/errno.c
linuxthreads/internals.h
linuxthreads/manager.c
linuxthreads/pthread.c
locale/lc-time.c
nss/getXXbyYY.c
nss/getXXbyYY_r.c
resolv/Banner
resolv/Makefile
resolv/Versions
resolv/arpa/nameser.h
resolv/arpa/nameser_compat.h [new file with mode: 0644]
resolv/gethnamaddr.c
resolv/ns_name.c [new file with mode: 0644]
resolv/ns_netint.c [new file with mode: 0644]
resolv/ns_parse.c [new file with mode: 0644]
resolv/ns_print.c [new file with mode: 0644]
resolv/ns_samedomain.c [new file with mode: 0644]
resolv/ns_ttl.c [new file with mode: 0644]
resolv/nsap_addr.c
resolv/nss_dns/dns-host.c
resolv/nss_dns/dns-network.c
resolv/res_comp.c
resolv/res_data.c
resolv/res_debug.c
resolv/res_debug.h [new file with mode: 0644]
resolv/res_init.c
resolv/res_libc.c [new file with mode: 0644]
resolv/res_mkquery.c
resolv/res_query.c
resolv/res_send.c
resolv/resolv.h
sysdeps/unix/sysv/linux/configure
sysdeps/unix/sysv/linux/configure.in

index 1dd355f..6914e16 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,63 @@
+1999-12-03  Andreas Jaeger  <aj@suse.de>
+
+       * nss/getXXbyYY.c: Include <resolv.h>
+       (FUNCTION_NAME): Use res_ninit instead of res_init.
+
+       * nss/getXXbyYY_r.c [NEED__RES]: Include <resolv.h> for _res
+       declaration and prototypes.
+       Remove extra _res declaration.
+       (INTERNAL): Use thread aware res_ninit function.
+
+       * inet/gethstbyad_r.c: Include <resolv.h>.
+
+       * resolv/res_data.c: Update from Bind 8.2.2-P5.  Moved res_init to
+       res_libc.c.  Disabled unneeded functions.
+
+       * resolv/res_libc.c: New file.
+
+       * Versions.def: Add version GLIBC_2.2 for libpthread.
+       Add versions GLIBC_2.1 and GLIBC_2.2 for libresolv.
+
+       * include/resolv.h: Add internal interfaces.
+
+       * resolv/Makefile (routines): Add new files.
+       (libresolv-routines): Likewise.
+       (distribute): Likewise.
+
+       * resolv/gethnamaddr.c: Use thread safe resolver functions.
+       * resolv/nss_dns/dns-host.c: Likewise.
+       * resolv/nss_dns/dns-network.c: Likewise.
+
+       * resolv/arpa/nameser.h: Update from Bind 8.2.2-P5.
+       * resolv/nsap_addr.c: Likewise.
+       * resolv/res_comp.c: Likewise.
+       * resolv/res_debug.c: Likewise.
+       * resolv/res_init.c: Likewise.
+       * resolv/res_mkquery.c: Likewise.
+       * resolv/res_query.c: Likewise.
+       * resolv/res_send.c: Likewise.
+       * resolv/resolv.h: Likewise.
+
+       * resolv/Versions: Add __res_state and __res_ninit with version
+       GLIBC_2.2 to libc.
+       Add new interfaces with version GLIBC_2.2 to libresolv.
+
+       * resolv/Banner: Update.
+
+       * include/arpa/nameser_compat.h: New file.
+
+       * resolv/ns_name.c: New file from Bind 8.2.2-P5.
+       * resolv/ns_netint.c: Likewise.
+       * resolv/ns_parse.c: Likewise.
+       * resolv/ns_print.c: Likewise.
+       * resolv/ns_samedomain.c: Likewise.
+       * resolv/ns_ttl.c: Likewise.
+       * resolv/arpa/nameser_compat.h: Likewise.
+       * resolv/res_debug.h: Likewise.
+
+       Some patches are based on work done by Adam D. Bradley
+       <artdodge@cs.bu.edu>.
+
 1999-11-30  Andreas Jaeger  <aj@suse.de>
 
        Add ldconfig:
@@ -25,6 +85,9 @@
        * config.make.in (has-ldconfig): Renamed to use-ldconfig, changed
        comment.
 
+       * sysdeps/unix/sysv/linux/configure.in: Remove check for ldconfig,
+       set always use_ldconfig instead.
+
 1999-12-03  Ulrich Drepper  <drepper@cygnus.com>
 
        * sysdeps/generic/bits/stropts.h: Update with LiS types and
index 1c9378e..de85078 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -94,7 +94,7 @@ $(inst_slibdir)/libc-$(version).so: elf/ldso_install
 elf/ldso_install:
        $(MAKE) -C $(@D) $(@F)
 
-# Create links for shared libraries using the `ldconfig' program is possible.
+# Create links for shared libraries using the `ldconfig' program if possible.
 # Ignore the error if we cannot update /etc/ld.so.cache.
 ifeq (no,$(cross-compiling))
 ifeq (yes,$(build-shared))
@@ -106,7 +106,7 @@ install-symbolic-link: subdir_install
 
 install:
        -test ! -x $(common-objpfx)elf/ldconfig || \
-         $(common-objpfx)elf/ldconfig -d $(inst_slibdir) $(inst_libdir)
+         $(common-objpfx)elf/ldconfig $(inst_slibdir) $(inst_libdir)
 ifneq (no,$(PERL))
 ifeq (/usr,$(prefix))
 ifeq (,$(install_root))
index 0a34a50..90b4e7e 100644 (file)
@@ -66,9 +66,12 @@ libpthread {
   GLIBC_2.1
   GLIBC_2.1.1
   GLIBC_2.1.2
+  GLIBC_2.2
 }
 libresolv {
   GLIBC_2.0
+  GLIBC_2.1
+  GLIBC_2.2
 }
 librt {
   GLIBC_2.1
index e4fb67e..eace3ba 100755 (executable)
--- a/configure
+++ b/configure
@@ -12,7 +12,7 @@
 
 
 # Guess values for system-dependent variables and create Makefiles.
-# Generated automatically using autoconf version 2.13 
+# Generated automatically using autoconf version 2.14.1 
 # Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
 #
 # This configure script is free software; the Free Software Foundation
@@ -394,7 +394,7 @@ EOF
     verbose=yes ;;
 
   -version | --version | --versio | --versi | --vers)
-    echo "configure generated by autoconf version 2.13"
+    echo "configure generated by autoconf version 2.14.1"
     exit 0 ;;
 
   -with-* | --with-*)
@@ -554,7 +554,7 @@ done
 
 if test -r "$cache_file"; then
   echo "loading cache $cache_file"
-  . $cache_file
+      test -f "$cache_file" && . $cache_file
 else
   echo "creating cache $cache_file"
   > $cache_file
@@ -606,9 +606,9 @@ done
 if test -z "$ac_aux_dir"; then
   { echo "configure: error: can not find install-sh or install.sh in scripts $srcdir/scripts" 1>&2; exit 1; }
 fi
-ac_config_guess=$ac_aux_dir/config.guess
-ac_config_sub=$ac_aux_dir/config.sub
-ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
+ac_config_guess="$SHELL $ac_aux_dir/config.guess"
+ac_config_sub="$SHELL $ac_aux_dir/config.sub"
+ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure.
 
 
 # This will get text that should go into config.make.
@@ -859,31 +859,45 @@ else
 fi
 
 
+echo $ac_n "checking host system type""... $ac_c" 1>&6
+echo "configure:864: checking host system type" >&5
+if test "x$ac_cv_host" = "x" || (test "x$host" != "xNONE" && test "x$host" != "x$ac_cv_host_alias"); then
+
 # Make sure we can run config.sub.
-if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then :
-else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
+  if $ac_config_sub sun4 >/dev/null 2>&1; then :
+    else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
+  fi
+
+  ac_cv_host_alias=$host
+  case "$ac_cv_host_alias" in
+  NONE)
+    case $nonopt in
+    NONE)
+      if ac_cv_host_alias=`$ac_config_guess`; then :
+      else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; }
+      fi ;;
+    *) ac_cv_host_alias=$nonopt ;;
+    esac ;;
+  esac
+
+  ac_cv_host=`$ac_config_sub $ac_cv_host_alias`
+  ac_cv_host_cpu=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+  ac_cv_host_vendor=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+  ac_cv_host_os=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+else
+  echo $ac_n "(cached) $ac_c" 1>&6
 fi
 
-echo $ac_n "checking host system type""... $ac_c" 1>&6
-echo "configure:869: checking host system type" >&5
+echo "$ac_t""$ac_cv_host" 1>&6
+
+host=$ac_cv_host
+host_alias=$ac_cv_host_alias
+host_cpu=$ac_cv_host_cpu
+host_vendor=$ac_cv_host_vendor
+host_os=$ac_cv_host_os
+
 
-host_alias=$host
-case "$host_alias" in
-NONE)
-  case $nonopt in
-  NONE)
-    if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then :
-    else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; }
-    fi ;;
-  *) host_alias=$nonopt ;;
-  esac ;;
-esac
 
-host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias`
-host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
-host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
-host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
-echo "$ac_t""$host" 1>&6
 
 
 # The way shlib-versions is used to generate soversions.mk uses a
@@ -990,7 +1004,7 @@ fi
 # This can take a while to compute.
 sysdep_dir=$srcdir/sysdeps
 echo $ac_n "checking sysdep dirs""... $ac_c" 1>&6
-echo "configure:994: checking sysdep dirs" >&5
+echo "configure:1008: checking sysdep dirs" >&5
 # Make sco3.2v4 become sco3.2.4 and sunos4.1.1_U1 become sunos4.1.1.U1.
 os="`echo $os | sed 's/\([0-9A-Z]\)[v_]\([0-9A-Z]\)/\1.\2/g'`"
 
@@ -1196,9 +1210,9 @@ echo "$ac_t""$default_sysnames" 1>&6
 # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
 # ./install, which can be erroneously created by make from ./install.sh.
 echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
-echo "configure:1200: checking for a BSD compatible install" >&5
+echo "configure:1214: checking for a BSD compatible install" >&5
 if test -z "$INSTALL"; then
-if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
+if eval "test \"\${ac_cv_path_install+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
     IFS="${IFS=        }"; ac_save_IFS="$IFS"; IFS=":"
@@ -1216,6 +1230,10 @@ else
             grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
            # AIX install.  It has an incompatible calling convention.
            :
+         elif test $ac_prog = install &&
+           grep pwplus $ac_dir/$ac_prog >/dev/null 2>&1; then
+           # program-specific install script used by HP pwplus--don't use.
+           :
          else
            ac_cv_path_install="$ac_dir/$ac_prog -c"
            break 2
@@ -1244,7 +1262,7 @@ echo "$ac_t""$INSTALL" 1>&6
 # It thinks the first close brace ends the variable substitution.
 test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
 
-test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
 
 test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
 
@@ -1253,8 +1271,8 @@ if test "$INSTALL" = "${srcdir}/scripts/install-sh -c"; then
   INSTALL='\$(..)./scripts/install-sh -c'
 fi
 echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6
-echo "configure:1257: checking whether ln -s works" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_LN_S'+set}'`\" = set"; then
+echo "configure:1275: checking whether ln -s works" >&5
+if eval "test \"\${ac_cv_prog_LN_S+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   rm -f conftestdata
@@ -1275,23 +1293,45 @@ fi
 
 
 # These programs are version sensitive.
+
 echo $ac_n "checking build system type""... $ac_c" 1>&6
-echo "configure:1280: checking build system type" >&5
-
-build_alias=$build
-case "$build_alias" in
-NONE)
-  case $nonopt in
-  NONE) build_alias=$host_alias ;;
-  *) build_alias=$nonopt ;;
-  esac ;;
-esac
+echo "configure:1299: checking build system type" >&5
+if test "x$ac_cv_build" = "x" || (test "x$build" != "xNONE" && test "x$build" != "x$ac_cv_build_alias"); then
+
+# Make sure we can run config.sub.
+  if $ac_config_sub sun4 >/dev/null 2>&1; then :
+    else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
+  fi
+
+  ac_cv_build_alias=$build
+  case "$ac_cv_build_alias" in
+  NONE)
+    case $nonopt in
+    NONE)
+      ac_cv_build_alias=$host_alias ;;
+
+    *) ac_cv_build_alias=$nonopt ;;
+    esac ;;
+  esac
+
+  ac_cv_build=`$ac_config_sub $ac_cv_build_alias`
+  ac_cv_build_cpu=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+  ac_cv_build_vendor=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+  ac_cv_build_os=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+else
+  echo $ac_n "(cached) $ac_c" 1>&6
+fi
+
+echo "$ac_t""$ac_cv_build" 1>&6
+
+build=$ac_cv_build
+build_alias=$ac_cv_build_alias
+build_cpu=$ac_cv_build_cpu
+build_vendor=$ac_cv_build_vendor
+build_os=$ac_cv_build_os
+
+
 
-build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias`
-build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
-build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
-build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
-echo "$ac_t""$build" 1>&6
 
 if test $host != $build; then
   ac_tool_prefix=${host_alias}-
@@ -1304,8 +1344,8 @@ do
 # Extract the first word of "$ac_prog", so it can be a program name with args.
 set dummy $ac_prog; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1308: checking for $ac_word" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+echo "configure:1348: checking for $ac_word" >&5
+if eval "test \"\${ac_cv_prog_CC+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   if test -n "$CC"; then
@@ -1338,7 +1378,7 @@ if test -z "$CC"; then
 else
   # Found it, now check the version.
   echo $ac_n "checking version of $CC""... $ac_c" 1>&6
-echo "configure:1342: checking version of $CC" >&5
+echo "configure:1382: checking version of $CC" >&5
   ac_prog_version=`$CC -v 2>&1 | sed -n 's/^.*version \([egcygnustp-]*[0-9.]*\).*$/\1/p'`
   case $ac_prog_version in
     '') ac_prog_version="v. ?.??, bad"; ac_verc_fail=yes;;
@@ -1358,8 +1398,8 @@ do
 # Extract the first word of "$ac_prog", so it can be a program name with args.
 set dummy $ac_prog; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1362: checking for $ac_word" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_MAKE'+set}'`\" = set"; then
+echo "configure:1402: checking for $ac_word" >&5
+if eval "test \"\${ac_cv_prog_MAKE+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   if test -n "$MAKE"; then
@@ -1392,7 +1432,7 @@ if test -z "$MAKE"; then
 else
   # Found it, now check the version.
   echo $ac_n "checking version of $MAKE""... $ac_c" 1>&6
-echo "configure:1396: checking version of $MAKE" >&5
+echo "configure:1436: checking version of $MAKE" >&5
   ac_prog_version=`$MAKE --version 2>&1 | sed -n 's/^.*GNU Make[^0-9]*\([0-9][0-9.]*\).*$/\1/p'`
   case $ac_prog_version in
     '') ac_prog_version="v. ?.??, bad"; ac_verc_fail=yes;;
@@ -1413,8 +1453,8 @@ do
 # Extract the first word of "$ac_prog", so it can be a program name with args.
 set dummy $ac_prog; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1417: checking for $ac_word" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_MSGFMT'+set}'`\" = set"; then
+echo "configure:1457: checking for $ac_word" >&5
+if eval "test \"\${ac_cv_prog_MSGFMT+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   if test -n "$MSGFMT"; then
@@ -1447,7 +1487,7 @@ if test -z "$MSGFMT"; then
 else
   # Found it, now check the version.
   echo $ac_n "checking version of $MSGFMT""... $ac_c" 1>&6
-echo "configure:1451: checking version of $MSGFMT" >&5
+echo "configure:1491: checking version of $MSGFMT" >&5
   ac_prog_version=`$MSGFMT --version 2>&1 | sed -n 's/^.*GNU gettext.* \([0-9]*\.[0-9.]*\).*$/\1/p'`
   case $ac_prog_version in
     '') ac_prog_version="v. ?.??, bad"; ac_verc_fail=yes;;
@@ -1467,8 +1507,8 @@ do
 # Extract the first word of "$ac_prog", so it can be a program name with args.
 set dummy $ac_prog; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1471: checking for $ac_word" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_MAKEINFO'+set}'`\" = set"; then
+echo "configure:1511: checking for $ac_word" >&5
+if eval "test \"\${ac_cv_prog_MAKEINFO+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   if test -n "$MAKEINFO"; then
@@ -1501,7 +1541,7 @@ if test -z "$MAKEINFO"; then
 else
   # Found it, now check the version.
   echo $ac_n "checking version of $MAKEINFO""... $ac_c" 1>&6
-echo "configure:1505: checking version of $MAKEINFO" >&5
+echo "configure:1545: checking version of $MAKEINFO" >&5
   ac_prog_version=`$MAKEINFO --version 2>&1 | sed -n 's/^.*GNU texinfo.* \([0-9][0-9.]*\).*$/\1/p'`
   case $ac_prog_version in
     '') ac_prog_version="v. ?.??, bad"; ac_verc_fail=yes;;
@@ -1534,8 +1574,8 @@ CCVERSION=`$CC -v 2>&1 | sed -n 's/gcc version //p'`
 
 
 echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
-echo "configure:1538: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_cc_works'+set}'`\" = set"; then
+echo "configure:1578: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+if eval "test \"\${ac_cv_prog_cc_works+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   
@@ -1548,12 +1588,12 @@ cross_compiling=$ac_cv_prog_cc_cross
 
 cat > conftest.$ac_ext << EOF
 
-#line 1552 "configure"
+#line 1592 "configure"
 #include "confdefs.h"
 
 main(){return(0);}
 EOF
-if { (eval echo configure:1557: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1597: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   ac_cv_prog_cc_works=yes
   # If we can't run a trivial program, we are probably using a cross compiler.
   if (./conftest; exit) 2>/dev/null; then
@@ -1584,8 +1624,8 @@ else
  cross_linkable=yes
 fi
 echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
-echo "configure:1588: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_cc_cross'+set}'`\" = set"; then
+echo "configure:1628: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+if eval "test \"\${ac_cv_prog_cc_cross+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   :
@@ -1596,8 +1636,8 @@ echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
 cross_compiling=$ac_cv_prog_cc_cross
 
 echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
-echo "configure:1600: checking whether we are using GNU C" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
+echo "configure:1640: checking whether we are using GNU C" >&5
+if eval "test \"\${ac_cv_prog_gcc+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.c <<EOF
@@ -1605,7 +1645,7 @@ else
   yes;
 #endif
 EOF
-if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1609: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1649: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
   ac_cv_prog_gcc=yes
 else
   ac_cv_prog_gcc=no
@@ -1617,23 +1657,45 @@ if test $ac_cv_prog_gcc != yes; then
   { echo "configure: error: GNU libc must be compiled using GNU CC" 1>&2; exit 1; }
 fi
 
+
 echo $ac_n "checking build system type""... $ac_c" 1>&6
-echo "configure:1622: checking build system type" >&5
-
-build_alias=$build
-case "$build_alias" in
-NONE)
-  case $nonopt in
-  NONE) build_alias=$host_alias ;;
-  *) build_alias=$nonopt ;;
-  esac ;;
-esac
+echo "configure:1663: checking build system type" >&5
+if test "x$ac_cv_build" = "x" || (test "x$build" != "xNONE" && test "x$build" != "x$ac_cv_build_alias"); then
+
+# Make sure we can run config.sub.
+  if $ac_config_sub sun4 >/dev/null 2>&1; then :
+    else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
+  fi
+
+  ac_cv_build_alias=$build
+  case "$ac_cv_build_alias" in
+  NONE)
+    case $nonopt in
+    NONE)
+      ac_cv_build_alias=$host_alias ;;
+
+    *) ac_cv_build_alias=$nonopt ;;
+    esac ;;
+  esac
+
+  ac_cv_build=`$ac_config_sub $ac_cv_build_alias`
+  ac_cv_build_cpu=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+  ac_cv_build_vendor=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+  ac_cv_build_os=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+else
+  echo $ac_n "(cached) $ac_c" 1>&6
+fi
+
+echo "$ac_t""$ac_cv_build" 1>&6
+
+build=$ac_cv_build
+build_alias=$ac_cv_build_alias
+build_cpu=$ac_cv_build_cpu
+build_vendor=$ac_cv_build_vendor
+build_os=$ac_cv_build_os
+
+
 
-build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias`
-build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
-build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
-build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
-echo "$ac_t""$build" 1>&6
 
 if test $host != $build; then
   for ac_prog in gcc cc
@@ -1641,8 +1703,8 @@ do
 # Extract the first word of "$ac_prog", so it can be a program name with args.
 set dummy $ac_prog; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1645: checking for $ac_word" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_BUILD_CC'+set}'`\" = set"; then
+echo "configure:1707: checking for $ac_word" >&5
+if eval "test \"\${ac_cv_prog_BUILD_CC+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   if test -n "$BUILD_CC"; then
@@ -1673,13 +1735,13 @@ done
 fi
 
 echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
-echo "configure:1677: checking how to run the C preprocessor" >&5
+echo "configure:1739: checking how to run the C preprocessor" >&5
 # On Suns, sometimes $CPP names a directory.
 if test -n "$CPP" && test -d "$CPP"; then
   CPP=
 fi
 if test -z "$CPP"; then
-if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then
+if eval "test \"\${ac_cv_prog_CPP+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
     # This must be in double quotes, not single quotes, because CPP may get
@@ -1688,13 +1750,13 @@ else
   # On the NeXT, cc -E runs the code through the compiler's parser,
   # not just through cpp.
   cat > conftest.$ac_ext <<EOF
-#line 1692 "configure"
+#line 1754 "configure"
 #include "confdefs.h"
 #include <assert.h>
 Syntax Error
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1698: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1760: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   :
@@ -1705,13 +1767,13 @@ else
   rm -rf conftest*
   CPP="${CC-cc} -E -traditional-cpp"
   cat > conftest.$ac_ext <<EOF
-#line 1709 "configure"
+#line 1771 "configure"
 #include "confdefs.h"
 #include <assert.h>
 Syntax Error
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1715: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1777: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   :
@@ -1722,13 +1784,13 @@ else
   rm -rf conftest*
   CPP="${CC-cc} -nologo -E"
   cat > conftest.$ac_ext <<EOF
-#line 1726 "configure"
+#line 1788 "configure"
 #include "confdefs.h"
 #include <assert.h>
 Syntax Error
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1732: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1794: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   :
@@ -1771,8 +1833,8 @@ if test $RANLIB = ranlib; then
 # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
 set dummy ${ac_tool_prefix}ranlib; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1775: checking for $ac_word" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
+echo "configure:1837: checking for $ac_word" >&5
+if eval "test \"\${ac_cv_prog_RANLIB+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   if test -n "$RANLIB"; then
@@ -1803,8 +1865,8 @@ if test -n "$ac_tool_prefix"; then
   # Extract the first word of "ranlib", so it can be a program name with args.
 set dummy ranlib; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1807: checking for $ac_word" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
+echo "configure:1869: checking for $ac_word" >&5
+if eval "test \"\${ac_cv_prog_RANLIB+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   if test -n "$RANLIB"; then
@@ -1840,8 +1902,8 @@ fi
 
 # Determine whether we are using GNU binutils.
 echo $ac_n "checking whether $AS is GNU as""... $ac_c" 1>&6
-echo "configure:1844: checking whether $AS is GNU as" >&5
-if eval "test \"`echo '$''{'libc_cv_prog_as_gnu'+set}'`\" = set"; then
+echo "configure:1906: checking whether $AS is GNU as" >&5
+if eval "test \"\${libc_cv_prog_as_gnu+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   # Most GNU programs take a -v and spit out some text including
@@ -1859,8 +1921,8 @@ rm -f a.out
 gnu_as=$libc_cv_prog_as_gnu
 
 echo $ac_n "checking whether $LD is GNU ld""... $ac_c" 1>&6
-echo "configure:1863: checking whether $LD is GNU ld" >&5
-if eval "test \"`echo '$''{'libc_cv_prog_ld_gnu'+set}'`\" = set"; then
+echo "configure:1925: checking whether $LD is GNU ld" >&5
+if eval "test \"\${libc_cv_prog_ld_gnu+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   # Most GNU programs take a -v and spit out some text including
@@ -1879,8 +1941,8 @@ gnu_ld=$libc_cv_prog_ld_gnu
 # Extract the first word of "${ac_tool_prefix}mig", so it can be a program name with args.
 set dummy ${ac_tool_prefix}mig; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1883: checking for $ac_word" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_MIG'+set}'`\" = set"; then
+echo "configure:1945: checking for $ac_word" >&5
+if eval "test \"\${ac_cv_prog_MIG+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   if test -n "$MIG"; then
@@ -1920,8 +1982,8 @@ fi
 
 # check if ranlib is necessary
 echo $ac_n "checking whether ranlib is necessary""... $ac_c" 1>&6
-echo "configure:1924: checking whether ranlib is necessary" >&5
-if eval "test \"`echo '$''{'libc_cv_ranlib_necessary'+set}'`\" = set"; then
+echo "configure:1986: checking whether ranlib is necessary" >&5
+if eval "test \"\${libc_cv_ranlib_necessary+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.c <<EOF
@@ -1954,7 +2016,7 @@ fi
 # - two terminals occur directly after each other
 # - the path contains an element with a dot in it
 echo $ac_n "checking LD_LIBRARY_PATH variable""... $ac_c" 1>&6
-echo "configure:1958: checking LD_LIBRARY_PATH variable" >&5
+echo "configure:2020: checking LD_LIBRARY_PATH variable" >&5
 case ${LD_LIBRARY_PATH} in
   [:\;]* | *[:\;] | *[:\;][:\;]* |  *[:\;]. | .[:\;]*| . | *[:\;].[:\;]* )
     ld_library_path_setting="contains current directory"
@@ -1974,8 +2036,8 @@ fi
 # Extract the first word of "bash", so it can be a program name with args.
 set dummy bash; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1978: checking for $ac_word" >&5
-if eval "test \"`echo '$''{'ac_cv_path_BASH'+set}'`\" = set"; then
+echo "configure:2040: checking for $ac_word" >&5
+if eval "test \"\${ac_cv_path_BASH+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   case "$BASH" in
@@ -2020,8 +2082,8 @@ if test "$BASH" = no; then
   # Extract the first word of "ksh", so it can be a program name with args.
 set dummy ksh; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:2024: checking for $ac_word" >&5
-if eval "test \"`echo '$''{'ac_cv_path_KSH'+set}'`\" = set"; then
+echo "configure:2086: checking for $ac_word" >&5
+if eval "test \"\${ac_cv_path_KSH+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   case "$KSH" in
@@ -2070,8 +2132,8 @@ do
 # Extract the first word of "$ac_prog", so it can be a program name with args.
 set dummy $ac_prog; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:2074: checking for $ac_word" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_AWK'+set}'`\" = set"; then
+echo "configure:2136: checking for $ac_word" >&5
+if eval "test \"\${ac_cv_prog_AWK+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   if test -n "$AWK"; then
@@ -2102,8 +2164,8 @@ done
 # Extract the first word of "perl", so it can be a program name with args.
 set dummy perl; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:2106: checking for $ac_word" >&5
-if eval "test \"`echo '$''{'ac_cv_path_PERL'+set}'`\" = set"; then
+echo "configure:2168: checking for $ac_word" >&5
+if eval "test \"\${ac_cv_path_PERL+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   case "$PERL" in
@@ -2139,8 +2201,8 @@ fi
 # Extract the first word of "install-info", so it can be a program name with args.
 set dummy install-info; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:2143: checking for $ac_word" >&5
-if eval "test \"`echo '$''{'ac_cv_path_INSTALL_INFO'+set}'`\" = set"; then
+echo "configure:2205: checking for $ac_word" >&5
+if eval "test \"\${ac_cv_path_INSTALL_INFO+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   case "$INSTALL_INFO" in
@@ -2175,8 +2237,8 @@ fi
 
 if test "$INSTALL_INFO" != "no"; then
 echo $ac_n "checking for old Debian install-info""... $ac_c" 1>&6
-echo "configure:2179: checking for old Debian install-info" >&5
-if eval "test \"`echo '$''{'libc_cv_old_debian_install_info'+set}'`\" = set"; then
+echo "configure:2241: checking for old Debian install-info" >&5
+if eval "test \"\${libc_cv_old_debian_install_info+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   mkdir conftest.d
@@ -2208,8 +2270,8 @@ fi
 
 
 echo $ac_n "checking for signed size_t type""... $ac_c" 1>&6
-echo "configure:2212: checking for signed size_t type" >&5
-if eval "test \"`echo '$''{'libc_cv_signed_size_t'+set}'`\" = set"; then
+echo "configure:2274: checking for signed size_t type" >&5
+if eval "test \"\${libc_cv_signed_size_t+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   echo '#include <stddef.h>
@@ -2232,12 +2294,12 @@ EOF
 fi
 
 echo $ac_n "checking for libc-friendly stddef.h""... $ac_c" 1>&6
-echo "configure:2236: checking for libc-friendly stddef.h" >&5
-if eval "test \"`echo '$''{'libc_cv_friendly_stddef'+set}'`\" = set"; then
+echo "configure:2298: checking for libc-friendly stddef.h" >&5
+if eval "test \"\${libc_cv_friendly_stddef+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2241 "configure"
+#line 2303 "configure"
 #include "confdefs.h"
 #define __need_size_t
 #define __need_wchar_t
@@ -2252,7 +2314,7 @@ size_t size; wchar_t wchar;
 if (&size == NULL || &wchar == NULL) abort ();
 ; return 0; }
 EOF
-if { (eval echo configure:2256: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:2318: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   libc_cv_friendly_stddef=yes
 else
@@ -2271,8 +2333,8 @@ override stddef.h = # The installed <stddef.h> seems to be libc-friendly."
 fi
 
 echo $ac_n "checking whether we need to use -P to assemble .S files""... $ac_c" 1>&6
-echo "configure:2275: checking whether we need to use -P to assemble .S files" >&5
-if eval "test \"`echo '$''{'libc_cv_need_minus_P'+set}'`\" = set"; then
+echo "configure:2337: checking whether we need to use -P to assemble .S files" >&5
+if eval "test \"\${libc_cv_need_minus_P+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.S <<EOF
@@ -2294,8 +2356,8 @@ asm-CPPFLAGS = -P # The assembler can't grok cpp's # line directives."
 fi
 
 echo $ac_n "checking whether .text pseudo-op must be used""... $ac_c" 1>&6
-echo "configure:2298: checking whether .text pseudo-op must be used" >&5
-if eval "test \"`echo '$''{'libc_cv_dot_text'+set}'`\" = set"; then
+echo "configure:2360: checking whether .text pseudo-op must be used" >&5
+if eval "test \"\${libc_cv_dot_text+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.s <<EOF
@@ -2315,8 +2377,8 @@ else
 fi
 
 echo $ac_n "checking for assembler global-symbol directive""... $ac_c" 1>&6
-echo "configure:2319: checking for assembler global-symbol directive" >&5
-if eval "test \"`echo '$''{'libc_cv_asm_global_directive'+set}'`\" = set"; then
+echo "configure:2381: checking for assembler global-symbol directive" >&5
+if eval "test \"\${libc_cv_asm_global_directive+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   libc_cv_asm_global_directive=UNKNOWN
@@ -2345,8 +2407,8 @@ EOF
 fi
 
 echo $ac_n "checking for .set assembler directive""... $ac_c" 1>&6
-echo "configure:2349: checking for .set assembler directive" >&5
-if eval "test \"`echo '$''{'libc_cv_asm_set_directive'+set}'`\" = set"; then
+echo "configure:2411: checking for .set assembler directive" >&5
+if eval "test \"\${libc_cv_asm_set_directive+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.s <<EOF
@@ -2379,8 +2441,8 @@ EOF
 fi
 
 echo $ac_n "checking for .symver assembler directive""... $ac_c" 1>&6
-echo "configure:2383: checking for .symver assembler directive" >&5
-if eval "test \"`echo '$''{'libc_cv_asm_symver_directive'+set}'`\" = set"; then
+echo "configure:2445: checking for .symver assembler directive" >&5
+if eval "test \"\${libc_cv_asm_symver_directive+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.s <<EOF
@@ -2398,8 +2460,8 @@ fi
 
 echo "$ac_t""$libc_cv_asm_symver_directive" 1>&6
 echo $ac_n "checking for ld --version-script""... $ac_c" 1>&6
-echo "configure:2402: checking for ld --version-script" >&5
-if eval "test \"`echo '$''{'libc_cv_ld_version_script_option'+set}'`\" = set"; then
+echo "configure:2464: checking for ld --version-script" >&5
+if eval "test \"\${libc_cv_ld_version_script_option+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   if test $libc_cv_asm_symver_directive = yes; then
@@ -2421,7 +2483,7 @@ EOF
     if { ac_try='${CC-cc} $CFLAGS -shared -o conftest.so conftest.o
                                        -nostartfiles -nostdlib
                                        -Wl,--version-script,conftest.map
-                      1>&5'; { (eval echo configure:2425: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; };
+                      1>&5'; { (eval echo configure:2487: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; };
     then
       libc_cv_ld_version_script_option=yes
     else
@@ -2459,15 +2521,15 @@ if test $VERSIONING = no; then
 fi
 if test $elf = yes; then
   echo $ac_n "checking for .previous assembler directive""... $ac_c" 1>&6
-echo "configure:2463: checking for .previous assembler directive" >&5
-if eval "test \"`echo '$''{'libc_cv_asm_previous_directive'+set}'`\" = set"; then
+echo "configure:2525: checking for .previous assembler directive" >&5
+if eval "test \"\${libc_cv_asm_previous_directive+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
     cat > conftest.s <<EOF
 .section foo_section
 .previous
 EOF
-  if { ac_try='${CC-cc} -c $CFLAGS conftest.s 1>&5'; { (eval echo configure:2471: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
+  if { ac_try='${CC-cc} -c $CFLAGS conftest.s 1>&5'; { (eval echo configure:2533: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
     libc_cv_asm_previous_directive=yes
   else
     libc_cv_asm_previous_directive=no
@@ -2483,15 +2545,15 @@ EOF
 
   else
     echo $ac_n "checking for .popsection assembler directive""... $ac_c" 1>&6
-echo "configure:2487: checking for .popsection assembler directive" >&5
-if eval "test \"`echo '$''{'libc_cv_asm_popsection_directive'+set}'`\" = set"; then
+echo "configure:2549: checking for .popsection assembler directive" >&5
+if eval "test \"\${libc_cv_asm_popsection_directive+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
       cat > conftest.s <<EOF
 .pushsection foo_section
 .popsection
 EOF
-    if { ac_try='${CC-cc} -c $CFLAGS conftest.s 1>&5'; { (eval echo configure:2495: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
+    if { ac_try='${CC-cc} -c $CFLAGS conftest.s 1>&5'; { (eval echo configure:2557: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
       libc_cv_asm_popsection_directive=yes
     else
       libc_cv_asm_popsection_directive=no
@@ -2511,12 +2573,12 @@ fi
 
 if test $elf != yes; then
   echo $ac_n "checking for .init and .fini sections""... $ac_c" 1>&6
-echo "configure:2515: checking for .init and .fini sections" >&5
-if eval "test \"`echo '$''{'libc_cv_have_initfini'+set}'`\" = set"; then
+echo "configure:2577: checking for .init and .fini sections" >&5
+if eval "test \"\${libc_cv_have_initfini+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2520 "configure"
+#line 2582 "configure"
 #include "confdefs.h"
 
 int main() {
@@ -2525,7 +2587,7 @@ asm (".section .init");
                                    asm ("${libc_cv_dot_text}");
 ; return 0; }
 EOF
-if { (eval echo configure:2529: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:2591: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   libc_cv_have_initfini=yes
 else
@@ -2553,19 +2615,19 @@ if test $elf = yes; then
 else
   if test $ac_cv_prog_cc_works = yes; then
     echo $ac_n "checking for _ prefix on C symbol names""... $ac_c" 1>&6
-echo "configure:2557: checking for _ prefix on C symbol names" >&5
-if eval "test \"`echo '$''{'libc_cv_asm_underscores'+set}'`\" = set"; then
+echo "configure:2619: checking for _ prefix on C symbol names" >&5
+if eval "test \"\${libc_cv_asm_underscores+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2562 "configure"
+#line 2624 "configure"
 #include "confdefs.h"
 asm ("_glibc_foobar:");
 int main() {
 glibc_foobar ();
 ; return 0; }
 EOF
-if { (eval echo configure:2569: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2631: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   libc_cv_asm_underscores=yes
 else
@@ -2580,17 +2642,17 @@ fi
 echo "$ac_t""$libc_cv_asm_underscores" 1>&6
   else
     echo $ac_n "checking for _ prefix on C symbol names""... $ac_c" 1>&6
-echo "configure:2584: checking for _ prefix on C symbol names" >&5
-if eval "test \"`echo '$''{'libc_cv_asm_underscores'+set}'`\" = set"; then
+echo "configure:2646: checking for _ prefix on C symbol names" >&5
+if eval "test \"\${libc_cv_asm_underscores+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2589 "configure"
+#line 2651 "configure"
 #include "confdefs.h"
 void underscore_test(void) {
 return; }
 EOF
-if { (eval echo configure:2594: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:2656: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   if grep _underscore_test conftest* >/dev/null; then
     rm -f conftest*
     libc_cv_asm_underscores=yes
@@ -2622,8 +2684,8 @@ if test $elf = yes; then
 fi
 
 echo $ac_n "checking for assembler .weak directive""... $ac_c" 1>&6
-echo "configure:2626: checking for assembler .weak directive" >&5
-if eval "test \"`echo '$''{'libc_cv_asm_weak_directive'+set}'`\" = set"; then
+echo "configure:2688: checking for assembler .weak directive" >&5
+if eval "test \"\${libc_cv_asm_weak_directive+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.s <<EOF
@@ -2645,8 +2707,8 @@ echo "$ac_t""$libc_cv_asm_weak_directive" 1>&6
 
 if test $libc_cv_asm_weak_directive = no; then
   echo $ac_n "checking for assembler .weakext directive""... $ac_c" 1>&6
-echo "configure:2649: checking for assembler .weakext directive" >&5
-if eval "test \"`echo '$''{'libc_cv_asm_weakext_directive'+set}'`\" = set"; then
+echo "configure:2711: checking for assembler .weakext directive" >&5
+if eval "test \"\${libc_cv_asm_weakext_directive+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.s <<EOF
@@ -2683,8 +2745,8 @@ EOF
 fi
 
 echo $ac_n "checking for ld --no-whole-archive""... $ac_c" 1>&6
-echo "configure:2687: checking for ld --no-whole-archive" >&5
-if eval "test \"`echo '$''{'libc_cv_ld_no_whole_archive'+set}'`\" = set"; then
+echo "configure:2749: checking for ld --no-whole-archive" >&5
+if eval "test \"\${libc_cv_ld_no_whole_archive+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.c <<\EOF
@@ -2694,7 +2756,7 @@ __throw () {}
 EOF
 if { ac_try='${CC-cc} $CFLAGS
                            -nostdlib -nostartfiles -Wl,--no-whole-archive
-                           -o conftest conftest.c 1>&5'; { (eval echo configure:2698: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
+                           -o conftest conftest.c 1>&5'; { (eval echo configure:2760: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
   libc_cv_ld_no_whole_archive=yes
 else
   libc_cv_ld_no_whole_archive=no
@@ -2708,8 +2770,8 @@ if test $libc_cv_ld_no_whole_archive = yes; then
 fi
 
 echo $ac_n "checking for gcc -fexceptions""... $ac_c" 1>&6
-echo "configure:2712: checking for gcc -fexceptions" >&5
-if eval "test \"`echo '$''{'libc_cv_gcc_exceptions'+set}'`\" = set"; then
+echo "configure:2774: checking for gcc -fexceptions" >&5
+if eval "test \"\${libc_cv_gcc_exceptions+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.c <<\EOF
@@ -2719,7 +2781,7 @@ __throw () {}
 EOF
 if { ac_try='${CC-cc} $CFLAGS
                            -nostdlib -nostartfiles -fexceptions
-                           -o conftest conftest.c 1>&5'; { (eval echo configure:2723: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
+                           -o conftest conftest.c 1>&5'; { (eval echo configure:2785: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
   libc_cv_gcc_exceptions=yes
 else
   libc_cv_gcc_exceptions=no
@@ -2734,14 +2796,14 @@ fi
 
 if test "$base_machine" = alpha ; then
 echo $ac_n "checking for function ..ng prefix""... $ac_c" 1>&6
-echo "configure:2738: checking for function ..ng prefix" >&5
-if eval "test \"`echo '$''{'libc_cv_gcc_alpha_ng_prefix'+set}'`\" = set"; then
+echo "configure:2800: checking for function ..ng prefix" >&5
+if eval "test \"\${libc_cv_gcc_alpha_ng_prefix+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.c <<\EOF
 foo () { }
 EOF
-if { ac_try='${CC-cc} -S conftest.c -o - | fgrep "\$foo..ng" > /dev/null'; { (eval echo configure:2745: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; };
+if { ac_try='${CC-cc} -S conftest.c -o - | fgrep "\$foo..ng" > /dev/null'; { (eval echo configure:2807: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; };
 then
   libc_cv_gcc_alpha_ng_prefix=yes
 else
@@ -2768,19 +2830,19 @@ if test "$host_cpu" = powerpc ; then
 # Check for a bug present in at least versions 2.8.x of GCC
 # and versions 1.0.x of EGCS.
 echo $ac_n "checking whether clobbering cr0 causes problems""... $ac_c" 1>&6
-echo "configure:2772: checking whether clobbering cr0 causes problems" >&5
-if eval "test \"`echo '$''{'libc_cv_c_asmcr0_bug'+set}'`\" = set"; then
+echo "configure:2834: checking whether clobbering cr0 causes problems" >&5
+if eval "test \"\${libc_cv_c_asmcr0_bug+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2777 "configure"
+#line 2839 "configure"
 #include "confdefs.h"
 int tester(int x) { asm ("" : : : "cc"); return x & 123; }
 int main() {
 
 ; return 0; }
 EOF
-if { (eval echo configure:2784: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:2846: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   libc_cv_c_asmcr0_bug='no'
 else
@@ -2802,12 +2864,12 @@ fi
 fi
 
 echo $ac_n "checking for DWARF2 unwind info support""... $ac_c" 1>&6
-echo "configure:2806: checking for DWARF2 unwind info support" >&5
-if eval "test \"`echo '$''{'libc_cv_gcc_dwarf2_unwind_info'+set}'`\" = set"; then
+echo "configure:2868: checking for DWARF2 unwind info support" >&5
+if eval "test \"\${libc_cv_gcc_dwarf2_unwind_info+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.c <<EOF
-#line 2811 "configure"
+#line 2873 "configure"
 static char __EH_FRAME_BEGIN__;
 _start ()
 {
@@ -2834,7 +2896,7 @@ __bzero () {}
 EOF
 if { ac_try='${CC-cc} $CFLAGS -DCHECK__register_frame_info
                            -nostdlib -nostartfiles
-                           -o conftest conftest.c -lgcc >&5'; { (eval echo configure:2838: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
+                           -o conftest conftest.c -lgcc >&5'; { (eval echo configure:2900: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
   libc_cv_gcc_dwarf2_unwind_info=static
 else
   libc_cv_gcc_dwarf2_unwind_info=no
@@ -2842,7 +2904,7 @@ fi
 if test $libc_cv_gcc_dwarf2_unwind_info = no; then
   if { ac_try='${CC-cc} $CFLAGS -DCHECK__register_frame
                              -nostdlib -nostartfiles
-                             -o conftest conftest.c -lgcc >&5'; { (eval echo configure:2846: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
+                             -o conftest conftest.c -lgcc >&5'; { (eval echo configure:2908: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
     libc_cv_gcc_dwarf2_unwind_info=yes
   else
     libc_cv_gcc_dwarf2_unwind_info=no
@@ -2872,12 +2934,12 @@ EOF
 esac
 
 echo $ac_n "checking for __builtin_expect""... $ac_c" 1>&6
-echo "configure:2876: checking for __builtin_expect" >&5
-if eval "test \"`echo '$''{'libc_cv_gcc_builtin_expect'+set}'`\" = set"; then
+echo "configure:2938: checking for __builtin_expect" >&5
+if eval "test \"\${libc_cv_gcc_builtin_expect+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.c <<EOF
-#line 2881 "configure"
+#line 2943 "configure"
 int foo (int a)
 {
   a = __builtin_expect (a, 10);
@@ -2885,7 +2947,7 @@ int foo (int a)
 }
 EOF
 if { ac_try='${CC-cc} $CFLAGS -nostdlib -nostartfiles
-                           -o conftest conftest.c -lgcc >&5'; { (eval echo configure:2889: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
+                           -o conftest conftest.c -lgcc >&5'; { (eval echo configure:2951: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
   libc_cv_gcc_builtin_expect=yes
 else
   libc_cv_gcc_builtin_expect=no
@@ -2902,12 +2964,12 @@ EOF
 fi
 
 echo $ac_n "checking for local label subtraction""... $ac_c" 1>&6
-echo "configure:2906: checking for local label subtraction" >&5
-if eval "test \"`echo '$''{'libc_cv_gcc_subtract_local_labels'+set}'`\" = set"; then
+echo "configure:2968: checking for local label subtraction" >&5
+if eval "test \"\${libc_cv_gcc_subtract_local_labels+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.c <<EOF
-#line 2911 "configure"
+#line 2973 "configure"
 int foo (int a)
 {
   static const int ar[] = { &&l1 - &&l1, &&l2 - &&l1 };
@@ -2920,7 +2982,7 @@ int foo (int a)
 }
 EOF
 if { ac_try='${CC-cc} $CFLAGS -nostdlib -nostartfiles
-                           -o conftest conftest.c -lgcc >&5'; { (eval echo configure:2924: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
+                           -o conftest conftest.c -lgcc >&5'; { (eval echo configure:2986: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
   libc_cv_gcc_subtract_local_labels=yes
 else
   libc_cv_gcc_subtract_local_labels=no
@@ -2937,7 +2999,7 @@ EOF
 fi
 
 echo $ac_n "checking for libgd""... $ac_c" 1>&6
-echo "configure:2941: checking for libgd" >&5
+echo "configure:3003: checking for libgd" >&5
 old_CFLAGS="$CFLAGS"
 CFLAGS="$CFLAGS $libgd_include"
 old_LDFLAGS="$LDFLAGS"
@@ -2945,14 +3007,14 @@ LDFLAGS="$LDFLAGS $libgd_ldflags"
 old_LIBS="$LIBS"
 LIBS="$LIBS -lgd -lpng -lz"
 cat > conftest.$ac_ext <<EOF
-#line 2949 "configure"
+#line 3011 "configure"
 #include "confdefs.h"
 #include <gd.h>
 int main() {
 gdImagePng (0, 0)
 ; return 0; }
 EOF
-if { (eval echo configure:2956: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:3018: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   LIBGD=yes
 else
@@ -2976,6 +3038,7 @@ libc_link_dests=
 libc_link_sources=
 
 # They also can set these variables.
+use_ldconfig=no
 ldd_rewrite_script=no
 
 # Iterate over all the sysdep directories we will use, running their
@@ -3013,8 +3076,8 @@ if test "$uname" = "sysdeps/generic"; then
   fi
 
   echo $ac_n "checking OS release for uname""... $ac_c" 1>&6
-echo "configure:3017: checking OS release for uname" >&5
-if eval "test \"`echo '$''{'libc_cv_uname_release'+set}'`\" = set"; then
+echo "configure:3080: checking OS release for uname" >&5
+if eval "test \"\${libc_cv_uname_release+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
     kernel_release=`echo "$kernel_id" | sed 's/^[^0-9.]*\([0-9.]*\).*$/\1/'`
@@ -3035,8 +3098,8 @@ echo "$ac_t""$libc_cv_uname_release" 1>&6
   uname_release="$libc_cv_uname_release"
 
   echo $ac_n "checking OS version for uname""... $ac_c" 1>&6
-echo "configure:3039: checking OS version for uname" >&5
-if eval "test \"`echo '$''{'libc_cv_uname_version'+set}'`\" = set"; then
+echo "configure:3102: checking OS version for uname" >&5
+if eval "test \"\${libc_cv_uname_version+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
     kernel_version=`echo "$kernel_id" | sed 's/^[^#]*#\([0-9]*\).*$/\1/'`
@@ -3057,7 +3120,7 @@ else
 fi
 
 echo $ac_n "checking stdio selection""... $ac_c" 1>&6
-echo "configure:3061: checking stdio selection" >&5
+echo "configure:3124: checking stdio selection" >&5
 
 case $stdio in
 libio) cat >> confdefs.h <<\EOF
@@ -3071,7 +3134,7 @@ echo "$ac_t""$stdio" 1>&6
 # Test for old glibc 2.0.x headers so that they can be removed properly
 # Search only in includedir.
 echo $ac_n "checking for old glibc 2.0.x headers""... $ac_c" 1>&6
-echo "configure:3075: checking for old glibc 2.0.x headers" >&5
+echo "configure:3138: checking for old glibc 2.0.x headers" >&5
 if eval test -f "${includedir}/elfclass.h" -a -f "${includedir}/fcntlbits.h"
 then
   old_glibc_headers=yes
@@ -3125,8 +3188,8 @@ if test $shared = default; then
 fi
 
 echo $ac_n "checking whether -fPIC is default""... $ac_c" 1>&6
-echo "configure:3129: checking whether -fPIC is default" >&5
-if eval "test \"`echo '$''{'pic_default'+set}'`\" = set"; then
+echo "configure:3192: checking whether -fPIC is default" >&5
+if eval "test \"\${pic_default+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   pic_default=yes
@@ -3263,7 +3326,7 @@ do
     echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
     exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
   -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
-    echo "$CONFIG_STATUS generated by autoconf version 2.13"
+    echo "$CONFIG_STATUS generated by autoconf version 2.14.1"
     exit 0 ;;
   -help | --help | --hel | --he | --h)
     echo "\$ac_cs_usage"; exit 0 ;;
@@ -3359,7 +3422,7 @@ s%@old_glibc_headers@%$old_glibc_headers%g
 s%@libc_cv_slibdir@%$libc_cv_slibdir%g
 s%@libc_cv_sysconfdir@%$libc_cv_sysconfdir%g
 s%@libc_cv_rootsbindir@%$libc_cv_rootsbindir%g
-s%@has_ldconfig@%$has_ldconfig%g
+s%@use_ldconfig@%$use_ldconfig%g
 s%@ldd_rewrite_script@%$ldd_rewrite_script%g
 s%@gnu_ld@%$gnu_ld%g
 s%@gnu_as@%$gnu_as%g
@@ -3642,7 +3705,7 @@ exit 0
 EOF
 chmod +x $CONFIG_STATUS
 rm -fr confdefs* $ac_clean_files
-test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+test "$no_create" = yes || $SHELL $CONFIG_STATUS || exit 1
 
 if test "$no_recursion" != yes; then
 
@@ -3706,7 +3769,7 @@ if test "$no_recursion" != yes; then
 
     # Check for guested configure; otherwise get Cygnus style configure.
     if test -f $ac_sub_srcdir/configure; then
-      ac_sub_configure=$ac_sub_srcdir/configure
+      ac_sub_configure="$SHELL $ac_sub_srcdir/configure"
     elif test -f $ac_sub_srcdir/configure.in; then
       ac_sub_configure=$ac_configure
     else
@@ -3728,9 +3791,9 @@ if test "$no_recursion" != yes; then
         *) INSTALL="$ac_dots$ac_given_INSTALL" ;;
         esac
 
-      echo "running ${CONFIG_SHELL-/bin/sh} $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_sub_srcdir"
+      echo "running $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_sub_srcdir"
       # The eval makes quoting arguments work.
-      if eval ${CONFIG_SHELL-/bin/sh} $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_sub_srcdir
+      if eval $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_sub_srcdir
       then :
       else
         { echo "configure: error: $ac_sub_configure failed for $ac_config_dir" 1>&2; exit 1; }
diff --git a/include/arpa/nameser_compat.h b/include/arpa/nameser_compat.h
new file mode 100644 (file)
index 0000000..bfbb2de
--- /dev/null
@@ -0,0 +1 @@
+#include <resolv/arpa/nameser_compat.h>
index 95b9eeb..cf4f375 100644 (file)
@@ -1 +1,7 @@
 #include <resolv/resolv.h>
+
+/* Internal interfaces.  */
+
+extern int __ns_name_ntop (const u_char *, char *, size_t);
+extern int __ns_name_unpack (const u_char *, const u_char *,
+                            const u_char *, u_char *, size_t);
index 522bea2..7d161b8 100644 (file)
@@ -1,3 +1,18 @@
+1999-12-03  Andreas Jaeger  <aj@suse.de>
+
+       * Versions: Add __res_state with version GLIBC_2.2.
+
+       * errno.c (__res_state): New function to return thread specific
+       resolver state.
+
+       * pthread.c (pthread_initialize): Initialize p_resp.
+       (__pthread_reset_main_thread): Also set p_resp.
+
+       * manager.c (pthread_handle_create): Initialize p_resp.
+
+       * internals.h: Add thread specific resolver state.
+       Based on patches by Adam D. Bradley <artdodge@cs.bu.edu>.
+
 1999-12-01  Ulrich Drepper  <drepper@cygnus.com>
 
        * sysdeps/i386/pt-machine.h: Move stack_pointer definition to the
index c0ec792..ab4dce5 100644 (file)
@@ -118,4 +118,7 @@ libpthread {
     __pthread_kill_other_threads_np;
     __vfork;
   }
+  GLIBC_2.2 {
+    __res_state;
+  }
 }
index 7464748..bd9584f 100644 (file)
@@ -30,3 +30,10 @@ int * __h_errno_location()
   pthread_descr self = thread_self();
   return THREAD_GETMEM (self, p_h_errnop);
 }
+
+/* Return thread specific resolver state.  */
+struct __res_state * __res_state()
+{
+  pthread_descr self = thread_self();
+  return THREAD_GETMEM (self, p_resp);
+}
index cd9091b..2e4b4b7 100644 (file)
@@ -26,6 +26,9 @@
 #include <sys/types.h>
 #include <bits/libc-tsd.h> /* for _LIBC_TSD_KEY_N */
 
+#include <resolv.h> /* for per-thread resolver context */
+
+
 #include "pt-machine.h"
 #include "semaphore.h"
 #include "../linuxthreads_db/thread_dbP.h"
@@ -119,9 +122,11 @@ struct _pthread_descr_struct {
   size_t p_guardsize;          /* size of guard area */
   pthread_descr p_self;                /* Pointer to this structure */
   int p_nr;                     /* Index of descriptor in __pthread_handles */
-  /* New elements must be added at the end.  */
   int p_report_events;         /* Nonzero if events must be reported.  */
   td_eventbuf_t p_eventbuf;     /* Data for event.  */
+  struct __res_state *p_resp;  /* Pointer to resolver state */
+  struct __res_state p_res;    /* per-thread resolver state */
+  /* New elements must be added at the end.  */
 } __attribute__ ((aligned(32))); /* We need to align the structure so that
                                    doubles are aligned properly.  This is 8
                                    bytes on MIPS and 16 bytes on MIPS64.
index 6fced74..307ce63 100644 (file)
@@ -384,6 +384,7 @@ static int pthread_handle_create(pthread_t *thread, const pthread_attr_t *attr,
   new_thread->p_canceltype = PTHREAD_CANCEL_DEFERRED;
   new_thread->p_errnop = &new_thread->p_errno;
   new_thread->p_h_errnop = &new_thread->p_h_errno;
+  new_thread->p_resp = &new_thread->p_res;
   new_thread->p_guardaddr = guardaddr;
   new_thread->p_guardsize = guardsize;
   new_thread->p_self = new_thread;
index bddec8c..41d09a8 100644 (file)
@@ -318,6 +318,8 @@ static void pthread_initialize(void)
   /* The errno/h_errno variable of the main thread are the global ones.  */
   __pthread_initial_thread.p_errnop = &_errno;
   __pthread_initial_thread.p_h_errnop = &_h_errno;
+  /* Likewise for the resolver state _res.  */
+  __pthread_initial_thread.p_resp = &_res;
 #ifdef __SIGRTMIN
   /* Initialize real-time signals. */
   init_rtsigs ();
@@ -725,6 +727,7 @@ void __pthread_reset_main_thread()
   /* Now this thread modifies the global variables.  */
   THREAD_SETMEM(self, p_errnop, &_errno);
   THREAD_SETMEM(self, p_h_errnop, &_h_errno);
+  THREAD_SETMEM(self, p_resp, &_res);
 }
 
 /* Process-wide exec() request */
index 764aec8..423adef 100644 (file)
@@ -218,7 +218,7 @@ _nl_get_era_year_start (int cnt)
 
   __libc_lock_lock (__libc_setlocale_lock);
 
-  _nl_init_era_entry();
+  init_era_entry ();
 
   result = eras[cnt]->start_date[0];
 
index 1a8271e..32327d6 100644 (file)
@@ -20,6 +20,7 @@
 #include <errno.h>
 #include <bits/libc-lock.h>
 #include <stdlib.h>
+#include <resolv.h>
 
 #include "nsswitch.h"
 
@@ -104,7 +105,7 @@ FUNCTION_NAME (ADD_PARAMS)
 #ifdef HANDLE_DIGITS_DOTS
       /* We have to test for the use of IPv6 which can only be done by
         examining `_res'.  */
-      if ((_res.options & RES_INIT) == 0 && res_init () == -1)
+      if ((_res.options & RES_INIT) == 0 && __res_ninit (&_res) == -1)
        {
 # ifdef NEED_H_ERRNO
          h_errno_tmp = NETDB_INTERNAL;
index a3130e4..c3d2010 100644 (file)
@@ -26,7 +26,9 @@
 #ifdef NEED__RES_HCONF
 # include <resolv/res_hconf.h>
 #endif
-
+#ifdef NEED__RES
+# include <resolv.h>
+#endif
 /*******************************************************************\
 |* Here we assume several symbols to be defined:                  *|
 |*                                                                *|
@@ -95,9 +97,6 @@
 typedef enum nss_status (*lookup_function) (ADD_PARAMS, LOOKUP_TYPE *, char *,
                                            size_t, int * H_ERRNO_PARM);
 
-/* Some usages of this file might use this variable.  */
-extern struct __res_state _res;
-
 /* The lookup function for the first entry of this service.  */
 extern int DB_LOOKUP_FCT (service_user **nip, const char *name, void **fctp);
 
@@ -126,7 +125,7 @@ INTERNAL (REENTRANT_NAME) (ADD_PARAMS, LOOKUP_TYPE *resbuf, char *buffer,
 #ifdef HANDLE_DIGITS_DOTS
   /* We have to test for the use of IPv6 which can only be done by
      examining `_res'.  */
-  if ((_res.options & RES_INIT) == 0 && res_init () == -1)
+  if ((_res.options & RES_INIT) == 0 && __res_ninit (&_res) == -1)
     {
       *h_errnop = NETDB_INTERNAL;
       *result = NULL;
@@ -166,7 +165,7 @@ INTERNAL (REENTRANT_NAME) (ADD_PARAMS, LOOKUP_TYPE *resbuf, char *buffer,
 #ifdef NEED__RES
          /* The resolver code will really be used so we have to
             initialize it.  */
-         if ((_res.options & RES_INIT) == 0 && res_init () == -1)
+         if ((_res.options & RES_INIT) == 0 && __res_ninit (&_res) == -1)
            {
              *h_errnop = NETDB_INTERNAL;
              *result = NULL;
index 5d1fdeb..d05a4e3 100644 (file)
@@ -1 +1 @@
-BIND-4.9.7-REL
+BIND-8.2.2-5
index 71a66fe..c8dc54a 100644 (file)
@@ -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
index 9bf6a39..3448c92 100644 (file)
@@ -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 {
index 8866d90..6655f3b 100644 (file)
@@ -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
  * 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 (file)
index 0000000..f67f5b3
--- /dev/null
@@ -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_ */
index 7f1b742..5808d92 100644 (file)
@@ -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 (file)
index 0000000..b75f731
--- /dev/null
@@ -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 (file)
index 0000000..9dcf91c
--- /dev/null
@@ -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 (file)
index 0000000..7bbdc41
--- /dev/null
@@ -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 (file)
index 0000000..cce3fb6
--- /dev/null
@@ -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 (file)
index 0000000..bac5a63
--- /dev/null
@@ -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 (file)
index 0000000..6be2b0d
--- /dev/null
@@ -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);
+}
index 53a19d5..c1c9a61 100644 (file)
@@ -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;
index 482cbd3..483e791 100644 (file)
@@ -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)
        {
index f81341c..b194852 100644 (file)
@@ -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.  */
index 2d90e37..e6f54ce 100644 (file)
@@ -1,6 +1,4 @@
 /*
- * ++Copyright++ 1985, 1993
- * -
  * Copyright (c) 1985, 1993
  *    The Regents of the University of California.  All rights reserved.
  *
  * 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*/
index aa3ecbd..a9f5a2a 100644 (file)
@@ -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
index dac878d..2df1c5b 100644 (file)
@@ -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
  * 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 (file)
index 0000000..4a0aa99
--- /dev/null
@@ -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_ */ 
index e5520ff..bf6cf7f 100644 (file)
@@ -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
  * 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 (file)
index 0000000..14d565d
--- /dev/null
@@ -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;
+}
index 8f3e66f..dba2c80 100644 (file)
@@ -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
  * 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);
index 80c1034..deebf4c 100644 (file)
@@ -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
  * 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);
index e315383..d3dc2ba 100644 (file)
@@ -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
  * 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
index 58742e9..b101262 100644 (file)
  */
 
 /*
+ * 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$
  */
  * 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.
 #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.
  */
 #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_ */
index 87a5bff..8367116 100644 (file)
@@ -13,7 +13,7 @@ if test -n "$sysheaders"; then
 fi
 echo $ac_n "checking installed Linux kernel header files""... $ac_c" 1>&6
 echo "configure:16: checking installed Linux kernel header files" >&5
-if eval "test \"`echo '$''{'libc_cv_linux2010'+set}'`\" = set"; then
+if eval "test \"\${libc_cv_linux2010+set}\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
@@ -143,11 +143,8 @@ if test "$message"; then
   fi
 fi
 
-# Check whether `ldconfig' sources are available.  This will go away as soon
-# as ldconfig is available in GNU libc.
-if test -f $srcdir/elf/ldconfig.c; then
-  has_ldconfig=yes
-fi
+# One Linux we use ldconfig.
+use_ldconfig=yes
 
 # We need some extensions to the `ldd' script.
 
@@ -173,7 +170,7 @@ if test $host = $build; then
     ac_prefix=$ac_default_prefix
   fi
   echo $ac_n "checking for symlinks in ${ac_prefix}/include""... $ac_c" 1>&6
-echo "configure:177: checking for symlinks in ${ac_prefix}/include" >&5
+echo "configure:174: checking for symlinks in ${ac_prefix}/include" >&5
   ac_message=
   if test -L ${ac_prefix}/include/net; then
     ac_message="$ac_message
index fae7934..96da653 100644 (file)
@@ -114,11 +114,8 @@ if test "$message"; then
   fi
 fi
 
-# Check whether `ldconfig' sources are available.  This will go away as soon
-# as ldconfig is available in GNU libc.
-if test -f $srcdir/elf/ldconfig.c; then
-  has_ldconfig=yes
-fi
+# One Linux we use ldconfig.
+use_ldconfig=yes
 
 # We need some extensions to the `ldd' script.
 changequote(,)