diff --unified -r flexbackup-1.2.1-orig/flexbackup flexbackup-1.2.1/flexbackup --- flexbackup-1.2.1-orig/flexbackup 2003-10-10 16:12:09.000000000 +0200 +++ flexbackup-1.2.1/flexbackup 2011-04-08 19:50:30.668709500 +0200 @@ -2887,6 +2887,10 @@ } } + if ($cfg::exclude_expr_filename ne '') { + $::exclude_expr_filename = $cfg::exclude_expr_filename; + } + # Traverse mountpoints? &checkvar(\$cfg::traverse_fs,'traverse_fs','false local all','false'); if ($cfg::traverse_fs eq "local") { @@ -4811,6 +4815,15 @@ } +# Perl trim function to remove whitespace from the start and end of the string +sub trim($) +{ + my $string = shift; + $string =~ s/^\s+//; + $string =~ s/\s+$//; + return $string; +} + ###################################################################### # Common commands to invoke 'find' & get a desired file list on stdout ###################################################################### @@ -4861,6 +4874,52 @@ $cmd .= "-depth "; } + # Search for 'backup_ignore'-Files and build an array of regular expressions + my $filter_cmd_null = " -print0"; # No filtering + my $filter_cmd_newline = " -print"; # No filtering + if ($::exclude_expr_filename) { + my @regexp_ignore = (); + my $find = &maybe_remote_cmd("cd \"$dir\"; $cmd -name '$::exclude_expr_filename' -print", $remote); + open(LIST,"$find |") || die; + while() { + chomp(my $file = $_); + open(IGNORE, "$dir/$file"); + my $regexp = ""; + while() { + my $pattern = trim($_); + if ($pattern ne "") { + &log("| Adding exclude expression from '$dir/$file': $pattern"); + eval { + qr{$pattern}; # Ensure that this can be compiled + $regexp .= "($pattern)|"; + } or do { + # Compilation error + warn("Could not compile regular expression from '$dir/$file': $pattern"); + } + } + } + $regexp =~ s/\|$//; + if ($regexp ne "") { + $file = dirname($file); + push(@regexp_ignore, qr{^\Q$file/\E($regexp)}); + } + close(IGNORE); + } + close(LIST); + + # Build regexp clauses to a filtering command (using perl ;-) + if (@regexp_ignore) { + $filter_cmd_null = " -print0 | xargs -0 perl -e 'foreach (\@ARGV) { print \"\$_\\0\" if "; + $filter_cmd_newline = " -print0 | xargs -0 perl -e 'foreach (\@ARGV) { print \"\$_\\n\" if "; + foreach (@regexp_ignore) { + $filter_cmd_null .= "! /$_/ and"; + $filter_cmd_newline .= "! /$_/ and"; + } + $filter_cmd_null .= " 1 }'"; + $filter_cmd_newline .= " 1 }'"; + } + } + $cmd .= "$::mountpoint_flag "; $cmd .= "! -type s "; @@ -4892,9 +4951,9 @@ if (!defined($::pkgdelta)) { if ($separator eq 'newline') { - $cmd .= "-print "; + $cmd .= $filter_cmd_newline; } else { - $cmd .= "-print0 "; + $cmd .= $filter_cmd_null; } } else { @@ -4903,7 +4962,7 @@ # Then only keep unowned or owned+changed files my $host; - my $find = &maybe_remote_cmd("cd \"$dir\"; $cmd -print", $remote); + my $find = &maybe_remote_cmd("cd \"$dir\"; $cmd $filter_cmd_newline", $remote); my $write = "> $::pkgdelta_filelist"; if(defined($remote)) { &log("| Listing level $level to-be-archived files for $remote:$dir"); diff --unified -r flexbackup-1.2.1-orig/flexbackup.conf flexbackup-1.2.1/flexbackup.conf --- flexbackup-1.2.1-orig/flexbackup.conf 2003-09-22 00:59:58.000000000 +0200 +++ flexbackup-1.2.1/flexbackup.conf 2011-04-08 19:35:24.853622743 +0200 @@ -100,6 +100,14 @@ $exclude_expr[0] = '.*/[Cc]ache/.*'; $exclude_expr[1] = '.*~$'; +# Read more exclude expressions from files with this name. +# Each line represents one expression. The directory path is +# prepended to this expressions. That means, if you have a +# file called dummy/.backup_ignore with a single line +# '.*.tmp$' this would be expanded to 'dummy\/.*.tmp$'. +# If a pattern could not be compiled it will be ignored. +$exclude_expr_filename = '.backup_ignore'; + # If true (default), and using a tape device, level zero "set" backups # assume you want to erase and use a new tape for each set. If false, level # zero "set" backups append to tapes. To force an erase for any backup,