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

📄 rsyncfileio.pm

📁 老外写的linux下的文件备份软件
💻 PM
📖 第 1 页 / 共 4 页
字号:
        }        if ( $attr->{mode} & S_HLINK_TARGET ) {            $attr->{hlink_self} = 1;            $attr->{mode} &= ~S_HLINK_TARGET;        }    }    return ($attr, $partial);}sub attribGet{    my($fio, $f, $doHardLink) = @_;    my($attr) = $fio->attribGetWhere($f);    if ( $doHardLink && $attr->{type} == BPC_FTYPE_HARDLINK ) {        $fio->log("$attr->{fullPath}: opening for hardlink read"                . " (name = $f->{name})") if ( $fio->{logLevel} >= 4 );        my $fh = BackupPC::FileZIO->open($attr->{fullPath}, 0,                                         $attr->{compress});        my $target;        if ( defined($fh) ) {            $fh->read(\$target,  65536);            $fh->close;            $target =~ s/^\.?\/+//;        } else {            $fio->log("$attr->{fullPath}: can't open for hardlink read");            $fio->{stats}{errorCnt}++;            $attr->{type} = BPC_FTYPE_FILE;            return $attr;        }        $target = "/$target" if ( $target !~ /^\// );        $fio->log("$attr->{fullPath}: redirecting to $target")                                    if ( $fio->{logLevel} >= 4 );        $target =~ s{^/+}{};        ($attr) = $fio->attribGetWhere($f, 1, $target);        $fio->log(" ... now got $attr->{fullPath}")                            if ( $fio->{logLevel} >= 4 );    }    return $attr;}sub mode2type{    my($fio, $f) = @_;    my $mode = $f->{mode};    if ( ($mode & S_IFMT) == S_IFREG ) {        if ( defined($f->{hlink}) && !$f->{hlink_self} ) {            return BPC_FTYPE_HARDLINK;        } else {            return BPC_FTYPE_FILE;        }    } elsif ( ($mode & S_IFMT) == S_IFDIR ) {	return BPC_FTYPE_DIR;    } elsif ( ($mode & S_IFMT) == S_IFLNK ) {	return BPC_FTYPE_SYMLINK;    } elsif ( ($mode & S_IFMT) == S_IFCHR ) {	return BPC_FTYPE_CHARDEV;    } elsif ( ($mode & S_IFMT) == S_IFBLK ) {	return BPC_FTYPE_BLOCKDEV;    } elsif ( ($mode & S_IFMT) == S_IFIFO ) {	return BPC_FTYPE_FIFO;    } elsif ( ($mode & S_IFMT) == S_IFSOCK ) {	return BPC_FTYPE_SOCKET;    } else {	return BPC_FTYPE_UNKNOWN;    }}## Set the attributes for a file.  Returns non-zero on error.#sub attribSet{    my($fio, $f, $placeHolder) = @_;    my($dir, $file);    return if ( $placeHolder && $fio->{phase} > 0 );    if ( $f->{name} =~ m{(.*)/(.*)}s ) {	$file = $2;	$dir  = "$fio->{shareM}/" . $1;    } elsif ( $f->{name} eq "." ) {	$dir  = "";	$file = $fio->{share};    } else {	$dir  = $fio->{shareM};	$file = $f->{name};    }    if ( $dir ne ""            && (!defined($fio->{attribLastDir}) || $fio->{attribLastDir} ne $dir) ) {        #        # Flush any directories that don't match the first part        # of the new directory.  Don't flush the top-level directory        # (ie: $dir eq "") since the "." might get sorted in the middle        # of other top-level directories or files.        #        foreach my $d ( keys(%{$fio->{attrib}}) ) {            next if ( $d eq "" || "$dir/" =~ m{^\Q$d/} );            $fio->attribWrite($d);        }	$fio->{attribLastDir} = $dir;    }    if ( !exists($fio->{attrib}{$dir}) ) {        $fio->log("attribSet: dir=$dir not found") if ( $fio->{logLevel} >= 4 );        $fio->{attrib}{$dir} = BackupPC::Attrib->new({				     compress => $fio->{xfer}{compress},				});        my $dirM = $dir;	$dirM = $1 . "/" . $fio->{bpc}->fileNameMangle($2)			if ( $dirM =~ m{(.*?)/(.*)}s );	my $path = $fio->{outDir} . $dirM;        if ( -f $fio->{attrib}{$dir}->fileName($path) ) {            if ( !$fio->{attrib}{$dir}->read($path) ) {                $fio->log(sprintf("Unable to read attribute file %s",			    $fio->{attrib}{$dir}->fileName($path)));            } else {                $fio->log(sprintf("attribRead file %s",			    $fio->{attrib}{$dir}->fileName($path)))                                     if ( $fio->{logLevel} >= 4 );            }        }    } else {        $fio->log("attribSet: dir=$dir exists") if ( $fio->{logLevel} >= 4 );    }    $fio->log("attribSet(dir=$dir, file=$file, size=$f->{size}, placeholder=$placeHolder)")                        if ( $fio->{logLevel} >= 4 );    my $mode = $f->{mode};    $mode |= S_HLINK_TARGET if ( $f->{hlink_self} );    $fio->{attrib}{$dir}->set($file, {                            type  => $fio->mode2type($f),                            mode  => $mode,                            uid   => $f->{uid},                            gid   => $f->{gid},                            size  => $placeHolder ? -1 : $f->{size},                            mtime => $f->{mtime},                       });    return;}sub attribWrite{    my($fio, $d) = @_;    my($poolWrite);    if ( !defined($d) ) {        #        # flush all entries (in reverse order)        #        foreach $d ( sort({$b cmp $a} keys(%{$fio->{attrib}})) ) {            $fio->attribWrite($d);        }        return;    }    return if ( !defined($fio->{attrib}{$d}) );    #    # Set deleted files in the attributes.  Any file in the view    # that doesn't have attributes is flagged as deleted for    # incremental dumps.  All files sent by rsync have attributes    # temporarily set so we can do deletion detection.  We also    # prune these temporary attributes.    #    if ( $d ne "" ) {	my $dir;	my $share;	$dir = $1 if ( $d =~ m{.+?/(.*)}s );	$fio->viewCacheDir(undef, $dir);	##print("attribWrite $d,$dir\n");	##$Data::Dumper::Indent = 1;	##$fio->log("attribWrite $d,$dir");	##$fio->log("viewCacheLogKeys = ", keys(%{$fio->{viewCache}}));	##$fio->log("attribKeys = ", keys(%{$fio->{attrib}}));	##print "viewCache = ", Dumper($fio->{attrib});	##print "attrib = ", Dumper($fio->{attrib});	if ( defined($fio->{viewCache}{$d}) ) {	    foreach my $f ( keys(%{$fio->{viewCache}{$d}}) ) {		my $name = $f;		$name = "$1/$name" if ( $d =~ m{.*?/(.*)}s );		if ( defined(my $a = $fio->{attrib}{$d}->get($f)) ) {		    #		    # delete temporary attributes (skipped files)		    #		    if ( $a->{size} < 0 ) {			$fio->{attrib}{$d}->set($f, undef);			$fio->logFileAction("skip", {				    %{$fio->{viewCache}{$d}{$f}},				    name => $name,				}) if ( $fio->{logLevel} >= 2                                      && $a->{type} == BPC_FTYPE_FILE );		    }		} elsif ( $fio->{phase} == 0 && !$fio->{full} ) {		    ##print("Delete file $f\n");		    $fio->logFileAction("delete", {				%{$fio->{viewCache}{$d}{$f}},				name => $name,			    }) if ( $fio->{logLevel} >= 1 );		    $fio->{attrib}{$d}->set($f, {				    type  => BPC_FTYPE_DELETED,				    mode  => 0,				    uid   => 0,				    gid   => 0,				    size  => 0,				    mtime => 0,			       });		}	    }	}    }    if ( $fio->{attrib}{$d}->fileCount || $fio->{phase} > 0 ) {        my $data = $fio->{attrib}{$d}->writeData;	my $dirM = $d;	$dirM = $1 . "/" . $fio->{bpc}->fileNameMangle($2)			if ( $dirM =~ m{(.*?)/(.*)}s );        my $fileName = $fio->{attrib}{$d}->fileName("$fio->{outDir}$dirM");	$fio->log("attribWrite(dir=$d) -> $fileName")				if ( $fio->{logLevel} >= 4 );        my $poolWrite = BackupPC::PoolWrite->new($fio->{bpc}, $fileName,                                     length($data), $fio->{xfer}{compress});        $poolWrite->write(\$data);        $fio->processClose($poolWrite, $fio->{attrib}{$d}->fileName($dirM),                           length($data), 0);    }    delete($fio->{attrib}{$d});}sub processClose{    my($fio, $poolWrite, $fileName, $origSize, $doStats) = @_;    my($exists, $digest, $outSize, $errs) = $poolWrite->close;    $fileName =~ s{^/+}{};    $fio->log(@$errs) if ( defined($errs) && @$errs );    if ( $doStats ) {	$fio->{stats}{TotalFileCnt}++;	$fio->{stats}{TotalFileSize} += $origSize;    }    if ( $exists ) {	if ( $doStats ) {	    $fio->{stats}{ExistFileCnt}++;	    $fio->{stats}{ExistFileSize}     += $origSize;	    $fio->{stats}{ExistFileCompSize} += $outSize;	}    } elsif ( $outSize > 0 ) {        my $fh = $fio->{newFilesFH};        print($fh "$digest $origSize $fileName\n") if ( defined($fh) );    }    return $exists && $origSize > 0;}sub statsGet{    my($fio) = @_;    return $fio->{stats};}## Make a given directory.  Returns non-zero on error.#sub makePath{    my($fio, $f) = @_;    my $name = $1 if ( $f->{name} =~ /(.*)/s );    my $path;    if ( $name eq "." ) {	$path = $fio->{outDirSh};    } else {	$path = $fio->{outDirSh} . $fio->{bpc}->fileNameMangle($name);    }    $fio->logFileAction("create", $f) if ( $fio->{logLevel} >= 1 );    $fio->log("makePath($path, 0777)") if ( $fio->{logLevel} >= 5 );    $path = $1 if ( $path =~ /(.*)/s );    File::Path::mkpath($path, 0, 0777) if ( !-d $path );    return $fio->attribSet($f) if ( -d $path );    $fio->log("Can't create directory $path");    $fio->{stats}{errorCnt}++;    return -1;}## Make a special file.  Returns non-zero on error.#sub makeSpecial{    my($fio, $f) = @_;    my $name = $1 if ( $f->{name} =~ /(.*)/s );    my $fNameM = $fio->{bpc}->fileNameMangle($name);    my $path = $fio->{outDirSh} . $fNameM;    my $attr = $fio->attribGet($f);    my $str = "";    my $type = $fio->mode2type($f);    $fio->log("makeSpecial($path, $type, $f->{mode})")		    if ( $fio->{logLevel} >= 5 );    if ( $type == BPC_FTYPE_CHARDEV || $type == BPC_FTYPE_BLOCKDEV ) {	my($major, $minor, $fh, $fileData);        if ( defined($f->{rdev_major}) ) {            $major = $f->{rdev_major};            $minor = $f->{rdev_minor};        } else {            $major = $f->{rdev} >> 8;            $minor = $f->{rdev} & 0xff;        }        $str = "$major,$minor";    } elsif ( ($f->{mode} & S_IFMT) == S_IFLNK ) {        $str = $f->{link};    } elsif ( ($f->{mode} & S_IFMT) == S_IFREG ) {        #        # this is a hardlink        #        if ( !defined($f->{hlink}) ) {            $fio->log("Error: makeSpecial($path, $type, $f->{mode}) called"                    . " on a regular non-hardlink file");            return 1;        }        $str  = $f->{hlink};    }    #    # Now see if the file is different, or this is a full, in which    # case we create the new file.    #    my($fh, $fileData);    if ( $fio->{full}            || !defined($attr)            || $attr->{type}       != $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}            || !defined($fh = BackupPC::FileZIO->open($attr->{fullPath}, 0,                                                      $attr->{compress}))            || $fh->read(\$fileData, length($str) + 1) != length($str)            || $fileData ne $str ) {        $fh->close if ( defined($fh) );        $fh = BackupPC::PoolWrite->new($fio->{bpc}, $path,                                     length($str), $fio->{xfer}{compress});	$fh->write(\$str);	my $exist = $fio->processClose($fh, "$fio->{shareM}/$fNameM",				       length($str), 1);	$fio->logFileAction($exist ? "pool" : "create", $f)			    if ( $fio->{logLevel} >= 1 );	return $fio->attribSet($f);    } else {	$fio->logFileAction("skip", $f) if ( $fio->{logLevel} >= 2 );    }    $fh->close if ( defined($fh) );}## Make a hardlink.  Returns non-zero on error.# This actually gets called twice for each hardlink.

⌨️ 快捷键说明

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