AnyEvent-FTP
view release on metacpan or search on metacpan
lib/AnyEvent/FTP/Client.pm view on Meta::CPAN
=head2 stor
$client->stor($filename, $local);
Send a file to the server with the given remote filename (C<$filename>)
and using C<$local> as a source.
Returns an instance of L<AnyEvent::FTP::Client::Transfer>, which supports the
AnyEvent condition variable interface (that is it has C<cb> and C<recv> methods).
Its callback will be called when the transfer is complete.
C<$local> may be one of
=over 4
=item scalar reference
The contents of the file will be retrieved from the scalar referred to by the reference.
my $local = 'some data for foo.txt';
$client->stor('foo.txt', \$local);
=item file handle
The contents of the file will be read from the file handle.
open my $fh, '<', 'foo.txt';
binmode $fh;
$client->stor('foo.txt', $fh);
=item the name of the local file
If C<$local> is just a regular non reference scalar, then it will be treated as the
local filename, which will be opened and read from in order to create the file on
the server.
$client->stor('foo.txt', 'foo.txt');
=back
=head2 stou
$client->stou($filename, $local)
Works exactly like the C<stor> method, except use the FTP C<STOU> command instead of
C<STOR>. Since the remote filename is optional for C<STOU> you may pass in C<undef>
as the remote filename. You can get the remote filename after the fact using the
C<remote_name> method.
my $xfer;
$xfer = $client->stou(undef, $local)->cb(sub {
my $remote_filename = $xfer->remote_name;
});
=head2 appe
$client->appe($filename, $local);
Works exactly like the C<stor> method, except use the FTP C<APPE> command instead of
C<STOR>. This method will append C<$local> to the remote file. One way to resume an
upload to the remote FTP server would be to open the local file, determine the remote
file's size and seek to that position in the local file and use the C<appe> method
with C<$local> as that file handle, as in this example:
# assume that foo.txt is in the current local dir
# and the remote local dir
my $filename = "foo.txt";
$client->size($filename)->cb(sub {
my $size = shift->recv;
open my $fh, '<', $filename;
binmode $fh;
seek $fh, $size, 0;
$client->appe($filename, $fh);
});
Note that the C<SIZE> command is an extension to FTP, and may not be available on all
servers.
=head2 list
$client->list($location)
Execute the FTP C<LIST> command. The results will be sent as a list reference
(instead of a L<AnyEvent::FTP::Client::Response> object) to the returned condition
variable.
use strict;
use warnings;
use AnyEvent;
use AnyEvent::FTP::Client;
my $client = AnyEvent::FTP::Client->new;
my $cv = AnyEvent->condvar;
# connect to CPAN ftp server
$client->connect('ftp://ftp.cpan.org/pub/CPAN/src')->cb(sub {
# execute LIST command and print results to stdout
$client->list->cb(sub {
my $list = shift->recv;
print "$_\n" for @$list;
$cv->send;
});
});
$cv->recv;
=head2 nlst
$client->nlst($location);
Works exactly like the C<list> method, except the FTP C<NLST> command is used.
The main difference is that this method returns filenames only.
=head2 rename
$client->rename($from, $to);
This method renames the remote file from C<$from> to C<$to>.
lib/AnyEvent/FTP/Client.pm view on Meta::CPAN
=item $client-E<gt>site-E<gt>microsoft
For commands specific to Microsoft's IIS FTP server.
See L<AnyEvent::FTP::Client::Site::Microsoft>.
=item $client-E<gt>site-E<gt>net_ftp_server
For commands specific to L<Net::FTPServer>.
See L<AnyEvent::FTP::Client::Site::NetFtpServer>.
=item $client-E<gt>site-E<gt>proftpd
For commands specific to proftpd.
See L<AnyEvent::FTP::Client::Site::Proftpd>.
=back
=head1 EXAMPLES
Here are some longer examples. They are also included with the
L<AnyEvent::FTP> distribution in its C<example> directory.
=head2 fget.pl
Given a URL to a file, this script will fetch the file and store it
on your local machine. If you use the C<-d> option you can see the
FTP commands and their responses as they happen.
#!/usr/bin/perl
use strict;
use warnings;
use autodie;
use 5.010;
use AnyEvent::FTP::Client;
use URI;
use URI::file;
use Term::ProgressBar;
use Term::Prompt qw( prompt );
use Getopt::Long qw( GetOptions );
use Path::Class qw( file );
my $debug = 0;
my $progress = 0;
my $active = 0;
GetOptions(
'd' => \$debug,
'p' => \$progress,
'a' => \$active,
);
my $remote = shift;
unless(defined $remote)
{
say STDERR "usage: perl fget.pl [ -d | -p ] [ -a ] remote";
say STDERR " where remote is a URL for a file on an FTP server";
say STDERR " and local is a local filename (optional) where to transfer it to";
say STDERR " -d (optional) prints FTP commands and responses";
say STDERR " -p (optional) displays a progress bar as the file uploads";
say STDERR " -a (optional) use active mode transfer";
exit 2;
}
$remote = URI->new($remote);
unless($remote->scheme eq 'ftp')
{
say STDERR "only FTP URLs are supported";
exit 2;
}
unless(defined $remote->password)
{
$remote->password(prompt('p', 'Password: ', '', ''));
say '';
}
do {
my $from = $remote->clone;
$from->password(undef);
say "SRC: ", $from;
};
my @path = split /\//, $remote->path;
my $fn = pop @path;
if(-e $fn)
{
say STDERR "local file already exists";
exit 2;
}
my $ftp = AnyEvent::FTP::Client->new( passive => $active ? 0 : 1 );
$ftp->on_send(sub {
my($cmd, $arguments) = @_;
$arguments //= '';
$arguments = 'XXXX' if $cmd eq 'PASS';
say "CLIENT: $cmd $arguments"
if $debug;
});
$ftp->on_each_response(sub {
my $res = shift;
if($debug)
{
say sprintf "SERVER: [ %d ] %s", $res->code, $_ for @{ $res->message };
}
});
$ftp->connect($remote->host, $remote->port)->recv;
$ftp->login($remote->user, $remote->password)->recv;
$ftp->type('I')->recv;
$ftp->cwd(join '/', '', @path)->recv;
my $remote_size;
if($progress)
lib/AnyEvent/FTP/Client.pm view on Meta::CPAN
use Term::Prompt qw( prompt );
use Getopt::Long qw( GetOptions );
my $debug = 0;
my $method = 'nlst';
GetOptions(
'd' => \$debug,
'l' => sub { $method = 'list' },
);
my $ftp = AnyEvent::FTP::Client->new;
if($debug)
{
$ftp->on_send(sub {
my($cmd, $arguments) = @_;
$arguments //= '';
$arguments = 'XXXX' if $cmd eq 'PASS';
say "CLIENT: $cmd $arguments";
});
$ftp->on_each_response(sub {
my $res = shift;
say sprintf "SERVER: [ %d ] %s", $res->code, $_ for @{ $res->message };
});
}
my $uri = shift;
unless(defined $uri)
{
say STDERR "usage: perl fls.pl URL\n";
exit 2;
}
$uri = URI->new($uri);
unless($uri->scheme eq 'ftp')
{
say STDERR "only FTP URL accpeted";
exit 2;
}
unless(defined $uri->password)
{
$uri->password(prompt('p', 'Password: ', '', ''));
say '';
}
my $path = $uri->path;
$uri->path('');
$ftp->connect($uri);
say $_ for @{ $ftp->$method($path)->recv };
=head2 fput.pl
This script uploads a local file to the remote given a local filename
and a remote FTP URL.
#!/usr/bin/perl
use strict;
use warnings;
use autodie;
use 5.010;
use AnyEvent::FTP::Client;
use URI;
use URI::file;
use Term::ProgressBar;
use Term::Prompt qw( prompt );
use Getopt::Long qw( GetOptions );
use Path::Class qw( file );
my $debug = 0;
my $progress = 0;
my $active = 0;
GetOptions(
'd' => \$debug,
'p' => \$progress,
'a' => \$active,
);
my $local = shift;
my $remote = shift;
unless(defined $local && defined $remote)
{
say STDERR "usage: perl fput.pl [ -d | -p ] [ -a ] local remote";
say STDERR " where local is a local file";
say STDERR " and remote is a URL for a FTP server";
say STDERR " -d (optional) prints FTP commands and responses";
say STDERR " -p (optional) displays a progress bar as the file uploads";
say STDERR " -a (optional) use an active transfer instead of passive";
exit 2;
}
$local = file($local);
$remote = URI->new($remote);
unless($remote->scheme eq 'ftp')
{
say STDERR "only FTP URLs are supported";
exit 2;
}
unless(defined $remote->password)
{
$remote->password(prompt('p', 'Password: ', '', ''));
say '';
}
do {
my $from = URI::file->new_abs($local);
my $to = $remote->clone;
$to->password(undef);
say "SRC: ", $from;
say "DST: ", $to;
};
my $ftp = AnyEvent::FTP::Client->new( passive => $active ? 0 : 1 );
$ftp->on_send(sub {
my($cmd, $arguments) = @_;
$arguments //= '';
$arguments = 'XXXX' if $cmd eq 'PASS';
say "CLIENT: $cmd $arguments"
if $debug;
});
$ftp->on_each_response(sub {
my $res = shift;
if($debug)
{
say sprintf "SERVER: [ %d ] %s", $res->code, $_ for @{ $res->message };
}
});
$ftp->connect($remote->host, $remote->port)->recv;
$ftp->login($remote->user, $remote->password)->recv;
$ftp->type('I')->recv;
if(defined $remote->path)
{
$ftp->cwd($remote->path)->recv;
}
open my $fh, '<', $local;
binmode $fh;
my $buffer;
( run in 1.372 second using v1.01-cache-2.11-cpan-b16cb0d3907 )