gethostnamadr.c revision 17903
11573Srgrimes/*- 23070Spst * Copyright (c) 1994, Garrett Wollman 31573Srgrimes * 41573Srgrimes * Redistribution and use in source and binary forms, with or without 51573Srgrimes * modification, are permitted provided that the following conditions 61573Srgrimes * are met: 71573Srgrimes * 1. Redistributions of source code must retain the above copyright 81573Srgrimes * notice, this list of conditions and the following disclaimer. 91573Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 101573Srgrimes * notice, this list of conditions and the following disclaimer in the 111573Srgrimes * documentation and/or other materials provided with the distribution. 121573Srgrimes * 133070Spst * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND 141573Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 151573Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 161573Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 171573Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 181573Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 191573Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 201573Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 211573Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 221573Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 231573Srgrimes * SUCH DAMAGE. 241573Srgrimes */ 251573Srgrimes 261573Srgrimes#if defined(LIBC_SCCS) && !defined(lint) 2717903Speterstatic char sccsid[] = "@(#)$Id: gethostnamadr.c,v 1.9 1996/08/20 08:20:21 julian Exp $"; 2817903Speterstatic char rcsid[] = "$Id: gethostnamadr.c,v 1.9 1996/08/20 08:20:21 julian Exp $"; 291573Srgrimes#endif /* LIBC_SCCS and not lint */ 301573Srgrimes 311573Srgrimes#include <sys/param.h> 321573Srgrimes#include <sys/socket.h> 331573Srgrimes#include <netinet/in.h> 341573Srgrimes#include <arpa/inet.h> 351573Srgrimes#include <netdb.h> 361573Srgrimes#include <stdio.h> 371573Srgrimes#include <ctype.h> 381573Srgrimes#include <errno.h> 391573Srgrimes#include <string.h> 4017903Speter#include <arpa/nameser.h> /* XXX hack for _res */ 4117903Speter#include <resolv.h> /* XXX hack for _res */ 421573Srgrimes 431991Swollman#define _PATH_HOSTCONF "/etc/host.conf" 441991Swollman 458870Srgrimesenum service_type { 461991Swollman SERVICE_NONE = 0, 471991Swollman SERVICE_BIND, 481991Swollman SERVICE_HOSTS, 491991Swollman SERVICE_NIS }; 501991Swollman#define SERVICE_MAX SERVICE_NIS 511991Swollman 521991Swollmanstatic struct { 531991Swollman const char *name; 541991Swollman enum service_type type; 551991Swollman} service_names[] = { 561991Swollman { "hosts", SERVICE_HOSTS }, 571991Swollman { "/etc/hosts", SERVICE_HOSTS }, 581991Swollman { "hosttable", SERVICE_HOSTS }, 591991Swollman { "htable", SERVICE_HOSTS }, 601991Swollman { "bind", SERVICE_BIND }, 611991Swollman { "dns", SERVICE_BIND }, 621991Swollman { "domain", SERVICE_BIND }, 631991Swollman { "yp", SERVICE_NIS }, 641991Swollman { "yellowpages", SERVICE_NIS }, 651991Swollman { "nis", SERVICE_NIS }, 661991Swollman { 0, SERVICE_NONE } 671991Swollman}; 681991Swollman 691991Swollmanstatic enum service_type service_order[SERVICE_MAX + 1]; 701991Swollmanstatic int service_done = 0; 711991Swollman 721991Swollmanstatic enum service_type 731991Swollmanget_service_name(const char *name) { 741991Swollman int i; 751991Swollman for(i = 0; service_names[i].type != SERVICE_NONE; i++) { 761991Swollman if(!strcasecmp(name, service_names[i].name)) { 771991Swollman return service_names[i].type; 781991Swollman } 791991Swollman } 801991Swollman return SERVICE_NONE; 811991Swollman} 821991Swollman 831991Swollmanstatic void 841991Swollmaninit_services() 851991Swollman{ 867324Sache char *cp, *p, buf[BUFSIZ]; 871991Swollman register int cc = 0; 881991Swollman FILE *fd; 891991Swollman 901991Swollman if ((fd = (FILE *)fopen(_PATH_HOSTCONF, "r")) == NULL) { 911991Swollman /* make some assumptions */ 921991Swollman service_order[0] = SERVICE_BIND; 931991Swollman service_order[1] = SERVICE_HOSTS; 941991Swollman service_order[2] = SERVICE_NONE; 951991Swollman } else { 961991Swollman while (fgets(buf, BUFSIZ, fd) != NULL && cc < SERVICE_MAX) { 971991Swollman if(buf[0] == '#') 981991Swollman continue; 991991Swollman 1007324Sache p = buf; 1017324Sache while ((cp = strsep(&p, "\n \t,:;")) != NULL && *cp == '\0') 1027324Sache ; 1037324Sache if (cp == NULL) 1047324Sache continue; 1051991Swollman do { 1067324Sache if (isalpha(cp[0])) { 1077324Sache service_order[cc] = get_service_name(cp); 1087324Sache if(service_order[cc] != SERVICE_NONE) 1097324Sache cc++; 1107324Sache } 1117324Sache while ((cp = strsep(&p, "\n \t,:;")) != NULL && *cp == '\0') 1127324Sache ; 1137324Sache } while(cp != NULL && cc < SERVICE_MAX); 1141991Swollman } 1151991Swollman service_order[cc] = SERVICE_NONE; 1161991Swollman fclose(fd); 1171991Swollman } 1181991Swollman service_done = 1; 1191991Swollman} 1201991Swollman 1211573Srgrimesstruct hostent * 1221991Swollmangethostbyname(const char *name) 1231991Swollman{ 12417903Speter struct hostent *hp; 12517903Speter 12617903Speter if (_res.options & RES_USE_INET6) { /* XXX */ 12717903Speter hp = gethostbyname2(name, AF_INET6); /* XXX */ 12817903Speter if (hp) /* XXX */ 12917903Speter return (hp); /* XXX */ 13017903Speter } /* XXX */ 13117903Speter return (gethostbyname2(name, AF_INET)); 13217903Speter} 13317903Speter 13417903Speterstruct hostent * 13517903Spetergethostbyname2(const char *name, int type) 13617903Speter{ 1371991Swollman struct hostent *hp = 0; 1381991Swollman int nserv = 0; 1391991Swollman 1403070Spst if (!service_done) 1411991Swollman init_services(); 1421991Swollman 1433070Spst while (!hp) { 1443070Spst switch (service_order[nserv]) { 1451991Swollman case SERVICE_NONE: 1463070Spst return NULL; 1471991Swollman case SERVICE_HOSTS: 14817903Speter hp = _gethostbyhtname(name, type); 1491991Swollman break; 1501991Swollman case SERVICE_BIND: 15117903Speter hp = _gethostbydnsname(name, type); 1521991Swollman break; 1531991Swollman case SERVICE_NIS: 15417903Speter hp = _gethostbynisname(name, type); 1551991Swollman break; 1561991Swollman } 1571991Swollman nserv++; 1581991Swollman } 1591991Swollman return hp; 1601991Swollman} 1611991Swollman 1621991Swollmanstruct hostent * 1631991Swollmangethostbyaddr(const char *addr, int len, int type) 1641991Swollman{ 1651991Swollman struct hostent *hp = 0; 1661991Swollman int nserv = 0; 1671991Swollman 1683070Spst if (!service_done) 1691992Swollman init_services(); 1701991Swollman 1713070Spst while (!hp) { 1723070Spst switch (service_order[nserv]) { 1731991Swollman case SERVICE_NONE: 1741991Swollman return 0; 1751991Swollman case SERVICE_HOSTS: 1763070Spst hp = _gethostbyhtaddr(addr, len, type); 1771991Swollman break; 1781991Swollman case SERVICE_BIND: 1793070Spst hp = _gethostbydnsaddr(addr, len, type); 1801991Swollman break; 1811991Swollman case SERVICE_NIS: 1823070Spst hp = _gethostbynisaddr(addr, len, type); 1831991Swollman break; 1841991Swollman } 1851991Swollman nserv++; 1861991Swollman } 1871991Swollman return hp; 1881991Swollman} 1891991Swollman 19017706Sjulian#ifdef _THREAD_SAFE 19117706Sjulianstruct hostent_data; 19217706Sjulian 19317706Sjulian/* 19417706Sjulian * Temporary function (not thread safe) 19517706Sjulian */ 19617706Sjulianint gethostbyaddr_r(const char *addr, int len, int type, 19717706Sjulian struct hostent *result, struct hostent_data *buffer) 19817706Sjulian{ 19917706Sjulian struct hostent *hp = 0; 20017706Sjulian int ret; 20117706Sjulian if ((hp = gethostbyaddr(addr, len, type)) == NULL) { 20217706Sjulian ret = -1; 20317706Sjulian } else { 20417706Sjulian memcpy(result, hp, sizeof(struct hostent)); 20517706Sjulian ret = 0; 20617706Sjulian } 20717706Sjulian return(ret); 20817706Sjulian} 20917706Sjulian#endif 21017706Sjulian 2113070Spstvoid 2123070Spstsethostent(stayopen) 2133070Spst int stayopen; 2143070Spst{ 2153070Spst _sethosthtent(stayopen); 2163070Spst _sethostdnsent(stayopen); 2173070Spst} 2183070Spst 2193070Spstvoid 2203070Spstendhostent() 2213070Spst{ 2223070Spst _endhosthtent(); 2233070Spst _endhostdnsent(); 2243070Spst} 225