net-sftp 1.1.1 → 2.0.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.
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