|  | @@ -120,886 +120,778 @@ struct BUG_too_small {
 | 
	
		
			
				|  |  |  			) <= 127 ? 1 : -1];
 | 
	
		
			
				|  |  |  };
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -struct gaih_service
 | 
	
		
			
				|  |  | -{
 | 
	
		
			
				|  |  | -    const char *name;
 | 
	
		
			
				|  |  | -    int num;
 | 
	
		
			
				|  |  | +struct gaih_service {
 | 
	
		
			
				|  |  | +	const char *name;
 | 
	
		
			
				|  |  | +	int num;
 | 
	
		
			
				|  |  |  };
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -struct gaih_servtuple
 | 
	
		
			
				|  |  | -{
 | 
	
		
			
				|  |  | -    struct gaih_servtuple *next;
 | 
	
		
			
				|  |  | -    int socktype;
 | 
	
		
			
				|  |  | -    int protocol;
 | 
	
		
			
				|  |  | -    int port;
 | 
	
		
			
				|  |  | +struct gaih_servtuple {
 | 
	
		
			
				|  |  | +	struct gaih_servtuple *next;
 | 
	
		
			
				|  |  | +	int socktype;
 | 
	
		
			
				|  |  | +	int protocol;
 | 
	
		
			
				|  |  | +	int port;
 | 
	
		
			
				|  |  |  };
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -struct gaih_addrtuple
 | 
	
		
			
				|  |  | -{
 | 
	
		
			
				|  |  | -    struct gaih_addrtuple *next;
 | 
	
		
			
				|  |  | -    int family;
 | 
	
		
			
				|  |  | -    char addr[16];
 | 
	
		
			
				|  |  | -    uint32_t scopeid;
 | 
	
		
			
				|  |  | +struct gaih_addrtuple {
 | 
	
		
			
				|  |  | +	struct gaih_addrtuple *next;
 | 
	
		
			
				|  |  | +	int family;
 | 
	
		
			
				|  |  | +	char addr[16];
 | 
	
		
			
				|  |  | +	uint32_t scopeid;
 | 
	
		
			
				|  |  |  };
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -struct gaih_typeproto
 | 
	
		
			
				|  |  | -{
 | 
	
		
			
				|  |  | -    socktype_t socktype;
 | 
	
		
			
				|  |  | -    protocol_t protocol;
 | 
	
		
			
				|  |  | -    int8_t protoflag;
 | 
	
		
			
				|  |  | -    char name[4];
 | 
	
		
			
				|  |  | +struct gaih_typeproto {
 | 
	
		
			
				|  |  | +	socktype_t socktype;
 | 
	
		
			
				|  |  | +	protocol_t protocol;
 | 
	
		
			
				|  |  | +	int8_t protoflag;
 | 
	
		
			
				|  |  | +	char name[4];
 | 
	
		
			
				|  |  |  };
 | 
	
		
			
				|  |  |  /* Values for `protoflag'.  */
 | 
	
		
			
				|  |  | -#define GAI_PROTO_NOSERVICE	1
 | 
	
		
			
				|  |  | -#define GAI_PROTO_PROTOANY	2
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -static const struct gaih_typeproto gaih_inet_typeproto[] =
 | 
	
		
			
				|  |  | -{
 | 
	
		
			
				|  |  | -    { 0          , 0          , 0                                     , ""    },
 | 
	
		
			
				|  |  | -    { SOCK_STREAM, IPPROTO_TCP, 0                                     , "tcp" },
 | 
	
		
			
				|  |  | -    { SOCK_DGRAM , IPPROTO_UDP, 0                                     , "udp" },
 | 
	
		
			
				|  |  | -    { SOCK_RAW   , 0          , GAI_PROTO_PROTOANY|GAI_PROTO_NOSERVICE, "raw" },
 | 
	
		
			
				|  |  | -    { 0          , 0          , 0                                     , ""    },
 | 
	
		
			
				|  |  | +#define GAI_PROTO_NOSERVICE 1
 | 
	
		
			
				|  |  | +#define GAI_PROTO_PROTOANY  2
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +static const struct gaih_typeproto gaih_inet_typeproto[] = {
 | 
	
		
			
				|  |  | +	{ 0          , 0          , 0, ""    },
 | 
	
		
			
				|  |  | +	{ SOCK_STREAM, IPPROTO_TCP, 0, "tcp" },
 | 
	
		
			
				|  |  | +	{ SOCK_DGRAM , IPPROTO_UDP, 0, "udp" },
 | 
	
		
			
				|  |  | +	{ SOCK_RAW   , 0          , GAI_PROTO_PROTOANY|GAI_PROTO_NOSERVICE, "raw" },
 | 
	
		
			
				|  |  | +	{ 0          , 0          , 0, ""    },
 | 
	
		
			
				|  |  |  };
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -struct gaih
 | 
	
		
			
				|  |  | -{
 | 
	
		
			
				|  |  | -    int family;
 | 
	
		
			
				|  |  | -    int (*gaih)(const char *name, const struct gaih_service *service,
 | 
	
		
			
				|  |  | -		const struct addrinfo *req, struct addrinfo **pai);
 | 
	
		
			
				|  |  | +struct gaih {
 | 
	
		
			
				|  |  | +	int family;
 | 
	
		
			
				|  |  | +	int (*gaih)(const char *name, const struct gaih_service *service,
 | 
	
		
			
				|  |  | +			const struct addrinfo *req, struct addrinfo **pai);
 | 
	
		
			
				|  |  |  };
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  #define SEEN_IPV4 1
 | 
	
		
			
				|  |  |  #define SEEN_IPV6 2
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -static unsigned __check_pf (void)
 | 
	
		
			
				|  |  | +static unsigned __check_pf(void)
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  | -  unsigned seen = 0;
 | 
	
		
			
				|  |  | +	unsigned seen = 0;
 | 
	
		
			
				|  |  |  #if defined __UCLIBC_SUPPORT_AI_ADDRCONFIG__
 | 
	
		
			
				|  |  | -  {
 | 
	
		
			
				|  |  | -    /* Get the interface list via getifaddrs.  */
 | 
	
		
			
				|  |  | -    struct ifaddrs *ifa = NULL;
 | 
	
		
			
				|  |  | -    struct ifaddrs *runp;
 | 
	
		
			
				|  |  | -    if (getifaddrs (&ifa) != 0)
 | 
	
		
			
				|  |  | -    {
 | 
	
		
			
				|  |  | -      /* We cannot determine what interfaces are available.  Be
 | 
	
		
			
				|  |  | -      optimistic.  */
 | 
	
		
			
				|  |  | +	{
 | 
	
		
			
				|  |  | +		/* Get the interface list via getifaddrs.  */
 | 
	
		
			
				|  |  | +		struct ifaddrs *ifa = NULL;
 | 
	
		
			
				|  |  | +		struct ifaddrs *runp;
 | 
	
		
			
				|  |  | +		if (getifaddrs(&ifa) != 0) {
 | 
	
		
			
				|  |  | +			/* We cannot determine what interfaces are available.
 | 
	
		
			
				|  |  | +			 * Be optimistic.  */
 | 
	
		
			
				|  |  |  #if defined __UCLIBC_HAS_IPV4__
 | 
	
		
			
				|  |  | -      seen |= SEEN_IPV4;
 | 
	
		
			
				|  |  | +			seen |= SEEN_IPV4;
 | 
	
		
			
				|  |  |  #endif /* __UCLIBC_HAS_IPV4__ */
 | 
	
		
			
				|  |  |  #if defined __UCLIBC_HAS_IPV6__
 | 
	
		
			
				|  |  | -      seen |= SEEN_IPV6;
 | 
	
		
			
				|  |  | +			seen |= SEEN_IPV6;
 | 
	
		
			
				|  |  |  #endif /* __UCLIBC_HAS_IPV6__ */
 | 
	
		
			
				|  |  | -      return seen;
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | +			return seen;
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    for (runp = ifa; runp != NULL; runp = runp->ifa_next)
 | 
	
		
			
				|  |  | +		for (runp = ifa; runp != NULL; runp = runp->ifa_next)
 | 
	
		
			
				|  |  |  #if defined __UCLIBC_HAS_IPV4__
 | 
	
		
			
				|  |  | -      if (runp->ifa_addr->sa_family == PF_INET)
 | 
	
		
			
				|  |  | -        seen |= SEEN_IPV4;
 | 
	
		
			
				|  |  | +			if (runp->ifa_addr->sa_family == PF_INET)
 | 
	
		
			
				|  |  | +				seen |= SEEN_IPV4;
 | 
	
		
			
				|  |  |  #endif /* __UCLIBC_HAS_IPV4__ */
 | 
	
		
			
				|  |  |  #if defined __UCLIBC_HAS_IPV4__ && defined __UCLIBC_HAS_IPV6__
 | 
	
		
			
				|  |  | -      else /* can't be both at once */
 | 
	
		
			
				|  |  | +			else /* can't be both at once */
 | 
	
		
			
				|  |  |  #endif /* __UCLIBC_HAS_IPV4__ && defined __UCLIBC_HAS_IPV6__ */
 | 
	
		
			
				|  |  |  #if defined __UCLIBC_HAS_IPV6__
 | 
	
		
			
				|  |  | -      if (runp->ifa_addr->sa_family == PF_INET6)
 | 
	
		
			
				|  |  | -        seen |= SEEN_IPV6;
 | 
	
		
			
				|  |  | +			if (runp->ifa_addr->sa_family == PF_INET6)
 | 
	
		
			
				|  |  | +				seen |= SEEN_IPV6;
 | 
	
		
			
				|  |  |  #endif /* __UCLIBC_HAS_IPV6__ */
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    (void) freeifaddrs (ifa);
 | 
	
		
			
				|  |  | -  }
 | 
	
		
			
				|  |  | +		freeifaddrs(ifa);
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  |  #else
 | 
	
		
			
				|  |  | -  /* AI_ADDRCONFIG is disabled, assume both ipv4 and ipv6 available. */
 | 
	
		
			
				|  |  | +	/* AI_ADDRCONFIG is disabled, assume both ipv4 and ipv6 available. */
 | 
	
		
			
				|  |  |  #if defined __UCLIBC_HAS_IPV4__
 | 
	
		
			
				|  |  | -  seen |= SEEN_IPV4;
 | 
	
		
			
				|  |  | +	seen |= SEEN_IPV4;
 | 
	
		
			
				|  |  |  #endif /* __UCLIBC_HAS_IPV4__ */
 | 
	
		
			
				|  |  |  #if defined __UCLIBC_HAS_IPV6__
 | 
	
		
			
				|  |  | -  seen |= SEEN_IPV6;
 | 
	
		
			
				|  |  | +	seen |= SEEN_IPV6;
 | 
	
		
			
				|  |  |  #endif /* __UCLIBC_HAS_IPV6__ */
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  #endif /* __UCLIBC_SUPPORT_AI_ADDRCONFIG__ */
 | 
	
		
			
				|  |  | -  return seen;
 | 
	
		
			
				|  |  | +	return seen;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -static int addrconfig (sa_family_t af)
 | 
	
		
			
				|  |  | +static int addrconfig(sa_family_t af)
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  | -    int s;
 | 
	
		
			
				|  |  | -    int ret;
 | 
	
		
			
				|  |  | -    int saved_errno = errno;
 | 
	
		
			
				|  |  | -    unsigned seen;
 | 
	
		
			
				|  |  | +	int s;
 | 
	
		
			
				|  |  | +	int ret;
 | 
	
		
			
				|  |  | +	int saved_errno = errno;
 | 
	
		
			
				|  |  | +	unsigned seen;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    seen = __check_pf();
 | 
	
		
			
				|  |  | +	seen = __check_pf();
 | 
	
		
			
				|  |  |  #if defined __UCLIBC_HAS_IPV4__
 | 
	
		
			
				|  |  | -    if (af == AF_INET)
 | 
	
		
			
				|  |  | -	ret = seen & SEEN_IPV4;
 | 
	
		
			
				|  |  | -    else
 | 
	
		
			
				|  |  | +	if (af == AF_INET)
 | 
	
		
			
				|  |  | +		ret = seen & SEEN_IPV4;
 | 
	
		
			
				|  |  | +	else
 | 
	
		
			
				|  |  |  #endif
 | 
	
		
			
				|  |  |  #if defined __UCLIBC_HAS_IPV6__
 | 
	
		
			
				|  |  | -    if (af == AF_INET6)
 | 
	
		
			
				|  |  | -	ret = seen & SEEN_IPV6;
 | 
	
		
			
				|  |  | -    else
 | 
	
		
			
				|  |  | +	if (af == AF_INET6)
 | 
	
		
			
				|  |  | +		ret = seen & SEEN_IPV6;
 | 
	
		
			
				|  |  | +	else
 | 
	
		
			
				|  |  |  #endif
 | 
	
		
			
				|  |  | -    {
 | 
	
		
			
				|  |  | -	s = socket(af, SOCK_DGRAM, 0);
 | 
	
		
			
				|  |  | -	ret = 1; /* Assume PF_UNIX. */
 | 
	
		
			
				|  |  | -	if (s < 0) {
 | 
	
		
			
				|  |  | -	    if (errno != EMFILE)
 | 
	
		
			
				|  |  | -	        ret = 0;
 | 
	
		
			
				|  |  | +	{
 | 
	
		
			
				|  |  | +		s = socket(af, SOCK_DGRAM, 0);
 | 
	
		
			
				|  |  | +		ret = 1; /* Assume PF_UNIX. */
 | 
	
		
			
				|  |  | +		if (s < 0) {
 | 
	
		
			
				|  |  | +			if (errno != EMFILE)
 | 
	
		
			
				|  |  | +	        		ret = 0;
 | 
	
		
			
				|  |  | +		} else
 | 
	
		
			
				|  |  | +			close(s);
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  | -	else
 | 
	
		
			
				|  |  | -	    close(s);
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -    __set_errno (saved_errno);
 | 
	
		
			
				|  |  | -    return ret;
 | 
	
		
			
				|  |  | +	__set_errno(saved_errno);
 | 
	
		
			
				|  |  | +	return ret;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  #if 0
 | 
	
		
			
				|  |  |  /* Using Unix sockets this way is a security risk.  */
 | 
	
		
			
				|  |  |  static int
 | 
	
		
			
				|  |  | -gaih_local (const char *name, const struct gaih_service *service,
 | 
	
		
			
				|  |  | +gaih_local(const char *name, const struct gaih_service *service,
 | 
	
		
			
				|  |  |  	    const struct addrinfo *req, struct addrinfo **pai)
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  | -    struct utsname utsname;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    if ((name != NULL) && (req->ai_flags & AI_NUMERICHOST))
 | 
	
		
			
				|  |  | -	return GAIH_OKIFUNSPEC | -EAI_NONAME;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    if ((name != NULL) || (req->ai_flags & AI_CANONNAME))
 | 
	
		
			
				|  |  | -	if (uname (&utsname) < 0)
 | 
	
		
			
				|  |  | -	    return -EAI_SYSTEM;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    if (name != NULL)
 | 
	
		
			
				|  |  | -    {
 | 
	
		
			
				|  |  | -	if (strcmp(name, "localhost") &&
 | 
	
		
			
				|  |  | -	    strcmp(name, "local") &&
 | 
	
		
			
				|  |  | -	    strcmp(name, "unix") &&
 | 
	
		
			
				|  |  | -	    strcmp(name, utsname.nodename))
 | 
	
		
			
				|  |  | -	    return GAIH_OKIFUNSPEC | -EAI_NONAME;
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    if (req->ai_protocol || req->ai_socktype)
 | 
	
		
			
				|  |  | -    {
 | 
	
		
			
				|  |  | -	const struct gaih_typeproto *tp = gaih_inet_typeproto + 1;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	while (tp->name[0]
 | 
	
		
			
				|  |  | -	       && ((tp->protoflag & GAI_PROTO_NOSERVICE) != 0
 | 
	
		
			
				|  |  | -		   || (req->ai_socktype != 0 && req->ai_socktype != tp->socktype)
 | 
	
		
			
				|  |  | -		   || (req->ai_protocol != 0
 | 
	
		
			
				|  |  | -		       && !(tp->protoflag & GAI_PROTO_PROTOANY)
 | 
	
		
			
				|  |  | -		       && req->ai_protocol != tp->protocol)))
 | 
	
		
			
				|  |  | -	    ++tp;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	if (! tp->name[0])
 | 
	
		
			
				|  |  | -	{
 | 
	
		
			
				|  |  | -	    if (req->ai_socktype)
 | 
	
		
			
				|  |  | -		return (GAIH_OKIFUNSPEC | -EAI_SOCKTYPE);
 | 
	
		
			
				|  |  | -	    return (GAIH_OKIFUNSPEC | -EAI_SERVICE);
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    *pai = malloc (sizeof (struct addrinfo) + sizeof (struct sockaddr_un)
 | 
	
		
			
				|  |  | -		   + ((req->ai_flags & AI_CANONNAME)
 | 
	
		
			
				|  |  | -		      ? (strlen(utsname.nodename) + 1): 0));
 | 
	
		
			
				|  |  | -    if (*pai == NULL)
 | 
	
		
			
				|  |  | -	return -EAI_MEMORY;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    (*pai)->ai_next = NULL;
 | 
	
		
			
				|  |  | -    (*pai)->ai_flags = req->ai_flags;
 | 
	
		
			
				|  |  | -    (*pai)->ai_family = AF_LOCAL;
 | 
	
		
			
				|  |  | -    (*pai)->ai_socktype = req->ai_socktype ? req->ai_socktype : SOCK_STREAM;
 | 
	
		
			
				|  |  | -    (*pai)->ai_protocol = req->ai_protocol;
 | 
	
		
			
				|  |  | -    (*pai)->ai_addrlen = sizeof (struct sockaddr_un);
 | 
	
		
			
				|  |  | -    (*pai)->ai_addr = (void *) (*pai) + sizeof (struct addrinfo);
 | 
	
		
			
				|  |  | +	struct utsname utsname;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	if ((name != NULL) && (req->ai_flags & AI_NUMERICHOST))
 | 
	
		
			
				|  |  | +		return GAIH_OKIFUNSPEC | -EAI_NONAME;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	if ((name != NULL) || (req->ai_flags & AI_CANONNAME))
 | 
	
		
			
				|  |  | +		if (uname(&utsname) < 0)
 | 
	
		
			
				|  |  | +			return -EAI_SYSTEM;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	if (name != NULL) {
 | 
	
		
			
				|  |  | +		if (strcmp(name, "localhost") &&
 | 
	
		
			
				|  |  | +		    strcmp(name, "local") &&
 | 
	
		
			
				|  |  | +		    strcmp(name, "unix") &&
 | 
	
		
			
				|  |  | +		    strcmp(name, utsname.nodename))
 | 
	
		
			
				|  |  | +			return (GAIH_OKIFUNSPEC | -EAI_NONAME);
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +		if (req->ai_protocol || req->ai_socktype) {
 | 
	
		
			
				|  |  | +			const struct gaih_typeproto *tp = gaih_inet_typeproto + 1;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +			while (tp->name[0]
 | 
	
		
			
				|  |  | +			    && ((tp->protoflag & GAI_PROTO_NOSERVICE) != 0
 | 
	
		
			
				|  |  | +			       || (req->ai_socktype != 0 && req->ai_socktype != tp->socktype)
 | 
	
		
			
				|  |  | +			       || (req->ai_protocol != 0 && !(tp->protoflag & GAI_PROTO_PROTOANY) && req->ai_protocol != tp->protocol))
 | 
	
		
			
				|  |  | +			) {
 | 
	
		
			
				|  |  | +				++tp;
 | 
	
		
			
				|  |  | +			}
 | 
	
		
			
				|  |  | +			if (! tp->name[0]) {
 | 
	
		
			
				|  |  | +				if (req->ai_socktype)
 | 
	
		
			
				|  |  | +					return (GAIH_OKIFUNSPEC | -EAI_SOCKTYPE);
 | 
	
		
			
				|  |  | +				return (GAIH_OKIFUNSPEC | -EAI_SERVICE);
 | 
	
		
			
				|  |  | +			}
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +		*pai = malloc(sizeof(struct addrinfo) + sizeof(struct sockaddr_un)
 | 
	
		
			
				|  |  | +			+ ((req->ai_flags & AI_CANONNAME)
 | 
	
		
			
				|  |  | +			    ? (strlen(utsname.nodename) + 1): 0));
 | 
	
		
			
				|  |  | +		if (*pai == NULL)
 | 
	
		
			
				|  |  | +			return -EAI_MEMORY;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +		(*pai)->ai_next = NULL;
 | 
	
		
			
				|  |  | +		(*pai)->ai_flags = req->ai_flags;
 | 
	
		
			
				|  |  | +		(*pai)->ai_family = AF_LOCAL;
 | 
	
		
			
				|  |  | +		(*pai)->ai_socktype = req->ai_socktype ? req->ai_socktype : SOCK_STREAM;
 | 
	
		
			
				|  |  | +		(*pai)->ai_protocol = req->ai_protocol;
 | 
	
		
			
				|  |  | +		(*pai)->ai_addrlen = sizeof(struct sockaddr_un);
 | 
	
		
			
				|  |  | +		(*pai)->ai_addr = (void *)(*pai) + sizeof(struct addrinfo);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  #if SALEN
 | 
	
		
			
				|  |  | -    ((struct sockaddr_un *) (*pai)->ai_addr)->sun_len =
 | 
	
		
			
				|  |  | -	sizeof (struct sockaddr_un);
 | 
	
		
			
				|  |  | +		((struct sockaddr_un *)(*pai)->ai_addr)->sun_len = sizeof(struct sockaddr_un);
 | 
	
		
			
				|  |  |  #endif /* SALEN */
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    ((struct sockaddr_un *)(*pai)->ai_addr)->sun_family = AF_LOCAL;
 | 
	
		
			
				|  |  | -    memset(((struct sockaddr_un *)(*pai)->ai_addr)->sun_path, 0, UNIX_PATH_MAX);
 | 
	
		
			
				|  |  | +		((struct sockaddr_un *)(*pai)->ai_addr)->sun_family = AF_LOCAL;
 | 
	
		
			
				|  |  | +		memset(((struct sockaddr_un *)(*pai)->ai_addr)->sun_path, 0, UNIX_PATH_MAX);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    if (service)
 | 
	
		
			
				|  |  | -    {
 | 
	
		
			
				|  |  | -	struct sockaddr_un *sunp = (struct sockaddr_un *) (*pai)->ai_addr;
 | 
	
		
			
				|  |  | +		if (service) {
 | 
	
		
			
				|  |  | +			struct sockaddr_un *sunp = (struct sockaddr_un *)(*pai)->ai_addr;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -	if (strchr (service->name, '/') != NULL)
 | 
	
		
			
				|  |  | -	{
 | 
	
		
			
				|  |  | -	    if (strlen (service->name) >= sizeof (sunp->sun_path))
 | 
	
		
			
				|  |  | -		return GAIH_OKIFUNSPEC | -EAI_SERVICE;
 | 
	
		
			
				|  |  | +			if (strchr(service->name, '/') != NULL) {
 | 
	
		
			
				|  |  | +				if (strlen(service->name) >= sizeof(sunp->sun_path))
 | 
	
		
			
				|  |  | +					return GAIH_OKIFUNSPEC | -EAI_SERVICE;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -	    strcpy (sunp->sun_path, service->name);
 | 
	
		
			
				|  |  | +			strcpy(sunp->sun_path, service->name);
 | 
	
		
			
				|  |  | +		} else {
 | 
	
		
			
				|  |  | +			if (strlen(P_tmpdir "/") + 1 + strlen(service->name) >= sizeof(sunp->sun_path))
 | 
	
		
			
				|  |  | +				return (GAIH_OKIFUNSPEC | -EAI_SERVICE);
 | 
	
		
			
				|  |  | +			stpcpy(stpcpy(sunp->sun_path, P_tmpdir "/"), service->name);
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +	} else {
 | 
	
		
			
				|  |  | +		/* This is a dangerous use of the interface since there is a time
 | 
	
		
			
				|  |  | +		   window between the test for the file and the actual creation
 | 
	
		
			
				|  |  | +		   (done by the caller) in which a file with the same name could
 | 
	
		
			
				|  |  | +		   be created.  */
 | 
	
		
			
				|  |  | +		char *buf = ((struct sockaddr_un *)(*pai)->ai_addr)->sun_path;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +		if (__path_search(buf, L_tmpnam, NULL, NULL, 0) != 0
 | 
	
		
			
				|  |  | +		 || __gen_tempname(buf, __GT_NOCREATE) != 0
 | 
	
		
			
				|  |  | +		) {
 | 
	
		
			
				|  |  | +			return -EAI_SYSTEM;
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  | -	else
 | 
	
		
			
				|  |  | -	{
 | 
	
		
			
				|  |  | -	    if (strlen (P_tmpdir "/") + 1 + strlen (service->name) >=
 | 
	
		
			
				|  |  | -		sizeof (sunp->sun_path))
 | 
	
		
			
				|  |  | -		return GAIH_OKIFUNSPEC | -EAI_SERVICE;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -	    stpcpy (stpcpy (sunp->sun_path, P_tmpdir "/"), service->name);
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -    else
 | 
	
		
			
				|  |  | -    {
 | 
	
		
			
				|  |  | -	/* This is a dangerous use of the interface since there is a time
 | 
	
		
			
				|  |  | -	   window between the test for the file and the actual creation
 | 
	
		
			
				|  |  | -	   (done by the caller) in which a file with the same name could
 | 
	
		
			
				|  |  | -	   be created.  */
 | 
	
		
			
				|  |  | -	char *buf = ((struct sockaddr_un *) (*pai)->ai_addr)->sun_path;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	if (__builtin_expect (__path_search (buf, L_tmpnam, NULL, NULL, 0),
 | 
	
		
			
				|  |  | -			      0) != 0
 | 
	
		
			
				|  |  | -	    || __builtin_expect (__gen_tempname (buf, __GT_NOCREATE), 0) != 0)
 | 
	
		
			
				|  |  | -	    return -EAI_SYSTEM;
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    if (req->ai_flags & AI_CANONNAME)
 | 
	
		
			
				|  |  | -	(*pai)->ai_canonname = strcpy ((char *) *pai + sizeof (struct addrinfo)
 | 
	
		
			
				|  |  | -				       + sizeof (struct sockaddr_un),
 | 
	
		
			
				|  |  | -				       utsname.nodename);
 | 
	
		
			
				|  |  | -    else
 | 
	
		
			
				|  |  | -	(*pai)->ai_canonname = NULL;
 | 
	
		
			
				|  |  | -    return 0;
 | 
	
		
			
				|  |  | +	if (req->ai_flags & AI_CANONNAME)
 | 
	
		
			
				|  |  | +		(*pai)->ai_canonname = strcpy((char *) *pai + sizeof(struct addrinfo) + sizeof(struct sockaddr_un),
 | 
	
		
			
				|  |  | +				utsname.nodename);
 | 
	
		
			
				|  |  | +	else
 | 
	
		
			
				|  |  | +		(*pai)->ai_canonname = NULL;
 | 
	
		
			
				|  |  | +	return 0;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  #endif	/* 0 */
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  static int
 | 
	
		
			
				|  |  | -gaih_inet_serv (const char *servicename, const struct gaih_typeproto *tp,
 | 
	
		
			
				|  |  | +gaih_inet_serv(const char *servicename, const struct gaih_typeproto *tp,
 | 
	
		
			
				|  |  |  		const struct addrinfo *req, struct gaih_servtuple *st)
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  | -    struct servent *s;
 | 
	
		
			
				|  |  | -    size_t tmpbuflen = 1024;
 | 
	
		
			
				|  |  | -    struct servent ts;
 | 
	
		
			
				|  |  | -    char *tmpbuf;
 | 
	
		
			
				|  |  | -    int r;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    do
 | 
	
		
			
				|  |  | -    {
 | 
	
		
			
				|  |  | -	tmpbuf = alloca (tmpbuflen);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	r = getservbyname_r (servicename, tp->name, &ts, tmpbuf, tmpbuflen,
 | 
	
		
			
				|  |  | -			     &s);
 | 
	
		
			
				|  |  | -	if (r != 0 || s == NULL)
 | 
	
		
			
				|  |  | -	{
 | 
	
		
			
				|  |  | -	    if (r == ERANGE)
 | 
	
		
			
				|  |  | +	struct servent *s;
 | 
	
		
			
				|  |  | +	size_t tmpbuflen = 1024;
 | 
	
		
			
				|  |  | +	struct servent ts;
 | 
	
		
			
				|  |  | +	char *tmpbuf;
 | 
	
		
			
				|  |  | +	int r;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	while (1) {
 | 
	
		
			
				|  |  | +		tmpbuf = alloca(tmpbuflen);
 | 
	
		
			
				|  |  | +		r = getservbyname_r(servicename, tp->name, &ts, tmpbuf, tmpbuflen, &s);
 | 
	
		
			
				|  |  | +		if (r == 0 && s != NULL)
 | 
	
		
			
				|  |  | +			break;
 | 
	
		
			
				|  |  | +		if (r != ERANGE)
 | 
	
		
			
				|  |  | +			return (GAIH_OKIFUNSPEC | -EAI_SERVICE);
 | 
	
		
			
				|  |  |  		tmpbuflen *= 2;
 | 
	
		
			
				|  |  | -	    else
 | 
	
		
			
				|  |  | -		return GAIH_OKIFUNSPEC | -EAI_SERVICE;
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -    while (r);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    st->next = NULL;
 | 
	
		
			
				|  |  | -    st->socktype = tp->socktype;
 | 
	
		
			
				|  |  | -    st->protocol = ((tp->protoflag & GAI_PROTO_PROTOANY)
 | 
	
		
			
				|  |  | -		    ? req->ai_protocol : tp->protocol);
 | 
	
		
			
				|  |  | -    st->port = s->s_port;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    return 0;
 | 
	
		
			
				|  |  | +	st->next = NULL;
 | 
	
		
			
				|  |  | +	st->socktype = tp->socktype;
 | 
	
		
			
				|  |  | +	st->protocol = ((tp->protoflag & GAI_PROTO_PROTOANY) ? req->ai_protocol : tp->protocol);
 | 
	
		
			
				|  |  | +	st->port = s->s_port;
 | 
	
		
			
				|  |  | +	return 0;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -#define gethosts(_family, _type)					\
 | 
	
		
			
				|  |  | -{									\
 | 
	
		
			
				|  |  | -    int i, herrno;							\
 | 
	
		
			
				|  |  | -    size_t tmpbuflen;							\
 | 
	
		
			
				|  |  | -    struct hostent th;							\
 | 
	
		
			
				|  |  | -    char *tmpbuf;							\
 | 
	
		
			
				|  |  | -    tmpbuflen = 512;							\
 | 
	
		
			
				|  |  | -    no_data = 0;							\
 | 
	
		
			
				|  |  | -    do {								\
 | 
	
		
			
				|  |  | -	tmpbuflen *= 2;							\
 | 
	
		
			
				|  |  | -	tmpbuf = alloca (tmpbuflen);					\
 | 
	
		
			
				|  |  | -	rc = gethostbyname2_r (name, _family, &th, tmpbuf,		\
 | 
	
		
			
				|  |  | -			       tmpbuflen, &h, &herrno);			\
 | 
	
		
			
				|  |  | -    } while (rc == ERANGE && herrno == NETDB_INTERNAL);			\
 | 
	
		
			
				|  |  | -    if (rc != 0)							\
 | 
	
		
			
				|  |  | -    {									\
 | 
	
		
			
				|  |  | -	if (herrno == NETDB_INTERNAL)					\
 | 
	
		
			
				|  |  | -	{								\
 | 
	
		
			
				|  |  | -	    __set_h_errno (herrno);					\
 | 
	
		
			
				|  |  | -		return -EAI_SYSTEM;					\
 | 
	
		
			
				|  |  | -	}								\
 | 
	
		
			
				|  |  | -	if (herrno == TRY_AGAIN)					\
 | 
	
		
			
				|  |  | -	    no_data = EAI_AGAIN;					\
 | 
	
		
			
				|  |  | -	else								\
 | 
	
		
			
				|  |  | -	    no_data = herrno == NO_DATA;				\
 | 
	
		
			
				|  |  | -    }									\
 | 
	
		
			
				|  |  | -    else if (h != NULL)							\
 | 
	
		
			
				|  |  | -    {									\
 | 
	
		
			
				|  |  | -	for (i = 0; h->h_addr_list[i]; i++)				\
 | 
	
		
			
				|  |  | -	{								\
 | 
	
		
			
				|  |  | -	    if (*pat == NULL) {						\
 | 
	
		
			
				|  |  | -		*pat = alloca (sizeof(struct gaih_addrtuple));		\
 | 
	
		
			
				|  |  | -		    (*pat)->scopeid = 0;				\
 | 
	
		
			
				|  |  | -	    }								\
 | 
	
		
			
				|  |  | -	    (*pat)->next = NULL;					\
 | 
	
		
			
				|  |  | -		(*pat)->family = _family;				\
 | 
	
		
			
				|  |  | -		memcpy ((*pat)->addr, h->h_addr_list[i],		\
 | 
	
		
			
				|  |  | -			sizeof(_type));					\
 | 
	
		
			
				|  |  | -		pat = &((*pat)->next);					\
 | 
	
		
			
				|  |  | -	}								\
 | 
	
		
			
				|  |  | -    }									\
 | 
	
		
			
				|  |  | +/* NB: also uses h,pat,rc,no_data variables */
 | 
	
		
			
				|  |  | +#define gethosts(_family, _type)						\
 | 
	
		
			
				|  |  | +{										\
 | 
	
		
			
				|  |  | +	int i, herrno;								\
 | 
	
		
			
				|  |  | +	size_t tmpbuflen;							\
 | 
	
		
			
				|  |  | +	struct hostent th;							\
 | 
	
		
			
				|  |  | +	char *tmpbuf;								\
 | 
	
		
			
				|  |  | +										\
 | 
	
		
			
				|  |  | +	tmpbuflen = 512;							\
 | 
	
		
			
				|  |  | +	no_data = 0;								\
 | 
	
		
			
				|  |  | +	do {									\
 | 
	
		
			
				|  |  | +		tmpbuflen *= 2;							\
 | 
	
		
			
				|  |  | +		tmpbuf = alloca(tmpbuflen);					\
 | 
	
		
			
				|  |  | +		rc = gethostbyname2_r(name, _family, &th, tmpbuf,		\
 | 
	
		
			
				|  |  | +				tmpbuflen, &h, &herrno);			\
 | 
	
		
			
				|  |  | +	} while (rc == ERANGE && herrno == NETDB_INTERNAL);			\
 | 
	
		
			
				|  |  | +	if (rc != 0) {								\
 | 
	
		
			
				|  |  | +		if (herrno == NETDB_INTERNAL) {					\
 | 
	
		
			
				|  |  | +			__set_h_errno(herrno);					\
 | 
	
		
			
				|  |  | +			return -EAI_SYSTEM;					\
 | 
	
		
			
				|  |  | +		}								\
 | 
	
		
			
				|  |  | +		if (herrno == TRY_AGAIN)					\
 | 
	
		
			
				|  |  | +			no_data = EAI_AGAIN;					\
 | 
	
		
			
				|  |  | +		else								\
 | 
	
		
			
				|  |  | +			no_data = (herrno == NO_DATA);				\
 | 
	
		
			
				|  |  | +	} else if (h != NULL) {							\
 | 
	
		
			
				|  |  | +		for (i = 0; h->h_addr_list[i]; i++) {				\
 | 
	
		
			
				|  |  | +			if (*pat == NULL) {					\
 | 
	
		
			
				|  |  | +				*pat = alloca(sizeof(struct gaih_addrtuple));	\
 | 
	
		
			
				|  |  | +				(*pat)->scopeid = 0;				\
 | 
	
		
			
				|  |  | +			}							\
 | 
	
		
			
				|  |  | +			(*pat)->next = NULL;					\
 | 
	
		
			
				|  |  | +			(*pat)->family = _family;				\
 | 
	
		
			
				|  |  | +			memcpy((*pat)->addr, h->h_addr_list[i], sizeof(_type));	\
 | 
	
		
			
				|  |  | +			pat = &((*pat)->next);					\
 | 
	
		
			
				|  |  | +		}								\
 | 
	
		
			
				|  |  | +	}									\
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  static int
 | 
	
		
			
				|  |  | -gaih_inet (const char *name, const struct gaih_service *service,
 | 
	
		
			
				|  |  | -	   const struct addrinfo *req, struct addrinfo **pai)
 | 
	
		
			
				|  |  | +gaih_inet(const char *name, const struct gaih_service *service,
 | 
	
		
			
				|  |  | +		const struct addrinfo *req, struct addrinfo **pai)
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  | -    struct gaih_servtuple nullserv;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    const struct gaih_typeproto *tp = gaih_inet_typeproto;
 | 
	
		
			
				|  |  | -    struct gaih_servtuple *st = &nullserv;
 | 
	
		
			
				|  |  | -    struct gaih_addrtuple *at = NULL;
 | 
	
		
			
				|  |  | -    int rc;
 | 
	
		
			
				|  |  | -    int v4mapped = (req->ai_family == PF_UNSPEC || req->ai_family == PF_INET6) &&
 | 
	
		
			
				|  |  | -	(req->ai_flags & AI_V4MAPPED);
 | 
	
		
			
				|  |  | -    unsigned seen = __check_pf();
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    memset(&nullserv, 0, sizeof(nullserv));
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    if (req->ai_protocol || req->ai_socktype)
 | 
	
		
			
				|  |  | -    {
 | 
	
		
			
				|  |  | -	++tp;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	while (tp->name[0]
 | 
	
		
			
				|  |  | -	       && ((req->ai_socktype != 0 && req->ai_socktype != tp->socktype)
 | 
	
		
			
				|  |  | -		   || (req->ai_protocol != 0
 | 
	
		
			
				|  |  | -		       && !(tp->protoflag & GAI_PROTO_PROTOANY)
 | 
	
		
			
				|  |  | -		       && req->ai_protocol != tp->protocol)))
 | 
	
		
			
				|  |  | -	    ++tp;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	if (! tp->name[0])
 | 
	
		
			
				|  |  | -	{
 | 
	
		
			
				|  |  | -	    if (req->ai_socktype)
 | 
	
		
			
				|  |  | -		return (GAIH_OKIFUNSPEC | -EAI_SOCKTYPE);
 | 
	
		
			
				|  |  | -	    return (GAIH_OKIFUNSPEC | -EAI_SERVICE);
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    if (service != NULL)
 | 
	
		
			
				|  |  | -    {
 | 
	
		
			
				|  |  | -	if ((tp->protoflag & GAI_PROTO_NOSERVICE) != 0)
 | 
	
		
			
				|  |  | -	    return (GAIH_OKIFUNSPEC | -EAI_SERVICE);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	if (service->num < 0)
 | 
	
		
			
				|  |  | -	{
 | 
	
		
			
				|  |  | -	    if (tp->name[0])
 | 
	
		
			
				|  |  | -	    {
 | 
	
		
			
				|  |  | -		st = (struct gaih_servtuple *)
 | 
	
		
			
				|  |  | -		    alloca (sizeof (struct gaih_servtuple));
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -		if ((rc = gaih_inet_serv (service->name, tp, req, st)))
 | 
	
		
			
				|  |  | -		    return rc;
 | 
	
		
			
				|  |  | -	    }
 | 
	
		
			
				|  |  | -	    else
 | 
	
		
			
				|  |  | -	    {
 | 
	
		
			
				|  |  | -		struct gaih_servtuple **pst = &st;
 | 
	
		
			
				|  |  | -		for (tp++; tp->name[0]; tp++)
 | 
	
		
			
				|  |  | -		{
 | 
	
		
			
				|  |  | -		    struct gaih_servtuple *newp;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -		    if ((tp->protoflag & GAI_PROTO_NOSERVICE) != 0)
 | 
	
		
			
				|  |  | -			continue;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -		    if (req->ai_socktype != 0
 | 
	
		
			
				|  |  | -			&& req->ai_socktype != tp->socktype)
 | 
	
		
			
				|  |  | -			continue;
 | 
	
		
			
				|  |  | -		    if (req->ai_protocol != 0
 | 
	
		
			
				|  |  | -			&& !(tp->protoflag & GAI_PROTO_PROTOANY)
 | 
	
		
			
				|  |  | -			&& req->ai_protocol != tp->protocol)
 | 
	
		
			
				|  |  | -			continue;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -		    newp = (struct gaih_servtuple *)
 | 
	
		
			
				|  |  | -			alloca (sizeof (struct gaih_servtuple));
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -		    if ((rc = gaih_inet_serv (service->name, tp, req, newp)))
 | 
	
		
			
				|  |  | -		    {
 | 
	
		
			
				|  |  | -			if (rc & GAIH_OKIFUNSPEC)
 | 
	
		
			
				|  |  | -			    continue;
 | 
	
		
			
				|  |  | -			return rc;
 | 
	
		
			
				|  |  | -		    }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -		    *pst = newp;
 | 
	
		
			
				|  |  | -		    pst = &(newp->next);
 | 
	
		
			
				|  |  | +	struct gaih_servtuple nullserv;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	const struct gaih_typeproto *tp = gaih_inet_typeproto;
 | 
	
		
			
				|  |  | +	struct gaih_servtuple *st = &nullserv;
 | 
	
		
			
				|  |  | +	struct gaih_addrtuple *at = NULL;
 | 
	
		
			
				|  |  | +	int rc;
 | 
	
		
			
				|  |  | +	int v4mapped = (req->ai_family == PF_UNSPEC || req->ai_family == PF_INET6)
 | 
	
		
			
				|  |  | +			&& (req->ai_flags & AI_V4MAPPED);
 | 
	
		
			
				|  |  | +	unsigned seen = __check_pf();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	memset(&nullserv, 0, sizeof(nullserv));
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	if (req->ai_protocol || req->ai_socktype) {
 | 
	
		
			
				|  |  | +		++tp;
 | 
	
		
			
				|  |  | +		while (tp->name[0]
 | 
	
		
			
				|  |  | +			&& ((req->ai_socktype != 0 && req->ai_socktype != tp->socktype)
 | 
	
		
			
				|  |  | +			    || (req->ai_protocol != 0 && !(tp->protoflag & GAI_PROTO_PROTOANY) && req->ai_protocol != tp->protocol)
 | 
	
		
			
				|  |  | +			)
 | 
	
		
			
				|  |  | +		) {
 | 
	
		
			
				|  |  | +			++tp;
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +		if (! tp->name[0]) {
 | 
	
		
			
				|  |  | +			if (req->ai_socktype)
 | 
	
		
			
				|  |  | +				return (GAIH_OKIFUNSPEC | -EAI_SOCKTYPE);
 | 
	
		
			
				|  |  | +			return (GAIH_OKIFUNSPEC | -EAI_SERVICE);
 | 
	
		
			
				|  |  |  		}
 | 
	
		
			
				|  |  | -		if (st == &nullserv)
 | 
	
		
			
				|  |  | -		    return (GAIH_OKIFUNSPEC | -EAI_SERVICE);
 | 
	
		
			
				|  |  | -	    }
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -	else
 | 
	
		
			
				|  |  | -	{
 | 
	
		
			
				|  |  | -	    st = alloca (sizeof (struct gaih_servtuple));
 | 
	
		
			
				|  |  | -	    st->next = NULL;
 | 
	
		
			
				|  |  | -	    st->socktype = tp->socktype;
 | 
	
		
			
				|  |  | -	    st->protocol = ((tp->protoflag & GAI_PROTO_PROTOANY)
 | 
	
		
			
				|  |  | -			    ? req->ai_protocol : tp->protocol);
 | 
	
		
			
				|  |  | -	    st->port = htons (service->num);
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -    else if (req->ai_socktype || req->ai_protocol)
 | 
	
		
			
				|  |  | -    {
 | 
	
		
			
				|  |  | -	st = alloca (sizeof (struct gaih_servtuple));
 | 
	
		
			
				|  |  | -	st->next = NULL;
 | 
	
		
			
				|  |  | -	st->socktype = tp->socktype;
 | 
	
		
			
				|  |  | -	st->protocol = ((tp->protoflag & GAI_PROTO_PROTOANY)
 | 
	
		
			
				|  |  | -			? req->ai_protocol : tp->protocol);
 | 
	
		
			
				|  |  | -	st->port = 0;
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -    else
 | 
	
		
			
				|  |  | -    {
 | 
	
		
			
				|  |  | -	/*
 | 
	
		
			
				|  |  | -	 * Neither socket type nor protocol is set.  Return all socket types
 | 
	
		
			
				|  |  | -	 * we know about.
 | 
	
		
			
				|  |  | -	 */
 | 
	
		
			
				|  |  | -	struct gaih_servtuple **lastp = &st;
 | 
	
		
			
				|  |  | -	for (++tp; tp->name[0]; ++tp)
 | 
	
		
			
				|  |  | -	{
 | 
	
		
			
				|  |  | -	    struct gaih_servtuple *newp;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	    newp = alloca (sizeof (struct gaih_servtuple));
 | 
	
		
			
				|  |  | -	    newp->next = NULL;
 | 
	
		
			
				|  |  | -	    newp->socktype = tp->socktype;
 | 
	
		
			
				|  |  | -	    newp->protocol = tp->protocol;
 | 
	
		
			
				|  |  | -	    newp->port = 0;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -	    *lastp = newp;
 | 
	
		
			
				|  |  | -	    lastp = &newp->next;
 | 
	
		
			
				|  |  | +	if (service != NULL) {
 | 
	
		
			
				|  |  | +		if ((tp->protoflag & GAI_PROTO_NOSERVICE) != 0)
 | 
	
		
			
				|  |  | +			return (GAIH_OKIFUNSPEC | -EAI_SERVICE);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +		if (service->num < 0) {
 | 
	
		
			
				|  |  | +			if (tp->name[0]) {
 | 
	
		
			
				|  |  | +				st = alloca(sizeof(struct gaih_servtuple));
 | 
	
		
			
				|  |  | +				rc = gaih_inet_serv(service->name, tp, req, st);
 | 
	
		
			
				|  |  | +				if (rc)
 | 
	
		
			
				|  |  | +					return rc;
 | 
	
		
			
				|  |  | +			} else {
 | 
	
		
			
				|  |  | +				struct gaih_servtuple **pst = &st;
 | 
	
		
			
				|  |  | +				for (tp++; tp->name[0]; tp++) {
 | 
	
		
			
				|  |  | +					struct gaih_servtuple *newp;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +					if ((tp->protoflag & GAI_PROTO_NOSERVICE) != 0)
 | 
	
		
			
				|  |  | +						continue;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +					if (req->ai_socktype != 0 && req->ai_socktype != tp->socktype)
 | 
	
		
			
				|  |  | +						continue;
 | 
	
		
			
				|  |  | +					if (req->ai_protocol != 0
 | 
	
		
			
				|  |  | +					 && !(tp->protoflag & GAI_PROTO_PROTOANY)
 | 
	
		
			
				|  |  | +					 && req->ai_protocol != tp->protocol)
 | 
	
		
			
				|  |  | +						continue;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +					newp = alloca(sizeof(struct gaih_servtuple));
 | 
	
		
			
				|  |  | +					rc = gaih_inet_serv(service->name, tp, req, newp);
 | 
	
		
			
				|  |  | +					if (rc) {
 | 
	
		
			
				|  |  | +						if (rc & GAIH_OKIFUNSPEC)
 | 
	
		
			
				|  |  | +							continue;
 | 
	
		
			
				|  |  | +						return rc;
 | 
	
		
			
				|  |  | +					}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +					*pst = newp;
 | 
	
		
			
				|  |  | +					pst = &(newp->next);
 | 
	
		
			
				|  |  | +				}
 | 
	
		
			
				|  |  | +				if (st == &nullserv)
 | 
	
		
			
				|  |  | +					return (GAIH_OKIFUNSPEC | -EAI_SERVICE);
 | 
	
		
			
				|  |  | +			}
 | 
	
		
			
				|  |  | +		} else {
 | 
	
		
			
				|  |  | +			st = alloca(sizeof(struct gaih_servtuple));
 | 
	
		
			
				|  |  | +			st->next = NULL;
 | 
	
		
			
				|  |  | +			st->socktype = tp->socktype;
 | 
	
		
			
				|  |  | +			st->protocol = ((tp->protoflag & GAI_PROTO_PROTOANY)
 | 
	
		
			
				|  |  | +					? req->ai_protocol : tp->protocol);
 | 
	
		
			
				|  |  | +			st->port = htons(service->num);
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +	} else if (req->ai_socktype || req->ai_protocol) {
 | 
	
		
			
				|  |  | +		st = alloca(sizeof(struct gaih_servtuple));
 | 
	
		
			
				|  |  | +		st->next = NULL;
 | 
	
		
			
				|  |  | +		st->socktype = tp->socktype;
 | 
	
		
			
				|  |  | +		st->protocol = ((tp->protoflag & GAI_PROTO_PROTOANY)
 | 
	
		
			
				|  |  | +				? req->ai_protocol : tp->protocol);
 | 
	
		
			
				|  |  | +		st->port = 0;
 | 
	
		
			
				|  |  | +	} else {
 | 
	
		
			
				|  |  | +		/*
 | 
	
		
			
				|  |  | +		 * Neither socket type nor protocol is set.  Return all socket types
 | 
	
		
			
				|  |  | +		 * we know about.
 | 
	
		
			
				|  |  | +		 */
 | 
	
		
			
				|  |  | +		struct gaih_servtuple **lastp = &st;
 | 
	
		
			
				|  |  | +		for (++tp; tp->name[0]; ++tp) {
 | 
	
		
			
				|  |  | +			struct gaih_servtuple *newp;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +			newp = alloca(sizeof(struct gaih_servtuple));
 | 
	
		
			
				|  |  | +			newp->next = NULL;
 | 
	
		
			
				|  |  | +			newp->socktype = tp->socktype;
 | 
	
		
			
				|  |  | +			newp->protocol = tp->protocol;
 | 
	
		
			
				|  |  | +			newp->port = 0;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +			*lastp = newp;
 | 
	
		
			
				|  |  | +			lastp = &newp->next;
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    if (name != NULL)
 | 
	
		
			
				|  |  | -    {
 | 
	
		
			
				|  |  | -	at = alloca (sizeof (struct gaih_addrtuple));
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	at->family = AF_UNSPEC;
 | 
	
		
			
				|  |  | -	at->scopeid = 0;
 | 
	
		
			
				|  |  | -	at->next = NULL;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	if (inet_pton (AF_INET, name, at->addr) > 0)
 | 
	
		
			
				|  |  | -	{
 | 
	
		
			
				|  |  | -	    if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET || v4mapped)
 | 
	
		
			
				|  |  | -		at->family = AF_INET;
 | 
	
		
			
				|  |  | -	    else
 | 
	
		
			
				|  |  | -		return -EAI_FAMILY;
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | +	if (name != NULL) {
 | 
	
		
			
				|  |  | +		at = alloca(sizeof(struct gaih_addrtuple));
 | 
	
		
			
				|  |  | +		at->family = AF_UNSPEC;
 | 
	
		
			
				|  |  | +		at->scopeid = 0;
 | 
	
		
			
				|  |  | +		at->next = NULL;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +		if (inet_pton(AF_INET, name, at->addr) > 0) {
 | 
	
		
			
				|  |  | +			if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET || v4mapped)
 | 
	
		
			
				|  |  | +				at->family = AF_INET;
 | 
	
		
			
				|  |  | +			else
 | 
	
		
			
				|  |  | +				return -EAI_FAMILY;
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  #if defined __UCLIBC_HAS_IPV6__
 | 
	
		
			
				|  |  | -	if (at->family == AF_UNSPEC)
 | 
	
		
			
				|  |  | -	{
 | 
	
		
			
				|  |  | -	    char *namebuf = strdupa (name);
 | 
	
		
			
				|  |  | -	    char *scope_delim;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	    scope_delim = strchr (namebuf, SCOPE_DELIMITER);
 | 
	
		
			
				|  |  | -	    if (scope_delim != NULL)
 | 
	
		
			
				|  |  | -		*scope_delim = '\0';
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	    if (inet_pton (AF_INET6, namebuf, at->addr) > 0)
 | 
	
		
			
				|  |  | -	    {
 | 
	
		
			
				|  |  | -		if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6)
 | 
	
		
			
				|  |  | -		    at->family = AF_INET6;
 | 
	
		
			
				|  |  | -		else
 | 
	
		
			
				|  |  | -		    return -EAI_FAMILY;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -		if (scope_delim != NULL)
 | 
	
		
			
				|  |  | -		{
 | 
	
		
			
				|  |  | -		    int try_numericscope = 0;
 | 
	
		
			
				|  |  | -		    if (IN6_IS_ADDR_LINKLOCAL (at->addr)
 | 
	
		
			
				|  |  | -			|| IN6_IS_ADDR_MC_LINKLOCAL (at->addr))
 | 
	
		
			
				|  |  | -		    {
 | 
	
		
			
				|  |  | -			at->scopeid = if_nametoindex (scope_delim + 1);
 | 
	
		
			
				|  |  | -			if (at->scopeid == 0)
 | 
	
		
			
				|  |  | -			    try_numericscope = 1;
 | 
	
		
			
				|  |  | -		    }
 | 
	
		
			
				|  |  | -		    else
 | 
	
		
			
				|  |  | -			try_numericscope = 1;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -		    if (try_numericscope != 0)
 | 
	
		
			
				|  |  | -		    {
 | 
	
		
			
				|  |  | -			char *end;
 | 
	
		
			
				|  |  | -			assert (sizeof (uint32_t) <= sizeof (unsigned long));
 | 
	
		
			
				|  |  | -			at->scopeid = (uint32_t) strtoul (scope_delim + 1, &end,
 | 
	
		
			
				|  |  | -							  10);
 | 
	
		
			
				|  |  | -			if (*end != '\0')
 | 
	
		
			
				|  |  | -			    return GAIH_OKIFUNSPEC | -EAI_NONAME;
 | 
	
		
			
				|  |  | -		    }
 | 
	
		
			
				|  |  | +		if (at->family == AF_UNSPEC) {
 | 
	
		
			
				|  |  | +			char *namebuf = strdupa(name);
 | 
	
		
			
				|  |  | +			char *scope_delim;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +			scope_delim = strchr(namebuf, SCOPE_DELIMITER);
 | 
	
		
			
				|  |  | +			if (scope_delim != NULL)
 | 
	
		
			
				|  |  | +				*scope_delim = '\0';
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +			if (inet_pton(AF_INET6, namebuf, at->addr) > 0) {
 | 
	
		
			
				|  |  | +				if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6)
 | 
	
		
			
				|  |  | +					at->family = AF_INET6;
 | 
	
		
			
				|  |  | +				else
 | 
	
		
			
				|  |  | +					return -EAI_FAMILY;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +				if (scope_delim != NULL) {
 | 
	
		
			
				|  |  | +					int try_numericscope = 0;
 | 
	
		
			
				|  |  | +					if (IN6_IS_ADDR_LINKLOCAL(at->addr) || IN6_IS_ADDR_MC_LINKLOCAL(at->addr)) {
 | 
	
		
			
				|  |  | +						at->scopeid = if_nametoindex(scope_delim + 1);
 | 
	
		
			
				|  |  | +						if (at->scopeid == 0)
 | 
	
		
			
				|  |  | +							try_numericscope = 1;
 | 
	
		
			
				|  |  | +					} else
 | 
	
		
			
				|  |  | +						try_numericscope = 1;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +					if (try_numericscope != 0) {
 | 
	
		
			
				|  |  | +						char *end;
 | 
	
		
			
				|  |  | +						assert(sizeof(uint32_t) <= sizeof(unsigned long));
 | 
	
		
			
				|  |  | +						at->scopeid = (uint32_t)strtoul(scope_delim + 1, &end, 10);
 | 
	
		
			
				|  |  | +						if (*end != '\0')
 | 
	
		
			
				|  |  | +							return (GAIH_OKIFUNSPEC | -EAI_NONAME);
 | 
	
		
			
				|  |  | +					}
 | 
	
		
			
				|  |  | +				}
 | 
	
		
			
				|  |  | +			}
 | 
	
		
			
				|  |  |  		}
 | 
	
		
			
				|  |  | -	    }
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  |  #endif
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -	if (at->family == AF_UNSPEC && (req->ai_flags & AI_NUMERICHOST) == 0)
 | 
	
		
			
				|  |  | -	{
 | 
	
		
			
				|  |  | -	    struct hostent *h;
 | 
	
		
			
				|  |  | -	    struct gaih_addrtuple **pat = &at;
 | 
	
		
			
				|  |  | -	    int no_data = 0;
 | 
	
		
			
				|  |  | -	    int no_inet6_data;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	    /*
 | 
	
		
			
				|  |  | -	     * If we are looking for both IPv4 and IPv6 address we don't want
 | 
	
		
			
				|  |  | -	     * the lookup functions to automatically promote IPv4 addresses to
 | 
	
		
			
				|  |  | -	     * IPv6 addresses.
 | 
	
		
			
				|  |  | -	     */
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | +		if (at->family == AF_UNSPEC && (req->ai_flags & AI_NUMERICHOST) == 0) {
 | 
	
		
			
				|  |  | +			struct hostent *h;
 | 
	
		
			
				|  |  | +			struct gaih_addrtuple **pat = &at;
 | 
	
		
			
				|  |  | +			int no_data = 0;
 | 
	
		
			
				|  |  | +			int no_inet6_data;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +			/*
 | 
	
		
			
				|  |  | +			 * If we are looking for both IPv4 and IPv6 address we don't want
 | 
	
		
			
				|  |  | +			 * the lookup functions to automatically promote IPv4 addresses to
 | 
	
		
			
				|  |  | +			 * IPv6 addresses.
 | 
	
		
			
				|  |  | +			 */
 | 
	
		
			
				|  |  |  #if defined __UCLIBC_HAS_IPV6__
 | 
	
		
			
				|  |  | -	    if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6)
 | 
	
		
			
				|  |  | -		if (!(req->ai_flags & AI_ADDRCONFIG) || (seen & SEEN_IPV6))
 | 
	
		
			
				|  |  | -		    gethosts (AF_INET6, struct in6_addr);
 | 
	
		
			
				|  |  | +			if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6)
 | 
	
		
			
				|  |  | +				if (!(req->ai_flags & AI_ADDRCONFIG) || (seen & SEEN_IPV6))
 | 
	
		
			
				|  |  | +					gethosts(AF_INET6, struct in6_addr);
 | 
	
		
			
				|  |  |  #endif
 | 
	
		
			
				|  |  | -	    no_inet6_data = no_data;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	    if (req->ai_family == AF_INET ||
 | 
	
		
			
				|  |  | -		(!v4mapped && req->ai_family == AF_UNSPEC) ||
 | 
	
		
			
				|  |  | -		(v4mapped && (no_inet6_data != 0 || (req->ai_flags & AI_ALL))))
 | 
	
		
			
				|  |  | -		if (!(req->ai_flags & AI_ADDRCONFIG) || (seen & SEEN_IPV4))
 | 
	
		
			
				|  |  | -		    gethosts (AF_INET, struct in_addr);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	    if (no_data != 0 && no_inet6_data != 0)
 | 
	
		
			
				|  |  | -	    {
 | 
	
		
			
				|  |  | -		/* If both requests timed out report this. */
 | 
	
		
			
				|  |  | -		if (no_data == EAI_AGAIN && no_inet6_data == EAI_AGAIN)
 | 
	
		
			
				|  |  | -		    return -EAI_AGAIN;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -		/*
 | 
	
		
			
				|  |  | -		 * We made requests but they turned out no data.
 | 
	
		
			
				|  |  | -		 * The name is known, though.
 | 
	
		
			
				|  |  | -		 */
 | 
	
		
			
				|  |  | -		return (GAIH_OKIFUNSPEC | -EAI_AGAIN);
 | 
	
		
			
				|  |  | -	    }
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	if (at->family == AF_UNSPEC)
 | 
	
		
			
				|  |  | -	    return (GAIH_OKIFUNSPEC | -EAI_NONAME);
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -    else
 | 
	
		
			
				|  |  | -    {
 | 
	
		
			
				|  |  | -	struct gaih_addrtuple *atr;
 | 
	
		
			
				|  |  | -	atr = at = alloca (sizeof (struct gaih_addrtuple));
 | 
	
		
			
				|  |  | -	memset (at, '\0', sizeof (struct gaih_addrtuple));
 | 
	
		
			
				|  |  | +			no_inet6_data = no_data;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +			if (req->ai_family == AF_INET
 | 
	
		
			
				|  |  | +			 || (!v4mapped && req->ai_family == AF_UNSPEC)
 | 
	
		
			
				|  |  | +			 || (v4mapped && (no_inet6_data != 0 || (req->ai_flags & AI_ALL)))
 | 
	
		
			
				|  |  | +			) {
 | 
	
		
			
				|  |  | +				if (!(req->ai_flags & AI_ADDRCONFIG) || (seen & SEEN_IPV4))
 | 
	
		
			
				|  |  | +					gethosts(AF_INET, struct in_addr);
 | 
	
		
			
				|  |  | +			}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +			if (no_data != 0 && no_inet6_data != 0) {
 | 
	
		
			
				|  |  | +				/* If both requests timed out report this. */
 | 
	
		
			
				|  |  | +				if (no_data == EAI_AGAIN && no_inet6_data == EAI_AGAIN)
 | 
	
		
			
				|  |  | +					return -EAI_AGAIN;
 | 
	
		
			
				|  |  | +				/*
 | 
	
		
			
				|  |  | +				 * We made requests but they turned out no data.
 | 
	
		
			
				|  |  | +				 * The name is known, though.
 | 
	
		
			
				|  |  | +				 */
 | 
	
		
			
				|  |  | +				return (GAIH_OKIFUNSPEC | -EAI_AGAIN);
 | 
	
		
			
				|  |  | +			}
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -	if (req->ai_family == 0)
 | 
	
		
			
				|  |  | -	{
 | 
	
		
			
				|  |  | -	    at->next = alloca (sizeof (struct gaih_addrtuple));
 | 
	
		
			
				|  |  | -	    memset (at->next, '\0', sizeof (struct gaih_addrtuple));
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | +		if (at->family == AF_UNSPEC)
 | 
	
		
			
				|  |  | +			return (GAIH_OKIFUNSPEC | -EAI_NONAME);
 | 
	
		
			
				|  |  | +	} else {
 | 
	
		
			
				|  |  | +		struct gaih_addrtuple *atr;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +		atr = at = alloca(sizeof(struct gaih_addrtuple));
 | 
	
		
			
				|  |  | +		memset(at, '\0', sizeof(struct gaih_addrtuple));
 | 
	
		
			
				|  |  | +		if (req->ai_family == 0) {
 | 
	
		
			
				|  |  | +			at->next = alloca(sizeof(struct gaih_addrtuple));
 | 
	
		
			
				|  |  | +			memset(at->next, '\0', sizeof(struct gaih_addrtuple));
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  |  #if defined __UCLIBC_HAS_IPV6__
 | 
	
		
			
				|  |  | -	if (req->ai_family == 0 || req->ai_family == AF_INET6)
 | 
	
		
			
				|  |  | -	{
 | 
	
		
			
				|  |  | -	    at->family = AF_INET6;
 | 
	
		
			
				|  |  | -	    if ((req->ai_flags & AI_PASSIVE) == 0)
 | 
	
		
			
				|  |  | -		memcpy (at->addr, &in6addr_loopback, sizeof (struct in6_addr));
 | 
	
		
			
				|  |  | -	    atr = at->next;
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | +		if (req->ai_family == 0 || req->ai_family == AF_INET6) {
 | 
	
		
			
				|  |  | +			at->family = AF_INET6;
 | 
	
		
			
				|  |  | +			if ((req->ai_flags & AI_PASSIVE) == 0)
 | 
	
		
			
				|  |  | +				memcpy(at->addr, &in6addr_loopback, sizeof(struct in6_addr));
 | 
	
		
			
				|  |  | +			atr = at->next;
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  |  #endif
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	if (req->ai_family == 0 || req->ai_family == AF_INET)
 | 
	
		
			
				|  |  | -	{
 | 
	
		
			
				|  |  | -	    atr->family = AF_INET;
 | 
	
		
			
				|  |  | -	    if ((req->ai_flags & AI_PASSIVE) == 0)
 | 
	
		
			
				|  |  | -		*(uint32_t *) atr->addr = htonl (INADDR_LOOPBACK);
 | 
	
		
			
				|  |  | +		if (req->ai_family == 0 || req->ai_family == AF_INET) {
 | 
	
		
			
				|  |  | +			atr->family = AF_INET;
 | 
	
		
			
				|  |  | +			if ((req->ai_flags & AI_PASSIVE) == 0)
 | 
	
		
			
				|  |  | +				*(uint32_t*)atr->addr = htonl(INADDR_LOOPBACK);
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    if (pai == NULL)
 | 
	
		
			
				|  |  | -	return 0;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    {
 | 
	
		
			
				|  |  | -	const char *c = NULL;
 | 
	
		
			
				|  |  | -	struct gaih_servtuple *st2;
 | 
	
		
			
				|  |  | -	struct gaih_addrtuple *at2 = at;
 | 
	
		
			
				|  |  | -	size_t socklen, namelen;
 | 
	
		
			
				|  |  | -	sa_family_t family;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -	/*
 | 
	
		
			
				|  |  | -	 * buffer is the size of an unformatted IPv6 address in
 | 
	
		
			
				|  |  | -	 * printable format.
 | 
	
		
			
				|  |  | -	 */
 | 
	
		
			
				|  |  | -	char buffer[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"];
 | 
	
		
			
				|  |  | +	if (pai == NULL)
 | 
	
		
			
				|  |  | +		return 0;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -	while (at2 != NULL)
 | 
	
		
			
				|  |  |  	{
 | 
	
		
			
				|  |  | -	    if (req->ai_flags & AI_CANONNAME)
 | 
	
		
			
				|  |  | -	    {
 | 
	
		
			
				|  |  | -		struct hostent *h = NULL;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -		int herrno;
 | 
	
		
			
				|  |  | -		struct hostent th;
 | 
	
		
			
				|  |  | -		size_t tmpbuflen = 512;
 | 
	
		
			
				|  |  | -		char *tmpbuf;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -		do
 | 
	
		
			
				|  |  | -		{
 | 
	
		
			
				|  |  | -		    tmpbuflen *= 2;
 | 
	
		
			
				|  |  | -		    tmpbuf = alloca (tmpbuflen);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -		    if (tmpbuf == NULL)
 | 
	
		
			
				|  |  | -			return -EAI_MEMORY;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -		    rc = gethostbyaddr_r (at2->addr,
 | 
	
		
			
				|  |  | -					  ((at2->family == AF_INET6)
 | 
	
		
			
				|  |  | -					   ? sizeof(struct in6_addr)
 | 
	
		
			
				|  |  | -					   : sizeof(struct in_addr)),
 | 
	
		
			
				|  |  | -					  at2->family, &th, tmpbuf, tmpbuflen,
 | 
	
		
			
				|  |  | -					  &h, &herrno);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  | -		while (rc == errno && herrno == NETDB_INTERNAL);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -		if (rc != 0 && herrno == NETDB_INTERNAL)
 | 
	
		
			
				|  |  | -		{
 | 
	
		
			
				|  |  | -		    __set_h_errno (herrno);
 | 
	
		
			
				|  |  | -		    return -EAI_SYSTEM;
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -		if (h == NULL)
 | 
	
		
			
				|  |  | -		    c = inet_ntop (at2->family, at2->addr, buffer, sizeof(buffer));
 | 
	
		
			
				|  |  | -		else
 | 
	
		
			
				|  |  | -		    c = h->h_name;
 | 
	
		
			
				|  |  | +		const char *c = NULL;
 | 
	
		
			
				|  |  | +		struct gaih_servtuple *st2;
 | 
	
		
			
				|  |  | +		struct gaih_addrtuple *at2 = at;
 | 
	
		
			
				|  |  | +		size_t socklen, namelen;
 | 
	
		
			
				|  |  | +		sa_family_t family;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -		if (c == NULL)
 | 
	
		
			
				|  |  | -		    return GAIH_OKIFUNSPEC | -EAI_NONAME;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -		namelen = strlen (c) + 1;
 | 
	
		
			
				|  |  | -	    }
 | 
	
		
			
				|  |  | -	    else
 | 
	
		
			
				|  |  | -		namelen = 0;
 | 
	
		
			
				|  |  | +		/*
 | 
	
		
			
				|  |  | +		 * buffer is the size of an unformatted IPv6 address in
 | 
	
		
			
				|  |  | +		 * printable format.
 | 
	
		
			
				|  |  | +		 */
 | 
	
		
			
				|  |  | +		char buffer[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +		while (at2 != NULL) {
 | 
	
		
			
				|  |  | +			if (req->ai_flags & AI_CANONNAME) {
 | 
	
		
			
				|  |  | +				struct hostent *h = NULL;
 | 
	
		
			
				|  |  | +				int herrno;
 | 
	
		
			
				|  |  | +				struct hostent th;
 | 
	
		
			
				|  |  | +				size_t tmpbuflen = 512;
 | 
	
		
			
				|  |  | +				char *tmpbuf;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +				do {
 | 
	
		
			
				|  |  | +					tmpbuflen *= 2;
 | 
	
		
			
				|  |  | +					tmpbuf = alloca(tmpbuflen);
 | 
	
		
			
				|  |  | +					//if (tmpbuf == NULL)
 | 
	
		
			
				|  |  | +					//	return -EAI_MEMORY;
 | 
	
		
			
				|  |  | +					rc = gethostbyaddr_r(at2->addr,
 | 
	
		
			
				|  |  | +						((at2->family == AF_INET6)
 | 
	
		
			
				|  |  | +						 ? sizeof(struct in6_addr)
 | 
	
		
			
				|  |  | +						 : sizeof(struct in_addr)),
 | 
	
		
			
				|  |  | +						at2->family,
 | 
	
		
			
				|  |  | +						&th, tmpbuf, tmpbuflen,
 | 
	
		
			
				|  |  | +						&h, &herrno);
 | 
	
		
			
				|  |  | +				} while (rc == errno && herrno == NETDB_INTERNAL);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +				if (rc != 0 && herrno == NETDB_INTERNAL) {
 | 
	
		
			
				|  |  | +					__set_h_errno(herrno);
 | 
	
		
			
				|  |  | +					return -EAI_SYSTEM;
 | 
	
		
			
				|  |  | +				}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +				if (h == NULL)
 | 
	
		
			
				|  |  | +					c = inet_ntop(at2->family, at2->addr, buffer, sizeof(buffer));
 | 
	
		
			
				|  |  | +				else
 | 
	
		
			
				|  |  | +					c = h->h_name;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +				if (c == NULL)
 | 
	
		
			
				|  |  | +					return (GAIH_OKIFUNSPEC | -EAI_NONAME);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +				namelen = strlen(c) + 1;
 | 
	
		
			
				|  |  | +			} else
 | 
	
		
			
				|  |  | +				namelen = 0;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  #if defined __UCLIBC_HAS_IPV6__
 | 
	
		
			
				|  |  | -	    if (at2->family == AF_INET6 || v4mapped)
 | 
	
		
			
				|  |  | -	    {
 | 
	
		
			
				|  |  | -		family = AF_INET6;
 | 
	
		
			
				|  |  | -		socklen = sizeof (struct sockaddr_in6);
 | 
	
		
			
				|  |  | -	    }
 | 
	
		
			
				|  |  | +			if (at2->family == AF_INET6 || v4mapped) {
 | 
	
		
			
				|  |  | +				family = AF_INET6;
 | 
	
		
			
				|  |  | +				socklen = sizeof(struct sockaddr_in6);
 | 
	
		
			
				|  |  | +			}
 | 
	
		
			
				|  |  |  #endif
 | 
	
		
			
				|  |  |  #if defined __UCLIBC_HAS_IPV4__ && defined __UCLIBC_HAS_IPV6__
 | 
	
		
			
				|  |  | -	    else
 | 
	
		
			
				|  |  | +			else
 | 
	
		
			
				|  |  |  #endif
 | 
	
		
			
				|  |  |  #if defined __UCLIBC_HAS_IPV4__
 | 
	
		
			
				|  |  | -	    {
 | 
	
		
			
				|  |  | -		family = AF_INET;
 | 
	
		
			
				|  |  | -		socklen = sizeof (struct sockaddr_in);
 | 
	
		
			
				|  |  | -	    }
 | 
	
		
			
				|  |  | +			{
 | 
	
		
			
				|  |  | +				family = AF_INET;
 | 
	
		
			
				|  |  | +				socklen = sizeof(struct sockaddr_in);
 | 
	
		
			
				|  |  | +			}
 | 
	
		
			
				|  |  |  #endif
 | 
	
		
			
				|  |  | -	    for (st2 = st; st2 != NULL; st2 = st2->next)
 | 
	
		
			
				|  |  | -	    {
 | 
	
		
			
				|  |  | -		if (req->ai_flags & AI_ADDRCONFIG) {
 | 
	
		
			
				|  |  | -		    if (family == AF_INET && !(seen & SEEN_IPV4))
 | 
	
		
			
				|  |  | -			break;
 | 
	
		
			
				|  |  | +			for (st2 = st; st2 != NULL; st2 = st2->next) {
 | 
	
		
			
				|  |  | +				if (req->ai_flags & AI_ADDRCONFIG) {
 | 
	
		
			
				|  |  | +					if (family == AF_INET && !(seen & SEEN_IPV4))
 | 
	
		
			
				|  |  | +						break;
 | 
	
		
			
				|  |  |  #if defined __UCLIBC_HAS_IPV6__
 | 
	
		
			
				|  |  | -		    else if (family == AF_INET6 && !(seen & SEEN_IPV6))
 | 
	
		
			
				|  |  | -			break;
 | 
	
		
			
				|  |  | +					else if (family == AF_INET6 && !(seen & SEEN_IPV6))
 | 
	
		
			
				|  |  | +						break;
 | 
	
		
			
				|  |  |  #endif
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  | -		*pai = malloc (sizeof (struct addrinfo) + socklen + namelen);
 | 
	
		
			
				|  |  | -		if (*pai == NULL)
 | 
	
		
			
				|  |  | -		    return -EAI_MEMORY;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -		(*pai)->ai_flags = req->ai_flags;
 | 
	
		
			
				|  |  | -		(*pai)->ai_family = family;
 | 
	
		
			
				|  |  | -		(*pai)->ai_socktype = st2->socktype;
 | 
	
		
			
				|  |  | -		(*pai)->ai_protocol = st2->protocol;
 | 
	
		
			
				|  |  | -		(*pai)->ai_addrlen = socklen;
 | 
	
		
			
				|  |  | -		(*pai)->ai_addr = (void *) (*pai) + sizeof(struct addrinfo);
 | 
	
		
			
				|  |  | +				}
 | 
	
		
			
				|  |  | +				*pai = malloc(sizeof(struct addrinfo) + socklen + namelen);
 | 
	
		
			
				|  |  | +				if (*pai == NULL)
 | 
	
		
			
				|  |  | +					return -EAI_MEMORY;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +				(*pai)->ai_flags = req->ai_flags;
 | 
	
		
			
				|  |  | +				(*pai)->ai_family = family;
 | 
	
		
			
				|  |  | +				(*pai)->ai_socktype = st2->socktype;
 | 
	
		
			
				|  |  | +				(*pai)->ai_protocol = st2->protocol;
 | 
	
		
			
				|  |  | +				(*pai)->ai_addrlen = socklen;
 | 
	
		
			
				|  |  | +				(*pai)->ai_addr = (void *) (*pai) + sizeof(struct addrinfo);
 | 
	
		
			
				|  |  |  #if SALEN
 | 
	
		
			
				|  |  | -		(*pai)->ai_addr->sa_len = socklen;
 | 
	
		
			
				|  |  | +				(*pai)->ai_addr->sa_len = socklen;
 | 
	
		
			
				|  |  |  #endif /* SALEN */
 | 
	
		
			
				|  |  | -		(*pai)->ai_addr->sa_family = family;
 | 
	
		
			
				|  |  | +				(*pai)->ai_addr->sa_family = family;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  #if defined __UCLIBC_HAS_IPV6__
 | 
	
		
			
				|  |  | -		if (family == AF_INET6)
 | 
	
		
			
				|  |  | -		{
 | 
	
		
			
				|  |  | -		    struct sockaddr_in6 *sin6p =
 | 
	
		
			
				|  |  | -			(struct sockaddr_in6 *) (*pai)->ai_addr;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -		    sin6p->sin6_flowinfo = 0;
 | 
	
		
			
				|  |  | -		    if (at2->family == AF_INET6)
 | 
	
		
			
				|  |  | -		    {
 | 
	
		
			
				|  |  | -			memcpy (&sin6p->sin6_addr,
 | 
	
		
			
				|  |  | -				at2->addr, sizeof (struct in6_addr));
 | 
	
		
			
				|  |  | -		    }
 | 
	
		
			
				|  |  | -		    else
 | 
	
		
			
				|  |  | -		    {
 | 
	
		
			
				|  |  | -			sin6p->sin6_addr.s6_addr32[0] = 0;
 | 
	
		
			
				|  |  | -			sin6p->sin6_addr.s6_addr32[1] = 0;
 | 
	
		
			
				|  |  | -			sin6p->sin6_addr.s6_addr32[2] = htonl(0x0000ffff);
 | 
	
		
			
				|  |  | -			memcpy(&sin6p->sin6_addr.s6_addr32[3],
 | 
	
		
			
				|  |  | -			       at2->addr, sizeof (sin6p->sin6_addr.s6_addr32[3]));
 | 
	
		
			
				|  |  | -		    }
 | 
	
		
			
				|  |  | -		    sin6p->sin6_port = st2->port;
 | 
	
		
			
				|  |  | -		    sin6p->sin6_scope_id = at2->scopeid;
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  | +				if (family == AF_INET6)	{
 | 
	
		
			
				|  |  | +					struct sockaddr_in6 *sin6p = (struct sockaddr_in6 *) (*pai)->ai_addr;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +					sin6p->sin6_flowinfo = 0;
 | 
	
		
			
				|  |  | +					if (at2->family == AF_INET6) {
 | 
	
		
			
				|  |  | +						memcpy(&sin6p->sin6_addr,
 | 
	
		
			
				|  |  | +							at2->addr, sizeof(struct in6_addr));
 | 
	
		
			
				|  |  | +					} else {
 | 
	
		
			
				|  |  | +						sin6p->sin6_addr.s6_addr32[0] = 0;
 | 
	
		
			
				|  |  | +						sin6p->sin6_addr.s6_addr32[1] = 0;
 | 
	
		
			
				|  |  | +						sin6p->sin6_addr.s6_addr32[2] = htonl(0x0000ffff);
 | 
	
		
			
				|  |  | +						memcpy(&sin6p->sin6_addr.s6_addr32[3],
 | 
	
		
			
				|  |  | +							at2->addr, sizeof(sin6p->sin6_addr.s6_addr32[3]));
 | 
	
		
			
				|  |  | +					}
 | 
	
		
			
				|  |  | +					sin6p->sin6_port = st2->port;
 | 
	
		
			
				|  |  | +					sin6p->sin6_scope_id = at2->scopeid;
 | 
	
		
			
				|  |  | +				}
 | 
	
		
			
				|  |  |  #endif
 | 
	
		
			
				|  |  |  #if defined __UCLIBC_HAS_IPV4__ && defined __UCLIBC_HAS_IPV6__
 | 
	
		
			
				|  |  | -		else
 | 
	
		
			
				|  |  | +				else
 | 
	
		
			
				|  |  |  #endif
 | 
	
		
			
				|  |  |  #if defined __UCLIBC_HAS_IPV4__
 | 
	
		
			
				|  |  | -		{
 | 
	
		
			
				|  |  | -		    struct sockaddr_in *sinp =
 | 
	
		
			
				|  |  | -			(struct sockaddr_in *) (*pai)->ai_addr;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -		    memcpy (&sinp->sin_addr,
 | 
	
		
			
				|  |  | -			    at2->addr, sizeof (struct in_addr));
 | 
	
		
			
				|  |  | -		    sinp->sin_port = st2->port;
 | 
	
		
			
				|  |  | -		    memset (sinp->sin_zero, '\0', sizeof (sinp->sin_zero));
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  | +				{
 | 
	
		
			
				|  |  | +					struct sockaddr_in *sinp = (struct sockaddr_in *) (*pai)->ai_addr;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +					memcpy(&sinp->sin_addr, at2->addr, sizeof(struct in_addr));
 | 
	
		
			
				|  |  | +					sinp->sin_port = st2->port;
 | 
	
		
			
				|  |  | +					memset(sinp->sin_zero, '\0', sizeof(sinp->sin_zero));
 | 
	
		
			
				|  |  | +				}
 | 
	
		
			
				|  |  |  #endif
 | 
	
		
			
				|  |  | -		if (c)
 | 
	
		
			
				|  |  | -		{
 | 
	
		
			
				|  |  | -		    (*pai)->ai_canonname = ((void *) (*pai) +
 | 
	
		
			
				|  |  | -					    sizeof (struct addrinfo) + socklen);
 | 
	
		
			
				|  |  | -		    strcpy ((*pai)->ai_canonname, c);
 | 
	
		
			
				|  |  | +				if (c) {
 | 
	
		
			
				|  |  | +					(*pai)->ai_canonname = ((void *) (*pai) +
 | 
	
		
			
				|  |  | +							sizeof(struct addrinfo) + socklen);
 | 
	
		
			
				|  |  | +					strcpy((*pai)->ai_canonname, c);
 | 
	
		
			
				|  |  | +				} else {
 | 
	
		
			
				|  |  | +					(*pai)->ai_canonname = NULL;
 | 
	
		
			
				|  |  | +				}
 | 
	
		
			
				|  |  | +				(*pai)->ai_next = NULL;
 | 
	
		
			
				|  |  | +				pai = &((*pai)->ai_next);
 | 
	
		
			
				|  |  | +			}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +			at2 = at2->next;
 | 
	
		
			
				|  |  |  		}
 | 
	
		
			
				|  |  | -		else
 | 
	
		
			
				|  |  | -		    (*pai)->ai_canonname = NULL;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -		(*pai)->ai_next = NULL;
 | 
	
		
			
				|  |  | -		pai = &((*pai)->ai_next);
 | 
	
		
			
				|  |  | -	    }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	    at2 = at2->next;
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -    return 0;
 | 
	
		
			
				|  |  | +	return 0;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -static const struct gaih gaih[] =
 | 
	
		
			
				|  |  | -{
 | 
	
		
			
				|  |  | +static const struct gaih gaih[] = {
 | 
	
		
			
				|  |  |  #if defined __UCLIBC_HAS_IPV6__
 | 
	
		
			
				|  |  | -    { PF_INET6, gaih_inet },
 | 
	
		
			
				|  |  | +	{ PF_INET6, gaih_inet },
 | 
	
		
			
				|  |  |  #endif
 | 
	
		
			
				|  |  | -    { PF_INET, gaih_inet },
 | 
	
		
			
				|  |  | +	{ PF_INET, gaih_inet },
 | 
	
		
			
				|  |  |  #if 0
 | 
	
		
			
				|  |  | -    { PF_LOCAL, gaih_local },
 | 
	
		
			
				|  |  | +	{ PF_LOCAL, gaih_local },
 | 
	
		
			
				|  |  |  #endif
 | 
	
		
			
				|  |  | -    { PF_UNSPEC, NULL }
 | 
	
		
			
				|  |  | +	{ PF_UNSPEC, NULL }
 | 
	
		
			
				|  |  |  };
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  libc_hidden_proto(freeaddrinfo)
 | 
	
		
			
				|  |  |  void
 | 
	
		
			
				|  |  | -freeaddrinfo (struct addrinfo *ai)
 | 
	
		
			
				|  |  | +freeaddrinfo(struct addrinfo *ai)
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  | -    struct addrinfo *p;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    while (ai != NULL)
 | 
	
		
			
				|  |  | -    {
 | 
	
		
			
				|  |  | -	p = ai;
 | 
	
		
			
				|  |  | -	ai = ai->ai_next;
 | 
	
		
			
				|  |  | -	free (p);
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | +	struct addrinfo *p;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	while (ai != NULL) {
 | 
	
		
			
				|  |  | +		p = ai;
 | 
	
		
			
				|  |  | +		ai = ai->ai_next;
 | 
	
		
			
				|  |  | +		free(p);
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  libc_hidden_def(freeaddrinfo)
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  libc_hidden_proto(getaddrinfo)
 | 
	
		
			
				|  |  |  int
 | 
	
		
			
				|  |  | -getaddrinfo (const char *name, const char *service,
 | 
	
		
			
				|  |  | +getaddrinfo(const char *name, const char *service,
 | 
	
		
			
				|  |  |  	     const struct addrinfo *hints, struct addrinfo **pai)
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  | -    int i = 0, j = 0, last_i = 0;
 | 
	
		
			
				|  |  | -    struct addrinfo *p = NULL, **end;
 | 
	
		
			
				|  |  | -    const struct gaih *g = gaih, *pg = NULL;
 | 
	
		
			
				|  |  | -    struct gaih_service gaih_service, *pservice;
 | 
	
		
			
				|  |  | -    struct addrinfo default_hints;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    if (name != NULL && name[0] == '*' && name[1] == 0)
 | 
	
		
			
				|  |  | -	name = NULL;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    if (service != NULL && service[0] == '*' && service[1] == 0)
 | 
	
		
			
				|  |  | -	service = NULL;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    if (name == NULL && service == NULL)
 | 
	
		
			
				|  |  | -	return EAI_NONAME;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    if (hints == NULL)
 | 
	
		
			
				|  |  | -    {
 | 
	
		
			
				|  |  | -	memset(&default_hints, 0, sizeof(default_hints));
 | 
	
		
			
				|  |  | -	if (AF_UNSPEC)
 | 
	
		
			
				|  |  | -	    default_hints.ai_family = AF_UNSPEC;
 | 
	
		
			
				|  |  | -	hints = &default_hints;
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    if (hints->ai_flags & ~(AI_PASSIVE|AI_CANONNAME|AI_NUMERICHOST|
 | 
	
		
			
				|  |  | -			    AI_ADDRCONFIG|AI_V4MAPPED|AI_NUMERICSERV|AI_ALL))
 | 
	
		
			
				|  |  | -	return EAI_BADFLAGS;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    if ((hints->ai_flags & AI_CANONNAME) && name == NULL)
 | 
	
		
			
				|  |  | -	return EAI_BADFLAGS;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    if (service && service[0])
 | 
	
		
			
				|  |  | -    {
 | 
	
		
			
				|  |  | -	char *c;
 | 
	
		
			
				|  |  | -	gaih_service.name = service;
 | 
	
		
			
				|  |  | -	gaih_service.num = strtoul (gaih_service.name, &c, 10);
 | 
	
		
			
				|  |  | -	if (*c != '\0') {
 | 
	
		
			
				|  |  | -		if (hints->ai_flags & AI_NUMERICSERV)
 | 
	
		
			
				|  |  | -			return EAI_NONAME;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	    gaih_service.num = -1;
 | 
	
		
			
				|  |  | +	int i = 0, j = 0, last_i = 0;
 | 
	
		
			
				|  |  | +	struct addrinfo *p = NULL, **end;
 | 
	
		
			
				|  |  | +	const struct gaih *g = gaih, *pg = NULL;
 | 
	
		
			
				|  |  | +	struct gaih_service gaih_service, *pservice;
 | 
	
		
			
				|  |  | +	struct addrinfo default_hints;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	if (name != NULL && name[0] == '*' && name[1] == 0)
 | 
	
		
			
				|  |  | +		name = NULL;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	if (service != NULL && service[0] == '*' && service[1] == 0)
 | 
	
		
			
				|  |  | +		service = NULL;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	if (name == NULL && service == NULL)
 | 
	
		
			
				|  |  | +		return EAI_NONAME;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	if (hints == NULL) {
 | 
	
		
			
				|  |  | +		memset(&default_hints, 0, sizeof(default_hints));
 | 
	
		
			
				|  |  | +		if (AF_UNSPEC)
 | 
	
		
			
				|  |  | +			default_hints.ai_family = AF_UNSPEC;
 | 
	
		
			
				|  |  | +		hints = &default_hints;
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	if (hints->ai_flags & ~(AI_PASSIVE|AI_CANONNAME|AI_NUMERICHOST|
 | 
	
		
			
				|  |  | +			AI_ADDRCONFIG|AI_V4MAPPED|AI_NUMERICSERV|AI_ALL))
 | 
	
		
			
				|  |  | +		return EAI_BADFLAGS;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	if ((hints->ai_flags & AI_CANONNAME) && name == NULL)
 | 
	
		
			
				|  |  | +		return EAI_BADFLAGS;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	if (service && service[0]) {
 | 
	
		
			
				|  |  | +		char *c;
 | 
	
		
			
				|  |  | +		gaih_service.name = service;
 | 
	
		
			
				|  |  | +		gaih_service.num = strtoul(gaih_service.name, &c, 10);
 | 
	
		
			
				|  |  | +		if (*c != '\0') {
 | 
	
		
			
				|  |  | +			if (hints->ai_flags & AI_NUMERICSERV)
 | 
	
		
			
				|  |  | +				return EAI_NONAME;
 | 
	
		
			
				|  |  | +			gaih_service.num = -1;
 | 
	
		
			
				|  |  | +		} else {
 | 
	
		
			
				|  |  | +			/*
 | 
	
		
			
				|  |  | +			 * Can't specify a numerical socket unless a protocol
 | 
	
		
			
				|  |  | +			 * family was given.
 | 
	
		
			
				|  |  | +			 */
 | 
	
		
			
				|  |  | +			if (hints->ai_socktype == 0 && hints->ai_protocol == 0)
 | 
	
		
			
				|  |  | +				return EAI_SERVICE;
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +		pservice = &gaih_service;
 | 
	
		
			
				|  |  | +	} else
 | 
	
		
			
				|  |  | +		pservice = NULL;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	if (pai)
 | 
	
		
			
				|  |  | +		end = &p;
 | 
	
		
			
				|  |  |  	else
 | 
	
		
			
				|  |  | -	    /*
 | 
	
		
			
				|  |  | -	     * Can't specify a numerical socket unless a protocol
 | 
	
		
			
				|  |  | -	     * family was given.
 | 
	
		
			
				|  |  | -	     */
 | 
	
		
			
				|  |  | -	    if (hints->ai_socktype == 0 && hints->ai_protocol == 0)
 | 
	
		
			
				|  |  | -		return EAI_SERVICE;
 | 
	
		
			
				|  |  | -	pservice = &gaih_service;
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -    else
 | 
	
		
			
				|  |  | -	pservice = NULL;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    if (pai)
 | 
	
		
			
				|  |  | -	end = &p;
 | 
	
		
			
				|  |  | -    else
 | 
	
		
			
				|  |  | -	end = NULL;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    while (g->gaih)
 | 
	
		
			
				|  |  | -    {
 | 
	
		
			
				|  |  | -	if (hints->ai_family == g->family || hints->ai_family == AF_UNSPEC)
 | 
	
		
			
				|  |  | -	{
 | 
	
		
			
				|  |  | -	    if ((hints->ai_flags & AI_ADDRCONFIG) && !addrconfig(g->family))
 | 
	
		
			
				|  |  | -	    {
 | 
	
		
			
				|  |  | -		++g;
 | 
	
		
			
				|  |  | -		continue;
 | 
	
		
			
				|  |  | -	    }
 | 
	
		
			
				|  |  | -	    j++;
 | 
	
		
			
				|  |  | -	    if (pg == NULL || pg->gaih != g->gaih)
 | 
	
		
			
				|  |  | -	    {
 | 
	
		
			
				|  |  | -		pg = g;
 | 
	
		
			
				|  |  | -		i = g->gaih (name, pservice, hints, end);
 | 
	
		
			
				|  |  | -		if (i != 0)
 | 
	
		
			
				|  |  | -		{
 | 
	
		
			
				|  |  | -		    last_i = i;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -		    if (hints->ai_family == AF_UNSPEC && (i & GAIH_OKIFUNSPEC))
 | 
	
		
			
				|  |  | -			continue;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -		    if (p)
 | 
	
		
			
				|  |  | -			freeaddrinfo (p);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -		    return -(i & GAIH_EAI);
 | 
	
		
			
				|  |  | +		end = NULL;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	while (g->gaih) {
 | 
	
		
			
				|  |  | +		if (hints->ai_family == g->family || hints->ai_family == AF_UNSPEC) {
 | 
	
		
			
				|  |  | +			if ((hints->ai_flags & AI_ADDRCONFIG) && !addrconfig(g->family)) {
 | 
	
		
			
				|  |  | +				++g;
 | 
	
		
			
				|  |  | +				continue;
 | 
	
		
			
				|  |  | +			}
 | 
	
		
			
				|  |  | +			j++;
 | 
	
		
			
				|  |  | +			if (pg == NULL || pg->gaih != g->gaih) {
 | 
	
		
			
				|  |  | +				pg = g;
 | 
	
		
			
				|  |  | +				i = g->gaih(name, pservice, hints, end);
 | 
	
		
			
				|  |  | +				if (i != 0) {
 | 
	
		
			
				|  |  | +					last_i = i;
 | 
	
		
			
				|  |  | +					if (hints->ai_family == AF_UNSPEC && (i & GAIH_OKIFUNSPEC))
 | 
	
		
			
				|  |  | +						continue;
 | 
	
		
			
				|  |  | +					if (p)
 | 
	
		
			
				|  |  | +						freeaddrinfo(p);
 | 
	
		
			
				|  |  | +					return -(i & GAIH_EAI);
 | 
	
		
			
				|  |  | +				}
 | 
	
		
			
				|  |  | +				if (end)
 | 
	
		
			
				|  |  | +					while (*end)
 | 
	
		
			
				|  |  | +						end = &((*end)->ai_next);
 | 
	
		
			
				|  |  | +			}
 | 
	
		
			
				|  |  |  		}
 | 
	
		
			
				|  |  | -		if (end)
 | 
	
		
			
				|  |  | -		    while(*end) end = &((*end)->ai_next);
 | 
	
		
			
				|  |  | -	    }
 | 
	
		
			
				|  |  | +		++g;
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  | -	++g;
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    if (j == 0)
 | 
	
		
			
				|  |  | -	return EAI_FAMILY;
 | 
	
		
			
				|  |  | +	if (j == 0)
 | 
	
		
			
				|  |  | +		return EAI_FAMILY;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    if (p)
 | 
	
		
			
				|  |  | -    {
 | 
	
		
			
				|  |  | -	*pai = p;
 | 
	
		
			
				|  |  | -	return 0;
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | +	if (p) {
 | 
	
		
			
				|  |  | +		*pai = p;
 | 
	
		
			
				|  |  | +		return 0;
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    if (pai == NULL && last_i == 0)
 | 
	
		
			
				|  |  | -	return 0;
 | 
	
		
			
				|  |  | +	if (pai == NULL && last_i == 0)
 | 
	
		
			
				|  |  | +		return 0;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    if (p)
 | 
	
		
			
				|  |  | -	freeaddrinfo (p);
 | 
	
		
			
				|  |  | +	if (p)
 | 
	
		
			
				|  |  | +		freeaddrinfo(p);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    return last_i ? -(last_i & GAIH_EAI) : EAI_NONAME;
 | 
	
		
			
				|  |  | +	return last_i ? -(last_i & GAIH_EAI) : EAI_NONAME;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  libc_hidden_def(getaddrinfo)
 |