while (tp->name != NULL
while (tp->name[0]
gaih_inet (const char *name, const struct gaih_service *service,	   const struct addrinfo *req, struct addrinfo **pai){  const struct gaih_typeproto *tp = gaih_inet_typeproto;  struct gaih_servtuple *st = (struct gaih_servtuple *) &nullserv;  struct gaih_addrtuple *at = NULL;  int rc;  if (req->ai_protocol || req->ai_socktype)    {      ++tp;      while (tp->name != NULL	     && ((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 == NULL)	{	  if (req->ai_socktype)	    return (GAIH_OKIFUNSPEC | -EAI_SOCKTYPE);	  else	    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 != NULL)	    {	      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; 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);		}	      if (st == (struct gaih_servtuple *) &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 != NULL; ++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)	    at->family = AF_INET;	  else	    return -EAI_ADDRFAMILY;	}      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_ADDRFAMILY;	      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 && (req->ai_flags & AI_NUMERICHOST) == 0)	{	  struct hostent *h;	  struct gaih_addrtuple **pat = &at;	  int no_data = 0;	  int no_inet6_data;	  int old_res_options = _res.options;	  /* 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.  Currently this is decided	     by setting the RES_USE_INET6 bit in _res.options.  */	  if (req->ai_family == AF_UNSPEC)	    _res.options &= ~RES_USE_INET6;	  if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6)	    gethosts (AF_INET6, struct in6_addr);	  no_inet6_data = no_data;	  if (req->ai_family == AF_UNSPEC)	    _res.options = old_res_options;	  if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET)	    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_NODATA);	    }	}      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 (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_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"];    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 (at2->family == AF_INET6)	  {	    family = AF_INET6;	    socklen = sizeof (struct sockaddr_in6);	  }	else	  {	    family = AF_INET;	    socklen = sizeof (struct sockaddr_in);	  }	for (st2 = st; st2 != NULL; st2 = st2->next)	  {	    *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;#endif /* SALEN */	    (*pai)->ai_addr->sa_family = family;	    if (family == AF_INET6)	      {		struct sockaddr_in6 *sin6p =		  (struct sockaddr_in6 *) (*pai)->ai_addr;		sin6p->sin6_flowinfo = 0;		memcpy (&sin6p->sin6_addr,			at2->addr, sizeof (struct in6_addr));		sin6p->sin6_port = st2->port;		sin6p->sin6_scope_id = at2->scopeid;	      }	    else	      {		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));	      }	    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;      }  }  return 0;}