aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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
@@ -2,2 +2,9 @@
2 2
3 * src/main.c: Implement MU configuration statements.
4 * tests/atlocal.in (MFOPTS): Ignore site-wide and per-user
5 configuration files.
6 * doc/mailfromd.texi: Document sieve interface.
7
82007-11-22 Sergey Poznyakoff <gray@gnu.org.ua>
9
3 * doc/mailfromd.texi: Update 10 * doc/mailfromd.texi: Update
diff --git a/doc/mailfromd.texi b/doc/mailfromd.texi
index 731c4ae1..95c6741f 100644
--- a/doc/mailfromd.texi
+++ b/doc/mailfromd.texi
@@ -223,2 +223,3 @@ Built-in and Library Functions
223* System functions:: 223* System functions::
224* Sieve Interface::
224* Interfaces to Third-Party Programs:: 225* Interfaces to Third-Party Programs::
@@ -987,3 +988,2 @@ the corresponding section below.
987@cindex Upgrading from 4.1 to 4.2 988@cindex Upgrading from 4.1 to 4.2
988@UNREVISED{}
989 Upgrading to this version does not require any special efforts. You 989 Upgrading to this version does not require any special efforts. You
@@ -5260,2 +5260,3 @@ in version @value{VERSION}.
5260* System functions:: 5260* System functions::
5261* Sieve Interface::
5261* Interfaces to Third-Party Programs:: 5262* Interfaces to Third-Party Programs::
@@ -6479,4 +6480,97 @@ the return status of the command otherwise.
6479@end deftypefn 6480@end deftypefn
6480
6481 6481
6482@node Sieve Interface
6483@subsubsection Sieve Interface
6484@cindex Sieve
6485@UNREVISED{}
6486 @samp{Sieve} is a powerful mail filtering language, defined in
6487@acronym{RFC} 3028. @command{Mailfromd} supports an extended form
6488of this language. For description of the language and available
6489extensions, @xref{Sieve Language, Sieve Language, Sieve Language,
6490mailutils, GNU Mailutils Manual}.
6491
6492@deftypefn {Built-in Function} boolean sieve (string @var{script} @
6493 [, number @var{flags}])
6494Compile the Sieve source file @var{script} and execute it over the
6495collected message. This function can be used only in @code{eom}
6496handler.
6497
6498@findex sieve.mfh
6499Optional @var{flags} define additional debugging and verbosity
6500settings. It is a bit-mask field, consisting of a bitwise @code{or}
6501of one or more of the following flags, defined in @file{sieve.mfh}:
6502
6503@table @code
6504@item MF_SIEVE_LOG
6505Log every executed @samp{Sieve} action.
6506
6507@item MF_SIEVE_DEBUG_TRACE
6508Trace execution of @samp{Sieve} tests.
6509
6510@item MF_SIEVE_DEBUG_INSTR
6511Log every instruction, executed in the compiled @samp{Sieve} code.
6512This produces huge amounts of output and is rarely useful, unless you
6513suspect some bug in @samp{Sieve} implementation and wish to trace it.
6514
6515@item MF_SIEVE_DEBUG_MAILUTILS
6516Log debugging information about the underlying Mailutils calls.
6517
6518@item MF_SIEVE_DEBUG_PROT
6519Trace networking protocols.
6520@end table
6521
6522For example, @code{MF_SIEVE_LOG|MF_SIEVE_DEBUG_TRACE} enables logging
6523@samp{Sieve} actions and tests.
6524
6525The @code{sieve} function returns @code{true} if the message was
6526accepted by the @var{script} program, and @code{false} otherwise.
6527Here, the word @dfn{accepted} means that some form of @samp{KEEP}
6528action (@pxref{Actions, keep, Actions, mailutils, GNU Mailutils
6529Manual}) was executed over the message.
6530@end deftypefn
6531
6532The following example discards each message not accepted by the
6533@samp{Sieve} program @file{/etc/mail/filter.siv}:
6534
6535@smallexample
6536#include_once <sieve.mfh>
6537group eom
6538do
6539 if not sieve("/etc/mail/filter.siv", MF_SIEVE_LOG)
6540 discard
6541 fi
6542done
6543@end smallexample
6544
6545The example below illustrates how one can adjust logging flags
6546depending on the current debugging level:
6547
6548@smallexample
6549#include_once <sieve.mfh>
6550prog eom
6551do
6552 number flags 0
6553 number level debug_level("bi_sieve")
6554 if %level >= 1
6555 set flags %flags | MF_SIEVE_LOG
6556 fi
6557 if %level >= 2
6558 set flags %flags | MF_SIEVE_DEBUG_TRACE
6559 fi
6560 if %level > 9
6561 set flags %flags | MF_SIEVE_DEBUG_INSTR
6562 fi
6563 if %level > 19
6564 set flags %flags | MF_SIEVE_DEBUG_MAILUTILS
6565 fi
6566 if %level > 20
6567 set flags %flags | MF_SIEVE_DEBUG_PROT
6568 fi
6569
6570 if not sieve("/etc/mail/filter.siv", %flags)
6571 discard
6572 fi
6573done
6574@end smallexample
6575
6482@node Interfaces to Third-Party Programs 6576@node Interfaces to Third-Party Programs
diff --git a/src/main.c b/src/main.c
index 80c81226..3798ca3f 100644
--- a/src/main.c
+++ b/src/main.c
@@ -39,2 +39,6 @@
39# include <mailutils/argp.h> 39# include <mailutils/argp.h>
40typedef struct {
41 char *file;
42 int line;
43} mu_cfg_locus_t;
40#else 44#else
@@ -239,2 +243,17 @@ log_status(sfsistat status, SMFICTX *ctx)
239 243
244static void
245mf_error_on_locus(mu_cfg_locus_t *locus, const char *fmt, ...)
246{
247 va_list ap;
248
249 va_start(ap, fmt);
250 if (locus) {
251 char *newfmt = NULL;
252 asprintf(&newfmt, "%s:%d: %s", locus->file, locus->line, fmt);
253 mu_verror(newfmt, ap);
254 } else
255 mu_verror(fmt, ap);
256 va_end(ap);
257}
258
240 259
@@ -252,4 +271,4 @@ compare_string(const void *item, const void *value)
252 DOMAIN_LIST */ 271 DOMAIN_LIST */
253void 272int
254read_domain_file(char *name) 273read_domain_file(mu_cfg_locus_t *locus, char *name)
255{ 274{
@@ -261,5 +280,5 @@ read_domain_file(char *name)
261 if (!fp) { 280 if (!fp) {
262 mu_error(_("Cannot open file `%s': %s"), 281 mf_error_on_locus(locus, _("Cannot open file `%s': %s"),
263 name, mu_strerror(errno)); 282 name, mu_strerror(errno));
264 return; 283 return 1;
265 } 284 }
@@ -289,2 +308,3 @@ read_domain_file(char *name)
289 fclose(fp); 308 fclose(fp);
309 return 0;
290} 310}
@@ -329,2 +349,120 @@ host_in_relayed_domain_p(char *client)
329 349
350/* ************************************************************************
351 Configuration directives and options.
352
353 This is rather complicated. Mailfromd can take its configurable values
354 from the following locations (in that order):
355
356 1. From the mailutils configuration file suite, $sysconfdir/mailutils.rc
357 and/or any files included herein;
358 2. From #pragma statements in the filter script file,
359 $sysconfdir/mailfromd.rc;
360 3. From command line options;
361
362 Versions prior to 4.2.90 supported only [2] and [3]. Generally speaking,
363 [2] was needed because Mailutils versions prior to 1.2.90 lacked proper
364 configuration file support. With the advent of it, [2] became obsolete
365 and will probably be removed in some point in the future.
366
367 For the time being, however, I need to support all flavors of options,
368 because it is reasonable to assume that many of the installers still have
369 MU 1.2 or prior, with which [1] is not available.
370
371 Technically speaking, [1] is supported by mu_app_init, whenever compiled
372 with newer Mailutils, [2] is supported by the "option handling" code below,
373 and [3] is handled by argp machinery (called either from mu_app_init, for
374 MU >=1.2.90, or from mu_argp_parse, for older Mailutils versions).
375
376 There are some functions common to [1] and [2], these are defined in this
377 section.
378 ************************************************************************ */
379
380static int
381gid_comp(const void *item, const void *data)
382{
383 return (gid_t) item != (gid_t) data;
384}
385
386static int
387mf_option_group(mu_cfg_locus_t *locus, char *arg)
388{
389 struct group *group = getgrnam(arg);
390 if (group) {
391 if (!retain_groups) {
392 int rc = mu_list_create(&retain_groups);
393 if (rc) {
394 mf_error_on_locus(locus,
395 _("Cannot create list: %s"),
396 mu_strerror(rc));
397 return 1;
398 }
399 mu_list_set_comparator(retain_groups, gid_comp);
400 }
401 mu_list_append(retain_groups, (void*)group->gr_gid);
402 } else {
403 mf_error_on_locus(locus, _("Unknown group: %s"), arg);
404 return 1;