Added the "Emacs comment line" on top of every shell file.
[matthijs/upstream/backupninja.git] / handlers / maildir
index 8de2b979b7a959f2b3d36e948f00920e29770dcb..a729a3aab17e06f6d561b801a51faa3f9f135156 100644 (file)
@@ -1,3 +1,4 @@
+# -*- mode: sh; sh-basic-offset: 3; indent-tabs-mode: nil; -*-
 ###############################################################
 #
 #  This handler slowly creates a backup of each user's maildir
 #    weekly.2
 #    monthly.1
 #  if keepdaily is 3, keepweekly is 2, and keepmonthly is 1. 
-# 
+#
+#  The basic algorithm is to rsync each maildir individually,
+#  and to use hard links for retaining historical data.
+#
+#  We rsync each maildir individually because it becomes very
+#  unweldy to start a single rsync of many hundreds of thousands
+#  of files. 
+#
+#  For the backup rotation to work, destuser must be able to run 
+#  arbitrary bash commands on the desthost.
+#
 ##############################################################
 
 getconf rotate yes
@@ -85,7 +96,9 @@ function do_user() {
 --exclude '.Trash/*' --exclude '.Mistakes/*' --exclude '.Spam/*' \
 $dir $destuser@$desthost:$destdir/$letter \
 2>&1`
-       if [ $? != 0 ]; then
+       ret=$?
+       # ignore 0 (success) and 24 (file vanished before it could be copied)
+       if [ $ret != 0 -a $ret != 24 ]; then
                warning "rsync $user failed"
                warning "  returned: $ret"
                let "failedcount = failedcount + 1"
@@ -99,8 +112,8 @@ $dir $destuser@$desthost:$destdir/$letter \
 # and add new ones which have just been created.
 
 function do_remove() {
-       local tmp1=/tmp/maildirtmpfile$$
-       local tmp2=/tmp/maildirtmpfile$$
+       local tmp1=`maketemp maildir-tmp-file`
+       local tmp2=`maketemp maildir-tmp-file`
        
        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
@@ -147,23 +160,23 @@ function do_rotate() {
                [ "\$oldest" == "" ] && oldest=0
                for (( i=\$oldest; i > 0; i-- )); do
                        if [ -d \$dir.\$i ]; then
-                               if [ -f \$dir.\$i/rotated ]; then
-                                       rotated=\`tail -1 \$dir.\$i/rotated\`
+                               if [ -f \$dir.\$i/created ]; then
+                                       created=\`tail -1 \$dir.\$i/created\`
                                else
-                                       rotated=0
+                                       created=0
                                fi
-                               cutoff_time=\$(( now - (seconds*i) ))
-                               if [ \$rotated -lt \$cutoff_time ]; then
+                               cutoff_time=\$(( now - (seconds*(i-1)) ))
+                               if [ ! \$created -gt \$cutoff_time ]; then
                                        next=\$(( i + 1 ))
                                        if [ ! -d \$dir.\$next ]; then
-                                               echo "mv \$dir.\$i \$dir.\$next"
+                                               echo "Debug: 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 \$dir.\$next already exists."
                                        fi
                                else
-                                       echo "Info: skipping rotation of \$dir.\$i because it was rotated" \$(( (now-rotated)/86400)) "days ago ("\$(( (now-cutoff_time)/86400))" needed)."
+                                       echo "Info: skipping rotation of \$dir.\$i because it was created" \$(( (now-created)/86400)) "days ago ("\$(( (now-cutoff_time)/86400))" needed)."
                                fi
                        fi
                done
@@ -194,10 +207,9 @@ function do_rotate() {
                                if [ -d $backuproot/rotate.tmp ]; then
                                        echo "Info: removing $backuproot/rotate.tmp"
                                        rm -rf $backuproot/rotate.tmp
-                               else
-                                       echo "Info: moving \$dir.\$i to $backuproot/rotate.tmp"
-                                       mv \$dir.\$i $backuproot/rotate.tmp
                                fi
+                               echo "Info: moving \$dir.\$i to $backuproot/rotate.tmp"
+                               mv \$dir.\$i $backuproot/rotate.tmp
                        fi
                done
        done
@@ -236,14 +248,17 @@ function setup_remote_dirs() {
                                        echo "Fatal: could not create directory $dir.1 on host $desthost"
                                        exit 1
                                fi
+                               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 y x z; do
+                                       mkdir $dir.1/\$i
+                               done
                        fi
                        if [ -d $destdir/$backuptype.2 ]; then
                                echo "Info: updating hard links to $dir.1. This may take a while."
-                               cp -al $destdir/$backuptype.2/. $dir.1
-                               if [ \$? == 1 ]; then
-                                       echo "Fatal: could not create hard links to $dir.1 on host $desthost"
-                                       exit 1
-                               fi
+                               cp -alf $destdir/$backuptype.2/. $dir.1
+                               #if [ \$? == 1 ]; then
+                               #       echo "Fatal: could not create hard links to $dir.1 on host $desthost"
+                               #       exit 1
+                               #fi
                        fi
                fi
                [ -f $dir.1/created ] && rm $dir.1/created