"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "lib/BackupPC/CGI/DirHistory.pm" between
BackupPC-4.3.2.tar.gz and BackupPC-4.4.0.tar.gz

About: BackupPC is a high-performance, enterprise-grade system for backing up Linux and WinXX PCs and laptops to a server’s disk (http/cgi user interface).

DirHistory.pm  (BackupPC-4.3.2):DirHistory.pm  (BackupPC-4.4.0)
skipping to change at line 30 skipping to change at line 30
# This program is distributed in the hope that it will be useful, # This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of # but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details. # GNU General Public License for more details.
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
# #
#======================================================================== #========================================================================
# #
# Version 4.3.2, released 17 Feb 2020. # Version 4.4.0, released 20 Jun 2020.
# #
# See http://backuppc.sourceforge.net. # See http://backuppc.sourceforge.net.
# #
#======================================================================== #========================================================================
package BackupPC::CGI::DirHistory; package BackupPC::CGI::DirHistory;
use strict; use strict;
use BackupPC::CGI::Lib qw(:all); use BackupPC::CGI::Lib qw(:all);
use BackupPC::View; use BackupPC::View;
skipping to change at line 53 skipping to change at line 53
sub action sub action
{ {
my $Privileged = CheckPermission($In{host}); my $Privileged = CheckPermission($In{host});
my($i, $dirStr, $fileStr, $attr); my($i, $dirStr, $fileStr, $attr);
my $checkBoxCnt = 0; my $checkBoxCnt = 0;
if ( !$Privileged ) { if ( !$Privileged ) {
ErrorExit(eval("qq{$Lang->{Only_privileged_users_can_browse_backup_files }}")); ErrorExit(eval("qq{$Lang->{Only_privileged_users_can_browse_backup_files }}"));
} }
my $host = $In{host};
my $share = $In{share}; my $host = $In{host};
my $dir = $In{dir}; my $share = $In{share};
my $dirURI = $dir; my $dir = $In{dir};
my $dirURI = $dir;
my $shareURI = $share; my $shareURI = $share;
$dirURI =~ s/([^\w.\/-])/uc sprintf("%%%02x", ord($1))/eg;
$shareURI =~ s/([^\w.\/-])/uc sprintf("%%%02x", ord($1))/eg; $dirURI =~ s/([^\w.\/-])/uc sprintf("%%%02x", ord($1))/eg;
$shareURI =~ s/([^\w.\/-])/uc sprintf("%%%02x", ord($1))/eg;
ErrorExit($Lang->{Empty_host_name}) if ( $host eq "" ); ErrorExit($Lang->{Empty_host_name}) if ( $host eq "" );
my @Backups = $bpc->BackupInfoRead($host); my @Backups = $bpc->BackupInfoRead($host);
my $view = BackupPC::View->new($bpc, $host, \@Backups, {inode => 1}); my $view = BackupPC::View->new($bpc, $host, \@Backups, {inode => 1});
my $hist = $view->dirHistory($share, $dir); my $hist = $view->dirHistory($share, $dir);
my($backupNumStr, $backupTimeStr, $fileStr); my($backupNumStr, $backupTimeStr, $fileStr);
$dir = "/$dir" if ( $dir !~ /^\// ); $dir = "/$dir" if ( $dir !~ /^\// );
if ( "/$host/$share/$dir/" =~ m{/\.\./} ) { if ( "/$host/$share/$dir/" =~ m{/\.\./} ) {
ErrorExit($Lang->{Nice_try__but_you_can_t_put}); ErrorExit($Lang->{Nice_try__but_you_can_t_put});
} }
my @backupList = $view->backupList($share, $dir); my @backupList = $view->backupList($share, $dir);
foreach $i ( @backupList ) { foreach $i ( @backupList ) {
my $backupTime = timeStamp2($Backups[$i]{startTime}); my $backupTime = timeStamp2($Backups[$i]{startTime});
my $num = $Backups[$i]{num}; my $num = $Backups[$i]{num};
$backupNumStr .= "<td align=center><a href=\"$MyURL?action=browse" $backupNumStr .=
. "&host=${EscURI($host)}&num=$num&share=$shareURI" "<td align=center><a href=\"$MyURL?action=browse"
. "&dir=$dirURI\">$num</a></td>"; . "&host=${EscURI($host)}&num=$num&share=$shareURI"
$backupTimeStr .= "<td align=center>$backupTime</td>"; . "&dir=$dirURI\">$num</a></td>";
$backupTimeStr .= "<td align=center>$backupTime</td>";
} }
# #
# For V3 we rely on inodes to identify identical files. # For V3 we rely on inodes to identify identical files.
# #
# For V4 the (fake) inodes might be the same between different versions of # For V4 the (fake) inodes might be the same between different versions of
# a file, so we rely on matching the digests instead. # a file, so we rely on matching the digests instead.
# #
# So, if digests are defined, we use those. Otherwise we used inodes. # So, if digests are defined, we use those. Otherwise we used inodes.
# #
foreach my $f ( sort {uc($a) cmp uc($b)} keys(%$hist) ) { foreach my $f ( sort { uc($a) cmp uc($b) } keys(%$hist) ) {
my %inode2name; my %inode2name;
my %digest2name; my %digest2name;
my $nameCnt = 0; my $nameCnt = 0;
(my $fDisp = "${EscHTML($f)}") =~ s/ /&nbsp;/g; (my $fDisp = "${EscHTML($f)}") =~ s/ /&nbsp;/g;
$fDisp = decode_utf8($fDisp); $fDisp = decode_utf8($fDisp);
$fileStr .= "<tr><td align=\"left\" class=\"histView\">$fDisp</td>"; $fileStr .= "<tr><td align=\"left\" class=\"histView\">$fDisp</td>";
my($colSpan, $url, $inode, $type, $digest); my($colSpan, $url, $inode, $type, $digest);
my $tdClass = ' class="histView"'; my $tdClass = ' class="histView"';
foreach $i ( @backupList ) {
my($path); foreach $i ( @backupList ) {
if ( $colSpan > 0 ) { my($path);
# if ( $colSpan > 0 ) {
# The file is the same if it also size==0 (inode == -1) #
# or if it is a directory and the previous one is (inode == -2) # The file is the same if it also size==0 (inode == -1)
# or if the inodes and digests agree and the types are the same. # or if it is a directory and the previous one is (inode == -2)
# # or if the inodes and digests agree and the types are the same.
if ( defined($hist->{$f}[$i]) #
&& $hist->{$f}[$i]{type} == $type if (
&& (($hist->{$f}[$i]{size} == 0 && $inode == -1) defined($hist->{$f}[$i])
|| ($hist->{$f}[$i]{type} == BPC_FTYPE_DIR && $inode == - && $hist->{$f}[$i]{type} == $type
2) && (
|| (length($hist->{$f}[$i]{digest}) ? $hist->{$f}[$i]{dig ($hist->{$f}[$i]{size} == 0 && $inode == -1)
est} eq $digest || ($hist->{$f}[$i]{type} == BPC_FTYPE_DIR && $inode ==
: $hist->{$f}[$i]{in -2)
ode} == $inode)) ) { || (
$colSpan++; length($hist->{$f}[$i]{digest})
next; ? $hist->{$f}[$i]{digest} eq $digest
} : $hist->{$f}[$i]{inode} == $inode
# )
# Also handle the case of a sequence of missing files )
# ) {
if ( !defined($hist->{$f}[$i]) && $inode == -3 ) { $colSpan++;
$colSpan++; next;
next; }
} #
$fileStr .= "<td align=center colspan=$colSpan$tdClass>" # Also handle the case of a sequence of missing files
. "$url</td>"; #
$colSpan = 0; if ( !defined($hist->{$f}[$i]) && $inode == -3 ) {
$tdClass = ' class="histView"'; $colSpan++;
} next;
if ( !defined($hist->{$f}[$i]) ) { }
$colSpan = 1; $fileStr .= "<td align=center colspan=$colSpan$tdClass>$url</td>
$url = "&nbsp;"; ";
$inode = -3; # special value for missing $colSpan = 0;
$tdClass = ' class="histView"';
}
if ( !defined($hist->{$f}[$i]) ) {
$colSpan = 1;
$url = "&nbsp;";
$inode = -3; # special value for missing
$digest = ""; $digest = "";
$tdClass = ' class="histViewMis"'; $tdClass = ' class="histViewMis"';
next; next;
} }
if ( $dir eq "" ) { if ( $dir eq "" ) {
$path = "/$f"; $path = "/$f";
} else { } else {
($path = "$dir/$f") =~ s{//+}{/}g; ($path = "$dir/$f") =~ s{//+}{/}g;
} }
$path =~ s{^/+}{/}; $path =~ s{^/+}{/};
$path =~ s/([^\w.\/-])/uc sprintf("%%%02X", ord($1))/eg; $path =~ s/([^\w.\/-])/uc sprintf("%%%02X", ord($1))/eg;
my $num = $hist->{$f}[$i]{backupNum}; my $num = $hist->{$f}[$i]{backupNum};
if ( $hist->{$f}[$i]{type} == BPC_FTYPE_DIR ) { if ( $hist->{$f}[$i]{type} == BPC_FTYPE_DIR ) {
$inode = -2; # special value for dir $inode = -2; # special value for dir
$type = $hist->{$f}[$i]{type}; $type = $hist->{$f}[$i]{type};
$url = <<EOF; $url = <<EOF;
<a href="$MyURL?action=dirHistory&host=${EscURI($host)}&share=$shareURI&dir=$pat h">$Lang->{DirHistory_dirLink}</a> <a href="$MyURL?action=dirHistory&host=${EscURI($host)}&share=$shareURI&dir=$pat h">$Lang->{DirHistory_dirLink}</a>
EOF EOF
} else { } else {
my $thisName; my $thisName;
$inode = $hist->{$f}[$i]{inode}; $inode = $hist->{$f}[$i]{inode};
$digest = $hist->{$f}[$i]{digest}; $digest = $hist->{$f}[$i]{digest};
$type = $hist->{$f}[$i]{type}; $type = $hist->{$f}[$i]{type};
# #
# special value for empty file # special value for empty file
# #
$inode = -1 if ( $hist->{$f}[$i]{size} == 0 ); $inode = -1 if ( $hist->{$f}[$i]{size} == 0 );
if ( length($digest) ) { if ( length($digest) ) {
if ( !defined($digest2name{$digest}) ) { if ( !defined($digest2name{$digest}) ) {
$digest2name{$digest} = "$Lang->{DirHistory_fileLink}$na meCnt"; $digest2name{$digest} = "$Lang->{DirHistory_fileLink}$na meCnt";
$nameCnt++; $nameCnt++;
} }
$thisName = $digest2name{$digest}; $thisName = $digest2name{$digest};
} else { } else {
if ( !defined($inode2name{$inode}) ) { if ( !defined($inode2name{$inode}) ) {
$inode2name{$inode} = "$Lang->{DirHistory_fileLink}$name Cnt"; $inode2name{$inode} = "$Lang->{DirHistory_fileLink}$name Cnt";
$nameCnt++; $nameCnt++;
} }
$thisName = $inode2name{$inode} $thisName = $inode2name{$inode};
} }
$url = <<EOF; $url = <<EOF;
<a href="$MyURL?action=RestoreFile&host=${EscURI($host)}&num=$num&share=$shareUR I&dir=$path">$thisName</a> <a href="$MyURL?action=RestoreFile&host=${EscURI($host)}&num=$num&share=$shareUR I&dir=$path">$thisName</a>
EOF EOF
} }
$colSpan = 1; $colSpan = 1;
} }
if ( $colSpan > 0 ) { if ( $colSpan > 0 ) {
$fileStr .= "<td align=center colspan=$colSpan$tdClass>$url</td>"; $fileStr .= "<td align=center colspan=$colSpan$tdClass>$url</td>";
$colSpan = 0; $colSpan = 0;
} }
$fileStr .= "</tr>\n"; $fileStr .= "</tr>\n";
} }
# #
# allow each level of the directory path to be navigated to # allow each level of the directory path to be navigated to
# #
my($thisPath, $dirDisplay); my($thisPath, $dirDisplay);
my $dirClean = $dir; my $dirClean = $dir;
$dirClean =~ s{//+}{/}g; $dirClean =~ s{//+}{/}g;
$dirClean =~ s{/+$}{}; $dirClean =~ s{/+$}{};
my @dirElts = split(/\//, $dirClean); my @dirElts = split(/\//, $dirClean);
skipping to change at line 210 skipping to change at line 220
$thisDir = decode_utf8($share); $thisDir = decode_utf8($share);
$thisPath = "/"; $thisPath = "/";
} else { } else {
$thisPath .= "/" if ( $thisPath ne "/" ); $thisPath .= "/" if ( $thisPath ne "/" );
$thisPath .= "$d"; $thisPath .= "$d";
$thisDir = decode_utf8($d); $thisDir = decode_utf8($d);
} }
my $thisPathURI = $thisPath; my $thisPathURI = $thisPath;
$thisPathURI =~ s/([^\w.\/-])/uc sprintf("%%%02x", ord($1))/eg; $thisPathURI =~ s/([^\w.\/-])/uc sprintf("%%%02x", ord($1))/eg;
$dirDisplay .= "/" if ( $dirDisplay ne "" ); $dirDisplay .= "/" if ( $dirDisplay ne "" );
$dirDisplay .= "<a href=\"$MyURL?action=dirHistory&host=${EscURI($host)} $dirDisplay .=
&share=$shareURI&dir=$thisPathURI\">${EscHTML($thisDir)}</a>"; "<a href=\"$MyURL?action=dirHistory&host=${EscURI($host)}&share=$share
URI&dir=$thisPathURI\">${EscHTML($thisDir)}</a>";
} }
my $content = eval("qq{$Lang->{DirHistory_for__host}}"); my $content = eval("qq{$Lang->{DirHistory_for__host}}");
Header(eval("qq{$Lang->{DirHistory_backup_for__host}}"), $content); Header(eval("qq{$Lang->{DirHistory_backup_for__host}}"), $content);
Trailer(); Trailer();
} }
1; 1;
 End of changes. 13 change blocks. 
92 lines changed or deleted 102 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)