X-Git-Url: http://git.rot13.org/?p=BackupPC.git;a=blobdiff_plain;f=lib%2FBackupPC%2FView.pm;h=c8664af7d745bb1c1718dd6f79864c01c0b014d6;hp=f550b00cf11b470af05c03f8c1ab815207fc05aa;hb=488bb662f6d144d42376b3d14e9b1e438e00e6f8;hpb=df717077755b9331fa245f72933ef03add7a3710 diff --git a/lib/BackupPC/View.pm b/lib/BackupPC/View.pm index f550b00..c8664af 100644 --- a/lib/BackupPC/View.pm +++ b/lib/BackupPC/View.pm @@ -13,7 +13,7 @@ # Craig Barratt # # COPYRIGHT -# Copyright (C) 2002-2003 Craig Barratt +# Copyright (C) 2002-2009 Craig Barratt # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -31,7 +31,7 @@ # #======================================================================== # -# Version 3.0.0beta1, released 30 Jul 2006. +# Version 3.2.0, released 31 Jul 2010. # # See http://backuppc.sourceforge.net. # @@ -46,24 +46,25 @@ use BackupPC::Lib; use BackupPC::Attrib qw(:all); use BackupPC::FileZIO; use Data::Dumper; +use Encode qw/from_to/; sub new { - my($class, $bpc, $host, $backups) = @_; + my($class, $bpc, $host, $backups, $options) = @_; my $m = bless { - bpc => $bpc, # BackupPC::Lib object - host => $host, # host name - backups => $backups, # all backups for this host - num => -1, # backup number - idx => -1, # index into backups for backup - # we are viewing - dirPath => undef, # path to current directory - dirAttr => undef, # attributes of current directory + bpc => $bpc, # BackupPC::Lib object + host => $host, # host name + backups => $backups, # all backups for this host + num => -1, # backup number + idx => -1, # index into backups for backup + # we are viewing + dirPath => undef, # path to current directory + dirAttr => undef, # attributes of current directory + dirOpts => $options, # $options is a hash of file attributes we need: + # type, inode, or nlink. If set, these parameters + # are added to the returned hash. + # See BackupPC::Lib::dirRead(). }, $class; - for ( my $i = 0 ; $i < @{$m->{backups}} ; $i++ ) { - next if ( defined($m->{backups}[$i]{level}) ); - $m->{backups}[$i]{level} = $m->{backups}[$i]{type} eq "incr" ? 1 : 0; - } $m->{topDir} = $m->{bpc}->TopDir(); return $m; } @@ -109,7 +110,8 @@ sub dirCache push(@{$m->{mergeNums}}, $backupNum); my $mangle = $m->{backups}[$i]{mangle}; my $compress = $m->{backups}[$i]{compress}; - my $path = "$m->{topDir}/pc/$m->{host}/$backupNum/"; + my $path = "$m->{topDir}/pc/$m->{host}/$backupNum/"; + my $legacyCharset = $m->{backups}[$i]{version} < 3.0; my $sharePathM; if ( $mangle ) { $sharePathM = $m->{bpc}->fileNameEltMangle($share) @@ -118,8 +120,18 @@ sub dirCache $sharePathM = $share . $dir; } $path .= $sharePathM; - #print(STDERR "Opening $path (share=$share)\n"); - if ( !opendir(DIR, $path) ) { + #print(STDERR "Opening $path (share=$share, mangle=$mangle)\n"); + + my $dirOpts = { %{$m->{dirOpts} || {} } }; + my $attribOpts = { compress => $compress }; + if ( $legacyCharset ) { + $dirOpts->{charsetLegacy} + = $attribOpts->{charsetLegacy} + = $m->{bpc}->{Conf}{ClientCharsetLegacy} || "iso-8859-1"; + } + + my $dirInfo = $m->{bpc}->dirRead($path, $dirOpts); + if ( !defined($dirInfo) ) { if ( $i == $m->{idx} ) { # # Oops, directory doesn't exist. @@ -129,18 +141,16 @@ sub dirCache } next; } - my @dir = readdir(DIR); - closedir(DIR); my $attr; if ( $mangle ) { - $attr = BackupPC::Attrib->new({ compress => $compress }); - if ( -f $attr->fileName($path) && !$attr->read($path) ) { - $m->{error} = "Can't read attribute file in $path"; + $attr = BackupPC::Attrib->new($attribOpts); + if ( !$attr->read($path) ) { + $m->{error} = "Can't read attribute file in $path: " . $attr->errStr(); $attr = undef; } } - foreach my $file ( @dir ) { - $file = $1 if ( $file =~ /(.*)/s ); + foreach my $entry ( @$dirInfo ) { + my $file = $1 if ( $entry->{name} =~ /(.*)/s ); my $fileUM = $file; $fileUM = $m->{bpc}->fileNameUnmangle($fileUM) if ( $mangle ); #print(STDERR "Doing $fileUM\n"); @@ -152,14 +162,14 @@ sub dirCache || $file eq "." || $file eq "backupInfo" || $mangle && $file eq "attrib" ); - # - # skip directories in earlier backups (each backup always - # has the complete directory tree). - # - my @s = stat("$path/$file"); - next if ( $i < $m->{idx} && -d _ ); + if ( defined($attr) && defined(my $a = $attr->get($fileUM)) ) { $m->{files}{$fileUM} = $a; + # + # skip directories in earlier backups (each backup always + # has the complete directory tree). + # + next if ( $i < $m->{idx} && $a->{type} == BPC_FTYPE_DIR ); $attr->set($fileUM, undef); } else { # @@ -167,6 +177,13 @@ sub dirCache # is on. We have to stat the file and read compressed files # to determine their size. # + my $realPath = "$path/$file"; + + from_to($realPath, "utf8", $attribOpts->{charsetLegacy}) + if ( $attribOpts->{charsetLegacy} ne "" ); + + my @s = stat($realPath); + next if ( $i < $m->{idx} && -d _ ); $m->{files}{$fileUM} = { type => -d _ ? BPC_FTYPE_DIR : BPC_FTYPE_FILE, mode => $s[2], @@ -179,10 +196,10 @@ sub dirCache # # Compute the correct size by reading the whole file # - my $f = BackupPC::FileZIO->open("$path/$file", + my $f = BackupPC::FileZIO->open($realPath, 0, $compress); if ( !defined($f) ) { - $m->{error} = "Can't open $path/$file"; + $m->{error} = "Can't open $realPath"; } else { my($data, $size); while ( $f->read(\$data, 65636 * 8) > 0 ) { @@ -197,10 +214,14 @@ sub dirCache ($m->{files}{$fileUM}{sharePathM} = "$sharePathM/$file") =~ s{//+}{/}g; ($m->{files}{$fileUM}{fullPath} = "$path/$file") =~ s{//+}{/}g; + from_to($m->{files}{$fileUM}{fullPath}, "utf8", $attribOpts->{charsetLegacy}) + if ( $attribOpts->{charsetLegacy} ne "" ); $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}{nlink} = $entry->{nlink} + if ( $m->{dirOpts}{nlink} ); + $m->{files}{$fileUM}{inode} = $entry->{inode} + if ( $m->{dirOpts}{inode} ); } # # Also include deleted files @@ -215,12 +236,16 @@ sub dirCache $m->{files}{$fileUM}{relPath} = "$dir/$fileUM"; $m->{files}{$fileUM}{sharePathM} = "$sharePathM/$file"; $m->{files}{$fileUM}{fullPath} = "$path/$file"; + from_to($m->{files}{$fileUM}{fullPath}, "utf8", $attribOpts->{charsetLegacy}) + if ( $attribOpts->{charsetLegacy} ne "" ); $m->{files}{$fileUM}{backupNum} = $backupNum; $m->{files}{$fileUM}{compress} = $compress; $m->{files}{$fileUM}{nlink} = 0; $m->{files}{$fileUM}{inode} = 0; } } + + last if $m->{dirOpts}->{only_increment}; # XXX ASA Search extension } # # Prune deleted files @@ -375,6 +400,7 @@ sub dirHistory my $mangle = $m->{backups}[$i]{mangle}; my $compress = $m->{backups}[$i]{compress}; my $path = "$m->{topDir}/pc/$m->{host}/$backupNum/"; + my $legacyCharset = $m->{backups}[$i]{version} < 3.0; my $sharePathM; if ( $mangle ) { $sharePathM = $m->{bpc}->fileNameEltMangle($share) @@ -384,24 +410,32 @@ sub dirHistory } $path .= $sharePathM; #print(STDERR "Opening $path (share=$share)\n"); - if ( !opendir(DIR, $path) ) { + + my $dirOpts = { %{$m->{dirOpts} || {} } }; + my $attribOpts = { compress => $compress }; + if ( $legacyCharset ) { + $dirOpts->{charsetLegacy} + = $attribOpts->{charsetLegacy} + = $m->{bpc}->{Conf}{ClientCharsetLegacy} || "iso-8859-1"; + } + + my $dirInfo = $m->{bpc}->dirRead($path, $dirOpts); + if ( !defined($dirInfo) ) { # # Oops, directory doesn't exist. # next; } - my @dir = readdir(DIR); - closedir(DIR); my $attr; if ( $mangle ) { - $attr = BackupPC::Attrib->new({ compress => $compress }); - if ( -f $attr->fileName($path) && !$attr->read($path) ) { + $attr = BackupPC::Attrib->new($attribOpts); + if ( !$attr->read($path) ) { $m->{error} = "Can't read attribute file in $path"; $attr = undef; } } - foreach my $file ( @dir ) { - $file = $1 if ( $file =~ /(.*)/s ); + foreach my $entry ( @$dirInfo ) { + my $file = $1 if ( $entry->{name} =~ /(.*)/s ); my $fileUM = $file; $fileUM = $m->{bpc}->fileNameUnmangle($fileUM) if ( $mangle ); #print(STDERR "Doing $fileUM\n"); @@ -412,7 +446,11 @@ sub dirHistory || $file eq "." || $mangle && $file eq "attrib" || defined($files->{$fileUM}[$i]) ); - my @s = stat("$path/$file"); + + my $realPath = "$path/$file"; + from_to($realPath, "utf8", $attribOpts->{charsetLegacy}) + if ( $attribOpts->{charsetLegacy} ne "" ); + my @s = stat($realPath); if ( defined($attr) && defined(my $a = $attr->get($fileUM)) ) { $files->{$fileUM}[$i] = $a; $attr->set($fileUM, undef); @@ -434,7 +472,7 @@ sub dirHistory # # Compute the correct size by reading the whole file # - my $f = BackupPC::FileZIO->open("$path/$file", + my $f = BackupPC::FileZIO->open("$realPath", 0, $compress); if ( !defined($f) ) { $m->{error} = "Can't open $path/$file"; @@ -454,8 +492,10 @@ sub dirHistory ($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]; + $files->{$fileUM}[$i]{nlink} = $entry->{nlink} + if ( $m->{dirOpts}{nlink} ); + $files->{$fileUM}[$i]{inode} = $entry->{inode} + if ( $m->{dirOpts}{inode} ); } #