1 /* Copyright (C) 1996, 1997 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3 Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1996.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public License as
7 published by the Free Software Foundation; either version 2 of the
8 License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
15 You should have received a copy of the GNU Library General Public
16 License along with the GNU C Library; see the file COPYING.LIB. If not,
17 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA. */
24 #include <netinet/in.h>
25 #include <arpa/inet.h>
27 #include <libc-lock.h>
28 #include <rpcsvc/yp.h>
29 #include <rpcsvc/ypclnt.h>
33 /* Get implementation for some internal functions. */
34 #include <resolv/mapv4v6addr.h>
36 #define ENTNAME hostent
37 #define DATABASE "hosts"
40 #define ENTDATA hostent_data
43 unsigned char host_addr[16]; /* IPv4 or IPv6 address. */
44 char *h_addr_ptrs[2]; /* Points to that and null terminator. */
47 #define TRAILING_LIST_MEMBER h_aliases
48 #define TRAILING_LIST_SEPARATOR_P isspace
49 #include <nss/nss_files/files-parse.c>
55 STRING_FIELD (addr, isspace, 1);
58 if (inet_pton (AF_INET6, addr, entdata->host_addr) > 0)
60 result->h_addrtype = AF_INET6;
61 result->h_length = IN6ADDRSZ;
64 if (inet_pton (AF_INET, addr, entdata->host_addr) > 0)
66 if (_res.options & RES_USE_INET6)
68 map_v4v6_address ((char *) entdata->host_addr,
69 (char *) entdata->host_addr);
70 result->h_addrtype = AF_INET6;
71 result->h_length = IN6ADDRSZ;
75 result->h_addrtype = AF_INET;
76 result->h_length = INADDRSZ;
80 /* Illegal address: ignore line. */
83 /* Store a pointer to the address in the expected form. */
84 entdata->h_addr_ptrs[0] = entdata->host_addr;
85 entdata->h_addr_ptrs[1] = NULL;
86 result->h_addr_list = entdata->h_addr_ptrs;
88 STRING_FIELD (result->h_name, isspace, 1);
92 __libc_lock_define_initialized (static, lock)
94 static bool_t new_start = 1;
95 static char *oldkey = NULL;
96 static int oldkeylen = 0;
99 _nss_nis_sethostent (void)
101 __libc_lock_lock (lock);
111 __libc_lock_unlock (lock);
113 return NSS_STATUS_SUCCESS;
117 _nss_nis_endhostent (void)
119 __libc_lock_lock (lock);
129 __libc_lock_unlock (lock);
131 return NSS_STATUS_SUCCESS;
134 static enum nss_status
135 internal_nis_gethostent_r (struct hostent *host, char *buffer,
136 size_t buflen, int *h_errnop)
143 struct parser_data *data = (void *) buffer;
144 size_t linebuflen = buffer + buflen - data->linebuffer;
146 if (yp_get_default_domain (&domain))
147 return NSS_STATUS_UNAVAIL;
149 if (buflen < sizeof *data + 1)
151 __set_errno (ERANGE);
152 *h_errnop = NETDB_INTERNAL;
153 return NSS_STATUS_TRYAGAIN;
156 /* Get the next entry until we found a correct one. */
159 enum nss_status retval;
163 retval = yperr2nss (yp_first (domain, "hosts.byname",
164 &outkey, &keylen, &result, &len));
166 retval = yperr2nss ( yp_next (domain, "hosts.byname",
168 &outkey, &keylen, &result, &len));
170 if (retval != NSS_STATUS_SUCCESS)
174 case NSS_STATUS_TRYAGAIN:
175 __set_errno (EAGAIN);
176 *h_errnop = TRY_AGAIN;
178 case NSS_STATUS_NOTFOUND:
179 *h_errnop = HOST_NOT_FOUND;
182 *h_errnop = NO_RECOVERY;
188 if ((size_t) (len + 1) > linebuflen)
191 *h_errnop = NETDB_INTERNAL;
192 __set_errno (ERANGE);
193 return NSS_STATUS_TRYAGAIN;
196 p = strncpy (data->linebuffer, result, len);
197 data->linebuffer[len] = '\0';
202 parse_res = parse_line (p, host, data, buflen);
203 if (!parse_res && errno == ERANGE)
205 *h_errnop = NETDB_INTERNAL;;
206 return NSS_STATUS_TRYAGAIN;
215 *h_errnop = NETDB_SUCCESS;
216 return NSS_STATUS_SUCCESS;
220 _nss_nis_gethostent_r (struct hostent *host, char *buffer, size_t buflen,
225 __libc_lock_lock (lock);
227 status = internal_nis_gethostent_r (host, buffer, buflen, h_errnop);
229 __libc_lock_unlock (lock);
235 _nss_nis_gethostbyname2_r (const char *name, int af, struct hostent *host,
236 char *buffer, size_t buflen, int *h_errnop)
238 enum nss_status retval;
239 char *domain, *result, *p;
241 struct parser_data *data = (void *) buffer;
242 size_t linebuflen = buffer + buflen - data->linebuffer;
246 __set_errno (EINVAL);
247 return NSS_STATUS_UNAVAIL;
250 if (yp_get_default_domain (&domain))
251 return NSS_STATUS_UNAVAIL;
253 if (buflen < sizeof *data + 1)
255 *h_errnop = NETDB_INTERNAL;
256 __set_errno (ERANGE);
257 return NSS_STATUS_TRYAGAIN;
259 retval = yperr2nss (yp_match (domain, "hosts.byname", name,
260 strlen (name), &result, &len));
262 if (retval != NSS_STATUS_SUCCESS)
264 if (retval == NSS_STATUS_TRYAGAIN)
266 *h_errnop = TRY_AGAIN;
267 __set_errno (EAGAIN);
269 if (retval == NSS_STATUS_NOTFOUND)
270 *h_errnop = HOST_NOT_FOUND;
274 if ((size_t) (len + 1) > linebuflen)
277 *h_errnop = NETDB_INTERNAL;
278 __set_errno (ERANGE);
279 return NSS_STATUS_TRYAGAIN;
282 p = strncpy (data->linebuffer, result, len);
283 data->linebuffer[len] = '\0';
288 parse_res = parse_line (p, host, data, buflen);
290 if (!parse_res || host->h_addrtype != af)
292 if (!parse_res && errno == ERANGE)
294 *h_errnop = NETDB_INTERNAL;
295 return NSS_STATUS_TRYAGAIN;
299 *h_errnop = HOST_NOT_FOUND;
300 return NSS_STATUS_NOTFOUND;
304 *h_errnop = NETDB_SUCCESS;
305 return NSS_STATUS_SUCCESS;
309 _nss_nis_gethostbyname_r (const char *name, struct hostent *host,
310 char *buffer, size_t buflen, int *h_errnop)
312 if (_res.options & RES_USE_INET6)
314 enum nss_status status;
316 status = _nss_nis_gethostbyname2_r (name, AF_INET6, host, buffer, buflen,
318 if (status == NSS_STATUS_SUCCESS)
322 return _nss_nis_gethostbyname2_r (name, AF_INET, host, buffer, buflen,
327 _nss_nis_gethostbyaddr_r (char *addr, int addrlen, int type,
328 struct hostent *host, char *buffer, size_t buflen,
331 enum nss_status retval;
332 char *domain, *result, *p;
335 struct parser_data *data = (void *) buffer;
336 size_t linebuflen = buffer + buflen - data->linebuffer;
338 if (yp_get_default_domain (&domain))
339 return NSS_STATUS_UNAVAIL;
341 if (buflen < sizeof *data + 1)
343 __set_errno (ERANGE);
344 *h_errnop = NETDB_INTERNAL;
345 return NSS_STATUS_TRYAGAIN;
348 buf = inet_ntoa (*(struct in_addr *) addr);
350 retval = yperr2nss (yp_match (domain, "hosts.byaddr", buf,
351 strlen (buf), &result, &len));
353 if (retval != NSS_STATUS_SUCCESS)
355 if (retval == NSS_STATUS_TRYAGAIN)
357 *h_errnop = TRY_AGAIN;
358 __set_errno (EAGAIN);
360 if (retval == NSS_STATUS_NOTFOUND)
361 *h_errnop = HOST_NOT_FOUND;
365 if ((size_t) (len + 1) > linebuflen)
368 __set_errno (ERANGE);
369 *h_errnop = NETDB_INTERNAL;
370 return NSS_STATUS_TRYAGAIN;
373 p = strncpy (data->linebuffer, result, len);
374 data->linebuffer[len] = '\0';
379 parse_res = parse_line (p, host, data, buflen);
385 *h_errnop = NETDB_INTERNAL;
386 return NSS_STATUS_TRYAGAIN;
390 *h_errnop = HOST_NOT_FOUND;
391 return NSS_STATUS_NOTFOUND;
395 *h_errnop = NETDB_SUCCESS;
396 return NSS_STATUS_SUCCESS;