diff options
Diffstat (limited to 'Mailman/Queue')
-rw-r--r-- | Mailman/Queue/BounceRunner.py | 15 | ||||
-rw-r--r-- | Mailman/Queue/CommandRunner.py | 31 | ||||
-rw-r--r-- | Mailman/Queue/IncomingRunner.py | 24 | ||||
-rw-r--r-- | Mailman/Queue/NewsRunner.py | 22 | ||||
-rwxr-xr-x[-rw-r--r--] | Mailman/Queue/OutgoingRunner.py | 3 | ||||
-rw-r--r-- | Mailman/Queue/Switchboard.py | 6 |
6 files changed, 68 insertions, 33 deletions
diff --git a/Mailman/Queue/BounceRunner.py b/Mailman/Queue/BounceRunner.py index d219d6e9..651039d6 100644 --- a/Mailman/Queue/BounceRunner.py +++ b/Mailman/Queue/BounceRunner.py @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2008 by the Free Software Foundation, Inc. +# Copyright (C) 2001-2015 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 @@ -30,6 +30,7 @@ from Mailman import mm_cfg from Mailman import Utils from Mailman import LockFile from Mailman.Message import UserNotification +from Mailman.Bouncer import _BounceInfo from Mailman.Bouncers import BouncerAPI from Mailman.Queue.Runner import Runner from Mailman.Queue.sbcache import get_switchboard @@ -151,6 +152,14 @@ class BounceMixin: try: op, addr, bmsg = mlist.pend_confirm(token) info = mlist.getBounceInfo(addr) + if not info: + # info was deleted before probe bounce was received. + # Just create a new info. + info = _BounceInfo(addr, + 0.0, + time.localtime()[:3], + mlist.bounce_you_are_disabled_warnings + ) mlist.disableBouncingMember(addr, info, bmsg) # Only save the list if we're unlocking it if not locked: @@ -244,6 +253,7 @@ class BounceRunner(Runner, BounceMixin): return # If that still didn't return us any useful addresses, then send it on # or discard it. + addrs = filter(None, addrs) if not addrs: syslog('bounce', '%s: bounce message w/no discernable addresses: %s', @@ -254,7 +264,8 @@ class BounceRunner(Runner, BounceMixin): # BAW: It's possible that there are None's in the list of addresses, # although I'm unsure how that could happen. Possibly ScanMessages() # can let None's sneak through. In any event, this will kill them. - addrs = filter(None, addrs) + # addrs = filter(None, addrs) + # MAS above filter moved up so we don't try to queue an empty list. self._queue_bounces(mlist.internal_name(), addrs, msg) _doperiodic = BounceMixin._doperiodic diff --git a/Mailman/Queue/CommandRunner.py b/Mailman/Queue/CommandRunner.py index b63b050c..c5cc3d94 100644 --- a/Mailman/Queue/CommandRunner.py +++ b/Mailman/Queue/CommandRunner.py @@ -1,4 +1,4 @@ -# Copyright (C) 1998-2011 by the Free Software Foundation, Inc. +# Copyright (C) 1998-2015 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 @@ -12,7 +12,8 @@ # # 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +# USA. """-request robot command queue runner.""" @@ -132,22 +133,34 @@ class Results: __import__(modname) handler = sys.modules[modname] # ValueError can be raised if cmd has dots in it. - except (ImportError, ValueError): + # and KeyError if cmd is otherwise good but ends with a dot. + except (ImportError, ValueError, KeyError): # If we're on line zero, it was the Subject: header that didn't # contain a command. It's possible there's a Re: prefix (or # localized version thereof) on the Subject: line that's messing # things up. Pop the prefix off and try again... once. # + # At least one MUA (163.com web mail) has been observed that + # inserts 'Re:' with no following space, so try to account for + # that too. + # # If that still didn't work it isn't enough to stop processing. # BAW: should we include a message that the Subject: was ignored? - if not self.subjcmdretried and args: + # + # But first, be sure we're looking at the Subject: and not past + # it already. + if self.lineno != 0: + return BADCMD + if self.subjcmdretried < 1: + self.subjcmdretried += 1 + if re.search('^.*:.+', cmd): + cmd = re.sub('.*:', '', cmd).lower() + return self.do_command(cmd, args) + if self.subjcmdretried < 2 and args: self.subjcmdretried += 1 - cmd = args.pop(0) + cmd = args.pop(0).lower() return self.do_command(cmd, args) - if self.lineno <> 0: - return BADCMD - else: - return BADSUBJ + return BADSUBJ if handler.process(self, args): return STOP else: diff --git a/Mailman/Queue/IncomingRunner.py b/Mailman/Queue/IncomingRunner.py index 71d93919..2c6c2815 100644 --- a/Mailman/Queue/IncomingRunner.py +++ b/Mailman/Queue/IncomingRunner.py @@ -1,4 +1,4 @@ -# Copyright (C) 1998-2003 by the Free Software Foundation, Inc. +# Copyright (C) 1998-2015 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 @@ -157,14 +157,32 @@ class IncomingRunner(Runner): os._exit(1) except Errors.DiscardMessage: # Throw the message away; we need do nothing else with it. - syslog('vette', 'Message discarded, msgid: %s', - msg.get('message-id', 'n/a')) + # We do need to push the current handler back in the pipeline + # just in case the syslog call throws an exception and the + # message is shunted. + pipeline.insert(0, handler) + syslog('vette', """Message discarded, msgid: %s' + list: %s, + handler: %s""", + msg.get('message-id', 'n/a'), + mlist.real_name, handler) return 0 except Errors.HoldMessage: # Let the approval process take it from here. The message no # longer needs to be queued. return 0 except Errors.RejectMessage, e: + # Log this. + # We do need to push the current handler back in the pipeline + # just in case the syslog call or BounceMessage throws an + # exception and the message is shunted. + pipeline.insert(0, handler) + syslog('vette', """Message rejected, msgid: %s + list: %s, + handler: %s, + reason: %s""", + msg.get('message-id', 'n/a'), + mlist.real_name, handler, e.notice()) mlist.BounceMessage(msg, msgdata, e) return 0 except: diff --git a/Mailman/Queue/NewsRunner.py b/Mailman/Queue/NewsRunner.py index 44850063..449532fb 100644 --- a/Mailman/Queue/NewsRunner.py +++ b/Mailman/Queue/NewsRunner.py @@ -1,4 +1,4 @@ -# Copyright (C) 2000-2005 by the Free Software Foundation, Inc. +# Copyright (C) 2000-2015 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 @@ -111,20 +111,12 @@ def prepare_message(mlist, msg, msgdata): del msg['subject'] msg['subject'] = stripped_subject # Add the appropriate Newsgroups: header - ngheader = msg['newsgroups'] - if ngheader is not None: - # See if the Newsgroups: header already contains our linked_newsgroup. - # If so, don't add it again. If not, append our linked_newsgroup to - # the end of the header list - ngroups = [s.strip() for s in ngheader.split(',')] - if mlist.linked_newsgroup not in ngroups: - ngroups.append(mlist.linked_newsgroup) - # Subtitute our new header for the old one. - del msg['newsgroups'] - msg['Newsgroups'] = COMMASPACE.join(ngroups) - else: - # Newsgroups: isn't in the message - msg['Newsgroups'] = mlist.linked_newsgroup + if msg['newsgroups'] is not None: + # This message is gated from our list to it's associated usnet group. + # If it has a Newsgroups: header mentioning other groups, it's not + # up to us to post it to those groups. + del msg['newsgroups'] + msg['Newsgroups'] = mlist.linked_newsgroup # Note: We need to be sure two messages aren't ever sent to the same list # in the same process, since message ids need to be unique. Further, if # messages are crossposted to two Usenet-gated mailing lists, they each diff --git a/Mailman/Queue/OutgoingRunner.py b/Mailman/Queue/OutgoingRunner.py index 0f51b663..defaf02d 100644..100755 --- a/Mailman/Queue/OutgoingRunner.py +++ b/Mailman/Queue/OutgoingRunner.py @@ -1,4 +1,4 @@ -# Copyright (C) 2000-2007 by the Free Software Foundation, Inc. +# Copyright (C) 2000-2012 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 @@ -89,6 +89,7 @@ class OutgoingRunner(Runner, BounceMixin): syslog('error', 'Cannot connect to SMTP server %s on port %s', mm_cfg.SMTPHOST, port) self.__logged = True + self._snooze(0) return True except Errors.SomeRecipientsFailed, e: # Handle local rejects of probe messages differently. diff --git a/Mailman/Queue/Switchboard.py b/Mailman/Queue/Switchboard.py index bd1cd357..a2c31263 100644 --- a/Mailman/Queue/Switchboard.py +++ b/Mailman/Queue/Switchboard.py @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2008 by the Free Software Foundation, Inc. +# Copyright (C) 2001-2013 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 @@ -184,8 +184,8 @@ class Switchboard: else: os.unlink(bakfile) except EnvironmentError, e: - syslog('error', 'Failed to unlink/preserve backup file: %s', - bakfile) + syslog('error', 'Failed to unlink/preserve backup file: %s\n%s', + bakfile, e) def files(self, extension='.pck'): times = {} |