BSD 4_3_Tahoe release
[unix-history] / usr / src / lib / libc / net / res_init.c
index 5597768..afdbce3 100644 (file)
@@ -1,19 +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.5 (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 <arpa/nameser.h>
 
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <stdio.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
@@ -21,50 +32,112 @@ static char sccsid[] = "@(#)res_init.c     5.5 (Berkeley) %G%";
  * non fully qualified domain names.
  */
 
  * non fully qualified domain names.
  */
 
-#ifdef CONFFILE
-char   *conffile = CONFFILE;
-#else
-char   *conffile = "/usr/local/lib/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 */
 };
 
 /*
 };
 
 /*
- * Read the configuration file for default settings.
- * Return true if the name server address is initialized.
+ * Set up default settings.  If the configuration file exist, the values
+ * there will have precedence.  Otherwise, the server address is set to
+ * INADDR_ANY and the default domain name comes from the gethostname().
+ *
+ * The configuration file should only be used if you want to redefine your
+ * domain or run without a server on your machine.
+ *
+ * Return 0 if completes successfully, -1 on error
  */
 res_init()
 {
  */
 res_init()
 {
-       FILE *fp;
-       char buf[BUFSIZ], *cp;
-       int n;
-       extern u_long inet_addr();
-       extern char *index(), *getenv();
+    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_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';
 
 
-       _res.options |= RES_INIT;
-       _res.nsaddr.sin_family = AF_INET;
-       _res.nsaddr.sin_addr.s_addr = INADDR_ANY;
-       _res.nsaddr.sin_port = htons(NAMESERVER_PORT);
+    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
+                    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);
+    }
 
 
-       /* first try reading the config file */
-       if ((fp = fopen(conffile, "r")) != NULL) {
-               if (fgets(_res.defdname, sizeof(_res.defdname), fp) == NULL)
-                       _res.defdname[0] = '\0';
-               else if ((cp = index(_res.defdname, '\n')) != NULL)
-                       *cp = '\0';
-               if (fgets(buf, sizeof (buf), fp) != NULL)
-                       _res.nsaddr.sin_addr.s_addr = inet_addr(buf);
-               (void) fclose(fp);
-       }
+    /* Allow user to override the local domain definition */
+    if ((cp = getenv("LOCALDOMAIN")) != NULL)
+        (void)strncpy(_res.defdname, cp, sizeof(_res.defdname));
 
 
-       /* Allow user to override the local domain definition */
-       if ((cp = getenv("LOCALDOMAIN")) != NULL)
-               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);
 }
 }