summaryrefslogtreecommitdiff
path: root/Mailman/Bouncers/Qmail.py
diff options
context:
space:
mode:
authorbwarsaw1999-12-09 23:59:58 +0000
committerbwarsaw1999-12-09 23:59:58 +0000
commit2c6f747e60f80ab0e1fd73c7ff1814f6ea19f711 (patch)
treeff0f176d7a8cc10a466b316bf968f5cbc8c1fdbd /Mailman/Bouncers/Qmail.py
parentb34a115136b8f201877ea239c33d7954cb9ff6c0 (diff)
downloadmailman-2c6f747e60f80ab0e1fd73c7ff1814f6ea19f711.tar.gz
mailman-2c6f747e60f80ab0e1fd73c7ff1814f6ea19f711.tar.zst
mailman-2c6f747e60f80ab0e1fd73c7ff1814f6ea19f711.zip
Diffstat (limited to 'Mailman/Bouncers/Qmail.py')
-rw-r--r--Mailman/Bouncers/Qmail.py59
1 files changed, 30 insertions, 29 deletions
diff --git a/Mailman/Bouncers/Qmail.py b/Mailman/Bouncers/Qmail.py
index 3ce2708bc..e1d678681 100644
--- a/Mailman/Bouncers/Qmail.py
+++ b/Mailman/Bouncers/Qmail.py
@@ -15,52 +15,53 @@
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
"""Parse bounce messages generated by qmail.
+
+Qmail actually has a standard, called QSBMF (qmail-send bounce message
+format), as described in
+
+ http://cr.yp.to/proto/qsbmf.txt
+
+This module should be conformant.
+
"""
import string
import re
-hcre = re.compile(r'\(qmail\s+\d+\s+invoked for bounce\)')
+introtag = 'Hi. This is the'
+
acre = re.compile(r'<(?P<addr>[^>]*)>:')
def process(mlist, msg):
- # there should be a received header that reveals that it's qmail bouncing
- # the message. don't rely on information in the body for this.
- headers = msg.getallmatchingheaders('received')
- for h in headers:
- try:
- hdr, val = string.split(h, ':', 1)
- except ValueError:
- continue
- if hcre.search(val):
- # probably a qmail bounce
- break
- else:
- # nope
- return None
- # the address is the first none blank line after qmail's "friendly"
- # message. hmm...
- # small state machine:
- # 0 = nothing seen
- # 1 = friendly comment seen
- # 2 = done with comment, addr must be next up
- state = 0
msg.rewindbody()
+ # simple state machine
+ # 0 = nothing seen yet
+ # 1 = intro paragraph seen
+ # 2 = recip paragraphs seen
+ state = 0
+ addrs = []
while 1:
line = msg.fp.readline()
if not line:
- # didn't find it
- return None
+ break
line = string.strip(line)
- if state == 0 and line:
+ if state == 0 and line[:len(introtag)] == introtag:
state = 1
elif state == 1 and not line:
state = 2
- elif state == 2 and line:
+ elif state == 2:
+ if line and line[0] == '-':
+ # we're looking at the break paragraph, so we're done
+ break
+ # At this point we know we must be looking at a recipient
+ # paragraph
mo = acre.match(line)
if mo:
- return [mo.group('addr')]
- # hmm, probably not a qmail bounce
- return None
+ addrs.append(mo.group('addr'))
+ # otherwise, it must be a continuation line, so just ignore it
+ # not looking at anything in particular
+ #
+ # we've parse everything we need to
+ return addrs or None