aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2017-10-20 19:32:28 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2017-10-20 19:32:28 +0300
commitb74300677afd3f489f6dc65959f722be28c2804b (patch)
tree39afd042f53ed37160031e2da1298d479be63765
parentef49628b07df9ddb5f6035fc4941a10136a73b22 (diff)
downloadmailfromd-b74300677afd3f489f6dc65959f722be28c2804b.tar.gz
mailfromd-b74300677afd3f489f6dc65959f722be28c2804b.tar.bz2
Improve DNS API consistency
* lib/dns.c (dns_get_mx_records, getmx, getmxip): Replace with a single function mx_lookup. All uses updated.
-rw-r--r--lib/dns.c80
-rw-r--r--lib/dns.h2
-rw-r--r--lib/libmf.h2
-rw-r--r--src/builtin/dns.bi74
-rw-r--r--src/callout.c2
-rw-r--r--src/prog.c2
-rw-r--r--src/spf.c2
-rw-r--r--tests/resolv.c49
8 files changed, 101 insertions, 112 deletions
diff --git a/lib/dns.c b/lib/dns.c
index f57eb7a9..c67ad02b 100644
--- a/lib/dns.c
+++ b/lib/dns.c
@@ -144,9 +144,41 @@ adns_to_dns_status(int e)
}
}
+static dns_status
+dns_reply_resolve(struct dns_reply *reply)
+{
+ GACOPYZ_UINT32_T *ipbuf = NULL;
+ size_t ipcount = 0;
+ size_t ipmax = 0;
+ size_t i;
+
+ ipcount = 0;
+ for (i = 0; i < reply->count; i++) {
+ struct dns_reply r;
+ dns_status stat = a_lookup(reply->data.str[i], &r);
+ if (stat == dns_success) {
+ size_t n;
+ for (n = 0; n < r.count; n++, ipcount++) {
+ if (ipcount == ipmax)
+ ipbuf = mu_2nrealloc(ipbuf, &ipmax,
+ sizeof(ipbuf));
+ ipbuf[ipcount] = ntohl(r.data.ip[n]);
+ }
+ dns_reply_free(&r);
+ }
+ }
+ dns_reply_free(reply);
+ if (ipcount == 0)
+ return dns_not_found;
+ reply->type = dns_reply_ip;
+ reply->count = ipcount;
+ reply->data.ip = ipbuf;
+ return dns_success;
+}
+
/* Return MX records for the given HOST. */
dns_status
-dns_get_mx_records(const char *host, struct dns_reply *reply)
+mx_lookup(const char *host, int resolve, struct dns_reply *reply)
{
dns_status status = dns_failure;
int rc;
@@ -169,6 +201,10 @@ dns_get_mx_records(const char *host, struct dns_reply *reply)
for (i = 0; i < ans->nrrs; i++)
reply->data.str[i] = mu_strdup(ans->rrs.inthostaddr[i].ha.host);
free(ans);
+
+ if (resolve)
+ status = dns_reply_resolve(reply);
+
return status;
}
@@ -444,48 +480,6 @@ mf_to_dns_status(mf_status stat)
}
mf_status
-getmx(const char *host, struct dns_reply *reply)
-{
- return dns_to_mf_status(dns_get_mx_records(host, reply));
-}
-
-mf_status
-getmxip(char *host, struct dns_reply *reply)
-{
- struct dns_reply mxnames;
- mf_status mxstat;
- GACOPYZ_UINT32_T *ipbuf = NULL;
- size_t ipcount = 0;
- size_t ipmax = 0;
- size_t i;
-
- mxstat = getmx(host, &mxnames);
- if (mxstat != mf_success)
- return mxstat;
-
- ipcount = 0;
- for (i = 0; i < mxnames.count; i++) {
- struct dns_reply r;
- dns_status stat = a_lookup(mxnames.data.str[i], &r);
- if (stat == dns_success) {
- size_t n;
- for (n = 0; n < r.count; n++, ipcount++) {
- if (ipcount == ipmax)
- ipbuf = mu_2nrealloc(ipbuf, &ipmax,
- sizeof(ipbuf));
- ipbuf[ipcount] = ntohl(r.data.ip[n]);
- }
- dns_reply_free(&r);
- }
- }
- dns_reply_free(&mxnames);
- reply->type = dns_reply_ip;
- reply->count = ipcount;
- reply->data.ip = ipbuf;
- return mf_success;
-}
-
-mf_status
resolve_ipstr_domain(const char *ipstr, const char *domain, char **phbuf)
{
char *hbuf;
diff --git a/lib/dns.h b/lib/dns.h
index fc0d4820..697d5a2f 100644
--- a/lib/dns.h
+++ b/lib/dns.h
@@ -43,7 +43,6 @@ struct dns_reply {
void dns_reply_free(struct dns_reply *r);
int dns_str_is_ipv4(const char *addr);
-dns_status dns_get_mx_records(const char *host, struct dns_reply *repl);
int dns_reverse_ipstr(const char *ipstr, char *revipstr);
@@ -61,5 +60,6 @@ dns_status ptr_validate(const char *ipstr, struct dns_reply *repl);
dns_status spf_lookup(const char *domain, char **record);
+dns_status mx_lookup(const char *host, int resolve, struct dns_reply *repl);
#endif
diff --git a/lib/libmf.h b/lib/libmf.h
index cf57e7a4..ebfd0e3e 100644
--- a/lib/libmf.h
+++ b/lib/libmf.h
@@ -282,8 +282,6 @@ size_t format_time_str(FILE *fp, time_t timestamp);
void dnsbase_init();
mf_status dns_to_mf_status(dns_status stat);
dns_status mf_to_dns_status(mf_status stat);
-mf_status getmx(const char *host, struct dns_reply *repl);
-mf_status getmxip(char *host, struct dns_reply *reply);
mf_status resolve_ipstr_domain(const char *ipstr, const char *domain, char **phbuf);
mf_status resolve_ipstr(const char *ipstr, char **phbuf);
mf_status resolve_hostname(const char *host, char **pipbuf);
diff --git a/src/builtin/dns.bi b/src/builtin/dns.bi
index 4bde9676..8d28748a 100644
--- a/src/builtin/dns.bi
+++ b/src/builtin/dns.bi
@@ -152,7 +152,7 @@ MF_DEFUN(primitive_hasmx, NUMBER, STRING string)
struct dns_reply repl;
mf_status mxstat;
- mxstat = getmx(string, &repl);
+ mxstat = dns_to_mf_status(mx_lookup(string, 0, &repl));
MF_ASSERT(mxstat == mf_success || mxstat == mf_not_found,
mf_status_to_exception(mxstat),
@@ -166,57 +166,41 @@ MF_DEFUN(primitive_hasmx, NUMBER, STRING string)
}
END
-MF_DEFUN(getmx, STRING, STRING domain, OPTIONAL, NUMBER no_resolve)
+MF_DEFUN(getmx, STRING, STRING domain, OPTIONAL, NUMBER resolve)
{
mf_status mxstat;
struct dns_reply reply;
-
- if (MF_OPTVAL(no_resolve)) {
- mxstat = getmxip(domain, &reply);
- if (!mf_resolved(mxstat)) {
- MF_THROW(mf_status_to_exception(mxstat),
- _("cannot get MX records for %s"), domain);
- }
- if (mxstat == mf_not_found) {
- MF_RETURN("");
- } else {
- int i;
+ int i;
+
+ mxstat = dns_to_mf_status(mx_lookup(domain, MF_OPTVAL(resolve),
+ &reply));
+ if (!mf_resolved(mxstat)) {
+ MF_THROW(mf_status_to_exception(mxstat),
+ _("cannot get MX records for %s"), domain);
+ }
+ if (mxstat == mf_not_found) {
+ MF_RETURN("");
+ } else if (reply.type == dns_reply_ip) {
+ MF_OBSTACK_BEGIN();
+ for (i = 0; i < reply.count; i++) {
+ struct in_addr s;
+ s.s_addr = htonl(reply.data.ip[i]);
- MF_OBSTACK_BEGIN();
- for (i = 0; i < reply.count; i++) {
- struct in_addr s;
- s.s_addr = htonl(reply.data.ip[i]);
-
- if (i > 0)
- MF_OBSTACK_1GROW(' ');
- MF_OBSTACK_GROW(inet_ntoa(s));
- }
- MF_OBSTACK_1GROW(0);
- dns_reply_free(&reply);
- MF_RETURN_OBSTACK();
+ if (i > 0)
+ MF_OBSTACK_1GROW(' ');
+ MF_OBSTACK_GROW(inet_ntoa(s));
}
} else {
- mxstat = getmx(domain, &reply);
- if (!mf_resolved(mxstat)) {
- MF_THROW(mf_status_to_exception(mxstat),
- _("cannot get MX records for %s"), domain);
- }
- if (mxstat == mf_not_found) {
- MF_RETURN("");
- } else {
- int i;
-
- MF_OBSTACK_BEGIN();
- for (i = 0; i < reply.count; i++) {
- if (i > 0)
- MF_OBSTACK_1GROW(' ');
- MF_OBSTACK_GROW(reply.data.str[i]);
- }
- MF_OBSTACK_1GROW(0);
- dns_reply_free(&reply);
- MF_RETURN_OBSTACK();
+ MF_OBSTACK_BEGIN();
+ for (i = 0; i < reply.count; i++) {
+ if (i > 0)
+ MF_OBSTACK_1GROW(' ');
+ MF_OBSTACK_GROW(reply.data.str[i]);
}
}
+ MF_OBSTACK_1GROW(0);
+ dns_reply_free(&reply);
+ MF_RETURN_OBSTACK();
}
END
@@ -259,7 +243,7 @@ MF_DEFUN(primitive_ismx, NUMBER, STRING domain, STRING ipstr)
_("cannot resolve host name %s"), ipstr);
ip = ntohl(ip);
- mxstat = getmxip(domain, &reply);
+ mxstat = dns_to_mf_status(mx_lookup(domain, 1, &reply));
if (mxstat != mf_success) {
MF_THROW(mf_status_to_exception(mxstat),
diff --git a/src/callout.c b/src/callout.c
index 1d46bc70..8b7cd3c1 100644
--- a/src/callout.c
+++ b/src/callout.c
@@ -637,7 +637,7 @@ callout_mx(struct smtp_io_data *iop, const char *hostname, int *pcount)
struct dns_reply reply;
mf_status rc, mxstat;
- mxstat = getmx(hostname, &reply);
+ mxstat = dns_to_mf_status(mx_lookup(hostname, 0, &reply));
if (pcount)
*pcount = 0;
diff --git a/src/prog.c b/src/prog.c
index 932efd25..b4ec247c 100644
--- a/src/prog.c
+++ b/src/prog.c
@@ -1602,7 +1602,7 @@ mx_match(eval_environ_t env, char *string,
p++;
else
p = string;
- mxstat = getmx(p, &reply);
+ mxstat = dns_to_mf_status(mx_lookup(p, 0, &reply));
rc = 0;
if (mxstat == mf_success) {
int i;
diff --git a/src/spf.c b/src/spf.c
index 87a158a9..68f1f91d 100644
--- a/src/spf.c
+++ b/src/spf.c
@@ -672,7 +672,7 @@ mech_mx(spf_data *dat, spf_term_arg *arg, unsigned long masklen)
("MX domain_spec=%s, netmask=%lx",
domain_spec, netmask));
- DNS_CATCH(dns_get_mx_records(domain_spec, &reply));
+ DNS_CATCH(mx_lookup(domain_spec, 0, &reply));
for (i = 0; i < reply.count; i++) {
spf_term_arg targ;
diff --git a/tests/resolv.c b/tests/resolv.c
index 460b14b2..35d2d80a 100644
--- a/tests/resolv.c
+++ b/tests/resolv.c
@@ -35,12 +35,13 @@ hostname_cmp(const void *a, const void *b)
}
void
-reply_print_str(struct dns_reply *reply)
+reply_print_str(struct dns_reply *reply, int sorted)
{
int i;
-
- qsort(reply->data.str, reply->count, sizeof reply->data.str[0],
- hostname_cmp);
+
+ if (sorted)
+ qsort(reply->data.str, reply->count, sizeof reply->data.str[0],
+ hostname_cmp);
for (i = 0; i < reply->count; i++) {
printf("%s\n", reply->data.str[i]);
}
@@ -59,12 +60,13 @@ ipaddr_cmp(const void *a, const void *b)
}
void
-reply_print_ip(struct dns_reply *reply)
+reply_print_ip(struct dns_reply *reply, int sorted)
{
int i;
-
- qsort(reply->data.ip, reply->count, sizeof reply->data.ip[0],
- ipaddr_cmp);
+
+ if (sorted)
+ qsort(reply->data.ip, reply->count, sizeof reply->data.ip[0],
+ ipaddr_cmp);
for (i = 0; i < reply->count; i++) {
struct in_addr ip;
ip.s_addr = reply->data.ip[i];
@@ -73,14 +75,14 @@ reply_print_ip(struct dns_reply *reply)
}
void
-reply_print(struct dns_reply *reply)
+reply_print(struct dns_reply *reply, int sorted)
{
switch (reply->type) {
case dns_reply_str:
- reply_print_str(reply);
+ reply_print_str(reply, sorted);
break;
case dns_reply_ip:
- reply_print_ip(reply);
+ reply_print_ip(reply, sorted);
break;
default:
mu_error("%s:%d: unrecognized reply type", __FILE__, __LINE__);
@@ -98,7 +100,7 @@ res_a(int argc, char **argv)
status = a_lookup(argv[0], &reply);
status_print(status);
if (status == dns_success) {
- reply_print(&reply);
+ reply_print(&reply, 1);
dns_reply_free(&reply);
}
return 0;
@@ -120,7 +122,7 @@ res_ptr(int argc, char **argv)
status = ptr_lookup(in, &reply);
status_print(status);
if (status == dns_success) {
- reply_print(&reply);
+ reply_print(&reply, 1);
dns_reply_free(&reply);
}
return 0;
@@ -136,7 +138,7 @@ res_ptr_val(int argc, char **argv)
status = ptr_validate(argv[0], &reply);
status_print(status);
if (status == dns_success) {
- reply_print(&reply);
+ reply_print(&reply, 1);
dns_reply_free(&reply);
}
return 0;
@@ -152,7 +154,7 @@ res_txt(int argc, char **argv)
status = txt_lookup(argv[0], &reply);
status_print(status);
if (status == dns_success) {
- reply_print(&reply);
+ reply_print(&reply, 1);
dns_reply_free(&reply);
}
return 0;
@@ -163,12 +165,23 @@ res_mx(int argc, char **argv)
{
dns_status status;
struct dns_reply reply;
-
+ int ip = 0;
+
+ if (argc == 2) {
+ if (strcmp(argv[0], "-ip") == 0)
+ ip = 1;
+ else {
+ mu_error("bad arguments");
+ abort();
+ }
+ argc--;
+ argv++;
+ }
assert(argc == 1);
- status = dns_get_mx_records(argv[0], &reply);
+ status = mx_lookup(argv[0], ip, &reply);
status_print(status);
if (status == dns_success) {
- reply_print(&reply);
+ reply_print(&reply, 0);
dns_reply_free(&reply);
}
return 0;

Return to:

Send suggestions and report system problems to the System administrator.