nis_ho.c revision 1.1.1.2 1 1.1 christos /* $NetBSD: nis_ho.c,v 1.1.1.2 2012/09/09 16:07:56 christos Exp $ */
2 1.1 christos
3 1.1 christos /*
4 1.1 christos * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
5 1.1 christos * Copyright (c) 1996,1999 by Internet Software Consortium.
6 1.1 christos *
7 1.1 christos * Permission to use, copy, modify, and distribute this software for any
8 1.1 christos * purpose with or without fee is hereby granted, provided that the above
9 1.1 christos * copyright notice and this permission notice appear in all copies.
10 1.1 christos *
11 1.1 christos * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
12 1.1 christos * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 1.1 christos * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
14 1.1 christos * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 1.1 christos * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 1.1 christos * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
17 1.1 christos * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 1.1 christos */
19 1.1 christos
20 1.1 christos #if defined(LIBC_SCCS) && !defined(lint)
21 1.1.1.2 christos static const char rcsid[] = "Id: nis_ho.c,v 1.5 2005/04/27 04:56:32 sra Exp ";
22 1.1 christos #endif /* LIBC_SCCS and not lint */
23 1.1 christos
24 1.1 christos /* Imports */
25 1.1 christos
26 1.1 christos #include "port_before.h"
27 1.1 christos
28 1.1 christos #ifndef WANT_IRS_NIS
29 1.1 christos static int __bind_irs_nis_unneeded;
30 1.1 christos #else
31 1.1 christos
32 1.1 christos #include <sys/types.h>
33 1.1 christos #include <sys/param.h>
34 1.1 christos #include <sys/socket.h>
35 1.1 christos #include <netinet/in.h>
36 1.1 christos #include <arpa/inet.h>
37 1.1 christos #include <arpa/nameser.h>
38 1.1 christos #ifdef T_NULL
39 1.1 christos #undef T_NULL /* Silence re-definition warning of T_NULL. */
40 1.1 christos #endif
41 1.1 christos #include <rpc/rpc.h>
42 1.1 christos #include <rpc/xdr.h>
43 1.1 christos #include <rpcsvc/yp_prot.h>
44 1.1 christos #include <rpcsvc/ypclnt.h>
45 1.1 christos
46 1.1 christos #include <ctype.h>
47 1.1 christos #include <errno.h>
48 1.1 christos #include <stdlib.h>
49 1.1 christos #include <netdb.h>
50 1.1 christos #include <resolv.h>
51 1.1 christos #include <stdio.h>
52 1.1 christos #include <string.h>
53 1.1 christos
54 1.1 christos #include <isc/memcluster.h>
55 1.1 christos #include <irs.h>
56 1.1 christos
57 1.1 christos #include "port_after.h"
58 1.1 christos
59 1.1 christos #include "irs_p.h"
60 1.1 christos #include "nis_p.h"
61 1.1 christos
62 1.1 christos /* Definitions */
63 1.1 christos
64 1.1 christos #define MAXALIASES 35
65 1.1 christos #define MAXADDRS 35
66 1.1 christos
67 1.1 christos #if PACKETSZ > 1024
68 1.1 christos #define MAXPACKET PACKETSZ
69 1.1 christos #else
70 1.1 christos #define MAXPACKET 1024
71 1.1 christos #endif
72 1.1 christos
73 1.1 christos struct pvt {
74 1.1 christos int needrewind;
75 1.1 christos char * nis_domain;
76 1.1 christos char * curkey_data;
77 1.1 christos int curkey_len;
78 1.1 christos char * curval_data;
79 1.1 christos int curval_len;
80 1.1 christos struct hostent host;
81 1.1 christos char * h_addr_ptrs[MAXADDRS + 1];
82 1.1 christos char * host_aliases[MAXALIASES + 1];
83 1.1 christos char hostbuf[8*1024];
84 1.1 christos u_char host_addr[16]; /*%< IPv4 or IPv6 */
85 1.1 christos struct __res_state *res;
86 1.1 christos void (*free_res)(void *);
87 1.1 christos };
88 1.1 christos
89 1.1 christos enum do_what { do_none = 0x0, do_key = 0x1, do_val = 0x2, do_all = 0x3 };
90 1.1 christos
91 1.1 christos static const u_char mapped[] = { 0,0, 0,0, 0,0, 0,0, 0,0, 0xff,0xff };
92 1.1 christos static const u_char tunnelled[] = { 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 };
93 1.1 christos static /*const*/ char hosts_byname[] = "hosts.byname";
94 1.1 christos static /*const*/ char hosts_byaddr[] = "hosts.byaddr";
95 1.1 christos static /*const*/ char ipnode_byname[] = "ipnode.byname";
96 1.1 christos static /*const*/ char ipnode_byaddr[] = "ipnode.byaddr";
97 1.1 christos static /*const*/ char yp_multi[] = "YP_MULTI_";
98 1.1 christos
99 1.1 christos /* Forwards */
100 1.1 christos
101 1.1 christos static void ho_close(struct irs_ho *this);
102 1.1 christos static struct hostent * ho_byname(struct irs_ho *this, const char *name);
103 1.1 christos static struct hostent * ho_byname2(struct irs_ho *this, const char *name,
104 1.1 christos int af);
105 1.1 christos static struct hostent * ho_byaddr(struct irs_ho *this, const void *addr,
106 1.1 christos int len, int af);
107 1.1 christos static struct hostent * ho_next(struct irs_ho *this);
108 1.1 christos static void ho_rewind(struct irs_ho *this);
109 1.1 christos static void ho_minimize(struct irs_ho *this);
110 1.1 christos static struct __res_state * ho_res_get(struct irs_ho *this);
111 1.1 christos static void ho_res_set(struct irs_ho *this,
112 1.1 christos struct __res_state *res,
113 1.1 christos void (*free_res)(void *));
114 1.1 christos static struct addrinfo * ho_addrinfo(struct irs_ho *this, const char *name,
115 1.1 christos const struct addrinfo *pai);
116 1.1 christos
117 1.1 christos static struct hostent * makehostent(struct irs_ho *this);
118 1.1 christos static void nisfree(struct pvt *, enum do_what);
119 1.1 christos static int init(struct irs_ho *this);
120 1.1 christos
121 1.1 christos /* Public */
122 1.1 christos
123 1.1 christos struct irs_ho *
124 1.1 christos irs_nis_ho(struct irs_acc *this) {
125 1.1 christos struct irs_ho *ho;
126 1.1 christos struct pvt *pvt;
127 1.1 christos
128 1.1 christos if (!(pvt = memget(sizeof *pvt))) {
129 1.1 christos errno = ENOMEM;
130 1.1 christos return (NULL);
131 1.1 christos }
132 1.1 christos memset(pvt, 0, sizeof *pvt);
133 1.1 christos if (!(ho = memget(sizeof *ho))) {
134 1.1 christos memput(pvt, sizeof *pvt);
135 1.1 christos errno = ENOMEM;
136 1.1 christos return (NULL);
137 1.1 christos }
138 1.1 christos memset(ho, 0x5e, sizeof *ho);
139 1.1 christos pvt->needrewind = 1;
140 1.1 christos pvt->nis_domain = ((struct nis_p *)this->private)->domain;
141 1.1 christos ho->private = pvt;
142 1.1 christos ho->close = ho_close;
143 1.1 christos ho->byname = ho_byname;
144 1.1 christos ho->byname2 = ho_byname2;
145 1.1 christos ho->byaddr = ho_byaddr;
146 1.1 christos ho->next = ho_next;
147 1.1 christos ho->rewind = ho_rewind;
148 1.1 christos ho->minimize = ho_minimize;
149 1.1 christos ho->res_set = ho_res_set;
150 1.1 christos ho->res_get = ho_res_get;
151 1.1 christos ho->addrinfo = ho_addrinfo;
152 1.1 christos return (ho);
153 1.1 christos }
154 1.1 christos
155 1.1 christos /* Methods */
156 1.1 christos
157 1.1 christos static void
158 1.1 christos ho_close(struct irs_ho *this) {
159 1.1 christos struct pvt *pvt = (struct pvt *)this->private;
160 1.1 christos
161 1.1 christos ho_minimize(this);
162 1.1 christos nisfree(pvt, do_all);
163 1.1 christos if (pvt->res && pvt->free_res)
164 1.1 christos (*pvt->free_res)(pvt->res);
165 1.1 christos memput(pvt, sizeof *pvt);
166 1.1 christos memput(this, sizeof *this);
167 1.1 christos }
168 1.1 christos
169 1.1 christos static struct hostent *
170 1.1 christos ho_byname(struct irs_ho *this, const char *name) {
171 1.1 christos struct pvt *pvt = (struct pvt *)this->private;
172 1.1 christos struct hostent *hp;
173 1.1 christos
174 1.1 christos if (init(this) == -1)
175 1.1 christos return (NULL);
176 1.1 christos
177 1.1 christos if (pvt->res->options & RES_USE_INET6) {
178 1.1 christos hp = ho_byname2(this, name, AF_INET6);
179 1.1 christos if (hp)
180 1.1 christos return (hp);
181 1.1 christos }
182 1.1 christos return (ho_byname2(this, name, AF_INET));
183 1.1 christos }
184 1.1 christos
185 1.1 christos static struct hostent *
186 1.1 christos ho_byname2(struct irs_ho *this, const char *name, int af) {
187 1.1 christos struct pvt *pvt = (struct pvt *)this->private;
188 1.1 christos int r;
189 1.1 christos char *tmp;
190 1.1 christos
191 1.1 christos UNUSED(af);
192 1.1 christos
193 1.1 christos if (init(this) == -1)
194 1.1 christos return (NULL);
195 1.1 christos
196 1.1 christos nisfree(pvt, do_val);
197 1.1 christos
198 1.1 christos strcpy(pvt->hostbuf, yp_multi);
199 1.1 christos strncat(pvt->hostbuf, name, sizeof(pvt->hostbuf) - sizeof(yp_multi));
200 1.1 christos pvt->hostbuf[sizeof(pvt->hostbuf) - 1] = '\0';
201 1.1 christos for (r = sizeof(yp_multi) - 1; pvt->hostbuf[r] != '\0'; r++)
202 1.1 christos if (isupper((unsigned char)pvt->hostbuf[r]))
203 1.1 christos tolower(pvt->hostbuf[r]);
204 1.1 christos
205 1.1 christos tmp = pvt->hostbuf;
206 1.1 christos r = yp_match(pvt->nis_domain, ipnode_byname, tmp,
207 1.1 christos strlen(tmp), &pvt->curval_data, &pvt->curval_len);
208 1.1 christos if (r != 0) {
209 1.1 christos tmp = pvt->hostbuf + sizeof(yp_multi) - 1;
210 1.1 christos r = yp_match(pvt->nis_domain, ipnode_byname, tmp,
211 1.1 christos strlen(tmp), &pvt->curval_data, &pvt->curval_len);
212 1.1 christos }
213 1.1 christos if (r != 0) {
214 1.1 christos tmp = pvt->hostbuf;
215 1.1 christos r = yp_match(pvt->nis_domain, hosts_byname, tmp,
216 1.1 christos strlen(tmp), &pvt->curval_data, &pvt->curval_len);
217 1.1 christos }
218 1.1 christos if (r != 0) {
219 1.1 christos tmp = pvt->hostbuf + sizeof(yp_multi) - 1;
220 1.1 christos r = yp_match(pvt->nis_domain, hosts_byname, tmp,
221 1.1 christos strlen(tmp), &pvt->curval_data, &pvt->curval_len);
222 1.1 christos }
223 1.1 christos if (r != 0) {
224 1.1 christos RES_SET_H_ERRNO(pvt->res, HOST_NOT_FOUND);
225 1.1 christos return (NULL);
226 1.1 christos }
227 1.1 christos return (makehostent(this));
228 1.1 christos }
229 1.1 christos
230 1.1 christos static struct hostent *
231 1.1 christos ho_byaddr(struct irs_ho *this, const void *addr, int len, int af) {
232 1.1 christos struct pvt *pvt = (struct pvt *)this->private;
233 1.1 christos char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"];
234 1.1 christos const u_char *uaddr = addr;
235 1.1 christos int r;
236 1.1 christos
237 1.1 christos if (init(this) == -1)
238 1.1 christos return (NULL);
239 1.1 christos
240 1.1 christos if (af == AF_INET6 && len == IN6ADDRSZ &&
241 1.1 christos (!memcmp(uaddr, mapped, sizeof mapped) ||
242 1.1 christos !memcmp(uaddr, tunnelled, sizeof tunnelled))) {
243 1.1 christos /* Unmap. */
244 1.1 christos addr = (const u_char *)addr + sizeof mapped;
245 1.1 christos uaddr += sizeof mapped;
246 1.1 christos af = AF_INET;
247 1.1 christos len = INADDRSZ;
248 1.1 christos }
249 1.1 christos if (inet_ntop(af, uaddr, tmp, sizeof tmp) == NULL) {
250 1.1 christos RES_SET_H_ERRNO(pvt->res, NETDB_INTERNAL);
251 1.1 christos return (NULL);
252 1.1 christos }
253 1.1 christos nisfree(pvt, do_val);
254 1.1 christos r = yp_match(pvt->nis_domain, ipnode_byaddr, tmp, strlen(tmp),
255 1.1 christos &pvt->curval_data, &pvt->curval_len);
256 1.1 christos if (r != 0)
257 1.1 christos r = yp_match(pvt->nis_domain, hosts_byaddr, tmp, strlen(tmp),
258 1.1 christos &pvt->curval_data, &pvt->curval_len);
259 1.1 christos if (r != 0) {
260 1.1 christos RES_SET_H_ERRNO(pvt->res, HOST_NOT_FOUND);
261 1.1 christos return (NULL);
262 1.1 christos }
263 1.1 christos return (makehostent(this));
264 1.1 christos }
265 1.1 christos
266 1.1 christos static struct hostent *
267 1.1 christos ho_next(struct irs_ho *this) {
268 1.1 christos struct pvt *pvt = (struct pvt *)this->private;
269 1.1 christos struct hostent *rval;
270 1.1 christos int r;
271 1.1 christos
272 1.1 christos if (init(this) == -1)
273 1.1 christos return (NULL);
274 1.1 christos
275 1.1 christos do {
276 1.1 christos if (pvt->needrewind) {
277 1.1 christos nisfree(pvt, do_all);
278 1.1 christos r = yp_first(pvt->nis_domain, hosts_byaddr,
279 1.1 christos &pvt->curkey_data, &pvt->curkey_len,
280 1.1 christos &pvt->curval_data, &pvt->curval_len);
281 1.1 christos pvt->needrewind = 0;
282 1.1 christos } else {
283 1.1 christos char *newkey_data;
284 1.1 christos int newkey_len;
285 1.1 christos
286 1.1 christos nisfree(pvt, do_val);
287 1.1 christos r = yp_next(pvt->nis_domain, hosts_byaddr,
288 1.1 christos pvt->curkey_data, pvt->curkey_len,
289 1.1 christos &newkey_data, &newkey_len,
290 1.1 christos &pvt->curval_data, &pvt->curval_len);
291 1.1 christos nisfree(pvt, do_key);
292 1.1 christos pvt->curkey_data = newkey_data;
293 1.1 christos pvt->curkey_len = newkey_len;
294 1.1 christos }
295 1.1 christos if (r != 0) {
296 1.1 christos RES_SET_H_ERRNO(pvt->res, HOST_NOT_FOUND);
297 1.1 christos return (NULL);
298 1.1 christos }
299 1.1 christos rval = makehostent(this);
300 1.1 christos } while (rval == NULL);
301 1.1 christos return (rval);
302 1.1 christos }
303 1.1 christos
304 1.1 christos static void
305 1.1 christos ho_rewind(struct irs_ho *this) {
306 1.1 christos struct pvt *pvt = (struct pvt *)this->private;
307 1.1 christos
308 1.1 christos pvt->needrewind = 1;
309 1.1 christos }
310 1.1 christos
311 1.1 christos static void
312 1.1 christos ho_minimize(struct irs_ho *this) {
313 1.1 christos struct pvt *pvt = (struct pvt *)this->private;
314 1.1 christos
315 1.1 christos if (pvt->res)
316 1.1 christos res_nclose(pvt->res);
317 1.1 christos }
318 1.1 christos
319 1.1 christos static struct __res_state *
320 1.1 christos ho_res_get(struct irs_ho *this) {
321 1.1 christos struct pvt *pvt = (struct pvt *)this->private;
322 1.1 christos
323 1.1 christos if (!pvt->res) {
324 1.1 christos struct __res_state *res;
325 1.1 christos res = (struct __res_state *)malloc(sizeof *res);
326 1.1 christos if (!res) {
327 1.1 christos errno = ENOMEM;
328 1.1 christos return (NULL);
329 1.1 christos }
330 1.1 christos memset(res, 0, sizeof *res);
331 1.1 christos ho_res_set(this, res, free);
332 1.1 christos }
333 1.1 christos
334 1.1 christos return (pvt->res);
335 1.1 christos }
336 1.1 christos
337 1.1 christos static void
338 1.1 christos ho_res_set(struct irs_ho *this, struct __res_state *res,
339 1.1 christos void (*free_res)(void *)) {
340 1.1 christos struct pvt *pvt = (struct pvt *)this->private;
341 1.1 christos
342 1.1 christos if (pvt->res && pvt->free_res) {
343 1.1 christos res_nclose(pvt->res);
344 1.1 christos (*pvt->free_res)(pvt->res);
345 1.1 christos }
346 1.1 christos
347 1.1 christos pvt->res = res;
348 1.1 christos pvt->free_res = free_res;
349 1.1 christos }
350 1.1 christos
351 1.1 christos struct nis_res_target {
352 1.1 christos struct nis_res_target *next;
353 1.1 christos int family;
354 1.1 christos };
355 1.1 christos
356 1.1 christos /* XXX */
357 1.1 christos extern struct addrinfo *hostent2addrinfo __P((struct hostent *,
358 1.1 christos const struct addrinfo *pai));
359 1.1 christos
360 1.1 christos static struct addrinfo *
361 1.1 christos ho_addrinfo(struct irs_ho *this, const char *name, const struct addrinfo *pai)
362 1.1 christos {
363 1.1 christos struct pvt *pvt = (struct pvt *)this->private;
364 1.1 christos struct hostent *hp;
365 1.1 christos struct nis_res_target q, q2, *p;
366 1.1 christos struct addrinfo sentinel, *cur;
367 1.1 christos
368 1.1 christos memset(&q, 0, sizeof(q2));
369 1.1 christos memset(&q2, 0, sizeof(q2));
370 1.1 christos memset(&sentinel, 0, sizeof(sentinel));
371 1.1 christos cur = &sentinel;
372 1.1 christos
373 1.1 christos switch(pai->ai_family) {
374 1.1 christos case AF_UNSPEC: /*%< INET6 then INET4 */
375 1.1 christos q.family = AF_INET6;
376 1.1 christos q.next = &q2;
377 1.1 christos q2.family = AF_INET;
378 1.1 christos break;
379 1.1 christos case AF_INET6:
380 1.1 christos q.family = AF_INET6;
381 1.1 christos break;
382 1.1 christos case AF_INET:
383 1.1 christos q.family = AF_INET;
384 1.1 christos break;
385 1.1 christos default:
386 1.1 christos RES_SET_H_ERRNO(pvt->res, NO_RECOVERY); /*%< ??? */
387 1.1 christos return(NULL);
388 1.1 christos }
389 1.1 christos
390 1.1 christos for (p = &q; p; p = p->next) {
391 1.1 christos struct addrinfo *ai;
392 1.1 christos
393 1.1 christos hp = (*this->byname2)(this, name, p->family);
394 1.1 christos if (hp == NULL) {
395 1.1 christos /* byname2 should've set an appropriate error */
396 1.1 christos continue;
397 1.1 christos }
398 1.1 christos if ((hp->h_name == NULL) || (hp->h_name[0] == 0) ||
399 1.1 christos (hp->h_addr_list[0] == NULL)) {
400 1.1 christos RES_SET_H_ERRNO(pvt->res, NO_RECOVERY);
401 1.1 christos continue;
402 1.1 christos }
403 1.1 christos ai = hostent2addrinfo(hp, pai);
404 1.1 christos if (ai) {
405 1.1 christos cur->ai_next = ai;
406 1.1 christos while (cur && cur->ai_next)
407 1.1 christos cur = cur->ai_next;
408 1.1 christos }
409 1.1 christos }
410 1.1 christos
411 1.1 christos if (sentinel.ai_next == NULL)
412 1.1 christos RES_SET_H_ERRNO(pvt->res, HOST_NOT_FOUND);
413 1.1 christos
414 1.1 christos return(sentinel.ai_next);
415 1.1 christos }
416 1.1 christos
417 1.1 christos /* Private */
418 1.1 christos
419 1.1 christos /*%
420 1.1 christos ipnodes:
421 1.1 christos ::1 localhost
422 1.1 christos 127.0.0.1 localhost
423 1.1 christos 1.2.3.4 FOO bar
424 1.1 christos 1.2.6.4 FOO bar
425 1.1 christos 1.2.6.5 host
426 1.1 christos
427 1.1 christos ipnodes.byname:
428 1.1 christos YP_MULTI_localhost ::1,127.0.0.1 localhost
429 1.1 christos YP_MULTI_foo 1.2.3.4,1.2.6.4 FOO bar
430 1.1 christos YP_MULTI_bar 1.2.3.4,1.2.6.4 FOO bar
431 1.1 christos host 1.2.6.5 host
432 1.1 christos
433 1.1 christos hosts.byname:
434 1.1 christos localhost 127.0.0.1 localhost
435 1.1 christos host 1.2.6.5 host
436 1.1 christos YP_MULTI_foo 1.2.3.4,1.2.6.4 FOO bar
437 1.1 christos YP_MULTI_bar 1.2.3.4,1.2.6.4 FOO bar
438 1.1 christos */
439 1.1 christos
440 1.1 christos static struct hostent *
441 1.1 christos makehostent(struct irs_ho *this) {
442 1.1 christos struct pvt *pvt = (struct pvt *)this->private;
443 1.1 christos static const char spaces[] = " \t";
444 1.1 christos char *cp, **q, *p, *comma, *ap;
445 1.1 christos int af = 0, len = 0;
446 1.1 christos int multi = 0;
447 1.1 christos int addr = 0;
448 1.1 christos
449 1.1 christos p = pvt->curval_data;
450 1.1 christos if ((cp = strpbrk(p, "#\n")) != NULL)
451 1.1 christos *cp = '\0';
452 1.1 christos if (!(cp = strpbrk(p, spaces)))
453 1.1 christos return (NULL);
454 1.1 christos *cp++ = '\0';
455 1.1 christos ap = pvt->hostbuf;
456 1.1 christos do {
457 1.1 christos if ((comma = strchr(p, ',')) != NULL) {
458 1.1 christos *comma++ = '\0';
459 1.1 christos multi = 1;
460 1.1 christos }
461 1.1 christos if ((ap + IN6ADDRSZ) > (pvt->hostbuf + sizeof(pvt->hostbuf)))
462 1.1 christos break;
463 1.1 christos if ((pvt->res->options & RES_USE_INET6) &&
464 1.1 christos inet_pton(AF_INET6, p, ap) > 0) {
465 1.1 christos af = AF_INET6;
466 1.1 christos len = IN6ADDRSZ;
467 1.1 christos } else if (inet_pton(AF_INET, p, pvt->host_addr) > 0) {
468 1.1 christos if (pvt->res->options & RES_USE_INET6) {
469 1.1 christos map_v4v6_address((char*)pvt->host_addr, ap);
470 1.1 christos af = AF_INET6;
471 1.1 christos len = IN6ADDRSZ;
472 1.1 christos } else {
473 1.1 christos af = AF_INET;
474 1.1 christos len = INADDRSZ;
475 1.1 christos }
476 1.1 christos } else {
477 1.1 christos if (!multi)
478 1.1 christos return (NULL);
479 1.1 christos continue;
480 1.1 christos }
481 1.1 christos if (addr < MAXADDRS) {
482 1.1 christos pvt->h_addr_ptrs[addr++] = ap;
483 1.1 christos pvt->h_addr_ptrs[addr] = NULL;
484 1.1 christos ap += len;
485 1.1 christos }
486 1.1 christos } while ((p = comma) != NULL);
487 1.1 christos if (ap == pvt->hostbuf)
488 1.1 christos return (NULL);
489 1.1 christos pvt->host.h_addr_list = pvt->h_addr_ptrs;
490 1.1 christos pvt->host.h_length = len;
491 1.1 christos pvt->host.h_addrtype = af;
492 1.1 christos cp += strspn(cp, spaces);
493 1.1 christos pvt->host.h_name = cp;
494 1.1 christos q = pvt->host.h_aliases = pvt->host_aliases;
495 1.1 christos if ((cp = strpbrk(cp, spaces)) != NULL)
496 1.1 christos *cp++ = '\0';
497 1.1 christos while (cp && *cp) {
498 1.1 christos if (*cp == ' ' || *cp == '\t') {
499 1.1 christos cp++;
500 1.1 christos continue;
501 1.1 christos }
502 1.1 christos if (q < &pvt->host_aliases[MAXALIASES])
503 1.1 christos *q++ = cp;
504 1.1 christos if ((cp = strpbrk(cp, spaces)) != NULL)
505 1.1 christos *cp++ = '\0';
506 1.1 christos }
507 1.1 christos *q = NULL;
508 1.1 christos RES_SET_H_ERRNO(pvt->res, NETDB_SUCCESS);
509 1.1 christos return (&pvt->host);
510 1.1 christos }
511 1.1 christos
512 1.1 christos static void
513 1.1 christos nisfree(struct pvt *pvt, enum do_what do_what) {
514 1.1 christos if ((do_what & do_key) && pvt->curkey_data) {
515 1.1 christos free(pvt->curkey_data);
516 1.1 christos pvt->curkey_data = NULL;
517 1.1 christos }
518 1.1 christos if ((do_what & do_val) && pvt->curval_data) {
519 1.1 christos free(pvt->curval_data);
520 1.1 christos pvt->curval_data = NULL;
521 1.1 christos }
522 1.1 christos }
523 1.1 christos
524 1.1 christos static int
525 1.1 christos init(struct irs_ho *this) {
526 1.1 christos struct pvt *pvt = (struct pvt *)this->private;
527 1.1 christos
528 1.1 christos if (!pvt->res && !ho_res_get(this))
529 1.1 christos return (-1);
530 1.1 christos if (((pvt->res->options & RES_INIT) == 0) &&
531 1.1 christos res_ninit(pvt->res) == -1)
532 1.1 christos return (-1);
533 1.1 christos return (0);
534 1.1 christos }
535 1.1 christos #endif /*WANT_IRS_NIS*/
536 1.1 christos
537 1.1 christos /*! \file */
538