gethostnamadr.c revision 17141
1/*- 2 * Copyright (c) 1994, Garrett Wollman 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND 14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23 * SUCH DAMAGE. 24 */ 25 26#if defined(LIBC_SCCS) && !defined(lint) 27static char sccsid[] = "@(#)$Id: gethostnamadr.c,v 1.7 1995/05/30 05:40:45 rgrimes Exp $"; 28static char rcsid[] = "$Id: gethostnamadr.c,v 1.7 1995/05/30 05:40:45 rgrimes Exp $"; 29#endif /* LIBC_SCCS and not lint */ 30 31#include <sys/param.h> 32#include <sys/socket.h> 33#include <netinet/in.h> 34#include <arpa/inet.h> 35#include <netdb.h> 36#include <stdio.h> 37#include <ctype.h> 38#include <errno.h> 39#include <string.h> 40 41extern void _sethosthtent __P(( int )); 42extern void _endhosthtent __P(( void )); 43extern void _sethostdnsent __P(( int )); 44extern void _endhostdnsent __P(( void )); 45 46extern struct hostent * _gethostbyhtname __P((const char *)); 47extern struct hostent * _gethostbydnsname __P((const char *)); 48extern struct hostent * _gethostbynisname __P((const char *)); 49extern struct hostent * _gethostbyhtaddr __P((const char *, int, int)); 50extern struct hostent * _gethostbydnsaddr __P((const char *, int, int)); 51extern struct hostent * _gethostbynisaddr __P((const char *, int, int)); 52 53#define _PATH_HOSTCONF "/etc/host.conf" 54 55enum service_type { 56 SERVICE_NONE = 0, 57 SERVICE_BIND, 58 SERVICE_HOSTS, 59 SERVICE_NIS }; 60#define SERVICE_MAX SERVICE_NIS 61 62static struct { 63 const char *name; 64 enum service_type type; 65} service_names[] = { 66 { "hosts", SERVICE_HOSTS }, 67 { "/etc/hosts", SERVICE_HOSTS }, 68 { "hosttable", SERVICE_HOSTS }, 69 { "htable", SERVICE_HOSTS }, 70 { "bind", SERVICE_BIND }, 71 { "dns", SERVICE_BIND }, 72 { "domain", SERVICE_BIND }, 73 { "yp", SERVICE_NIS }, 74 { "yellowpages", SERVICE_NIS }, 75 { "nis", SERVICE_NIS }, 76 { 0, SERVICE_NONE } 77}; 78 79static enum service_type service_order[SERVICE_MAX + 1]; 80static int service_done = 0; 81 82static enum service_type 83get_service_name(const char *name) { 84 int i; 85 for(i = 0; service_names[i].type != SERVICE_NONE; i++) { 86 if(!strcasecmp(name, service_names[i].name)) { 87 return service_names[i].type; 88 } 89 } 90 return SERVICE_NONE; 91} 92 93static void 94init_services() 95{ 96 char *cp, *p, buf[BUFSIZ]; 97 register int cc = 0; 98 FILE *fd; 99 100 if ((fd = (FILE *)fopen(_PATH_HOSTCONF, "r")) == NULL) { 101 /* make some assumptions */ 102 service_order[0] = SERVICE_BIND; 103 service_order[1] = SERVICE_HOSTS; 104 service_order[2] = SERVICE_NONE; 105 } else { 106 while (fgets(buf, BUFSIZ, fd) != NULL && cc < SERVICE_MAX) { 107 if(buf[0] == '#') 108 continue; 109 110 p = buf; 111 while ((cp = strsep(&p, "\n \t,:;")) != NULL && *cp == '\0') 112 ; 113 if (cp == NULL) 114 continue; 115 do { 116 if (isalpha(cp[0])) { 117 service_order[cc] = get_service_name(cp); 118 if(service_order[cc] != SERVICE_NONE) 119 cc++; 120 } 121 while ((cp = strsep(&p, "\n \t,:;")) != NULL && *cp == '\0') 122 ; 123 } while(cp != NULL && cc < SERVICE_MAX); 124 } 125 service_order[cc] = SERVICE_NONE; 126 fclose(fd); 127 } 128 service_done = 1; 129} 130 131struct hostent * 132gethostbyname(const char *name) 133{ 134 struct hostent *hp = 0; 135 int nserv = 0; 136 137 if (!service_done) 138 init_services(); 139 140 while (!hp) { 141 switch (service_order[nserv]) { 142 case SERVICE_NONE: 143 return NULL; 144 case SERVICE_HOSTS: 145 hp = _gethostbyhtname(name); 146 break; 147 case SERVICE_BIND: 148 hp = _gethostbydnsname(name); 149 break; 150 case SERVICE_NIS: 151 hp = _gethostbynisname(name); 152 break; 153 } 154 nserv++; 155 } 156 return hp; 157} 158 159struct hostent * 160gethostbyaddr(const char *addr, int len, int type) 161{ 162 struct hostent *hp = 0; 163 int nserv = 0; 164 165 if (!service_done) 166 init_services(); 167 168 while (!hp) { 169 switch (service_order[nserv]) { 170 case SERVICE_NONE: 171 return 0; 172 case SERVICE_HOSTS: 173 hp = _gethostbyhtaddr(addr, len, type); 174 break; 175 case SERVICE_BIND: 176 hp = _gethostbydnsaddr(addr, len, type); 177 break; 178 case SERVICE_NIS: 179 hp = _gethostbynisaddr(addr, len, type); 180 break; 181 } 182 nserv++; 183 } 184 return hp; 185} 186 187void 188sethostent(stayopen) 189 int stayopen; 190{ 191 _sethosthtent(stayopen); 192 _sethostdnsent(stayopen); 193} 194 195void 196endhostent() 197{ 198 _endhosthtent(); 199 _endhostdnsent(); 200} 201