net-sftp 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/doc/LICENSE-BSD +27 -0
- data/doc/LICENSE-GPL +280 -0
- data/doc/LICENSE-RUBY +56 -0
- data/examples/asynchronous.rb +57 -0
- data/examples/ssh-service.rb +31 -0
- data/examples/synchronous.rb +120 -0
- data/lib/net/sftp.rb +39 -0
- data/lib/net/sftp/errors.rb +25 -0
- data/lib/net/sftp/operations/abstract.rb +103 -0
- data/lib/net/sftp/operations/close.rb +31 -0
- data/lib/net/sftp/operations/errors.rb +76 -0
- data/lib/net/sftp/operations/fsetstat.rb +36 -0
- data/lib/net/sftp/operations/fstat.rb +32 -0
- data/lib/net/sftp/operations/lstat.rb +31 -0
- data/lib/net/sftp/operations/mkdir.rb +33 -0
- data/lib/net/sftp/operations/open.rb +32 -0
- data/lib/net/sftp/operations/opendir.rb +32 -0
- data/lib/net/sftp/operations/read.rb +84 -0
- data/lib/net/sftp/operations/readdir.rb +55 -0
- data/lib/net/sftp/operations/realpath.rb +37 -0
- data/lib/net/sftp/operations/remove.rb +31 -0
- data/lib/net/sftp/operations/rename.rb +32 -0
- data/lib/net/sftp/operations/rmdir.rb +31 -0
- data/lib/net/sftp/operations/services.rb +42 -0
- data/lib/net/sftp/operations/setstat.rb +33 -0
- data/lib/net/sftp/operations/stat.rb +31 -0
- data/lib/net/sftp/operations/write.rb +63 -0
- data/lib/net/sftp/protocol/01/attributes.rb +146 -0
- data/lib/net/sftp/protocol/01/impl.rb +251 -0
- data/lib/net/sftp/protocol/01/packet-assistant.rb +82 -0
- data/lib/net/sftp/protocol/01/services.rb +47 -0
- data/lib/net/sftp/protocol/02/impl.rb +39 -0
- data/lib/net/sftp/protocol/02/packet-assistant.rb +32 -0
- data/lib/net/sftp/protocol/02/services.rb +44 -0
- data/lib/net/sftp/protocol/03/impl.rb +42 -0
- data/lib/net/sftp/protocol/03/packet-assistant.rb +35 -0
- data/lib/net/sftp/protocol/03/services.rb +44 -0
- data/lib/net/sftp/protocol/04/attributes.rb +227 -0
- data/lib/net/sftp/protocol/04/impl.rb +134 -0
- data/lib/net/sftp/protocol/04/packet-assistant.rb +51 -0
- data/lib/net/sftp/protocol/04/services.rb +44 -0
- data/lib/net/sftp/protocol/05/services.rb +44 -0
- data/lib/net/sftp/protocol/constants.rb +60 -0
- data/lib/net/sftp/protocol/driver.rb +232 -0
- data/lib/net/sftp/protocol/packet-assistant.rb +84 -0
- data/lib/net/sftp/protocol/services.rb +55 -0
- data/lib/net/sftp/session.rb +215 -0
- data/lib/net/sftp/version.rb +25 -0
- data/test/ALL-TESTS.rb +21 -0
- data/test/operations/tc_abstract.rb +124 -0
- data/test/operations/tc_close.rb +40 -0
- data/test/operations/tc_fsetstat.rb +48 -0
- data/test/operations/tc_fstat.rb +40 -0
- data/test/operations/tc_lstat.rb +40 -0
- data/test/operations/tc_mkdir.rb +48 -0
- data/test/operations/tc_open.rb +42 -0
- data/test/operations/tc_opendir.rb +40 -0
- data/test/operations/tc_read.rb +103 -0
- data/test/operations/tc_readdir.rb +88 -0
- data/test/operations/tc_realpath.rb +54 -0
- data/test/operations/tc_remove.rb +40 -0
- data/test/operations/tc_rmdir.rb +40 -0
- data/test/operations/tc_setstat.rb +48 -0
- data/test/operations/tc_stat.rb +40 -0
- data/test/operations/tc_write.rb +91 -0
- data/test/protocol/01/tc_attributes.rb +138 -0
- data/test/protocol/01/tc_impl.rb +294 -0
- data/test/protocol/01/tc_packet_assistant.rb +81 -0
- data/test/protocol/02/tc_impl.rb +41 -0
- data/test/protocol/02/tc_packet_assistant.rb +31 -0
- data/test/protocol/03/tc_impl.rb +48 -0
- data/test/protocol/03/tc_packet_assistant.rb +34 -0
- data/test/protocol/04/tc_attributes.rb +174 -0
- data/test/protocol/04/tc_impl.rb +102 -0
- data/test/protocol/04/tc_packet_assistant.rb +41 -0
- data/test/protocol/tc_driver.rb +219 -0
- metadata +137 -0
@@ -0,0 +1,33 @@
|
|
1
|
+
#--
|
2
|
+
# =============================================================================
|
3
|
+
# Copyright (c) 2004, Jamis Buck (jgb3@email.byu.edu)
|
4
|
+
# All rights reserved.
|
5
|
+
#
|
6
|
+
# This source file is distributed as part of the Net::SFTP Secure FTP Client
|
7
|
+
# library for Ruby. This file (and the library as a whole) may be used only as
|
8
|
+
# allowed by either the BSD license, or the Ruby license (or, by association
|
9
|
+
# with the Ruby license, the GPL). See the "doc" subdirectory of the Net::SFTP
|
10
|
+
# distribution for the texts of these licenses.
|
11
|
+
# -----------------------------------------------------------------------------
|
12
|
+
# net-sftp website: http://net-ssh.rubyforge.org/sftp
|
13
|
+
# project website : http://rubyforge.org/projects/net-ssh
|
14
|
+
# =============================================================================
|
15
|
+
#++
|
16
|
+
|
17
|
+
require 'net/sftp/operations/abstract'
|
18
|
+
|
19
|
+
module Net ; module SFTP ; module Operations
|
20
|
+
|
21
|
+
# Implements the +setstat+ operation.
|
22
|
+
class Setstat < Abstract
|
23
|
+
|
24
|
+
# Perform the operation. The +hash+ parameter is a hash of attributes that
|
25
|
+
# should be set on the file or directory indicated by the +path+.
|
26
|
+
def perform( path, hash )
|
27
|
+
attrs = @driver.attr_factory.from_hash( hash )
|
28
|
+
@driver.setstat( nil, path, attrs )
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
end ; end ; end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
#--
|
2
|
+
# =============================================================================
|
3
|
+
# Copyright (c) 2004, Jamis Buck (jgb3@email.byu.edu)
|
4
|
+
# All rights reserved.
|
5
|
+
#
|
6
|
+
# This source file is distributed as part of the Net::SFTP Secure FTP Client
|
7
|
+
# library for Ruby. This file (and the library as a whole) may be used only as
|
8
|
+
# allowed by either the BSD license, or the Ruby license (or, by association
|
9
|
+
# with the Ruby license, the GPL). See the "doc" subdirectory of the Net::SFTP
|
10
|
+
# distribution for the texts of these licenses.
|
11
|
+
# -----------------------------------------------------------------------------
|
12
|
+
# net-sftp website: http://net-ssh.rubyforge.org/sftp
|
13
|
+
# project website : http://rubyforge.org/projects/net-ssh
|
14
|
+
# =============================================================================
|
15
|
+
#++
|
16
|
+
|
17
|
+
require 'net/sftp/operations/abstract'
|
18
|
+
|
19
|
+
module Net ; module SFTP ; module Operations
|
20
|
+
|
21
|
+
# Implements the +stat+ operation.
|
22
|
+
class Stat < Abstract
|
23
|
+
|
24
|
+
# Perform the operation.
|
25
|
+
def perform( path )
|
26
|
+
@driver.stat( nil, path )
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
end ; end ; end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
#--
|
2
|
+
# =============================================================================
|
3
|
+
# Copyright (c) 2004, Jamis Buck (jgb3@email.byu.edu)
|
4
|
+
# All rights reserved.
|
5
|
+
#
|
6
|
+
# This source file is distributed as part of the Net::SFTP Secure FTP Client
|
7
|
+
# library for Ruby. This file (and the library as a whole) may be used only as
|
8
|
+
# allowed by either the BSD license, or the Ruby license (or, by association
|
9
|
+
# with the Ruby license, the GPL). See the "doc" subdirectory of the Net::SFTP
|
10
|
+
# distribution for the texts of these licenses.
|
11
|
+
# -----------------------------------------------------------------------------
|
12
|
+
# net-sftp website: http://net-ssh.rubyforge.org/sftp
|
13
|
+
# project website : http://rubyforge.org/projects/net-ssh
|
14
|
+
# =============================================================================
|
15
|
+
#++
|
16
|
+
|
17
|
+
require 'net/sftp/operations/abstract'
|
18
|
+
|
19
|
+
module Net ; module SFTP ; module Operations
|
20
|
+
|
21
|
+
# Implements the +write+ operation. Handles, automatically, the looping
|
22
|
+
# necessary to write a large data set.
|
23
|
+
class Write < Abstract
|
24
|
+
|
25
|
+
# The maximum size of data that will be written at one time.
|
26
|
+
CHUNK_SIZE = 64 * 1024
|
27
|
+
|
28
|
+
# Perform the operation. Only CHUNK_SIZE portions of the +data+ parameter
|
29
|
+
# will be written at a time, with subsequent chunks being writteni
|
30
|
+
# automatically when prior chunks complete.
|
31
|
+
def perform( handle, data, offset=0 )
|
32
|
+
@handle = handle
|
33
|
+
@offset = offset
|
34
|
+
@data = data
|
35
|
+
@pos = 0
|
36
|
+
|
37
|
+
@driver.write( nil, handle, offset, data[0,CHUNK_SIZE] )
|
38
|
+
end
|
39
|
+
|
40
|
+
# Invoked when the server sends a status packet. If the status is FX_OK,
|
41
|
+
# then the callback is invoked (if all data has been written), or the
|
42
|
+
# next chunk is written to the server (if more data remains). Other
|
43
|
+
# status codes are handled by the superclass.
|
44
|
+
def do_status( code, message, language )
|
45
|
+
if code == FX_OK
|
46
|
+
@log.debug "[#{@id}] chunk written" if @log.debug?
|
47
|
+
@pos += CHUNK_SIZE
|
48
|
+
|
49
|
+
if @pos > @data.length
|
50
|
+
@callback[ OK ]
|
51
|
+
return
|
52
|
+
end
|
53
|
+
|
54
|
+
@driver.write @id, @handle, @offset + @pos, @data[@pos,CHUNK_SIZE]
|
55
|
+
@session.register @id, self
|
56
|
+
else
|
57
|
+
super
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
end ; end ; end
|
@@ -0,0 +1,146 @@
|
|
1
|
+
#--
|
2
|
+
# =============================================================================
|
3
|
+
# Copyright (c) 2004, Jamis Buck (jgb3@email.byu.edu)
|
4
|
+
# All rights reserved.
|
5
|
+
#
|
6
|
+
# This source file is distributed as part of the Net::SFTP Secure FTP Client
|
7
|
+
# library for Ruby. This file (and the library as a whole) may be used only as
|
8
|
+
# allowed by either the BSD license, or the Ruby license (or, by association
|
9
|
+
# with the Ruby license, the GPL). See the "doc" subdirectory of the Net::SFTP
|
10
|
+
# distribution for the texts of these licenses.
|
11
|
+
# -----------------------------------------------------------------------------
|
12
|
+
# net-sftp website: http://net-ssh.rubyforge.org/sftp
|
13
|
+
# project website : http://rubyforge.org/projects/net-ssh
|
14
|
+
# =============================================================================
|
15
|
+
#++
|
16
|
+
|
17
|
+
module Net ; module SFTP ; module Protocol ; module V_01
|
18
|
+
|
19
|
+
# A class representing the attributes of a file or directory on the server.
|
20
|
+
# It may be used to specify new attributes, or to query existing attributes.
|
21
|
+
class Attributes
|
22
|
+
|
23
|
+
F_SIZE = 0x00000001
|
24
|
+
F_UIDGID = 0x00000002
|
25
|
+
F_PERMISSIONS = 0x00000004
|
26
|
+
F_ACMODTIME = 0x00000008
|
27
|
+
F_EXTENDED = 0x80000000
|
28
|
+
|
29
|
+
attr_accessor :size
|
30
|
+
attr_accessor :uid
|
31
|
+
attr_accessor :gid
|
32
|
+
attr_accessor :permissions
|
33
|
+
attr_accessor :atime
|
34
|
+
attr_accessor :mtime
|
35
|
+
attr_accessor :extended
|
36
|
+
|
37
|
+
# An initialization routine, to grant the class (factory) access to a
|
38
|
+
# buffer factory. The buffer factory is used by the class' #to_s
|
39
|
+
# method to encode the object's attributes.
|
40
|
+
#
|
41
|
+
# This returns +self+, making it suitable for chaining.
|
42
|
+
def self.init( buffers )
|
43
|
+
@buffers = buffers
|
44
|
+
self
|
45
|
+
end
|
46
|
+
|
47
|
+
# Returns the buffer factory for this class.
|
48
|
+
def self.buffers
|
49
|
+
@buffers
|
50
|
+
end
|
51
|
+
|
52
|
+
# Returns the buffer factory for the object's class.
|
53
|
+
def buffers
|
54
|
+
self.class.buffers
|
55
|
+
end
|
56
|
+
|
57
|
+
# Create a new, empty Attributes object.
|
58
|
+
def self.empty
|
59
|
+
new
|
60
|
+
end
|
61
|
+
|
62
|
+
# Create a new Attributes object, initialized from the given buffer.
|
63
|
+
def self.from_buffer( buffer )
|
64
|
+
flags = buffer.read_long
|
65
|
+
|
66
|
+
size = buffer.read_int64 if ( flags & F_SIZE ) != 0
|
67
|
+
uid = buffer.read_long if ( flags & F_UIDGID ) != 0
|
68
|
+
gid = buffer.read_long if ( flags & F_UIDGID ) != 0
|
69
|
+
permissions = buffer.read_long if ( flags & F_PERMISSIONS ) != 0
|
70
|
+
atime = buffer.read_long if ( flags & F_ACMODTIME ) != 0
|
71
|
+
mtime = buffer.read_long if ( flags & F_ACMODTIME ) != 0
|
72
|
+
|
73
|
+
if ( flags & F_EXTENDED ) != 0
|
74
|
+
extended = Hash.new
|
75
|
+
buffer.read_long.times do
|
76
|
+
extended[ buffer.read_string ] = buffer.read_string
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
new( size, uid, gid, permissions, atime, mtime, extended )
|
81
|
+
end
|
82
|
+
|
83
|
+
# Create a new attributes object, initialized from the given hash. The
|
84
|
+
# :owner and :group attributes are treated specially; they are not actually
|
85
|
+
# supported by this version of the protocol, but are instead converted
|
86
|
+
# by this method to their corresponding id numbers, and assigned
|
87
|
+
# (respectively) to :uid and :gid.
|
88
|
+
def self.from_hash( hash )
|
89
|
+
if hash[:owner]
|
90
|
+
require 'etc'
|
91
|
+
hash[:uid] = Etc.getpwnam( hash[:owner] ).uid
|
92
|
+
end
|
93
|
+
|
94
|
+
if hash[:group]
|
95
|
+
require 'etc'
|
96
|
+
hash[:gid] = Etc.getgrnam( hash[:group] ).gid
|
97
|
+
end
|
98
|
+
|
99
|
+
new hash[:size], hash[:uid], hash[:gid], hash[:permissions],
|
100
|
+
hash[:atime], hash[:mtime], hash[:extended]
|
101
|
+
end
|
102
|
+
|
103
|
+
private_class_method :new
|
104
|
+
|
105
|
+
# Create a new Attributes with the given attributes.
|
106
|
+
def initialize( size=nil, uid=nil, gid=nil, permissions=nil,
|
107
|
+
atime=nil, mtime=nil, extended=nil )
|
108
|
+
# begin
|
109
|
+
@size = size
|
110
|
+
@uid = uid
|
111
|
+
@gid = gid
|
112
|
+
@permissions = permissions
|
113
|
+
@atime = atime
|
114
|
+
@mtime = mtime
|
115
|
+
@extended = extended
|
116
|
+
end
|
117
|
+
|
118
|
+
# Convert the object to a string suitable for passing in an SFTP
|
119
|
+
# packet.
|
120
|
+
def to_s
|
121
|
+
flags = 0
|
122
|
+
|
123
|
+
flags |= F_SIZE if @size
|
124
|
+
flags |= F_UIDGID if @uid && @gid
|
125
|
+
flags |= F_PERMISSIONS if @permissions
|
126
|
+
flags |= F_ACMODTIME if @atime && @mtime
|
127
|
+
flags |= F_EXTENDED if @extended
|
128
|
+
|
129
|
+
buffer = buffers.writer
|
130
|
+
buffer.write_long flags
|
131
|
+
buffer.write_int64 @size if @size
|
132
|
+
buffer.write_long @uid, @gid if @uid && @gid
|
133
|
+
buffer.write_long @permissions if @permissions
|
134
|
+
buffer.write_long @atime, @mtime if @atime && @mtime
|
135
|
+
|
136
|
+
if @extended
|
137
|
+
buffer.write_long @extended.size
|
138
|
+
@extended.each { |k,v| buffer.write_string k, v }
|
139
|
+
end
|
140
|
+
|
141
|
+
buffer.to_s
|
142
|
+
end
|
143
|
+
|
144
|
+
end
|
145
|
+
|
146
|
+
end ; end ; end ; end
|
@@ -0,0 +1,251 @@
|
|
1
|
+
#--
|
2
|
+
# =============================================================================
|
3
|
+
# Copyright (c) 2004, Jamis Buck (jgb3@email.byu.edu)
|
4
|
+
# All rights reserved.
|
5
|
+
#
|
6
|
+
# This source file is distributed as part of the Net::SFTP Secure FTP Client
|
7
|
+
# library for Ruby. This file (and the library as a whole) may be used only as
|
8
|
+
# allowed by either the BSD license, or the Ruby license (or, by association
|
9
|
+
# with the Ruby license, the GPL). See the "doc" subdirectory of the Net::SFTP
|
10
|
+
# distribution for the texts of these licenses.
|
11
|
+
# -----------------------------------------------------------------------------
|
12
|
+
# net-sftp website: http://net-ssh.rubyforge.org/sftp
|
13
|
+
# project website : http://rubyforge.org/projects/net-ssh
|
14
|
+
# =============================================================================
|
15
|
+
#++
|
16
|
+
|
17
|
+
require 'net/sftp/errors'
|
18
|
+
require 'net/sftp/protocol/constants'
|
19
|
+
|
20
|
+
module Net ; module SFTP ; module Protocol ; module V_01
|
21
|
+
|
22
|
+
# The implementing class for version 1 of the SFTP protocol. It
|
23
|
+
# implements the various operations and callbacks available to this
|
24
|
+
# level of the protocol. Other protocol versions will typically
|
25
|
+
# extend this class, adding (or modifying) methods as needed to bring
|
26
|
+
# the implementation into sync with the needed version.
|
27
|
+
class Impl
|
28
|
+
include Constants
|
29
|
+
|
30
|
+
Name = Struct.new( :filename, :longname, :attributes )
|
31
|
+
|
32
|
+
# The protocol driver that drives this dispatcher.
|
33
|
+
attr_reader :driver
|
34
|
+
|
35
|
+
# The attribute-factory used by this dispatcher.
|
36
|
+
attr_reader :attr_factory
|
37
|
+
|
38
|
+
# The protocol extensions specified when the protocol version was
|
39
|
+
# negotiated.
|
40
|
+
attr_accessor :extensions
|
41
|
+
|
42
|
+
# Create a new instance using the given protocol driver, packet
|
43
|
+
# assistant, and attributes factory.
|
44
|
+
def initialize( buffers, driver, assistant, attr_factory )
|
45
|
+
@buffers = buffers
|
46
|
+
@driver = driver
|
47
|
+
@assistant = assistant
|
48
|
+
@attr_factory = attr_factory
|
49
|
+
@on_status = nil
|
50
|
+
@on_handle = nil
|
51
|
+
@on_data = nil
|
52
|
+
@on_name = nil
|
53
|
+
@on_attrs = nil
|
54
|
+
end
|
55
|
+
|
56
|
+
# A helper method for defining new operations supported by this
|
57
|
+
# implementation. This will create one method for each named operation.
|
58
|
+
# By default, the method simply formats the packet (using the packet
|
59
|
+
# assistant), and then sends the data via the driver. It will then
|
60
|
+
# return the request id used for this operation.
|
61
|
+
def self.operation( *names )
|
62
|
+
names.each do |name|
|
63
|
+
const = "FXP_#{name.to_s.upcase}"
|
64
|
+
class_eval <<-EOF, __FILE__, __LINE__+1
|
65
|
+
def #{name}( id, *args )
|
66
|
+
id, packet = @assistant.#{name}( id, *args )
|
67
|
+
@driver.send_data #{const}, packet
|
68
|
+
id
|
69
|
+
end
|
70
|
+
EOF
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
# A helper method for registering new callbacks. Each callback will
|
75
|
+
# cause three new methods to be created, <tt>on_<em>name</em></tt>,
|
76
|
+
# <tt>has_on_<em>name</em>?</tt>, and <tt>call_on_<em>name</em></tt>.
|
77
|
+
# The <tt>on_<em>name</em></tt> method may be used to register a block
|
78
|
+
# for the corresponding callback.
|
79
|
+
def self.callback( *names )
|
80
|
+
names.each do |name|
|
81
|
+
class_eval <<-EOF, __FILE__, __LINE__+1
|
82
|
+
def on_#{name}( &block )
|
83
|
+
@on_#{name} = block
|
84
|
+
end
|
85
|
+
|
86
|
+
def has_on_#{name}?
|
87
|
+
not @on_#{name}.nil?
|
88
|
+
end
|
89
|
+
|
90
|
+
def call_on_#{name}( *args )
|
91
|
+
return unless @on_#{name}
|
92
|
+
@on_#{name}.call( *args )
|
93
|
+
end
|
94
|
+
|
95
|
+
public :on_#{name}
|
96
|
+
protected :has_on_#{name}?, :call_on_#{name}
|
97
|
+
EOF
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
operation :open,
|
102
|
+
:close,
|
103
|
+
:read,
|
104
|
+
:write,
|
105
|
+
:opendir,
|
106
|
+
:readdir,
|
107
|
+
:remove,
|
108
|
+
:stat,
|
109
|
+
:lstat,
|
110
|
+
:fstat,
|
111
|
+
:setstat,
|
112
|
+
:fsetstat,
|
113
|
+
:mkdir,
|
114
|
+
:rmdir,
|
115
|
+
:realpath
|
116
|
+
|
117
|
+
callback :status,
|
118
|
+
:handle,
|
119
|
+
:data,
|
120
|
+
:name,
|
121
|
+
:attrs
|
122
|
+
|
123
|
+
alias :open_raw :open
|
124
|
+
alias :stat_raw :stat
|
125
|
+
alias :lstat_raw :lstat
|
126
|
+
alias :fstat_raw :fstat
|
127
|
+
|
128
|
+
alias :close_handle :close
|
129
|
+
|
130
|
+
F_READ = 0x00000001
|
131
|
+
F_WRITE = 0x00000002
|
132
|
+
F_APPEND = 0x00000004
|
133
|
+
F_CREAT = 0x00000008
|
134
|
+
F_TRUNC = 0x00000010
|
135
|
+
F_EXCL = 0x00000020
|
136
|
+
|
137
|
+
# The open operation is special, since it protects the caller from the
|
138
|
+
# specific flags and options required by SFTP. Instead, the caller simply
|
139
|
+
# specifies a combination of IO flags, and an appropriate posix mode, and
|
140
|
+
# they are translated into the correct SFTP flags.
|
141
|
+
def open( id, path, flags, mode=0660 )
|
142
|
+
sftp_flags = case
|
143
|
+
when ( flags & IO::WRONLY ) != 0 then F_WRITE
|
144
|
+
when ( flags & IO::RDWR ) != 0 then F_READ | F_WRITE
|
145
|
+
when ( flags & IO::APPEND ) != 0 then F_APPEND
|
146
|
+
else F_READ
|
147
|
+
end
|
148
|
+
|
149
|
+
sftp_flags |= F_CREAT if ( flags & IO::CREAT ) != 0
|
150
|
+
sftp_flags |= F_TRUNC if ( flags & IO::TRUNC ) != 0
|
151
|
+
sftp_flags |= F_EXCL if ( flags & IO::EXCL ) != 0
|
152
|
+
|
153
|
+
attributes = @attr_factory.empty
|
154
|
+
attributes.permissions = mode
|
155
|
+
|
156
|
+
open_raw id, path, sftp_flags, attributes
|
157
|
+
end
|
158
|
+
|
159
|
+
# The stat operation is special, since later versions of the protocol add
|
160
|
+
# support for 'flags'. These flags are ignored in this version, but the
|
161
|
+
# parameter exists to allow a program written for one version of the
|
162
|
+
# protocol to work with later versions.
|
163
|
+
def stat( id, filename, flags=nil )
|
164
|
+
stat_raw id, filename
|
165
|
+
end
|
166
|
+
|
167
|
+
# The lstat operation is special, since later versions of the protocol add
|
168
|
+
# support for 'flags'. These flags are ignored in this version, but the
|
169
|
+
# parameter exists to allow a program written for one version of the
|
170
|
+
# protocol to work with later versions.
|
171
|
+
def lstat( id, filename, flags=nil )
|
172
|
+
lstat_raw id, filename
|
173
|
+
end
|
174
|
+
|
175
|
+
# The fstat operation is special, since later versions of the protocol add
|
176
|
+
# support for 'flags'. These flags are ignored in this version, but the
|
177
|
+
# parameter exists to allow a program written for one version of the
|
178
|
+
# protocol to work with later versions.
|
179
|
+
def fstat( id, handle, flags=nil )
|
180
|
+
fstat_raw id, handle
|
181
|
+
end
|
182
|
+
|
183
|
+
# Dispatches the given packet type to the appropriate handler method.
|
184
|
+
# If a new protocol version adds a new packet type, it should override
|
185
|
+
# this method, performing its own checking first, followed by calling
|
186
|
+
# +super+.
|
187
|
+
def dispatch( channel, type, content )
|
188
|
+
case type
|
189
|
+
when FXP_STATUS then do_status( channel, content )
|
190
|
+
when FXP_HANDLE then do_handle( channel, content )
|
191
|
+
when FXP_DATA then do_data( channel, content )
|
192
|
+
when FXP_NAME then do_name( channel, content )
|
193
|
+
when FXP_ATTRS then do_attrs( channel, content )
|
194
|
+
else
|
195
|
+
raise Net::SFTP::Exception,
|
196
|
+
"unsupported SFTP packet type #{type} (#{content.to_s.inspect})"
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
# Used internally to handle +status+ packets. The +on_status+ callback is
|
201
|
+
# invoked, if registered, with the driver, id, and code.
|
202
|
+
def do_status( channel, content )
|
203
|
+
return unless has_on_status?
|
204
|
+
id = content.read_long
|
205
|
+
code = content.read_long
|
206
|
+
call_on_status( driver, id, code, nil, nil )
|
207
|
+
end
|
208
|
+
|
209
|
+
# Used internally to handle +handle+ packets. The +on_handle+ callback is
|
210
|
+
# invoked, if registered, with the driver, id, and handle.
|
211
|
+
def do_handle( channel, content )
|
212
|
+
return unless has_on_handle?
|
213
|
+
id = content.read_long
|
214
|
+
handle = content.read_string
|
215
|
+
call_on_handle( driver, id, handle )
|
216
|
+
end
|
217
|
+
|
218
|
+
# Used internally to handle +data+ packets. The +on_data+ callback is
|
219
|
+
# invoked, if registered, with the driver, id, and data (as a buffer).
|
220
|
+
def do_data( channel, content )
|
221
|
+
return unless has_on_data?
|
222
|
+
id = content.read_long
|
223
|
+
data = content.read_string
|
224
|
+
call_on_data( driver, id, data )
|
225
|
+
end
|
226
|
+
|
227
|
+
# Used internally to handle +name+ packets. The +on_name+ callback is
|
228
|
+
# invoked, if registered, with the driver, id, and array of items.
|
229
|
+
def do_name( channel, content )
|
230
|
+
return unless has_on_name?
|
231
|
+
id = content.read_long
|
232
|
+
items = []
|
233
|
+
content.read_long.times do
|
234
|
+
items.push( Name.new( content.read_string, content.read_string,
|
235
|
+
@attr_factory.from_buffer( content ) ) )
|
236
|
+
end
|
237
|
+
call_on_name( driver, id, items )
|
238
|
+
end
|
239
|
+
|
240
|
+
# Used internally to handle +attrs+ packets. The +on_attrs+ callback is
|
241
|
+
# invoked, if registered, with the driver, id, and attribute object.
|
242
|
+
def do_attrs( channel, content )
|
243
|
+
return unless has_on_attrs?
|
244
|
+
id = content.read_long
|
245
|
+
attrs = @attr_factory.from_buffer( content )
|
246
|
+
call_on_attrs( driver, id, attrs )
|
247
|
+
end
|
248
|
+
|
249
|
+
end
|
250
|
+
|
251
|
+
end ; end ; end ; end
|