X-Git-Url: http://git.rot13.org/?p=BackupPC.git;a=blobdiff_plain;f=lib%2FBackupPC%2FView.pm;h=b71eecbefece5f6a4aaafe0ab29267fbd37d3ff1;hp=b75321dbfd1eb741617c2841f5536eab51fa7927;hb=b81d2da5e16975674f011e4833337ac0fa24e0ea;hpb=5729095faa3ef12dc5d4f02538c3650ac81912ef diff --git a/lib/BackupPC/View.pm b/lib/BackupPC/View.pm index b75321d..b71eecb 100644 --- a/lib/BackupPC/View.pm +++ b/lib/BackupPC/View.pm @@ -31,7 +31,7 @@ # #======================================================================== # -# Version 2.1.0_CVS, released 3 Jul 2003. +# Version 3.0.0beta2, released 11 Nov 2006. # # See http://backuppc.sourceforge.net. # @@ -78,18 +78,11 @@ sub dirCache $dir =~ s{/+$}{}; return if ( $m->{num} == $backupNum && $m->{share} eq $share + && defined($m->{dir}) && $m->{dir} eq $dir ); - if ( $m->{num} != $backupNum ) { - for ( $i = 0 ; $i < @{$m->{backups}} ; $i++ ) { - last if ( $m->{backups}[$i]{num} == $backupNum ); - } - if ( $i >= @{$m->{backups}} ) { - $m->{idx} = -1; - return; - } - $m->{num} = $backupNum; - $m->{idx} = $i; - } + $m->backupNumCache($backupNum) if ( $m->{num} != $backupNum ); + return if ( $m->{idx} < 0 ); + $m->{files} = {}; $level = $m->{backups}[$m->{idx}]{level} + 1; @@ -147,7 +140,7 @@ sub dirCache } } foreach my $file ( @dir ) { - $file = $1 if ( $file =~ /(.*)/ ); + $file = $1 if ( $file =~ /(.*)/s ); my $fileUM = $file; $fileUM = $m->{bpc}->fileNameUnmangle($fileUM) if ( $mangle ); #print(STDERR "Doing $fileUM\n"); @@ -157,6 +150,7 @@ sub dirCache next if ( defined($m->{files}{$fileUM}) || $file eq ".." || $file eq "." + || $file eq "backupInfo" || $mangle && $file eq "attrib" ); # # skip directories in earlier backups (each backup always @@ -199,13 +193,14 @@ sub dirCache } } } - $m->{files}{$fileUM}{relPath} = "$dir/$fileUM"; - $m->{files}{$fileUM}{sharePathM} = "$sharePathM/$file"; - $m->{files}{$fileUM}{fullPath} = "$path/$file"; - $m->{files}{$fileUM}{backupNum} = $backupNum; - $m->{files}{$fileUM}{compress} = $compress; - $m->{files}{$fileUM}{nlink} = $s[3]; - $m->{files}{$fileUM}{inode} = $s[1]; + ($m->{files}{$fileUM}{relPath} = "$dir/$fileUM") =~ s{//+}{/}g; + ($m->{files}{$fileUM}{sharePathM} = "$sharePathM/$file") + =~ s{//+}{/}g; + ($m->{files}{$fileUM}{fullPath} = "$path/$file") =~ s{//+}{/}g; + $m->{files}{$fileUM}{backupNum} = $backupNum; + $m->{files}{$fileUM}{compress} = $compress; + $m->{files}{$fileUM}{nlink} = $s[3]; + $m->{files}{$fileUM}{inode} = $s[1]; } # # Also include deleted files @@ -237,6 +232,55 @@ sub dirCache #print STDERR "Returning:\n", Dumper($m->{files}); } +# +# Return list of shares for this backup +# +sub shareList +{ + my($m, $backupNum) = @_; + my @shareList; + + $m->backupNumCache($backupNum) if ( $m->{num} != $backupNum ); + return if ( $m->{idx} < 0 ); + + my $mangle = $m->{backups}[$m->{idx}]{mangle}; + my $path = "$m->{topDir}/pc/$m->{host}/$backupNum/"; + return if ( !opendir(DIR, $path) ); + my @dir = readdir(DIR); + closedir(DIR); + foreach my $file ( @dir ) { + $file = $1 if ( $file =~ /(.*)/s ); + next if ( $file eq "attrib" && $mangle + || $file eq "." + || $file eq ".." + || $file eq "backupInfo" + ); + my $fileUM = $file; + $fileUM = $m->{bpc}->fileNameUnmangle($fileUM) if ( $mangle ); + push(@shareList, $fileUM); + } + $m->{dir} = undef; + return @shareList; +} + +sub backupNumCache +{ + my($m, $backupNum) = @_; + + if ( $m->{num} != $backupNum ) { + my $i; + for ( $i = 0 ; $i < @{$m->{backups}} ; $i++ ) { + last if ( $m->{backups}[$i]{num} == $backupNum ); + } + if ( $i >= @{$m->{backups}} ) { + $m->{idx} = -1; + return; + } + $m->{num} = $backupNum; + $m->{idx} = $i; + } +} + # # Return the attributes of a specific file # @@ -244,16 +288,18 @@ sub fileAttrib { my($m, $backupNum, $share, $path) = @_; - if ( $path =~ s{(.*)/+(.+)}{$1} ) { + #print(STDERR "fileAttrib($backupNum, $share, $path)\n"); + if ( $path =~ s{(.*)/+(.+)}{$1}s ) { my $file = $2; $m->dirCache($backupNum, $share, $path); return $m->{files}{$file}; } else { #print STDERR "Got empty $path\n"; $m->dirCache($backupNum, "", ""); - my %attr = %{$m->{files}{$share}}; - $attr{relPath} = "/"; - return \%attr; + my $attr = $m->{files}{$share}; + return if ( !defined($attr) ); + $attr->{relPath} = "/"; + return $attr; } } @@ -268,6 +314,9 @@ sub dirAttrib return $m->{files}; } +# +# Return a listref of backup numbers that are merged to create this view +# sub mergeNums { my($m) = @_; @@ -275,6 +324,9 @@ sub mergeNums return $m->{mergeNums}; } +# +# Return a list of backup indexes for which the directory exists +# sub backupList { my($m, $share, $dir) = @_; @@ -296,7 +348,7 @@ sub backupList } $path .= $sharePathM; next if ( !-d $path ); - push(@backupList, $backupNum); + push(@backupList, $i); } return @backupList; } @@ -349,7 +401,7 @@ sub dirHistory } } foreach my $file ( @dir ) { - $file = $1 if ( $file =~ /(.*)/ ); + $file = $1 if ( $file =~ /(.*)/s ); my $fileUM = $file; $fileUM = $m->{bpc}->fileNameUnmangle($fileUM) if ( $mangle ); #print(STDERR "Doing $fileUM\n"); @@ -396,15 +448,27 @@ sub dirHistory } } } - $files->{$fileUM}[$i]{relPath} = "$dir/$fileUM"; - $files->{$fileUM}[$i]{sharePathM} = "$sharePathM/$file"; - $files->{$fileUM}[$i]{fullPath} = "$path/$file"; - $files->{$fileUM}[$i]{backupNum} = $backupNum; - $files->{$fileUM}[$i]{compress} = $compress; - $files->{$fileUM}[$i]{nlink} = $s[3]; - $files->{$fileUM}[$i]{inode} = $s[1]; + ($files->{$fileUM}[$i]{relPath} = "$dir/$fileUM") =~ s{//+}{/}g; + ($files->{$fileUM}[$i]{sharePathM} = "$sharePathM/$file") + =~ s{//+}{/}g; + ($files->{$fileUM}[$i]{fullPath} = "$path/$file") =~ s{//+}{/}g; + $files->{$fileUM}[$i]{backupNum} = $backupNum; + $files->{$fileUM}[$i]{compress} = $compress; + $files->{$fileUM}[$i]{nlink} = $s[3]; + $files->{$fileUM}[$i]{inode} = $s[1]; } + # + # Flag deleted files + # + if ( defined($attr) ) { + my $a = $attr->get; + foreach my $fileUM ( keys(%$a) ) { + next if ( $a->{$fileUM}{type} != BPC_FTYPE_DELETED ); + $files->{$fileUM}[$i]{type} = BPC_FTYPE_DELETED; + } + } + # # Merge old backups. Don't merge directories from old # backups because every backup has an accurate directory @@ -420,18 +484,19 @@ sub dirHistory $files->{$fileUM}[$i] = $files->{$fileUM}[$k]; } } + } - # - # Finally, remove deleted files - # - if ( defined($attr) ) { - my $a = $attr->get; - foreach my $fileUM ( keys(%$a) ) { - next if ( $a->{$fileUM}{type} != BPC_FTYPE_DELETED ); - $files->{$fileUM}[$i] = undef if ( defined($files->{$fileUM}) ); - } - } + # + # Remove deleted files + # + for ( $i = 0 ; $i < @{$m->{backups}} ; $i++ ) { + foreach my $fileUM ( keys(%$files) ) { + next if ( !defined($files->{$fileUM}[$i]) + || $files->{$fileUM}[$i]{type} != BPC_FTYPE_DELETED ); + $files->{$fileUM}[$i] = undef; + } } + #print STDERR "Returning:\n", Dumper($files); return $files; } @@ -448,6 +513,7 @@ sub find { my($m, $backupNum, $share, $path, $depth, $callback, @callbackArgs) = @_; + #print(STDERR "find: got $backupNum, $share, $path\n"); # # First call the callback on the given $path #