aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2015-04-18 08:04:50 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2015-04-18 08:04:50 +0300
commit0018c8d2531e93883441e8bddab87548f190e176 (patch)
treef97688b299a2f0e181a8b05edcbaf57611160d9e
parent37d3720edd2a052e7a0e8b180a0aa7a64355c95b (diff)
downloadmailman-0018c8d2531e93883441e8bddab87548f190e176.tar.gz
mailman-0018c8d2531e93883441e8bddab87548f190e176.tar.bz2
Rewrite sieve filter script
* Mailman/Handlers/Sieve.py: Rewrite using libmu_python * bin/mailsync: Change default location for configuration file. * man/mailsync.1: Update
-rw-r--r--Mailman/Handlers/Sieve.py96
-rwxr-xr-xbin/mailsync5
-rw-r--r--man/mailsync.113
3 files changed, 69 insertions, 45 deletions
diff --git a/Mailman/Handlers/Sieve.py b/Mailman/Handlers/Sieve.py
index 9b187a4..077f5ab 100644
--- a/Mailman/Handlers/Sieve.py
+++ b/Mailman/Handlers/Sieve.py
@@ -1,4 +1,3 @@
# GNU Mailutils -- a suite of utilities for electronic mail
-# Copyright (C) 1999, 2000, 2001, 2002, 2003,
-# 2005, 2006, 2007, 2008, 2014 Free Software Foundation, Inc.
+# Copyright (C) 1999-2015 Free Software Foundation, Inc.
#
@@ -15,21 +14,16 @@
# You should have received a copy of the GNU General Public License
-# along with GNU Mailutils; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
-# MA 02110-1301 USA
+# along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>.
-"""Filter message through GNU Sieve.
+"""Filter message through GNU Mailutils (sieve)."""
-Since there is no Mailutils module (yet), the sieve binary is invoked
-with `-f -' flag and the message is fed to it. If sieve exits successfully,
-the message is accepted. If it exits with code 1, which means the Sieve
-script used discard, the message is discarded. Otherwise, the message is
-held for approval.
-"""
-
-import string
import os
+import sys
+
+from email.MIMEMessage import MIMEMessage
+from email.MIMEText import MIMEText
-from subprocess import Popen,PIPE
from Mailman import mm_cfg
from Mailman import Errors
+from Mailman import Utils
+from Mailman import Message
from Mailman.Logging.Syslog import syslog
@@ -37,7 +31,7 @@ from Mailman.Handlers import Hold
-sieve_program = "/usr/local/bin/sieve"
-sieve_script_dir="/srv/mailman/sieve"
+from mailutils import stream, sieve
+from mailutils.error import SieveMachineError,MU_ERR_PARSE
class SieveDiscard(Errors.DiscardMessage):
- '''The message was discarded by Sieve'''
+ """The message was discarded by Sieve"""
reason = 'Sieve discarded this message'
@@ -46,29 +40,49 @@ class SieveDiscard(Errors.DiscardMessage):
class SieveHold(Errors.HoldMessage):
- '''The message was held due to Sieve error'''
- def __init__(self, retcode, err):
- Errors.HoldMessage.__init__(self)
- self.reason = 'Your message was held for moderation because of' \
- ' internal software error or misconfiguration.' \
- ' Please, report this to the list owner.'
+ """The message was held due to Sieve error"""
+ reason = 'Your message was held for moderation because of' \
+ ' internal software error or misconfiguration.' \
+ ' Please, report this to the list owner.'
-
def process(mlist, msg, msgdata):
- syslog("post", "begin")
if msgdata.get('approved'):
return
- script = sieve_script_dir + "/" + mlist.internal_name() + '.siv'
- syslog("post", "Using script file %s" % (script))
- if os.path.isfile(script):
- p = Popen([sieve_program, "--program-name", "mailman-sieve", "-f", "-", script], shell=False, stdin=PIPE,
- stdout=PIPE, stderr=PIPE)
- (out,err) = p.communicate(str(msg))
- if p.returncode != 0 and p.returncode != 1:
- syslog("post", "%s returned %d, error=%s"
- % (sieve_program, p.returncode, err))
- if p.returncode == 1:
- raise SieveDiscard
- elif p.returncode != 0:
- Hold.hold_for_approval(mlist, msg, msgdata,
- SieveHold(p.returncode, err))
+ scriptbasename = mlist.internal_name() + '.siv'
+ script = mm_cfg.SIEVE_SCRIPT_DIR + "/" + scriptbasename
+ if not os.path.isfile(script):
+ return
+ syslog("post", "Sieve is using script file %s" % script)
+
+ try:
+ mu_msg = stream.MemoryStream(str(msg)).to_message()
+ mu_sieve = sieve.Machine()
+ mu_sieve.compile(script)
+ mu_sieve.message(mu_msg)
+ except SieveMachineError, e:
+ lang = mlist.preferred_language
+ nmsg = Message.UserNotification(mlist.GetOwnerEmail(),
+ mlist.GetBouncesEmail(),
+ 'Sieve error notification',
+ lang=lang)
+ nmsg.set_type('multipart/mixed')
+ if e.status == MU_ERR_PARSE:
+ text = MIMEText(Utils.wrap('Sieve was unable to compile your script %s. The reason given was as follows:\n\n%s\n\nFor convenience, the failed script is attached herewith.' % (scriptbasename, e.strerror)),
+ charset=Utils.GetCharSet(lang))
+ else:
+ text = 'Sieve failed to execute script %s:\n\n %s.' % \
+ (script, e.strerror)
+ text = MIMEText(Utils.wrap(text),
+ charset=Utils.GetCharSet(lang))
+
+ nmsg.attach(text)
+ nmsg.attach(MIMEText(open(script, 'r').read()))
+
+ nmsg['X-Mailer'] = "Mailman Sieve Processor"
+ nmsg.send(mlist)
+
+ Hold.hold_for_approval(mlist, msg, msgdata, SieveHold)
+
+ except Exception, e:
+ Hold.hold_for_approval(mlist, msg, msgdata, SieveHold)
-
+ if mu_msg.attribute.is_deleted():
+ raise SieveDiscard
diff --git a/bin/mailsync b/bin/mailsync
index a3b7308..04b0f3b 100755
--- a/bin/mailsync
+++ b/bin/mailsync
@@ -261,3 +261,3 @@ OPTIONS are:
if __name__ == '__main__':
- config = '/etc/mailsync.conf'
+ config = ''
try:
@@ -284,2 +284,5 @@ if __name__ == '__main__':
+ if config == '':
+ config = os.path.abspath(os.path.dirname(sys.argv[0]) + '/../etc/mailsync.conf')
+
read_config(config)
diff --git a/man/mailsync.1 b/man/mailsync.1
index cbac3a2..0a68132 100644
--- a/man/mailsync.1
+++ b/man/mailsync.1
@@ -15,3 +15,3 @@
.\" along with this program. If not, see <http://www.gnu.org/licenses/>.
-.TH MAILSYNC 1 "April 9, 2015" "MAILSYNC"
+.TH MAILSYNC 1 "April 17, 2015" "MAILSYNC"
.SH NAME
@@ -35,4 +35,11 @@ for indexing.
.PP
-All necessary settings are defined in the configuration file
-\fB/etc/mailsync.conf\fR. Alternative location can be given using the
+All necessary settings are defined in the configuration file. By
+default, the program reads file \fBmailsync.conf\fR located in the
+directory \fBetc\fR one directory level up relative to the program
+itself. E.g. if the full pathname of the program is
+.BR /var/mailman/bin/mailsync ,
+then the configuration file is
+.BR /var/mailman/etc/mailsync.conf .
+.PP
+Alternative location can be given using the
\fB\-c\fR (\fB\-\-config\fR) command line option.

Return to:

Send suggestions and report system problems to the System administrator.