xref: /aosp_15_r20/external/musl/src/network/gethostbyname2_r.c (revision c9945492fdd68bbe62686c5b452b4dc1be3f8453)
1*c9945492SAndroid Build Coastguard Worker #define _GNU_SOURCE
2*c9945492SAndroid Build Coastguard Worker 
3*c9945492SAndroid Build Coastguard Worker #include <sys/socket.h>
4*c9945492SAndroid Build Coastguard Worker #include <netdb.h>
5*c9945492SAndroid Build Coastguard Worker #include <string.h>
6*c9945492SAndroid Build Coastguard Worker #include <netinet/in.h>
7*c9945492SAndroid Build Coastguard Worker #include <errno.h>
8*c9945492SAndroid Build Coastguard Worker #include <stdint.h>
9*c9945492SAndroid Build Coastguard Worker #include "lookup.h"
10*c9945492SAndroid Build Coastguard Worker 
gethostbyname2_r(const char * name,int af,struct hostent * h,char * buf,size_t buflen,struct hostent ** res,int * err)11*c9945492SAndroid Build Coastguard Worker int gethostbyname2_r(const char *name, int af,
12*c9945492SAndroid Build Coastguard Worker 	struct hostent *h, char *buf, size_t buflen,
13*c9945492SAndroid Build Coastguard Worker 	struct hostent **res, int *err)
14*c9945492SAndroid Build Coastguard Worker {
15*c9945492SAndroid Build Coastguard Worker 	struct address addrs[MAXADDRS];
16*c9945492SAndroid Build Coastguard Worker 	char canon[256];
17*c9945492SAndroid Build Coastguard Worker 	int i, cnt;
18*c9945492SAndroid Build Coastguard Worker 	size_t align, need;
19*c9945492SAndroid Build Coastguard Worker 
20*c9945492SAndroid Build Coastguard Worker 	*res = 0;
21*c9945492SAndroid Build Coastguard Worker 	cnt = __lookup_name(addrs, canon, name, af, AI_CANONNAME);
22*c9945492SAndroid Build Coastguard Worker 	if (cnt<0) switch (cnt) {
23*c9945492SAndroid Build Coastguard Worker 	case EAI_NONAME:
24*c9945492SAndroid Build Coastguard Worker 		*err = HOST_NOT_FOUND;
25*c9945492SAndroid Build Coastguard Worker 		return 0;
26*c9945492SAndroid Build Coastguard Worker 	case EAI_NODATA:
27*c9945492SAndroid Build Coastguard Worker 		*err = NO_DATA;
28*c9945492SAndroid Build Coastguard Worker 		return 0;
29*c9945492SAndroid Build Coastguard Worker 	case EAI_AGAIN:
30*c9945492SAndroid Build Coastguard Worker 		*err = TRY_AGAIN;
31*c9945492SAndroid Build Coastguard Worker 		return EAGAIN;
32*c9945492SAndroid Build Coastguard Worker 	default:
33*c9945492SAndroid Build Coastguard Worker 	case EAI_FAIL:
34*c9945492SAndroid Build Coastguard Worker 		*err = NO_RECOVERY;
35*c9945492SAndroid Build Coastguard Worker 		return EBADMSG;
36*c9945492SAndroid Build Coastguard Worker 	case EAI_SYSTEM:
37*c9945492SAndroid Build Coastguard Worker 		*err = NO_RECOVERY;
38*c9945492SAndroid Build Coastguard Worker 		return errno;
39*c9945492SAndroid Build Coastguard Worker 	}
40*c9945492SAndroid Build Coastguard Worker 
41*c9945492SAndroid Build Coastguard Worker 	h->h_addrtype = af;
42*c9945492SAndroid Build Coastguard Worker 	h->h_length = af==AF_INET6 ? 16 : 4;
43*c9945492SAndroid Build Coastguard Worker 
44*c9945492SAndroid Build Coastguard Worker 	/* Align buffer */
45*c9945492SAndroid Build Coastguard Worker 	align = -(uintptr_t)buf & sizeof(char *)-1;
46*c9945492SAndroid Build Coastguard Worker 
47*c9945492SAndroid Build Coastguard Worker 	need = 4*sizeof(char *);
48*c9945492SAndroid Build Coastguard Worker 	need += (cnt + 1) * (sizeof(char *) + h->h_length);
49*c9945492SAndroid Build Coastguard Worker 	need += strlen(name)+1;
50*c9945492SAndroid Build Coastguard Worker 	need += strlen(canon)+1;
51*c9945492SAndroid Build Coastguard Worker 	need += align;
52*c9945492SAndroid Build Coastguard Worker 
53*c9945492SAndroid Build Coastguard Worker 	if (need > buflen) return ERANGE;
54*c9945492SAndroid Build Coastguard Worker 
55*c9945492SAndroid Build Coastguard Worker 	buf += align;
56*c9945492SAndroid Build Coastguard Worker 	h->h_aliases = (void *)buf;
57*c9945492SAndroid Build Coastguard Worker 	buf += 3*sizeof(char *);
58*c9945492SAndroid Build Coastguard Worker 	h->h_addr_list = (void *)buf;
59*c9945492SAndroid Build Coastguard Worker 	buf += (cnt+1)*sizeof(char *);
60*c9945492SAndroid Build Coastguard Worker 
61*c9945492SAndroid Build Coastguard Worker 	for (i=0; i<cnt; i++) {
62*c9945492SAndroid Build Coastguard Worker 		h->h_addr_list[i] = (void *)buf;
63*c9945492SAndroid Build Coastguard Worker 		buf += h->h_length;
64*c9945492SAndroid Build Coastguard Worker 		memcpy(h->h_addr_list[i], addrs[i].addr, h->h_length);
65*c9945492SAndroid Build Coastguard Worker 	}
66*c9945492SAndroid Build Coastguard Worker 	h->h_addr_list[i] = 0;
67*c9945492SAndroid Build Coastguard Worker 
68*c9945492SAndroid Build Coastguard Worker 	h->h_name = h->h_aliases[0] = buf;
69*c9945492SAndroid Build Coastguard Worker 	strcpy(h->h_name, canon);
70*c9945492SAndroid Build Coastguard Worker 	buf += strlen(h->h_name)+1;
71*c9945492SAndroid Build Coastguard Worker 
72*c9945492SAndroid Build Coastguard Worker 	if (strcmp(h->h_name, name)) {
73*c9945492SAndroid Build Coastguard Worker 		h->h_aliases[1] = buf;
74*c9945492SAndroid Build Coastguard Worker 		strcpy(h->h_aliases[1], name);
75*c9945492SAndroid Build Coastguard Worker 		buf += strlen(h->h_aliases[1])+1;
76*c9945492SAndroid Build Coastguard Worker 	} else h->h_aliases[1] = 0;
77*c9945492SAndroid Build Coastguard Worker 
78*c9945492SAndroid Build Coastguard Worker 	h->h_aliases[2] = 0;
79*c9945492SAndroid Build Coastguard Worker 
80*c9945492SAndroid Build Coastguard Worker 	*res = h;
81*c9945492SAndroid Build Coastguard Worker 	return 0;
82*c9945492SAndroid Build Coastguard Worker }
83