X-Git-Url: http://git.rot13.org/?p=BackupPC.git;a=blobdiff_plain;f=bin%2FBackupPC_tarPCCopy;h=1fcd3dead4a619cef28f5eab9569ed2f79a42cad;hp=8c6ff2e9f3f1f486f046addc1d1f885feb7672c4;hb=c615e1bfc6f2b0604a2658996f5dd6b6cfa9469c;hpb=4cdaa6b8a9f5161ee2da4371d68cbbad41248ea0 diff --git a/bin/BackupPC_tarPCCopy b/bin/BackupPC_tarPCCopy index 8c6ff2e..1fcd3de 100755 --- a/bin/BackupPC_tarPCCopy +++ b/bin/BackupPC_tarPCCopy @@ -1,4 +1,4 @@ -#!/bin/perl +#!/usr/bin/perl #============================================================= -*-perl-*- # # BackupPC_tarPCCopy: create a tar archive of the PC directory @@ -6,6 +6,8 @@ # contain hardlinks to the pool directory, which should be copied # before BackupPC_tarPCCopy is run. # +# See the documentation for use. +# # DESCRIPTION # # Usage: BackupPC_tarPCCopy [options] files/directories... @@ -18,7 +20,7 @@ # Craig Barratt # # COPYRIGHT -# Copyright (C) 2005 Craig Barratt +# Copyright (C) 2005-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 @@ -36,7 +38,7 @@ # #======================================================================== # -# Version 3.0.0beta0, released 11 Jul 2006. +# Version 3.2.0, released 31 Jul 2010. # # See http://backuppc.sourceforge.net. # @@ -175,8 +177,7 @@ sub archiveFile my @s = stat($_); # - # We just handle directories and files; no symlinks or - # char/block special files. + # Default type - we'll update later if it is a symlink, hardlink etc # $hdr->{type} = -d _ ? BPC_FTYPE_DIR : -f _ ? BPC_FTYPE_FILE @@ -230,8 +231,7 @@ sub archiveFile } } $hdr->{compress} = $ClientBkupCompress; - if ( $hdr->{type} == BPC_FTYPE_FILE && $hdr->{nlink} > 1 - && $hdr->{name} =~ /^f/ ) { + if ( $hdr->{type} == BPC_FTYPE_FILE && $hdr->{name} =~ /^f/ ) { (my $dir = $hdr->{fullPath}) =~ s{(.*)/.*}{$1}; if ( $ClientDir ne $dir ) { $ClientDir = $dir; @@ -247,8 +247,12 @@ sub archiveFile my $name = $hdr->{name}; $name = $bpc->fileNameUnmangle($name) if ( $ClientBkupMangle ); my $attr = $ClientDirAttr->get($name); - $hdr->{realSize} = $attr->{size} if ( defined($attr) ); - #print STDERR "$hdr->{fullPath} has real size $hdr->{realSize}\n"; + if ( defined($attr) ) { + $hdr->{type} = $attr->{type}; + $hdr->{realSize} = $attr->{size} + if ( $attr->{type} == BPC_FTYPE_FILE ); + } + #print STDERR "$hdr->{fullPath} has type $hdr->{type} and real size $hdr->{realSize}\n"; } } } else { @@ -425,91 +429,97 @@ sub TarWriteFile $hdr->{name} .= "/" if ( $hdr->{name} !~ m{/$} ); TarWriteFileInfo($fh, $hdr); $DirCnt++; - } elsif ( $hdr->{type} == BPC_FTYPE_FILE ) { + } elsif ( $hdr->{type} == BPC_FTYPE_FILE + || $hdr->{type} == BPC_FTYPE_HARDLINK + || $hdr->{type} == BPC_FTYPE_SYMLINK + || $hdr->{type} == BPC_FTYPE_CHARDEV + || $hdr->{type} == BPC_FTYPE_BLOCKDEV + || $hdr->{type} == BPC_FTYPE_FIFO + || $hdr->{type} == BPC_FTYPE_SOCKET ) { # - # Regular file: write the header and file + # Underlying file is a regular file: write the header and file # my($data, $dataMD5, $size, $linkName); - if ( $hdr->{type} == BPC_FTYPE_FILE && $hdr->{nlink} > 1 ) { - if ( defined($Inode2Path{$hdr->{inode}}) ) { - $linkName = $Inode2Path{$hdr->{inode}}; - #print STDERR "Got cache hit for $linkName\n"; - } else { - my $f = BackupPC::FileZIO->open($hdr->{fullPath}, 0, - $hdr->{compress}); - if ( !defined($f) ) { - print(STDERR "Unable to open file $hdr->{fullPath}\n"); - $ErrorCnt++; - return; - } + if ( defined($Inode2Path{$hdr->{inode}}) ) { + $linkName = $Inode2Path{$hdr->{inode}}; + #print STDERR "Got cache hit for $linkName\n"; + } else { + my $f = BackupPC::FileZIO->open($hdr->{fullPath}, 0, + $hdr->{compress}); + if ( !defined($f) ) { + print(STDERR "Unable to open file $hdr->{fullPath}\n"); + $ErrorCnt++; + return; + } + # + # Try to find the hardlink it points to by computing + # the pool file digest. + # + $f->read(\$dataMD5, $BufSize); + if ( !defined($hdr->{realSize}) ) { # - # Try to find the hardlink it points to by computing - # the pool file digest. + # Need to get the real size # - $f->read(\$dataMD5, $BufSize); - if ( !defined($hdr->{realSize}) ) { - # - # Need to get the real size - # - $size = length($dataMD5); - while ( $f->read(\$data, $BufSize) > 0 ) { - $size += length($data); - } - $hdr->{realSize} = $size; + $size = length($dataMD5); + while ( $f->read(\$data, $BufSize) > 0 ) { + $size += length($data); } - $f->close(); - my $md5 = Digest::MD5->new; - my $len = length($dataMD5); - $hdr->{realSize} = $len if ( $hdr->{type} != BPC_FTYPE_FILE ); - if ( $hdr->{realSize} < 1048576 - && length($dataMD5) != $hdr->{realSize} ) { - print(STDERR "File $hdr->{fullPath} has bad size" - . " (expect $hdr->{realSize}, got $len)\n"); - } else { - my $digest = $bpc->Buffer2MD5($md5, $hdr->{realSize}, - \$dataMD5); - my $path = $bpc->MD52Path($digest, $hdr->{compress}); - my $i = -1; - - # print(STDERR "Looking up $hdr->{fullPath} at $path\n"); - while ( 1 ) { - my $testPath = $path; - $testPath .= "_$i" if ( $i >= 0 ); - last if ( !-f $testPath ); - my $inode = (stat(_))[1]; - if ( $inode == $hdr->{inode} ) { - # - # Found it! Just emit a tar hardlink - # - $testPath =~ s{\Q$TopDir\E}{..}; - $linkName = $testPath; - last; - } - $i++; + $hdr->{realSize} = $size; + } + $f->close(); + my $md5 = Digest::MD5->new; + my $len = length($dataMD5); + if ( $hdr->{realSize} < 1048576 + && length($dataMD5) != $hdr->{realSize} ) { + print(STDERR "File $hdr->{fullPath} has bad size" + . " (expect $hdr->{realSize}, got $len)\n"); + } else { + my $digest = $bpc->Buffer2MD5($md5, $hdr->{realSize}, + \$dataMD5); + my $path = $bpc->MD52Path($digest, $hdr->{compress}); + my $i = -1; + + # print(STDERR "Looking up $hdr->{fullPath} at $path\n"); + while ( 1 ) { + my $testPath = $path; + $testPath .= "_$i" if ( $i >= 0 ); + last if ( !-f $testPath ); + my $inode = (stat(_))[1]; + if ( $inode == $hdr->{inode} ) { + # + # Found it! Just emit a tar hardlink + # + $testPath =~ s{\Q$TopDir\E}{..}; + $linkName = $testPath; + last; } + $i++; } } - if ( defined($linkName) ) { - $hdr->{type} = BPC_FTYPE_HARDLINK; - $hdr->{linkname} = $linkName; - TarWriteFileInfo($fh, $hdr); - $HLinkCnt++; - #print STDERR "$hdr->{relPath} matches $testPath\n"; - if ( !$opts{c} && $hdr->{nlink} > 2 ) { - # - # add it to the cache if there are more - # than 2 links (pool + current file), - # since there are more to go - # - $Inode2Path{$hdr->{inode}} = $linkName; - } - return; + } + if ( defined($linkName) ) { + $hdr->{type} = BPC_FTYPE_HARDLINK; + $hdr->{linkname} = $linkName; + TarWriteFileInfo($fh, $hdr); + $HLinkCnt++; + #print STDERR "$hdr->{relPath} matches $testPath\n"; + if ( !$opts{c} && $hdr->{nlink} > 2 ) { + # + # add it to the cache if there are more + # than 2 links (pool + current file), + # since there are more to go + # + $Inode2Path{$hdr->{inode}} = $linkName; } - $size = 0; + return; + } + $size = 0; + if ( $hdr->{nlink} > 1 ) { print STDERR "Can't find $hdr->{relPath} in pool, will copy file\n"; $ErrorCnt++; } + $hdr->{type} = BPC_FTYPE_FILE; my $f = BackupPC::FileZIO->open($hdr->{fullPath}, 0, 0); if ( !defined($f) ) {