Update.
authorUlrich Drepper <drepper@redhat.com>
Wed, 19 Jul 2000 22:03:58 +0000 (22:03 +0000)
committerUlrich Drepper <drepper@redhat.com>
Wed, 19 Jul 2000 22:03:58 +0000 (22:03 +0000)
2000-07-18  Mark Kettenis  <kettenis@gnu.org>

Update resolver code to BIND 8.2.3-T5B.

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

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

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

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

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

* resolv/arpa/namser.h: Update from BIND 8.2.3-T5B.
* resolv/arpa/nameser_compat.h: Likewise.

31 files changed:
ChangeLog
include/resolv.h
linuxthreads/manager.c
resolv/Banner
resolv/Versions
resolv/arpa/nameser.h
resolv/arpa/nameser_compat.h
resolv/base64.c
resolv/herror.c
resolv/inet_addr.c
resolv/inet_net_ntop.c
resolv/inet_net_pton.c
resolv/inet_neta.c
resolv/inet_ntop.c
resolv/inet_pton.c
resolv/ns_name.c
resolv/ns_netint.c
resolv/ns_parse.c
resolv/ns_print.c
resolv/ns_samedomain.c
resolv/ns_ttl.c
resolv/nsap_addr.c
resolv/res_comp.c
resolv/res_data.c
resolv/res_debug.c
resolv/res_init.c
resolv/res_libc.c
resolv/res_mkquery.c
resolv/res_query.c
resolv/res_send.c
resolv/resolv.h

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