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