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
get_service_name(const char * name)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
init_services()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 *
gethostbyname(const char * name)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 *
gethostbyname2(const char * name,int type)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 *
gethostbyaddr(const char * addr,socklen_t len,int type)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 */
gethostbyaddr_r(const char * addr,int len,int type,struct hostent * result,struct hostent_data * buffer)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
sethostent(int stayopen)214 sethostent(int stayopen)
215 {
216 _sethosthtent(stayopen);
217 _sethostdnsent(stayopen);
218 }
219
220 void
endhostent()221 endhostent()
222 {
223 _endhosthtent();
224 _endhostdnsent();
225 }
226