[Mailman-Developers] Looping digest - mailman bug?

Kaja P. Christiansen kaja@daimi.au.dk
Mon, 30 Jul 2001 19:09:47 +0200


On Wed, 20 Jun 2001 19:12:00 +0200, I wrote:

 > Last Monday, one of our mailing lists went mad and sent multiple copies 
 > of the same digest to the list's digest users.
 > [...]
 > The traceback in the errors log shows:
 >   Jun 19 00:01:01 2001 (18618) Traceback (innermost last):
 >     File "/usr/local/mailman203/Mailman/Handlers/HandlerAPI.py", line 82, in do_pipeline
 >       func(mlist, msg, msgdata)
 >     File "/usr/local/mailman203/Mailman/Handlers/Sendmail.py", line 86, in process
 >       fp.write(msgtext)
 >   IOError: [Errno 32] Broken pipe
 > We run Mailman 2.0.3 with Postfix. I addressed this problem earlier 
 > (March 26th), but there was no reply.

Several of our lists suffered from Mailman's mail bombing and we turned
the digest option off in hope it'll help. It did, for a while, until
the same happened with a non-digest message being send over and over again
(once per minute, by qrunner).

We were able to locate where and how it happens, and to 'reproduce' the 
error (in laboratory conditions :-) both under mailman 2.0.3 and 2.0.6.

The mail looping occurs when there is a MIME message with a single . (dot)
in a line; Mailman sends it to sendmail 'as is'. But since sendmail/postfix
interprets a line with single dot as the end of the message, it sends
everything before the dot and exits with 'Broken pipe'. Mailman, however,
still has the message in it's queue and sends it all over again...

When I tried sending non-MIME message with single-dot-line in it to a Mailman 
list, there was no looping, but the message body after the single dot was 

Until there is something better, I suggest adding to Sendmail.py a patch 
which perhaps is not pretty (it adds a space before the infamous dot), 
but it works:

--- ./Mailman/Handlers/Sendmail.py.orig	Fri Jul 27 13:40:31 2001
+++ ./Mailman/Handlers/Sendmail.py	Fri Jul 27 14:11:46 2001
@@ -31,6 +31,7 @@
 import string
 import os
+import re
 import HandlerAPI
 from Mailman import mm_cfg
@@ -80,6 +81,8 @@
     msgtext = str(msg)
     # cycle through all chunks
     failedrecips = []
+    bar = re.compile('\n\.')
+    msgtext = re.sub(bar, '\n .', msgtext, 0)
     for chunk in recipchunks:
         # TBD: SECURITY ALERT.  This invokes the shell!
         fp = os.popen(cmd + chunk, 'w')