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) 27 static char sccsid[] = "@(#)$Id: gethostnamadr.c,v 1.1.1.1 2003/11/19 01:51:27 kyu3 Exp $"; 28 static char rcsid[] = "$Id: gethostnamadr.c,v 1.1.1.1 2003/11/19 01:51:27 kyu3 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 <paths.h> 40 #include <string.h> 41 #include <arpa/nameser.h> /* XXX hack for _res */ 42 #include <resolv.h> /* XXX hack for _res */ 43 44 #include "Socklib_internals.h" 45 46 47 enum service_type { 48 SERVICE_NONE = 0, 49 SERVICE_BIND, 50 SERVICE_HOSTS, 51 SERVICE_NIS }; 52 #define SERVICE_MAX SERVICE_NIS 53 54 static struct { 55 const char *name; 56 enum service_type type; 57 } service_names[] = { 58 { "hosts", SERVICE_HOSTS }, 59 { _PATH_HOSTS, SERVICE_HOSTS }, 60 { "hosttable", SERVICE_HOSTS }, 61 { "htable", SERVICE_HOSTS }, 62 { "bind", SERVICE_BIND }, 63 { "dns", SERVICE_BIND }, 64 { "domain", SERVICE_BIND }, 65 { "yp", SERVICE_NIS }, 66 { "yellowpages", SERVICE_NIS }, 67 { "nis", SERVICE_NIS }, 68 { 0, SERVICE_NONE } 69 }; 70 71 static enum service_type service_order[SERVICE_MAX + 1]; 72 static int service_done = 0; 73 74 static enum service_type 75 get_service_name(const char *name) { 76 int i; 77 for(i = 0; service_names[i].type != SERVICE_NONE; i++) { 78 if(!strcasecmp(name, service_names[i].name)) { 79 return service_names[i].type; 80 } 81 } 82 return SERVICE_NONE; 83 } 84 85 static void 86 init_services() 87 { 88 char *cp, *p, buf[BUFSIZ]; 89 register int cc = 0; 90 FILE *fd; 91 92 if ((fd = (FILE *)fopen(_PATH_HOSTCONF, "r")) == NULL) { 93 /* make some assumptions */ 94 service_order[0] = SERVICE_HOSTS; 95 service_order[1] = SERVICE_BIND; 96 service_order[2] = SERVICE_NONE; 97 } else { 98 while (fgets(buf, BUFSIZ, fd) != NULL && cc < SERVICE_MAX) { 99 if(buf[0] == '#') 100 continue; 101 102 p = buf; 103 while ((cp = strsep(&p, "\n \t,:;")) != NULL && *cp == '\0') 104 ; 105 if (cp == NULL) 106 continue; 107 do { 108 if (isalpha(cp[0])) { 109 service_order[cc] = get_service_name(cp); 110 if(service_order[cc] != SERVICE_NONE) 111 cc++; 112 } 113 while ((cp = strsep(&p, "\n \t,:;")) != NULL && *cp == '\0') 114 ; 115 } while(cp != NULL && cc < SERVICE_MAX); 116 } 117 service_order[cc] = SERVICE_NONE; 118 fclose(fd); 119 } 120 service_done = 1; 121 } 122 123 struct hostent * 124 gethostbyname(const char *name) 125 { 126 struct hostent *hp; 127 128 if (_res.options & RES_USE_INET6) { /* XXX */ 129 hp = gethostbyname2(name, AF_INET6); /* XXX */ 130 if (hp) /* XXX */ 131 return (hp); /* XXX */ 132 } /* XXX */ 133 return (gethostbyname2(name, AF_INET)); 134 } 135 136 struct hostent * 137 gethostbyname2(const char *name, int type) 138 { 139 struct hostent *hp = 0; 140 int nserv = 0; 141 142 if (!service_done) 143 init_services(); 144 145 while (!hp) { 146 switch (service_order[nserv]) { 147 case SERVICE_NONE: 148 return NULL; 149 case SERVICE_HOSTS: 150 hp = _gethostbyhtname(name, type); 151 break; 152 case SERVICE_BIND: 153 hp = _gethostbydnsname(name, type); 154 break; 155 case SERVICE_NIS: 156 hp = _gethostbynisname(name, type); 157 break; 158 } 159 nserv++; 160 } 161 return hp; 162 } 163 164 struct hostent * 165 gethostbyaddr(const char *addr, socklen_t len, int type) 166 { 167 struct hostent *hp = 0; 168 int nserv = 0; 169 170 if (!service_done) 171 init_services(); 172 173 while (!hp) { 174 switch (service_order[nserv]) { 175 case SERVICE_NONE: 176 return 0; 177 case SERVICE_HOSTS: 178 hp = _gethostbyhtaddr(addr, len, type); 179 break; 180 case SERVICE_BIND: 181 hp = _gethostbydnsaddr(addr, len, type); 182 break; 183 case SERVICE_NIS: 184 hp = _gethostbynisaddr(addr, len, type); 185 break; 186 } 187 nserv++; 188 } 189 return hp; 190 } 191 192 #ifdef _THREAD_SAFE 193 struct hostent_data; 194 195 /* 196 * Temporary function (not thread safe) 197 */ 198 int gethostbyaddr_r(const char *addr, int len, int type, 199 struct hostent *result, struct hostent_data *buffer) 200 { 201 struct hostent *hp; 202 int ret; 203 if ((hp = gethostbyaddr(addr, len, type)) == NULL) { 204 ret = -1; 205 } else { 206 memcpy(result, hp, sizeof(struct hostent)); 207 ret = 0; 208 } 209 return(ret); 210 } 211 #endif 212 213 void 214 sethostent(int stayopen) 215 { 216 _sethosthtent(stayopen); 217 _sethostdnsent(stayopen); 218 } 219 220 void 221 endhostent() 222 { 223 _endhosthtent(); 224 _endhostdnsent(); 225 } 226