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.10 (Berkeley) 12/14/89"; 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 havesearch = 0; 62 63 _res.nsaddr.sin_addr.s_addr = INADDR_ANY; 64 _res.nsaddr.sin_family = AF_INET; 65 _res.nsaddr.sin_port = htons(NAMESERVER_PORT); 66 _res.nscount = 1; 67 68 /* Allow user to override the local domain definition */ 69 if ((cp = getenv("LOCALDOMAIN")) != NULL) 70 (void)strncpy(_res.defdname, cp, sizeof(_res.defdname)); 71 72 if ((fp = fopen(_PATH_RESCONF, "r")) != NULL) { 73 /* read the config file */ 74 while (fgets(buf, sizeof(buf), fp) != NULL) { 75 /* read default domain name */ 76 if (!strncmp(buf, "domain", sizeof("domain") - 1)) { 77 if (_res.defdname[0]) /* skip if have from environ */ 78 continue; 79 cp = buf + sizeof("domain") - 1; 80 while (*cp == ' ' || *cp == '\t') 81 cp++; 82 if (*cp == '\0') 83 continue; 84 (void)strncpy(_res.defdname, cp, sizeof(_res.defdname) - 1); 85 if ((cp = index(_res.defdname, '\n')) != NULL) 86 *cp = '\0'; 87 havesearch = 0; 88 continue; 89 } 90 /* set search list */ 91 if (!strncmp(buf, "search", sizeof("search") - 1)) { 92 cp = buf + sizeof("search") - 1; 93 while (*cp == ' ' || *cp == '\t') 94 cp++; 95 if (*cp == '\0') 96 continue; 97 (void)strncpy(_res.defdname, cp, sizeof(_res.defdname) - 1); 98 if ((cp = index(_res.defdname, '\n')) != NULL) 99 *cp = '\0'; 100 /* 101 * Set search list to be blank-separated strings 102 * on rest of line. 103 */ 104 cp = _res.defdname; 105 pp = _res.dnsrch; 106 *pp++ = cp; 107 for (n = 0; *cp && pp < _res.dnsrch + MAXDNSRCH; cp++) { 108 if (*cp == ' ' || *cp == '\t') { 109 *cp = 0; 110 n = 1; 111 } else if (n) { 112 *pp++ = cp; 113 n = 0; 114 } 115 } 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') 126 continue; 127 if ((_res.nsaddr_list[nserv].sin_addr.s_addr = 128 inet_addr(cp)) == (unsigned)-1) 129 continue; 130 _res.nsaddr_list[nserv].sin_family = AF_INET; 131 _res.nsaddr_list[nserv].sin_port = htons(NAMESERVER_PORT); 132 nserv++; 133 continue; 134 } 135 } 136 if (nserv > 1) 137 _res.nscount = nserv; 138 (void) fclose(fp); 139 } 140 if (_res.defdname[0] == 0) { 141 if (gethostname(buf, sizeof(_res.defdname)) == 0 && 142 (cp = index(buf, '.'))) 143 (void)strcpy(_res.defdname, cp + 1); 144 } 145 146 /* find components of local domain that might be searched */ 147 if (havesearch == 0) { 148 pp = _res.dnsrch; 149 *pp++ = _res.defdname; 150 for (cp = _res.defdname, n = 0; *cp; cp++) 151 if (*cp == '.') 152 n++; 153 cp = _res.defdname; 154 for (; n >= LOCALDOMAINPARTS && pp < _res.dnsrch + MAXDNSRCH; 155 n--) { 156 cp = index(cp, '.'); 157 *pp++ = ++cp; 158 } 159 } 160 _res.options |= RES_INIT; 161 return (0); 162 } 163