diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2015-04-18 08:04:50 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2015-04-18 08:04:50 +0300 |
commit | 0018c8d2531e93883441e8bddab87548f190e176 (patch) | |
tree | f97688b299a2f0e181a8b05edcbaf57611160d9e | |
parent | 37d3720edd2a052e7a0e8b180a0aa7a64355c95b (diff) | |
download | mailman-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.py | 96 | ||||
-rwxr-xr-x | bin/mailsync | 5 | ||||
-rw-r--r-- | man/mailsync.1 | 13 |
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. |