aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog13
-rw-r--r--NEWS13
-rw-r--r--doc/mailfromd.texi37
-rw-r--r--src/bi_dns.m439
-rw-r--r--src/dns.c58
-rw-r--r--src/mailfromd.h1
6 files changed, 159 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog
index 3fd0f501..c080ebff 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2007-03-21 Sergey Poznyakoff <gray@gnu.org.ua>
+
+ * src/mailfromd.h (getmxip): New function
+ * src/dns.c (getmxip): New function
+ * src/bi_dns.m4: (getmx): New built-in
+ * doc/mailfromd.texi: Document getmx
+
+ * src/prog.c (mx_match): Do not raise exception if mf_not_found is
+ returned.
+ * src/bi_sa.m4 (open_connection): Raise mf_url if unknown protocol
+ is specified in the URL.
+ * src/mtasim.c: Minor fix
+
2007-03-19 Sergey Poznyakoff <gray@gnu.org.ua>
* src/engine.c, src/gram.y, src/status.mfi, doc/mailfromd.texi:
diff --git a/NEWS b/NEWS
index 8367bb9a..a56f6abb 100644
--- a/NEWS
+++ b/NEWS
@@ -1,4 +1,4 @@
-Mailfromd NEWS -- history of user-visible changes. 2007-03-19
+Mailfromd NEWS -- history of user-visible changes. 2007-03-21
Copyright (C) 2005, 2006, 2007 Sergey Poznyakoff
See the end of file for copying conditions.
@@ -27,6 +27,17 @@ Return full file name of the database file corresponding to format
Return the expiration period for db format `fmt'
+- string getmx(string domain [, number resolve])
+
+Returns a whitespace-separated list of MX names (if `resolve' is not
+given or is 0) or MX IP addresses (if `resolve'==1) for `domain'. If
+`domain' has no MX records, empty string is returned. If the DNS
+query fails, `getmx' raises an appropriate exception.
+
+This interface differs from that of version 3.1.4 in that the calls to
+getmx(domain) and getmx(domain,1) can return different number of
+entries (see the docs for an example).
+
* #pragma regex stack
The `#pragma regex' statement can keep a stack of regex flags. The
diff --git a/doc/mailfromd.texi b/doc/mailfromd.texi
index 63e677e8..8dd33e3b 100644
--- a/doc/mailfromd.texi
+++ b/doc/mailfromd.texi
@@ -4520,7 +4520,6 @@ fi
@end smallexample
@end deftypefn
-
@node DNS functions
@subsubsection DNS Functions
@@ -4539,6 +4538,42 @@ without throwing exceptions.
The built-in layer is always available. The library calls become
available after inclusion of @file{dns.mf}.
+@deftypefn {Built-in Function} string getmx (string @var{domain} @
+ [, number @var{resolve}])
+ Returns a whitespace-separated list of MX names (if @var{resolve} is not
+given or if it is @code{0}) or MX IP addresses (if
+@code{@var{resolve}!=0})) for @var{domain}. Within the returned
+strings, items are sorted lexicographically. If @var{domain} has no
+MX records, empty string is returned. If the DNS query fails,
+@code{getmx} raises an appropriate exception.
+
+@emph{Notes}:
+@enumerate 1
+@item The @code{getmx} function returns at most 32 MX names or IP addresses.
+
+@item The number of items returned by @code{getmx(@var{domain})} can
+differ from that obtained from @code{getmx(@var{domain}, 1)}, e.g.:
+
+@smallexample
+@group
+getmx("aol.com")
+ @result{} mailin-01.mx.aol.com mailin-02.mx.aol.com
+ mailin-03.mx.aol.com mailin-04.mx.aol.com
+getmx("aol.com", 1)
+ @result{} 64.12.137.89 64.12.137.168 64.12.137.184
+ 64.12.137.249 64.12.138.57 64.12.138.88
+ 64.12.138.120 64.12.138.185 205.188.155.89
+ 205.188.156.185 205.188.156.249 205.188.157.25
+ 205.188.157.217 205.188.158.121 205.188.159.57
+ 205.188.159.217
+@end group
+@end smallexample
+
+@item This interface will change in future releases, when array
+data types are implemented.
+@end enumerate
+@end deftypefn
+
@anchor{primitive_hasmx}
@deftypefn {Built-in Function} boolean primitive_hasmx (string @var{domain})
Returns @code{true} if the domain name given by its argument
diff --git a/src/bi_dns.m4 b/src/bi_dns.m4
index aa179492..021f2d08 100644
--- a/src/bi_dns.m4
+++ b/src/bi_dns.m4
@@ -78,6 +78,45 @@ MF_DEFUN(primitive_hasmx, NUMBER, STRING string)
}
END
+MF_DEFUN(getmx, STRING, STRING domain, OPTIONAL, NUMBER resolve)
+{
+ mxbuf_t mxbuf;
+ mf_status mxstat;
+ int i;
+
+ if (resolve)
+ mxstat = getmxip(domain, mxbuf);
+ else
+ mxstat = getmx(domain, mxbuf);
+ MF_ASSERT(mxstat == mf_success || mxstat == mf_not_found,
+ mxstat,
+ "Cannot get MX records for %s", domain);
+ if (mxstat == mf_not_found)
+ MF_RETURN_STRING("");
+ else {
+ int i;
+ size_t ns;
+ char *p;
+
+ MF_BEGIN_TEMP_SPACE(s, size);
+
+ for (i = 0, ns = 0, p = s; mxbuf[i]; i++) {
+ size_t len = strlen(mxbuf[i]);
+ if (ns + len + 1 > size)
+ break;
+ if (i > 0)
+ *p++ = ' ';
+ memcpy(p, mxbuf[i], len);
+ p += len;
+ ns += len + 1;
+ }
+ *p = 0;
+ dns_freemx(mxbuf);
+ MF_RETURN_TEMP_SPACE(ns);
+ }
+}
+END
+
static int
resolve_host(const char *string, unsigned long *ip)
{
diff --git a/src/dns.c b/src/dns.c
index 39af6a81..f71f1942 100644
--- a/src/dns.c
+++ b/src/dns.c
@@ -55,6 +55,64 @@ getmx(char *host, mxbuf_t mxbuf)
return rc;
}
+static int
+comp_ipbuf(const void *a, const void *b)
+{
+ const GACOPYZ_UINT32_T *in_a = a;
+ const GACOPYZ_UINT32_T *in_b = b;
+
+ if (*in_a < *in_b)
+ return -1;
+ else if (*in_a > *in_b)
+ return 1;
+ return 0;
+}
+
+mf_status
+getmxip(char *host, mxbuf_t mxbuf)
+{
+ mf_status mxstat;
+ GACOPYZ_UINT32_T ipbuf[MAXMXCOUNT];
+ size_t ipcount;
+ size_t i;
+
+ mxstat = getmx(host, mxbuf);
+ if (mxstat != mf_success)
+ return mxstat;
+
+ ipcount = 0;
+ for (i = 0; i < MAXMXCOUNT && mxbuf[i]; i++) {
+ size_t ipn;
+ mf_status stat = a_lookup(mxbuf[i],
+ ipbuf + ipcount,
+ NELEMS(ipbuf) - ipcount,
+ &ipn,
+ NULL, NULL, 0);
+ if (stat == mf_success) {
+ size_t n;
+ for (n = 0; ipcount < NELEMS(ipbuf) && n < ipn;
+ n++, ipcount++)
+ ipbuf[ipcount] = ntohl(ipbuf[ipcount]);
+ if (ipcount == NELEMS(ipbuf))
+ break;
+ }
+ }
+
+ dns_freemx(mxbuf);
+
+ qsort(ipbuf, ipcount, sizeof ipbuf[0], comp_ipbuf);
+
+ for (i = 0; i < ipcount; i++) {
+ struct in_addr s;
+ s.s_addr = htonl(ipbuf[i]);
+ mxbuf[i] = xstrdup(inet_ntoa(s));
+ }
+
+ if (i < MAXMXCOUNT)
+ mxbuf[i] = NULL;
+ return mf_success;
+}
+
mf_status
resolve_ipstr_domain(const char *ipstr, const char *domain, char **phbuf)
{
diff --git a/src/mailfromd.h b/src/mailfromd.h
index 836b4fd0..cb60441a 100644
--- a/src/mailfromd.h
+++ b/src/mailfromd.h
@@ -132,6 +132,7 @@ mf_status resolve_ipstr_domain(const char *ipstr, const char *domain,
mf_status resolve_hostname(const char *host, char **pipbuf);
mf_status getmx(char *ipstr, mxbuf_t mxbuf);
+mf_status getmxip(char *ipstr, mxbuf_t mxbuf);
/* Default file names */

Return to:

Send suggestions and report system problems to the System administrator.