From a65bc7af30e0ba963a007bc47b6287054bc2f276 Mon Sep 17 00:00:00 2001
From: intrigeri <intrigeri@boum.org>
Date: Sun, 4 Jun 2006 00:30:03 +0000
Subject: [PATCH] rdiff and dup handlers/helpers/examples symlink and globbing
 support enhancement and clarification: for a given include/exclude/vsinclude
 statement, they now support EITHER globbing with '*' OR symlinks in the path.

---
 examples/example.dup   |  8 ++++----
 examples/example.rdiff | 12 +++++------
 handlers/dup           | 46 +++++++++++++++++++++++++-----------------
 handlers/dup.helper    | 22 ++++----------------
 handlers/rdiff         | 35 +++++++++++++++++++++++---------
 handlers/rdiff.helper  |  9 ++++++++-
 6 files changed, 74 insertions(+), 58 deletions(-)

diff --git a/examples/example.dup b/examples/example.dup
index b906551..f3d3981 100644
--- a/examples/example.dup
+++ b/examples/example.dup
@@ -55,9 +55,11 @@ password = a_very_complicated_passphrase
 
 [source]
 
-# files to include in the backup
-# (supports globbing with '*')
+# WARNING: include, exclude and vsinclude statements support EITHER globbing
+# with '*' OR symlinks in the path; usage of both in the same statement is *not*
+# supported and will lead to weird behaviour.
 
+# files to include in the backup
 include = /var/spool/cron/crontabs
 include = /var/backups
 include = /etc
@@ -82,10 +84,8 @@ include = /var/lib/dpkg/status-old
 # vsinclude will add to the include list /vservers/foo/home, /vservers/bar/home
 # and /vservers/baz/home.
 # Vservers paths are derived from $VROOTDIR.
-# vsinclude supports globbing with '*'.
 
 # files to exclude from the backup
-# (supports globbing with '*')
 exclude = /home/*/.gnupg
 
 ######################################################
diff --git a/examples/example.rdiff b/examples/example.rdiff
index 698776e..dd2ac5e 100644
--- a/examples/example.rdiff
+++ b/examples/example.rdiff
@@ -33,12 +33,14 @@ type = local
 # (you can also use the time format of rdiff-backup, e.g. 6D5h)
 keep = 60
 
-# a note about includes and excludes:
-# All the excludes come after all the includes. The order is
-# not otherwise taken into account. 
+# A few notes about includes and excludes:
+#   - include, exclude and vsinclude statements support EITHER globbing with '*'
+#     OR symlinks in the path; usage of both in the same statement is *not*
+#     supported and will lead to weird behaviour.
+#   - All the excludes come after all the includes. The order is not otherwise
+#     taken into account.
 
 # files to include in the backup
-# (supports globbing with '*')
 include = /var/spool/cron/crontabs
 include = /var/backups
 include = /etc
@@ -63,10 +65,8 @@ include = /var/lib/dpkg/status-old
 # vsinclude will add to the include list /vservers/foo/home, /vservers/bar/home
 # and /vservers/baz/home.
 # Vservers paths are derived from $VROOTDIR.
-# vsinclude supports globbing with '*'.
 
 # files to exclude from the backup
-# (supports globbing with '*')
 #exclude = /home/*/.gnupg
 
 ######################################################
diff --git a/handlers/dup b/handlers/dup
index 59bb9bf..c16ec40 100644
--- a/handlers/dup
+++ b/handlers/dup
@@ -129,41 +129,49 @@ execstr_clientpart="/"
 
 set -o noglob
 
+symlinks_warning="Maybe you have mixed symlinks and '*' in this statement, which is not supported."
+
 # excludes
 for i in $exclude; do
-	str="${i//__star__/*}"
-	i=`readlink -f ${i#}`
-	execstr="${execstr}--exclude '$str' "
+   str="${i//__star__/*}"
+   str=`readlink -f $str`
+   if [ -n "$str" ]; then
+      execstr="${execstr}--exclude '$str' "
+   else
+      warning "exclude statement ${i//__star__/*} will be ignored. $symlinks_warning"
+   fi
 done
 	
 # includes 
 for i in $include; do
-	str="${i//__star__/*}"
-	i=`readlink -f ${i#}`
-	execstr="${execstr}--include '$str' "
+   str="${i//__star__/*}"
+   str=`readlink -f $str`
+   if [ -n "$str" ]; then
+      execstr="${execstr}--include '$str' "
+   else
+      warning "include statement ${i//__star__/*} will be ignored. $symlinks_warning"
+   fi
 done
 
 # vsincludes
 if [ $usevserver = yes ]; then
-    for vserver in $vsnames; do
-	for vi in $vsinclude; do
-	    i=`readlink -f $VROOTDIR/$vserver$vi`
-	    str="${i//__star__/*}"
-	    execstr="${execstr}--include '$VROOTDIR/$vserver$str' "
-	done
-    done
+   for vserver in $vsnames; do
+      for vi in $vsinclude; do
+	 str="${vi//__star__/*}"
+	 str=`readlink -f $VROOTDIR/$vserver$str`
+         if [ -n "$str" ]; then
+	    execstr="${execstr}--include '$str' "
+         else
+            warning "vsinclude statement ${vi//__star__/*} will be ignored for VServer $vserver. $symlinks_warning"
+         fi
+      done
+   done
 fi
 
 set +o noglob
 
 ### EXECUTE ###
 
-# exclude everything else, start with root
-#execstr="${execstr}--exclude '**' / "
-		
-# include client-part and server-part
-#execstr="$execstr $execstr_serverpart"
-
 execstr=${execstr//\\*/\\\\\\*}
 
 debug "duplicity $execstr --exclude '**' / $execstr_serverpart"
diff --git a/handlers/dup.helper b/handlers/dup.helper
index a18063d..dbf9643 100644
--- a/handlers/dup.helper
+++ b/handlers/dup.helper
@@ -310,22 +310,11 @@ password = $dup_gpg_password
 
 [source]
 
+# WARNING: include, exclude and vsinclude statements support EITHER globbing
+# with '*' OR symlinks in the path; usage of both in the same statement is *not*
+# supported and will lead to weird behaviour.
+
 # files to include in the backup
-# (supports globbing with '*')
-# BIG FAT WARNING
-# Symlinks are not dereferenced. Moreover, an include line whose path
-# contains, at any level, a symlink to a directory, will only have the
-# symlink backed-up, not the target directory's content. Yes, you have
-# to dereference yourself the symlinks, or to use 'mount --bind'
-# instead.
-# EXAMPLE
-# Let's say /home is a symlink to /mnt/crypt/home ; the following line
-# will only backup a "/home" symlink ; neither /home/user nor
-# /home/user/Mail will be backed-up :
-#   include = /home/user/Mail
-# A workaround is to 'mount --bind /mnt/crypt/home /home' ; another
-# one is to write :
-#   include = /mnt/crypt/home/user/Mail
 EOF
 
    if [ "$host_or_vservers" == host -o "$host_or_vservers" == both ]; then
@@ -352,7 +341,6 @@ EOF
 # vsinclude will add to the include list /vservers/foo/home, /vservers/bar/home
 # and /vservers/baz/home.
 # Vservers paths are derived from $VROOTDIR.
-# vsinclude supports globbing with '*'.
 
 EOF
 
@@ -368,9 +356,7 @@ EOF
    # excludes
    cat >> $next_filename <<EOF
 
-# rdiff-backup specific comment, TO ADAPT
 # files to exclude from the backup
-# (supports globbing with '*')
 EOF
     set -o noglob
     for i in $dup_excludes; do
diff --git a/handlers/rdiff b/handlers/rdiff
index a80b2c5..8f0edfb 100644
--- a/handlers/rdiff
+++ b/handlers/rdiff
@@ -112,6 +112,7 @@ else
 fi
 
 # check the connection at the source and destination
+[ -n "$test" ] || test=0
 if [ "$testconnect" = "yes" ] || [ "${test}" -eq 1 ]; then
 	test_connection $sourceuser $sourcehost
 	test_connection $destuser $desthost
@@ -171,28 +172,42 @@ execstr="$RDIFFBACKUP $options --print-statistics "
 
 set -o noglob
 
+symlinks_warning="Maybe you have mixed symlinks and '*' in this statement, which is not supported."
+
 # TODO: order the includes and excludes
 # excludes
 for i in $exclude; do
-	str="${i//__star__/*}"
-	i=`readlink -f ${i#}`
-	execstr="${execstr}--exclude '$str' "
+   str="${i//__star__/*}"
+   str=`readlink -f $str`
+   if [ -n "$str" ]; then
+      execstr="${execstr}--exclude '$str' "
+   else
+      warning "exclude statement ${i//__star__/*} will be ignored. $symlinks_warning"
+   fi
 done
 # includes 
 for i in $include; do
-	[ "$i" != "/" ] || fatal "Sorry, you cannot use 'include = /'"
-	str="${i//__star__/*}"
-	i=`readlink -f $i`
-	execstr="${execstr}--include '$str' "
+   [ "$i" != "/" ] || fatal "Sorry, you cannot use 'include = /'"
+   str="${i//__star__/*}"
+   str=`readlink -f $str`
+   if [ -n "$str" ]; then
+      execstr="${execstr}--include '$str' "
+   else
+      warning "include statement ${i//__star__/*} will be ignored. $symlinks_warning"
+   fi
 done
 
 # vsinclude
 if [ $usevserver = yes ]; then
    for vserver in $vsnames; do
       for vi in $vsinclude; do
-      	 i=`readlink -f $VROOTDIR/$vserver$vi`
-	 str="${i//__star__/*}"
-	 execstr="${execstr}--include '$str' "
+	 str="${vi//__star__/*}"
+	 str=`readlink -f $VROOTDIR/$vserver$str`
+         if [ -n "$str" ]; then
+	    execstr="${execstr}--include '$str' "
+         else
+            warning "vsinclude statement ${vi//__star__/*} will be ignored for VServer $vserver. $symlinks_warning"
+         fi
       done
    done
 fi
diff --git a/handlers/rdiff.helper b/handlers/rdiff.helper
index d28375e..904ac98 100644
--- a/handlers/rdiff.helper
+++ b/handlers/rdiff.helper
@@ -269,6 +269,14 @@ do_rdiff_finish() {
 [source]
 type = local
 keep = $rdiff_keep
+
+# A few notes about includes and excludes:
+#   - include, exclude and vsinclude statements support EITHER globbing with '*'
+#     OR symlinks in the path; usage of both in the same statement is *not*
+#     supported and will lead to weird behaviour.
+#   - All the excludes come after all the includes. The order is not otherwise
+#     taken into account.
+
 EOF
    ## includes ##
    if [ "$host_or_vservers" == host -o "$host_or_vservers" == both ]; then
@@ -296,7 +304,6 @@ EOF
 # vsinclude will add to the include list /vservers/foo/home, /vservers/bar/home
 # and /vservers/baz/home.
 # Vservers paths are derived from $VROOTDIR.
-# vsinclude supports globbing with '*'.
 
 EOF
       set -o noglob
-- 
GitLab