1 /*- 2 * Copyright (c) 1985, 1989 Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 */ 7 8 #if defined(LIBC_SCCS) && !defined(lint) 9 static char sccsid[] = "@(#)res_init.c 6.15 (Berkeley) 02/24/91"; 10 #endif /* LIBC_SCCS and not lint */ 11 12 #include <sys/param.h> 13 #include <sys/socket.h> 14 #include <netinet/in.h> 15 #include <arpa/inet.h> 16 #include <arpa/nameser.h> 17 #include <resolv.h> 18 #include <unistd.h> 19 #include <stdio.h> 20 #include <stdlib.h> 21 #include <string.h> 22 23 /* 24 * Resolver state default settings 25 */ 26 27 struct state _res = { 28 RES_TIMEOUT, /* retransmition time interval */ 29 4, /* number of times to retransmit */ 30 RES_DEFAULT, /* options flags */ 31 1, /* number of name servers */ 32 }; 33 34 /* 35 * Set up default settings. If the configuration file exist, the values 36 * there will have precedence. Otherwise, the server address is set to 37 * INADDR_ANY and the default domain name comes from the gethostname(). 38 * 39 * The configuration file should only be used if you want to redefine your 40 * domain or run without a server on your machine. 41 * 42 * Return 0 if completes successfully, -1 on error 43 */ 44 res_init() 45 { 46 register FILE *fp; 47 register char *cp, **pp; 48 register int n; 49 char buf[BUFSIZ]; 50 int nserv = 0; /* number of nameserver records read from file */ 51 int haveenv = 0; 52 int havesearch = 0; 53 54 _res.nsaddr.sin_addr.s_addr = INADDR_ANY; 55 _res.nsaddr.sin_family = AF_INET; 56 _res.nsaddr.sin_port = htons(NAMESERVER_PORT); 57 _res.nscount = 1; 58 59 /* Allow user to override the local domain definition */ 60 if ((cp = getenv("LOCALDOMAIN")) != NULL) { 61 (void)strncpy(_res.defdname, cp, sizeof(_res.defdname)); 62 haveenv++; 63 } 64 65 if ((fp = fopen(_PATH_RESCONF, "r")) != NULL) { 66 /* read the config file */ 67 while (fgets(buf, sizeof(buf), fp) != NULL) { 68 /* read default domain name */ 69 if (!strncmp(buf, "domain", sizeof("domain") - 1)) { 70 if (haveenv) /* skip if have from environ */ 71 continue; 72 cp = buf + sizeof("domain") - 1; 73 while (*cp == ' ' || *cp == '\t') 74 cp++; 75 if ((*cp == '\0') || (*cp == '\n')) 76 continue; 77 (void)strncpy(_res.defdname, cp, sizeof(_res.defdname) - 1); 78 if ((cp = index(_res.defdname, '\n')) != NULL) 79 *cp = '\0'; 80 havesearch = 0; 81 continue; 82 } 83 /* set search list */ 84 if (!strncmp(buf, "search", sizeof("search") - 1)) { 85 if (haveenv) /* skip if have from environ */ 86 continue; 87 cp = buf + sizeof("search") - 1; 88 while (*cp == ' ' || *cp == '\t') 89 cp++; 90 if ((*cp == '\0') || (*cp == '\n')) 91 continue; 92 (void)strncpy(_res.defdname, cp, sizeof(_res.defdname) - 1); 93 if ((cp = index(_res.defdname, '\n')) != NULL) 94 *cp = '\0'; 95 /* 96 * Set search list to be blank-separated strings 97 * on rest of line. 98 */ 99 cp = _res.defdname; 100 pp = _res.dnsrch; 101 *pp++ = cp; 102 for (n = 0; *cp && pp < _res.dnsrch + MAXDNSRCH; cp++) { 103 if (*cp == ' ' || *cp == '\t') { 104 *cp = 0; 105 n = 1; 106 } else if (n) { 107 *pp++ = cp; 108 n = 0; 109 } 110 } 111 /* null terminate last domain if there are excess */ 112 while (*cp != '\0' && *cp != ' ' && *cp != '\t') 113 cp++; 114 *cp = '\0'; 115 *pp++ = 0; 116 havesearch = 1; 117 continue; 118 } 119 /* read nameservers to query */ 120 if (!strncmp(buf, "nameserver", sizeof("nameserver") - 1) && 121 nserv < MAXNS) { 122 cp = buf + sizeof("nameserver") - 1; 123 while (*cp == ' ' || *cp == '\t') 124 cp++; 125 if ((*cp == '\0') || (*cp == '\n')) 126 continue; 127 if ((_res.nsaddr_list[nserv].sin_addr.s_addr = 128 inet_addr(cp)) == (unsigned)-1) { 129 _res.nsaddr_list[nserv].sin_addr.s_addr 130 = INADDR_ANY; 131 continue; 132 } 133 _res.nsaddr_list[nserv].sin_family = AF_INET; 134 _res.nsaddr_list[nserv].sin_port = htons(NAMESERVER_PORT); 135 nserv++; 136 continue; 137 } 138 } 139 if (nserv > 1) 140 _res.nscount = nserv; 141 (void) fclose(fp); 142 } 143 if (_res.defdname[0] == 0) { 144 if (gethostname(buf, sizeof(_res.defdname)) == 0 && 145 (cp = index(buf, '.'))) 146 (void)strcpy(_res.defdname, cp + 1); 147 } 148 149 /* find components of local domain that might be searched */ 150 if (havesearch == 0) { 151 pp = _res.dnsrch; 152 *pp++ = _res.defdname; 153 for (cp = _res.defdname, n = 0; *cp; cp++) 154 if (*cp == '.') 155 n++; 156 cp = _res.defdname; 157 for (; n >= LOCALDOMAINPARTS && pp < _res.dnsrch + MAXDFLSRCH; 158 n--) { 159 cp = index(cp, '.'); 160 *pp++ = ++cp; 161 } 162 *pp++ = 0; 163 } 164 _res.options |= RES_INIT; 165 return (0); 166 } 167