summaryrefslogtreecommitdiff
path: root/Mailman/Bouncers/Postfix.py
diff options
context:
space:
mode:
authorbwarsaw2001-02-15 03:49:40 +0000
committerbwarsaw2001-02-15 03:49:40 +0000
commitb23aba751bdd33faeb409867783e96510b57637d (patch)
tree3803ffdfc49bf3c839f242206802e42ca14e57d6 /Mailman/Bouncers/Postfix.py
parent2092282e4f9ec91b2e3a45936566474e88d5a602 (diff)
downloadmailman-b23aba751bdd33faeb409867783e96510b57637d.tar.gz
mailman-b23aba751bdd33faeb409867783e96510b57637d.tar.zst
mailman-b23aba751bdd33faeb409867783e96510b57637d.zip
Diffstat (limited to 'Mailman/Bouncers/Postfix.py')
-rw-r--r--Mailman/Bouncers/Postfix.py67
1 files changed, 29 insertions, 38 deletions
diff --git a/Mailman/Bouncers/Postfix.py b/Mailman/Bouncers/Postfix.py
index 61993d76a..1a261ab7e 100644
--- a/Mailman/Bouncers/Postfix.py
+++ b/Mailman/Bouncers/Postfix.py
@@ -1,4 +1,4 @@
-# Copyright (C) 1998,1999,2000 by the Free Software Foundation, Inc.
+# Copyright (C) 1998,1999,2000,2001 by the Free Software Foundation, Inc.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
@@ -17,44 +17,18 @@
"""Parse bounce messages generated by Postfix."""
-import string
import re
-import multifile
-import mimetools
-
from Mailman.pythonlib.StringIO import StringIO
-def process(msg):
- if msg.gettype() <> 'multipart/mixed':
- return None
- boundary = msg.getparam('boundary')
- msg.fp.seek(0)
- mfile = multifile.MultiFile(msg.fp)
- mfile.push(boundary)
- # find the subpart with message/delivery-status information
- while 1:
- try:
- more = mfile.next()
- except multifile.Error:
- # looked like a multipart, but really wasn't
- return None
- if not more:
- # we didn't find it
- return None
- try:
- s = StringIO(mfile.read())
- except multifile.Error:
- # It is a mis-formated or incomplete message
- return None
- msg2 = mimetools.Message(s)
- if msg2.gettype() == 'text/plain':
- desc = msg2.get('content-description')
- if desc and string.lower(desc) == 'notification':
- return findaddr(msg2.fp)
- # probably not a Postfix bounce
- return None
+def flatten(msg, leaves):
+ # give us all the leaf (non-multipart) subparts
+ if msg.ismultipart():
+ for part in msg.get_payload():
+ flatten(part, leaves)
+ else:
+ leaves.append(msg)
@@ -63,18 +37,19 @@ pcre = re.compile(r'\t\t\tthe postfix program$', re.IGNORECASE)
rcre = re.compile(r'failure reason:$', re.IGNORECASE)
acre = re.compile(r'<(?P<addr>[^>]*)>:')
-def findaddr(fp):
+def findaddr(msg):
addrs = []
+ body = StringIO(msg.get_payload())
# simple state machine
# 0 == nothing found
# 1 == salutation found
state = 0
while 1:
- line = fp.readline()
+ line = body.readline()
if not line:
break
# preserve leading whitespace
- line = string.rstrip(line)
+ line = line.rstrip()
# yes use match to match at beginning of string
if state == 0 and (pcre.match(line) or rcre.match(line)):
state = 1
@@ -83,4 +58,20 @@ def findaddr(fp):
if mo:
addrs.append(mo.group('addr'))
# probably a continuation line
- return addrs or None
+ return addrs
+
+
+
+def process(msg):
+ if msg.gettype() <> 'multipart/mixed':
+ return None
+ # We're looking for the plain/text subpart with a Content-Description: of
+ # `notification'.
+ leaves = []
+ flatten(msg, leaves)
+ for subpart in leaves:
+ if subpart.gettype() == 'text/plain' and \
+ subpart.get('content-description', '').lower() == 'notification':
+ # then...
+ return findaddr(subpart)
+ return None