diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2007-11-21 18:11:59 +0000 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2007-11-21 18:11:59 +0000 |
commit | 1bbc73988e4669ad338c9434ebefcc80e08a69a5 (patch) | |
tree | 3adcfe8a9a39f900889ebd7723d8b280c842a06c | |
parent | a54d77908064d87a7e9439445baff7dfa17b1e79 (diff) | |
download | mailfromd-1bbc73988e4669ad338c9434ebefcc80e08a69a5.tar.gz mailfromd-1bbc73988e4669ad338c9434ebefcc80e08a69a5.tar.bz2 |
* 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.
* mflib/Makefile.am (inc_DATA): Add sieve.mfh.
* configure.ac: Set patchlevel 90.
(AM_GNU_MAILUTILS): Request 'all' and 'sieve' link flags.
* doc/mailfromd.texi: Document 3rd argument of write.
* NEWS: Update.
git-svn-id: file:///svnroot/mailfromd/trunk@1530 7a8a7f39-df28-0410-adc6-e0d955640f24
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | NEWS | 23 | ||||
-rw-r--r-- | configure.ac | 4 | ||||
-rw-r--r-- | doc/mailfromd.texi | 6 | ||||
-rw-r--r-- | mflib/Makefile.am | 1 | ||||
-rw-r--r-- | mflib/sieve.mfh | 24 | ||||
-rw-r--r-- | src/Makefile.am | 1 | ||||
-rw-r--r-- | src/bi_io.m4 | 7 | ||||
-rw-r--r-- | src/bi_sa.m4 | 3 | ||||
-rw-r--r-- | src/bi_sieve.m4 | 178 | ||||
-rw-r--r-- | src/mailfromd.h | 1 | ||||
-rw-r--r-- | src/main.c | 2 | ||||
-rw-r--r-- | src/mtasim.c | 5 |
13 files changed, 250 insertions, 10 deletions
@@ -1,3 +1,8 @@ +2007-11-21 Sergey Poznyakoff <gray@gnu.org.ua> + + * src/bi_io.m4 (write): Implement optional third argument. + + 2007-11-19 Sergey Poznyakoff <gray@gnu.org.ua> * README-alpha: Update @@ -1,10 +1,31 @@ -Mailfromd NEWS -- history of user-visible changes. 2007-10-23 +Mailfromd NEWS -- history of user-visible changes. 2007-11-21 Copyright (C) 2005, 2006, 2007 Sergey Poznyakoff See the end of file for copying conditions. Please send mailfromd bug reports to <bug-mailfromd@gnu.org.ua> +Version 4.2.90 (SVN) + +* write built-in + +The `write' built-in function takes an optional third argument, +specifying the number of bytes to write. This form is particualry +useful in `body' handler for writing $1, because it is not null- +terminated, e.g.: + +prog body +do + write(fd, $1, $2) + ... +done + +* sieve + +New built-in function `sieve' provides an interface to Sieve +interpreter. + + Version 4.2, 2007-10-23 * Licensed under the GPLv3 diff --git a/configure.ac b/configure.ac index cef20881..12f50008 100644 --- a/configure.ac +++ b/configure.ac @@ -17,7 +17,7 @@ AC_PREREQ(2.59) m4_define([MF_VERSION_MAJOR], 4) m4_define([MF_VERSION_MINOR], 2) -dnl m4_define([MF_VERSION_PATCH], 0) +m4_define([MF_VERSION_PATCH], 90) AC_INIT([mailfromd], MF_VERSION_MAJOR.MF_VERSION_MINOR[]m4_ifdef([MF_VERSION_PATCH],.MF_VERSION_PATCH), [bug-mailfromd@gnu.org.ua]) @@ -85,7 +85,7 @@ extern char *strtok_r (char *s, const char *delim, char **save_ptr); ]) # Check for GNU Mailutils -AM_GNU_MAILUTILS(1.0, [auth mailer cfg argp], [:]) +AM_GNU_MAILUTILS(1.0, [all sieve cfg argp], [:]) save_LIBS=$LIBS LIBS="$LIBS $MAILUTILS_LIBS" diff --git a/doc/mailfromd.texi b/doc/mailfromd.texi index 33d6b208..b583341d 100644 --- a/doc/mailfromd.texi +++ b/doc/mailfromd.texi @@ -6375,8 +6375,10 @@ termination of the filtering program. The following functions provide basic read/write capabilities. -@deftypefn {Built-in Function} void write (number @var{rd}, string @var{str}) - Writes the string @var{str} to the resource descriptor @var{rd}. +@deftypefn {Built-in Function} void write (number @var{rd}, string @var{str} @ + [, number @var{size}]) + Writes the string @var{str} to the resource descriptor @var{rd}. If +the @var{size} argument is given, writes this number of bytes. The function will signal @code{range} exception if @var{rd} lies outside of allowed range of resource descriptors, and @code{ioerr} diff --git a/mflib/Makefile.am b/mflib/Makefile.am index e2130ee4..38c191f4 100644 --- a/mflib/Makefile.am +++ b/mflib/Makefile.am @@ -25,6 +25,7 @@ inc_DATA =\ match_rhsbl.mf\ revip.mf\ safedb.mf\ + sieve.mfh\ spf.mf\ strip_domain_part.mf\ valid_domain.mf\ diff --git a/mflib/sieve.mfh b/mflib/sieve.mfh new file mode 100644 index 00000000..03caa180 --- /dev/null +++ b/mflib/sieve.mfh @@ -0,0 +1,24 @@ +/* Constants for sieve interface. + Copyright (C) 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/>. */ + +/* FIXME: These are duplicated in src/bi_sieve.m4. This file should be + generated automatically. */ + +const MF_SIEVE_LOG 0x01 +const MF_SIEVE_DEBUG_TRACE 0x02 +const MF_SIEVE_DEBUG_INSTR 0x04 +const MF_SIEVE_DEBUG_MAILUTILS 0x08 +const MF_SIEVE_DEBUG_PROT 0x10 diff --git a/src/Makefile.am b/src/Makefile.am index ea504d53..eb7efed5 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -29,6 +29,7 @@ M4_FILES=\ bi_mail.m4\ bi_poll.m4\ bi_sa.m4\ + bi_sieve.m4\ bi_spf.m4\ bi_sprintf.m4\ bi_string.m4\ diff --git a/src/bi_io.m4 b/src/bi_io.m4 index d660ca64..17303a92 100644 --- a/src/bi_io.m4 +++ b/src/bi_io.m4 @@ -275,17 +275,16 @@ MF_DEFUN(close, VOID, NUMBER fd) } END -MF_DEFUN(write, VOID, NUMBER fd, STRING str) +MF_DEFUN(write, VOID, NUMBER fd, STRING str, OPTIONAL, NUMBER n) { struct io_stream *iotab = MF_GET_DATA; - int n, rc; + int rc; debug2(10, "writing %s to %d", str, fd); MF_ASSERT(fd >= 0 && fd < NSTREAMS && OFD(iotab[fd]), mf_range, _("Invalid file descriptor")); - n = strlen(str); - rc = write(OFD(iotab[fd]), str, n); + rc = write(OFD(iotab[fd]), str, MF_OPTVAL(n, strlen (str))); MF_ASSERT(n == rc, mf_ioerr, _("Write error on %s: %s"), diff --git a/src/bi_sa.m4 b/src/bi_sa.m4 index 3f14adbc..3bd5cad1 100644 --- a/src/bi_sa.m4 +++ b/src/bi_sa.m4 @@ -27,6 +27,9 @@ MF_VAR(sa_threshold, NUMBER); MF_VAR(sa_keywords, STRING); MF_VAR(clamav_virus_name, STRING); +/* FIXME: Use socket_stream from the Mailutils when 1.3 (2.0?) stable is + out. +*/ static int spamd_connect_tcp(eval_environ_t env, mu_stream_t *stream, char *host, int port) diff --git a/src/bi_sieve.m4 b/src/bi_sieve.m4 new file mode 100644 index 00000000..d018f9ce --- /dev/null +++ b/src/bi_sieve.m4 @@ -0,0 +1,178 @@ +/* This file is part of mailfromd. -*- c -*- + Copyright (C) 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 <mailutils/mailutils.h> + +#define MF_SIEVE_LOG 0x01 +#define MF_SIEVE_DEBUG_TRACE 0x02 +#define MF_SIEVE_DEBUG_INSTR 0x04 +#define MF_SIEVE_DEBUG_MAILUTILS 0x08 +#define MF_SIEVE_DEBUG_PROT 0x10 + +static int +_mu_debug_printer (mu_debug_t unused, size_t level, const char *fmt, + va_list ap) +{ + vlogmsg((level == MU_DEBUG_ERROR) ? LOG_ERR : LOG_DEBUG, fmt, ap); + return 0; +} + +static int +_sieve_debug_printer (void *unused, const char *fmt, va_list ap) +{ + vlogmsg(LOG_DEBUG, fmt, ap); + return 0; +} + +static void +_sieve_action_log (void *unused, + const mu_sieve_locus_t *locus, size_t msgno, + mu_message_t msg, + const char *action, const char *fmt, va_list ap) +{ + logmsg(LOG_INFO, "%s:%lu: %s", + locus->source_file, (unsigned long) locus->source_line, + action); +} + +static int +_sieve_parse_error (void *unused, const char *filename, int lineno, + const char *fmt, va_list ap) +{ + if (filename) { + char *newfmt = NULL; + asprintf(&newfmt, "%s:%lu: %s", + filename, (unsigned long)lineno, fmt); + vlogmsg(LOG_ERR, newfmt, ap); + free(newfmt); + } else + vlogmsg(LOG_ERR, fmt, ap); +} + +/* FIXME (mailutils): Cannot use mu_stream_to_message because it ignores + envelope line */ +int +mf_stream_to_message(mu_stream_t stream, mu_message_t *msg) +{ + int rc; + mu_mailbox_t mbox; + char *buf = NULL; + size_t n; + + mu_stream_flush (stream); + rc = mu_mailbox_create (&mbox, "/dev/null"); + if (rc) + return rc; + rc = mu_mailbox_open (mbox, MU_STREAM_RDWR); + if (rc) + return rc; + mu_stream_seek(stream, 0, SEEK_SET); + rc = mu_mailbox_set_stream (mbox, stream); + if (rc) + return rc; + rc = mu_mailbox_messages_count (mbox, &n); + if (rc) + return rc; + return mu_mailbox_get_message (mbox, 1, msg); +} + + +MF_STATE(eom) +MF_CAPTURE +MF_DEFUN(sieve, NUMBER, STRING script, OPTIONAL, NUMBER dbg) +{ + mu_sieve_machine_t mach; + mu_debug_t mudebug = NULL; + int debug_flags = 0; /* FIXME: Init */ + int sieve_debug_flags = 0; + int sieve_log = 0; + int rc = mu_sieve_machine_init(&mach, NULL); + int retval = 0; + int f = MF_OPTVAL(dbg); + + MF_ASSERT(rc == 0, mf_failure, + _("Failed to initialize sieve machine: %s"), + mu_strerror(rc)); + + mu_sieve_set_debug(mach, _sieve_debug_printer); + + if (f) { + if (f & MF_SIEVE_DEBUG_TRACE) + sieve_debug_flags |= MU_SIEVE_DEBUG_TRACE; + if (f & MF_SIEVE_DEBUG_INSTR) + sieve_debug_flags |= MU_SIEVE_DEBUG_INSTR; + if (f & MF_SIEVE_DEBUG_MAILUTILS) + debug_flags |= MU_DEBUG_TRACE; + if (f & MF_SIEVE_DEBUG_PROT) + debug_flags |= MU_DEBUG_PROT; + if (f & MF_SIEVE_LOG) + sieve_log = 1; + } + + if (debug_flags) { + rc = mu_debug_create(&mudebug, NULL); + MF_ASSERT(rc == 0, mf_failure, + _("Cannot create debug object: %s"), + mu_strerror(rc)); + mu_debug_set_level(mudebug, debug_flags); + mu_debug_set_print(mudebug, _mu_debug_printer, NULL); + } + + mu_sieve_set_debug_level(mach, mudebug, sieve_debug_flags); + mu_sieve_set_parse_error(mach, _sieve_parse_error); + if (sieve_log) + mu_sieve_set_logger(mach, _sieve_action_log); + + rc = mu_sieve_compile(mach, script); + if (rc == 0){ + mu_stream_t mstr = env_get_stream(env); + mu_attribute_t attr; + mu_message_t msg; + + rc = mf_stream_to_message(mstr, &msg); + if (rc) { + mu_sieve_machine_destroy(&mach); + MF_THROW(mf_failure, + _("Cannot translate stream to message: %s"), + mu_strerror (rc)); + } + + mu_message_get_attribute(msg, &attr); + mu_attribute_unset_deleted(attr); + rc = mu_sieve_message(mach, msg); + if (rc == 0) + retval = !(mu_attribute_is_deleted(attr) == 0); + /*mu_message_destroy(&msg, mu_message_get_owner(msg));*/ + if (rc) { + mu_sieve_machine_destroy(&mach); + MF_THROW(mf_failure, + _("Sieving failed: %s"), + mu_strerror(rc)); + } + } else { + mu_sieve_machine_destroy(&mach); + MF_THROW(mf_failure, + _("Compilation of Sieve script %s failed"), + script); + } + + mu_sieve_machine_destroy(&mach); + + MF_RETURN(retval); +} +END + +MF_INIT diff --git a/src/mailfromd.h b/src/mailfromd.h index 97faceea..ff533745 100644 --- a/src/mailfromd.h +++ b/src/mailfromd.h @@ -781,6 +781,7 @@ void capture_on(void); const char *mailfromd_msgid(SMFICTX *ctx); char *mailfromd_timestr(time_t timestamp, char *timebuf, size_t bufsize); void logmsg(int prio, const char *fmt, ...); +void vlogmsg(int prio, const char *fmt, va_list ap); void log_status(sfsistat status, SMFICTX *ctx); void trace(const char *fmt, ...); int convert_rate(const char *arg, double *rate); @@ -1347,6 +1347,7 @@ parse_opt (int key, char *arg, struct argp_state *state) static const char *capa[] = { "auth", + "common", "logging", "mailer", NULL @@ -1770,6 +1771,7 @@ main(int argc, char **argv) #endif MU_AUTH_REGISTER_ALL_MODULES(); + mu_register_all_formats (); mu_register_all_mailer_formats(); if (!program_invocation_short_name) program_invocation_short_name = argv[0]; diff --git a/src/mtasim.c b/src/mtasim.c index 228e832f..3f6b398a 100644 --- a/src/mtasim.c +++ b/src/mtasim.c @@ -1556,11 +1556,14 @@ process_header (struct obstack *stk, size_t header_size, hv = strchr (hn, ':'); if (hv) { - int rc; + int rc, len; *hv++ = 0; while (*hv && isascii (*hv) && isspace (*hv)) hv++; + len = strlen (hv); + if (len > 0 && hv[len-1] == '\n') + hv[len - 1] = 0; rc = gacopyz_srv_header(gsrv, hn, hv); status = process_data_reply ("cmd", "header", rc, state, reply); } |