Updated from BIND 4.9.3-BETA14.
authorroland <roland>
Wed, 28 Dec 1994 10:38:01 +0000 (10:38 +0000)
committerroland <roland>
Wed, 28 Dec 1994 10:38:01 +0000 (10:38 +0000)
resolv/herror.c
resolv/res_comp.c
resolv/res_debug.c
resolv/res_init.c
resolv/res_mkquery.c
resolv/res_send.c

index 759ff7b..872a009 100644 (file)
@@ -69,13 +69,13 @@ static char rcsid[] = "$Id$";
 #endif
 
 char   *h_errlist[] = {
-       "Error 0",
+       "Resolver Error 0 (no error)",
        "Unknown host",                         /* 1 HOST_NOT_FOUND */
        "Host name lookup failure",             /* 2 TRY_AGAIN */
        "Unknown server error",                 /* 3 NO_RECOVERY */
        "No address associated with name",      /* 4 NO_ADDRESS */
 };
-int    h_nerr = { sizeof(h_errlist)/sizeof(h_errlist[0]) };
+int    h_nerr = { sizeof h_errlist / sizeof h_errlist[0] };
 
 extern int     h_errno;
 
@@ -98,8 +98,7 @@ herror(s)
                v->iov_len = 2;
                v++;
        }
-       v->iov_base = (u_int)h_errno < h_nerr ?
-           h_errlist[h_errno] : "Unknown error";
+       v->iov_base = hstrerror(h_errno);
        v->iov_len = strlen(v->iov_base);
        v++;
        v->iov_base = "\n";
@@ -111,5 +110,9 @@ char *
 hstrerror(err)
        int err;
 {
-       return (u_int)err < h_nerr ? h_errlist[err] : "Unknown resolver error";
+       if (err < 0)
+               return ("Resolver internal error");
+       else if (err < h_nerr)
+               return (h_errlist[err]);
+       return ("Unknown resolver error");
 }
index ae40d63..ad24a98 100644 (file)
@@ -123,7 +123,7 @@ dn_expand(msg, eomorig, comp_dn, exp_dn, length)
                                }
                                *dn++ = c;
                                if (cp >= eomorig)      /* out of range */
-                                       return(-1);
+                                       return (-1);
                        }
                        break;
 
@@ -132,7 +132,7 @@ dn_expand(msg, eomorig, comp_dn, exp_dn, length)
                                len = cp - comp_dn + 1;
                        cp = msg + (((n & 0x3f) << 8) | (*cp & 0xff));
                        if (cp < msg || cp >= eomorig)  /* out of range */
-                               return(-1);
+                               return (-1);
                        checked += 2;
                        /*
                         * Check for loops in the compressed name;
@@ -268,12 +268,12 @@ __dn_skipname(comp_dn, eom)
                        cp++;
                        break;
                default:                /* illegal type */
-                       return -1;
+                       return (-1);
                }
                break;
        }
        if (cp > eom)
-               return -1;
+               return (-1);
        return (cp - comp_dn);
 }
 
@@ -324,11 +324,12 @@ dn_find(exp_dn, msg, dnptrs, lastdnptr)
                                        continue;
                                goto next;
 
-                       default:        /* illegal type */
-                               return (-1);
-
                        case INDIR_MASK:        /* indirection */
                                cp = msg + (((n & 0x3f) << 8) | *cp);
+                               break;
+
+                       default:        /* illegal type */
+                               return (-1);
                        }
                }
                if (*dn == '\0')
@@ -356,6 +357,18 @@ _getshort(msgp)
        return (u);
 }
 
+#ifdef NeXT
+/*
+ * nExt machines have some funky library conventions, which we must maintain.
+ */
+u_int16_t
+res_getshort(msgp)
+       register const u_char *msgp;
+{
+       return (_getshort(msgp));
+}
+#endif
+
 u_int32_t
 _getlong(msgp)
        register const u_char *msgp;
@@ -415,6 +428,6 @@ putlong(l, msgp)
 dn_skipname(comp_dn, eom)
        const u_char *comp_dn, *eom;
 {
-       return __dn_skipname(comp_dn, eom);
+       return (__dn_skipname(comp_dn, eom));
 }
 #endif /* Ultrix 4.0 hackery */
index c16bea8..254e1ef 100644 (file)
@@ -79,8 +79,8 @@ const char *_res_opcodes[] = {
        "QUERY",
        "IQUERY",
        "CQUERYM",
-       "CQUERYU",
-       "4",
+       "CQUERYU",      /* experimental */
+       "NOTIFY",       /* experimental */
        "5",
        "6",
        "7",
@@ -210,7 +210,18 @@ do_rrset(msg, cp, cnt, pflag, file, hs)
                    ((sflag) && (_res.pfcode & RES_PRF_HEAD1)))
                        fprintf(file, hs);
                while (--n >= 0) {
-                       cp = p_rr(cp, msg, file);
+                       if ((!_res.pfcode) || sflag) {
+                               cp = p_rr(cp, msg, file);
+                       } else {
+                               unsigned int dlen;
+                               cp += __dn_skipname(cp, cp + MAXCDNAME);
+                               cp += INT16SZ;
+                               cp += INT16SZ;
+                               cp += INT32SZ;
+                               dlen = _getshort((u_char*)cp);
+                               cp += INT16SZ;
+                               cp += dlen;
+                       }
                        if ((cp - msg) > PACKETSZ)
                                return (NULL);
                }
@@ -292,7 +303,7 @@ __fp_nquery(msg, len, file)
        }
        putc(';', file);
        if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEAD2)) {
-               fprintf(file,"; flags:");
+               fprintf(file, "; flags:");
                if (hp->qr)
                        fprintf(file, " qr");
                if (hp->aa)
@@ -321,9 +332,9 @@ __fp_nquery(msg, len, file)
         */
        if (n = ntohs(hp->qdcount)) {
                if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES))
-                       fprintf(file,";; QUESTIONS:\n");
+                       fprintf(file, ";; QUESTIONS:\n");
                while (--n >= 0) {
-                       fprintf(file,";;\t");
+                       fprintf(file, ";;\t");
                        TruncTest(cp);
                        cp = p_cdname(cp, msg, file);
                        ErrorTest(cp);
@@ -468,7 +479,7 @@ __p_rr(cp, msg, file)
                case C_HS:
                        bcopy(cp, (char *)&inaddr, INADDRSZ);
                        if (dlen == 4) {
-                               fprintf(file,"\t%s", inet_ntoa(inaddr));
+                               fprintf(file, "\t%s", inet_ntoa(inaddr));
                                cp += dlen;
                        } else if (dlen == 7) {
                                char *address;
@@ -496,55 +507,71 @@ __p_rr(cp, msg, file)
        case T_NS:
        case T_PTR:
                putc('\t', file);
-               cp = p_fqname(cp, msg, file);
+               if ((cp = p_fqname(cp, msg, file)) == NULL)
+                       return (NULL);
                break;
 
        case T_HINFO:
        case T_ISDN:
+               cp2 = cp + dlen;
                if (n = *cp++) {
-                       fprintf(file,"\t%.*s", n, cp);
+                       fprintf(file, "\t%.*s", n, cp);
                        cp += n;
                }
-               if (n = *cp++) {
-                       fprintf(file,"\t%.*s", n, cp);
+               if ((cp < cp2) && (n = *cp++)) {
+                       fprintf(file, "\t%.*s", n, cp);
                        cp += n;
-               }
+               } else if (type == T_HINFO)
+                       fprintf(file, "\n;; *** Warning *** OS-type missing");
                break;
 
        case T_SOA:
                putc('\t', file);
-               cp = p_fqname(cp, msg, file);   /* origin */
+               if ((cp = p_fqname(cp, msg, file)) == NULL)
+                       return (NULL);
                putc(' ', file);
-               cp = p_fqname(cp, msg, file);   /* mail addr */
+               if ((cp = p_fqname(cp, msg, file)) == NULL)
+                       return (NULL);
                fputs(" (\n", file);
                t = _getlong((u_char*)cp);  cp += INT32SZ;
-               fprintf(file,"\t\t\t%lu\t; serial\n", t);
+               fprintf(file, "\t\t\t%lu\t; serial\n", t);
                t = _getlong((u_char*)cp);  cp += INT32SZ;
-               fprintf(file,"\t\t\t%lu\t; refresh (%s)\n", t, __p_time(t));
+               fprintf(file, "\t\t\t%lu\t; refresh (%s)\n", t, __p_time(t));
                t = _getlong((u_char*)cp);  cp += INT32SZ;
-               fprintf(file,"\t\t\t%lu\t; retry (%s)\n", t, __p_time(t));
+               fprintf(file, "\t\t\t%lu\t; retry (%s)\n", t, __p_time(t));
                t = _getlong((u_char*)cp);  cp += INT32SZ;
-               fprintf(file,"\t\t\t%lu\t; expire (%s)\n", t, __p_time(t));
+               fprintf(file, "\t\t\t%lu\t; expire (%s)\n", t, __p_time(t));
                t = _getlong((u_char*)cp);  cp += INT32SZ;
-               fprintf(file,"\t\t\t%lu )\t; minimum (%s)", t, __p_time(t));
+               fprintf(file, "\t\t\t%lu )\t; minimum (%s)", t, __p_time(t));
                break;
 
        case T_MX:
        case T_AFSDB:
        case T_RT:
-               fprintf(file,"\t%d ", _getshort((u_char*)cp));
+               fprintf(file, "\t%d ", _getshort((u_char*)cp));
                cp += INT16SZ;
-               cp = p_fqname(cp, msg, file);
+               if ((cp = p_fqname(cp, msg, file)) == NULL)
+                       return (NULL);
                break;
 
-       case T_TXT:
+       case T_PX:
+               fprintf(file, "\t%d ", _getshort((u_char*)cp));
+               cp += INT16SZ;
+               if ((cp = p_fqname(cp, msg, file)) == NULL)
+                       return (NULL);
+               putc(' ', file);
+               if ((cp = p_fqname(cp, msg, file)) == NULL)
+                       return (NULL);
+               break;
+
+       case T_TXT:
        case T_X25:
                (void) fputs("\t\"", file);
                cp2 = cp1 + dlen;
                while (cp < cp2) {
                        if (n = (unsigned char) *cp++) {
                                for (c = n; c > 0 && cp < cp2; c--)
-                                       if (*cp == '\n') {
+                                       if ((*cp == '\n') || (*cp == '"')) {
                                            (void) putc('\\', file);
                                            (void) putc(*cp++, file);
                                        } else
@@ -552,19 +579,21 @@ __p_rr(cp, msg, file)
                        }
                }
                putc('"', file);
-               break;
+               break;
 
-       case T_NSAP:
+       case T_NSAP:
                (void) fprintf(file, "\t%s", inet_nsap_ntoa(dlen, cp, NULL));
                cp += dlen;
-               break;
+               break;
 
        case T_MINFO:
        case T_RP:
                putc('\t', file);
-               cp = p_fqname(cp, msg, file);
+               if ((cp = p_fqname(cp, msg, file)) == NULL)
+                       return (NULL);
                putc(' ', file);
-               cp = p_fqname(cp, msg, file);
+               if ((cp = p_fqname(cp, msg, file)) == NULL)
+                       return (NULL);
                break;
 
        case T_UINFO:
@@ -576,7 +605,7 @@ __p_rr(cp, msg, file)
        case T_UID:
        case T_GID:
                if (dlen == 4) {
-                       fprintf(file,"\t%u", _getlong((u_char*)cp));
+                       fprintf(file, "\t%u", _getlong((u_char*)cp));
                        cp += INT32SZ;
                }
                break;
@@ -595,7 +624,7 @@ __p_rr(cp, msg, file)
                while (cp < cp1 + dlen) {
                        c = *cp++;
                        do {
-                               if (c & 0200) {
+                               if (c & 0200) {
                                        if (lcnt == 0) {
                                                fputs("\n\t\t\t", file);
                                                lcnt = 5;
@@ -604,7 +633,7 @@ __p_rr(cp, msg, file)
                                        putc(' ', file);
                                        lcnt--;
                                }
-                               c <<= 1;
+                               c <<= 1;
                        } while (++n & 07);
                }
                putc(')', file);
@@ -628,7 +657,7 @@ __p_rr(cp, msg, file)
 #endif /* ALLOW_T_UNSPEC */
 
        default:
-               fprintf(file,"\t?%d?", type);
+               fprintf(file, "\t?%d?", type);
                cp += dlen;
        }
 #if 0
@@ -637,7 +666,7 @@ __p_rr(cp, msg, file)
        putc('\n', file);
 #endif
        if (cp - cp1 != dlen) {
-               fprintf(file,";; packet size error (found %d, dlen was %d)\n",
+               fprintf(file, ";; packet size error (found %d, dlen was %d)\n",
                        cp - cp1, dlen);
                cp = NULL;
        }
@@ -668,12 +697,19 @@ __p_type(type)
        case T_MINFO:   return "MINFO";
        case T_MX:      return "MX";
        case T_TXT:     return "TXT";
-       case T_NSAP:    return "NSAP";
        case T_RP:      return "RP";
        case T_AFSDB:   return "AFSDB";
        case T_X25:     return "X25";
        case T_ISDN:    return "ISDN";
        case T_RT:      return "RT";
+       case T_NSAP:    return "NSAP";
+       case T_NSAP_PTR: return "NSAP_PTR";
+       case T_SIG:     return "SIG";
+       case T_KEY:     return "KEY";
+       case T_PX:      return "PX";
+       case T_GPOS:    return "GPOS";
+       case T_AAAA:    return "AAAA";
+       case T_LOC:     return "LOC";
        case T_AXFR:    return "AXFR";
        case T_MAILB:   return "MAILB";
        case T_MAILA:   return "MAILA";
@@ -696,9 +732,9 @@ __p_class(class)
        int class;
 {
        switch (class) {
-       case C_IN:      return("IN");
-       case C_HS:      return("HS");
-       case C_ANY:     return("ANY");
+       case C_IN:      return "IN";
+       case C_HS:      return "HS";
+       case C_ANY:     return "ANY";
        default:        (void)sprintf(nbuf, "%d", class); return (nbuf);
        }
 }
@@ -723,7 +759,7 @@ __p_option(option)
        case RES_DNSRCH:        return "dnsrch";
        case RES_INSECURE1:     return "insecure1";
        case RES_INSECURE2:     return "insecure2";
-       default:                sprintf(nbuf, "?0x%x?", option); return nbuf;
+       default:                sprintf(nbuf, "?0x%x?", option); return (nbuf);
        }
 }
 
index b6b1368..0092dbc 100644 (file)
@@ -75,6 +75,36 @@ static char rcsid[] = "$Id$";
 # include "../conf/portability.h"
 #endif
 
+/*
+ * Marc Majka          1994/04/16
+ * Allan Nathanson     1994/10/29 (BIND 4.9.3.x)
+ *
+ * NetInfo resolver configuration directory support.
+ *
+ * Allow a NetInfo directory to be created in the hierarchy which
+ * contains the same information as the resolver configuration file.
+ *
+ * - The local domain name is stored as the value of the "domain" property.
+ * - The Internet address(es) of the name server(s) are stored as values
+ *   of the "nameserver" property.
+ * - The name server addresses are stored as values of the "nameserver"
+ *   property.
+ * - The search list for host-name lookup is stored as values of the
+ *   "search" property.
+ * - The sortlist comprised of IP address netmask pairs are stored as
+ *   values of the "sortlist" property. The IP address and optional netmask
+ *   should be seperated by a slash (/) character.
+ * - Internal resolver variables can be set from the value of the "options"
+ *   property.
+ *
+ */
+#if defined(NeXT)
+#  include <netinfo/ni.h>
+#  define NI_PATH_RESCONF "/locations/resolver"
+#  define NI_TIMEOUT 10
+static int netinfo_res_init __P((int *haveenv, int *havesearch));
+#endif
+
 #if defined(USE_OPTIONS_H)
 # include "../conf/options.h"
 #endif
@@ -131,7 +161,7 @@ res_init()
 #endif
 
        /*
-        * These four fields used to be statically initialized.  This made
+        * These three fields used to be statically initialized.  This made
         * it hard to use this code in a shared library.  It is necessary,
         * now that we're doing dynamic initialization here, that we preserve
         * the old semantics: if an application modifies one of these three
@@ -195,14 +225,22 @@ res_init()
                *pp++ = 0;
        }
 
+#define        MATCH(line, name) \
+       (!strncmp(line, name, sizeof(name) - 1) && \
+       (line[sizeof(name) - 1] == ' ' || \
+        line[sizeof(name) - 1] == '\t'))
+
+#ifdef NeXT
+       if (netinfo_res_init(&haveenv, &havesearch) == 0)
+#endif
        if ((fp = fopen(_PATH_RESCONF, "r")) != NULL) {
            /* read the config file */
            while (fgets(buf, sizeof(buf), fp) != NULL) {
                /* skip comments */
-               if ((*buf == ';') || (*buf == '#'))
+               if (*buf == ';' || *buf == '#')
                        continue;
                /* read default domain name */
-               if (!strncmp(buf, "domain", sizeof("domain") - 1)) {
+               if (MATCH(buf, "domain")) {
                    if (haveenv)        /* skip if have from environ */
                            continue;
                    cp = buf + sizeof("domain") - 1;
@@ -210,15 +248,14 @@ res_init()
                            cp++;
                    if ((*cp == '\0') || (*cp == '\n'))
                            continue;
-                   (void)strncpy(_res.defdname, cp,
-                                 sizeof(_res.defdname) - 1);
+                   strncpy(_res.defdname, cp, sizeof(_res.defdname) - 1);
                    if ((cp = strpbrk(_res.defdname, " \t\n")) != NULL)
                            *cp = '\0';
                    havesearch = 0;
                    continue;
                }
                /* set search list */
-               if (!strncmp(buf, "search", sizeof("search") - 1)) {
+               if (MATCH(buf, "search")) {
                    if (haveenv)        /* skip if have from environ */
                            continue;
                    cp = buf + sizeof("search") - 1;
@@ -226,8 +263,7 @@ res_init()
                            cp++;
                    if ((*cp == '\0') || (*cp == '\n'))
                            continue;
-                   (void)strncpy(_res.defdname, cp,
-                                 sizeof(_res.defdname) - 1);
+                   strncpy(_res.defdname, cp, sizeof(_res.defdname) - 1);
                    if ((cp = strchr(_res.defdname, '\n')) != NULL)
                            *cp = '\0';
                    /*
@@ -237,9 +273,7 @@ res_init()
                    cp = _res.defdname;
                    pp = _res.dnsrch;
                    *pp++ = cp;
-                   for (n = 0;
-                        *cp && pp < _res.dnsrch + MAXDNSRCH;
-                        cp++) {
+                   for (n = 0; *cp && pp < _res.dnsrch + MAXDNSRCH; cp++) {
                            if (*cp == ' ' || *cp == '\t') {
                                    *cp = 0;
                                    n = 1;
@@ -257,9 +291,8 @@ res_init()
                    continue;
                }
                /* read nameservers to query */
-               if (!strncmp(buf, "nameserver", sizeof("nameserver") - 1) &&
-                  nserv < MAXNS) {
-                  struct in_addr a;
+               if (MATCH(buf, "nameserver") && nserv < MAXNS) {
+                   struct in_addr a;
 
                    cp = buf + sizeof("nameserver") - 1;
                    while (*cp == ' ' || *cp == '\t')
@@ -274,7 +307,7 @@ res_init()
                    continue;
                }
 #ifdef RESOLVSORT
-               if (!strncmp(buf, "sortlist", sizeof("sortlist") -1)) {
+               if (MATCH(buf, "sortlist")) {
                    struct in_addr a;
 
                    cp = buf + sizeof("sortlist") - 1;
@@ -285,7 +318,7 @@ res_init()
                            break;
                        net = cp;
                        while (*cp && *cp != '/' &&
-                           isascii(*cp) && !isspace(*cp))
+                              isascii(*cp) && !isspace(*cp))
                                cp++;
                        n = *cp;
                        *cp = 0;
@@ -315,7 +348,7 @@ res_init()
                    continue;
                }
 #endif
-               if (!strncmp(buf, "options", sizeof("options") -1)) {
+               if (MATCH(buf, "options")) {
                    res_setoptions(buf + sizeof("options") - 1, "conf");
                    continue;
                }
@@ -326,13 +359,11 @@ res_init()
            _res.nsort = nsort;
 #endif
            (void) fclose(fp);
-       } /*if(fopen)*/
-       if (_res.defdname[0] == 0) {
-               if (gethostname(buf, sizeof(_res.defdname) - 1) == 0 &&
-                  (cp = strchr(buf, '.'))) {
-                       (void)strcpy(_res.defdname, cp + 1);
-               }
        }
+       if (_res.defdname[0] == 0 &&
+           gethostname(buf, sizeof(_res.defdname) - 1) == 0 &&
+           (cp = strchr(buf, '.')) != NULL)
+               strcpy(_res.defdname, cp + 1);
 
        /* find components of local domain that might be searched */
        if (havesearch == 0) {
@@ -342,14 +373,13 @@ res_init()
 
 #ifndef RFC1535
                dots = 0;
-               for (cp = _res.defdname;  *cp;  cp++)
+               for (cp = _res.defdname; *cp; cp++)
                        dots += (*cp == '.');
 
                cp = _res.defdname;
                while (pp < _res.dnsrch + MAXDFLSRCH) {
-                       if (dots < LOCALDOMAINPARTS) {
+                       if (dots < LOCALDOMAINPARTS)
                                break;
-                       }
                        cp = strchr(cp, '.') + 1;    /* we know there is one */
                        *pp++ = cp;
                        dots--;
@@ -358,23 +388,20 @@ res_init()
 #ifdef DEBUG
                if (_res.options & RES_DEBUG) {
                        printf(";; res_init()... default dnsrch list:\n");
-                       for (pp = _res.dnsrch;  *pp;  pp++) {
+                       for (pp = _res.dnsrch; *pp; pp++)
                                printf(";;\t%s\n", *pp);
-                       }
                        printf(";;\t..END..\n");
                }
-#endif /*DEBUG*/
-#endif /*!RFC1535*/
+#endif /* DEBUG */
+#endif /* !RFC1535 */
        }
 
-       if ((cp = getenv("RES_OPTIONS")) != NULL) {
+       if ((cp = getenv("RES_OPTIONS")) != NULL)
                res_setoptions(cp, "env");
-       }
        _res.options |= RES_INIT;
        return (0);
 }
 
-
 static void
 res_setoptions(options, source)
        char *options, *source;
@@ -383,28 +410,26 @@ res_setoptions(options, source)
        int i;
 
 #ifdef DEBUG
-       if (_res.options & RES_DEBUG) {
+       if (_res.options & RES_DEBUG)
                printf(";; res_setoptions(\"%s\", \"%s\")...\n",
                       options, source);
-       }
 #endif
        while (*cp) {
                /* skip leading and inner runs of spaces */
                while (*cp == ' ' || *cp == '\t')
                        cp++;
                /* search for and process individual options */
-               if (!strncmp(cp, "ndots:", sizeof("ndots:")-1)) {
+               if (!strncmp(cp, "ndots:", sizeof("ndots:") - 1)) {
                        i = atoi(cp + sizeof("ndots:") - 1);
                        if (i <= RES_MAXNDOTS)
                                _res.ndots = i;
                        else
                                _res.ndots = RES_MAXNDOTS;
 #ifdef DEBUG
-                       if (_res.options & RES_DEBUG) {
+                       if (_res.options & RES_DEBUG)
                                printf(";;\tndots=%d\n", _res.ndots);
-                       }
 #endif
-               } else if (!strncmp(cp, "debug", sizeof("debug")-1)) {
+               } else if (!strncmp(cp, "debug", sizeof("debug") - 1)) {
 #ifdef DEBUG
                        if (!(_res.options & RES_DEBUG)) {
                                printf(";; res_setoptions(\"%s\", \"%s\")..\n",
@@ -427,13 +452,158 @@ static u_int32_t
 net_mask(in)           /* XXX - should really use system's version of this */
        struct in_addr in;
 {
-        register u_int32_t i = ntohl(in.s_addr);
-
-        if (IN_CLASSA(i))
-                return (htonl(IN_CLASSA_NET));
-        else if (IN_CLASSB(i))
-                return (htonl(IN_CLASSB_NET));
-        else
-                return (htonl(IN_CLASSC_NET));
+       register u_int32_t i = ntohl(in.s_addr);
+
+       if (IN_CLASSA(i))
+               return (htonl(IN_CLASSA_NET));
+       else if (IN_CLASSB(i))
+               return (htonl(IN_CLASSB_NET));
+       return (htonl(IN_CLASSC_NET));
 }
 #endif
+
+#ifdef NeXT
+static int
+netinfo_res_init(haveenv, havesearch)
+       int *haveenv;
+       int *havesearch;
+{
+    register   int n;
+    void       *domain, *parent;
+    ni_id      dir;
+    ni_status  status;
+    ni_namelist        nl;
+    int                nserv = 0;
+#ifdef RESOLVSORT
+    int                nsort = 0;
+#endif
+
+    status = ni_open(NULL, ".", &domain);
+    if (status == NI_OK) {
+       ni_setreadtimeout(domain, NI_TIMEOUT);
+       ni_setabort(domain, 1);
+
+       /* climb the NetInfo hierarchy to find a resolver directory */
+       while (status == NI_OK) {
+           status = ni_pathsearch(domain, &dir, NI_PATH_RESCONF);
+           if (status == NI_OK) {
+           /* found a resolver directory */
+
+               if (*haveenv == 0) {
+                   /* get the default domain name */
+                   status = ni_lookupprop(domain, &dir, "domain", &nl);
+                   if (status == NI_OK && nl.ni_namelist_len > 0) {
+                       (void)strncpy(_res.defdname,
+                                     nl.ni_namelist_val[0],
+                                     sizeof(_res.defdname) - 1);
+                       _res.defdname[sizeof(_res.defdname) - 1] = '\0';
+                       ni_namelist_free(&nl);
+                       *havesearch = 0;
+                   }
+
+                   /* get search list */
+                   status = ni_lookupprop(domain, &dir, "search", &nl);
+                   if (status == NI_OK && nl.ni_namelist_len > 0) {
+                       (void)strncpy(_res.defdname,
+                                     nl.ni_namelist_val[0],
+                                     sizeof(_res.defdname) - 1);
+                       _res.defdname[sizeof(_res.defdname) - 1] = '\0';
+                       /* copy  */
+                       for (n = 0;
+                            n < nl.ni_namelist_len && n < MAXDNSRCH;
+                            n++) {
+                            /* duplicate up to MAXDNSRCH servers */
+                            char *cp = nl.ni_namelist_val[n];
+                           _res.dnsrch[n] =
+                               strcpy((char *)malloc(strlen(cp) + 1), cp);
+                       }
+                       ni_namelist_free(&nl);
+                       *havesearch = 1;
+                   }
+               }
+
+               /* get list of nameservers */
+               status = ni_lookupprop(domain, &dir, "nameserver", &nl);
+               if (status == NI_OK && nl.ni_namelist_len > 0) {
+                   /* copy up to MAXNS servers */
+                   for (n = 0;
+                        n < nl.ni_namelist_len && nserv < MAXNS;
+                        n++) {
+                       struct in_addr a;
+
+                       if (inet_aton(nl.ni_namelist_val[n], &a)) {
+                           _res.nsaddr_list[nserv].sin_addr = a;
+                           _res.nsaddr_list[nserv].sin_family = AF_INET;
+                           _res.nsaddr_list[nserv].sin_port =
+                               htons(NAMESERVER_PORT);
+                           nserv++;
+                       }
+                   }
+                   ni_namelist_free(&nl);
+               }
+               
+               if (nserv > 1)
+                   _res.nscount = nserv;
+
+#ifdef RESOLVSORT
+               /* get sort order */
+               status = ni_lookupprop(domain, &dir, "sortlist", &nl);
+               if (status == NI_OK && nl.ni_namelist_len > 0) {
+
+                   /* copy up to MAXRESOLVSORT address/netmask pairs */
+                   for (n = 0;
+                        n < nl.ni_namelist_len && nsort < MAXRESOLVSORT;
+                        n++) {
+                       char ch;
+                       char *cp;
+                       struct in_addr a;
+
+                       cp = strchr(nl.ni_namelist_val[n], '/');
+                       if (cp != NULL) {
+                           ch = *cp;
+                           *cp = '\0';
+                       }
+                       
+                       if (inet_aton(nl.ni_namelist_val[n], &a)) {
+                           _res.sort_list[nsort].addr = a;
+                           if (*cp && ch == '/') {
+                               *cp++ = ch;
+                               if (inet_aton(cp, &a)) {
+                                   _res.sort_list[nsort].mask = a.s_addr;
+                               } else {
+                                   _res.sort_list[nsort].mask =
+                                       net_mask(_res.sort_list[nsort].addr);
+                               }
+                           } else {
+                               _res.sort_list[nsort].mask =
+                                   net_mask(_res.sort_list[nsort].addr);
+                           }
+                           nsort++;
+                       }
+                   }
+                   ni_namelist_free(&nl);
+               }
+
+               _res.nsort = nsort;
+#endif
+
+               /* get resolver options */
+               status = ni_lookupprop(domain, &dir, "options", &nl);
+               if (status == NI_OK && nl.ni_namelist_len > 0) {
+                   res_setoptions(nl.ni_namelist_val[0], "conf");
+                   ni_namelist_free(&nl);
+               }
+
+               ni_free(domain);
+               return(1);      /* using DNS configuration from NetInfo */
+           }
+
+           status = ni_open(domain, "..", &parent);
+           ni_free(domain);
+           if (status == NI_OK)
+               domain = parent;
+       }
+    }
+    return(0); /* if not using DNS configuration from NetInfo */
+}
+#endif /* NeXT */
index ade1ed2..0695670 100644 (file)
@@ -100,11 +100,15 @@ res_mkquery(op, dname, class, type, data, datalen, newrr_in, buf, buflen)
                printf(";; res_mkquery(%d, %s, %d, %d)\n",
                       op, dname, class, type);
 #endif
+       if (!(_res.options & RES_INIT)) {
+               if (res_init() == -1)
+                       return (-1);
+       }
        /*
         * Initialize header fields.
         */
        if ((buf == NULL) || (buflen < HFIXEDSZ))
-               return(-1);
+               return (-1);
        bzero(buf, HFIXEDSZ);
        hp = (HEADER *) buf;
        hp->id = htons(++_res.id);
@@ -122,9 +126,10 @@ res_mkquery(op, dname, class, type, data, datalen, newrr_in, buf, buflen)
         * perform opcode specific processing
         */
        switch (op) {
-       case QUERY:
+       case QUERY:     /*FALLTHROUGH*/
+       case NS_NOTIFY_OP:
                if ((buflen -= QFIXEDSZ) < 0)
-                       return(-1);
+                       return (-1);
                if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0)
                        return (-1);
                cp += n;
@@ -198,13 +203,13 @@ res_mkquery(op, dname, class, type, data, datalen, newrr_in, buf, buflen)
                        return (-1);
                cp += n;
                __putshort(type, cp);
-                cp += INT16SZ;
-                __putshort(class, cp);
-                cp += INT16SZ;
+               cp += INT16SZ;
+               __putshort(class, cp);
+               cp += INT16SZ;
                __putlong(0, cp);
                cp += INT32SZ;
                __putshort(datalen, cp);
-                cp += INT16SZ;
+               cp += INT16SZ;
                if (datalen) {
                        bcopy(data, cp, datalen);
                        cp += datalen;
@@ -221,21 +226,22 @@ res_mkquery(op, dname, class, type, data, datalen, newrr_in, buf, buflen)
                        return (-1);
                cp += n;
                __putshort(newrr->r_type, cp);
-                cp += INT16SZ;
-                __putshort(newrr->r_class, cp);
-                cp += INT16SZ;
+               cp += INT16SZ;
+               __putshort(newrr->r_class, cp);
+               cp += INT16SZ;
                __putlong(0, cp);
                cp += INT32SZ;
                __putshort(newrr->r_size, cp);
-                cp += INT16SZ;
+               cp += INT16SZ;
                if (newrr->r_size) {
                        bcopy(newrr->r_data, cp, newrr->r_size);
                        cp += newrr->r_size;
                }
                hp->ancount = htons(0);
                break;
-
 #endif /* ALLOW_UPDATES */
+       default:
+               return (-1);
        }
        return (cp - buf);
 }
index 9a3bafe..03055d3 100644 (file)
@@ -128,10 +128,10 @@ static int vc = 0;        /* is the socket a virtual ciruit? */
        int save = errno;
 
        if (_res.options & RES_DEBUG) {
-               fprintf(file, "res_send: %s ([%s].%d): %s\n",
+               fprintf(file, "res_send: %s ([%s].%u): %s\n",
                        string,
                        inet_ntoa(address.sin_addr),
-                       address.sin_port,
+                       ntohs(address.sin_port),
                        strerror(error));
        }
        errno = save;
@@ -159,6 +159,7 @@ void
 res_send_setqhook(hook)
        res_send_qhook hook;
 {
+
        Qhook = hook;
 }
 
@@ -166,11 +167,12 @@ void
 res_send_setrhook(hook)
        res_send_rhook hook;
 {
+
        Rhook = hook;
 }
 
 /* int
- * our_server(ina)
+ * res_isourserver(ina)
  *     looks up "ina" in _res.ns_addr_list[]
  * returns:
  *     0  : not found
@@ -178,8 +180,8 @@ res_send_setrhook(hook)
  * author:
  *     paul vixie, 29may94
  */
-static int
-our_server(inp)
+int
+res_isourserver(inp)
        const struct sockaddr_in *inp;
 {
        struct sockaddr_in ina;
@@ -202,15 +204,17 @@ our_server(inp)
 }
 
 /* int
- * name_in_query(name, type, class, buf, eom)
+ * res_nameinquery(name, type, class, buf, eom)
  *     look for (name,type,class) in the query section of packet (buf,eom)
  * returns:
  *     -1 : format error
  *     0  : not found
  *     >0 : found
+ * author:
+ *     paul vixie, 29may94
  */
-static int
-name_in_query(name, type, class, buf, eom)
+int
+res_nameinquery(name, type, class, buf, eom)
        const char *name;
        register int type, class;
        const u_char *buf, *eom;
@@ -237,16 +241,18 @@ name_in_query(name, type, class, buf, eom)
 }
 
 /* int
- * queries_match(buf1, eom1, buf2, eom2)
+ * res_queriesmatch(buf1, eom1, buf2, eom2)
  *     is there a 1:1 mapping of (name,type,class)
  *     in (buf1,eom1) and (buf2,eom2)?
  * returns:
  *     -1 : format error
  *     0  : not a 1:1 mapping
  *     >0 : is a 1:1 mapping
+ * author:
+ *     paul vixie, 29may94
  */
-static int
-queries_match(buf1, eom1, buf2, eom2)
+int
+res_queriesmatch(buf1, eom1, buf2, eom2)
        const u_char *buf1, *eom1;
        const u_char *buf2, *eom2;
 {
@@ -265,7 +271,7 @@ queries_match(buf1, eom1, buf2, eom2)
                cp += n;
                ttype = _getshort(cp);  cp += INT16SZ;
                tclass = _getshort(cp); cp += INT16SZ;
-               if (!name_in_query(tname, ttype, tclass, buf2, eom2))
+               if (!res_nameinquery(tname, ttype, tclass, buf2, eom2))
                        return (0);
        }
        return (1);
@@ -273,28 +279,25 @@ queries_match(buf1, eom1, buf2, eom2)
 
 int
 res_send(buf, buflen, ans, anssiz)
-       const u_char    *buf;
-       int             buflen;
-       u_char          *ans;
-       int             anssiz;
+       const u_char *buf;
+       int buflen;
+       u_char *ans;
+       int anssiz;
 {
-       HEADER          *hp = (HEADER *) buf;
-       HEADER          *anhp = (HEADER *) ans;
-       int             gotsomewhere = 0,
-                       connreset = 0,
-                       terrno = ETIMEDOUT;
-
-       register int    n;
-       int             try, v_circuit, resplen, ns;
-       u_int           badns;  /* XXX NSMAX can't exceed #/bits in this var */
+       HEADER *hp = (HEADER *) buf;
+       HEADER *anhp = (HEADER *) ans;
+       int gotsomewhere, connreset, terrno, try, v_circuit, resplen, ns;
+       register int n;
+       u_int badns;    /* XXX NSMAX can't exceed #/bits in this var */
 
        DprintQ((_res.options & RES_DEBUG) || (_res.pfcode & RES_PRF_QUERY),
                (stdout, ";; res_send()\n"), buf);
-       if (!(_res.options & RES_INIT)) {
-               if (res_init() == -1)
-                       return (-1);
-       }
+       if (!(_res.options & RES_INIT) && res_init() == -1)
+               return (-1);
        v_circuit = (_res.options & RES_USEVC) || buflen > PACKETSZ;
+       gotsomewhere = 0;
+       connreset = 0;
+       terrno = ETIMEDOUT;
        badns = 0;
 
        /*
@@ -304,7 +307,7 @@ res_send(buf, buflen, ans, anssiz)
            for (ns = 0; ns < _res.nscount; ns++) {
                struct sockaddr_in *nsap = &_res.nsaddr_list[ns];
     same_ns:
-               if (badns & (1<<ns)) {
+               if (badns & (1 << ns)) {
                        _res_close();
                        goto next_ns;
                }
@@ -315,12 +318,8 @@ res_send(buf, buflen, ans, anssiz)
                        do {
                                res_sendhookact act;
 
-                               act = (*Qhook)(&nsap,
-                                              &buf,
-                                              &buflen,
-                                              ans,
-                                              anssiz,
-                                              &resplen);
+                               act = (*Qhook)(&nsap, &buf, &buflen,
+                                              ans, anssiz, &resplen);
                                switch (act) {
                                case res_goahead:
                                        done = 1;
@@ -345,13 +344,13 @@ res_send(buf, buflen, ans, anssiz)
 
                Dprint(_res.options & RES_DEBUG,
                       (stdout, ";; Querying server (# %d) address = %s\n",
-                       ns+1, inet_ntoa(nsap->sin_addr)));
+                       ns + 1, inet_ntoa(nsap->sin_addr)));
 
                if (v_circuit) {
-                       int             truncated;
-                       struct iovec    iov[2];
-                       u_short         len;
-                       u_char          *cp;
+                       int truncated;
+                       struct iovec iov[2];
+                       u_short len;
+                       u_char *cp;
 
                        /*
                         * Use virtual circuit;
@@ -369,14 +368,12 @@ res_send(buf, buflen, ans, anssiz)
                                        Perror(stderr, "socket(vc)", errno);
                                        return (-1);
                                }
-                               if (connect(s,
-                                           (struct sockaddr *)nsap,
-                                           sizeof(struct sockaddr))
-                                   < 0) {
+                               if (connect(s, (struct sockaddr *)nsap,
+                                           sizeof(struct sockaddr)) < 0) {
                                        terrno = errno;
                                        Aerror(stderr, "connect/vc",
                                               errno, *nsap);
-                                       badns |= (1<<ns);
+                                       badns |= (1 << ns);
                                        _res_close();
                                        goto next_ns;
                                }
@@ -393,7 +390,7 @@ res_send(buf, buflen, ans, anssiz)
                        if (writev(s, iov, 2) != (INT16SZ + buflen)) {
                                terrno = errno;
                                Perror(stderr, "write failed", errno);
-                               badns |= (1<<ns);
+                               badns |= (1 << ns);
                                _res_close();
                                goto next_ns;
                        }
@@ -439,8 +436,7 @@ res_send(buf, buflen, ans, anssiz)
                                len = resplen;
                        cp = ans;
                        while (len != 0 &&
-                              (n = read(s, (char *)cp, (int)len)) > 0
-                              ) {
+                              (n = read(s, (char *)cp, (int)len)) > 0) {
                                cp += n;
                                len -= n;
                        }
@@ -458,7 +454,7 @@ res_send(buf, buflen, ans, anssiz)
                                anhp->tc = 1;
                                len = resplen - anssiz;
                                while (len != 0) {
-                                       char junk[512];
+                                       char junk[PACKETSZ];
 
                                        n = (len > sizeof(junk)
                                             ? sizeof(junk)
@@ -473,10 +469,10 @@ res_send(buf, buflen, ans, anssiz)
                        /*
                         * Use datagrams.
                         */
-                       struct timeval  timeout;
-                       fd_set          dsmask;
+                       struct timeval timeout;
+                       fd_set dsmask;
                        struct sockaddr_in from;
-                       int             fromlen;
+                       int fromlen;
 
                        if ((s < 0) || vc) {
                                if (vc)
@@ -510,23 +506,21 @@ res_send(buf, buflen, ans, anssiz)
                                 * receive a response from another server.
                                 */
                                if (!connected) {
-                                       if (connect(s,
-                                                   (struct sockaddr *)nsap,
+                                       if (connect(s, (struct sockaddr *)nsap,
                                                    sizeof(struct sockaddr)
-                                                   ) < 0
-                                           ) {
+                                                   ) < 0) {
                                                Aerror(stderr,
                                                       "connect(dg)",
                                                       errno, *nsap);
-                                               badns |= (1<<ns);
+                                               badns |= (1 << ns);
                                                _res_close();
                                                goto next_ns;
                                        }
                                        connected = 1;
                                }
-                               if (send(s, buf, buflen, 0) != buflen) {
+                               if (send(s, (char*)buf, buflen, 0) != buflen) {
                                        Perror(stderr, "send", errno);
-                                       badns |= (1<<ns);
+                                       badns |= (1 << ns);
                                        _res_close();
                                        goto next_ns;
                                }
@@ -559,12 +553,12 @@ res_send(buf, buflen, ans, anssiz)
                                        connected = 0;
                                        errno = 0;
                                }
-                               if (sendto(s, buf, buflen, 0,
+                               if (sendto(s, (char*)buf, buflen, 0,
                                           (struct sockaddr *)nsap,
                                           sizeof(struct sockaddr))
                                    != buflen) {
                                        Aerror(stderr, "sendto", errno, *nsap);
-                                       badns |= (1<<ns);
+                                       badns |= (1 << ns);
                                        _res_close();
                                        goto next_ns;
                                }
@@ -594,14 +588,13 @@ res_send(buf, buflen, ans, anssiz)
                                 * timeout
                                 */
                                Dprint(_res.options & RES_DEBUG,
-                                      (stdout, ";; timeout\n")
-                                      );
+                                      (stdout, ";; timeout\n"));
                                gotsomewhere = 1;
                                _res_close();
                                goto next_ns;
                        }
                        fromlen = sizeof(struct sockaddr_in);
-                       resplen = recvfrom(s, ans, anssiz, 0,
+                       resplen = recvfrom(s, (char*)ans, anssiz, 0,
                                           (struct sockaddr *)&from, &fromlen);
                        if (resplen <= 0) {
                                Perror(stderr, "recvfrom", errno);
@@ -623,7 +616,7 @@ res_send(buf, buflen, ans, anssiz)
                        }
 #if CHECK_SRVR_ADDR
                        if (!(_res.options & RES_INSECURE1) &&
-                           !our_server(&from)) {
+                           !res_isourserver(&from)) {
                                /*
                                 * response from wrong server? ignore it.
                                 * XXX - potential security hazard could
@@ -637,8 +630,8 @@ res_send(buf, buflen, ans, anssiz)
                        }
 #endif
                        if (!(_res.options & RES_INSECURE2) &&
-                           !queries_match(buf, buf + buflen,
-                                          ans, ans + anssiz)) {
+                           !res_queriesmatch(buf, buf + buflen,
+                                             ans, ans + anssiz)) {
                                /*
                                 * response contains wrong query? ignore it.
                                 * XXX - potential security hazard could
@@ -656,9 +649,11 @@ res_send(buf, buflen, ans, anssiz)
                                DprintQ(_res.options & RES_DEBUG,
                                        (stdout, "server rejected query:\n"),
                                        ans);
-                               badns |= (1<<ns);
+                               badns |= (1 << ns);
                                _res_close();
-                               goto next_ns;
+                               /* don't retry if called from dig */
+                               if (!_res.pfcode)
+                                       goto next_ns;
                        }
                        if (!(_res.options & RES_IGNTC) && anhp->tc) {
                                /*
@@ -666,8 +661,7 @@ res_send(buf, buflen, ans, anssiz)
                                 * use TCP with same server.
                                 */
                                Dprint(_res.options & RES_DEBUG,
-                                      (stdout, ";; truncated answer\n")
-                                      );
+                                      (stdout, ";; truncated answer\n"));
                                v_circuit = 1;
                                _res_close();
                                goto same_ns;
@@ -695,12 +689,8 @@ res_send(buf, buflen, ans, anssiz)
                        do {
                                res_sendhookact act;
 
-                               act = (*Rhook)(nsap,
-                                              buf,
-                                              buflen,
-                                              ans,
-                                              anssiz,
-                                              &resplen);
+                               act = (*Rhook)(nsap, buf, buflen,
+                                              ans, anssiz, &resplen);
                                switch (act) {
                                case res_goahead:
                                case res_done:
@@ -727,14 +717,13 @@ res_send(buf, buflen, ans, anssiz)
           } /*foreach ns*/
        } /*foreach retry*/
        _res_close();
-       if (!v_circuit) {
+       if (!v_circuit)
                if (!gotsomewhere)
                        errno = ECONNREFUSED;   /* no nameservers found */
                else
                        errno = ETIMEDOUT;      /* no answer obtained */
-       } else {
+       else
                errno = terrno;
-       }
        return (-1);
 }