⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rsyncdigest.pm

📁 老外写的linux下的文件备份软件
💻 PM
📖 第 1 页 / 共 2 页
字号:
##  - doCache <  0: don't generate/use cached checksums#  - doCache == 0: don't generate, but do use cached checksums if available#  - doCache >  0: generate (if necessary) and use cached checksums## Note: caching is only enabled when compression is on and the# checksum seed is RSYNC_CSUMSEED_CACHE (32761).## Returns 0 on success.  Returns a variety of negative values on error.#sub digestStart{    my($class, $fileName, $fileSize, $blockSize, $defBlkSize,       $checksumSeed, $needMD4, $compress, $doCache, $protocol_version) = @_;    return -1 if ( !$RsyncLibOK );    my $data;    my $dg = bless {        name     => $fileName,        needMD4  => $needMD4,        digest   => File::RsyncP::Digest->new,        protocol_version => $protocol_version,    }, $class;    $dg->{digest}->protocol($dg->{protocol_version})                        if ( defined($dg->{protocol_version}) );    if ( $fileSize > 0 && $compress && $doCache >= 0 ) {        open(my $fh, "<", $fileName) || return -2;        binmode($fh);        return -3 if ( sysread($fh, $data, 4096) < 1 );        my $ret;        if ( (vec($data, 0, 8) == 0x78 || vec($data, 0, 8) == 0xd6) && $doCache > 0                     && $checksumSeed == RSYNC_CSUMSEED_CACHE ) {            #            # RSYNC_CSUMSEED_CACHE (32761) is the magic number that            # rsync uses for checksumSeed with the --fixed-csum option.            #            # We now add the cached checksum data to the file.  There            # is a possible race condition here since two BackupPC_dump            # processes might call this function at the same time            # on the same file.  But this should be ok since both            # processes will write the same data, and the order            # in which they write it doesn't matter.            #            close($fh);            $ret = $dg->digestAdd($fileName,                            $blockSize                                || BackupPC::Xfer::RsyncDigest->blockSize(                                                    $fileSize, $defBlkSize),                                $checksumSeed, 0, $dg->{protocol_version});            if ( $ret < 0 ) {                &$Log("digestAdd($fileName) failed ($ret)");            }            #            # now re-open the file and re-read the first byte            #            open($fh, "<", $fileName) || return -4;            binmode($fh);            return -5 if ( read($fh, $data, 1) != 1 );        }        if ( $ret >= 0 && vec($data, 0, 8) == 0xd7 ) {            #            # Looks like this file has cached checksums            # Read the last 48 bytes: that's 2 file MD4s (32 bytes)            # plus 4 words of meta data            #            my $cacheInfo;            if ( length($data) >= 4096 ) {                return -6 if ( !defined(sysseek($fh, -4096, 2)) );                 return -7 if ( sysread($fh, $data, 4096) != 4096 );            }            $cacheInfo = substr($data, -48);            ($dg->{md4DigestOld},             $dg->{md4Digest},             $dg->{blockSize},             $dg->{checksumSeed},             $dg->{nBlocks},             $dg->{magic}) = unpack("a16 a16 V V V V", $cacheInfo);            if ( $dg->{magic} == 0x5fe3c289                    && $dg->{checksumSeed} == $checksumSeed                    && ($blockSize == 0 || $dg->{blockSize} == $blockSize) ) {                $dg->{fh}     = $fh;                $dg->{cached} = 1;                if ( length($data) >= $dg->{nBlocks} * 20 + 48 ) {                    #                    # We have all the data already - just remember it                    #                    $dg->{digestData} = substr($data,                                               length($data) - $dg->{nBlocks} * 20 - 48,                                               $dg->{nBlocks} * 20);                } else {                    #                    # position the file at the start of the rsync block checksums                    # (4 (adler) + 16 (md4) bytes each)                    #                    return -8                        if ( !defined(sysseek($fh, -$dg->{nBlocks} * 20 - 48, 2)) );                }            } else {                #                # cached checksums are not valid, so we close the                # file and treat it as uncached.                #                $dg->{cachedInvalid} = 1;                close($fh);            }        }    }    if ( !$dg->{cached} ) {        #        # This file doesn't have cached checksums, or the checksumSeed        # or blocksize doesn't match.  Open the file and prepare to        # compute the checksums.        #        $blockSize	    = BackupPC::Xfer::RsyncDigest->blockSize($fileSize, $defBlkSize)				    if ( $blockSize == 0 );        $dg->{checksumSeed} = $checksumSeed;        $dg->{blockSize}    = $blockSize;        $dg->{fh} = BackupPC::FileZIO->open($fileName, 0, $compress);        return -9 if ( !defined($dg->{fh}) );        if ( $needMD4) {            $dg->{csumDigest} = File::RsyncP::Digest->new;            $dg->{csumDigest}->protocol($dg->{protocol_version})                                if ( defined($dg->{protocol_version}) );            $dg->{csumDigest}->add(pack("V", $dg->{checksumSeed}));        }    }    return (undef, $dg, $dg->{blockSize});}sub digestGet{    my($dg, $num, $csumLen, $noPad) = @_;    my($fileData);    my $blockSize = $dg->{blockSize};    if ( $dg->{cached} ) {        my $thisNum = $num;        $thisNum = $dg->{nBlocks} if ( $thisNum > $dg->{nBlocks} );        if ( defined($dg->{digestData}) ) {            $fileData = substr($dg->{digestData}, 0, 20 * $thisNum);            $dg->{digestData} = substr($dg->{digestData}, 20 * $thisNum);        } else {            sysread($dg->{fh}, $fileData, 20 * $thisNum);        }        $dg->{nBlocks} -= $thisNum;        if ( $thisNum < $num && !$noPad) {            #            # unexpected shortfall of data; pad with zero digest            #            $fileData .= pack("c", 0) x (20 * ($num - $thisNum));        }        return $dg->{digest}->blockDigestExtract($fileData, $csumLen);    } else {        if ( $dg->{fh}->read(\$fileData, $blockSize * $num) <= 0 ) {            #            # unexpected shortfall of data; pad with zeros            #            $fileData = pack("c", 0) x ($blockSize * $num) if ( !$noPad );        }        $dg->{csumDigest}->add($fileData) if ( $dg->{needMD4} );        return $dg->{digest}->blockDigest($fileData, $blockSize,                                           $csumLen, $dg->{checksumSeed});    }}sub digestEnd{    my($dg, $skipMD4) = @_;    my($fileData);    if ( $dg->{cached} ) {        close($dg->{fh});        if ( $dg->{needMD4} ) {            if ( $dg->{protocol_version} <= 26 ) {                return $dg->{md4DigestOld};            } else {                return $dg->{md4Digest};            }        }    } else {        #        # make sure we read the entire file for the file MD4 digest        #        if ( $dg->{needMD4} && !$skipMD4 ) {            my $fileData;            while ( $dg->{fh}->read(\$fileData, 65536) > 0 ) {                $dg->{csumDigest}->add($fileData);            }        }        $dg->{fh}->close();        return $dg->{csumDigest}->digest if ( $dg->{needMD4} );    }}sub isCached{    my($dg) = @_;     return wantarray ? ($dg->{cached}, $dg->{cachedInvalid}) : $dg->{cached};}sub blockSizeCurr{    my($dg) = @_;     return $dg->{blockSize};}## Default log handler#sub logHandler{    my($str) = @_;    print(STDERR $str, "\n");}## Set log handler to a new subroutine.#sub logHandlerSet{    my($dg, $sub) = @_;    $Log = $sub;}1;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -