int main(int argc, char **argv) { MAI_HOSTADDR_STR hostaddr; struct addrinfo *res0; struct addrinfo *res; struct addrinfo **resv; size_t len, n; DNS_RR *rr; int aierr; myname = argv[0]; if (argc < 2) usage(); inet_proto_init(argv[0], INET_PROTO_NAME_ALL); while (*++argv) { if ((aierr = hostname_to_sockaddr(argv[0], (char *) 0, 0, &res0)) != 0) msg_fatal("%s: %s", argv[0], MAI_STRERROR(aierr)); for (len = 0, res = res0; res != 0; res = res->ai_next) len += 1; resv = (struct addrinfo **) mymalloc(len * sizeof(*resv)); for (len = 0, res = res0; res != 0; res = res->ai_next) resv[len++] = res; qsort((void *) resv, len, sizeof(*resv), compare_family); for (n = 0; n < len; n++) { if ((rr = dns_sa_to_rr(argv[0], 0, resv[n]->ai_addr)) == 0) msg_fatal("dns_sa_to_rr: %m"); if (dns_rr_to_pa(rr, &hostaddr) == 0) msg_fatal("dns_rr_to_pa: %m"); vstream_printf("%s -> %s\n", argv[0], hostaddr.buf); vstream_fflush(VSTREAM_OUT); dns_rr_free(rr); } freeaddrinfo(res0); myfree((void *) resv); } return (0); }
static DNS_RR *smtp_addr_one(DNS_RR *addr_list, const char *host, unsigned pref, DSN_BUF *why) { const char *myname = "smtp_addr_one"; DNS_RR *addr = 0; DNS_RR *rr; int aierr; struct addrinfo *res0; struct addrinfo *res; INET_PROTO_INFO *proto_info = inet_proto_info(); int found; if (msg_verbose) msg_info("%s: host %s", myname, host); /* * Interpret a numerical name as an address. */ if (hostaddr_to_sockaddr(host, (char *) 0, 0, &res0) == 0 && strchr((char *) proto_info->sa_family_list, res0->ai_family) != 0) { if ((addr = dns_sa_to_rr(host, pref, res0->ai_addr)) == 0) msg_fatal("host %s: conversion error for address family %d: %m", host, ((struct sockaddr *) (res0->ai_addr))->sa_family); addr_list = dns_rr_append(addr_list, addr); freeaddrinfo(res0); return (addr_list); } /* * Use DNS lookup, but keep the option open to use native name service. * * XXX A soft error dominates past and future hard errors. Therefore we * should not clobber a soft error text and status code. */ if (smtp_host_lookup_mask & SMTP_HOST_FLAG_DNS) { switch (dns_lookup_v(host, smtp_dns_res_opt, &addr, (VSTRING *) 0, why->reason, DNS_REQ_FLAG_NONE, proto_info->dns_atype_list)) { case DNS_OK: for (rr = addr; rr; rr = rr->next) rr->pref = pref; addr_list = dns_rr_append(addr_list, addr); return (addr_list); default: dsb_status(why, "4.4.3"); return (addr_list); case DNS_FAIL: dsb_status(why, SMTP_HAS_SOFT_DSN(why) ? "4.4.3" : "5.4.3"); return (addr_list); case DNS_INVAL: dsb_status(why, SMTP_HAS_SOFT_DSN(why) ? "4.4.4" : "5.4.4"); return (addr_list); case DNS_NOTFOUND: dsb_status(why, SMTP_HAS_SOFT_DSN(why) ? "4.4.4" : "5.4.4"); /* maybe native naming service will succeed */ break; } } /* * Use the native name service which also looks in /etc/hosts. * * XXX A soft error dominates past and future hard errors. Therefore we * should not clobber a soft error text and status code. */ #define RETRY_AI_ERROR(e) \ ((e) == EAI_AGAIN || (e) == EAI_MEMORY || (e) == EAI_SYSTEM) #ifdef EAI_NODATA #define DSN_NOHOST(e) \ ((e) == EAI_AGAIN || (e) == EAI_NODATA || (e) == EAI_NONAME) #else #define DSN_NOHOST(e) \ ((e) == EAI_AGAIN || (e) == EAI_NONAME) #endif if (smtp_host_lookup_mask & SMTP_HOST_FLAG_NATIVE) { if ((aierr = hostname_to_sockaddr(host, (char *) 0, 0, &res0)) != 0) { dsb_simple(why, (SMTP_HAS_SOFT_DSN(why) || RETRY_AI_ERROR(aierr)) ? (DSN_NOHOST(aierr) ? "4.4.4" : "4.3.0") : (DSN_NOHOST(aierr) ? "5.4.4" : "5.3.0"), "unable to look up host %s: %s", host, MAI_STRERROR(aierr)); } else { for (found = 0, res = res0; res != 0; res = res->ai_next) { if (strchr((char *) proto_info->sa_family_list, res->ai_family) == 0) { msg_info("skipping address family %d for host %s", res->ai_family, host); continue; } found++; if ((addr = dns_sa_to_rr(host, pref, res->ai_addr)) == 0) msg_fatal("host %s: conversion error for address family %d: %m", host, ((struct sockaddr *) (res0->ai_addr))->sa_family); addr_list = dns_rr_append(addr_list, addr); } freeaddrinfo(res0); if (found == 0) { dsb_simple(why, SMTP_HAS_SOFT_DSN(why) ? "4.4.4" : "5.4.4", "%s: host not found", host); } return (addr_list); } } /* * No further alternatives for host lookup. */ return (addr_list); }