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