118548Sralph /* 221386Sdist * Copyright (c) 1985 Regents of the University of California. 3*33679Sbostic * All rights reserved. 4*33679Sbostic * 5*33679Sbostic * Redistribution and use in source and binary forms are permitted 6*33679Sbostic * provided that this notice is preserved and that due credit is given 7*33679Sbostic * to the University of California at Berkeley. The name of the University 8*33679Sbostic * may not be used to endorse or promote products derived from this 9*33679Sbostic * software without specific prior written permission. This software 10*33679Sbostic * is provided ``as is'' without express or implied warranty. 1118548Sralph */ 1218548Sralph 1326633Sdonn #if defined(LIBC_SCCS) && !defined(lint) 14*33679Sbostic static char sccsid[] = "@(#)res_init.c 6.8 (Berkeley) 03/07/88"; 15*33679Sbostic #endif /* LIBC_SCCS and not lint */ 1621386Sdist 1718142Sralph #include <sys/types.h> 1818142Sralph #include <sys/socket.h> 1918142Sralph #include <netinet/in.h> 2018142Sralph #include <stdio.h> 2124081Skjd #include <arpa/nameser.h> 2226902Skjd #include <resolv.h> 2318142Sralph 2418142Sralph /* 2524111Skjd * Resolver configuration file. Contains the address of the 2624111Skjd * inital name server to query and the default domain for 2724111Skjd * non fully qualified domain names. 2824111Skjd */ 2924111Skjd 3032294Sbostic #ifndef CONFFILE 3132294Sbostic #define CONFFILE "/etc/resolv.conf" 3224111Skjd #endif 3324111Skjd 3424111Skjd /* 3518142Sralph * Resolver state default settings 3618142Sralph */ 3725242Skjd 3818142Sralph struct state _res = { 3931112Skarels RES_TIMEOUT, /* retransmition time interval */ 4031112Skarels 4, /* number of times to retransmit */ 4131112Skarels RES_DEFAULT, /* options flags */ 4231112Skarels 1, /* number of name servers */ 4318142Sralph }; 4418142Sralph 4518142Sralph /* 4624736Sbloom * Set up default settings. If the configuration file exist, the values 4724736Sbloom * there will have precedence. Otherwise, the server address is set to 4824736Sbloom * INADDR_ANY and the default domain name comes from the gethostname(). 4924736Sbloom * 5024736Sbloom * The configuration file should only be used if you want to redefine your 5124736Sbloom * domain or run without a server on your machine. 5224736Sbloom * 5324736Sbloom * Return 0 if completes successfully, -1 on error 5418142Sralph */ 5518142Sralph res_init() 5618142Sralph { 5725242Skjd register FILE *fp; 5831112Skarels register char *cp, **pp; 5931112Skarels char buf[BUFSIZ]; 6025242Skjd extern u_long inet_addr(); 6125242Skjd extern char *index(); 6225242Skjd extern char *strcpy(), *strncpy(); 6325242Skjd extern char *getenv(); 6425242Skjd int n = 0; /* number of nameserver records read from file */ 6518142Sralph 6625242Skjd _res.nsaddr.sin_addr.s_addr = INADDR_ANY; 6725242Skjd _res.nsaddr.sin_family = AF_INET; 6825242Skjd _res.nsaddr.sin_port = htons(NAMESERVER_PORT); 6925242Skjd _res.nscount = 1; 7025242Skjd _res.defdname[0] = '\0'; 7118142Sralph 7232294Sbostic if ((fp = fopen(CONFFILE, "r")) != NULL) { 7325242Skjd /* read the config file */ 7425242Skjd while (fgets(buf, sizeof(buf), fp) != NULL) { 7525242Skjd /* read default domain name */ 7625242Skjd if (!strncmp(buf, "domain", sizeof("domain") - 1)) { 7725242Skjd cp = buf + sizeof("domain") - 1; 7825242Skjd while (*cp == ' ' || *cp == '\t') 7925242Skjd cp++; 8025242Skjd if (*cp == '\0') 8125242Skjd continue; 8225242Skjd (void)strncpy(_res.defdname, cp, sizeof(_res.defdname)); 8325242Skjd _res.defdname[sizeof(_res.defdname) - 1] = '\0'; 8425242Skjd if ((cp = index(_res.defdname, '\n')) != NULL) 8525242Skjd *cp = '\0'; 8625242Skjd continue; 8725242Skjd } 8825242Skjd /* read nameservers to query */ 8925242Skjd if (!strncmp(buf, "nameserver", 9025242Skjd sizeof("nameserver") - 1) && (n < MAXNS)) { 9125242Skjd cp = buf + sizeof("nameserver") - 1; 9225242Skjd while (*cp == ' ' || *cp == '\t') 9325242Skjd cp++; 9425242Skjd if (*cp == '\0') 9525242Skjd continue; 9625242Skjd _res.nsaddr_list[n].sin_addr.s_addr = inet_addr(cp); 9725242Skjd if (_res.nsaddr_list[n].sin_addr.s_addr == (unsigned)-1) 9825242Skjd _res.nsaddr_list[n].sin_addr.s_addr = INADDR_ANY; 9926902Skjd _res.nsaddr_list[n].sin_family = AF_INET; 10026902Skjd _res.nsaddr_list[n].sin_port = htons(NAMESERVER_PORT); 10126902Skjd if ( ++n >= MAXNS) { 10226902Skjd n = MAXNS; 10325242Skjd #ifdef DEBUG 10426902Skjd if ( _res.options & RES_DEBUG ) 10526902Skjd printf("MAXNS reached, reading resolv.conf\n"); 10625242Skjd #endif DEBUG 10725242Skjd } 10825242Skjd continue; 10925242Skjd } 11025242Skjd } 11125242Skjd if ( n > 1 ) 11225242Skjd _res.nscount = n; 11325242Skjd (void) fclose(fp); 11425242Skjd } 11525242Skjd if (_res.defdname[0] == 0) { 11625242Skjd if (gethostname(buf, sizeof(_res.defdname)) == 0 && 11725242Skjd (cp = index(buf, '.'))) 11825242Skjd (void)strcpy(_res.defdname, cp + 1); 11925242Skjd } 12018142Sralph 12125242Skjd /* Allow user to override the local domain definition */ 12225242Skjd if ((cp = getenv("LOCALDOMAIN")) != NULL) 12325242Skjd (void)strncpy(_res.defdname, cp, sizeof(_res.defdname)); 12431112Skarels 12531112Skarels /* find components of local domain that might be searched */ 12631112Skarels pp = _res.dnsrch; 12731112Skarels *pp++ = _res.defdname; 12831112Skarels for (cp = _res.defdname, n = 0; *cp; cp++) 12931112Skarels if (*cp == '.') 13031112Skarels n++; 13131112Skarels cp = _res.defdname; 13231112Skarels for (; n >= LOCALDOMAINPARTS && pp < _res.dnsrch + MAXDNSRCH; n--) { 13331112Skarels cp = index(cp, '.'); 13431112Skarels *pp++ = ++cp; 13531112Skarels } 13625242Skjd _res.options |= RES_INIT; 13725242Skjd return(0); 13818142Sralph } 139