#!/usr/bin/perl # ---------------------------------------------------------------------- # nightly_spamkill.pl - nuke old spam files from spammy Maildir folders # Sun Oct 13 18:17:53 PDT 2002, Rudy Rucker, rruckerBLAHBLAH@monkeybrains.net # Version 0.1 (not planning on another...) # Feel free to use this ASIS and at your own risk. # ---------------------------------------------------------------------- # This is run nightly as a cron job. # here is a good line for your crontab: # 9 0 * * * /root/bin/nightly_spamkill.pl | /usr/bin/mail -E -s "Spam nuke stats" you@email.com # # Here is an excerpt from my procmailrc file which activates the spamassassian: # # procmailrc: SPAMFOLDER=${HOME}/Maildir/.spam/ # procmailrc: # send to the ninja spam assassin # procmailrc: :0fw # procmailrc: * < 256000 # procmailrc: | /usr/local/bin/spamc # procmailrc: # procmailrc: :0: # procmailrc: *^Subject:.*--SPAM-- # procmailrc: ${SPAMFOLDER} # # N.B. you may have something other than --SPAM--, like <SPAM> or ***SPAM*** in your procmailrc # # ---------------------------------------------------------------------- # configure this script be editing these variables. # ---------------------------------------------------------------------- my $MIN_UID = 1000; # uid's less than $MIN_UID are not affected. my $SPAM_FOLDER = "Maildir/.spam/"; # relative to users HOME (HOME is pulled from /etc/passwd) my $MAX_SPAM_FILES = 50; # set to undef or 0 to skip this limit my $MAX_DAYS = 7; # erase all spams MAX_DAYS old; set this to 0 to nuke all! my $VERBOSE = 0; # turn on for a bunch of output. my $PRINT_SPAM_COUNT_AT_END = 1; #leave this on to get an email from this cronjob, fun! # ---------------------------------------------------------------------- # Don't need to change much below here. # ---------------------------------------------------------------------- # redirect STDERR... ls complains when a user has no spam. (eg they erase it themselves) open STDERR, ">/dev/null" or die "Redirect STDERR failed, $!"; my $count = 0; while (my ($name,$uid,$dir) = (getpwent)[0,2,7]) { # ------------------------------------------------------------------ # Check to see if we want to do this user # ------------------------------------------------------------------ print "\n" if $VERBOSE; print "$name" if $VERBOSE; $uid < $MIN_UID and next; print " (uid:$uid)" if $VERBOSE; -d $dir or next; print "\t$dir" if $VERBOSE; unless (chdir "$dir/$SPAM_FOLDER") { print "\tNo spam folder!" if $VERBOSE; next; } # ------------------------------------------------------------------ # okay, get list and see if there are mmore than MAX_SPAM_FILES # ------------------------------------------------------------------ my $this_user_count; open KILL_LIST, "/bin/ls -t cur/* new/* |" or die "no /bin/ls in $0, $!"; if ($MAX_SPAM_FILES and $MAX_SPAM_FILES > 0) { $this_user_count = 0; for (1..$MAX_SPAM_FILES) { <KILL_LIST> }; #skip these files... while ( my $file = <KILL_LIST>) { chomp($file); $count++; $this_user_count++; unlink $file or (print "failed to unlink $file"); } print "\t$this_user_count spams overlimit" if $VERBOSE; } close KILL_LIST; # ------------------------------------------------------------------ # Now nuke any spams older than MAX_DAYS # ------------------------------------------------------------------ open KILL_LIST, "/bin/ls -t cur/* new/* |" or die "no /bin/ls in $0, $!"; $this_user_count = 0; while ( my $file = <KILL_LIST>) { chomp($file); -M $file < $MAX_DAYS and next; print "$name nuking $file\n"; unlink $file or (print "failed to unlink $file"); $count++; $this_user_count++; } print "\t$this_user_count old spams" if $VERBOSE; close KILL_LIST; } print "\n" if $VERBOSE; #clean up line endings... # ------------------------------------------------------------------ # print out some stats for the cronjob to mail you@email.com # ------------------------------------------------------------------ if ($PRINT_SPAM_COUNT_AT_END or $VERBOSE) { $count > 1 and (print "$count spam files nuked.\n"); $count == 1 and (print "only one lonely spam file nuked.\n"); $count == 0 and (print "No spams eliminated. You are lucky to not get any!\n"); } exit; __END__ After thought: You could do most of this from procmail itself with a line something like this: cd ${SPAMFOLDER} && rm -f dummy `ls -t */*mail* | sed -e 1,50d` BUT, I wanted age control, number control, a report emailed to me, and to speed the server up by only running this once per day for each user instead of once per incoming email.