home *** CD-ROM | disk | FTP | other *** search
/ PC Professionell 2004 December / PCpro_2004_12.ISO / files / webserver / tsw / TSW_3.4.0.exe / Apache2 / perl / SFTP.pm < prev    next >
Encoding:
Perl POD Document  |  2003-12-12  |  26.5 KB  |  891 lines

  1. # $Id: SFTP.pm,v 1.29 2003/12/12 21:24:21 autarch Exp $
  2.  
  3. package Net::SFTP;
  4. use strict;
  5.  
  6. use Net::SFTP::Constants qw( :fxp :flags :status :att SSH2_FILEXFER_VERSION );
  7. use Net::SFTP::Util qw( fx2txt );
  8. use Net::SFTP::Attributes;
  9. use Net::SFTP::Buffer;
  10. use Net::SSH::Perl::Constants qw( :msg2 );
  11. use Net::SSH::Perl 1.24;
  12.  
  13. use Carp qw( croak );
  14.  
  15. use vars qw( $VERSION );
  16. $VERSION = 0.08;
  17.  
  18. use constant COPY_SIZE => 8192;
  19.  
  20. sub new {
  21.     my $class = shift;
  22.     my $sftp = bless { }, $class;
  23.     $sftp->{host} = shift;
  24.     $sftp->init(@_);
  25. }
  26.  
  27. sub init {
  28.     my $sftp = shift;
  29.     my %param = @_;
  30.     $sftp->{debug} = delete $param{debug};
  31.     $param{ssh_args} ||= [];
  32.  
  33.     $sftp->{_msg_id} = 0;
  34.  
  35.     my $ssh = Net::SSH::Perl->new($sftp->{host}, protocol => 2,
  36.         debug => $sftp->{debug}, @{ $param{ssh_args} });
  37.     $ssh->login($param{user}, $param{password});
  38.     $sftp->{ssh} = $ssh;
  39.  
  40.     my $channel = $sftp->_open_channel;
  41.     $sftp->{channel} = $channel;
  42.  
  43.     $sftp->do_init;
  44.  
  45.     $sftp;
  46. }
  47.  
  48. sub _open_channel {
  49.     my $sftp = shift;
  50.     my $ssh = $sftp->{ssh};
  51.  
  52.     my $channel = $ssh->_session_channel;
  53.     $channel->open;
  54.  
  55.     $channel->register_handler(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, sub {
  56.         my($c, $packet) = @_;
  57.         $c->{ssh}->debug("Sending subsystem: sftp");
  58.         my $r_packet = $c->request_start("subsystem", 1);
  59.         $r_packet->put_str("sftp");
  60.         $r_packet->send;
  61.     });
  62.  
  63.     my $subsystem_reply = sub {
  64.         my($c, $packet) = @_;
  65.         my $id = $packet->get_int32;
  66.         if ($packet->type == SSH2_MSG_CHANNEL_FAILURE) {
  67.             $c->{ssh}->fatal_disconnect("Request for " .
  68.                 "subsystem 'sftp' failed on channel '$id'");
  69.         }
  70.         $c->{ssh}->break_client_loop;
  71.     };
  72.  
  73.     my $cmgr = $ssh->channel_mgr;
  74.     $cmgr->register_handler(SSH2_MSG_CHANNEL_FAILURE, $subsystem_reply);
  75.     $cmgr->register_handler(SSH2_MSG_CHANNEL_SUCCESS, $subsystem_reply);
  76.  
  77.     $sftp->{incoming} = Net::SFTP::Buffer->new;
  78.     my $incoming = $sftp->{incoming};
  79.     $channel->register_handler("_output_buffer", sub {
  80.         my($c, $buffer) = @_;
  81.         $incoming->append($buffer->bytes);
  82.         $c->{ssh}->break_client_loop;
  83.     });
  84.  
  85.     ## Get channel confirmation, etc. Break once we get a response
  86.     ## to subsystem execution.
  87.     $ssh->client_loop;
  88.  
  89.     $channel;
  90. }
  91.  
  92. sub do_init {
  93.     my $sftp = shift;
  94.     my $ssh = $sftp->{ssh};
  95.  
  96.     $sftp->debug("Sending SSH2_FXP_INIT");
  97.     my $msg = $sftp->new_msg(SSH2_FXP_INIT);
  98.     $msg->put_int32(SSH2_FILEXFER_VERSION);
  99.     $sftp->send_msg($msg);
  100.  
  101.     $msg = $sftp->get_msg;
  102.     my $type = $msg->get_int8;
  103.     if ($type != SSH2_FXP_VERSION) {
  104.         croak "Invalid packet back from SSH2_FXP_INIT (type $type)";
  105.     }
  106.     my $version = $msg->get_int32;
  107.     $sftp->debug("Remote version: $version");
  108.  
  109.     ## XXX Check for extensions.
  110. }
  111.  
  112. sub debug {
  113.     my $sftp = shift;
  114.     if ($sftp->{debug}) {
  115.         $sftp->{ssh}->debug("sftp: @_");
  116.     }
  117. }
  118.  
  119. ## Server -> client methods.
  120.  
  121. sub get_attrs {
  122.     my $sftp = shift;
  123.     my($expected_id) = @_;
  124.     my $msg = $sftp->get_msg;
  125.     my $type = $msg->get_int8;
  126.     my $id = $msg->get_int32;
  127.     $sftp->debug("Received stat reply T:$type I:$id");
  128.     croak "ID mismatch ($id != $expected_id)" unless $id == $expected_id;
  129.     if ($type == SSH2_FXP_STATUS) {
  130.         my $status = $msg->get_int32;
  131.         warn "Couldn't stat remote file: ", fx2txt($status);
  132.         return;
  133.     }
  134.     elsif ($type != SSH2_FXP_ATTRS) {
  135.         croak "Expected SSH2_FXP_ATTRS packet, got $type";
  136.     }
  137.     $msg->get_attributes;
  138. }
  139.  
  140. sub get_status {
  141.     my $sftp = shift;
  142.     my($expected_id) = @_;
  143.     my $msg = $sftp->get_msg;
  144.     my $type = $msg->get_int8;
  145.     my $id = $msg->get_int32;
  146.  
  147.     croak "ID mismatch ($id != $expected_id)" unless $id == $expected_id;
  148.     if ($type != SSH2_FXP_STATUS) {
  149.         croak "Expected SSH2_FXP_STATUS packet, got $type";
  150.     }
  151.  
  152.     $msg->get_int32;
  153. }
  154.  
  155. sub get_handle {
  156.     my $sftp = shift;
  157.     my($expected_id) = @_;
  158.  
  159.     my $msg = $sftp->get_msg;
  160.     my $type = $msg->get_int8;
  161.     my $id = $msg->get_int32;
  162.  
  163.     croak "ID mismatch ($id != $expected_id)" unless $id == $expected_id;
  164.     if ($type == SSH2_FXP_STATUS) {
  165.         my $status = $msg->get_int32;
  166.         warn "Couldn't get handle: ", fx2txt($status);
  167.         return;
  168.     }
  169.     elsif ($type != SSH2_FXP_HANDLE) {
  170.         croak "Expected SSH2_FXP_HANDLE packet, got $type";
  171.     }
  172.  
  173.     $msg->get_str;
  174. }
  175.  
  176. ## Client -> server methods.
  177.  
  178. sub _send_str_request {
  179.     my $sftp = shift;
  180.     my($code, $str) = @_;
  181.     my($msg, $id) = $sftp->new_msg_w_id($code);
  182.     $msg->put_str($str);
  183.     $sftp->send_msg($msg);
  184.     $sftp->debug("Sent message T:$code I:$id");
  185.     $id;
  186. }
  187.  
  188. sub _send_str_attrs_request {
  189.     my $sftp = shift;
  190.     my($code, $str, $a) = @_;
  191.     my($msg, $id) = $sftp->new_msg_w_id($code);
  192.     $msg->put_str($str);
  193.     $msg->put_attributes($a);
  194.     $sftp->send_msg($msg);
  195.     $sftp->debug("Sent message T:$code I:$id");
  196.     $id;
  197. }
  198.  
  199. sub _check_ok_status {
  200.     my $status = $_[0]->get_status($_[1]);
  201.     warn "Couldn't $_[2]: ", fx2txt($status) unless $status == SSH2_FX_OK;
  202.     $status;
  203. }
  204.  
  205. ## SSH2_FXP_OPEN (3)
  206. sub do_open {
  207.     my $sftp = shift;
  208.     my($path, $flags, $a) = @_;
  209.     $a ||= Net::SFTP::Attributes->new;
  210.     my($msg, $id) = $sftp->new_msg_w_id(SSH2_FXP_OPEN);
  211.     $msg->put_str($path);
  212.     $msg->put_int32($flags);
  213.     $msg->put_attributes($a);
  214.     $sftp->send_msg($msg);
  215.     $sftp->debug("Sent SSH2_FXP_OPEN I:$id P:$path");
  216.     $sftp->get_handle($id);
  217. }
  218.  
  219. ## SSH2_FXP_READ (4)
  220. sub do_read {
  221.     my $sftp = shift;
  222.     my($handle, $offset, $size) = @_;
  223.     $size ||= COPY_SIZE;
  224.     my($msg, $expected_id) = $sftp->new_msg_w_id(SSH2_FXP_READ);
  225.     $msg->put_str($handle);
  226.     $msg->put_int64(int $offset);
  227.     $msg->put_int32($size);
  228.     $sftp->send_msg($msg);
  229.     $sftp->debug("Sent message SSH2_FXP_READ I:$expected_id O:$offset");
  230.     $msg = $sftp->get_msg;
  231.     my $type = $msg->get_int8;
  232.     my $id = $msg->get_int32;
  233.     $sftp->debug("Received reply T:$type I:$id");
  234.     croak "ID mismatch ($id != $expected_id)" unless $id == $expected_id;
  235.     if ($type == SSH2_FXP_STATUS) {
  236.         my $status = $msg->get_int32;
  237.         if ($status != SSH2_FX_EOF) {
  238.             warn "Couldn't read from remote file: ", fx2txt($status);
  239.             $sftp->do_close($handle);
  240.         }
  241.         return(undef, $status);
  242.     }
  243.     elsif ($type != SSH2_FXP_DATA) {
  244.         croak "Expected SSH2_FXP_DATA packet, got $type";
  245.     }
  246.     $msg->get_str;
  247. }
  248.  
  249. ## SSH2_FXP_WRITE (6)
  250. sub do_write {
  251.     my $sftp = shift;
  252.     my($handle, $offset, $data) = @_;
  253.     my($msg, $id) = $sftp->new_msg_w_id(SSH2_FXP_WRITE);
  254.     $msg->put_str($handle);
  255.     $msg->put_int64(int $offset);
  256.     $msg->put_str($data);
  257.     $sftp->send_msg($msg);
  258.     $sftp->debug("Sent message SSH2_FXP_WRITE I:$id O:$offset");
  259.     my $status = $sftp->get_status($id);
  260.     if ($status != SSH2_FX_OK) {
  261.         warn "Couldn't write to remote file: ", fx2txt($status);
  262.         $sftp->do_close($handle);
  263.     }
  264.     return $status;
  265. }
  266.  
  267. ## SSH2_FXP_LSTAT (7), SSH2_FXP_FSTAT (8), SSH2_FXP_STAT (17)
  268. sub do_lstat { $_[0]->_do_stat(SSH2_FXP_LSTAT, $_[1]) }
  269. sub do_fstat { $_[0]->_do_stat(SSH2_FXP_FSTAT, $_[1]) }
  270. sub do_stat  { $_[0]->_do_stat(SSH2_FXP_STAT , $_[1]) }
  271. sub _do_stat {
  272.     my $sftp = shift;
  273.     my $id = $sftp->_send_str_request(@_);
  274.     $sftp->get_attrs($id);
  275. }
  276.  
  277. ## SSH2_FXP_OPENDIR (11)
  278. sub do_opendir {
  279.     my $sftp = shift;
  280.     my $id = $sftp->_send_str_request(SSH2_FXP_OPENDIR, @_);
  281.     $sftp->get_handle($id);
  282. }
  283.  
  284. ## SSH2_FXP_CLOSE (4),   SSH2_FXP_REMOVE (13),
  285. ## SSH2_FXP_MKDIR (14),  SSH2_FXP_RMDIR (15),
  286. ## SSH2_FXP_SETSTAT (9), SSH2_FXP_FSETSTAT (10)
  287. {
  288.     no strict 'refs';
  289.     *do_close    = _gen_simple_method(SSH2_FXP_CLOSE,  'close file');
  290.     *do_remove   = _gen_simple_method(SSH2_FXP_REMOVE, 'delete file');
  291.     *do_mkdir    = _gen_simple_method(SSH2_FXP_MKDIR,  'create directory');
  292.     *do_rmdir    = _gen_simple_method(SSH2_FXP_RMDIR,  'remove directory');
  293.     *do_setstat  = _gen_simple_method(SSH2_FXP_SETSTAT , 'setstat');
  294.     *do_fsetstat = _gen_simple_method(SSH2_FXP_FSETSTAT , 'fsetstat');
  295. }
  296.  
  297. sub _gen_simple_method {
  298.     my($code, $msg) = @_;
  299.     sub {
  300.         my $sftp = shift;
  301.         my $id = @_ > 1 ?
  302.             $sftp->_send_str_attrs_request($code, @_) :
  303.             $sftp->_send_str_request($code, @_);
  304.         $sftp->_check_ok_status($id, $msg);
  305.     };
  306. }
  307.  
  308. ## SSH2_FXP_REALPATH (16)
  309. sub do_realpath {
  310.     my $sftp = shift;
  311.     my($path) = @_;
  312.     my $expected_id = $sftp->_send_str_request(SSH2_FXP_REALPATH, $path);
  313.     my $msg = $sftp->get_msg;
  314.     my $type = $msg->get_int8;
  315.     my $id = $msg->get_int32;
  316.     croak "ID mismatch ($id != $expected_id)" unless $id == $expected_id;
  317.     if ($type == SSH2_FXP_STATUS) {
  318.         my $status = $msg->get_int32;
  319.         warn "Couldn't canonicalise $path: ", fx2txt($status);
  320.         return;
  321.     }
  322.     elsif ($type != SSH2_FXP_NAME) {
  323.         croak "Expected SSH2_FXP_NAME packet, got $type";
  324.     }
  325.     my $count = $msg->get_int32;
  326.     croak "Got multiple names ($count) from SSH2_FXP_REALPATH"
  327.         unless $count == 1;
  328.     $msg->get_str;   ## Filename.
  329. }
  330.  
  331. ## SSH2_FXP_RENAME (18)
  332. sub do_rename {
  333.     my $sftp = shift;
  334.     my($old, $new) = @_;
  335.     my($msg, $id) = $sftp->new_msg_w_id(SSH2_FXP_RENAME);
  336.     $msg->put_str($old);
  337.     $msg->put_str($new);
  338.     $sftp->send_msg($msg);
  339.     $sftp->debug("Sent message SSH2_FXP_RENAME '$old' => '$new'");
  340.     $sftp->_check_ok_status($id, "rename '$old' to '$new'");
  341. }
  342.  
  343. ## High-level client -> server methods.
  344.  
  345. sub get {
  346.     my $sftp = shift;
  347.     my($remote, $local, $cb) = @_;
  348.     my $ssh = $sftp->{ssh};
  349.     my $want = defined wantarray ? 1 : 0;
  350.  
  351.     my $a = $sftp->do_stat($remote) or return;
  352.     local *FH;
  353.     if ($local) {
  354.         open FH, ">$local" or croak "Can't open $local: $!";
  355.         binmode FH or croak "Can't binmode FH: $!";
  356.     }
  357.  
  358.     my $handle = $sftp->do_open($remote, SSH2_FXF_READ);
  359.     my $offset = 0;
  360.     my $ret = '';
  361.     while (1) {
  362.         my($data, $status) = $sftp->do_read($handle, $offset, COPY_SIZE);
  363.         last if defined $status && $status == SSH2_FX_EOF;
  364.         return unless $data;
  365.         my $len = length($data);
  366.         croak "Received more data than asked for $len > " . COPY_SIZE
  367.             if $len > COPY_SIZE;
  368.         $sftp->debug("In read loop, got $len offset $offset");
  369.         $cb->($sftp, $data, $offset, $a->size) if defined $cb;
  370.         if ($local) {
  371.             print FH $data;
  372.         }
  373.         elsif ($want) {
  374.             $ret .= $data;
  375.         }
  376.         $offset += $len;
  377.     }
  378.     $sftp->do_close($handle);
  379.  
  380.     if ($local) {
  381.         close FH;
  382.         my $flags = $a->flags;
  383.         my $mode = $flags & SSH2_FILEXFER_ATTR_PERMISSIONS ?
  384.             $a->perm & 0777 : 0666;
  385.         chmod $mode, $local or croak "Can't chmod $local: $!";
  386.  
  387.         if ($flags & SSH2_FILEXFER_ATTR_ACMODTIME) {
  388.             utime $a->atime, $a->mtime, $local or
  389.                 croak "Can't utime $local: $!";
  390.         }
  391.     }
  392.     $ret;
  393. }
  394.  
  395. sub put {
  396.     my $sftp = shift;
  397.     my($local, $remote, $cb) = @_;
  398.     my $ssh = $sftp->{ssh};
  399.  
  400.     my @stat = stat $local or croak "Can't stat local $local: $!";
  401.     my $size = $stat[7];
  402.     my $a = Net::SFTP::Attributes->new(Stat => \@stat);
  403.     my $flags = $a->flags;
  404.     $flags &= ~SSH2_FILEXFER_ATTR_SIZE;
  405.     $flags &= ~SSH2_FILEXFER_ATTR_UIDGID;
  406.     $a->flags($flags);
  407.     $a->perm( $a->perm & 0777 );
  408.  
  409.     local *FH;
  410.     open FH, $local or croak "Can't open local file $local: $!";
  411.     binmode FH or die "Can't binmode FH: $!";
  412.  
  413.     my $handle = $sftp->do_open($remote, SSH2_FXF_WRITE | SSH2_FXF_CREAT |
  414.         SSH2_FXF_TRUNC, $a);
  415.  
  416.     my $offset = 0;
  417.     while (1) {
  418.         my($len, $data, $msg, $id);
  419.         $len = read FH, $data, COPY_SIZE;
  420.         last unless $len;
  421.         $cb->($sftp, $data, $offset, $size) if defined $cb;
  422.         my $status = $sftp->do_write($handle, $offset, $data);
  423.         if ($status != SSH2_FX_OK) {
  424.             close FH;
  425.             return;
  426.         }
  427.         $sftp->debug("In write loop, got $len offset $offset");
  428.         $offset += $len;
  429.     }
  430.  
  431.     close FH or warn "Can't close local file $local: $!";
  432.  
  433.     $sftp->do_fsetstat($handle, $a);
  434.     $sftp->do_close($handle);
  435. }
  436.  
  437. sub ls {
  438.     my $sftp = shift;
  439.     my($remote, $code) = @_;
  440.     my @dir;
  441.     my $handle = $sftp->do_opendir($remote);
  442.     while (1) {
  443.         my $expected_id = $sftp->_send_str_request(SSH2_FXP_READDIR, $handle);
  444.         my $msg = $sftp->get_msg;
  445.         my $type = $msg->get_int8;
  446.         my $id = $msg->get_int32;
  447.         $sftp->debug("Received reply T:$type I:$id");
  448.  
  449.         croak "ID mismatch ($id != $expected_id)" unless $id == $expected_id;
  450.         if ($type == SSH2_FXP_STATUS) {
  451.             my $status = $msg->get_int32;
  452.             $sftp->debug("Received SSH2_FXP_STATUS $status");
  453.             if ($status == SSH2_FX_EOF) {
  454.                 last;
  455.             }
  456.             else {
  457.                 warn "Couldn't read directory: ", fx2txt($status);
  458.                 $sftp->do_close($handle);
  459.                 return;
  460.             }
  461.         }
  462.         elsif ($type != SSH2_FXP_NAME) {
  463.             croak "Expected SSH2_FXP_NAME packet, got $type";
  464.         }
  465.  
  466.         my $count = $msg->get_int32;
  467.         last unless $count;
  468.         $sftp->debug("Received $count SSH2_FXP_NAME responses");
  469.         for my $i (0..$count-1) {
  470.             my $fname = $msg->get_str;
  471.             my $lname = $msg->get_str;
  472.             my $a = $msg->get_attributes;
  473.             my $rec = {
  474.                 filename => $fname,
  475.                 longname => $lname,
  476.                 a        => $a,
  477.             };
  478.             if ($code && ref($code) eq "CODE") {
  479.                 $code->($rec);
  480.             }
  481.             else {
  482.                 push @dir, $rec;
  483.             }
  484.         }
  485.     }
  486.     $sftp->do_close($handle);
  487.     @dir;
  488. }
  489.  
  490. ## Messaging methods--messages are essentially sub-packets.
  491.  
  492. sub msg_id { $_[0]->{_msg_id}++ }
  493.  
  494. sub new_msg {
  495.     my $sftp = shift;
  496.     my($code) = @_;
  497.     my $msg = Net::SFTP::Buffer->new;
  498.     $msg->put_int8($code);
  499.     $msg;
  500. }
  501.  
  502. sub new_msg_w_id {
  503.     my $sftp = shift;
  504.     my($code, $sid) = @_;
  505.     my $msg = $sftp->new_msg($code);
  506.     my $id = defined $sid ? $sid : $sftp->msg_id;
  507.     $msg->put_int32($id);
  508.     ($msg, $id);
  509. }
  510.  
  511. sub send_msg {
  512.     my $sftp = shift;
  513.     my($buf) = @_;
  514.     my $b = Net::SFTP::Buffer->new;
  515.     $b->put_int32($buf->length);
  516.     $b->append($buf->bytes);
  517.     $sftp->{channel}->send_data($b->bytes);
  518. }
  519.  
  520. sub get_msg {
  521.     my $sftp = shift;
  522.     my $buf = $sftp->{incoming};
  523.     my $len;
  524.     unless ($buf->length > 4) {
  525.         $sftp->{ssh}->client_loop;
  526.         croak "Connection closed" unless $buf->length > 4;
  527.         $len = unpack "N", $buf->bytes(0, 4, '');
  528.         croak "Received message too long $len" if $len > 256 * 1024;
  529.         while ($buf->length < $len) {
  530.             $sftp->{ssh}->client_loop;
  531.         }
  532.     }
  533.     my $b = Net::SFTP::Buffer->new;
  534.     $b->append( $buf->bytes(0, $len, '') );
  535.     $b;
  536. }
  537.  
  538. 1;
  539. __END__
  540.  
  541. =head1 NAME
  542.  
  543. Net::SFTP - Secure File Transfer Protocol client
  544.  
  545. =head1 SYNOPSIS
  546.  
  547.     use Net::SFTP;
  548.     my $sftp = Net::SFTP->new($host);
  549.     $sftp->get("foo", "bar");
  550.     $sftp->put("bar", "baz");
  551.  
  552. =head1 DESCRIPTION
  553.  
  554. I<Net::SFTP> is a pure-Perl implementation of the Secure File
  555. Transfer Protocol (SFTP)--file transfer built on top of the
  556. SSH protocol. I<Net::SFTP> uses I<Net::SSH::Perl> to build a
  557. secure, encrypted tunnel through which files can be transferred
  558. and managed. It provides a subset of the commands listed in
  559. the SSH File Transfer Protocol IETF draft, which can be found
  560. at I<http://www.openssh.com/txt/draft-ietf-secsh-filexfer-00.txt>.
  561.  
  562. SFTP stands for Secure File Transfer Protocol and is a method of
  563. transferring files between machines over a secure, encrypted
  564. connection (as opposed to regular FTP, which functions over an
  565. insecure connection). The security in SFTP comes through its
  566. integration with SSH, which provides an encrypted transport
  567. layer over which the SFTP commands are executed, and over which
  568. files can be transferred. The SFTP protocol defines a client
  569. and a server; only the client, not the server, is implemented
  570. in I<Net::SFTP>.
  571.  
  572. Because it is built upon SSH, SFTP inherits all of the built-in
  573. functionality provided by I<Net::SSH::Perl>: encrypted
  574. communications between client and server, multiple supported
  575. authentication methods (eg. password, public key, etc.).
  576.  
  577. =head1 USAGE
  578.  
  579. =head2 Net::SFTP->new($host, %args)
  580.  
  581. Opens a new SFTP connection with a remote host I<$host>, and
  582. returns a I<Net::SFTP> object representing that open
  583. connection.
  584.  
  585. I<%args> can contain:
  586.  
  587. =over 4
  588.  
  589. =item * user
  590.  
  591. The username to use to log in to the remote server. This should
  592. be your SSH login, and can be empty, in which case the username
  593. is drawn from the user executing the process.
  594.  
  595. See the I<login> method in I<Net::SSH::Perl> for more details.
  596.  
  597. =item * password
  598.  
  599. The password to use to log in to the remote server. This should
  600. be your SSH password, if you use password authentication in
  601. SSH; if you use public key authentication, this argument is
  602. unused.
  603.  
  604. See the I<login> method in I<Net::SSH::Perl> for more details.
  605.  
  606. =item * debug
  607.  
  608. If set to a true value, debugging messages will be printed out
  609. for both the SSH and SFTP protocols. This automatically turns
  610. on the I<debug> parameter in I<Net::SSH::Perl>.
  611.  
  612. The default is false.
  613.  
  614. =item * ssh_args
  615.  
  616. Specifies a reference to a list of named arguments that should
  617. be given to the constructor of the I<Net::SSH::Perl> object
  618. underlying the I<Net::SFTP> connection.
  619.  
  620. For example, you could use this to set up your authentication
  621. identity files, to set a specific cipher for encryption, etc.
  622.  
  623. See the I<new> method in I<Net::SSH::Perl> for more details.
  624.  
  625. =back
  626.  
  627. =head2 $sftp->get($remote [, $local [, \&callback ] ])
  628.  
  629. Downloads a file I<$remote> from the remote host. If I<$local>
  630. is specified, it is opened/created, and the contents of the
  631. remote file I<$remote> are written to I<$local>. In addition,
  632. its filesystem attributes (atime, mtime, permissions, etc.)
  633. will be set to those of the remote file.
  634.  
  635. If I<get> is called in a non-void context, returns the contents
  636. of I<$remote> (as well as writing them to I<$local>, if I<$local>
  637. is provided.
  638.  
  639. I<$local> is optional. If not provided, the contents of the
  640. remote file I<$remote> will be either discarded, if I<get> is
  641. called in void context, or returned from I<get> if called in
  642. a non-void context. Presumably, in the former case, you will
  643. use the callback function I<\&callback> to "do something" with
  644. the contents of I<$remote>.
  645.  
  646. If I<\&callback> is specified, it should be a reference to a
  647. subroutine. The subroutine will be executed at each iteration
  648. of the read loop (files are generally read in 8192-byte
  649. blocks, although this depends on the server implementation).
  650. The callback function will receive as arguments: a
  651. I<Net::SFTP> object with an open SFTP connection; the data
  652. read from the SFTP server; the offset from the beginning of
  653. the file (in bytes); and the total size of the file (in
  654. bytes). You can use this mechanism to provide status messages,
  655. download progress meters, etc.:
  656.  
  657.     sub callback {
  658.         my($sftp, $data, $offset, $size) = @_;
  659.         print "Read $offset / $size bytes\r";
  660.     }
  661.  
  662. =head2 $sftp->put($local, $remote [, \&callback ])
  663.  
  664. Uploads a file I<$local> from the local host to the remote
  665. host, and saves it as I<$remote>.
  666.  
  667. If I<\&callback> is specified, it should be a reference to a
  668. subroutine. The subroutine will be executed at each iteration
  669. of the write loop, directly after the data has been read from
  670. the local file. The callback function will receive as arguments:
  671. a I<Net::SFTP> object with an open SFTP connection; the data
  672. read from I<$local>, generally in 8192-byte chunks;; the offset
  673. from the beginning of the file (in bytes); and the total size
  674. of the file (in bytes). You can use this mechanism to provide
  675. status messages, upload progress meters, etc.:
  676.  
  677.     sub callback {
  678.         my($sftp, $data, $offset, $size) = @_;
  679.         print "Wrote $offset / $size bytes\r";
  680.     }
  681.  
  682. =head2 $sftp->ls($remote [, $subref ])
  683.  
  684. Fetches a directory listing of I<$remote>.
  685.  
  686. If I<$subref> is specified, for each entry in the directory,
  687. I<$subref> will be called and given a reference to a hash
  688. with three keys: I<filename>, the name of the entry in the
  689. directory listing; I<longname>, an entry in a "long" listing
  690. like C<ls -l>; and I<a>, a I<Net::SFTP::Attributes> object,
  691. which contains the file attributes of the entry (atime, mtime,
  692. permissions, etc.).
  693.  
  694. If I<$subref> is not specified, returns a list of directory
  695. entries, each of which is a reference to a hash as described
  696. in the previous paragraph.
  697.  
  698. =head1 COMMAND METHODS
  699.  
  700. I<Net::SFTP> supports all of the commands listed in the SFTP
  701. version 3 protocol specification. Each command is available
  702. for execution as a separate method, with a few exceptions:
  703. I<SSH_FXP_INIT>, I<SSH_FXP_VERSION>, and I<SSH_FXP_READDIR>.
  704.  
  705. These are the available command methods:
  706.  
  707. =head2 $sftp->do_open($path, $flags [, $attrs ])
  708.  
  709. Sends the I<SSH_FXP_OPEN> command to open a remote file I<$path>,
  710. and returns an open handle on success. On failure returns
  711. I<undef>. The "open handle" is not a Perl filehandle, nor is
  712. it a file descriptor; it is merely a marker used to identify
  713. the open file between the client and the server.
  714.  
  715. I<$flags> should be a bitmask of open flags, whose values can
  716. be obtained from I<Net::SFTP::Constants>:
  717.  
  718.     use Net::SFTP::Constants qw( :flags );
  719.  
  720. I<$attrs> should be a I<Net::SFTP::Attributes> object,
  721. specifying the initial attributes for the file I<$path>. If
  722. you're opening the file for reading only, I<$attrs> can be
  723. left blank, in which case it will be initialized to an
  724. empty set of attributes.
  725.  
  726. =head2 $sftp->do_read($handle, $offset, $copy_size)
  727.  
  728. Sends the I<SSH_FXP_READ> command to read from an open file
  729. handle I<$handle>, starting at I<$offset>, and reading at most
  730. I<$copy_size> bytes.
  731.  
  732. Returns a two-element list consisting of the data read from
  733. the SFTP server in the first slot, and the status code (if any)
  734. in the second. In the case of a successful read, the status code
  735. will be I<undef>, and the data will be defined and true. In the
  736. case of EOF, the status code will be I<SSH2_FX_EOF>, and the
  737. data will be I<undef>. And in the case of an error in the read,
  738. a warning will be emitted, the status code will contain the
  739. error code, and the data will be I<undef>.
  740.  
  741. =head2 $sftp->do_write($handle, $offset, $data)
  742.  
  743. Sends the I<SSH_FXP_WRITE> command to write to an open file handle
  744. I<$handle>, starting at I<$offset>, and where the data to be
  745. written is in I<$data>.
  746.  
  747. Returns the status code. On a successful write, the status code
  748. will be equal to SSH2_FX_OK; in the case of an unsuccessful
  749. write, a warning will be emitted, and the status code will
  750. contain the error returned from the server.
  751.  
  752. =head2 $sftp->do_close($handle)
  753.  
  754. Sends the I<SSH_FXP_CLOSE> command to close either an open
  755. file or open directory, identified by I<$handle> (the handle
  756. returned from either I<do_open> or I<do_opendir>).
  757.  
  758. Emits a warning if the I<CLOSE> fails.
  759.  
  760. Returns the status code for the operation. To turn the
  761. status code into a text message, take a look at the C<fx2txt>
  762. function in I<Net::SFTP::Util>.
  763.  
  764. =head2 $sftp->do_lstat($path)
  765.  
  766. =head2 $sftp->do_fstat($handle)
  767.  
  768. =head2 $sftp->do_stat($path)
  769.  
  770. These three methods all perform similar functionality: they
  771. run a I<stat> on a remote file and return the results in a
  772. I<Net::SFTP::Attributes> object on success.
  773.  
  774. On failure, all three methods return I<undef>, and emit a
  775. warning.
  776.  
  777. I<do_lstat> sends a I<SSH_FXP_LSTAT> command to obtain file
  778. attributes for a named file I<$path>. I<do_stat> sends a
  779. I<SSH_FXP_STAT> command, and differs from I<do_lstat> only
  780. in that I<do_stat> follows symbolic links on the server,
  781. whereas I<do_lstat> does not follow symbolic links.
  782.  
  783. I<do_fstat> sends a I<SSH_FXP_FSTAT> command to obtain file
  784. attributes for an open file handle I<$handle>.
  785.  
  786. =head2 $sftp->do_setstat($path, $attrs)
  787.  
  788. =head2 $sftp->do_fsetstat($handle, $attrs)
  789.  
  790. These two methods both perform similar functionality: they
  791. set the file attributes of a remote file. In both cases
  792. I<$attrs> should be a I<Net::SFTP::Attributes> object.
  793.  
  794. I<do_setstat> sends a I<SSH_FXP_SETSTAT> command to set file
  795. attributes for a remote named file I<$path> to I<$attrs>.
  796.  
  797. I<do_fsetstat> sends a I<SSH_FXP_FSETSTAT> command to set the
  798. attributes of an open file handle I<$handle> to I<$attrs>.
  799.  
  800. Both methods emit a warning if the operation failes, and
  801. both return the status code for the operation. To turn the
  802. status code into a text message, take a look at the C<fx2txt>
  803. function in I<Net::SFTP::Util>.
  804.  
  805. =head2 $sftp->do_opendir($path)
  806.  
  807. Sends a I<SSH_FXP_OPENDIR> command to open the remote
  808. directory I<$path>, and returns an open handle on success.
  809. On failure returns I<undef>.
  810.  
  811. =head2 $sftp->do_remove($path)
  812.  
  813. Sends a I<SSH_FXP_REMOVE> command to remove the remote file
  814. I<$path>.
  815.  
  816. Emits a warning if the operation fails.
  817.  
  818. Returns the status code for the operation. To turn the
  819. status code into a text message, take a look at the C<fx2txt>
  820. function in I<Net::SFTP::Util>.
  821.  
  822. =head2 $sftp->do_mkdir($path, $attrs)
  823.  
  824. Sends a I<SSH_FXP_MKDIR> command to create a remote directory
  825. I<$path> whose attributes should be initialized to I<$attrs>,
  826. a I<Net::SFTP::Attributes> object.
  827.  
  828. Emits a warning if the operation fails.
  829.  
  830. Returns the status code for the operation. To turn the
  831. status code into a text message, take a look at the C<fx2txt>
  832. function in I<Net::SFTP::Util>.
  833.  
  834. =head2 $sftp->do_rmdir($path)
  835.  
  836. Sends a I<SSH_FXP_RMDIR> command to remove a remote directory
  837. I<$path>.
  838.  
  839. Emits a warning if the operation fails.
  840.  
  841. Returns the status code for the operation. To turn the
  842. status code into a text message, take a look at the C<fx2txt>
  843. function in I<Net::SFTP::Util>.
  844.  
  845. =head2 $sftp->do_realpath($path)
  846.  
  847. Sends a I<SSH_FXP_REALPATH> command to canonicalise I<$path>
  848. to an absolute path. This can be useful for turning paths
  849. containing I<'..'> into absolute paths.
  850.  
  851. Returns the absolute path on success, I<undef> on failure.
  852.  
  853. =head2 $sftp->do_rename($old, $new)
  854.  
  855. Sends a I<SSH_FXP_RENAME> command to rename I<$old> to I<$new>.
  856.  
  857. Emits a warning if the operation fails.
  858.  
  859. Returns the status code for the operation. To turn the
  860. status code into a text message, take a look at the C<fx2txt>
  861. function in I<Net::SFTP::Util>.
  862.  
  863. =head1 SUPPORT
  864.  
  865. For samples/tutorials, take a look at the scripts in F<eg/> in
  866. the distribution directory.
  867.  
  868. There is a mailing list for development discussion and usage
  869. questions.  Posting is limited to subscribers only.  You can sign up
  870. at http://lists.sourceforge.net/lists/listinfo/ssh-sftp-perl-users
  871.  
  872. Please report all bugs via rt.cpan.org at
  873. https://rt.cpan.org/NoAuth/ReportBug.html?Queue=net%3A%3Asftp
  874.  
  875. =head1 AUTHOR
  876.  
  877. Current maintainer is Dave Rolsky, autarch@urth.org.
  878.  
  879. Originally written by Benjamin Trott.
  880.  
  881. =head1 COPYRIGHT
  882.  
  883. Copyright (c) 2001 Benjamin Trott, Copyright (c) 2003 David Rolsky.
  884. All rights reserved.  This program is free software; you can
  885. redistribute it and/or modify it under the same terms as Perl itself.
  886.  
  887. The full text of the license can be found in the LICENSE file included
  888. with this module.
  889.  
  890. =cut
  891.