Bug Summary

File:src/lib/libc/asr/gethostnamadr_async.c
Warning:line 286, column 8
Although the value stored to 'r' is used in the enclosing expression, the value is never actually read from 'r'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name gethostnamadr_async.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 1 -pic-is-pie -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/lib/libc/obj -resource-dir /usr/local/lib/clang/13.0.0 -include namespace.h -I /usr/src/lib/libc/include -I /usr/src/lib/libc/hidden -D __LIBC__ -D APIWARN -D YP -I /usr/src/lib/libc/yp -I /usr/src/lib/libc -I /usr/src/lib/libc/gdtoa -I /usr/src/lib/libc/arch/amd64/gdtoa -D INFNAN_CHECK -D MULTIPLE_THREADS -D NO_FENV_H -D USE_LOCALE -I /usr/src/lib/libc -I /usr/src/lib/libc/citrus -D RESOLVSORT -D FLOATING_POINT -D PRINTF_WIDE_CHAR -D SCANF_WIDE_CHAR -D FUTEX -internal-isystem /usr/local/lib/clang/13.0.0/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/lib/libc/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/ben/Projects/vmm/scan-build/2022-01-12-194120-40624-1 -x c /usr/src/lib/libc/asr/gethostnamadr_async.c
1/* $OpenBSD: gethostnamadr_async.c,v 1.45 2019/06/27 05:26:37 martijn Exp $ */
2/*
3 * Copyright (c) 2012 Eric Faurot <eric@openbsd.org>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18#include <sys/types.h>
19#include <sys/socket.h>
20#include <netinet/in.h>
21#include <arpa/inet.h>
22#include <arpa/nameser.h>
23#include <netdb.h>
24
25#include <asr.h>
26#include <ctype.h>
27#include <errno(*__errno()).h>
28#include <resolv.h> /* for res_hnok */
29#include <stdlib.h>
30#include <string.h>
31#include <unistd.h>
32#include <limits.h>
33
34#include "asr_private.h"
35
36#define MAXALIASES35 35
37#define MAXADDRS35 35
38
39struct hostent_ext {
40 struct hostent h;
41 char *aliases[MAXALIASES35 + 1];
42 char *addrs[MAXADDRS35 + 1];
43 char *end;
44 char *pos;
45};
46
47struct netent_ext {
48 struct netent n;
49 char *aliases[MAXALIASES35 + 1];
50 char *end;
51 char *pos;
52};
53
54static int gethostnamadr_async_run(struct asr_query *, struct asr_result *);
55static struct hostent_ext *hostent_alloc(int);
56static int hostent_set_cname(struct hostent_ext *, const char *, int);
57static int hostent_add_alias(struct hostent_ext *, const char *, int);
58static int hostent_add_addr(struct hostent_ext *, const void *, size_t);
59static struct hostent_ext *hostent_from_addr(int, const char *, const char *);
60static struct hostent_ext *hostent_file_match(FILE *, int, int, const char *,
61 int);
62static struct hostent_ext *hostent_from_packet(int, int, char *, size_t);
63static void netent_from_hostent(struct asr_result *ar);
64
65struct asr_query *
66gethostbyname_async(const char *name, void *asr)
67{
68 return gethostbyname2_async(name, AF_INET2, asr);
69}
70DEF_WEAK(gethostbyname_async)__asm__(".weak " "gethostbyname_async" " ; " "gethostbyname_async"
" = " "_libc_gethostbyname_async")
;
71
72struct asr_query *
73gethostbyname2_async(const char *name, int af, void *asr)
74{
75 struct asr_ctx *ac;
76 struct asr_query *as;
77
78 /* the original segfaults */
79 if (name == NULL((void *)0)) {
80 errno(*__errno()) = EINVAL22;
81 return (NULL((void *)0));
82 }
83
84 ac = _asr_use_resolver(asr);
85 if ((as = _asr_async_new(ac, ASR_GETHOSTBYNAME)) == NULL((void *)0))
86 goto abort; /* errno set */
87 as->as_run = gethostnamadr_async_run;
88
89 as->as.hostnamadr.family = af;
90 if (af == AF_INET2)
91 as->as.hostnamadr.addrlen = INADDRSZ4;
92 else if (af == AF_INET624)
93 as->as.hostnamadr.addrlen = IN6ADDRSZ16;
94 as->as.hostnamadr.name = strdup(name);
95 if (as->as.hostnamadr.name == NULL((void *)0))
96 goto abort; /* errno set */
97
98 _asr_ctx_unref(ac);
99 return (as);
100
101 abort:
102 if (as)
103 _asr_async_free(as);
104 _asr_ctx_unref(ac);
105 return (NULL((void *)0));
106}
107DEF_WEAK(gethostbyname2_async)__asm__(".weak " "gethostbyname2_async" " ; " "gethostbyname2_async"
" = " "_libc_gethostbyname2_async")
;
108
109struct asr_query *
110gethostbyaddr_async(const void *addr, socklen_t len, int af, void *asr)
111{
112 struct asr_ctx *ac;
113 struct asr_query *as;
114
115 ac = _asr_use_resolver(asr);
116 as = _gethostbyaddr_async_ctx(addr, len, af, ac);
117 _asr_ctx_unref(ac);
118
119 return (as);
120}
121DEF_WEAK(gethostbyaddr_async)__asm__(".weak " "gethostbyaddr_async" " ; " "gethostbyaddr_async"
" = " "_libc_gethostbyaddr_async")
;
122
123struct asr_query *
124_gethostbyaddr_async_ctx(const void *addr, socklen_t len, int af,
125 struct asr_ctx *ac)
126{
127 struct asr_query *as;
128
129 if ((as = _asr_async_new(ac, ASR_GETHOSTBYADDR)) == NULL((void *)0))
130 goto abort; /* errno set */
131 as->as_run = gethostnamadr_async_run;
132
133 as->as.hostnamadr.family = af;
134 as->as.hostnamadr.addrlen = len;
135 if (len > 0)
136 memmove(as->as.hostnamadr.addr, addr, (len > 16) ? 16 : len);
137
138 return (as);
139
140 abort:
141 if (as)
142 _asr_async_free(as);
143 return (NULL((void *)0));
144}
145
146static int
147gethostnamadr_async_run(struct asr_query *as, struct asr_result *ar)
148{
149 struct hostent_ext *h;
150 int r, type, saved_errno;
151 FILE *f;
152 char name[MAXDNAME1025], *data, addr[16], *c;
153
154 next:
155 switch (as->as_state) {
156
157 case ASR_STATE_INIT:
158
159 if (as->as.hostnamadr.family != AF_INET2 &&
160 as->as.hostnamadr.family != AF_INET624) {
161 ar->ar_h_errno = NETDB_INTERNAL-1;
162 ar->ar_errno = EAFNOSUPPORT47;
163 async_set_state(as, ASR_STATE_HALT)do { ; (as)->as_state = (ASR_STATE_HALT); } while (0);
164 break;
165 }
166
167 if ((as->as.hostnamadr.family == AF_INET2 &&
168 as->as.hostnamadr.addrlen != INADDRSZ4) ||
169 (as->as.hostnamadr.family == AF_INET624 &&
170 as->as.hostnamadr.addrlen != IN6ADDRSZ16)) {
171 ar->ar_h_errno = NETDB_INTERNAL-1;
172 ar->ar_errno = EINVAL22;
173 async_set_state(as, ASR_STATE_HALT)do { ; (as)->as_state = (ASR_STATE_HALT); } while (0);
174 break;
175 }
176
177 if (as->as_type == ASR_GETHOSTBYNAME) {
178
179 if (as->as.hostnamadr.name[0] == '\0') {
180 ar->ar_h_errno = NO_DATA4;
181 async_set_state(as, ASR_STATE_HALT)do { ; (as)->as_state = (ASR_STATE_HALT); } while (0);
182 break;
183 }
184
185 /* Name might be an IP address string */
186 for (c = as->as.hostnamadr.name; *c; c++)
187 if (!isdigit((unsigned char)*c) &&
188 *c != '.' && *c != ':')
189 break;
190 if (*c == 0 &&
191 inet_pton(as->as.hostnamadr.family,
192 as->as.hostnamadr.name, addr) == 1) {
193 h = hostent_from_addr(as->as.hostnamadr.family,
194 as->as.hostnamadr.name, addr);
195 if (h == NULL((void *)0)) {
196 ar->ar_errno = errno(*__errno());
197 ar->ar_h_errno = NETDB_INTERNAL-1;
198 }
199 else {
200 ar->ar_hostent = &h->h;
201 ar->ar_h_errno = NETDB_SUCCESS0;
202 }
203 async_set_state(as, ASR_STATE_HALT)do { ; (as)->as_state = (ASR_STATE_HALT); } while (0);
204 break;
205 }
206 }
207 async_set_state(as, ASR_STATE_NEXT_DB)do { ; (as)->as_state = (ASR_STATE_NEXT_DB); } while (0);
208 break;
209
210 case ASR_STATE_NEXT_DB:
211
212 if (_asr_iter_db(as) == -1) {
213 async_set_state(as, ASR_STATE_NOT_FOUND)do { ; (as)->as_state = (ASR_STATE_NOT_FOUND); } while (0);
214 break;
215 }
216
217 switch (AS_DB(as)((as)->as_ctx->ac_db[(as)->as_db_idx - 1])) {
218
219 case ASR_DB_DNS'b':
220
221 /* Create a subquery to do the DNS lookup */
222
223 if (as->as_type == ASR_GETHOSTBYNAME) {
224 type = (as->as.hostnamadr.family == AF_INET2) ?
225 T_A1 : T_AAAA28;
226 as->as_subq = _res_search_async_ctx(
227 as->as.hostnamadr.name,
228 C_IN1, type, as->as_ctx);
229 } else {
230 _asr_addr_as_fqdn(as->as.hostnamadr.addr,
231 as->as.hostnamadr.family,
232 name, sizeof(name));
233 as->as_subq = _res_query_async_ctx(
234 name, C_IN1, T_PTR12, as->as_ctx);
235 }
236
237 if (as->as_subq == NULL((void *)0)) {
238 ar->ar_errno = errno(*__errno());
239 ar->ar_h_errno = NETDB_INTERNAL-1;
240 async_set_state(as, ASR_STATE_HALT)do { ; (as)->as_state = (ASR_STATE_HALT); } while (0);
241 break;
242 }
243
244 async_set_state(as, ASR_STATE_SUBQUERY)do { ; (as)->as_state = (ASR_STATE_SUBQUERY); } while (0);
245 break;
246
247 case ASR_DB_FILE'f':
248
249 /* Try to find a match in the host file */
250
251 if ((f = fopen(_PATH_HOSTS"/etc/hosts", "re")) == NULL((void *)0))
252 break;
253
254 if (as->as_type == ASR_GETHOSTBYNAME)
255 data = as->as.hostnamadr.name;
256 else
257 data = as->as.hostnamadr.addr;
258
259 h = hostent_file_match(f, as->as_type,
260 as->as.hostnamadr.family, data,
261 as->as.hostnamadr.addrlen);
262 saved_errno = errno(*__errno());
263 fclose(f);
264 errno(*__errno()) = saved_errno;
265
266 if (h == NULL((void *)0)) {
267 if (errno(*__errno())) {
268 ar->ar_errno = errno(*__errno());
269 ar->ar_h_errno = NETDB_INTERNAL-1;
270 async_set_state(as, ASR_STATE_HALT)do { ; (as)->as_state = (ASR_STATE_HALT); } while (0);
271 }
272 /* otherwise not found */
273 break;
274 }
275 ar->ar_hostent = &h->h;
276 ar->ar_h_errno = NETDB_SUCCESS0;
277 async_set_state(as, ASR_STATE_HALT)do { ; (as)->as_state = (ASR_STATE_HALT); } while (0);
278 break;
279 }
280 break;
281
282 case ASR_STATE_SUBQUERY:
283
284 /* Run the DNS subquery. */
285
286 if ((r = asr_run(as->as_subq, ar)) == ASYNC_COND0)
Although the value stored to 'r' is used in the enclosing expression, the value is never actually read from 'r'
287 return (ASYNC_COND0);
288
289 /* Done. */
290 as->as_subq = NULL((void *)0);
291
292 /*
293 * We either got no packet or a packet without an answer.
294 * Saveguard the h_errno and use the next DB.
295 */
296 if (ar->ar_count == 0) {
297 free(ar->ar_data);
298 as->as.hostnamadr.subq_h_errno = ar->ar_h_errno;
299 async_set_state(as, ASR_STATE_NEXT_DB)do { ; (as)->as_state = (ASR_STATE_NEXT_DB); } while (0);
300 break;
301 }
302
303 /* Read the hostent from the packet. */
304
305 h = hostent_from_packet(as->as_type,
306 as->as.hostnamadr.family, ar->ar_data, ar->ar_datalen);
307 free(ar->ar_data);
308 if (h == NULL((void *)0)) {
309 ar->ar_errno = errno(*__errno());
310 ar->ar_h_errno = NETDB_INTERNAL-1;
311 async_set_state(as, ASR_STATE_HALT)do { ; (as)->as_state = (ASR_STATE_HALT); } while (0);
312 break;
313 }
314
315 if (as->as_type == ASR_GETHOSTBYADDR) {
316 if (hostent_add_addr(h, as->as.hostnamadr.addr,
317 as->as.hostnamadr.addrlen) == -1) {
318 free(h);
319 ar->ar_errno = errno(*__errno());
320 ar->ar_h_errno = NETDB_INTERNAL-1;
321 async_set_state(as, ASR_STATE_HALT)do { ; (as)->as_state = (ASR_STATE_HALT); } while (0);
322 break;
323 }
324 }
325
326 /*
327 * No valid hostname or address found in the dns packet.
328 * Ignore it.
329 */
330 if ((as->as_type == ASR_GETHOSTBYNAME &&
331 h->h.h_addr_list[0] == NULL((void *)0)) ||
332 h->h.h_name == NULL((void *)0)) {
333 free(h);
334 async_set_state(as, ASR_STATE_NEXT_DB)do { ; (as)->as_state = (ASR_STATE_NEXT_DB); } while (0);
335 break;
336 }
337
338 ar->ar_hostent = &h->h;
339 ar->ar_h_errno = NETDB_SUCCESS0;
340 async_set_state(as, ASR_STATE_HALT)do { ; (as)->as_state = (ASR_STATE_HALT); } while (0);
341 break;
342
343 case ASR_STATE_NOT_FOUND:
344 ar->ar_errno = 0;
345 if (as->as.hostnamadr.subq_h_errno)
346 ar->ar_h_errno = as->as.hostnamadr.subq_h_errno;
347 else
348 ar->ar_h_errno = HOST_NOT_FOUND1;
349 async_set_state(as, ASR_STATE_HALT)do { ; (as)->as_state = (ASR_STATE_HALT); } while (0);
350 break;
351
352 case ASR_STATE_HALT:
353 if (ar->ar_h_errno == NETDB_SUCCESS0 &&
354 as->as_flags & ASYNC_GETNET0x00001000)
355 netent_from_hostent(ar);
356 if (ar->ar_h_errno) {
357 ar->ar_hostent = NULL((void *)0);
358 ar->ar_netent = NULL((void *)0);
359 } else
360 ar->ar_errno = 0;
361 return (ASYNC_DONE1);
362
363 default:
364 ar->ar_errno = EOPNOTSUPP45;
365 ar->ar_h_errno = NETDB_INTERNAL-1;
366 ar->ar_gai_errno = EAI_SYSTEM-11;
367 async_set_state(as, ASR_STATE_HALT)do { ; (as)->as_state = (ASR_STATE_HALT); } while (0);
368 break;
369 }
370 goto next;
371}
372
373/*
374 * Create a hostent from a numeric address string.
375 */
376static struct hostent_ext *
377hostent_from_addr(int family, const char *name, const char *addr)
378{
379 struct hostent_ext *h;
380
381 if ((h = hostent_alloc(family)) == NULL((void *)0))
382 return (NULL((void *)0));
383 if (hostent_set_cname(h, name, 0) == -1)
384 goto fail;
385 if (hostent_add_addr(h, addr, h->h.h_length) == -1)
386 goto fail;
387 return (h);
388fail:
389 free(h);
390 return (NULL((void *)0));
391}
392
393/*
394 * Lookup the first matching entry in the hostfile, either by address or by
395 * name depending on reqtype, and build a hostent from the line.
396 */
397static struct hostent_ext *
398hostent_file_match(FILE *f, int reqtype, int family, const char *data,
399 int datalen)
400{
401 char *tokens[MAXTOKEN10], addr[16], buf[BUFSIZ1024 + 1];
402 struct hostent_ext *h;
403 int n, i;
404
405 for (;;) {
406 n = _asr_parse_namedb_line(f, tokens, MAXTOKEN10, buf, sizeof(buf));
407 if (n == -1) {
408 errno(*__errno()) = 0; /* ignore errors reading the file */
409 return (NULL((void *)0));
410 }
411
412 /* there must be an address and at least one name */
413 if (n < 2)
414 continue;
415
416 if (reqtype == ASR_GETHOSTBYNAME) {
417 for (i = 1; i < n; i++) {
418 if (strcasecmp(data, tokens[i]))
419 continue;
420 if (inet_pton(family, tokens[0], addr) == 1)
421 goto found;
422 }
423 } else {
424 if (inet_pton(family, tokens[0], addr) == 1 &&
425 memcmp(addr, data, datalen) == 0)
426 goto found;
427 }
428 }
429
430found:
431 if ((h = hostent_alloc(family)) == NULL((void *)0))
432 return (NULL((void *)0));
433 if (hostent_set_cname(h, tokens[1], 0) == -1)
434 goto fail;
435 for (i = 2; i < n; i ++)
436 if (hostent_add_alias(h, tokens[i], 0) == -1)
437 goto fail;
438 if (hostent_add_addr(h, addr, h->h.h_length) == -1)
439 goto fail;
440 return (h);
441fail:
442 free(h);
443 return (NULL((void *)0));
444}
445
446/*
447 * Fill the hostent from the given DNS packet.
448 */
449static struct hostent_ext *
450hostent_from_packet(int reqtype, int family, char *pkt, size_t pktlen)
451{
452 struct hostent_ext *h;
453 struct asr_unpack p;
454 struct asr_dns_header hdr;
455 struct asr_dns_query q;
456 struct asr_dns_rr rr;
457 char dname[MAXDNAME1025];
458
459 if ((h = hostent_alloc(family)) == NULL((void *)0))
460 return (NULL((void *)0));
461
462 _asr_unpack_init(&p, pkt, pktlen);
463 _asr_unpack_header(&p, &hdr);
464 for (; hdr.qdcount; hdr.qdcount--)
465 _asr_unpack_query(&p, &q);
466 strlcpy(dname, q.q_dname, sizeof(dname));
467
468 for (; hdr.ancount; hdr.ancount--) {
469 _asr_unpack_rr(&p, &rr);
470 if (rr.rr_class != C_IN1)
471 continue;
472 switch (rr.rr_type) {
473
474 case T_CNAME5:
475 if (reqtype == ASR_GETHOSTBYNAME) {
476 if (hostent_add_alias(h, rr.rr_dname, 1) == -1)
477 goto fail;
478 } else {
479 if (strcasecmp(rr.rr_dname, dname) == 0)
480 strlcpy(dname, rr.rr.cname.cname,
481 sizeof(dname));
482 }
483 break;
484
485 case T_PTR12:
486 if (reqtype != ASR_GETHOSTBYADDR)
487 break;
488 if (strcasecmp(rr.rr_dname, dname) != 0)
489 continue;
490 if (hostent_set_cname(h, rr.rr.ptr.ptrname, 1) == -1)
491 hostent_add_alias(h, rr.rr.ptr.ptrname, 1);
492 break;
493
494 case T_A1:
495 if (reqtype != ASR_GETHOSTBYNAME)
496 break;
497 if (family != AF_INET2)
498 break;
499 if (hostent_set_cname(h, rr.rr_dname, 1) == -1)
500 ;
501 if (hostent_add_addr(h, &rr.rr.in_a.addr, 4) == -1)
502 goto fail;
503 break;
504
505 case T_AAAA28:
506 if (reqtype != ASR_GETHOSTBYNAME)
507 break;
508 if (family != AF_INET624)
509 break;
510 if (hostent_set_cname(h, rr.rr_dname, 1) == -1)
511 ;
512 if (hostent_add_addr(h, &rr.rr.in_aaaa.addr6, 16) == -1)
513 goto fail;
514 break;
515 }
516 }
517
518 return (h);
519fail:
520 free(h);
521 return (NULL((void *)0));
522}
523
524static struct hostent_ext *
525hostent_alloc(int family)
526{
527 struct hostent_ext *h;
528 size_t alloc;
529
530 alloc = sizeof(*h) + 1024;
531 if ((h = calloc(1, alloc)) == NULL((void *)0))
532 return (NULL((void *)0));
533
534 h->h.h_addrtype = family;
535 h->h.h_length = (family == AF_INET2) ? 4 : 16;
536 h->h.h_aliases = h->aliases;
537 h->h.h_addr_list = h->addrs;
538 h->pos = (char *)(h) + sizeof(*h);
539 h->end = h->pos + 1024;
540
541 return (h);
542}
543
544static int
545hostent_set_cname(struct hostent_ext *h, const char *name, int isdname)
546{
547 char buf[MAXDNAME1025];
548 size_t n;
549
550 if (h->h.h_name)
551 return (-1);
552
553 if (isdname) {
554 _asr_strdname(name, buf, sizeof buf);
555 buf[strlen(buf) - 1] = '\0';
556 if (!res_hnok__res_hnok(buf))
557 return (-1);
558 name = buf;
559 }
560
561 n = strlen(name) + 1;
562 if (h->pos + n >= h->end)
563 return (-1);
564
565 h->h.h_name = h->pos;
566 memmove(h->pos, name, n);
567 h->pos += n;
568 return (0);
569}
570
571static int
572hostent_add_alias(struct hostent_ext *h, const char *name, int isdname)
573{
574 char buf[MAXDNAME1025];
575 size_t i, n;
576
577 for (i = 0; i < MAXALIASES35; i++)
578 if (h->aliases[i] == NULL((void *)0))
579 break;
580 if (i == MAXALIASES35)
581 return (0);
582
583 if (isdname) {
584 _asr_strdname(name, buf, sizeof buf);
585 buf[strlen(buf)-1] = '\0';
586 if (!res_hnok__res_hnok(buf))
587 return (-1);
588 name = buf;
589 }
590
591 n = strlen(name) + 1;
592 if (h->pos + n >= h->end)
593 return (0);
594
595 h->aliases[i] = h->pos;
596 memmove(h->pos, name, n);
597 h->pos += n;
598 return (0);
599}
600
601static int
602hostent_add_addr(struct hostent_ext *h, const void *addr, size_t size)
603{
604 int i;
605
606 for (i = 0; i < MAXADDRS35; i++)
607 if (h->addrs[i] == NULL((void *)0))
608 break;
609 if (i == MAXADDRS35)
610 return (0);
611
612 if (h->pos + size >= h->end)
613 return (0);
614
615 h->addrs[i] = h->pos;
616 memmove(h->pos, addr, size);
617 h->pos += size;
618 return (0);
619}
620
621static void
622netent_from_hostent(struct asr_result *ar)
623{
624 struct in_addr *addr;
625 struct netent_ext *n;
626 struct hostent_ext *h;
627 char **na, **ha;
628 size_t sz;
629
630 /* Allocate and initialize the output. */
631 if ((n = calloc(1, sizeof(*n) + 1024)) == NULL((void *)0)) {
632 ar->ar_h_errno = NETDB_INTERNAL-1;
633 ar->ar_errno = errno(*__errno());
634 goto out;
635 }
636 n->pos = (char *)(n) + sizeof(*n);
637 n->end = n->pos + 1024;
638 n->n.n_name = n->pos;
639 n->n.n_aliases = n->aliases;
640
641 /* Copy the fixed-size data. */
642 h = (struct hostent_ext *)ar->ar_hostent;
643 addr = (struct in_addr *)h->h.h_addrh_addr_list[0];
644 n->n.n_net = ntohl(addr->s_addr)(__uint32_t)(__builtin_constant_p(addr->s_addr) ? (__uint32_t
)(((__uint32_t)(addr->s_addr) & 0xff) << 24 | ((
__uint32_t)(addr->s_addr) & 0xff00) << 8 | ((__uint32_t
)(addr->s_addr) & 0xff0000) >> 8 | ((__uint32_t)
(addr->s_addr) & 0xff000000) >> 24) : __swap32md
(addr->s_addr))
;
645 n->n.n_addrtype = h->h.h_addrtype;
646
647 /* Copy the network name. */
648 sz = strlen(h->h.h_name) + 1;
649 memcpy(n->pos, h->h.h_name, sz);
650 n->pos += sz;
651
652 /*
653 * Copy the aliases.
654 * No overflow check is needed because we are merely copying
655 * a part of the data from a structure of the same size.
656 */
657 na = n->aliases;
658 for (ha = h->aliases; *ha != NULL((void *)0); ha++) {
659 sz = strlen(*ha) + 1;
660 memcpy(n->pos, *ha, sz);
661 *na++ = n->pos;
662 n->pos += sz;
663 }
664 *na = NULL((void *)0);
665
666 /* Handle the return values. */
667 ar->ar_netent = &n->n;
668out:
669 free(ar->ar_hostent);
670 ar->ar_hostent = NULL((void *)0);
671}