With the last release of that module 21 years ago, I think it's safe to say that author isn't going to add SFTP support any time soon :-)
If you look at the source of the module, though, there's not much there. It should be fairly easy to write a new one for SFTP.
Unfortunately, the API between Net::FTP and Net::SFTP are not quite the same. In case it helps, here is some code I have that hides the difference between the two modules with my own API (though this only covers ls and get, not put)
*NOTE* Actually wait, looking closer at the original code I see what looks like a custom FTP command? https://metacpan.org/dist/MVS-JESFTP/source/JESFTP.pm#L106. Are you sure that job control is possible over SFTP?
sub _fetch_uri {
my ($self, $uri)= @_;
my $conn= $self->_cached_connection($uri);
if ($uri->scheme eq 'ftp') {
my $buf= '';
open my $fh, '>', \$buf or die;
$conn->get($uri->path, $fh)
or die 'file could not be downloaded: ' . $conn->message;
close $fh;
return $buf;
}
elsif ($uri->scheme eq 'sftp') {
return scalar $conn->get($uri->path);
}
elsif ($uri->scheme eq 'file') {
return $conn->slurp_raw;
}
else { die "BUG: Unhandled scheme ".$uri->scheme; }
}
# Return arrayref of file names under the URI path
#
sub _readdir_uri {
my ($self, $uri)= @_;
my $conn= $self->_cached_connection($uri);
if ($uri->scheme eq 'ftp') {
# connection refers to root filesystem. path can be multiple co
+mponents
# deep reaching into the file tree. Then, need to remove all di
+rectory portions
# of the response.
return [ map { $_ =~ s|.*/||; $_ } $conn->ls($uri->path) ];
}
elsif ($uri->scheme eq 'sftp') {
return [ map $_->{filename}, $conn->ls($uri->path) ];
}
elsif ($uri->scheme eq 'file') {
return [ $conn->children ];
}
else { die "BUG: Unhandled scheme ".$uri->scheme; }
}
sub _cached_connection {
my ($self, $uri)= @_;
if ($uri->scheme eq 'ftp') {
return ($self->_conn_cache->{'ftp:'.$uri->user.'@'.$uri->host} /
+/= $self->_connect_ftp($uri));
}
elsif ($uri->scheme eq 'sftp') {
return ($self->_conn_cache->{'sftp:'.$uri->user.'@'.$uri->host}
+//= $self->_connect_sftp($uri));
}
elsif ($uri->scheme eq 'file') {
_logcroak('Refusing to access local file URL')
unless $ENV{DATA_SERVICE_ACCESS_LOCAL}; # for debugging
return Path::Tiny::path($uri->file);
}
else {
_logcroak("Don't know how to access ".$self->_redacted_uri($uri)
+);
}
}
sub _connect_ftp {
my ($self, $uri)= @_;
my $host= $uri->host;
my $ftp = Net::FTP->new($host, Passive => 1)
or die "Cannot connect to '$host': $@";
$ftp->login($uri->user, $uri->password)
or die 'Cannot login: ', $ftp->message;
$ftp->binary
or die "Can't start binary mode";
return $ftp
}
sub _connect_sftp {
my ($self, $uri)= @_;
my $host= $uri->host;
Net::SFTP->new(
$host, user => $uri->user, password => $uri->password,
ssh_args => [
# See https://stackoverflow.com/questions/41964908/netsftp-pe
+rl-rsa-authentification/51863332#51863332
identity_files => [],
# deprecated, but needed for ancient servers
options => [ "MACs +hmac-sha1" ],
],
);
}
|