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
> 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 @@
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')