aboutsummaryrefslogtreecommitdiffstats
path: root/cron
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--cron/Makefile.in4
-rw-r--r--cron/crontab.in.in3
-rwxr-xr-xcron/cull_bad_shunt123
3 files changed, 128 insertions, 2 deletions
diff --git a/cron/Makefile.in b/cron/Makefile.in
index afb03370..2a7c8fd2 100644
--- a/cron/Makefile.in
+++ b/cron/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 1998-2003 by the Free Software Foundation, Inc.
+# Copyright (C) 1998-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
@@ -42,7 +42,7 @@ CRONDIR= $(prefix)/cron
SHELL= /bin/sh
PROGRAMS= checkdbs mailpasswds senddigests gate_news \
- nightly_gzip bumpdigests disabled
+ nightly_gzip bumpdigests disabled cull_bad_shunt
FILES= crontab.in
BUILDDIR= ../build/cron
diff --git a/cron/crontab.in.in b/cron/crontab.in.in
index 49f27c72..540dfc1d 100644
--- a/cron/crontab.in.in
+++ b/cron/crontab.in.in
@@ -22,3 +22,6 @@
# turn this on if the internal archiver is used and
# GZIP_ARCHIVE_TXT_FILES is false in mm_cfg.py
27 3 * * * @PYTHON@ -S @prefix@/cron/nightly_gzip
+#
+# At 4:30AM daily, cull old entries from the 'bad' and 'shunt' queues.
+30 4 * * * @PYTHON@ -S @prefix@/cron/cull_bad_shunt
diff --git a/cron/cull_bad_shunt b/cron/cull_bad_shunt
new file mode 100755
index 00000000..ce0dfb0f
--- /dev/null
+++ b/cron/cull_bad_shunt
@@ -0,0 +1,123 @@
+#! @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()