net-sftp-backports 4.0.0.backports

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.
@@ -0,0 +1,152 @@
1
+ require 'net/sftp/protocol/01/attributes'
2
+
3
+ module Net; module SFTP; module Protocol; module V04
4
+
5
+ # A class representing the attributes of a file or directory on the server.
6
+ # It may be used to specify new attributes, or to query existing attributes.
7
+ # This particular class is specific to versions 4 and 5 of the SFTP
8
+ # protocol.
9
+ #
10
+ # To specify new attributes, just pass a hash as the argument to the
11
+ # constructor. The following keys are supported:
12
+ #
13
+ # * :type:: the type of the item (integer, one of the T_ constants)
14
+ # * :size:: the size of the item (integer)
15
+ # * :uid:: the user-id that owns the file (integer)
16
+ # * :gid:: the group-id that owns the file (integer)
17
+ # * :owner:: the name of the user that owns the file (string)
18
+ # * :group:: the name of the group that owns the file (string)
19
+ # * :permissions:: the permissions on the file (integer, e.g. 0755)
20
+ # * :atime:: the access time of the file (integer, seconds since epoch)
21
+ # * :atime_nseconds:: the nanosecond component of atime (integer)
22
+ # * :createtime:: the time at which the file was created (integer, seconds since epoch)
23
+ # * :createtime_nseconds:: the nanosecond component of createtime (integer)
24
+ # * :mtime:: the modification time of the file (integer, seconds since epoch)
25
+ # * :mtime_nseconds:: the nanosecond component of mtime (integer)
26
+ # * :acl:: an array of ACL entries for the item
27
+ # * :extended:: a hash of name/value pairs identifying extended info
28
+ #
29
+ # Likewise, when the server sends an Attributes object, all of the
30
+ # above attributes are exposed as methods (though not all will be set with
31
+ # non-nil values from the server).
32
+ class Attributes < V01::Attributes
33
+
34
+ F_ACCESSTIME = 0x00000008
35
+ F_CREATETIME = 0x00000010
36
+ F_MODIFYTIME = 0x00000020
37
+ F_ACL = 0x00000040
38
+ F_OWNERGROUP = 0x00000080
39
+ F_SUBSECOND_TIMES = 0x00000100
40
+
41
+ # A simple struct for representing a single entry in an Access Control
42
+ # List. (See Net::SFTP::Constants::ACE)
43
+ ACL = Struct.new(:type, :flag, :mask, :who)
44
+
45
+ class <<self
46
+ # The list of supported elements in the attributes structure as defined
47
+ # by v4 of the sftp protocol.
48
+ def elements #:nodoc:
49
+ @elements ||= [
50
+ [:type, :byte, 0],
51
+ [:size, :int64, V01::Attributes::F_SIZE],
52
+ [:owner, :string, F_OWNERGROUP],
53
+ [:group, :string, F_OWNERGROUP],
54
+ [:permissions, :long, V01::Attributes::F_PERMISSIONS],
55
+ [:atime, :int64, F_ACCESSTIME],
56
+ [:atime_nseconds, :long, F_ACCESSTIME | F_SUBSECOND_TIMES],
57
+ [:createtime, :int64, F_CREATETIME],
58
+ [:createtime_nseconds, :long, F_CREATETIME | F_SUBSECOND_TIMES],
59
+ [:mtime, :int64, F_MODIFYTIME],
60
+ [:mtime_nseconds, :long, F_MODIFYTIME | F_SUBSECOND_TIMES],
61
+ [:acl, :special, F_ACL],
62
+ [:extended, :special, V01::Attributes::F_EXTENDED]
63
+ ]
64
+ end
65
+
66
+ private
67
+
68
+ # A helper method for parsing the ACL entry in an Attributes struct.
69
+ def parse_acl(buffer)
70
+ acl_buf = Net::SSH::Buffer.new(buffer.read_string)
71
+ acl = []
72
+ acl_buf.read_long.times do
73
+ acl << ACL.new(acl_buf.read_long, acl_buf.read_long, acl_buf.read_long, acl_buf.read_string)
74
+ end
75
+ acl
76
+ end
77
+ end
78
+
79
+ # The type of the item on the remote server. Must be one of the T_* constants.
80
+ attr_accessor :type
81
+
82
+ # The owner of the item on the remote server, as a string.
83
+ attr_writer :owner
84
+
85
+ # The group of the item on the remote server, as a string.
86
+ attr_writer :group
87
+
88
+ # The nanosecond component of the access time.
89
+ attr_accessor :atime_nseconds
90
+
91
+ # The creation time of the remote item, in seconds since the epoch.
92
+ attr_accessor :createtime
93
+
94
+ # The nanosecond component of the creation time.
95
+ attr_accessor :createtime_nseconds
96
+
97
+ # The nanosecond component of the modification time.
98
+ attr_accessor :mtime_nseconds
99
+
100
+ # The array of access control entries for this item.
101
+ attr_accessor :acl
102
+
103
+ # Create a new Attributes instance with the given attributes. The
104
+ # following keys are supported:
105
+ #
106
+ # * :type:: the type of the item (integer, one of the T_ constants)
107
+ # * :size:: the size of the item (integer)
108
+ # * :uid:: the user-id that owns the file (integer)
109
+ # * :gid:: the group-id that owns the file (integer)
110
+ # * :owner:: the name of the user that owns the file (string)
111
+ # * :group:: the name of the group that owns the file (string)
112
+ # * :permissions:: the permissions on the file (integer, e.g. 0755)
113
+ # * :atime:: the access time of the file (integer, seconds since epoch)
114
+ # * :atime_nseconds:: the nanosecond component of atime (integer)
115
+ # * :createtime:: the time at which the file was created (integer, seconds since epoch)
116
+ # * :createtime_nseconds:: the nanosecond component of createtime (integer)
117
+ # * :mtime:: the modification time of the file (integer, seconds since epoch)
118
+ # * :mtime_nseconds:: the nanosecond component of mtime (integer)
119
+ # * :acl:: an array of ACL entries for the item
120
+ # * :extended:: a hash of name/value pairs identifying extended info
121
+ #
122
+ # All of them default to +nil+ if omitted, except for +type+, which defaults
123
+ # to T_REGULAR.
124
+ def initialize(attributes={})
125
+ super
126
+ attributes[:type] ||= T_REGULAR
127
+ end
128
+
129
+ private
130
+
131
+ # Perform protocol-version-specific preparations for serialization.
132
+ def prepare_serialization!
133
+ # force the group/owner to be translated from uid/gid, if those keys
134
+ # were given on instantiation
135
+ owner
136
+ group
137
+ end
138
+
139
+ # Performs protocol-version-specific encoding of the access control
140
+ # list, if one exists.
141
+ def encode_acl(buffer)
142
+ acl_buf = Net::SSH::Buffer.from(:long, acl.length)
143
+ acl.each do |item|
144
+ acl_buf.write_long item.type, item.flag, item.mask
145
+ acl_buf.write_string item.who
146
+ end
147
+ buffer.write_string(acl_buf.to_s)
148
+ end
149
+
150
+ end
151
+
152
+ end ; end ; end ; end
@@ -0,0 +1,94 @@
1
+ require 'net/sftp/protocol/03/base'
2
+ require 'net/sftp/protocol/04/attributes'
3
+ require 'net/sftp/protocol/04/name'
4
+
5
+ module Net; module SFTP; module Protocol; module V04
6
+
7
+ # Wraps the low-level SFTP calls for version 4 of the SFTP protocol. Also
8
+ # implements the updated FXP_NAME packet parsing as mandated by v4 of the
9
+ # protocol.
10
+ #
11
+ # None of these protocol methods block--all of them return immediately,
12
+ # requiring the SSH event loop to be run while the server response is
13
+ # pending.
14
+ #
15
+ # You will almost certainly never need to use this driver directly. Please
16
+ # see Net::SFTP::Session for the recommended interface.
17
+ class Base < V03::Base
18
+
19
+ # Returns the protocol version implemented by this driver. (4, in this
20
+ # case)
21
+ def version
22
+ 4
23
+ end
24
+
25
+ # As of v4 of the SFTP protocol, the "longname" member was removed from the
26
+ # FXP_NAME structure. This method is essentially the same as the previous
27
+ # implementation, but omits longname.
28
+ def parse_name_packet(packet)
29
+ names = []
30
+
31
+ packet.read_long.times do
32
+ filename = packet.read_string
33
+ attrs = attribute_factory.from_buffer(packet)
34
+ names << name_factory.new(filename, attrs)
35
+ end
36
+
37
+ { :names => names }
38
+ end
39
+
40
+ # Sends a FXP_STAT packet to the server for the given +path+, and with the
41
+ # given +flags+. If +flags+ is nil, it defaults to F_SIZE | F_PERMISSIONS |
42
+ # F_ACCESSTIME | F_CREATETIME | F_MODIFYTIME | F_ACL | F_OWNERGROUP |
43
+ # F_SUBSECOND_TIMES | F_EXTENDED (see Net::SFTP::Protocol::V04::Attributes
44
+ # for those constants).
45
+ def stat(path, flags=nil)
46
+ send_request(FXP_STAT, :string, path, :long, flags || DEFAULT_FLAGS)
47
+ end
48
+
49
+ # Sends a FXP_LSTAT packet to the server for the given +path+, and with the
50
+ # given +flags+. If +flags+ is nil, it defaults to F_SIZE | F_PERMISSIONS |
51
+ # F_ACCESSTIME | F_CREATETIME | F_MODIFYTIME | F_ACL | F_OWNERGROUP |
52
+ # F_SUBSECOND_TIMES | F_EXTENDED (see Net::SFTP::Protocol::V04::Attributes
53
+ # for those constants).
54
+ def lstat(path, flags=nil)
55
+ send_request(FXP_LSTAT, :string, path, :long, flags || DEFAULT_FLAGS)
56
+ end
57
+
58
+ # Sends a FXP_FSTAT packet to the server for the given +path+, and with the
59
+ # given +flags+. If +flags+ is nil, it defaults to F_SIZE | F_PERMISSIONS |
60
+ # F_ACCESSTIME | F_CREATETIME | F_MODIFYTIME | F_ACL | F_OWNERGROUP |
61
+ # F_SUBSECOND_TIMES | F_EXTENDED (see Net::SFTP::Protocol::V04::Attributes
62
+ # for those constants).
63
+ def fstat(handle, flags=nil)
64
+ send_request(FXP_FSTAT, :string, handle, :long, flags || DEFAULT_FLAGS)
65
+ end
66
+
67
+ protected
68
+
69
+ # The default flags used if the +flags+ parameter is nil for any of the
70
+ # #stat, #lstat, or #fstat operations.
71
+ DEFAULT_FLAGS = Attributes::F_SIZE |
72
+ Attributes::F_PERMISSIONS |
73
+ Attributes::F_ACCESSTIME |
74
+ Attributes::F_CREATETIME |
75
+ Attributes::F_MODIFYTIME |
76
+ Attributes::F_ACL |
77
+ Attributes::F_OWNERGROUP |
78
+ Attributes::F_SUBSECOND_TIMES |
79
+ Attributes::F_EXTENDED
80
+
81
+ # Returns the Attributes class used by this version of the protocol
82
+ # (Net::SFTP::Protocol::V04::Attributes, in this case)
83
+ def attribute_factory
84
+ V04::Attributes
85
+ end
86
+
87
+ # Returns the Name class used by this version of the protocol
88
+ # (Net::SFTP::Protocol::V04::Name, in this case)
89
+ def name_factory
90
+ V04::Name
91
+ end
92
+ end
93
+
94
+ end; end; end; end
@@ -0,0 +1,67 @@
1
+ module Net; module SFTP; module Protocol; module V04
2
+
3
+ # Represents a single named item on the remote server. This includes the
4
+ # name, and attributes about the item, and the "longname".
5
+ #
6
+ # For backwards compatibility with the format and interface of the Name
7
+ # structure from previous protocol versions, this also exposes a #longname
8
+ # method, which returns a string that can be used to display this item in
9
+ # a directory listing.
10
+ class Name
11
+ # The name of the item on the remote server.
12
+ attr_reader :name
13
+
14
+ # Attributes instance describing this item.
15
+ attr_reader :attributes
16
+
17
+ # Create a new Name object with the given name and attributes.
18
+ def initialize(name, attributes)
19
+ @name, @attributes = name, attributes
20
+ end
21
+
22
+ # Returns +true+ if the item is a directory.
23
+ def directory?
24
+ attributes.directory?
25
+ end
26
+
27
+ # Returns +true+ if the item is a symlink.
28
+ def symlink?
29
+ attributes.symlink?
30
+ end
31
+
32
+ # Returns +true+ if the item is a regular file.
33
+ def file?
34
+ attributes.file?
35
+ end
36
+
37
+ # Returns a string representing this file, in a format similar to that
38
+ # used by the unix "ls" utility.
39
+ def longname
40
+ @longname ||= begin
41
+ longname = if directory?
42
+ "d"
43
+ elsif symlink?
44
+ "l"
45
+ else
46
+ "-"
47
+ end
48
+
49
+ longname << (attributes.permissions & 0400 != 0 ? "r" : "-")
50
+ longname << (attributes.permissions & 0200 != 0 ? "w" : "-")
51
+ longname << (attributes.permissions & 0100 != 0 ? "x" : "-")
52
+ longname << (attributes.permissions & 0040 != 0 ? "r" : "-")
53
+ longname << (attributes.permissions & 0020 != 0 ? "w" : "-")
54
+ longname << (attributes.permissions & 0010 != 0 ? "x" : "-")
55
+ longname << (attributes.permissions & 0004 != 0 ? "r" : "-")
56
+ longname << (attributes.permissions & 0002 != 0 ? "w" : "-")
57
+ longname << (attributes.permissions & 0001 != 0 ? "x" : "-")
58
+
59
+ longname << (" %-8s %-8s %8d " % [attributes.owner, attributes.group, attributes.size])
60
+
61
+ longname << Time.at(attributes.mtime).strftime("%b %e %H:%M ")
62
+ longname << name
63
+ end
64
+ end
65
+ end
66
+
67
+ end; end; end; end
@@ -0,0 +1,66 @@
1
+ require 'net/sftp/protocol/04/base'
2
+
3
+ module Net; module SFTP; module Protocol; module V05
4
+
5
+ # Wraps the low-level SFTP calls for version 5 of the SFTP protocol.
6
+ #
7
+ # None of these protocol methods block--all of them return immediately,
8
+ # requiring the SSH event loop to be run while the server response is
9
+ # pending.
10
+ #
11
+ # You will almost certainly never need to use this driver directly. Please
12
+ # see Net::SFTP::Session for the recommended interface.
13
+ class Base < V04::Base
14
+ # Returns the protocol version implemented by this driver. (5, in this
15
+ # case)
16
+ def version
17
+ 5
18
+ end
19
+
20
+ # Sends a FXP_RENAME packet to the server to request that the file or
21
+ # directory with the given +name+ (must be a full path) be changed to
22
+ # +new_name+ (which must also be a path). The +flags+ parameter must be
23
+ # either +nil+ or 0 (the default), or some combination of the
24
+ # Net::SFTP::Constants::RenameFlags constants.
25
+ def rename(name, new_name, flags=nil)
26
+ send_request(FXP_RENAME, :string, name, :string, new_name, :long, flags || 0)
27
+ end
28
+
29
+ # Sends a FXP_OPEN packet to the server and returns the packet identifier.
30
+ # The +flags+ parameter is either an integer (in which case it must be
31
+ # a combination of the IO constants) or a string (in which case it must
32
+ # be one of the mode strings that IO::open accepts). The +options+
33
+ # parameter is a hash that is used to construct a new Attribute object,
34
+ # to pass as part of the FXP_OPEN request.
35
+ def open(path, flags, options)
36
+ flags = normalize_open_flags(flags)
37
+
38
+ sftp_flags, desired_access = if flags & (IO::WRONLY | IO::RDWR) != 0
39
+ open = if flags & (IO::CREAT | IO::EXCL) == (IO::CREAT | IO::EXCL)
40
+ FV5::CREATE_NEW
41
+ elsif flags & (IO::CREAT | IO::TRUNC) == (IO::CREAT | IO::TRUNC)
42
+ FV5::CREATE_TRUNCATE
43
+ elsif flags & IO::CREAT == IO::CREAT
44
+ FV5::OPEN_OR_CREATE
45
+ else
46
+ FV5::OPEN_EXISTING
47
+ end
48
+ access = ACE::Mask::WRITE_DATA | ACE::Mask::WRITE_ATTRIBUTES
49
+ access |= ACE::Mask::READ_DATA | ACE::Mask::READ_ATTRIBUTES if (flags & IO::RDWR) == IO::RDWR
50
+ if flags & IO::APPEND == IO::APPEND
51
+ open |= FV5::APPEND_DATA
52
+ access |= ACE::Mask::APPEND_DATA
53
+ end
54
+ [open, access]
55
+ else
56
+ [FV5::OPEN_EXISTING, ACE::Mask::READ_DATA | ACE::Mask::READ_ATTRIBUTES]
57
+ end
58
+
59
+ attributes = attribute_factory.new(options)
60
+
61
+ send_request(FXP_OPEN, :string, path, :long, desired_access, :long, sftp_flags, :raw, attributes.to_s)
62
+ end
63
+
64
+ end
65
+
66
+ end; end; end; end
@@ -0,0 +1,107 @@
1
+ require 'net/sftp/protocol/04/attributes'
2
+
3
+ module Net; module SFTP; module Protocol; module V06
4
+
5
+ # A class representing the attributes of a file or directory on the server.
6
+ # It may be used to specify new attributes, or to query existing attributes.
7
+ # This particular class is specific to versions 6 and higher of the SFTP
8
+ # protocol.
9
+ #
10
+ # To specify new attributes, just pass a hash as the argument to the
11
+ # constructor. The following keys are supported:
12
+ #
13
+ # * :type:: the type of the item (integer, one of the T_ constants)
14
+ # * :size:: the size of the item (integer)
15
+ # * :allocation_size:: the actual number of bytes that the item uses on disk (integer)
16
+ # * :uid:: the user-id that owns the file (integer)
17
+ # * :gid:: the group-id that owns the file (integer)
18
+ # * :owner:: the name of the user that owns the file (string)
19
+ # * :group:: the name of the group that owns the file (string)
20
+ # * :permissions:: the permissions on the file (integer, e.g. 0755)
21
+ # * :atime:: the access time of the file (integer, seconds since epoch)
22
+ # * :atime_nseconds:: the nanosecond component of atime (integer)
23
+ # * :createtime:: the time at which the file was created (integer, seconds since epoch)
24
+ # * :createtime_nseconds:: the nanosecond component of createtime (integer)
25
+ # * :mtime:: the modification time of the file (integer, seconds since epoch)
26
+ # * :mtime_nseconds:: the nanosecond component of mtime (integer)
27
+ # * :ctime:: the time that the file's attributes were last changed (integer)
28
+ # * :ctime_nseconds:: the nanosecond component of ctime (integer)
29
+ # * :acl:: an array of ACL entries for the item
30
+ # * :attrib_bits:: other attributes of the file or directory (as a bit field) (integer)
31
+ # * :attrib_bits_valid:: a mask describing which bits in attrib_bits are valid (integer)
32
+ # * :text_hint:: whether the file may or may not contain textual data (integer)
33
+ # * :mime_type:: the mime type of the file (string)
34
+ # * :link_count:: the hard link count of the file (integer)
35
+ # * :untranslated_name:: the value of the filename before filename translation was attempted (string)
36
+ # * :extended:: a hash of name/value pairs identifying extended info
37
+ #
38
+ # Likewise, when the server sends an Attributes object, all of the
39
+ # above attributes are exposed as methods (though not all will be set with
40
+ # non-nil values from the server).
41
+ class Attributes < V04::Attributes
42
+ F_BITS = 0x00000200
43
+ F_ALLOCATION_SIZE = 0x00000400
44
+ F_TEXT_HINT = 0x00000800
45
+ F_MIME_TYPE = 0x00001000
46
+ F_LINK_COUNT = 0x00002000
47
+ F_UNTRANSLATED_NAME = 0x00004000
48
+ F_CTIME = 0x00008000
49
+
50
+ # The array of elements that describe this structure, in order. Used when
51
+ # parsing and serializing attribute objects.
52
+ def self.elements #:nodoc:
53
+ @elements ||= [
54
+ [:type, :byte, 0],
55
+ [:size, :int64, F_SIZE],
56
+ [:allocation_size, :int64, F_ALLOCATION_SIZE],
57
+ [:owner, :string, F_OWNERGROUP],
58
+ [:group, :string, F_OWNERGROUP],
59
+ [:permissions, :long, F_PERMISSIONS],
60
+ [:atime, :int64, F_ACCESSTIME],
61
+ [:atime_nseconds, :long, F_ACCESSTIME | F_SUBSECOND_TIMES],
62
+ [:createtime, :int64, F_CREATETIME],
63
+ [:createtime_nseconds, :long, F_CREATETIME | F_SUBSECOND_TIMES],
64
+ [:mtime, :int64, F_MODIFYTIME],
65
+ [:mtime_nseconds, :long, F_MODIFYTIME | F_SUBSECOND_TIMES],
66
+ [:ctime, :int64, F_CTIME],
67
+ [:ctime_nseconds, :long, F_CTIME | F_SUBSECOND_TIMES],
68
+ [:acl, :special, F_ACL],
69
+ [:attrib_bits, :long, F_BITS],
70
+ [:attrib_bits_valid, :long, F_BITS],
71
+ [:text_hint, :byte, F_TEXT_HINT],
72
+ [:mime_type, :string, F_MIME_TYPE],
73
+ [:link_count, :long, F_LINK_COUNT],
74
+ [:untranslated_name, :string, F_UNTRANSLATED_NAME],
75
+ [:extended, :special, F_EXTENDED]
76
+ ]
77
+ end
78
+
79
+ # The size on-disk of the file
80
+ attr_accessor :allocation_size
81
+
82
+ # The time at which the file's attributes were last changed
83
+ attr_accessor :ctime
84
+
85
+ # The nanosecond component of #ctime
86
+ attr_accessor :ctime_nseconds
87
+
88
+ # Other attributes of this file or directory (as a bit field)
89
+ attr_accessor :attrib_bits
90
+
91
+ # A bit mask describing which bits in #attrib_bits are valid
92
+ attr_accessor :attrib_bits_valid
93
+
94
+ # Describes whether the file may or may not contain textual data
95
+ attr_accessor :text_hint
96
+
97
+ # The mime-type of the file
98
+ attr_accessor :mime_type
99
+
100
+ # The hard link count for the file
101
+ attr_accessor :link_count
102
+
103
+ # The value of the file name before filename translation was attempted
104
+ attr_accessor :untranslated_name
105
+ end
106
+
107
+ end; end; end; end
@@ -0,0 +1,63 @@
1
+ require 'net/sftp/protocol/05/base'
2
+ require 'net/sftp/protocol/06/attributes'
3
+
4
+ module Net; module SFTP; module Protocol; module V06
5
+
6
+ # Wraps the low-level SFTP calls for version 6 of the SFTP protocol.
7
+ #
8
+ # None of these protocol methods block--all of them return immediately,
9
+ # requiring the SSH event loop to be run while the server response is
10
+ # pending.
11
+ #
12
+ # You will almost certainly never need to use this driver directly. Please
13
+ # see Net::SFTP::Session for the recommended interface.
14
+ class Base < V05::Base
15
+
16
+ # Returns the protocol version implemented by this driver. (6, in this
17
+ # case)
18
+ def version
19
+ 6
20
+ end
21
+
22
+ # Sends a FXP_LINK packet to the server to request that a link be created
23
+ # at +new_link_path+, pointing to +existing_path+. If +symlink+ is true, a
24
+ # symbolic link will be created; otherwise a hard link will be created.
25
+ def link(new_link_path, existing_path, symlink)
26
+ send_request(FXP_LINK, :string, new_link_path, :string, existing_path, :bool, symlink)
27
+ end
28
+
29
+ # Provided for backwards compatibility; v6 of the SFTP protocol removes the
30
+ # older FXP_SYMLINK packet type, so this method simply calls the #link
31
+ # method.
32
+ def symlink(path, target)
33
+ link(path, target, true)
34
+ end
35
+
36
+ # Sends a FXP_BLOCK packet to the server to request that a byte-range lock
37
+ # be obtained on the given +handle+, for the given byte +offset+ and
38
+ # +length+. The +mask+ parameter is a bitfield indicating what kind of
39
+ # lock to acquire, and must be a combination of one or more of the
40
+ # Net::SFTP::Constants::LockTypes constants.
41
+ def block(handle, offset, length, mask)
42
+ send_request(FXP_BLOCK, :string, handle, :int64, offset, :int64, length, :long, mask)
43
+ end
44
+
45
+ # Sends a FXP_UNBLOCK packet to the server to request that a previously
46
+ # acquired byte-range lock be released on the given +handle+, for the
47
+ # given byte +offset+ and +length+. The +handle+, +offset+, and +length+
48
+ # must all exactly match the parameters that were given when the lock was
49
+ # originally acquired (see #block).
50
+ def unblock(handle, offset, length)
51
+ send_request(FXP_UNBLOCK, :string, handle, :int64, offset, :int64, length)
52
+ end
53
+
54
+ protected
55
+
56
+ # Returns the Attributes class used by this version of the protocol
57
+ # (Net::SFTP::Protocol::V06::Attributes, in this case)
58
+ def attribute_factory
59
+ V06::Attributes
60
+ end
61
+ end
62
+
63
+ end; end; end; end
@@ -0,0 +1,50 @@
1
+ require 'net/ssh/loggable'
2
+ require 'net/sftp/constants'
3
+
4
+ module Net; module SFTP; module Protocol
5
+
6
+ # The abstract superclass of the specific implementations for each supported
7
+ # SFTP protocol version. It implements general packet parsing logic, and
8
+ # provides a way for subclasses to send requests.
9
+ class Base
10
+ include Net::SSH::Loggable
11
+ include Net::SFTP::Constants
12
+ include Net::SFTP::Constants::PacketTypes
13
+
14
+ # The SFTP session object that acts as client to this protocol instance
15
+ attr_reader :session
16
+
17
+ # Create a new instance of a protocol driver, servicing the given session.
18
+ def initialize(session)
19
+ @session = session
20
+ self.logger = session.logger
21
+ @request_id_counter = -1
22
+ end
23
+
24
+ # Attept to parse the given packet. If the packet is of an unsupported
25
+ # type, an exception will be raised. Returns the parsed data as a hash
26
+ # (the keys in the hash are packet-type specific).
27
+ def parse(packet)
28
+ case packet.type
29
+ when FXP_STATUS then parse_status_packet(packet)
30
+ when FXP_HANDLE then parse_handle_packet(packet)
31
+ when FXP_DATA then parse_data_packet(packet)
32
+ when FXP_NAME then parse_name_packet(packet)
33
+ when FXP_ATTRS then parse_attrs_packet(packet)
34
+ else raise NotImplementedError, "unknown packet type: #{packet.type}"
35
+ end
36
+ end
37
+
38
+ private
39
+
40
+ # Send a new packet of the given type, and with the given data arguments.
41
+ # A new request identifier will be allocated to this request, and will
42
+ # be returned.
43
+ def send_request(type, *args)
44
+ @request_id_counter += 1
45
+ session.send_packet(type, :long, @request_id_counter, *args)
46
+ return @request_id_counter
47
+ end
48
+ end
49
+
50
+ end; end; end
@@ -0,0 +1,32 @@
1
+ require 'net/sftp/protocol/01/base'
2
+ require 'net/sftp/protocol/02/base'
3
+ require 'net/sftp/protocol/03/base'
4
+ require 'net/sftp/protocol/04/base'
5
+ require 'net/sftp/protocol/05/base'
6
+ require 'net/sftp/protocol/06/base'
7
+
8
+ module Net; module SFTP
9
+
10
+ # The Protocol module contains the definitions for all supported SFTP
11
+ # protocol versions.
12
+ module Protocol
13
+
14
+ # Instantiates and returns a new protocol driver instance for the given
15
+ # protocol version. +session+ must be a valid SFTP session object, and
16
+ # +version+ must be an integer. If an unsupported version is given,
17
+ # an exception will be raised.
18
+ def self.load(session, version)
19
+ case version
20
+ when 1 then V01::Base.new(session)
21
+ when 2 then V02::Base.new(session)
22
+ when 3 then V03::Base.new(session)
23
+ when 4 then V04::Base.new(session)
24
+ when 5 then V05::Base.new(session)
25
+ when 6 then V06::Base.new(session)
26
+ else raise NotImplementedError, "unsupported SFTP version #{version.inspect}"
27
+ end
28
+ end
29
+
30
+ end
31
+
32
+ end; end