| Index: fusl/src/network/gethostbyaddr_r.c | 
| diff --git a/fusl/src/network/gethostbyaddr_r.c b/fusl/src/network/gethostbyaddr_r.c | 
| new file mode 100644 | 
| index 0000000000000000000000000000000000000000..66e03309408c9df979a0949a2f23acf3bd8b8591 | 
| --- /dev/null | 
| +++ b/fusl/src/network/gethostbyaddr_r.c | 
| @@ -0,0 +1,70 @@ | 
| +#define _GNU_SOURCE | 
| + | 
| +#include <sys/socket.h> | 
| +#include <netdb.h> | 
| +#include <string.h> | 
| +#include <netinet/in.h> | 
| +#include <errno.h> | 
| +#include <inttypes.h> | 
| + | 
| +int gethostbyaddr_r(const void *a, socklen_t l, int af, | 
| +	struct hostent *h, char *buf, size_t buflen, | 
| +	struct hostent **res, int *err) | 
| +{ | 
| +	union { | 
| +		struct sockaddr_in sin; | 
| +		struct sockaddr_in6 sin6; | 
| +	} sa = { .sin.sin_family = af }; | 
| +	socklen_t sl = af==AF_INET6 ? sizeof sa.sin6 : sizeof sa.sin; | 
| +	int i; | 
| + | 
| +	*res = 0; | 
| + | 
| +	/* Load address argument into sockaddr structure */ | 
| +	if (af==AF_INET6 && l==16) memcpy(&sa.sin6.sin6_addr, a, 16); | 
| +	else if (af==AF_INET && l==4) memcpy(&sa.sin.sin_addr, a, 4); | 
| +	else { | 
| +		*err = NO_RECOVERY; | 
| +		return EINVAL; | 
| +	} | 
| + | 
| +	/* Align buffer and check for space for pointers and ip address */ | 
| +	i = (uintptr_t)buf & sizeof(char *)-1; | 
| +	if (!i) i = sizeof(char *); | 
| +	if (buflen <= 5*sizeof(char *)-i + l) return ERANGE; | 
| +	buf += sizeof(char *)-i; | 
| +	buflen -= 5*sizeof(char *)-i + l; | 
| + | 
| +	h->h_addr_list = (void *)buf; | 
| +	buf += 2*sizeof(char *); | 
| +	h->h_aliases = (void *)buf; | 
| +	buf += 2*sizeof(char *); | 
| + | 
| +	h->h_addr_list[0] = buf; | 
| +	memcpy(h->h_addr_list[0], a, l); | 
| +	buf += l; | 
| +	h->h_addr_list[1] = 0; | 
| +	h->h_aliases[0] = buf; | 
| +	h->h_aliases[1] = 0; | 
| + | 
| +	switch (getnameinfo((void *)&sa, sl, buf, buflen, 0, 0, 0)) { | 
| +	case EAI_AGAIN: | 
| +		*err = TRY_AGAIN; | 
| +		return EAGAIN; | 
| +	case EAI_OVERFLOW: | 
| +		return ERANGE; | 
| +	default: | 
| +	case EAI_MEMORY: | 
| +	case EAI_SYSTEM: | 
| +	case EAI_FAIL: | 
| +		*err = NO_RECOVERY; | 
| +		return errno; | 
| +	case 0: | 
| +		break; | 
| +	} | 
| + | 
| +	h->h_addrtype = af; | 
| +	h->h_name = h->h_aliases[0]; | 
| +	*res = h; | 
| +	return 0; | 
| +} | 
|  |