net-sftp-backports 4.0.0.backports

Sign up to get free protection for your applications and to get access to all the features.
@@ -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