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

📄 rsyncfileio.pm

📁 老外写的linux下的文件备份软件
💻 PM
📖 第 1 页 / 共 4 页
字号:
    }}## Finish up the current receive file.  Returns undef if ok, -1 if not.# Returns 1 if the md4 digest doesn't match.#sub fileDeltaRxDone{    my($fio, $md4, $phase) = @_;    my $name = $1 if ( $fio->{rxFile}{name} =~ /(.*)/s );    my $ret;    close($fio->{rxInFd})  if ( defined($fio->{rxInFd}) );    unlink("$fio->{outDirSh}RStmp") if  ( -f "$fio->{outDirSh}RStmp" );    $fio->{phase} = $phase;    #    # Check the final md4 digest    #    if ( defined($md4) ) {        my $newDigest;        if ( !defined($fio->{rxDigest}) ) {            #            # File was exact match, but we still need to verify the            # MD4 checksum.  Compute the md4 digest (or fetch the            # cached one.)            #            if ( defined(my $attr = $fio->{rxLocalAttr}) ) {                #                # block size doesn't matter: we're only going to                # fetch the md4 file digest, not the block digests.                #                my($err, $csum, $blkSize)                         = BackupPC::Xfer::RsyncDigest->digestStart(                                 $attr->{fullPath}, $attr->{size},                                 0, 2048, $fio->{checksumSeed}, 1,                                 $attr->{compress}, 1,                                 $fio->{protocol_version});                if ( $err ) {                    $fio->log("Can't open $attr->{fullPath} for MD4"                            . " check (err=$err, $name)");                    $fio->{stats}{errorCnt}++;                } else {                    if ( $fio->{logLevel} >= 5 ) {                        my($isCached, $invalid) = $csum->isCached;                        $fio->log("MD4 $attr->{fullPath} cache = $isCached,"                                . " invalid = $invalid");                    }                    $newDigest = $csum->digestEnd;                }                $fio->{rxSize} = $attr->{size};            } else {		#		# Empty file; just create an empty file digest		#		$fio->{rxDigest} = File::RsyncP::Digest->new();                $fio->{rxDigest}->protocol($fio->{protocol_version});		$fio->{rxDigest}->add(pack("V", $fio->{checksumSeed}));		$newDigest = $fio->{rxDigest}->digest;	    }            $fio->log("$name got exact match") if ( $fio->{logLevel} >= 5 );        } else {            $newDigest = $fio->{rxDigest}->digest;        }        if ( $fio->{logLevel} >= 3 ) {            my $md4Str = unpack("H*", $md4);            my $newStr = unpack("H*", $newDigest);            $fio->log("$name got digests $md4Str vs $newStr")        }        if ( $md4 ne $newDigest ) {            if ( $phase > 0 ) {                $fio->log("$name: fatal error: md4 doesn't match on retry;"                        . " file removed");                $fio->{stats}{errorCnt}++;            } else {                $fio->log("$name: md4 doesn't match: will retry in phase 1;"                        . " file removed");            }            if ( defined($fio->{rxOutFd}) ) {                $fio->{rxOutFd}->close;                unlink($fio->{rxOutFile});            }            delete($fio->{rxFile});	    delete($fio->{rxOutFile});            return 1;        }    }    #    # One special case is an empty file: if the file size is    # zero we need to open the output file to create it.    #    if ( $fio->{rxSize} == 0 ) {	my $rxOutFileRel = "$fio->{shareM}/"			 . $fio->{bpc}->fileNameMangle($name);        my $rxOutFile    = $fio->{outDir} . $rxOutFileRel;        $fio->{rxOutFd}  = BackupPC::PoolWrite->new($fio->{bpc},					   $rxOutFile, $fio->{rxSize},                                           $fio->{xfer}{compress});    }    if ( !defined($fio->{rxOutFd}) ) {        #        # No output file, meaning original was an exact match.        #        $fio->log("$name: nothing to do")                        if ( $fio->{logLevel} >= 5 );        my $attr = $fio->{rxLocalAttr};        my $f = $fio->{rxFile};	$fio->logFileAction("same", $f) if ( $fio->{logLevel} >= 1 );        if ( $fio->{full}                || $attr->{type}       != $f->{type}                || $attr->{mtime}      != $f->{mtime}                || $attr->{size}       != $f->{size}                || $attr->{uid}        != $f->{uid}                || $attr->{gid}        != $f->{gid}                || $attr->{mode}       != $f->{mode}                || $attr->{hlink_self} != $f->{hlink_self} ) {            #            # In the full case, or if the attributes are different,            # we need to make a link from the previous file and            # set the attributes.            #            my $rxOutFile = $fio->{outDirSh}                            . $fio->{bpc}->fileNameMangle($name);            my($exists, $digest, $origSize, $outSize, $errs)                                = BackupPC::PoolWrite::LinkOrCopy(                                      $fio->{bpc},                                      $attr->{fullPath},                                      $attr->{compress},                                      $rxOutFile,                                      $fio->{xfer}{compress});            #            # Cumulate the stats            #            $fio->{stats}{TotalFileCnt}++;            $fio->{stats}{TotalFileSize} += $fio->{rxSize};            $fio->{stats}{ExistFileCnt}++;            $fio->{stats}{ExistFileSize} += $fio->{rxSize};            $fio->{stats}{ExistFileCompSize} += -s $rxOutFile;            $fio->{rxFile}{size} = $fio->{rxSize};            $ret = $fio->attribSet($fio->{rxFile});            $fio->log(@$errs) if ( defined($errs) && @$errs );            if ( !$exists && $outSize > 0 ) {                #                # the hard link failed, most likely because the target                # file has too many links.  We have copied the file                # instead, so add this to the new file list.                #                my $rxOutFileRel = "$fio->{shareM}/"                                 . $fio->{bpc}->fileNameMangle($name);                $rxOutFileRel =~ s{^/+}{};                my $fh = $fio->{newFilesFH};                print($fh "$digest $origSize $rxOutFileRel\n")                                                if ( defined($fh) );            }        }    } else {	my $exist = $fio->processClose($fio->{rxOutFd},				       $fio->{rxOutFileRel},				       $fio->{rxSize}, 1);	$fio->logFileAction($exist ? "pool" : "create", $fio->{rxFile})			    if ( $fio->{logLevel} >= 1 );	$fio->{rxFile}{size} = $fio->{rxSize};	$ret = $fio->attribSet($fio->{rxFile});    }    delete($fio->{rxDigest});    delete($fio->{rxInData});    delete($fio->{rxFile});    delete($fio->{rxOutFile});    return $ret;}## Callback function for BackupPC::View->find.  Note the order of the# first two arguments.#sub fileListEltSend{    my($a, $fio, $fList, $outputFunc) = @_;    my $name = $a->{relPath};    my $n = $name;    my $type = $a->{type};    my $extraAttribs = {};    if ( $a->{mode} & S_HLINK_TARGET ) {        $a->{hlink_self} = 1;        $a->{mode} &= ~S_HLINK_TARGET;    }    $n =~ s/^\Q$fio->{xfer}{pathHdrSrc}//;    $fio->log("Sending $name (remote=$n) type = $type") if ( $fio->{logLevel} >= 1 );    if ( $type == BPC_FTYPE_CHARDEV	    || $type == BPC_FTYPE_BLOCKDEV	    || $type == BPC_FTYPE_SYMLINK ) {	my $fh = BackupPC::FileZIO->open($a->{fullPath}, 0, $a->{compress});	my($str, $rdSize);	if ( defined($fh) ) {	    $rdSize = $fh->read(\$str, $a->{size} + 1024);	    if ( $type == BPC_FTYPE_SYMLINK ) {		#		# Reconstruct symbolic link		#		$extraAttribs = { link => $str };		if ( $rdSize != $a->{size} ) {		    # ERROR		    $fio->log("$name: can't read exactly $a->{size} bytes");		    $fio->{stats}{errorCnt}++;		}	    } elsif ( $str =~ /(\d*),(\d*)/ ) {		#		# Reconstruct char or block special major/minor device num		#		# Note: char/block devices have $a->{size} = 0, so we		# can't do an error check on $rdSize.		#		$extraAttribs = {                    rdev       => $1 * 256 + $2,                    rdev_major => $1,                    rdev_minor => $2,                };	    } else {		$fio->log("$name: unexpected special file contents $str");		$fio->{stats}{errorCnt}++;	    }	    $fh->close;	} else {	    # ERROR	    $fio->log("$name: can't open");	    $fio->{stats}{errorCnt}++;	}    } elsif ( $fio->{preserve_hard_links}            && ($type == BPC_FTYPE_HARDLINK || $type == BPC_FTYPE_FILE)            && ($type == BPC_FTYPE_HARDLINK                    || $fio->{protocol_version} < 27                    || $a->{hlink_self}) ) {        #        # Fill in fake inode information so that the remote rsync        # can correctly create hardlinks.        #        $name =~ s/^\.?\/+//;        my($target, $inode);        if ( $type == BPC_FTYPE_HARDLINK ) {            my $fh = BackupPC::FileZIO->open($a->{fullPath}, 0,                                             $a->{compress});            if ( defined($fh) ) {                $fh->read(\$target,  65536);                $fh->close;                $target =~ s/^\.?\/+//;                if ( defined($fio->{hlinkFile2Num}{$target}) ) {                    $inode = $fio->{hlinkFile2Num}{$target};                } else {                    $inode = $fio->{fileListCnt};                    $fio->{hlinkFile2Num}{$target} = $inode;                }            } else {                $fio->log("$a->{fullPath}: can't open for hardlink");                $fio->{stats}{errorCnt}++;            }        } elsif ( $a->{hlink_self} ) {            if ( defined($fio->{hlinkFile2Num}{$name}) ) {                $inode = $fio->{hlinkFile2Num}{$name};            } else {                $inode = $fio->{fileListCnt};                $fio->{hlinkFile2Num}{$name} = $inode;            }        }        $inode = $fio->{fileListCnt} if ( !defined($inode) );        $fio->log("$name: setting inode to $inode");        $extraAttribs = {            %$extraAttribs,            dev   => 0,            inode => $inode,        };    }    my $f = {        name  => $n,        mode  => $a->{mode} & ~S_HLINK_TARGET,        uid   => $a->{uid},        gid   => $a->{gid},        mtime => $a->{mtime},        size  => $a->{size},        %$extraAttribs,    };    my $logName = $f->{name};    from_to($f->{name}, "utf8", $fio->{clientCharset})                            if ( $fio->{clientCharset} ne "" );    $fList->encode($f);    $logName = "$fio->{xfer}{pathHdrDest}/$logName";    $logName =~ s{//+}{/}g;    $f->{name} = $logName;    $fio->logFileAction("restore", $f) if ( $fio->{logLevel} >= 1 );    &$outputFunc($fList->encodeData);    #    # Cumulate stats    #    $fio->{fileListCnt}++;    if ( $type != BPC_FTYPE_DIR ) {	$fio->{stats}{TotalFileCnt}++;	$fio->{stats}{TotalFileSize} += $a->{size};    }}sub fileListSend{    my($fio, $flist, $outputFunc) = @_;    #    # Populate the file list with the files requested by the user.    # Since some might be directories so we call BackupPC::View::find.    #    $fio->log("fileListSend: sending file list: "	     . join(" ", @{$fio->{fileList}})) if ( $fio->{logLevel} >= 4 );    $fio->{fileListCnt} = 0;    $fio->{hlinkFile2Num} = {};    foreach my $name ( @{$fio->{fileList}} ) {	$fio->{view}->find($fio->{xfer}{bkupSrcNum},			   $fio->{xfer}{bkupSrcShare},			   $name, 1,			   \&fileListEltSend, $fio, $flist, $outputFunc);    }}sub finish{    my($fio, $isChild) = @_;    #    # If we are aborting early, remove the last file since    # it was not complete    #    if ( $isChild && defined($fio->{rxFile}) ) {	unlink("$fio->{outDirSh}RStmp") if  ( -f "$fio->{outDirSh}RStmp" );	if ( defined($fio->{rxFile}) ) {	    unlink($fio->{rxOutFile});	    $fio->log("finish: removing in-process file $fio->{rxFile}{name}");	}    }    #    # Flush the attributes if this is the child    #    $fio->attribWrite(undef) if ( $isChild );}#sub is_tainted#{#    return ! eval {#        join('',@_), kill 0;#        1;#    };#}1;

⌨️ 快捷键说明

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