aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2008-02-10 14:08:36 +0000
committerSergey Poznyakoff <gray@gnu.org.ua>2008-02-10 14:08:36 +0000
commita1871918823166cac9f0c12164ba27cb3b1f0c2c (patch)
tree7260d118aa5af6a8f006f9b2dac6cabde782db8c /src
parent455b645247bdc0f01239b2352a9d8f07f446024f (diff)
downloadmailfromd-a1871918823166cac9f0c12164ba27cb3b1f0c2c.tar.gz
mailfromd-a1871918823166cac9f0c12164ba27cb3b1f0c2c.tar.bz2
Merged HEAD from branches/gmach
git-svn-id: file:///svnroot/mailfromd/trunk@1612 7a8a7f39-df28-0410-adc6-e0d955640f24
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am186
-rw-r--r--src/bi_db.m4319
-rw-r--r--src/bi_dns.m4297
-rw-r--r--src/bi_gettext.m442
-rw-r--r--src/bi_io.m4312
-rw-r--r--src/bi_ipaddr.m4102
-rw-r--r--src/bi_mail.m4313
-rw-r--r--src/bi_other.m4140
-rw-r--r--src/bi_poll.m4117
-rw-r--r--src/bi_sa.m4512
-rw-r--r--src/bi_sieve.m4193
-rw-r--r--src/bi_spf.m473
-rw-r--r--src/bi_sprintf.m4421
-rw-r--r--src/bi_string.m4183
-rw-r--r--src/bi_system.m444
-rw-r--r--src/bi_vars.m458
-rw-r--r--src/builtin.def14
-rw-r--r--src/cache.c197
-rw-r--r--src/daemon.c195
-rw-r--r--src/db.c393
-rw-r--r--src/debug.cin196
-rw-r--r--src/debug.hin53
-rw-r--r--src/debugdef.m463
-rw-r--r--src/dns.c206
-rw-r--r--src/dns.h97
-rw-r--r--src/dnsbase.c814
-rw-r--r--src/dnscache.c250
-rw-r--r--src/drivers.c2308
-rw-r--r--src/drv.awk63
-rw-r--r--src/engine.c1466
-rw-r--r--src/gram.y3910
-rw-r--r--src/init.m462
-rw-r--r--src/lex.l803
-rw-r--r--src/mailfromd.h889
-rw-r--r--src/main.c2244
-rw-r--r--src/mf-status.mfi52
-rw-r--r--src/mfstat.awk55
-rw-r--r--src/mtasim.c2208
-rw-r--r--src/mu_dbm.c668
-rw-r--r--src/mu_dbm.h77
-rw-r--r--src/opcode.awk97
-rw-r--r--src/opcodes93
-rw-r--r--src/openat-die.c38
-rw-r--r--src/optab.opc56
-rw-r--r--src/optab.oph6
-rw-r--r--src/pp.c803
-rw-r--r--src/prog.c2391
-rw-r--r--src/prog.h78
-rw-r--r--src/rate.c182
-rw-r--r--src/snarf.m4566
-rw-r--r--src/spf.c1278
-rw-r--r--src/spf.h53
-rw-r--r--src/stack.c119
-rw-r--r--src/status.mfi11
-rw-r--r--src/symtab.c496
-rw-r--r--src/syslog_async.c445
-rw-r--r--src/syslog_async.h126
-rw-r--r--src/version.c51
58 files changed, 0 insertions, 27484 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
deleted file mode 100644
index f568c65e..00000000
--- a/src/Makefile.am
+++ /dev/null
@@ -1,186 +0,0 @@
-# This file is part of mailfromd.
-# Copyright (C) 2005, 2006, 2007 Sergey Poznyakoff
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3, or (at your option)
-# any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-sbin_PROGRAMS = mailfromd
-bin_PROGRAMS = mtasim
-
-incdir=$(pkgdatadir)/$(VERSION)/include
-inc_DATA = status.mfh
-
-M4_FILES=\
- bi_db.m4\
- bi_dns.m4\
- bi_gettext.m4\
- bi_io.m4\
- bi_ipaddr.m4\
- bi_mail.m4\
- bi_poll.m4\
- bi_sa.m4\
- bi_sieve.m4\
- bi_spf.m4\
- bi_sprintf.m4\
- bi_string.m4\
- bi_system.m4\
- bi_other.m4\
- bi_vars.m4
-
-mailfromd_SOURCES = \
- debug.c\
- cache.c\
- dnscache.c\
- db.c\
- dns.c\
- dnsbase.c\
- engine.c\
- gram.y\
- lex.l\
- main.c\
- mf-status.c\
- mu_dbm.c\
- optab.c\
- optab.h\
- pp.c\
- prog.c\
- prog.h\
- spf.c\
- stack.c\
- symtab.c\
- rate.c\
- $(M4_FILES:.m4=.c)
-
-noinst_LIBRARIES=libmf.a
-
-SYSLOG_ASYNC_O=syslog_async.o
-
-libmf_a_SOURCES=\
- version.c
-
-libmf_a_LIBADD=$(LIBOBJS) $(BUILD_SYSLOG_ASYNC)
-libmf_a_DEPENDENCIES=$(BUILD_SYSLOG_ASYNC)
-
-mailfromd_LDADD = ./libmf.a $(LDADD)
-
-mtasim_SOURCES = mtasim.c openat-die.c
-mtasim_LDADD = ./libmf.a $(LDADD) $(READLINE_LIBS)
-
-noinst_HEADERS = mailfromd.h mu_dbm.h builtin.h dns.h spf.h drivers.c debug.h \
- syslog_async.h
-
-EXTRA_DIST = \
- $(M4_FILES)\
- builtin.def\
- builtin.h\
- daemon.c\
- debug.cin\
- debug.hin\
- debugdef.m4\
- drv.awk\
- gram.h\
- init.m4\
- mf-status.mfi\
- mfstat.awk\
- node-tab.c\
- node-type.h\
- opcode.awk\
- opcodes\
- optab.opc\
- optab.oph\
- snarf.m4\
- status.mfh\
- status.mfi\
- syslog_async.c
-
-BUILT_SOURCES=\
- $(M4_FILES:.m4=.c)\
- builtin.h\
- debug.c\
- debug.h\
- mf-status.c\
- node-tab.c\
- node-type.h\
- optab.c\
- optab.h
-
-AM_CPPFLAGS=-DSYSCONFDIR=\"$(sysconfdir)\"\
- -DDEFAULT_STATE_DIR=\"$(DEFAULT_STATE_DIR)\"\
- -DDEFAULT_SOCKET=\"$(DEFAULT_SOCKET)\"\
- -DDEFAULT_VERSION_INCLUDE_DIR=\"$(incdir)\"\
- -DDEFAULT_INCLUDE_DIR=\"$(pkgdatadir)/include\"\
- -DDEFAULT_PREPROCESSOR="\"$(DEFAULT_PREPROCESSOR)\""\
- -DLOCALEDIR=\"$(localedir)\"
-
-INCLUDES = $(MAILUTILS_INCLUDES) $(MU_COMMON_INCLUDES) -I$(top_srcdir)/lib -I../lib $(MILTER_INCLUDES)
-LDADD = ../lib/libgnu.a $(MAILUTILS_LIBS) $(MILTER)
-
-builtin.h: Makefile.am
-
-node-type.h: drivers.c
- $(AWK) -v MODE=types -f $(top_srcdir)/src/drv.awk drivers.c > node-type.h
-
-node-tab.c: drivers.c
- $(AWK) -f $(top_srcdir)/src/drv.awk drivers.c > node-tab.c
-
-
-SUFFIXES = .m4 .c .def .h .mfi .mfh .opc .oph .cin .hin
-
-.mfi.c:
- $(AWK) -f $(top_srcdir)/src/mfstat.awk \
- $(top_srcdir)/src/mailfromd.h $< > $@
-
-.mfi.mfh:
- $(AWK) -f $(top_srcdir)/src/mfstat.awk \
- $(top_srcdir)/src/mailfromd.h $< > $@
-
-
-M4=m4
-
-.m4.c:
- $(M4) --prefix -s -DSOURCE="$<" $(top_srcdir)/src/snarf.m4 $< > $@-t
- sed '1{/#line/d;}' $@-t > $@
- rm $@-t
-
-.def.h:
- $(M4) --prefix $(top_srcdir)/src/init.m4 $(M4_FILES) $< > $@
-
-.opc.c:
- $(AWK) -f $(top_srcdir)/src/opcode.awk \
- $(top_srcdir)/src/opcodes $< > $@
-
-.oph.h:
- $(AWK) -f $(top_srcdir)/src/opcode.awk \
- $(top_srcdir)/src/opcodes $< > $@
-
-optab.c optab.h: opcodes
-
-.cin.c:
- SRCLIST=`echo $(mailfromd_SOURCES) | tr -s ' ' ','`; \
- $(M4) -s -DSRCLIST="$$SRCLIST" $(top_srcdir)/src/debugdef.m4 $< > $@
-
-.hin.h:
- SRCLIST=`echo $(mailfromd_SOURCES) | tr -s ' ' ','`; \
- $(M4) -DSRCLIST="$$SRCLIST" $(top_srcdir)/src/debugdef.m4 $< > $@
-
-debug.c: Makefile.in debugdef.m4 debug.cin
-debug.h: Makefile.in debugdef.m4 debug.hin
-
-AM_YFLAGS=-dtv
-AM_LFLAGS=-dvp
-
-install-data-local:
- -test -d $(DESTDIR)$(DEFAULT_STATE_DIR) || \
- $(mkinstalldirs) -o $(DEFAULT_USER) $(DESTDIR)$(DEFAULT_STATE_DIR)
-
-
diff --git a/src/bi_db.m4 b/src/bi_db.m4
deleted file mode 100644
index f366008f..00000000
--- a/src/bi_db.m4
+++ /dev/null
@@ -1,319 +0,0 @@
-/* This file is part of Mailfromd. -*- c -*-
- Copyright (C) 2006, 2007, 2008 Sergey Poznyakoff
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-#define LOOKUP_NULL_BYTE 0x1
-#define LOOKUP_TEST_ONLY 0x2
-
-static int
-dbmap_lookup(eval_environ_t env, char *dbname, const char *keystr,
- const char *defval, int flags)
-{
- int rc;
- DBM_FILE db;
- DBM_DATUM key;
- DBM_DATUM contents;
-
- if (!defval)
- defval = "";
- if (mu_dbm_open(dbname, &db, MU_STREAM_READ, 0, NULL))
- MF_THROW(mf_dbfailure,
- _("mu_dbm_open(%s) failed: %s"),
- dbname,
- mu_dbm_strerror());
-
- memset(&key, 0, sizeof key);
- memset(&contents, 0, sizeof contents);
- MU_DATUM_PTR(key) = (void*) keystr;
- MU_DATUM_SIZE(key) = strlen(keystr);
- if (flags & LOOKUP_NULL_BYTE)
- MU_DATUM_SIZE(key)++;
- rc = mu_dbm_fetch(&db, key, &contents) == 0;
- debug2(10, "Looking up %s: %s", keystr, rc ? "true" : "false");
- if (flags & LOOKUP_TEST_ONLY)
- push(env, (STKVAL)rc);
- else {
- if (!rc) {
- if (defval)
- pushs(env, (STKVAL)defval);
- else
- push(env, 0);
- } else if (((char*)MU_DATUM_PTR(contents))[MU_DATUM_SIZE(contents)-1]) {
- size_t off;
- size_t len = MU_DATUM_SIZE(contents);
- char *s = MF_ALLOC_HEAP(off, len + 1);
- memcpy(s, MU_DATUM_PTR(contents), len);
- s[len] = 0;
- push(env, (STKVAL) off);
- } else
- pushs(env, MU_DATUM_PTR(contents));
- }
- mu_dbm_datum_free(&contents);
- mu_dbm_close(&db);
- return rc;
-}
-
-MF_DEFUN(dbmap, NUMBER, STRING dbname, STRING key, OPTIONAL, NUMBER null)
-{
- dbmap_lookup(env, dbname, key, NULL,
- LOOKUP_TEST_ONLY |
- (MF_OPTVAL(null) ? LOOKUP_NULL_BYTE : 0));
-}
-END
-
-MF_DEFUN(dbget, STRING, STRING dbname, STRING key, OPTIONAL,
- STRING defval, NUMBER null)
-{
- dbmap_lookup(env, dbname, key,
- MF_OPTVAL(defval),
- (MF_OPTVAL(null) ? LOOKUP_NULL_BYTE : 0));
-}
-END
-
-MF_DEFUN(dbput, VOID, STRING dbname, STRING keystr, STRING value,
- OPTIONAL, NUMBER null)
-{
- int rc;
- DBM_FILE db;
- DBM_DATUM key;
- DBM_DATUM contents;
-
- if (mu_dbm_open(dbname, &db, MU_STREAM_RDWR, 0640, NULL))
- MF_THROW(mf_dbfailure,
- _("mu_dbm_open(%s) failed: %s"),
- dbname,
- mu_dbm_strerror());
- memset(&key, 0, sizeof key);
- MU_DATUM_PTR(key) = keystr;
- MU_DATUM_SIZE(key) = strlen(keystr);
- if (MF_OPTVAL(null))
- MU_DATUM_SIZE(key)++;
-
- memset(&contents, 0, sizeof contents);
- MU_DATUM_PTR(contents) = value;
- MU_DATUM_SIZE(contents) = strlen(value) + 1;
-
- rc = mu_dbm_insert(&db, key, contents, 1);
- mu_dbm_close(&db);
- MF_ASSERT(rc == 0,
- mf_dbfailure,
- _("Failed to insert data to %s: %s %s: %s"),
- dbname,
- keystr,
- value,
- mu_dbm_strerror());
-}
-END
-
-MF_DEFUN(dbdel, VOID, STRING dbname, STRING keystr, OPTIONAL, NUMBER null)
-{
- DBM_FILE db;
- DBM_DATUM key;
- int rc;
- if (mu_dbm_open(dbname, &db, MU_STREAM_RDWR, 0640, NULL))
- MF_THROW(mf_dbfailure,
- _("mu_dbm_open(%s) failed: %s"),
- dbname,
- mu_dbm_strerror());
- memset(&key, 0, sizeof key);
- MU_DATUM_PTR(key) = keystr;
- MU_DATUM_SIZE(key) = strlen(keystr);
- if (MF_OPTVAL(null))
- MU_DATUM_SIZE(key)++;
- rc = mu_dbm_delete(&db, key);
- mu_dbm_close(&db);
- MF_ASSERT(rc == 0,
- mf_dbfailure,
- _("Failed to delete data `%s' from `%s': %s"),
- keystr,
- dbname,
- mu_dbm_strerror());
-}
-END
-
-
-static void
-greylist_print_item(const char *key, size_t size, const void *content)
-{
- time_t timestamp = *(time_t*) content;
- size--; /* Size includes the trailing nul */
- printf("%*.*s ", size, size, key);
- format_time_str(stdout, timestamp);
- putchar('\n');
-}
-
-static int
-greylist_expire_item(const void *content)
-{
- time_t timestamp = *(time_t*) content;
- return greylist_format->expire_interval &&
- time(NULL) - timestamp > greylist_format->expire_interval;
-}
-
-
-static struct db_format greylist_format_struct = {
- "greylist",
- DEFAULT_GREYLIST_DATABASE,
- 1,
- DEFAULT_EXPIRE_INTERVAL,
- greylist_print_item,
- greylist_expire_item
-};
-
-struct db_format *greylist_format = &greylist_format_struct;
-
-MF_VAR(greylist_seconds_left, NUMBER);
-
-/* greylist(key, interval)
-
- Returns true if the key is greylisted, false if it's OK to
- deliver mail.
- */
-MF_DEFUN(greylist, NUMBER, STRING email, NUMBER interval)
-{
- int rc;
- DBM_FILE db;
- DBM_DATUM key;
- DBM_DATUM contents;
- int readonly;
- time_t now;
-
- rc = mu_dbm_open(greylist_format->dbname, &db, MU_STREAM_RDWR, 0600,
- &readonly);
- MF_ASSERT(rc == 0, mf_dbfailure, _("mu_dbm_open(%s) failed: %s"),
- greylist_format->dbname, mu_dbm_strerror());
-
- memset(&key, 0, sizeof key);
- memset(&contents, 0, sizeof contents);
- MU_DATUM_PTR(key) = email;
- MU_DATUM_SIZE(key) = strlen(email)+1;
-
- time(&now);
- if (mu_dbm_fetch(&db, key, &contents) == 0) {
- time_t timestamp, diff;
-
- MF_ASSERT(MU_DATUM_SIZE(contents) == sizeof timestamp,
- mf_dbfailure,
- _("Greylist database %s has wrong data size"),
- greylist_format->dbname);
-
- timestamp = *(time_t*) MU_DATUM_PTR(contents);
- diff = now - timestamp;
-
- __DBG(20) {
- char timebuf[32];
- debug_log("%s entered greylist database on %s, "
- "%ld seconds ago",
- email,
- mailfromd_timestr(timestamp, timebuf,
- sizeof timebuf),
- (long) diff);
- }
-
- if (diff < interval) {
- diff = interval - diff;
-
- MF_VAR_REF(greylist_seconds_left, diff);
-
- debug2(20, "%s still greylisted (for %lu sec.)",
- email,
- (unsigned long) diff);
- rc = 1;
- } else if (diff > greylist_format->expire_interval) {
- debug1(20, "greylist record for %s expired",
- email);
- if (!readonly) {
- memcpy(MU_DATUM_PTR(contents),
- &now, sizeof now);
- if (mu_dbm_insert(&db, key, contents, 1))
- mu_error(_("Cannot insert datum `%-.*s' in "
- "greylist database %s: %s"),
- MU_DATUM_SIZE(key),
- (char*)MU_DATUM_PTR(key),
- greylist_format->dbname,
- mu_dbm_strerror());
- } else
- debug(20, "database opened in readonly mode: "
- "not updating");
- rc = 1;
- } else {
- debug1(20, "%s finished greylisting period",
- email);
- rc = 0;
- }
- mu_dbm_datum_free(&contents);
- } else if (!readonly) {
- debug1(20, "greylisting %s", email);
- MF_VAR_REF(greylist_seconds_left, interval);
- MU_DATUM_PTR(contents) = (void*)&now;
- MU_DATUM_SIZE(contents) = sizeof now;
- if (mu_dbm_insert(&db, key, contents, 1))
- mu_error(_("Cannot insert datum `%-.*s' in greylist "
- "database %s: %s"),
- MU_DATUM_SIZE(key), (char*)MU_DATUM_PTR(key),
- greylist_format->dbname,
- mu_dbm_strerror());
- rc = 1;
- } else
- rc = 0;
-
- mu_dbm_close(&db);
-
- MF_RETURN(rc);
-}
-END
-
-MF_DEFUN(db_name, STRING, STRING fmtid)
-{
- struct db_format *fmt = db_format_lookup(fmtid);
- MF_ASSERT(fmt != NULL,
- mf_not_found,
- _("No such db format: %s"), fmtid);
- MF_RETURN_STRING(fmt->dbname);
-}
-END
-
-MF_DEFUN(db_get_active, NUMBER, STRING fmtid)
-{
- struct db_format *fmt = db_format_lookup(fmtid);
- MF_ASSERT(fmt != NULL,
- mf_not_found,
- _("No such db format: %s"), fmtid);
- MF_RETURN(fmt->enabled);
-}
-END
-
-MF_DEFUN(db_set_active, VOID, STRING fmtid, NUMBER active)
-{
- struct db_format *fmt = db_format_lookup(fmtid);
- MF_ASSERT(fmt != NULL,
- mf_not_found,
- _("No such db format: %s"), fmtid);
- fmt->enabled = active;
-}
-END
-
-MF_DEFUN(db_expire_interval, NUMBER, STRING fmtid)
-{
- struct db_format *fmt = db_format_lookup(fmtid);
- MF_ASSERT(fmt != NULL,
- mf_not_found,
- _("No such db format: %s"), fmtid);
- MF_RETURN(fmt->expire_interval);
-}
-END
-
-MF_INIT
-
diff --git a/src/bi_dns.m4 b/src/bi_dns.m4
deleted file mode 100644
index 7e92c964..00000000
--- a/src/bi_dns.m4
+++ /dev/null
@@ -1,297 +0,0 @@
-/* This file is part of mailfromd. -*- c -*-
- Copyright (C) 2006, 2007 Sergey Poznyakoff
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netdb.h>
-#include <arpa/inet.h>
-
-MF_DEFUN(primitive_hostname, STRING, STRING string)
-{
- char *hbuf;
- mf_status stat;
-
- stat = resolve_ipstr(string, &hbuf);
- MF_ASSERT(stat == mf_success,
- stat,
- _("Cannot resolve IP %s"),
- string);
-
- pushs(env, hbuf);
- free(hbuf);
-}
-END
-
-MF_DEFUN(primitive_resolve, STRING, STRING string, OPTIONAL, STRING domain)
-{
- char *ipstr;
- mf_status stat;
-
- if (MF_OPTVAL(domain,"")[0]) {
- stat = resolve_ipstr_domain(string, domain, &ipstr);
- MF_ASSERT(stat == mf_success,
- stat,
- _("Cannot resolve %s.%s"), string, domain);
- } else {
- stat = resolve_hostname(string, &ipstr);
- MF_ASSERT(stat == mf_success,
- stat,
- _("Cannot resolve %s"), string);
- }
- pushs(env, ipstr);
- free(ipstr);
-}
-END
-
-static int
-ipaddr_cmp(const void *a, const void *b)
-{
- GACOPYZ_UINT32_T ipa = ntohl(*(GACOPYZ_UINT32_T*)a);
- GACOPYZ_UINT32_T ipb = ntohl(*(GACOPYZ_UINT32_T*)b);
- if (ipa < ipb)
- return -1;
- if (ipa > ipb)
- return 1;
- return 0;
-}
-
-MF_DEFUN(dns_getaddr, STRING, STRING string)
-{
- GACOPYZ_UINT32_T ipbuf[64]; /* FIXME: arbitrary limit */
- size_t i, ipcount;
- unsigned long ttl;
- dns_status dnstat;
-
- dnstat = a_lookup(string, ipbuf, NELEMS(ipbuf), &ipcount,
- &ttl, NULL, 0);
- switch (dnstat) {
- case dns_success: {
- MF_OBSTACK_BEGIN();
- qsort(ipbuf, ipcount, sizeof ipbuf[0], ipaddr_cmp);
- for (i = 0; i < ipcount; i++) {
- struct in_addr addr;
- char *q;
-
- addr.s_addr = ipbuf[i];
- q = inet_ntoa(addr);
- if (i > 0)
- MF_OBSTACK_1GROW(' ');
- MF_OBSTACK_GROW(q);
- }
- MF_OBSTACK_1GROW(0);
- MF_RETURN_OBSTACK();
- }
- case dns_not_found:
- MF_RETURN_STRING("");
- default:
- MF_THROW(dns_to_mf_status(dnstat),
- _("Failed to get A record for %s"), string);
- }
-}
-END
-
-static int
-hostname_cmp(const void *a, const void *b)
-{
- return strcmp(*(const char**) a, *(const char**) b);
-}
-
-MF_DEFUN(dns_getname, STRING, STRING ipstr)
-{
- dns_status dnstat;
- struct in_addr addr;
- unsigned long ttl;
- char *names[64];
-
- MF_ASSERT(inet_aton(ipstr, &addr),
- mf_invip,
- _("Invalid IP: %s"), ipstr);
-
- dnstat = ptr_lookup(addr, names, NELEMS(names), &ttl, NULL, 0);
- switch (dnstat) {
- case dns_success: {
- size_t i;
- size_t ncount;
-
- for (ncount = 0; ncount < NELEMS(names) && names[ncount];
- ncount++);
-
- qsort(names, ncount, sizeof names[0], hostname_cmp);
-
- for (i = 0; i < ncount; i++) {
- if (i > 0)
- MF_OBSTACK_1GROW(' ');
- MF_OBSTACK_GROW(names[i]);
- }
- MF_OBSTACK_1GROW(0);
-
- for (; i < ncount; i++)
- free(names[i]);
-
- MF_RETURN_OBSTACK();
- }
- case dns_not_found:
- MF_RETURN_STRING("");
- default:
- MF_THROW(dns_to_mf_status(dnstat),
- _("Failed to get PTR record for %s"), ipstr);
- }
-}
-END
-
-MF_DEFUN(primitive_hasmx, NUMBER, STRING string)
-{
- mxbuf_t mxbuf;
- mf_status mxstat;
-
- mxstat = getmx(string, mxbuf);
-
- MF_ASSERT(mxstat == mf_success || mxstat == mf_not_found,
- mxstat,
- _("Cannot get MX records for %s"),
- string);
-
- if (mxstat == mf_success) {
- dns_freemx(mxbuf);
- MF_RETURN(1);
- }
- MF_RETURN(0);
-}
-END
-
-MF_DEFUN(getmx, STRING, STRING domain, OPTIONAL, NUMBER resolve)
-{
- mxbuf_t mxbuf;
- mf_status mxstat;
-
- if (MF_OPTVAL(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;
-
- MF_OBSTACK_BEGIN();
- for (i = 0; i < MAXMXCOUNT && mxbuf[i]; i++) {
- if (i > 0)
- MF_OBSTACK_1GROW(' ');
- MF_OBSTACK_GROW(mxbuf[i]);
- }
- MF_OBSTACK_1GROW(0);
- dns_freemx(mxbuf);
- MF_RETURN_OBSTACK();
- }
-}
-END
-
-static int
-resolve_host(const char *string, unsigned long *ip)
-{
- int rc;
- struct in_addr addr;
- char *ipstr;
-
- if (inet_aton(string, &addr)) {
- *ip = addr.s_addr;
- return 0;
- }
-
- if (resolve_hostname(string, &ipstr) != mf_success)
- return 1;
-
- rc = inet_aton(ipstr, &addr);
- free(ipstr);
- if (rc == 0) {
- mu_error(_("INTERNAL ERROR at %s:%lu: resolve_hostname returned "
- "invalid IP address: %s"),
- __FILE__, __FILE__, ipstr);
- return 1;
- }
- *ip = addr.s_addr;
- return 0;
-}
-