#! @PYTHON@ # # Copyright (C) 2008 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, # USA. """Cull bad and shunt queues, recommended once per day. This script goes through the 'bad' and 'shunt' queue directories and, if mm_cfg.BAD_SHUNT_STALE_AFTER is > 0, it removes all files more than that many seconds old. If mm_cfg.BAD_SHUNT_ARCHIVE_DIRECTORY is a writable directory, the old files are moved there. Otherwise they are deleted. Only regular files immediately subordinate to the 'bad' and 'shunt' directories are processed. Anything else is skipped. Usage: %(PROGRAM)s [options] Options: -h / --help Print this message and exit. """ import os import sys import stat import time import errno import getopt import paths # mm_cfg must be imported before the other modules, due to the side-effect of # it hacking sys.paths to include site-packages. Without this, running this # script from cron with python -S will fail. from Mailman import mm_cfg from Mailman.i18n import _ # Work around known problems with some RedHat cron daemons import signal signal.signal(signal.SIGCHLD, signal.SIG_DFL) PROGRAM = sys.argv[0] def usage(code, msg=''): if code: fd = sys.stderr else: fd = sys.stdout print >> fd, _(__doc__) if msg: print >> fd, msg sys.exit(code) def main(): try: opts, args = getopt.getopt( sys.argv[1:], 'h', ['help']) except getopt.error, msg: usage(1, msg) if args: usage(1) if mm_cfg.BAD_SHUNT_STALE_AFTER <= 0: # Nothing to do return now = time.time() old = now - float(mm_cfg.BAD_SHUNT_STALE_AFTER) os.stat_float_times(True) adir = mm_cfg.BAD_SHUNT_ARCHIVE_DIRECTORY if (adir and os.access(adir, os.W_OK | os.X_OK) and stat.S_ISDIR(os.stat(adir).st_mode)): pass else: if adir: print >>sys.stderr, '%s: archive directory %s not usable.' % ( PROGRAM, adir) adir = None for qdir in (mm_cfg.BADQUEUE_DIR, mm_cfg.SHUNTQUEUE_DIR): try: names = os.listdir(qdir) except OSError, e: if e.errno <> errno.ENOENT: # OK if qdir doesn't exist, else raise continue for name in names: pathname = os.path.join(qdir, name) pstat = os.stat(pathname) if not stat.S_ISREG(pstat.st_mode): # Not a regular file continue if pstat.st_mtime > old: # File is new continue if adir: os.rename(pathname, os.path.join(adir, name)) else: os.remove(pathname) if __name__ == '__main__': main()