X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=src%2Fnetwork%2Fgethostbyname2_r.c;h=f012ec2f9945a42d1de1ab4a57b8aab9b48524fe;hb=f081d5336a80b68d3e1bed789cc373c5c3d6699b;hp=27eb080f8502128179fcaa92a9bf15c8b66ea4f9;hpb=571744447c23f91feb6439948f3a619aca850dfb;p=musl diff --git a/src/network/gethostbyname2_r.c b/src/network/gethostbyname2_r.c index 27eb080f..f012ec2f 100644 --- a/src/network/gethostbyname2_r.c +++ b/src/network/gethostbyname2_r.c @@ -6,66 +6,62 @@ #include #include #include +#include "lookup.h" int gethostbyname2_r(const char *name, int af, struct hostent *h, char *buf, size_t buflen, struct hostent **res, int *err) { - struct addrinfo hint = { - .ai_family = af==AF_INET6 ? af : AF_INET, - .ai_flags = AI_CANONNAME - }; - struct addrinfo *ai, *p; - int i; - size_t need; - const char *canon; + struct address addrs[MAXADDRS]; + char canon[256]; + int i, cnt; + size_t align, need; - af = hint.ai_family; - - /* Align buffer */ - i = (uintptr_t)buf & sizeof(char *)-1; - if (i) { - if (buflen < sizeof(char *)-i) return ERANGE; - buf += sizeof(char *)-i; - buflen -= sizeof(char *)-i; - } - - switch (getaddrinfo(name, 0, &hint, &ai)) { + *res = 0; + cnt = __lookup_name(addrs, canon, name, af, AI_CANONNAME); + if (cnt<0) switch (cnt) { case EAI_NONAME: *err = HOST_NOT_FOUND; - return errno; + return 0; case EAI_AGAIN: *err = TRY_AGAIN; - return errno; + return EAGAIN; default: + case EAI_FAIL: + *err = NO_RECOVERY; + return EBADMSG; case EAI_MEMORY: case EAI_SYSTEM: - case EAI_FAIL: *err = NO_RECOVERY; return errno; - case 0: - break; } h->h_addrtype = af; h->h_length = af==AF_INET6 ? 16 : 4; - canon = ai->ai_canonname ? ai->ai_canonname : name; + /* Align buffer */ + align = -(uintptr_t)buf & sizeof(char *)-1; + need = 4*sizeof(char *); - for (i=0, p=ai; p; i++, p=p->ai_next) - need += sizeof(char *) + h->h_length; + need += (cnt + 1) * (sizeof(char *) + h->h_length); need += strlen(name)+1; need += strlen(canon)+1; + need += align; - if (need > buflen) { - freeaddrinfo(ai); - return ERANGE; - } + if (need > buflen) return ERANGE; + buf += align; h->h_aliases = (void *)buf; buf += 3*sizeof(char *); h->h_addr_list = (void *)buf; - buf += (i+1)*sizeof(char *); + buf += (cnt+1)*sizeof(char *); + + for (i=0; ih_addr_list[i] = (void *)buf; + buf += h->h_length; + memcpy(h->h_addr_list[i], addrs[i].addr, h->h_length); + } + h->h_addr_list[i] = 0; h->h_name = h->h_aliases[0] = buf; strcpy(h->h_name, canon); @@ -79,16 +75,6 @@ int gethostbyname2_r(const char *name, int af, h->h_aliases[2] = 0; - for (i=0, p=ai; p; i++, p=p->ai_next) { - h->h_addr_list[i] = (void *)buf; - buf += h->h_length; - memcpy(h->h_addr_list[i], - &((struct sockaddr_in *)p->ai_addr)->sin_addr, - h->h_length); - } - h->h_addr_list[i] = 0; - *res = h; - freeaddrinfo(ai); return 0; }