118548Sralph /* 239708Skarels * Copyright (c) 1985, 1989 Regents of the University of California. 333679Sbostic * All rights reserved. 433679Sbostic * 533679Sbostic * Redistribution and use in source and binary forms are permitted 634817Sbostic * provided that the above copyright notice and this paragraph are 734817Sbostic * duplicated in all such forms and that any documentation, 834817Sbostic * advertising materials, and other materials related to such 934817Sbostic * distribution and use acknowledge that the software was developed 1034817Sbostic * by the University of California, Berkeley. The name of the 1134817Sbostic * University may not be used to endorse or promote products derived 1234817Sbostic * from this software without specific prior written permission. 1334817Sbostic * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 1434817Sbostic * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 1534817Sbostic * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 1618548Sralph */ 1718548Sralph 1826633Sdonn #if defined(LIBC_SCCS) && !defined(lint) 19*42258Sbloom static char sccsid[] = "@(#)res_init.c 6.13 (Berkeley) 05/20/90"; 2033679Sbostic #endif /* LIBC_SCCS and not lint */ 2121386Sdist 2218142Sralph #include <sys/types.h> 2318142Sralph #include <sys/socket.h> 2418142Sralph #include <netinet/in.h> 2518142Sralph #include <stdio.h> 2624081Skjd #include <arpa/nameser.h> 2726902Skjd #include <resolv.h> 2818142Sralph 2918142Sralph /* 3018142Sralph * Resolver state default settings 3118142Sralph */ 3225242Skjd 3318142Sralph struct state _res = { 3439708Skarels RES_TIMEOUT, /* retransmition time interval */ 3539708Skarels 4, /* number of times to retransmit */ 3639708Skarels RES_DEFAULT, /* options flags */ 3739708Skarels 1, /* number of name servers */ 3818142Sralph }; 3918142Sralph 4018142Sralph /* 4124736Sbloom * Set up default settings. If the configuration file exist, the values 4224736Sbloom * there will have precedence. Otherwise, the server address is set to 4324736Sbloom * INADDR_ANY and the default domain name comes from the gethostname(). 4424736Sbloom * 4524736Sbloom * The configuration file should only be used if you want to redefine your 4624736Sbloom * domain or run without a server on your machine. 4724736Sbloom * 4824736Sbloom * Return 0 if completes successfully, -1 on error 4918142Sralph */ 5018142Sralph res_init() 5118142Sralph { 5239708Skarels register FILE *fp; 5339708Skarels register char *cp, **pp; 5439708Skarels register int n; 5539708Skarels char buf[BUFSIZ]; 5639708Skarels extern u_long inet_addr(); 5739708Skarels extern char *index(); 5839708Skarels extern char *strcpy(), *strncpy(); 5939708Skarels extern char *getenv(); 6039708Skarels int nserv = 0; /* number of nameserver records read from file */ 6139717Skarels int haveenv = 0; 6239708Skarels int havesearch = 0; 6318142Sralph 6439708Skarels _res.nsaddr.sin_addr.s_addr = INADDR_ANY; 6539708Skarels _res.nsaddr.sin_family = AF_INET; 6639708Skarels _res.nsaddr.sin_port = htons(NAMESERVER_PORT); 6739708Skarels _res.nscount = 1; 6818142Sralph 6939708Skarels /* Allow user to override the local domain definition */ 7039717Skarels if ((cp = getenv("LOCALDOMAIN")) != NULL) { 7139708Skarels (void)strncpy(_res.defdname, cp, sizeof(_res.defdname)); 7239717Skarels haveenv++; 7339717Skarels } 7418142Sralph 7539708Skarels if ((fp = fopen(_PATH_RESCONF, "r")) != NULL) { 7639708Skarels /* read the config file */ 7739708Skarels while (fgets(buf, sizeof(buf), fp) != NULL) { 7839708Skarels /* read default domain name */ 7939708Skarels if (!strncmp(buf, "domain", sizeof("domain") - 1)) { 8039717Skarels if (haveenv) /* skip if have from environ */ 8139708Skarels continue; 8239708Skarels cp = buf + sizeof("domain") - 1; 8339708Skarels while (*cp == ' ' || *cp == '\t') 8439708Skarels cp++; 8539791Sbloom if ((*cp == '\0') || (*cp == '\n')) 8639708Skarels continue; 8739708Skarels (void)strncpy(_res.defdname, cp, sizeof(_res.defdname) - 1); 8839708Skarels if ((cp = index(_res.defdname, '\n')) != NULL) 8939708Skarels *cp = '\0'; 9039708Skarels havesearch = 0; 9139708Skarels continue; 9239708Skarels } 9339708Skarels /* set search list */ 9439708Skarels if (!strncmp(buf, "search", sizeof("search") - 1)) { 9539717Skarels if (haveenv) /* skip if have from environ */ 9639717Skarels continue; 9739708Skarels cp = buf + sizeof("search") - 1; 9839708Skarels while (*cp == ' ' || *cp == '\t') 9939708Skarels cp++; 10039791Sbloom if ((*cp == '\0') || (*cp == '\n')) 10139708Skarels continue; 10239708Skarels (void)strncpy(_res.defdname, cp, sizeof(_res.defdname) - 1); 10339708Skarels if ((cp = index(_res.defdname, '\n')) != NULL) 10439708Skarels *cp = '\0'; 10539708Skarels /* 10639708Skarels * Set search list to be blank-separated strings 10739708Skarels * on rest of line. 10839708Skarels */ 10939708Skarels cp = _res.defdname; 11039708Skarels pp = _res.dnsrch; 11139708Skarels *pp++ = cp; 11239708Skarels for (n = 0; *cp && pp < _res.dnsrch + MAXDNSRCH; cp++) { 11339708Skarels if (*cp == ' ' || *cp == '\t') { 11439708Skarels *cp = 0; 11539708Skarels n = 1; 11639708Skarels } else if (n) { 11739708Skarels *pp++ = cp; 11839708Skarels n = 0; 11939708Skarels } 12039708Skarels } 12139717Skarels *pp++ = 0; 12239708Skarels havesearch = 1; 12339708Skarels continue; 12439708Skarels } 12539708Skarels /* read nameservers to query */ 12639708Skarels if (!strncmp(buf, "nameserver", sizeof("nameserver") - 1) && 12739708Skarels nserv < MAXNS) { 12839708Skarels cp = buf + sizeof("nameserver") - 1; 12939708Skarels while (*cp == ' ' || *cp == '\t') 13039708Skarels cp++; 13139791Sbloom if ((*cp == '\0') || (*cp == '\n')) 13239708Skarels continue; 13339708Skarels if ((_res.nsaddr_list[nserv].sin_addr.s_addr = 134*42258Sbloom inet_addr(cp)) == (unsigned)-1) { 135*42258Sbloom _res.nsaddr_list[nserv].sin_addr.s_addr 136*42258Sbloom = INADDR_ANY; 13739708Skarels continue; 138*42258Sbloom } 13939708Skarels _res.nsaddr_list[nserv].sin_family = AF_INET; 14039708Skarels _res.nsaddr_list[nserv].sin_port = htons(NAMESERVER_PORT); 14139708Skarels nserv++; 14239708Skarels continue; 14339708Skarels } 14439708Skarels } 14539708Skarels if (nserv > 1) 14639708Skarels _res.nscount = nserv; 14739708Skarels (void) fclose(fp); 14839708Skarels } 14939708Skarels if (_res.defdname[0] == 0) { 15039708Skarels if (gethostname(buf, sizeof(_res.defdname)) == 0 && 15139708Skarels (cp = index(buf, '.'))) 15239708Skarels (void)strcpy(_res.defdname, cp + 1); 15339708Skarels } 15431112Skarels 15539708Skarels /* find components of local domain that might be searched */ 15639708Skarels if (havesearch == 0) { 15739708Skarels pp = _res.dnsrch; 15839708Skarels *pp++ = _res.defdname; 15939708Skarels for (cp = _res.defdname, n = 0; *cp; cp++) 16039708Skarels if (*cp == '.') 16139708Skarels n++; 16239708Skarels cp = _res.defdname; 16339717Skarels for (; n >= LOCALDOMAINPARTS && pp < _res.dnsrch + MAXDFLSRCH; 16439708Skarels n--) { 16539708Skarels cp = index(cp, '.'); 16639708Skarels *pp++ = ++cp; 16739708Skarels } 16839717Skarels *pp++ = 0; 16939708Skarels } 17039708Skarels _res.options |= RES_INIT; 17139708Skarels return (0); 17218142Sralph } 173