if ((size_t) n > buflen || n >= MAXHOSTNAMELEN)
if (n > linebuflen) goto too_small; if (n >= MAXHOSTNAMELEN)
getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype,	     struct hostent *result, char *buffer, size_t buflen,	     int *errnop, int *h_errnop){  struct host_data  {    char *aliases[MAX_NR_ALIASES];    unsigned char host_addr[16];	/* IPv4 or IPv6 */    char *h_addr_ptrs[MAX_NR_ADDRS + 1];    char linebuffer[0];  } *host_data = (struct host_data *) buffer;  int linebuflen = buflen - offsetof (struct host_data, linebuffer);  register const HEADER *hp;  const u_char *end_of_message, *cp;  int n, ancount, qdcount;  int haveanswer, had_error;  char *bp, **ap, **hap;  char tbuf[MAXDNAME];  const char *tname;  int (*name_ok) __P ((const char *));  u_char packtmp[NS_MAXCDNAME];  if (linebuflen < 0)    {      /* The buffer is too small.  */    too_small:      *errnop = ERANGE;      *h_errnop = NETDB_INTERNAL;      return NSS_STATUS_TRYAGAIN;    }  tname = qname;  result->h_name = NULL;  end_of_message = answer->buf + anslen;  switch (qtype)    {    case T_A:    case T_AAAA:      name_ok = res_hnok;      break;    case T_PTR:      name_ok = res_dnok;      break;    default:      return NSS_STATUS_UNAVAIL;  /* XXX should be abort(); */    }  /*   * find first satisfactory answer   */  hp = &answer->hdr;  bp = host_data->linebuffer;  ancount = ntohs (hp->ancount);  qdcount = ntohs (hp->qdcount);  cp = answer->buf + HFIXEDSZ;  if (qdcount != 1)    {      *h_errnop = NO_RECOVERY;      return NSS_STATUS_UNAVAIL;    }  n = __ns_name_unpack (answer->buf, end_of_message, cp,			packtmp, sizeof packtmp);  if (n != -1 && __ns_name_ntop (packtmp, bp, linebuflen) == -1)    {      if (errno == EMSGSIZE)	goto too_small;      n = -1;    }  if (n > 0 && bp[0] == '.')    bp[0] = '\0';  if (n < 0 || (*name_ok) (bp) == 0)    {      *errnop = errno;      *h_errnop = NO_RECOVERY;      return NSS_STATUS_UNAVAIL;    }  cp += n + QFIXEDSZ;  if (qtype == T_A || qtype == T_AAAA)    {      /* res_send() has already verified that the query name is the       * same as the one we sent; this just gets the expanded name       * (i.e., with the succeeding search-domain tacked on).       */      n = strlen (bp) + 1;             /* for the \0 */      if (n >= MAXHOSTNAMELEN)	{	  *h_errnop = NO_RECOVERY;	  return NSS_STATUS_TRYAGAIN;	}      result->h_name = bp;      bp += n;      linebuflen -= n;      if (linebuflen < 0)	goto too_small;      /* The qname can be abbreviated, but h_name is now absolute. */      qname = result->h_name;    }  ap = host_data->aliases;  *ap = NULL;  result->h_aliases = host_data->aliases;  hap = host_data->h_addr_ptrs;  *hap = NULL;  result->h_addr_list = host_data->h_addr_ptrs;  haveanswer = 0;  had_error = 0;  while (ancount-- > 0 && cp < end_of_message && had_error == 0)    {      int type, class;      n = __ns_name_unpack (answer->buf, end_of_message, cp,			    packtmp, sizeof packtmp);      if (n != -1 && __ns_name_ntop (packtmp, bp, linebuflen) == -1)	{	  if (errno == EMSGSIZE)	    {	      *errnop = ERANGE;	      *h_errnop = NETDB_INTERNAL;	      return NSS_STATUS_TRYAGAIN;	    }	  n = -1;	}      if (n < 0 || (*name_ok) (bp) == 0)	{	  ++had_error;	  continue;	}      cp += n;				/* name */      type = _getshort (cp);      cp += INT16SZ;			/* type */      class = _getshort (cp);      cp += INT16SZ + INT32SZ;		/* class, TTL */      n = _getshort (cp);      cp += INT16SZ;			/* len */      if (class != C_IN)	{	  /* XXX - debug? syslog? */	  cp += n;	  continue;			/* XXX - had_error++ ? */	}      if ((qtype ==T_A || qtype == T_AAAA) && type == T_CNAME)	{	  if (ap >= &host_data->aliases[MAX_NR_ALIASES - 1])	    continue;	  n = dn_expand (answer->buf, end_of_message, cp, tbuf, sizeof tbuf);	  if (n < 0 || (*name_ok) (tbuf) == 0)	    {	      ++had_error;	      continue;	    }	  cp += n;	  /* Store alias.  */	  *ap++ = bp;	  n = strlen (bp) + 1;		/* For the \0.  */	  if (n >= MAXHOSTNAMELEN)	    {	      ++had_error;	      continue;	    }	  bp += n;	  linebuflen -= n;	  /* Get canonical name.  */	  n = strlen (tbuf) + 1;	/* For the \0.  */	  if ((size_t) n > buflen || n >= MAXHOSTNAMELEN)	    {	      ++had_error;	      continue;	    }	  result->h_name = bp;	  bp = __mempcpy (bp, tbuf, n);	/* Cannot overflow.  */	  linebuflen -= n;	  continue;	}      if (qtype == T_PTR && type == T_CNAME)	{	  n = dn_expand (answer->buf, end_of_message, cp, tbuf, sizeof tbuf);	  if (n < 0 || res_dnok (tbuf) == 0)	    {	      ++had_error;	      continue;	    }	  cp += n;	  /* Get canonical name.  */	  n = strlen (tbuf) + 1;   /* For the \0.  */	  if ((size_t) n > buflen || n >= MAXHOSTNAMELEN)	    {	      ++had_error;	      continue;	    }	  tname = bp;	  bp = __mempcpy (bp, tbuf, n);	/* Cannot overflow.  */	  linebuflen -= n;	  continue;	}      if (type == T_SIG || type == T_KEY || type == T_NXT)	{	  /* We don't support DNSSEC yet.  For now, ignore the record	     and send a low priority message to syslog.  */	  syslog (LOG_DEBUG | LOG_AUTH,	       "gethostby*.getanswer: asked for \"%s %s %s\", got type \"%s\"",		  qname, p_class (C_IN), p_type(qtype), p_type (type));	  cp += n;	  continue;	}      if (type != qtype)	{	  syslog (LOG_NOTICE | LOG_AUTH,	       "gethostby*.getanswer: asked for \"%s %s %s\", got type \"%s\"",		  qname, p_class (C_IN), p_type (qtype), p_type (type));	  cp += n;	  continue;			/* XXX - had_error++ ? */	}      switch (type)	{	case T_PTR:	  if (__strcasecmp (tname, bp) != 0)	    {	      syslog (LOG_NOTICE | LOG_AUTH, AskedForGot, qname, bp);	      cp += n;	      continue;			/* XXX - had_error++ ? */	    }	  n = __ns_name_unpack (answer->buf, end_of_message, cp,				packtmp, sizeof packtmp);	  if (n != -1 && __ns_name_ntop (packtmp, bp, linebuflen) == -1)	    {	      if (errno == EMSGSIZE)		{		  *errnop = ERANGE;		  *h_errnop = NETDB_INTERNAL;		  return NSS_STATUS_TRYAGAIN;		}	      n = -1;	    }	  if (n < 0 || res_hnok (bp) == 0)	    {	      ++had_error;	      break;	    }#if MULTI_PTRS_ARE_ALIASES	  cp += n;	  if (haveanswer == 0)	    result->h_name = bp;	  else if (ap < &host_data->aliases[MAXALIASES-1])	    *ap++ = bp;	  else	    n = -1;	  if (n != -1)	    {	      n = strlen (bp) + 1;	/* for the \0 */	      if (n >= MAXHOSTNAMELEN)		{		  ++had_error;		  break;		}	      bp += n;	      linebuflen -= n;	    }	  break;#else	  result->h_name = bp;	  if (_res.options & RES_USE_INET6)	    {	      n = strlen (bp) + 1;	/* for the \0 */	      if (n >= MAXHOSTNAMELEN)		{		  ++had_error;		  break;		}	      bp += n;	      linebuflen -= n;	      map_v4v6_hostent (result, &bp, &linebuflen);	    }	  *h_errnop = NETDB_SUCCESS;	  return NSS_STATUS_SUCCESS;#endif	case T_A:	case T_AAAA:	  if (strcasecmp (result->h_name, bp) != 0)	    {	      syslog (LOG_NOTICE | LOG_AUTH, AskedForGot, result->h_name, bp);	      cp += n;	      continue;			/* XXX - had_error++ ? */	    }	  if (n != result->h_length)	    {	      cp += n;	      continue;	    }	  if (!haveanswer)	    {	      register int nn;	      result->h_name = bp;	      nn = strlen (bp) + 1;	/* for the \0 */	      bp += nn;	      linebuflen -= nn;	    }	  linebuflen -= sizeof (align) - ((u_long) bp % sizeof (align));	  bp += sizeof (align) - ((u_long) bp % sizeof (align));	  if (n >= linebuflen)	    {	      ++had_error;	      continue;	    }	  if (hap >= &host_data->h_addr_ptrs[MAX_NR_ADDRS-1])	    {	      cp += n;	      continue;	    }	  bp = __mempcpy (*hap++ = bp, cp, n);	  cp += n;	  linebuflen -= n;	  break;	default:	  abort ();	}      if (had_error == 0)	++haveanswer;    }  if (haveanswer > 0)    {      *ap = NULL;      *hap = NULL;#if defined RESOLVSORT      /*       * Note: we sort even if host can take only one address       * in its return structures - should give it the "best"       * address in that case, not some random one       */      if (_res.nsort && haveanswer > 1 && qtype == T_A)	addrsort (host_data->h_addr_ptrs, haveanswer);#endif /*RESOLVSORT*/      if (result->h_name == NULL)	{	  n = strlen (qname) + 1;	/* For the \0.  */	  if (n > linebuflen)	    {	      *errnop = ERANGE;	      *h_errnop = NETDB_INTERNAL;	      return NSS_STATUS_TRYAGAIN;	    }	  if (n >= MAXHOSTNAMELEN)	    goto no_recovery;	  result->h_name = bp;	  bp = __mempcpy (bp, qname, n);	/* Cannot overflow.  */	  linebuflen -= n;	}      if (_res.options & RES_USE_INET6)	map_v4v6_hostent (result, &bp, &linebuflen);      *h_errnop = NETDB_SUCCESS;      return NSS_STATUS_SUCCESS;    } no_recovery:  *h_errnop = NO_RECOVERY;  return NSS_STATUS_TRYAGAIN;}