summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Mailman/Bouncers/BouncerAPI.py3
-rw-r--r--Mailman/Bouncers/GroupWise.py66
-rw-r--r--Mailman/Bouncers/SMTP32.py42
-rw-r--r--Mailman/Bouncers/SimpleMatch.py68
4 files changed, 179 insertions, 0 deletions
diff --git a/Mailman/Bouncers/BouncerAPI.py b/Mailman/Bouncers/BouncerAPI.py
index ecb6d206a..9ba39e2c6 100644
--- a/Mailman/Bouncers/BouncerAPI.py
+++ b/Mailman/Bouncers/BouncerAPI.py
@@ -48,6 +48,9 @@ def ScanMessages(mlist, msg, testing=0):
'Netscape',
'Compuserve',
'Microsoft',
+ 'GroupWise',
+ 'SMTP32',
+ 'SimpleMatch',
'Catchall',
]
for modname in pipeline:
diff --git a/Mailman/Bouncers/GroupWise.py b/Mailman/Bouncers/GroupWise.py
new file mode 100644
index 000000000..f5ab205c2
--- /dev/null
+++ b/Mailman/Bouncers/GroupWise.py
@@ -0,0 +1,66 @@
+# Copyright (C) 1998,1999,2000 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
+# as published by the Free Software Foundation; either version 2
+# of the License, 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, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+"""This appears to be the format for Novell GroupWise and NTMail
+
+X-Mailer: Novell GroupWise Internet Agent 5.5.3.1
+X-Mailer: NTMail v4.30.0012
+"""
+
+import string
+import re
+import mimetools
+import multifile
+
+from Mailman.pythonlib.StringIO import StringIO
+
+acre = re.compile(r'<(?P<addr>[^>]*)>')
+
+
+
+def process(msg):
+ if msg.gettype() <> 'multipart/mixed':
+ return None
+ addrs = {}
+ boundary = msg.getparam('boundary')
+ msg.rewindbody()
+ mfile = multifile.MultiFile(msg.fp)
+ try:
+ mfile.push(boundary)
+ while 1:
+ if not mfile.next():
+ return None
+ msg2 = mimetools.Message(StringIO(mfile.read()))
+ if msg2.gettype() == 'text/plain':
+ # Hmm, could there be more than one part per message?
+ break
+ msg2.rewindbody()
+ while 1:
+ line = string.strip(msg2.fp.readline())
+ if not line:
+ break
+ mo = acre.search(line)
+ if mo:
+ addrs[mo.group('addr')] = 1
+ elif '@' in line:
+ i = string.find(line, ' ')
+ if i < 0:
+ addrs[line] = 1
+ else:
+ addrs[line[:i]] = 1
+ except multifile.Error:
+ pass
+ return addrs.keys() or None
diff --git a/Mailman/Bouncers/SMTP32.py b/Mailman/Bouncers/SMTP32.py
new file mode 100644
index 000000000..ea9693ba7
--- /dev/null
+++ b/Mailman/Bouncers/SMTP32.py
@@ -0,0 +1,42 @@
+# Copyright (C) 1998,1999,2000 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
+# as published by the Free Software Foundation; either version 2
+# of the License, 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, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+"""Something which claims
+X-Mailer: <SMTP32 vXXXXXX>
+
+What the heck is this thing?
+"""
+
+import re
+
+ecre = re.compile('original message follows', re.IGNORECASE)
+acre = re.compile(r'user mailbox[^:]*:\s*(?P<addr>.*)', re.IGNORECASE)
+
+
+
+def process(msg):
+ msg.rewindbody()
+ addrs = {}
+ while 1:
+ line = msg.fp.readline()
+ if not line:
+ break
+ if ecre.search(line):
+ break
+ mo = acre.search(line)
+ if mo:
+ addrs[mo.group('addr')] = 1
+ return addrs.keys() or None
diff --git a/Mailman/Bouncers/SimpleMatch.py b/Mailman/Bouncers/SimpleMatch.py
new file mode 100644
index 000000000..675017df4
--- /dev/null
+++ b/Mailman/Bouncers/SimpleMatch.py
@@ -0,0 +1,68 @@
+# Copyright (C) 1998,1999,2000 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
+# as published by the Free Software Foundation; either version 2
+# of the License, 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, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+"""Recognizes simple heuristically delimited bounces."""
+
+import re
+
+def _c(pattern):
+ return re.compile(pattern, re.IGNORECASE)
+
+patterns = [
+ # sdm.de
+ (_c('here is your list of failed recipients'),
+ _c('here is your returned mail'),
+ _c(r'<(?P<addr>[^>]*)>')),
+ # sz-sb.de, corridor.com
+ (_c('the following addresses had'),
+ _c('transcript of session follows'),
+ _c(r'<(?P<addr>[^>]*)>')),
+ # robanal.demon.co.uk
+ (_c('this message was created automatically by mail delivery software'),
+ _c('original message follows'),
+ _c('rcpt to:\s*<(?P<addr>[^>]*)>')),
+ # s1.com (InterScan E-Mail VirusWall NT ???)
+ (_c('message from interscan e-mail viruswall nt'),
+ _c('end of message'),
+ _c('rcpt to:\s*<(?P<addr>[^>]*)>')),
+ ]
+
+
+
+
+def process(msg):
+ msg.rewindbody()
+ # simple state machine
+ # 0 = nothing seen yet
+ # 1 = intro seen
+ addrs = {}
+ state = 0
+ while 1:
+ line = msg.fp.readline()
+ if not line:
+ break
+ if state == 0:
+ for scre, ecre, acre in patterns:
+ if scre.search(line):
+ state = 1
+ break
+ elif state == 1:
+ mo = acre.search(line)
+ if mo:
+ addrs[mo.group('addr')] = 1
+ elif ecre.search(line):
+ break
+ return addrs.keys() or None