view release on metacpan or search on metacpan
lib/App/SimpleBackuper/Backup.pm view on Meta::CPAN
if(time - $last_db_save > $SAVE_DB_PERIOD) {
App::SimpleBackuper::BackupDB($options, $state);
$last_db_save = time;
}
}
while(my($full_path, $dir2upd) = each %dirs2upd) {
print "Updating dir $full_path..." if $options->{verbose};
my $file = $files->find_by_parent_id_name($dir2upd->{parent_id}, $dir2upd->{filename});
my @stat = lstat($full_path);
if(@stat and $file->{versions}->[-1]->{backup_id_max} != $state->{last_backup_id}) {
my($uid, $gid) =_proc_uid_gid($stat[4], $stat[5], $state->{db}->{uids_gids});
if($file->{versions}->[-1]->{backup_id_max} == $state->{last_backup_id} - 1) {
$file->{versions}->[-1] = {
%{ $file->{versions}->[-1] },
backup_id_max => $state->{last_backup_id},
uid => $uid,
gid => $gid,
size => $stat[7],
mode => $stat[2],
lib/App/SimpleBackuper/Backup.pm view on Meta::CPAN
}
if(! $priority) { # Excluded by user
print " -> skip\n" if $options->{verbose};
return;
}
$state->{profile}->{fs} -= time;
$state->{profile}->{fs_lstat} -= time;
$file_time_spent -= time;
my @stat = lstat($task->[0]);
$file_time_spent += time;
$state->{profile}->{fs} += time;
$state->{profile}->{fs_lstat} += time;
if(! @stat) {
print ". Not exists\n" if $options->{verbose};
return;
}
else {
printf ", stat: %s:%s %o %s modified at %s", scalar getpwuid($stat[4]), scalar getgrgid($stat[5]), $stat[2], fmt_weight($stat[7]), fmt_datetime($stat[9]) if $options->{verbose};
}
lib/App/SimpleBackuper/Restore.pm view on Meta::CPAN
print "$backup_path -> $fs_path\n" if $options->{verbose};
my($version) = grep {$_->{backup_id_min} <= $state->{backup_id} and $_->{backup_id_max} >= $state->{backup_id}}
@{ $file->{versions} };
if(! $version) {
print "\tnot exists in this backup.\n" if $options->{verbose};
return;
}
my @stat = lstat($fs_path);
my($fs_user, $fs_group);
if(@stat) {
$fs_user = getpwuid($stat[4]);
$fs_group = getpwuid($stat[5]);
}
if(S_ISDIR $version->{mode}) {
my $need2mkdir;
if(@stat) {
if(! S_ISDIR $stat[2]) {
local/lib/perl5/Net/SFTP/Foreign.pm view on Meta::CPAN
my $check = delete $opts{check};
$check = 1 unless defined $check;
%opts and _croak_bad_options(keys %opts);
if (defined $cwd) {
if ($check) {
$cwd = $sftp->realpath($cwd);
return undef unless defined $cwd;
_untaint($cwd);
my $a = $sftp->stat($cwd)
or return undef;
unless (_is_dir($a->perm)) {
$sftp->_set_error(SFTP_ERR_REMOTE_BAD_OBJECT,
"Remote object '$cwd' is not a directory");
return undef;
}
}
else {
$cwd = $sftp->_rel2abs($cwd);
}
local/lib/perl5/Net/SFTP/Foreign.pm view on Meta::CPAN
my ($sftp, $rfh, $pos, $whence) = @_;
$sftp->flush($rfh) or return undef;
if (!$whence) {
$rfh->_pos($pos)
}
elsif ($whence == 1) {
$rfh->_inc_pos($pos)
}
elsif ($whence == 2) {
my $a = $sftp->stat($rfh) or return undef;
$rfh->_pos($pos + $a->size);
}
else {
croak "invalid value for whence argument ('$whence')";
}
1;
}
sub tell {
@_ == 2 or croak 'Usage: $sftp->tell($fh)';
local/lib/perl5/Net/SFTP/Foreign.pm view on Meta::CPAN
${$rfh->_bin} = '';
}
if ($dir ne 'in') { # flush out!
my $bout = $rfh->_bout;
my $len = length $$bout;
if ($len) {
my $start;
my $append = $rfh->_flag('append');
if ($append) {
my $attr = $sftp->stat($rfh)
or return undef;
$start = $attr->size;
}
else {
$start = $rfh->_pos;
${$rfh->_bin} = '';
}
my $off = 0;
my $written = $sftp->_write($rfh, $start,
sub {
local/lib/perl5/Net/SFTP/Foreign.pm view on Meta::CPAN
$rfh->_inc_pos(1);
return substr $$bin, 0, 1, '';
}
return undef;
}
## SSH2_FXP_LSTAT (7), SSH2_FXP_FSTAT (8), SSH2_FXP_STAT (17)
# these all return a Net::SFTP::Foreign::Attributes object on success, undef on failure
sub lstat {
@_ <= 2 or croak 'Usage: $sftp->lstat($path)';
${^TAINT} and &_catch_tainted_args;
my ($sftp, $path) = @_;
$path = '.' unless defined $path;
$path = $sftp->_rel2abs($path);
my $id = $sftp->_queue_str_request(SSH2_FXP_LSTAT, $sftp->_fs_encode($path));
if (my $msg = $sftp->_get_msg_and_check(SSH2_FXP_ATTRS, $id,
SFTP_ERR_REMOTE_LSTAT_FAILED, "Couldn't stat remote link")) {
return $msg->get_attributes;
}
return undef;
}
sub stat {
@_ <= 2 or croak 'Usage: $sftp->stat($path_or_fh)';
${^TAINT} and &_catch_tainted_args;
my ($sftp, $pofh) = @_;
$pofh = '.' unless defined $pofh;
my $id = $sftp->_queue_new_msg( (ref $pofh and UNIVERSAL::isa($pofh, 'Net::SFTP::Foreign::FileHandle'))
? ( SSH2_FXP_FSTAT, str => $sftp->_rid($pofh))
: ( SSH2_FXP_STAT, str => $sftp->_fs_encode($sftp->_rel2abs($pofh))) );
if (my $msg = $sftp->_get_msg_and_check(SSH2_FXP_ATTRS, $id,
SFTP_ERR_REMOTE_STAT_FAILED, "Couldn't stat remote file")) {
return $msg->get_attributes;
local/lib/perl5/Net/SFTP/Foreign.pm view on Meta::CPAN
"mkdir '$target' failed", $!);
return;
}
}
}
$debug and $debug & 32768 and _debug "_mkpath_local succeeded";
return 1;
}
sub setstat {
@_ == 3 or croak 'Usage: $sftp->setstat($path_or_fh, $attrs)';
${^TAINT} and &_catch_tainted_args;
my ($sftp, $pofh, $attrs) = @_;
my $id = $sftp->_queue_new_msg( ( (ref $pofh and UNIVERSAL::isa($pofh, 'Net::SFTP::Foreign::FileHandle') )
? ( SSH2_FXP_FSETSTAT, str => $sftp->_rid($pofh) )
: ( SSH2_FXP_SETSTAT, str => $sftp->_fs_encode($sftp->_rel2abs($pofh)) ) ),
attr => $attrs );
return $sftp->_check_status_ok($id,
SFTP_ERR_REMOTE_SETSTAT_FAILED,
"Couldn't setstat remote file");
local/lib/perl5/Net/SFTP/Foreign.pm view on Meta::CPAN
}
$overwrite = 1 unless (defined $overwrite or $local_is_fh or $numbered or $append);
$copy_perm = 1 unless (defined $perm or defined $copy_perm or $local_is_fh);
$copy_time = 1 unless (defined $copy_time or $local_is_fh);
$mkpath = 1 unless defined $mkpath;
$cleanup = ($atomic || $numbered) unless defined $cleanup;
my $a = do {
local $sftp->{_autodie};
$sftp->stat($remote);
};
my ($rperm, $size, $atime, $mtime) = ($a ? ($a->perm, $a->size, $a->atime, $a->mtime) : ());
$size = -1 unless defined $size;
if ($copy_time and not defined $atime) {
if ($best_effort) {
undef $copy_time;
}
else {
$sftp->_ok_or_autodie and $sftp->_set_error(SFTP_ERR_REMOTE_STAT_FAILED,
local/lib/perl5/Net/SFTP/Foreign.pm view on Meta::CPAN
my $rfh;
my $writeoff = 0;
my $converter = _gen_converter $conversion;
my $converted_input = '';
my $rattrs;
if ($resume or $append) {
$rattrs = do {
local $sftp->{_autodie};
$sftp->stat($remote);
};
if ($rattrs) {
if ($resume and $resume eq 'auto' and $rattrs->mtime <= $lmtime) {
$debug and $debug & 16384 and
_debug "not resuming because local file is newer, r: ".$rattrs->mtime." l: $lmtime";
undef $resume;
}
else {
$writeoff = $rattrs->size;
$debug and $debug & 16384 and _debug "resuming from $writeoff";
local/lib/perl5/Net/SFTP/Foreign.pm view on Meta::CPAN
my $ln = $sftp->_fs_decode($msg->get_str);
# my $a = $msg->get_attributes;
my $a = Net::SFTP::Foreign::Attributes->new_from_buffer($msg);
my $entry = { filename => $fn,
longname => $ln,
a => $a };
if ($follow_links and _is_lnk($a->perm)) {
if ($a = $sftp->stat($sftp->join($dir, $fn))) {
$entry->{a} = $a;
}
else {
$sftp->_clear_error_and_status;
}
}
if ($realpath) {
my $rp = $sftp->realpath($sftp->join($dir, $fn));
if (defined $rp) {
local/lib/perl5/Net/SFTP/Foreign.pm view on Meta::CPAN
my ($sftp, $remote, $local, %opts) = @_;
my $overwrite = delete $opts{overwrite};
my $numbered = delete $opts{numbered};
croak "'overwrite' and 'numbered' can not be used together"
if ($overwrite and $numbered);
%opts and _croak_bad_options(keys %opts);
$overwrite = 1 unless (defined $overwrite or $numbered);
my $a = $sftp->lstat($remote) or return undef;
unless (_is_lnk($a->perm)) {
$sftp->_set_error(SFTP_ERR_REMOTE_BAD_OBJECT,
"Remote object '$remote' is not a symlink");
return undef;
}
my $link = $sftp->readlink($remote) or return undef;
# TODO: this is too weak, may contain race conditions.
if ($numbered) {
local/lib/perl5/Net/SFTP/Foreign.pm view on Meta::CPAN
if ($sftp->put_symlink($fn, $rpath,
%put_symlink_opts)) {
$count++;
return undef;
}
$lfs->_copy_error($sftp);
}
elsif (_is_reg($e->{a}->perm)) {
my $ra;
if ( $newer_only and
$ra = $sftp->stat($rpath) and
$ra->mtime >= $e->{a}->mtime) {
$lfs->_set_error(SFTP_ERR_REMOTE_ALREADY_EXISTS,
"Newer remote file '$rpath' already exists");
}
else {
if ($sftp->put($fn, $rpath,
( defined($perm) ? (perm => $perm)
: $copy_perm ? (perm => $e->{a}->perm & $mask)
: (copy_perm => 0, umask => $umask) ),
copy_time => $copy_time,
local/lib/perl5/Net/SFTP/Foreign.pm view on Meta::CPAN
returns the next entry from the remote directory C<$handle> (or all
the remaining entries when called in list context).
The return values are a hash with three keys: C<filename>, C<longname> and
C<a>. The C<a> value contains a L<Net::SFTP::Foreign::Attributes>
object describing the entry.
Returns undef on error or when no more entries exist on the directory.
=item $sftp-E<gt>stat($path_or_fh)
performs a C<stat> on the remote file and returns a
L<Net::SFTP::Foreign::Attributes> object with the result values. Both
paths and open remote file handles can be passed to this method.
Returns undef on failure.
=item $sftp-E<gt>fstat($handle)
this method is deprecated.
=item $sftp-E<gt>lstat($path)
this method is similar to C<stat> method but stats a symbolic link
instead of the file the symbolic links points to.
=item $sftp-E<gt>setstat($path_or_fh, $attrs)
sets file attributes on the remote file. Accepts both paths and open
remote file handles.
Returns true on success and undef on failure.
=item $sftp-E<gt>fsetstat($handle, $attrs)
this method is deprecated.
=item $sftp-E<gt>truncate($path_or_fh, $size)
=item $sftp-E<gt>chown($path_or_fh, $uid, $gid)
=item $sftp-E<gt>chmod($path_or_fh, $perm)
=item $sftp-E<gt>utime($path_or_fh, $atime, $mtime)
local/lib/perl5/Net/SFTP/Foreign/Attributes.pm view on Meta::CPAN
Net::SFTP::Foreign::Attributes - File/directory attribute container
=head1 SYNOPSIS
use Net::SFTP::Foreign;
my $a1 = Net::SFTP::Foreign::Attributes->new();
$a1->set_size($size);
$a1->set_ugid($uid, $gid);
my $a2 = $sftp->stat($file)
or die "remote stat command failed: ".$sftp->status;
my $size = $a2->size;
my $mtime = $a2->mtime;
=head1 DESCRIPTION
I<Net::SFTP::Foreign::Attributes> encapsulates file/directory
attributes for I<Net::SFTP::Foreign>. It also provides serialization
and deserialization methods to encode/decode attributes into
local/lib/perl5/Net/SFTP/Foreign/Common.pm view on Meta::CPAN
my $follow = ($follow_links and _is_lnk($entry->{a}->perm));
if ($follow or $realpath) {
unless (defined $entry->{realpath}) {
my $rp = $entry->{realpath} = $self->realpath($fn);
next unless (defined $rp and not $rpdone{$rp}++);
}
}
if ($follow) {
my $a = $self->stat($fn);
if (defined $a) {
$entry->{a} = $a;
# we queue it for reprocessing as it could be a directory
unshift @queue, $entry;
}
next;
}
if (!$wanted or $wanted->($self, $entry)) {
if ($wantarray) {
local/lib/perl5/Net/SFTP/Foreign/Common.pm view on Meta::CPAN
$self->_call_on_error($on_error, $entry)
}
};
my $try;
while (@queue) {
no warnings 'uninitialized';
$try = shift @queue;
my $fn = $try->{filename};
my $a = $try->{a} ||= $self->lstat($fn)
or next;
next if (_is_dir($a->perm) and $done{$fn}++);
$task->($try);
if (_is_dir($a->perm)) {
if (!$descend or $descend->($self, $try)) {
if ($ordered or $atomic_readdir) {
my $ls = $self->ls( $fn,
local/lib/perl5/Net/SFTP/Foreign/Common.pm view on Meta::CPAN
my $pfn = $parent->{filename};
if ($has_wildcards) {
$sftp->ls( $pfn,
ordered => $ordered,
_wanted => sub {
my $e = $_[1];
if ($e->{filename} =~ $re) {
my $fn = $e->{filename} = $sftp->join($pfn, $e->{filename});
if ( (@parts or $follow_links)
and _is_lnk($e->{a}->perm) ) {
if (my $a = $sftp->stat($fn)) {
$e->{a} = $a;
}
else {
$on_error and $sftp->_call_on_error($on_error, $e);
return undef;
}
}
if (@parts) {
push @res, $e if _is_dir($e->{a}->perm)
}
local/lib/perl5/Net/SFTP/Foreign/Common.pm view on Meta::CPAN
}
}
}
return wantarray ? @res : $res;
}
sub test_d {
my ($sftp, $name) = @_;
{
local $sftp->{_autodie};
my $a = $sftp->stat($name);
return _is_dir($a->perm) if $a;
}
if ($sftp->{_status} == SSH2_FX_NO_SUCH_FILE) {
$sftp->_clear_error_and_status;
return undef;
}
$sftp->_ok_or_autodie;
}
sub test_e {
my ($sftp, $name) = @_;
{
local $sftp->{_autodie};
$sftp->stat($name) and return 1;
}
if ($sftp->{_status} == SSH2_FX_NO_SUCH_FILE) {
$sftp->_clear_error_and_status;
return undef;
}
$sftp->_ok_or_autodie;
}
1;
local/lib/perl5/Net/SFTP/Foreign/Compat.pm view on Meta::CPAN
if (my $a = $sftp->$method(@_)) {
return _rebless_attrs($a);
}
else {
$sftp->_warn_error;
return undef;
}
}
}
*do_lstat = _gen_do_stat('lstat');
*do_fstat = _gen_do_stat('fstat');
*do_stat = _gen_do_stat('stat');
1;
__END__
=head1 NAME
Net::SFTP::Foreign::Compat - Adapter for Net::SFTP compatibility
local/lib/perl5/Net/SFTP/Foreign/Local.pm view on Meta::CPAN
bless $self, $class;
}
sub realpath {
$! = 0;
File::Spec->rel2abs($_[1])
}
sub stat {
$! = 0;
my $a = Net::SFTP::Foreign::Attributes->new_from_stat(CORE::stat($_[1]));
unless ($a) {
$_[0]->_set_error(SFTP_ERR_LOCAL_STAT_FAILED, "Couldn't stat local file '$_[1]'", $!);
}
$a
}
sub lstat {
$! = 0;
my $a = Net::SFTP::Foreign::Attributes->new_from_stat(CORE::lstat($_[1]));
unless ($a) {
$_[0]->_set_error(SFTP_ERR_LOCAL_STAT_FAILED, "Couldn't stat local file '$_[1]'", $!);
}
$a
}
sub readlink {
$! = 0;
my $target = readlink $_[1];
unless (defined $target) {
local/lib/perl5/Net/SFTP/Foreign/Local.pm view on Meta::CPAN
%opts and croak "invalid option(s) '".CORE::join("', '", keys %opts)."'";
$! = 0;
opendir(my $ldh, $dir)
or return undef;
my @dir;
while (defined(my $part = readdir $ldh)) {
my $fn = File::Spec->join($dir, $part);
my $a = $self->lstat($fn);
if ($a and $follow_links and S_ISLNK($a->perm)) {
if (my $fa = $self->stat($fn)) {
$a = $fa;
}
else {
$! = 0;
}
}
my $entry = { filename => $part,
a => $a };
if ($atomic_readdir or !$wanted or $wanted->($self, $entry)) {
push @dir, $entry;
t/Actions.t view on Meta::CPAN
is_deeply App::SimpleBackuper::Info(\%options, \%state)->{subfiles},
[ { name => 'tmp', oldest_backup => 'test', newest_backup => 'test'} ];
is_deeply App::SimpleBackuper::Info({%options, path => '/'}, \%state)->{subfiles},
[ { name => 'tmp', oldest_backup => 'test', newest_backup => 'test'} ];
is_deeply App::SimpleBackuper::Info({%options, path => '/not-existent'}, \%state), {error => 'NOT_FOUND'};
my $result = App::SimpleBackuper::Info({%options, path => '/tmp/simple-backuper-test/src'}, \%state);
is_deeply $result->{subfiles}, [ { name => 'a.file', oldest_backup => 'test', newest_backup => 'test'} ];
my @lstat = lstat('/tmp/simple-backuper-test/src');
is $result->{versions}->[0]->{user}, scalar getpwuid($lstat[4]);
is $result->{versions}->[0]->{group}, scalar getgrgid($lstat[5]);
is_deeply $result->{versions}->[0]->{backups}, ['test'];
ok ! App::SimpleBackuper::Restore({
db => '/tmp/simple-backuper-test/db',
'backup-name' => 'test',
path => '/tmp/simple-backuper-test/src',
destination => '/tmp/simple-backuper-test/dst',