static void next_lookup(struct addr_query *aquery)
{
  const char *p;
  char name[128];
  int status;
  struct hostent *host;

  for (p = aquery->remaining_lookups; *p; p++)
    {
      switch (*p)
        {
        case 'b':
          ptr_rr_name(name, &aquery->addr);
          aquery->remaining_lookups = p + 1;
          ares_query(aquery->channel, name, C_IN, T_PTR, addr_callback,
                     aquery);
          return;
        case 'f':
          status = file_lookup(&aquery->addr, &host);

          /* this status check below previously checked for !ARES_ENOTFOUND,
             but we should not assume that this single error code is the one
             that can occur, as that is in fact no longer the case */
          if (status == ARES_SUCCESS)
            {
              end_aquery(aquery, status, host);
              return;
            }
          break;
        }
    }
  end_aquery(aquery, ARES_ENOTFOUND, NULL);
}
static void addr_callback(void *arg, int status, int timeouts,
                          unsigned char *abuf, int alen)
{
  struct addr_query *aquery = (struct addr_query *) arg;
  struct hostent *host;
  size_t addrlen;

  aquery->timeouts += timeouts;
  if (status == ARES_SUCCESS)
    {
      if (aquery->addr.family == AF_INET)
        {
          addrlen = sizeof(struct in_addr);
          status = ares_parse_ptr_reply(abuf, alen, &aquery->addr.addrV4,
                                        (int)addrlen, AF_INET, &host);
        }
      else
        {
          addrlen = sizeof(struct in6_addr);
          status = ares_parse_ptr_reply(abuf, alen, &aquery->addr.addrV6,
                                        (int)addrlen, AF_INET6, &host);
        }
      end_aquery(aquery, status, host);
    }
  else if (status == ARES_EDESTRUCTION)
    end_aquery(aquery, status, NULL);
  else
    next_lookup(aquery);
}