CTKlib

 view release on metacpan or  search on metacpan

lib/CTK/Plugin/SFTP.pm  view on Meta::CPAN

            return unless S_ISREG($entry->{a}->perm);
            $found{ $entry->{filename} } = $entry->{a}->size || 0;
            return 1;
        });
        if ($sftp->error) {
            $self->error(sprintf("The ls failed: %s", $sftp->error));
            $sftp->disconnect;
            return;
        }
    }

    # Change dir
    if (length($path)) {
        $sftp->setcwd($path) or do {
            $self->error(sprintf("Can't change directory %s on %s: %s", $path, $wop, $sftp->error));
            $sftp->disconnect;
            return;
        };
        $wop .= $path =~ /^\// ? $path : sprintf("/%s", $path);
    }

    # List processing
    my $top = length($dirin) ? $dirin : getcwd();
    find({ wanted => sub {
        return if -d;
        my $name = $_; # File name only
        my $file = $File::Find::name; # File (full path)
        my $dir = $File::Find::dir; # Directory
        return if $dir ne $dirin;
        @inlist = _expand_wildcards(@list) unless @inlist;
        if ($reg) {
            return unless $name =~ $reg;
        } elsif (@inlist) {
            return unless grep {$_ eq $name} @inlist;
        } else {
            return if length $filter;
        }

        # Start!
        #printf "#%d Dir: %s; Name: %s; File: %s\n", $count, $dir, $name, $file;
        my ($fs_local, $fs_remote) = (0, 0);
        $fs_local = _filesize($name); # Get local file size
        $fs_remote = $uniq && exists($found{$name}) ? ($found{$name} || 0) : 0;  # Get remote file size

        # Put file
        my $statput = 0;
        if ($uniq && (-e $name) && $fs_remote == $fs_local) {
            $statput = -1; # Skip! If uniq
        } else {
            $self->debug(sprintf("store \"%s\" \"%s\"", $file, $wop));
            if ($sftp->put($file, $name)) {
                $statput = 1;
            } else {
                $self->error(sprintf("Can't put file %s to %s: %s", $name, $wop, $sftp->error));
                return;
            }
        }

        # Get file size if put is success
        if ($statput == 1) {
            if (my $rstat = $sftp->stat($name)) {
                $fs_remote = $rstat->size || 0;
            } else {
                $self->error(sprintf("The stat() failed: %s", $sftp->error)) if $sftp->error;
            }
        }

        # Remove file
        if ($fs_remote == $fs_local) { # Ok
            $count++ if $statput == 1;
            if ($op =~ /^move/i) {
                unlink($name) or $self->error(sprintf("Can't delete file \"%s\": %s", $name, $!));
            }
        } else { # Error
            $self->error(sprintf("Can't put file \"%s\". Size mismatch: Got: %d; Expected: %d", $name, $fs_remote, $fs_local));
        }

    }}, $dirin);

    # Disconnect
    $sftp->disconnect;

    return $count;
});

sub _filesize {
    my $f = shift;
    my $filesize = 0;
    $filesize = (stat $f)[7] if -e $f;
    return $filesize // 0;
}

sub _expand_wildcards {
    my @wildcards = grep {defined && length} @_;
    return () unless @wildcards;
    my @g = map(/[*?]/o ? (glob($_)) : ($_), @wildcards);
    return () unless @g;
    return @g;
}

sub _get_path {
    my $d = shift;
    return getcwd() unless defined($d) && length($d);
    return abs_path($d) if -e $d and -l $d;
    return File::Spec->catdir(getcwd(), $d) unless File::Spec->file_name_is_absolute($d);
    return $d;
}

1;

__END__



( run in 1.346 second using v1.01-cache-2.11-cpan-39bf76dae61 )