mailbox_remover.pl 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. #!/usr/bin/perl
  2. #
  3. # by Petr Znojemsky (c) 2004
  4. # Mailbox remover 0.1a 23/10/2004 - the very first version for MySQL
  5. # removes maildirs from disk when they are not found in a database
  6. #
  7. # Added subdir support and pause --- Alan Batie 2007
  8. # Lists directories to be deleted then pauses for 5 seconds for chance to abort
  9. # $Id: mailbox_remover.pl 211 2007-11-11 23:36:46Z christian_boltz $
  10. #
  11. # All your maildirs or other directories could be accidentally removed.
  12. # Use it at own risk. No warranties!
  13. use strict;
  14. use DBI;
  15. use File::Path;
  16. ##########
  17. # Set these variables according to your configuration
  18. # when mailboxes are removed, save their tarballs here
  19. my $archdir="/var/archive/mailboxes";
  20. # expected to support z option, tweak invocation if you want different
  21. my $archcmd="/usr/bin/tar";
  22. # trailing slash not needed
  23. my $maildir_path="/var/mail";
  24. # find out if we need to check subdirs for mailboxes or just maildir_path
  25. # $CONF['domain_path'] = 'YES';
  26. my $pfadmin_config="/usr/local/www/postfixadmin/config.inc.php";
  27. # database information
  28. my $host="localhost";
  29. my $port="3306";
  30. my $userid="dbuser";
  31. my $passwd="dbpw";
  32. my $db="dbname";
  33. ############
  34. my $connectionInfo="DBI:mysql:database=$db;$host:$port";
  35. # make connection to database
  36. my $dbh = DBI->connect($connectionInfo,$userid,$passwd);
  37. # prepare and execute query
  38. my $query = "SELECT maildir FROM mailbox";
  39. my $sth = $dbh->prepare($query);
  40. $sth->execute();
  41. # assign fields to variables
  42. my ($db_maildir, %db_maildirs);
  43. $sth->bind_columns(\$db_maildir);
  44. # load up directory list
  45. while($sth->fetch()) {
  46. $db_maildirs{$db_maildir} = 1;
  47. }
  48. $sth->finish();
  49. # disconnect from database
  50. $dbh->disconnect;
  51. #
  52. # find out if we need to check subdirs for mailboxes or just maildir_path
  53. # $CONF['domain_path'] = 'YES';
  54. #
  55. my $use_subdirs = 0;
  56. open(CONFIG, "<$pfadmin_config") || die "Can't open '$pfadmin_config': $!\n";
  57. while(<CONFIG>) {
  58. if (/\$CONF\['domain_path'\] *= *'([^']*)'/) {
  59. $use_subdirs = ($1 =~ /yes/i);
  60. }
  61. }
  62. close(CONFIG);
  63. # store maildir list to %directories
  64. # key is path, value is username to use in archive file
  65. my %directories;
  66. opendir(DIR, $maildir_path) || die "Cannot open dir $maildir_path: $!\n";
  67. foreach my $name (readdir(DIR)) {
  68. next if ($name eq '.' || $name eq '..' || ! -d "$maildir_path/$name");
  69. if ($use_subdirs) {
  70. opendir(SUBDIR, "$maildir_path/$name") || die "Cannot open dir $maildir_path/$name: $!\n";
  71. foreach my $subname (readdir(SUBDIR)) {
  72. next if ($subname eq '.' || $subname eq '..' || ! -d "$maildir_path/$name/$subname");
  73. # db entry has trailing slash...
  74. if (!defined($db_maildirs{"$name/$subname/"})) {
  75. print "marking $maildir_path/$name/$subname for deletion.\n";
  76. $directories{"$name/$subname"} = "$name-$subname";
  77. }
  78. }
  79. closedir(SUBDIR);
  80. } else {
  81. # db entry has trailing slash...
  82. if (!defined($db_maildirs{"$name/"})) {
  83. print "marking $maildir_path/$name for deletion.\n";
  84. $directories{"$name"} = $name;
  85. }
  86. }
  87. }
  88. closedir(DIR);
  89. print "Ctrl-C in 5 seconds to abort before removal starts...\n";
  90. sleep 5;
  91. my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
  92. # yyyymmddhhmm
  93. my $tstamp = sprintf("%04d%02d%02d%02d%02d", $year+1900, $mon+1, $mday, $hour, $min);
  94. # compare two arrays and erase maildirs not found in database
  95. chdir $maildir_path || die "Can't change to maildir '$maildir_path': $!\n";;
  96. my @args;
  97. foreach my $maildir (keys(%directories)) {
  98. my $archive = "$archdir/$directories{$maildir}-$tstamp.tgz";
  99. # quick permissions check
  100. open(TOUCH, ">$archive") || die "Can't create archive file $archive: $!\n";
  101. close(TOUCH);
  102. print "Archiving $maildir\n";
  103. @args = ($archcmd, "cvzf", $archive, $maildir);
  104. system(@args) == 0 or die "Creating archive for $maildir failed: $?"
  105. rmtree($maildir);
  106. print localtime() . " $maildir has been deleted.\n";
  107. }