Don't use relative include paths, use <...>.
[glibc/history.git] / nis / nss_nis / nis-hosts.c
blob5ca24c76255de567676fb4471bd234cf783abde9
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. */
20 #include <nss.h>
21 #include <ctype.h>
22 #include <netdb.h>
23 #include <string.h>
24 #include <netinet/in.h>
25 #include <arpa/inet.h>
26 #include <resolv.h>
27 #include <libc-lock.h>
28 #include <rpcsvc/yp.h>
29 #include <rpcsvc/ypclnt.h>
31 #include "nss-nis.h"
33 /* Get implementation for some internal functions. */
34 #include <resolv/mapv4v6addr.h>
35 #include <resolv/mapv4v6hostent.h>
37 #define ENTNAME hostent
38 #define DATABASE "hosts"
39 #define NEED_H_ERRNO
41 #define ENTDATA hostent_data
42 struct hostent_data
44 unsigned char host_addr[16]; /* IPv4 or IPv6 address. */
45 char *h_addr_ptrs[2]; /* Points to that and null terminator. */
48 #define TRAILING_LIST_MEMBER h_aliases
49 #define TRAILING_LIST_SEPARATOR_P isspace
50 #include <nss/nss_files/files-parse.c>
51 LINE_PARSER
52 ("#",
54 char *addr;
56 STRING_FIELD (addr, isspace, 1);
58 /* Parse address. */
59 if ((_res.options & RES_USE_INET6)
60 && inet_pton (AF_INET6, addr, entdata->host_addr) > 0)
62 result->h_addrtype = AF_INET6;
63 result->h_length = IN6ADDRSZ;
65 else
66 if (inet_pton (AF_INET, addr, entdata->host_addr) > 0)
68 if (_res.options & RES_USE_INET6)
70 map_v4v6_address ((char *) entdata->host_addr,
71 (char *) entdata->host_addr);
72 result->h_addrtype = AF_INET6;
73 result->h_length = IN6ADDRSZ;
75 else
77 result->h_addrtype = AF_INET;
78 result->h_length = INADDRSZ;
81 else
82 /* Illegal address: ignore line. */
83 return 0;
85 /* Store a pointer to the address in the expected form. */
86 entdata->h_addr_ptrs[0] = entdata->host_addr;
87 entdata->h_addr_ptrs[1] = NULL;
88 result->h_addr_list = entdata->h_addr_ptrs;
90 /* If we need the host entry in IPv6 form change it now. */
91 if (_res.options & RES_USE_INET6)
93 char *bufptr = data->linebuffer;
94 size_t buflen = (char *) data + datalen - bufptr;
95 map_v4v6_hostent (result, &bufptr, &buflen);
98 STRING_FIELD (result->h_name, isspace, 1);
102 __libc_lock_define_initialized (static, lock)
104 static bool_t new_start = 1;
105 static char *oldkey = NULL;
106 static int oldkeylen = 0;
108 enum nss_status
109 _nss_nis_sethostent (void)
111 __libc_lock_lock (lock);
113 new_start = 1;
114 if (oldkey != NULL)
116 free (oldkey);
117 oldkey = NULL;
118 oldkeylen = 0;
121 __libc_lock_unlock (lock);
123 return NSS_STATUS_SUCCESS;
126 enum nss_status
127 _nss_nis_endhostent (void)
129 __libc_lock_lock (lock);
131 new_start = 1;
132 if (oldkey != NULL)
134 free (oldkey);
135 oldkey = NULL;
136 oldkeylen = 0;
139 __libc_lock_unlock (lock);
141 return NSS_STATUS_SUCCESS;
144 static enum nss_status
145 internal_nis_gethostent_r (struct hostent *host, char *buffer,
146 size_t buflen, int *h_errnop)
148 char *domain;
149 char *result;
150 int len, parse_res;
151 char *outkey;
152 int keylen;
153 struct parser_data *data = (void *) buffer;
154 size_t linebuflen = buffer + buflen - data->linebuffer;
156 if (yp_get_default_domain (&domain))
157 return NSS_STATUS_UNAVAIL;
159 if (buflen < sizeof *data + 1)
161 __set_errno (ERANGE);
162 *h_errnop = NETDB_INTERNAL;
163 return NSS_STATUS_TRYAGAIN;
166 /* Get the next entry until we found a correct one. */
169 enum nss_status retval;
170 char *p;
172 if (new_start)
173 retval = yperr2nss (yp_first (domain, "hosts.byname",
174 &outkey, &keylen, &result, &len));
175 else
176 retval = yperr2nss ( yp_next (domain, "hosts.byname",
177 oldkey, oldkeylen,
178 &outkey, &keylen, &result, &len));
180 if (retval != NSS_STATUS_SUCCESS)
182 switch (retval)
184 case NSS_STATUS_TRYAGAIN:
185 __set_errno (EAGAIN);
186 *h_errnop = TRY_AGAIN;
187 break;
188 case NSS_STATUS_NOTFOUND:
189 *h_errnop = HOST_NOT_FOUND;
190 break;
191 default:
192 *h_errnop = NO_RECOVERY;
193 break;
195 return retval;
198 if ((size_t) (len + 1) > linebuflen)
200 free (result);
201 *h_errnop = NETDB_INTERNAL;
202 __set_errno (ERANGE);
203 return NSS_STATUS_TRYAGAIN;
206 p = strncpy (data->linebuffer, result, len);
207 data->linebuffer[len] = '\0';
208 while (isspace (*p))
209 ++p;
210 free (result);
212 parse_res = parse_line (p, host, data, buflen);
213 if (!parse_res && errno == ERANGE)
215 *h_errnop = NETDB_INTERNAL;;
216 return NSS_STATUS_TRYAGAIN;
218 free (oldkey);
219 oldkey = outkey;
220 oldkeylen = keylen;
221 new_start = 0;
223 while (!parse_res);
225 *h_errnop = NETDB_SUCCESS;
226 return NSS_STATUS_SUCCESS;
230 _nss_nis_gethostent_r (struct hostent *host, char *buffer, size_t buflen,
231 int *h_errnop)
233 int status;
235 __libc_lock_lock (lock);
237 status = internal_nis_gethostent_r (host, buffer, buflen, h_errnop);
239 __libc_lock_unlock (lock);
241 return status;
244 enum nss_status
245 _nss_nis_gethostbyname2_r (const char *name, int af, struct hostent *host,
246 char *buffer, size_t buflen, int *h_errnop)
248 enum nss_status retval;
249 char *domain, *result, *p;
250 int len, parse_res;
251 struct parser_data *data = (void *) buffer;
252 size_t linebuflen = buffer + buflen - data->linebuffer;
254 if (name == NULL)
256 __set_errno (EINVAL);
257 return NSS_STATUS_UNAVAIL;
260 if (yp_get_default_domain (&domain))
261 return NSS_STATUS_UNAVAIL;
263 if (buflen < sizeof *data + 1)
265 *h_errnop = NETDB_INTERNAL;
266 __set_errno (ERANGE);
267 return NSS_STATUS_TRYAGAIN;
269 retval = yperr2nss (yp_match (domain, "hosts.byname", name,
270 strlen (name), &result, &len));
272 if (retval != NSS_STATUS_SUCCESS)
274 if (retval == NSS_STATUS_TRYAGAIN)
276 *h_errnop = TRY_AGAIN;
277 __set_errno (EAGAIN);
279 if (retval == NSS_STATUS_NOTFOUND)
280 *h_errnop = HOST_NOT_FOUND;
281 return retval;
284 if ((size_t) (len + 1) > linebuflen)
286 free (result);
287 *h_errnop = NETDB_INTERNAL;
288 __set_errno (ERANGE);
289 return NSS_STATUS_TRYAGAIN;
292 p = strncpy (data->linebuffer, result, len);
293 data->linebuffer[len] = '\0';
294 while (isspace (*p))
295 ++p;
296 free (result);
298 parse_res = parse_line (p, host, data, buflen);
300 if (!parse_res || host->h_addrtype != af)
302 if (!parse_res && errno == ERANGE)
304 *h_errnop = NETDB_INTERNAL;
305 return NSS_STATUS_TRYAGAIN;
307 else
309 *h_errnop = HOST_NOT_FOUND;
310 return NSS_STATUS_NOTFOUND;
314 *h_errnop = NETDB_SUCCESS;
315 return NSS_STATUS_SUCCESS;
318 enum nss_status
319 _nss_nis_gethostbyname_r (const char *name, struct hostent *host,
320 char *buffer, size_t buflen, int *h_errnop)
322 if (_res.options & RES_USE_INET6)
324 enum nss_status status;
326 status = _nss_nis_gethostbyname2_r (name, AF_INET6, host, buffer, buflen,
327 h_errnop);
328 if (status == NSS_STATUS_SUCCESS)
329 return status;
332 return _nss_nis_gethostbyname2_r (name, AF_INET, host, buffer, buflen,
333 h_errnop);
336 enum nss_status
337 _nss_nis_gethostbyaddr_r (char *addr, int addrlen, int type,
338 struct hostent *host, char *buffer, size_t buflen,
339 int *h_errnop)
341 enum nss_status retval;
342 char *domain, *result, *p;
343 int len, parse_res;
344 char *buf;
345 struct parser_data *data = (void *) buffer;
346 size_t linebuflen = buffer + buflen - data->linebuffer;
348 if (yp_get_default_domain (&domain))
349 return NSS_STATUS_UNAVAIL;
351 if (buflen < sizeof *data + 1)
353 __set_errno (ERANGE);
354 *h_errnop = NETDB_INTERNAL;
355 return NSS_STATUS_TRYAGAIN;
358 buf = inet_ntoa (*(struct in_addr *) addr);
360 retval = yperr2nss (yp_match (domain, "hosts.byaddr", buf,
361 strlen (buf), &result, &len));
363 if (retval != NSS_STATUS_SUCCESS)
365 if (retval == NSS_STATUS_TRYAGAIN)
367 *h_errnop = TRY_AGAIN;
368 __set_errno (EAGAIN);
370 if (retval == NSS_STATUS_NOTFOUND)
371 *h_errnop = HOST_NOT_FOUND;
372 return retval;
375 if ((size_t) (len + 1) > linebuflen)
377 free (result);
378 __set_errno (ERANGE);
379 *h_errnop = NETDB_INTERNAL;
380 return NSS_STATUS_TRYAGAIN;
383 p = strncpy (data->linebuffer, result, len);
384 data->linebuffer[len] = '\0';
385 while (isspace (*p))
386 ++p;
387 free (result);
389 parse_res = parse_line (p, host, data, buflen);
391 if (!parse_res)
393 if (errno == ERANGE)
395 *h_errnop = NETDB_INTERNAL;
396 return NSS_STATUS_TRYAGAIN;
398 else
400 *h_errnop = HOST_NOT_FOUND;
401 return NSS_STATUS_NOTFOUND;
405 *h_errnop = NETDB_SUCCESS;
406 return NSS_STATUS_SUCCESS;