]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - lib/libc/net/gethostbynis.c
This commit was generated by cvs2svn to compensate for changes in r147173,
[FreeBSD/FreeBSD.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
26 #include <sys/cdefs.h>
27 __FBSDID("$FreeBSD$");
28
29 #include <sys/param.h>
30 #include <sys/socket.h>
31 #include <netinet/in.h>
32 #include <arpa/inet.h>
33 #include <arpa/nameser.h>
34 #include <netdb.h>
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <ctype.h>
38 #include <errno.h>
39 #include <string.h>
40 #include <stdarg.h>
41 #include <nsswitch.h>
42 #include <resolv.h>             /* XXX */
43 #ifdef YP
44 #include <rpc/rpc.h>
45 #include <rpcsvc/yp_prot.h>
46 #include <rpcsvc/ypclnt.h>
47 #endif
48 #include "netdb_private.h"
49
50 #ifdef YP
51 static int
52 _gethostbynis(const char *name, char *map, int af, struct hostent *he,
53     struct hostent_data *hed)
54 {
55         char *p, *bp, *ep;
56         char *cp, **q;
57         char *result;
58         int resultlen, size, addrok = 0;
59         char ypbuf[YPMAXRECORD + 2];
60
61         switch(af) {
62         case AF_INET:
63                 size = NS_INADDRSZ;
64                 break;
65         case AF_INET6:
66                 size = NS_IN6ADDRSZ;
67                 break;
68         default:
69                 errno = EAFNOSUPPORT;
70                 h_errno = NETDB_INTERNAL;
71                 return -1;
72         }
73
74         if (hed->yp_domain == (char *)NULL)
75                 if (yp_get_default_domain (&hed->yp_domain)) {
76                         h_errno = NETDB_INTERNAL;
77                         return -1;
78                 }
79
80         if (yp_match(hed->yp_domain, map, name, strlen(name), &result,
81             &resultlen)) {
82                 h_errno = HOST_NOT_FOUND;
83                 return -1;
84         }
85
86         /* avoid potential memory leak */
87         bcopy((char *)result, (char *)&ypbuf, resultlen);
88         ypbuf[resultlen] = '\0';
89         free(result);
90         result = (char *)&ypbuf;
91
92         if ((cp = index(result, '\n')))
93                 *cp = '\0';
94
95         cp = strpbrk(result, " \t");
96         *cp++ = '\0';
97         he->h_addr_list = hed->h_addr_ptrs;
98         he->h_addr = (char *)hed->host_addr;
99         switch (af) {
100         case AF_INET:
101                 addrok = inet_aton(result, (struct in_addr *)hed->host_addr);
102                 if (addrok != 1)
103                         break;
104                 if (_res.options & RES_USE_INET6) {
105                         _map_v4v6_address((char *)hed->host_addr,
106                             (char *)hed->host_addr);
107                         af = AF_INET6;
108                         size = NS_IN6ADDRSZ;
109                 }
110                 break;
111         case AF_INET6:
112                 addrok = inet_pton(af, result, hed->host_addr);
113                 break;
114         }
115         if (addrok != 1) {
116                 h_errno = HOST_NOT_FOUND;
117                 return -1;
118         }
119         he->h_addr_list[1] = NULL;
120         he->h_length = size;
121         he->h_addrtype = af;
122         while (*cp == ' ' || *cp == '\t')
123                 cp++;
124         bp = hed->hostbuf;
125         ep = hed->hostbuf + sizeof hed->hostbuf;
126         he->h_name = bp;
127         q = he->h_aliases = hed->host_aliases;
128         p = strpbrk(cp, " \t");
129         if (p != NULL)
130                 *p++ = '\0';
131         size = strlen(cp) + 1;
132         if (ep - bp < size) {
133                 h_errno = NO_RECOVERY;
134                 return -1;
135         }
136         strlcpy(bp, cp, ep - bp);
137         bp += size;
138         cp = p;
139         while (cp && *cp) {
140                 if (*cp == ' ' || *cp == '\t') {
141                         cp++;
142                         continue;
143                 }
144                 if (q >= &hed->host_aliases[_MAXALIASES - 1])
145                         break;
146                 p = strpbrk(cp, " \t");
147                 if (p != NULL)
148                         *p++ = '\0';
149                 size = strlen(cp) + 1;
150                 if (ep - bp < size)
151                         break;
152                 strlcpy(bp, cp, ep - bp);
153                 *q++ = bp;
154                 bp += size;
155                 cp = p;
156         }
157         *q = NULL;
158         return 0;
159 }
160
161 static int
162 _gethostbynisname_r(const char *name, int af, struct hostent *he,
163     struct hostent_data *hed)
164 {
165         char *map;
166
167         switch (af) {
168         case AF_INET:
169                 map = "hosts.byname";
170                 break;
171         default:
172                 map = "ipnodes.byname";
173                 break;
174         }
175         return _gethostbynis(name, map, af, he, hed);
176 }
177
178 static int
179 _gethostbynisaddr_r(const char *addr, int len, int af, struct hostent *he,
180     struct hostent_data *hed)
181 {
182         char *map;
183         char numaddr[46];
184
185         switch (af) {
186         case AF_INET:
187                 map = "hosts.byaddr";
188                 break;
189         default:
190                 map = "ipnodes.byaddr";
191                 break;
192         }
193         if (inet_ntop(af, addr, numaddr, sizeof(numaddr)) == NULL)
194                 return -1;
195         return _gethostbynis(numaddr, map, af, he, hed);
196 }
197 #endif /* YP */
198
199 /* XXX _gethostbynisname/_gethostbynisaddr only used by getipnodeby*() */
200 struct hostent *
201 _gethostbynisname(const char *name, int af)
202 {
203 #ifdef YP
204         struct hostdata *hd;
205         u_long oresopt;
206         int error;
207
208         if ((hd = __hostdata_init()) == NULL) {
209                 h_errno = NETDB_INTERNAL;
210                 return NULL;
211         }
212         oresopt = _res.options;
213         _res.options &= ~RES_USE_INET6;
214         error = _gethostbynisname_r(name, af, &hd->host, &hd->data);
215         _res.options = oresopt;
216         return (error == 0) ? &hd->host : NULL;
217 #else
218         return NULL;
219 #endif
220 }
221
222 struct hostent *
223 _gethostbynisaddr(const char *addr, int len, int af)
224 {
225 #ifdef YP
226         struct hostdata *hd;
227         u_long oresopt;
228         int error;
229
230         if ((hd = __hostdata_init()) == NULL) {
231                 h_errno = NETDB_INTERNAL;
232                 return NULL;
233         }
234         oresopt = _res.options;
235         _res.options &= ~RES_USE_INET6;
236         error = _gethostbynisaddr_r(addr, len, af, &hd->host, &hd->data);
237         _res.options = oresopt;
238         return (error == 0) ? &hd->host : NULL;
239 #else
240         return NULL;
241 #endif
242 }
243
244 int
245 _nis_gethostbyname(void *rval, void *cb_data, va_list ap)
246 {
247 #ifdef YP
248         const char *name;
249         int af;
250         struct hostent *he;
251         struct hostent_data *hed;
252         int error;
253
254         name = va_arg(ap, const char *);
255         af = va_arg(ap, int);
256         he = va_arg(ap, struct hostent *);
257         hed = va_arg(ap, struct hostent_data *);
258
259         error = _gethostbynisname_r(name, af, he, hed);
260         return (error == 0) ? NS_SUCCESS : NS_NOTFOUND;
261 #else
262         return NS_UNAVAIL;
263 #endif
264 }
265
266 int
267 _nis_gethostbyaddr(void *rval, void *cb_data, va_list ap)
268 {
269 #ifdef YP
270         const char *addr;
271         int len;
272         int af;
273         struct hostent *he;
274         struct hostent_data *hed;
275         int error;
276
277         addr = va_arg(ap, const char *);
278         len = va_arg(ap, int);
279         af = va_arg(ap, int);
280         he = va_arg(ap, struct hostent *);
281         hed = va_arg(ap, struct hostent_data *);
282
283         error = _gethostbynisaddr_r(addr, len, af, he, hed);
284         return (error == 0) ? NS_SUCCESS : NS_NOTFOUND;
285 #else
286         return NS_UNAVAIL;
287 #endif
288 }