BSD 4_3_Tahoe release
[unix-history] / usr / src / lib / libc / net / res_init.c
index aa26864..afdbce3 100644 (file)
@@ -1,20 +1,30 @@
 /*
  * Copyright (c) 1985 Regents of the University of California.
 /*
  * Copyright (c) 1985 Regents of the University of California.
- * All rights reserved.  The Berkeley software License Agreement
- * specifies the terms and conditions for redistribution.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, Berkeley.  The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  */
 
  */
 
-#ifndef lint
-static char sccsid[] = "@(#)res_init.c 5.6 (Berkeley) %G%";
-#endif not lint
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)res_init.c 6.9 (Berkeley) 6/27/88";
+#endif /* LIBC_SCCS and not lint */
 
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <stdio.h>
 
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <stdio.h>
-#include <netdb.h>
 #include <arpa/nameser.h>
 #include <arpa/nameser.h>
-#include <arpa/resolv.h>
+#include <resolv.h>
 
 /*
  * Resolver configuration file. Contains the address of the
 
 /*
  * Resolver configuration file. Contains the address of the
@@ -22,19 +32,19 @@ static char sccsid[] = "@(#)res_init.c      5.6 (Berkeley) %G%";
  * non fully qualified domain names.
  */
 
  * non fully qualified domain names.
  */
 
-#ifdef CONFFILE
-char   *conffile = CONFFILE;
-#else
-char   *conffile = "/etc/resolv.conf";
+#ifndef        CONFFILE
+#define        CONFFILE        "/etc/resolv.conf"
 #endif
 
 /*
  * Resolver state default settings
  */
 #endif
 
 /*
  * Resolver state default settings
  */
+
 struct state _res = {
 struct state _res = {
-       10,
-       4,
-       RES_RECURSE|RES_DEFNAMES,
+    RES_TIMEOUT,                       /* retransmition time interval */
+    4,                                 /* number of times to retransmit */
+    RES_DEFAULT,               /* options flags */
+    1,                                 /* number of name servers */
 };
 
 /*
 };
 
 /*
@@ -49,66 +59,85 @@ struct state _res = {
  */
 res_init()
 {
  */
 res_init()
 {
-       FILE *fp;
-       char buf[BUFSIZ], *cp;
-       extern u_long inet_addr();
-       extern char *index();
-       extern char *strcpy(), *strncpy();
-       struct servent *serv;
-#ifdef DEBUG
-       extern char *getenv();
-#endif
+    register FILE *fp;
+    register char *cp, **pp;
+    char buf[BUFSIZ];
+    extern u_long inet_addr();
+    extern char *index();
+    extern char *strcpy(), *strncpy();
+    extern char *getenv();
+    int n = 0;    /* number of nameserver records read from file */
 
 
-       _res.nsaddr.sin_family = AF_INET;
-       _res.nsaddr.sin_addr.s_addr = INADDR_ANY;
-       _res.defdname[0] = '\0';
-       if ((serv = getservbyname(NAMESERVER_SNAME, "tcp")) == NULL)
-               return(-1);
-       _res.nsaddr.sin_port = (u_short)serv->s_port;
-
-       if ((fp = fopen(conffile, "r")) != NULL) {
-               while (fgets(buf, sizeof(buf), fp) != NULL) {
-                       if (!strncmp(buf, "domain", sizeof("domain") - 1)) {
-                               cp = buf + sizeof("domain") - 1;
-                               while (*cp == ' ' || *cp == '\t')
-                                       cp++;
-                               if (*cp == '\0')
-                                       continue;
-                               (void)strncpy(_res.defdname, cp,
-                                       sizeof(_res.defdname));
-                               _res.defdname[sizeof(_res.defdname) - 1] = '\0';
-                               if ((cp = index(_res.defdname, '\n')) != NULL)
-                                       *cp = '\0';
-                               continue;
-                       }
-                       if (!strncmp(buf, "resolver", sizeof("resolver") - 1)) {
-                               cp = buf + sizeof("resolver") - 1;
-                               while (*cp == ' ' || *cp == '\t')
-                                       cp++;
-                               if (*cp == '\0')
-                                       continue;
-                               _res.nsaddr.sin_addr.s_addr = inet_addr(cp);
-                               if (_res.nsaddr.sin_addr.s_addr == (unsigned)-1)
-                                       _res.nsaddr.sin_addr.s_addr =
-                                               INADDR_ANY;
-                               continue;
-                       }
-               }
-               (void) fclose(fp);
-       }
-       if (_res.defdname[0] == 0) {
-               if (gethostname(buf, sizeof(_res.defdname)) == -1)
-                       return(-1);
-               if ((cp = index(buf, '.')) == NULL)
-                       return(-1);
-               (void)strcpy(_res.defdname, cp + 1);
-       }
+    _res.nsaddr.sin_addr.s_addr = INADDR_ANY;
+    _res.nsaddr.sin_family = AF_INET;
+    _res.nsaddr.sin_port = htons(NAMESERVER_PORT);
+    _res.nscount = 1;
+    _res.defdname[0] = '\0';
 
 
+    if ((fp = fopen(CONFFILE, "r")) != NULL) {
+        /* read the config file */
+        while (fgets(buf, sizeof(buf), fp) != NULL) {
+            /* read default domain name */
+            if (!strncmp(buf, "domain", sizeof("domain") - 1)) {
+                cp = buf + sizeof("domain") - 1;
+                while (*cp == ' ' || *cp == '\t')
+                    cp++;
+                if (*cp == '\0')
+                    continue;
+                (void)strncpy(_res.defdname, cp, sizeof(_res.defdname));
+                _res.defdname[sizeof(_res.defdname) - 1] = '\0';
+                if ((cp = index(_res.defdname, '\n')) != NULL)
+                    *cp = '\0';
+                continue;
+            }
+            /* read nameservers to query */
+            if (!strncmp(buf, "nameserver", 
+               sizeof("nameserver") - 1) && (n < MAXNS)) {
+                cp = buf + sizeof("nameserver") - 1;
+                while (*cp == ' ' || *cp == '\t')
+                    cp++;
+                if (*cp == '\0')
+                    continue;
+                _res.nsaddr_list[n].sin_addr.s_addr = inet_addr(cp);
+                if (_res.nsaddr_list[n].sin_addr.s_addr == (unsigned)-1) 
+                    _res.nsaddr_list[n].sin_addr.s_addr = INADDR_ANY;
+                _res.nsaddr_list[n].sin_family = AF_INET;
+                _res.nsaddr_list[n].sin_port = htons(NAMESERVER_PORT);
+                if ( ++n >= MAXNS) { 
+                    n = MAXNS;
 #ifdef DEBUG
 #ifdef DEBUG
-       /* Allow user to override the local domain definition */
-       if ((cp = getenv("LOCALDOMAIN")) != NULL)
-               (void)strncpy(_res.defdname, cp, sizeof(_res.defdname));
-#endif
-       _res.options |= RES_INIT;
-       return(0);
+                    if ( _res.options & RES_DEBUG )
+                        printf("MAXNS reached, reading resolv.conf\n");
+#endif DEBUG
+                }
+                continue;
+            }
+        }
+        if ( n > 1 ) 
+            _res.nscount = n;
+        (void) fclose(fp);
+    }
+    if (_res.defdname[0] == 0) {
+        if (gethostname(buf, sizeof(_res.defdname)) == 0 &&
+           (cp = index(buf, '.')))
+             (void)strcpy(_res.defdname, cp + 1);
+    }
+
+    /* Allow user to override the local domain definition */
+    if ((cp = getenv("LOCALDOMAIN")) != NULL)
+        (void)strncpy(_res.defdname, cp, sizeof(_res.defdname));
+
+    /* find components of local domain that might be searched */
+    pp = _res.dnsrch;
+    *pp++ = _res.defdname;
+    for (cp = _res.defdname, n = 0; *cp; cp++)
+       if (*cp == '.')
+           n++;
+    cp = _res.defdname;
+    for (; n >= LOCALDOMAINPARTS && pp < _res.dnsrch + MAXDNSRCH; n--) {
+       cp = index(cp, '.');
+       *pp++ = ++cp;
+    }
+    _res.options |= RES_INIT;
+    return(0);
 }
 }