Revision: 133
http://postfixadmin.svn.sourceforge.net/postfixadmin/?rev=133&view=rev
Author: christian_boltz
Date: 2007-10-04 17:05:31 -0700 (Thu, 04 Oct 2007)
Log Message:
-----------
- fix: do not remove . and .. (thanks rschetterer!)
- added support for domain subdir style layouts and lots of error checks (thanks abatie!)
- added exit status check after archiving mailbox before calling rmtree
- references:
- https://sourceforge.net/tracker/index.php?func=detail&aid=1750088&group_id=191583&atid=937964
- http://www.rdrop.com/files/mailbox_remover.pl
Modified Paths:
--------------
trunk/ADDITIONS/mailbox_remover.pl
Modified: trunk/ADDITIONS/mailbox_remover.pl
===================================================================
--- trunk/ADDITIONS/mailbox_remover.pl 2007-10-04 14:58:38 UTC (rev 132)
+++ trunk/ADDITIONS/mailbox_remover.pl 2007-10-05 00:05:31 UTC (rev 133)
@@ -3,64 +3,122 @@
# by Petr Znojemsky (c) 2004
# Mailbox remover 0.1a 23/10/2004 - the very first version for MySQL
# removes maildirs from disk when they are not found in a database
-# Run program and read the $logfile before uncommenting the "rmtree" line!
+#
+# Added subdir support and pause --- Alan Batie 2007
+# Lists directories to be deleted then pauses for 5 seconds for chance to abort
+# $Id: mbox_remover,v 1.4 2007/07/12 22:11:09 alan Exp alan $
+#
# All your maildirs or other directories could be accidentally removed.
# Use it at own risk. No warranties!
+use strict;
use DBI;
use File::Path;
##########
# Set these variables according to your configuration
-$maildir_path="/var/mail/virtual/";
-$logfile="/var/log/mail/removed_maildirs";
+# when mailboxes are removed, save their tarballs here
+my $archdir="/var/archive/mailboxes";
+
+# expected to support z option, tweak invocation if you want different
+my $archcmd="/usr/bin/tar";
+
+# trailing slash not needed
+my $maildir_path="/var/mail";
+# find out if we need to check subdirs for mailboxes or just maildir_path
+# $CONF['domain_path'] = 'YES';
+my $pfadmin_config="/usr/local/www/postfixadmin/config.inc.php";
+
# database information
-$host="localhost";
-$port="3306";
-$userid="postfix";
-$passwd="postfix";
-$db="postfix";
+my $host="localhost";
+my $port="3306";
+my $userid="dbuser";
+my $passwd="dbpw";
+my $db="dbname";
############
-$connectionInfo="DBI:mysql:database=$db;$host:$port";
+my $connectionInfo="DBI:mysql:database=$db;$host:$port";
# make connection to database
-$dbh = DBI->connect($connectionInfo,$userid,$passwd);
+my $dbh = DBI->connect($connectionInfo,$userid,$passwd);
# prepare and execute query
-$query = "SELECT username FROM mailbox";
-$sth = $dbh->prepare($query);
+my $query = "SELECT maildir FROM mailbox";
+my $sth = $dbh->prepare($query);
$sth->execute();
+
# assign fields to variables
-$sth->bind_columns(\$username);
-# output computer list to the browser
+my ($db_maildir, %db_maildirs);
+$sth->bind_columns(\$db_maildir);
+
+# load up directory list
while($sth->fetch()) {
-push(@usernames, $username);
+ $db_maildirs{$db_maildir} = 1;
}
+
$sth->finish();
# disconnect from database
$dbh->disconnect;
-# store maildir list to @directories
-opendir(DIRHANDLE, $maildir_path) || die "Cannot open dir $maildir_path: $!";
-foreach $name (sort readdir(DIRHANDLE))
-{
- push (@directories, $name);
+#
+# find out if we need to check subdirs for mailboxes or just maildir_path
+# $CONF['domain_path'] = 'YES';
+#
+my $use_subdirs = 0;
+open(CONFIG, "<$pfadmin_config") || die "Can't open '$pfadmin_config': $!\n";
+while(<CONFIG>) {
+ if (/\$CONF\['domain_path'\] *= *'([^']*)'/) {
+ $use_subdirs = ($1 =~ /yes/i);
+ }
}
-closedir(DIRHANDLE);
-# eliminate "." and ".." from the maildir list
-($dot, $doubledot, @directories) = @directories;
+close(CONFIG);
+# store maildir list to %directories
+# key is path, value is username to use in archive file
+my %directories;
+opendir(DIR, $maildir_path) || die "Cannot open dir $maildir_path: $!\n";
+foreach my $name (readdir(DIR)) {
+ next if ($name eq '.' || $name eq '..' || ! -d "$maildir_path/$name");
+ if ($use_subdirs) {
+ opendir(SUBDIR, "$maildir_path/$name") || die "Cannot open dir $maildir_path/$name: $!\n";
+ foreach my $subname (readdir(SUBDIR)) {
+ next if ($subname eq '.' || $subname eq '..' || ! -d "$maildir_path/$name/$subname");
+ # db entry has trailing slash...
+ if (!defined($db_maildirs{"$name/$subname/"})) {
+ print "marking $maildir_path/$name/$subname for deletion.\n";
+ $directories{"$name/$subname"} = "$name-$subname";
+ }
+ }
+ closedir(SUBDIR);
+ } else {
+ # db entry has trailing slash...
+ if (!defined($db_maildirs{"$name/"})) {
+ print "marking $maildir_path/$name for deletion.\n";
+ $directories{"$name"} = $name;
+ }
+ }
+}
+closedir(DIR);
+
+print "Ctrl-C in 5 seconds to abort before removal starts...\n";
+sleep 5;
+
+my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
+# yyyymmddhhmm
+my $tstamp = sprintf("%04d%02d%02d%02d%02d", $year+1900, $mon+1, $mday, $hour, $min);
+
# compare two arrays and erase maildirs not found in database
-foreach $maildir (@directories)
-{
- if ((grep { $_ eq $maildir} @usernames)==0)
- {
- # username not found, delete maildir.
- # Please read $logfile before uncommenting following line!
- # rmtree($maildir_path.$maildir);
- open(INFO, ">>$logfile") || die "Cannot write to the logfile: $logfile.";
- print INFO localtime()." Maildir ".$maildir_path.$maildir." has been deleted.\n";
- close(INFO);
- }
+chdir $maildir_path || die "Can't change to maildir '$maildir_path': $!\n";;
+my @args;
+foreach my $maildir (keys(%directories)) {
+ my $archive = "$archdir/$directories{$maildir}-$tstamp.tgz";
+ # quick permissions check
+ open(TOUCH, ">$archive") || die "Can't create archive file $archive: $!\n";
+ close(TOUCH);
+ print "Archiving $maildir\n";
+ @args = ($archcmd, "cvzf", $archive, $maildir);
+ system(@args) == 0 or die "Creating archive for $maildir failed: $?"
+
+ rmtree($maildir);
+ print localtime() . " $maildir has been deleted.\n";
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|