not working yet, but i am checking in changes
authorElijah Saxon <elijah@riseup.net>
Thu, 13 Jan 2005 01:01:34 +0000 (01:01 +0000)
committerElijah Saxon <elijah@riseup.net>
Thu, 13 Jan 2005 01:01:34 +0000 (01:01 +0000)
handlers/maildir

index c07cd7e3a68d5ef0af603e37d731eda9ccd414bb..2ea94ff146e8b1ae316a650aaa46edb5d8212e8a 100644 (file)
@@ -1,12 +1,18 @@
-#!/usr/bin/php4 -q
-<?php
-
 ###############################################################
 #
 #  This handler slowly creates a backup of each user's maildir
 #  to a remote server. It is designed to be run with low overhead
 #  in terms of cpu and bandwidth so it runs pretty slow.
 #
+#  if destdir is /backup/maildir/, then it will contain the files
+#    daily.1
+#    daily.2
+#    daily.3
+#    weekly.1
+#    weekly.2
+#    monthly.1
+#  if keepdaily is 3, keepweekly is 2, and keepmonthly is 1. 
+# 
 ##############################################################
 
 getconf rotate yes
@@ -14,8 +20,9 @@ getconf remove yes
 
 getconf loadlimit 5
 getconf speedlimit 0
-getconf keepdaily 7
-getconf keepweekly 4
+getconf keepdaily 5
+getconf keepweekly 3
+getconf keepmonthly 1
 
 getconf srcdir /var/maildir
 getconf destdir
@@ -23,6 +30,10 @@ getconf desthost
 getconf destport 22
 getconf destuser
 
+# strip trailing /
+destdir=${destdir%/}
+srcdir=${srcdir%/}
+
 # used for testing
 getconf letter
 getconf user
@@ -47,6 +58,14 @@ fi
 ##################################################################
 ### FUNCTIONS
 
+# remote run the args remotely
+function rrun() {
+       debug ssh -o PasswordAuthentication=no $desthost -l $destuser $@
+       if [ ! $test ]; then
+               debug ssh -o PasswordAuthentication=no $desthost -l $destuser $@
+       fi
+}
+
 function do_letters() {
        for i in a b c d e f g h i j k l m n o p q r s t u v w x y z; do
                do_maildirs "$srcdir/$i"
@@ -91,7 +110,7 @@ function do_remove() {
        
        for i in a b c d e f g h i j k l m n o p q r s t u v w x y z; do
                ls -1 "$srcdir/$i" | sort > $tmp1
-               ssh -p $destport $desthost 'ls -1 '$destdir/maildir/$i' | sort > $tmp2
+               ssh -p $destport $desthost ls -1 '$destdir/maildir/$i' | sort > $tmp2
                for deluser in `join -v 2 $tmp1 $tmp2`; do
                        cmd="ssh -p $destport $desthost rm -vr '$destdir/maildir/$i/$deluser/'"
                        debug $cmd
@@ -101,27 +120,105 @@ function do_remove() {
        rm $tmp2        
 }
 
+function do_rotate() {
+       backuproot=$destdir
+       now=`date %s`
+       seconds_daily=86400
+       seconds_weekly=604800
+       seconds_monthly=2628000
+
+       ssh -o PasswordAuthentication=no $desthost -l $destuser <<EOF
+       keepdaily=$keepdaily
+       keepweekly=$keepweekly
+       keepmonthly=$keepmonthly
+
+       for rottype in daily weekly monthly; do
+               seconds=\`echo seconds_\${rottype}\`
+
+               dir="$backuproot/\$rottype"
+               if [ ! -d \$dir.1 ]; then
+                       echo "Warning: \$dir.1 does not exist. This backup is missing, so we are skipping the rotation."
+                       continue
+               elif [ ! -f \$dir.1/created ]; then
+                       echo "Warning: \$dir.1/created does not exist. This backup may be only partially completed, so we are skipping the rotation."
+                       continue
+               fi
+               
+               # Rotate the current list of backups, if we can.
+               oldest=\`ls -d $\dir.* | sed 's/^.*\.//' | sort -n | tail -1\`
+               for (( i=\$oldest; i > 0; i-- )); do
+                       if [ -d \$dir.\$i ]; then
+                               if [ -f \$dir.\$i/rotated ]; then
+                                       rotated=\`tail -1 \$dir.\$i/rotated\`
+                               else
+                                       rotated=0
+                               fi
+                               cutoff_time=\$(( now - (seconds*i) ))
+                               if [ \$rotated -gt \$cutoff_time ]; then
+                                       next=\$(( i + 1 ))
+                                       echo "mv \$dir.\$i \$dir.\$next"
+                                       mv \$dir.\$i \$dir.\$next
+                                       date +%c%n%s > \$dir.\$next/rotated
+                               else
+                                       echo "Info: skipping rotation of \$dir.\$i because it was already rotated within the last " \$((cutoff_time/86400)) " days."
+                               fi 
+                       fi
+               done
+       done
+
+       max=\$((keepdaily+1))
+       if [ ( \$keepweekly -a -d $backuproot/daily.\$max ) -a ! -d $backuproot/weekly.1 ]; then
+               echo mv $backuproot/daily.\$max $backuproot/weekly.1
+               mv $backuproot/daily.\$max $backuproot/weekly.1
+               date +%c%n%s > $backuproot/weekly.1/rotated
+       fi
+
+       max=\$((keepweekly+1))
+       if [ ( \$keepmonthly -a -d $backuproot/weekly.\$max ) -a ! -d $backuproot/monthly.1 ]; then
+               echo mv $backuproot/weekly.\$max $backuproot/monthly.1
+               mv $backuproot/weekly.\$max $backuproot/monthly.1
+               date +%c%n%s > $backuproot/monthly.1/rotated
+       fi
+
+       for rottype in daily weekly monthly; do
+               max=\`echo keep\${rottype}\`
+               max=\$((max+1))
+               dir="$backuproot/\$rottype"
+               oldest=\`ls -d $\dir.* | sed 's/^.*\.//' | sort -n | tail -1\`
+
+               # if we've rotated the last backup off the stack, remove it.
+               for (( i=\$oldest; i >= \$max; i-- )); do
+                       if [ -d \$dir.\$i ]; then
+                               echo "Info: removing \$dir.\$i"
+                               rm -rf \$dir.\$i
+                       fi
+               done
+       done
+EOF
+}
+
+
 ###
 ##################################################################
 
 ### ROTATE BACKUPS ###
 
-if [ "$remove" == "yes" ]; then
-
+if [ "$rotate" == "yes" ]; then
+       do_rotate
 fi
 
 ### REMOVE OLD MAILDIRS ###
 
-if [ "$rotate" == "yes" ]; then
-
+if [ "$remove" == "yes" ]; then
+       debug remove
 fi
 
 ### ROTATE BACKUPS ###
 
 if [ "$letter" != "" ]; then
-
+       debug letter
 fi
 
 if [ "$user" != "" ]; then
-
+       debug user
 fi