net-sftp 1.1.1 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (138) hide show
  1. data/CHANGELOG.rdoc +23 -0
  2. data/Manifest +55 -0
  3. data/README.rdoc +96 -0
  4. data/Rakefile +30 -0
  5. data/lib/net/sftp.rb +53 -38
  6. data/lib/net/sftp/constants.rb +187 -0
  7. data/lib/net/sftp/errors.rb +34 -20
  8. data/lib/net/sftp/operations/dir.rb +93 -0
  9. data/lib/net/sftp/operations/download.rb +364 -0
  10. data/lib/net/sftp/operations/file.rb +176 -0
  11. data/lib/net/sftp/operations/file_factory.rb +60 -0
  12. data/lib/net/sftp/operations/upload.rb +387 -0
  13. data/lib/net/sftp/packet.rb +21 -0
  14. data/lib/net/sftp/protocol.rb +32 -0
  15. data/lib/net/sftp/protocol/01/attributes.rb +265 -96
  16. data/lib/net/sftp/protocol/01/base.rb +268 -0
  17. data/lib/net/sftp/protocol/01/name.rb +43 -0
  18. data/lib/net/sftp/protocol/02/base.rb +31 -0
  19. data/lib/net/sftp/protocol/03/base.rb +35 -0
  20. data/lib/net/sftp/protocol/04/attributes.rb +120 -195
  21. data/lib/net/sftp/protocol/04/base.rb +94 -0
  22. data/lib/net/sftp/protocol/04/name.rb +67 -0
  23. data/lib/net/sftp/protocol/05/base.rb +66 -0
  24. data/lib/net/sftp/protocol/06/attributes.rb +107 -0
  25. data/lib/net/sftp/protocol/06/base.rb +63 -0
  26. data/lib/net/sftp/protocol/base.rb +50 -0
  27. data/lib/net/sftp/request.rb +91 -0
  28. data/lib/net/sftp/response.rb +76 -0
  29. data/lib/net/sftp/session.rb +914 -238
  30. data/lib/net/sftp/version.rb +14 -21
  31. data/net-sftp.gemspec +60 -0
  32. data/setup.rb +1331 -0
  33. data/test/common.rb +173 -0
  34. data/test/protocol/01/test_attributes.rb +97 -0
  35. data/test/protocol/01/test_base.rb +210 -0
  36. data/test/protocol/01/test_name.rb +27 -0
  37. data/test/protocol/02/test_base.rb +26 -0
  38. data/test/protocol/03/test_base.rb +27 -0
  39. data/test/protocol/04/test_attributes.rb +148 -0
  40. data/test/protocol/04/test_base.rb +74 -0
  41. data/test/protocol/04/test_name.rb +49 -0
  42. data/test/protocol/05/test_base.rb +62 -0
  43. data/test/protocol/06/test_attributes.rb +124 -0
  44. data/test/protocol/06/test_base.rb +51 -0
  45. data/test/protocol/test_base.rb +42 -0
  46. data/test/test_all.rb +3 -0
  47. data/test/test_dir.rb +47 -0
  48. data/test/test_download.rb +252 -0
  49. data/test/test_file.rb +159 -0
  50. data/test/test_file_factory.rb +48 -0
  51. data/test/test_packet.rb +9 -0
  52. data/test/test_protocol.rb +17 -0
  53. data/test/test_request.rb +71 -0
  54. data/test/test_response.rb +53 -0
  55. data/test/test_session.rb +741 -0
  56. data/test/test_upload.rb +219 -0
  57. metadata +59 -111
  58. data/doc/LICENSE-BSD +0 -27
  59. data/doc/LICENSE-GPL +0 -280
  60. data/doc/LICENSE-RUBY +0 -56
  61. data/doc/faq/faq.html +0 -298
  62. data/doc/faq/faq.rb +0 -154
  63. data/doc/faq/faq.yml +0 -183
  64. data/examples/asynchronous.rb +0 -57
  65. data/examples/get-put.rb +0 -45
  66. data/examples/sftp-open-uri.rb +0 -30
  67. data/examples/ssh-service.rb +0 -30
  68. data/examples/synchronous.rb +0 -131
  69. data/lib/net/sftp/operations/abstract.rb +0 -108
  70. data/lib/net/sftp/operations/close.rb +0 -31
  71. data/lib/net/sftp/operations/errors.rb +0 -76
  72. data/lib/net/sftp/operations/fsetstat.rb +0 -36
  73. data/lib/net/sftp/operations/fstat.rb +0 -32
  74. data/lib/net/sftp/operations/lstat.rb +0 -31
  75. data/lib/net/sftp/operations/mkdir.rb +0 -33
  76. data/lib/net/sftp/operations/open.rb +0 -32
  77. data/lib/net/sftp/operations/opendir.rb +0 -32
  78. data/lib/net/sftp/operations/read.rb +0 -88
  79. data/lib/net/sftp/operations/readdir.rb +0 -55
  80. data/lib/net/sftp/operations/realpath.rb +0 -37
  81. data/lib/net/sftp/operations/remove.rb +0 -31
  82. data/lib/net/sftp/operations/rename.rb +0 -32
  83. data/lib/net/sftp/operations/rmdir.rb +0 -31
  84. data/lib/net/sftp/operations/services.rb +0 -42
  85. data/lib/net/sftp/operations/setstat.rb +0 -33
  86. data/lib/net/sftp/operations/stat.rb +0 -31
  87. data/lib/net/sftp/operations/write.rb +0 -63
  88. data/lib/net/sftp/protocol/01/impl.rb +0 -251
  89. data/lib/net/sftp/protocol/01/packet-assistant.rb +0 -82
  90. data/lib/net/sftp/protocol/01/services.rb +0 -47
  91. data/lib/net/sftp/protocol/02/impl.rb +0 -39
  92. data/lib/net/sftp/protocol/02/packet-assistant.rb +0 -32
  93. data/lib/net/sftp/protocol/02/services.rb +0 -44
  94. data/lib/net/sftp/protocol/03/impl.rb +0 -42
  95. data/lib/net/sftp/protocol/03/packet-assistant.rb +0 -35
  96. data/lib/net/sftp/protocol/03/services.rb +0 -44
  97. data/lib/net/sftp/protocol/04/impl.rb +0 -86
  98. data/lib/net/sftp/protocol/04/packet-assistant.rb +0 -45
  99. data/lib/net/sftp/protocol/04/services.rb +0 -44
  100. data/lib/net/sftp/protocol/05/impl.rb +0 -90
  101. data/lib/net/sftp/protocol/05/packet-assistant.rb +0 -34
  102. data/lib/net/sftp/protocol/05/services.rb +0 -44
  103. data/lib/net/sftp/protocol/constants.rb +0 -60
  104. data/lib/net/sftp/protocol/driver.rb +0 -235
  105. data/lib/net/sftp/protocol/packet-assistant.rb +0 -84
  106. data/lib/net/sftp/protocol/services.rb +0 -55
  107. data/lib/uri/open-sftp.rb +0 -54
  108. data/lib/uri/sftp.rb +0 -42
  109. data/test/ALL-TESTS.rb +0 -23
  110. data/test/operations/tc_abstract.rb +0 -124
  111. data/test/operations/tc_close.rb +0 -40
  112. data/test/operations/tc_fsetstat.rb +0 -48
  113. data/test/operations/tc_fstat.rb +0 -40
  114. data/test/operations/tc_lstat.rb +0 -40
  115. data/test/operations/tc_mkdir.rb +0 -48
  116. data/test/operations/tc_open.rb +0 -42
  117. data/test/operations/tc_opendir.rb +0 -40
  118. data/test/operations/tc_read.rb +0 -103
  119. data/test/operations/tc_readdir.rb +0 -88
  120. data/test/operations/tc_realpath.rb +0 -54
  121. data/test/operations/tc_remove.rb +0 -40
  122. data/test/operations/tc_rmdir.rb +0 -40
  123. data/test/operations/tc_setstat.rb +0 -48
  124. data/test/operations/tc_stat.rb +0 -40
  125. data/test/operations/tc_write.rb +0 -91
  126. data/test/protocol/01/tc_attributes.rb +0 -138
  127. data/test/protocol/01/tc_impl.rb +0 -294
  128. data/test/protocol/01/tc_packet_assistant.rb +0 -81
  129. data/test/protocol/02/tc_impl.rb +0 -41
  130. data/test/protocol/02/tc_packet_assistant.rb +0 -31
  131. data/test/protocol/03/tc_impl.rb +0 -48
  132. data/test/protocol/03/tc_packet_assistant.rb +0 -34
  133. data/test/protocol/04/tc_attributes.rb +0 -174
  134. data/test/protocol/04/tc_impl.rb +0 -91
  135. data/test/protocol/04/tc_packet_assistant.rb +0 -38
  136. data/test/protocol/05/tc_impl.rb +0 -61
  137. data/test/protocol/05/tc_packet_assistant.rb +0 -32
  138. data/test/protocol/tc_driver.rb +0 -219
@@ -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