"Normalize" some types, s/long unsigned/unsigned long/ etc.
[dragonfly.git] / lib / libc / net / gethostbynis.c
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  * $FreeBSD: src/lib/libc/net/gethostbynis.c,v 1.28 2006/05/12 15:37:23 ume Exp $
26  */
27
28 #include <sys/param.h>
29 #include <sys/socket.h>
30 #include <netinet/in.h>
31 #include <arpa/inet.h>
32 #include <arpa/nameser.h>
33 #include <netdb.h>
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <ctype.h>
37 #include <errno.h>
38 #include <string.h>
39 #include <stdarg.h>
40 #include <nsswitch.h>
41 #include <resolv.h>             /* XXX */
42 #ifdef YP
43 #include <rpc/rpc.h>
44 #include <rpcsvc/yp_prot.h>
45 #include <rpcsvc/ypclnt.h>
46 #endif
47 #include "netdb_private.h"
48
49 #ifdef YP
50 static int
51 _gethostbynis(const char *name, char *map, int af, struct hostent *he,
52               struct hostent_data *hed)
53 {
54         char *p, *bp, *ep;
55         char *cp, **q;
56         char *result;
57         int resultlen, size, addrok = 0;
58         char ypbuf[YPMAXRECORD + 2];
59         res_state statp;
60
61         statp = __res_state();
62         switch(af) {
63         case AF_INET:
64                 size = NS_INADDRSZ;
65                 break;
66         case AF_INET6:
67                 size = NS_IN6ADDRSZ;
68                 break;
69         default:
70                 errno = EAFNOSUPPORT;
71                 RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
72                 return (-1);
73         }
74
75         if (hed->yp_domain == NULL)
76                 if (yp_get_default_domain (&hed->yp_domain)) {
77                         RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
78                         return (-1);
79                 }
80
81         if (yp_match(hed->yp_domain, map, name, strlen(name), &result,
82             &resultlen)) {
83                 RES_SET_H_ERRNO(statp, HOST_NOT_FOUND);
84                 return (-1);
85         }
86
87         /* avoid potential memory leak */
88         bcopy((char *)result, (char *)&ypbuf, resultlen);
89         ypbuf[resultlen] = '\0';
90         free(result);
91         result = (char *)&ypbuf;
92
93         if ((cp = index(result, '\n')))
94                 *cp = '\0';
95
96         cp = strpbrk(result, " \t");
97         *cp++ = '\0';
98         he->h_addr_list = hed->h_addr_ptrs;
99         he->h_addr = (char *)hed->host_addr;
100         switch (af) {
101         case AF_INET:
102                 addrok = inet_aton(result, (struct in_addr *)hed->host_addr);
103                 if (addrok != 1)
104                         break;
105                 if (statp->options & RES_USE_INET6) {
106                         _map_v4v6_address((char *)hed->host_addr,
107                             (char *)hed->host_addr);
108                         af = AF_INET6;
109                         size = NS_IN6ADDRSZ;
110                 }
111                 break;
112         case AF_INET6:
113                 addrok = inet_pton(af, result, hed->host_addr);
114                 break;
115         }
116         if (addrok != 1) {
117                 RES_SET_H_ERRNO(statp, HOST_NOT_FOUND);
118                 return (-1);
119         }
120         he->h_addr_list[1] = NULL;
121         he->h_length = size;
122         he->h_addrtype = af;
123         while (*cp == ' ' || *cp == '\t')
124                 cp++;
125         bp = hed->hostbuf;
126         ep = hed->hostbuf + sizeof hed->hostbuf;
127         he->h_name = bp;
128         q = he->h_aliases = hed->host_aliases;
129         p = strpbrk(cp, " \t");
130         if (p != NULL)
131                 *p++ = '\0';
132         size = strlen(cp) + 1;
133         if (ep - bp < size) {
134                 RES_SET_H_ERRNO(statp, NO_RECOVERY);
135                 return (-1);
136         }
137         strlcpy(bp, cp, ep - bp);
138         bp += size;
139         cp = p;
140         while (cp && *cp) {
141                 if (*cp == ' ' || *cp == '\t') {
142                         cp++;
143                         continue;
144                 }
145                 if (q >= &hed->host_aliases[_MAXALIASES - 1])
146                         break;
147                 p = strpbrk(cp, " \t");
148                 if (p != NULL)
149                         *p++ = '\0';
150                 size = strlen(cp) + 1;
151                 if (ep - bp < size)
152                         break;
153                 strlcpy(bp, cp, ep - bp);
154                 *q++ = bp;
155                 bp += size;
156                 cp = p;
157         }
158         *q = NULL;
159         return (0);
160 }
161
162 static int
163 _gethostbynisname_r(const char *name, int af, struct hostent *he,
164                     struct hostent_data *hed)
165 {
166         char *map;
167
168         switch (af) {
169         case AF_INET:
170                 map = "hosts.byname";
171                 break;
172         default:
173                 map = "ipnodes.byname";
174                 break;
175         }
176         return (_gethostbynis(name, map, af, he, hed));
177 }
178
179 static int
180 _gethostbynisaddr_r(const void *addr, socklen_t len __unused, int af,
181                     struct hostent *he, struct hostent_data *hed)
182 {
183         char *map;
184         char numaddr[46];
185
186         switch (af) {
187         case AF_INET:
188                 map = "hosts.byaddr";
189                 break;
190         default:
191                 map = "ipnodes.byaddr";
192                 break;
193         }
194         if (inet_ntop(af, addr, numaddr, sizeof(numaddr)) == NULL)
195                 return (-1);
196         return (_gethostbynis(numaddr, map, af, he, hed));
197 }
198 #endif /* YP */
199
200 /* XXX _gethostbynisname/_gethostbynisaddr only used by getipnodeby*() */
201 struct hostent *
202 _gethostbynisname(const char *name, int af)
203 {
204 #ifdef YP
205         struct hostent *he;
206         struct hostent_data *hed;
207         u_long oresopt;
208         int error;
209         res_state statp;
210
211         statp = __res_state();
212         if ((he = __hostent_init()) == NULL ||
213             (hed = __hostent_data_init()) == NULL) {
214                 RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
215                 return (NULL);
216         }
217
218         oresopt = statp->options;
219         statp->options &= ~RES_USE_INET6;
220         error = _gethostbynisname_r(name, af, he, hed);
221         statp->options = oresopt;
222         return (error == 0) ? he : NULL;
223 #else
224         return (NULL);
225 #endif
226 }
227
228 struct hostent *
229 _gethostbynisaddr(const void *addr, socklen_t len, int af)
230 {
231 #ifdef YP
232         struct hostent *he;
233         struct hostent_data *hed;
234         u_long oresopt;
235         int error;
236         res_state statp;
237
238         statp = __res_state();
239         if ((he = __hostent_init()) == NULL ||
240             (hed = __hostent_data_init()) == NULL) {
241                 RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
242                 return (NULL);
243         }
244
245         oresopt = statp->options;
246         statp->options &= ~RES_USE_INET6;
247         error = _gethostbynisaddr_r(addr, len, af, he, hed);
248         statp->options = oresopt;
249         return (error == 0) ? he : NULL;
250 #else
251         return (NULL);
252 #endif
253 }
254
255 int
256 _nis_gethostbyname(void *rval, void *cb_data __unused, va_list ap)
257 {
258 #ifdef YP
259         const char *name;
260         int af;
261         char *buffer;
262         size_t buflen;
263         int *errnop, *h_errnop;
264         struct hostent *hptr, he;
265         struct hostent_data *hed;
266         res_state statp;
267
268         name = va_arg(ap, const char *);
269         af = va_arg(ap, int);
270         hptr = va_arg(ap, struct hostent *);
271         buffer = va_arg(ap, char *);
272         buflen = va_arg(ap, size_t);
273         errnop = va_arg(ap, int *);
274         h_errnop = va_arg(ap, int *);
275
276         *((struct hostent **)rval) = NULL;
277
278         statp = __res_state();
279         if ((hed = __hostent_data_init()) == NULL) {
280                 RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
281                 *h_errnop = statp->res_h_errno;
282                 return (NS_NOTFOUND);
283         }
284
285         if (_gethostbynisname_r(name, af, &he, hed) != 0) {
286                 *h_errnop = statp->res_h_errno;
287                 return (NS_NOTFOUND);
288         }
289         if (__copy_hostent(&he, hptr, buffer, buflen) != 0) {
290                 *h_errnop = statp->res_h_errno;
291                 return (NS_NOTFOUND);
292         }
293         *((struct hostent **)rval) = hptr;
294         return (NS_SUCCESS);
295 #else
296         *((struct hostent **)rval) = NULL;
297         return (NS_UNAVAIL);
298 #endif
299 }
300
301 int
302 _nis_gethostbyaddr(void *rval, void *cb_data __unused, va_list ap)
303 {
304 #ifdef YP
305         const void *addr;
306         socklen_t len;
307         int af;
308         char *buffer;
309         size_t buflen;
310         int *errnop, *h_errnop;
311         struct hostent *hptr, he;
312         struct hostent_data *hed;
313         res_state statp;
314
315         addr = va_arg(ap, const void *);
316         len = va_arg(ap, socklen_t);
317         af = va_arg(ap, int);
318         hptr = va_arg(ap, struct hostent *);
319         buffer = va_arg(ap, char *);
320         buflen = va_arg(ap, size_t);
321         errnop = va_arg(ap, int *);
322         h_errnop = va_arg(ap, int *);
323
324         *((struct hostent **)rval) = NULL;
325
326         statp = __res_state();
327         if ((hed = __hostent_data_init()) == NULL) {
328                 RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
329                 *h_errnop = statp->res_h_errno;
330                 return (NS_NOTFOUND);
331         }
332
333         if (_gethostbynisaddr_r(addr, len, af, &he, hed) != 0) {
334                 *h_errnop = statp->res_h_errno;
335                 return (NS_NOTFOUND);
336         }
337         if (__copy_hostent(&he, hptr, buffer, buflen) != 0) {
338                 *h_errnop = statp->res_h_errno;
339                 return (NS_NOTFOUND);
340         }
341         *((struct hostent **)rval) = hptr;
342         return (NS_SUCCESS);
343 #else
344         *((struct hostent **)rval) = NULL;
345         return (NS_UNAVAIL);
346 #endif
347 }