aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2007-11-22 12:23:06 +0000
committerSergey Poznyakoff <gray@gnu.org.ua>2007-11-22 12:23:06 +0000
commit080cc8f1c899f91f143694f3a3399a159239496b (patch)
tree8cd38a0e3c0c376a614a60312a9c2e80bae2b845
parent861696aa40909d5c11ab4876b716d48fef73a49d (diff)
downloadmailfromd-080cc8f1c899f91f143694f3a3399a159239496b.tar.gz
mailfromd-080cc8f1c899f91f143694f3a3399a159239496b.tar.bz2
* src/main.c: Implement MU configuration statements.
* tests/atlocal.in (MFOPTS): Ignore site-wide and per-user configuration files. * doc/mailfromd.texi: Document sieve interface. git-svn-id: file:///svnroot/mailfromd/trunk@1533 7a8a7f39-df28-0410-adc6-e0d955640f24
-rw-r--r--ChangeLog7
-rw-r--r--doc/mailfromd.texi98
-rw-r--r--src/main.c398
-rw-r--r--tests/atlocal.in2
4 files changed, 439 insertions, 66 deletions
diff --git a/ChangeLog b/ChangeLog
index 2fe622e9..08f55f73 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,14 +1,21 @@
2007-11-22 Sergey Poznyakoff <gray@gnu.org.ua>
+ * src/main.c: Implement MU configuration statements.
+ * tests/atlocal.in (MFOPTS): Ignore site-wide and per-user
+ configuration files.
+ * doc/mailfromd.texi: Document sieve interface.
+
+2007-11-22 Sergey Poznyakoff <gray@gnu.org.ua>
+
* doc/mailfromd.texi: Update
2007-11-21 Sergey Poznyakoff <gray@gnu.org.ua>
* src/bi_io.m4 (write): Implement optional third argument.
* src/bi_sieve.m4: New file.
* src/mailfromd.h (vlogmsg): New proto.
* src/main.c (capa): Request "common" capability.
(main): Register all mailbox formats (needed for sieve).
* src/Makefile.am (M4_FILES): Add bi_sieve.m4
* src/mtasim.c (process_header): chop trailing newline.
* mflib/sieve.mfh: New file.
diff --git a/doc/mailfromd.texi b/doc/mailfromd.texi
index 731c4ae1..95c6741f 100644
--- a/doc/mailfromd.texi
+++ b/doc/mailfromd.texi
@@ -212,24 +212,25 @@ Functions
Built-in and Library Functions
* String manipulation::
* String formatting::
* Mail header functions::
* Polling functions::
* Internet address manipulation functions::
* DNS functions::
* Database functions::
* I/O functions::
* System functions::
+* Sieve Interface::
* Interfaces to Third-Party Programs::
* Special test functions::
* Mail Sending Functions::
* NLS Functions::
* Debugging Functions::
* Blacklisting Functions::
* SPF Functions::
User-Defined Functions
* Some Useful Functions::
@@ -976,25 +977,24 @@ the corresponding section below.
@menu
* 410-420:: Upgrading from 4.1 to 4.2
* 400-410:: Upgrading from 4.0 to 4.1
* 31x-400:: Upgrading from 3.1.x to 4.0
* 30x-31x:: Upgrading from 3.0.x to 3.1
* 2x-30x:: Upgrading from 2.x to 3.0.x
* 1x-2x:: Upgrading from 1.x to 2.x
@end menu
@node 410-420
@section Upgrading from 4.1 to 4.2
@cindex Upgrading from 4.1 to 4.2
-@UNREVISED{}
Upgrading to this version does not require any special efforts. You
can use your configuration files and filter scripts without any
changes. The only difference worth noticing is that starting from this
version @command{mailfromd} is always compiled with asynchronous
syslog implementation. The @option{--enable-syslog-async}
configuration file option is still available, but its meaning has
changed: it sets the @emph{default} syslog implementation to use
(@pxref{syslog-async}). Thus, it can be used the same way it was in
previous versions. You can also select the syslog implementation at
run time, see @ref{Logging and Debugging, --syslog-async option}, for
more detailed information.
@@ -5249,24 +5249,25 @@ functions}.
in version @value{VERSION}.
@menu
* String manipulation::
* String formatting::
* Mail header functions::
* Polling functions::
* Internet address manipulation functions::
* DNS functions::
* Database functions::
* I/O functions::
* System functions::
+* Sieve Interface::
* Interfaces to Third-Party Programs::
* Special test functions::
* Mail Sending Functions::
* NLS Functions::
* Debugging Functions::
* Blacklisting Functions::
* SPF Functions::
@end menu
@node String manipulation
@subsubsection String Manipulation Functions
@deftypefn {Built-in Function} string domainpart (string @var{str})
@@ -6468,26 +6469,119 @@ strftime('%Y-%m-%d %H:%M:%S %Z', 1164477564)
@result{} 2006-11-25 19:59:24 EET
strftime('%Y-%m-%d %H:%M:%S %Z', 1164477564, 1)
@result{} 2006-11-25 17:59:24 GMT
@end group
@end smallexample
@end deftypefn
@deftypefn {Built-in Function} number system (string @var{str})
The function @code{system} executes a command specified in @var{str}
by calling @command{/bin/sh -c string}, and returns -1 on error or
the return status of the command otherwise.
@end deftypefn
-
+@node Sieve Interface
+@subsubsection Sieve Interface
+@cindex Sieve
+@UNREVISED{}
+ @samp{Sieve} is a powerful mail filtering language, defined in
+@acronym{RFC} 3028. @command{Mailfromd} supports an extended form
+of this language. For description of the language and available
+extensions, @xref{Sieve Language, Sieve Language, Sieve Language,
+mailutils, GNU Mailutils Manual}.
+
+@deftypefn {Built-in Function} boolean sieve (string @var{script} @
+ [, number @var{flags}])
+Compile the Sieve source file @var{script} and execute it over the
+collected message. This function can be used only in @code{eom}
+handler.
+
+@findex sieve.mfh
+Optional @var{flags} define additional debugging and verbosity
+settings. It is a bit-mask field, consisting of a bitwise @code{or}
+of one or more of the following flags, defined in @file{sieve.mfh}:
+
+@table @code
+@item MF_SIEVE_LOG
+Log every executed @samp{Sieve} action.
+
+@item MF_SIEVE_DEBUG_TRACE
+Trace execution of @samp{Sieve} tests.
+
+@item MF_SIEVE_DEBUG_INSTR
+Log every instruction, executed in the compiled @samp{Sieve} code.
+This produces huge amounts of output and is rarely useful, unless you
+suspect some bug in @samp{Sieve} implementation and wish to trace it.
+
+@item MF_SIEVE_DEBUG_MAILUTILS
+Log debugging information about the underlying Mailutils calls.
+
+@item MF_SIEVE_DEBUG_PROT
+Trace networking protocols.
+@end table
+
+For example, @code{MF_SIEVE_LOG|MF_SIEVE_DEBUG_TRACE} enables logging
+@samp{Sieve} actions and tests.
+
+The @code{sieve} function returns @code{true} if the message was
+accepted by the @var{script} program, and @code{false} otherwise.
+Here, the word @dfn{accepted} means that some form of @samp{KEEP}
+action (@pxref{Actions, keep, Actions, mailutils, GNU Mailutils
+Manual}) was executed over the message.
+@end deftypefn
+
+The following example discards each message not accepted by the
+@samp{Sieve} program @file{/etc/mail/filter.siv}:
+
+@smallexample
+#include_once <sieve.mfh>
+group eom
+do
+ if not sieve("/etc/mail/filter.siv", MF_SIEVE_LOG)
+ discard
+ fi
+done
+@end smallexample
+
+The example below illustrates how one can adjust logging flags
+depending on the current debugging level:
+
+@smallexample
+#include_once <sieve.mfh>
+prog eom
+do
+ number flags 0
+ number level debug_level("bi_sieve")
+ if %level >= 1
+ set flags %flags | MF_SIEVE_LOG
+ fi
+ if %level >= 2
+ set flags %flags | MF_SIEVE_DEBUG_TRACE
+ fi
+ if %level > 9
+ set flags %flags | MF_SIEVE_DEBUG_INSTR
+ fi
+ if %level > 19
+ set flags %flags | MF_SIEVE_DEBUG_MAILUTILS
+ fi
+ if %level > 20
+ set flags %flags | MF_SIEVE_DEBUG_PROT
+ fi
+
+ if not sieve("/etc/mail/filter.siv", %flags)
+ discard
+ fi
+done
+@end smallexample
+
@node Interfaces to Third-Party Programs
@subsubsection Interfaces to Third-Party Programs
A set of functions is defined for interfacing with other filters via
@acronym{TCP}. Currently implemented are interfaces with
@command{SpamAssassin} @command{spamd} daemon and with
@command{ClamAV} antivirus.
These functions can be used only in @code{eom} handler.
Both interfaces work much the same way: the remote filter is
connected and the message is passed to it. If the remote filter
diff --git a/src/main.c b/src/main.c
index 80c81226..3798ca3f 100644
--- a/src/main.c
+++ b/src/main.c
@@ -28,24 +28,28 @@
#include <syslog.h>
#include <signal.h>
#include <pwd.h>
#include <grp.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <mailutils/mailutils.h>
#if MAILUTILS_VERSION_NUMBER < 1290
# include <mailutils/argp.h>
+typedef struct {
+ char *file;
+ int line;
+} mu_cfg_locus_t;
#else
# include <mailutils/libargp.h>
#endif
#include "mailfromd.h"
#include "syslog_async.h"
/* Configurable options */
int mode = MAILFROMD_DAEMON; /* Default operation mode */
enum smtp_state test_state = smtp_state_envfrom; /* State for --test mode */
@@ -228,49 +232,64 @@ log_status(sfsistat status, SMFICTX *ctx)
if (lev >= 1 && status != SMFIS_CONTINUE) {
const char *str = sfsistat_str(status);
if (str)
logmsg(LOG_INFO,
"%s%s", mailfromd_msgid(ctx), str);
else
logmsg(LOG_INFO,
"%sstatus %d",
mailfromd_msgid(ctx), status);
}
}
+static void
+mf_error_on_locus(mu_cfg_locus_t *locus, const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ if (locus) {
+ char *newfmt = NULL;
+ asprintf(&newfmt, "%s:%d: %s", locus->file, locus->line, fmt);
+ mu_verror(newfmt, ap);
+ } else
+ mu_verror(fmt, ap);
+ va_end(ap);
+}
+
/* Sendmail class file support */
static mu_list_t domain_list;
int
compare_string(const void *item, const void *value)
{
return strcmp(item, value);
}
/* Read domains from sendmail-style domain file NAME and store them in
DOMAIN_LIST */
-void
-read_domain_file(char *name)
+int
+read_domain_file(mu_cfg_locus_t *locus, char *name)
{
FILE *fp;
char buf[256];
char *p;
fp = fopen(name, "r");
if (!fp) {
- mu_error(_("Cannot open file `%s': %s"),
- name, mu_strerror(errno));
- return;
+ mf_error_on_locus(locus, _("Cannot open file `%s': %s"),
+ name, mu_strerror(errno));
+ return 1;
}
if (!domain_list) {
mu_list_create(&domain_list);
mu_list_set_comparator(domain_list, compare_string);
}
while (p = fgets(buf, sizeof buf, fp)) {
char *q;
while (*p && isspace(*p))
p++;
@@ -278,24 +297,25 @@ read_domain_file(char *name)
continue;
for (q = p + strlen(p) - 1; q > p && isspace(*q); q--)
*q = 0;
if (*p == 0)
continue;
mu_list_append(domain_list, strdup(p));
}
fclose(fp);
+ return 0;
}
/* Return true if we relay domain NAME */
int
relayed_domain_p(char *name)
{
char *p = name;
while (p) {
if (mu_list_locate(domain_list, p, NULL) == 0) {
debug2(10,"%s is in relayed domain %s",
name, p);
@@ -318,24 +338,142 @@ host_in_relayed_domain_p(char *client)
if (mu_list_is_empty(domain_list))
return 0;
if (resolve_ipstr(client, &hbuf))
return 0;
rc = relayed_domain_p(hbuf);
free(hbuf);
return rc;
}
+/* ************************************************************************
+ Configuration directives and options.
+
+ This is rather complicated. Mailfromd can take its configurable values
+ from the following locations (in that order):
+
+ 1. From the mailutils configuration file suite, $sysconfdir/mailutils.rc
+ and/or any files included herein;
+ 2. From #pragma statements in the filter script file,
+ $sysconfdir/mailfromd.rc;
+ 3. From command line options;
+
+ Versions prior to 4.2.90 supported only [2] and [3]. Generally speaking,
+ [2] was needed because Mailutils versions prior to 1.2.90 lacked proper
+ configuration file support. With the advent of it, [2] became obsolete
+ and will probably be removed in some point in the future.
+
+ For the time being, however, I need to support all flavors of options,
+ because it is reasonable to assume that many of the installers still have
+ MU 1.2 or prior, with which [1] is not available.
+
+ Technically speaking, [1] is supported by mu_app_init, whenever compiled
+ with newer Mailutils, [2] is supported by the "option handling" code below,
+ and [3] is handled by argp machinery (called either from mu_app_init, for
+ MU >=1.2.90, or from mu_argp_parse, for older Mailutils versions).
+
+ There are some functions common to [1] and [2], these are defined in this
+ section.
+ ************************************************************************ */
+
+static int
+gid_comp(const void *item, const void *data)
+{
+ return (gid_t) item != (gid_t) data;
+}
+
+static int
+mf_option_group(mu_cfg_locus_t *locus, char *arg)
+{
+ struct group *group = getgrnam(arg);
+ if (group) {
+ if (!retain_groups) {
+ int rc = mu_list_create(&retain_groups);
+ if (rc) {
+ mf_error_on_locus(locus,
+ _("Cannot create list: %s"),
+ mu_strerror(rc));
+ return 1;
+ }
+ mu_list_set_comparator(retain_groups, gid_comp);
+ }
+ mu_list_append(retain_groups, (void*)group->gr_gid);
+ } else {
+ mf_error_on_locus(locus, _("Unknown group: %s"), arg);
+ return 1;
+ }
+ return 0;
+}
+
+static int
+mf_option_mailfrom(mu_cfg_locus_t *locus, char *arg)
+{
+ int rc;
+ mu_address_t addr;
+
+ rc = mu_address_create(&addr, arg);
+ if (rc) {
+ mf_error_on_locus(locus, _("Cannot create address `%s': %s"),
+ arg, mu_strerror(rc));
+ return 1;
+ }
+ mu_address_destroy(&addr);
+ defer_initialize_variable("mailfrom_address", arg);
+ return 0;
+}
+
+static int
+mf_option_state_directory(mu_cfg_locus_t *locus, char *arg)
+{
+ struct stat st;
+ if (stat(arg, &st)) {
+ mf_error_on_locus(locus, _("Cannot stat file `%s': %s"),
+ arg,
+ mu_strerror(errno));
+ return 1;
+ }
+ if (!S_ISDIR(st.st_mode)) {
+ mf_error_on_locus(locus, _("`%s' is not a directory"), arg);
+ return 1;
+ }
+ if (arg[0] != '/') {
+ mf_error_on_locus(locus,
+ _("State directory `%s' is not an absolute file name"),
+ arg);
+ return 1;
+ }
+ mailfromd_state_dir = xstrdup(arg);
+ return 0;
+}
+
+static int
+mf_option_source_ip(mu_cfg_locus_t *locus, char *arg, unsigned long *pval)
+{
+ unsigned long address = inet_addr(arg);
+ if (address == INADDR_NONE) {
+ struct hostent *phe = gethostbyname(arg);
+ if (!phe) {
+ mf_error_on_locus(locus, _("Cannot resolve `%s'"),
+ arg);
+ return 1;
+ }
+ address = *(((unsigned long **) phe->h_addr_list)[0]);
+ }
+ *pval = address;
+ return 0;
+}
+
+
/* Option handling.
There are two classes of options: those that can be set using #pragma
directive in the configuration file, and those that can be used only in
command line.
The latter are handled as usual. The former are processed in two stages:
first, upon processing command line, their command line settings are
verified and stored in struct option_cache below. Then, configuration
file is parsed. Any valid `#pragma option' directives found there overwrite
values in option_cache. Finally, process_options() is called that scans the
cache and actually sets any options found there. */
@@ -495,25 +633,25 @@ set_connect_timeout(void *value)
}
static void
set_response_timeout(void *value)
{
response_timeout = *(time_t*) value;
free(value);
}
static int
load_relay_file(void *item, void *data)
{
- read_domain_file(item);
+ read_domain_file(NULL, item);
return 0;
}
static void
set_relay(void *value)
{
mu_list_do(value, load_relay_file, NULL);
}
static void
set_source(void *value)
{
@@ -635,98 +773,51 @@ option_pidfile(char *opt, void **pval, char *newval)
static int
option_relay(char *opt, void **pval, char *newval)
{
if (!*pval)
mu_list_create((mu_list_t*)pval);
mu_list_append(*pval, strdup(newval));
return 0;
}
static int
option_source(char *opt, void **pval, char *newval)
{
- unsigned long address = inet_addr (newval);
- if (address == INADDR_NONE) {
- struct hostent *phe = gethostbyname (newval);
- if (!phe) {
- mu_error(_("Cannot resolve `%s'"), newval);
- return 1;
- }
- address = *(((unsigned long **) phe->h_addr_list)[0]);
- }
+ unsigned long address;
+
+ if (mf_option_source_ip(NULL, newval, &address))
+ return 1;
- if (*pval == 0) {
- *pval = malloc (sizeof address);
- if (!*pval)
- return 1;
- }
+ if (*pval == 0)
+ *pval = xmalloc (sizeof address);
*(unsigned long*)*pval = address;
return 0;
}
static int
-gid_comp(const void *item, const void *data)
-{
- return (gid_t) item != (gid_t) data;
-}
-
-static int
option_group(char *opt, void **pval, char *newval)
{
- struct group *group = getgrnam(newval);
- if (group) {
- if (!retain_groups) {
- int rc = mu_list_create(&retain_groups);
- if (rc) {
- mu_error(_("Cannot create list: %s"),
- mu_strerror(rc));
- return 1;
- }
- mu_list_set_comparator(retain_groups, gid_comp);
- }
- mu_list_append(retain_groups, (void*)group->gr_gid);
- } else {
- mu_error(_("Unknown group: %s"), newval);
- return 1;
- }
- return 0;
+ return mf_option_group(NULL, newval);
}
void
set_state_directory(void *value)
{
/* nothing */
}
int
option_state_directory(char *opt, void **pval, char *newval)
{
- struct stat st;
- if (stat(newval, &st)) {
- mu_error(_("Cannot stat file `%s': %s"),
- newval,
- mu_strerror(errno));
- return 1;
- }
- if (!S_ISDIR(st.st_mode)) {
- mu_error(_("`%s' is not a directory"), newval);
- return 1;
- }
- if (newval[0] != '/') {
- mu_error(_("State directory `%s' is not an absolute file name"),
- newval);
- return 1;
- }
- mailfromd_state_dir = xstrdup(newval);
- return 0;
+ return mf_option_state_directory(NULL, newval);
}
struct option_cache {
char *name;
void *value;
int (*handler)(char *opt, void **pval, char *newval);
void (*set)(void *value);
int cumulative;
} option_cache[] = {
{ "ehlo", NULL, option_ehlo, set_ehlo },
{ "debug", NULL, option_debug, set_debug },
{ "source-info", NULL, option_boolean, set_source_info },
@@ -1355,24 +1446,204 @@ static const char *capa[] = {
static struct argp argp = {
options,
parse_opt,
args_doc,
doc,
NULL,
NULL,
NULL
};
+/* Mailutils-2.0 configuration */
+#if MAILUTILS_VERSION_NUMBER >= 1290
+int
+cb_timeout(time_t *pinterval, mu_cfg_locus_t *locus, void *data, char *arg)
+{
+ const char *endp;
+ if (parse_time_interval(arg, pinterval, &endp)) {
+ mf_error_on_locus(locus,
+ _("unrecognized time format (near `%s')"),
+ endp);
+ return 1;
+ }
+ return 0;
+}
+
+int
+cb_milter_timeout(mu_cfg_locus_t *locus, void *data, char *arg)
+{
+ time_t interval;
+
+ if (cb_timeout(&interval, locus, data, arg))
+ return 1;
+ if (smfi_settimeout(interval) == MI_FAILURE) {
+ mf_error_on_locus(locus,
+ _("%s:%d: Invalid milter timeout: %lu"),
+ (unsigned long) interval);
+ exit(EX_USAGE);
+ }
+
+ return 0;
+}
+
+int
+cb_io_timeout(mu_cfg_locus_t *locus, void *data, char *arg)
+{
+ if (cb_timeout(&io_timeout, locus, data, arg))
+ return 1;
+ return 0;
+}
+
+int
+cb_connect_timeout(mu_cfg_locus_t *locus, void *data, char *arg)
+{
+ if (cb_timeout(&connect_timeout, locus, data, arg))
+ return 1;
+ return 0;
+}
+
+int
+cb_initial_response_timeout(mu_cfg_locus_t *locus, void *data, char *arg)
+{
+ if (cb_timeout(&response_timeout, locus, data, arg))
+ return 1;
+ return 0;
+}
+
+int
+cb_lock_retry_timeout(mu_cfg_locus_t *locus, void *data, char *arg)
+{
+ if (cb_timeout(&lock_retry_timeout_option, locus, data, arg))
+ return 1;
+ return 0;
+}
+
+int
+cb_set_variable(mu_cfg_locus_t *locus, void *data, char *arg)
+{
+ char *p, *value;
+ char *tmp = NULL;
+
+ for (p = arg; !(*p == ' ' || *p == '\t'); p++)
+ if (!*p) {
+ mf_error_on_locus(locus, _("missing value"));
+ return 1;
+ }
+
+ for (; *p == ' ' || *p == '\t'; p++)
+ if (!*p) {
+ mf_error_on_locus(locus, _("missing value"));
+ return 1;
+ }
+
+ if (*p == '"' || *p == '\'') {
+ size_t len = strlen(p) + 1;
+ tmp = xmalloc(len);
+ mu_argcv_unquote_copy(tmp, p, len);
+ value = tmp;
+ } else
+ value = p;
+
+ defer_initialize_variable(arg, value);
+ free(tmp);
+ return 0;
+}
+
+int
+cb_ehlo_domain(mu_cfg_locus_t *locus, void *data, char *arg)
+{
+ defer_initialize_variable("ehlo_domain", arg);
+ return 0;
+}
+
+int
+cb_mail_from_address(mu_cfg_locus_t *locus, void *data, char *arg)
+{
+ return mf_option_mailfrom(locus, arg);
+}
+
+int
+cb_debug(mu_cfg_locus_t *locus, void *data, char *arg)
+{
+ debug_parse_spec(arg);
+ return 0;
+}
+
+/* See also option_group. */
+int
+cb_group(mu_cfg_locus_t *locus, void *data, char *arg)
+{
+ return mf_option_group(locus, arg);
+}
+
+int
+cb_state_directory(mu_cfg_locus_t *locus, void *data, char *arg)
+{
+ return mf_option_state_directory(locus, arg);
+}
+
+int
+cb_relay_file(mu_cfg_locus_t *locus, void *data, char *arg)
+{
+ return read_domain_file(locus, arg);
+}
+
+int
+cb_source_ip(mu_cfg_locus_t *locus, void *data, char *arg)
+{
+ return mf_option_source_ip(locus, arg, &source_address);
+}
+
+int
+cb_include_path(mu_cfg_locus_t *locus, void *data, char *arg)
+{
+ char *p, *sp;
+
+ for (p = strtok_r(arg, ":", &sp); p; p = strtok_r(NULL, ":", &sp))
+ add_include_dir(p);
+ return 0;
+}
+
+/* Keep alphabetical ordering of statements */
+struct mu_cfg_param mf_cfg_param[] = {
+ { "connect-timeout", mu_cfg_callback, NULL, cb_connect_timeout },
+ { "debug", mu_cfg_callback, NULL, cb_debug },
+ { "ehlo-domain", mu_cfg_callback, NULL, cb_ehlo_domain },
+ { "group", mu_cfg_callback, NULL, cb_group },
+ { "include-path", mu_cfg_callback, NULL, cb_include_path },
+ { "initial-response-timeout", mu_cfg_callback, NULL,
+ cb_initial_response_timeout },
+ { "io-timeout", mu_cfg_callback, NULL, cb_io_timeout },
+ { "lock-retry-count", mu_cfg_size, &lock_retry_count_option },
+ { "lock-retry-timeout", mu_cfg_callback, NULL,
+ cb_lock_retry_timeout },
+ { "mail-from-address", mu_cfg_callback, NULL, cb_mail_from_address },
+ { "milter-timeout", mu_cfg_callback, NULL, cb_milter_timeout },
+ { "pidfile", mu_cfg_string, &pidfile },
+ { "relay-file", mu_cfg_callback, NULL, cb_relay_file },
+ { "setvar", mu_cfg_callback, NULL, cb_set_variable },
+ { "script-file", mu_cfg_string, &script_file },
+ { "source-info", mu_cfg_bool, &source_info_option },
+ /* FIXME: Could have used mu_cfg_ipv4 here, but... */
+ { "source-ip", mu_cfg_callback, NULL, cb_source_ip },
+ { "stack-trace", mu_cfg_bool, &stack_trace_option },
+ { "state-directory", mu_cfg_callback, NULL, cb_state_directory },
+ { "user", mu_cfg_string, &user },
+ { NULL }
+};
+#endif
+
+
/* Auxiliary functions */
/* Switch to the given UID/GID */
int
switch_to_privs(uid_t uid, gid_t gid)
{
int rc = 0;
gid_t *emptygidset;
size_t size = 1, j = 1;
mu_iterator_t itr;
if (uid == 0) {
@@ -1762,47 +2033,48 @@ main(int argc, char **argv)
{
int rc;
int index;
#ifdef ENABLE_NLS
mu_init_nls();
setlocale (LC_ALL, "");
bindtextdomain (PACKAGE, LOCALEDIR);
textdomain (PACKAGE);
#endif
MU_AUTH_REGISTER_ALL_MODULES();
- mu_register_all_formats ();
+ mu_register_all_formats();
mu_register_all_mailer_formats();
if (!program_invocation_short_name)
program_invocation_short_name = argv[0];
argp_program_version_hook = version;
yy_flex_debug = 0;
/* Set default logging */
log_facility = DEFAULT_LOG_FACILITY;
log_setup(!stderr_closed_p());
init_names();
init_string_space();
builtin_setup();
db_format_setup();
include_path_setup();
save_cmdline(argc, argv);
mu_argp_init(program_version, "<" PACKAGE_BUGREPORT ">");
#if MAILUTILS_VERSION_NUMBER < 1290
rc = mu_argp_parse(&argp, &argc, &argv, 0, capa, &index, NULL);
#else
- rc = mu_app_init(&argp, capa, NULL, argc, argv, 0, &index, NULL);
+ rc = mu_app_init(&argp, capa, mf_cfg_param, argc, argv, 0, &index,
+ NULL);
#endif
if (rc)
exit (EX_CONFIG);
log_setup(log_to_stderr);
argv += index;
argc -= index;
if (need_config) {
if (argc) {
int i, n = -1;
diff --git a/tests/atlocal.in b/tests/atlocal.in
index b4679606..6e19f90a 100644
--- a/tests/atlocal.in
+++ b/tests/atlocal.in
@@ -13,25 +13,25 @@ checkstatedir() {
mkdir $STATEDIR || exit 1
sed "s,STATEDIR,$STATEDIR," @abs_top_srcdir@/tests/etc/config.in > \
@abs_top_builddir@/tests/etc/config.rc
fi
}
cleanup() {
rm -rf $STATEDIR
}
trap "cleanup; test -r $XFAILFILE && cat $XFAILFILE; exit $?" 1 2 13 15
-MFOPTS="-I@abs_builddir@/etc -I@abs_top_srcdir@/tests/etc -I@abs_top_srcdir@/src -I@abs_top_srcdir@/mflib --no-preprocess"
+MFOPTS="-I@abs_builddir@/etc -I@abs_top_srcdir@/tests/etc -I@abs_top_srcdir@/src -I@abs_top_srcdir@/mflib --no-preprocess --no-site-rcfile --no-user-rcfile"
ETCDIR=@abs_top_srcdir@/tests/etc
PORT="unix:$STATEDIR/socket"
MTAOPTS="-X$PORT --stdio"
PIDFILE=$STATEDIR/pid
mailfromd_start() {
checkstatedir
mailfromd $MFOPTS \
--port=$PORT \
--pidfile=$PIDFILE \
--debug=100\

Return to:

Send suggestions and report system problems to the System administrator.