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
@@ -1,90 +0,0 @@
1
- #--
2
- # =============================================================================
3
- # Copyright (c) 2004, Jamis Buck (jamis@37signals.com)
4
- # All rights reserved.
5
- #
6
- # This source file is distributed as part of the Net::SFTP Secure FTP Client
7
- # library for Ruby. This file (and the library as a whole) may be used only as
8
- # allowed by either the BSD license, or the Ruby license (or, by association
9
- # with the Ruby license, the GPL). See the "doc" subdirectory of the Net::SFTP
10
- # distribution for the texts of these licenses.
11
- # -----------------------------------------------------------------------------
12
- # net-sftp website: http://net-ssh.rubyforge.org/sftp
13
- # project website : http://rubyforge.org/projects/net-ssh
14
- # =============================================================================
15
- #++
16
-
17
- require 'net/sftp/protocol/04/impl'
18
-
19
- module Net ; module SFTP ; module Protocol ; module V_05
20
-
21
- # The implementation of the operations available to version 5 of the SFTP
22
- # protocol.
23
- class Impl < V_04::Impl
24
-
25
- F_CREATE_NEW = 0x00000000
26
- F_CREATE_TRUNCATE = 0x00000001
27
- F_OPEN_EXISTING = 0x00000002
28
- F_OPEN_OR_CREATE = 0x00000003
29
- F_TRUNCATE_EXISTING = 0x00000004
30
-
31
- F_APPEND_DATA = 0x00000008
32
- F_APPEND_DATA_ATOMIC = 0x00000010
33
- F_TEXT_MODE = 0x00000020
34
- F_READ_LOCK = 0x00000040
35
- F_WRITE_LOCK = 0x00000080
36
- F_DELETE_LOCK = 0x00000100
37
-
38
- module ACE
39
- F_READ_DATA = 0x00000001
40
- F_LIST_DIRECTORY = 0x00000001
41
- F_WRITE_DATA = 0x00000002
42
- F_ADD_FILE = 0x00000002
43
- F_APPEND_DATA = 0x00000004
44
- F_ADD_SUBDIRECTORY = 0x00000004
45
- F_READ_NAMED_ATTRS = 0x00000008
46
- F_WRITE_NAMED_ATTRS = 0x00000010
47
- F_EXECUTE = 0x00000020
48
- F_DELETE_CHILD = 0x00000040
49
- F_READ_ATTRIBUTES = 0x00000080
50
- F_WRITE_ATTRIBUTES = 0x00000100
51
- F_DELETE = 0x00010000
52
- F_READ_ACL = 0x00020000
53
- F_WRITE_ACL = 0x00040000
54
- F_WRITE_OWNER = 0x00080000
55
- F_SYNCHRONIZE = 0x00100000
56
- end
57
-
58
- # The open operation changed in version 4. This method keeps the same
59
- # interface as previous versions, but changes how the parameters are
60
- # interpreted and converted into a packet.
61
- def open( id, path, flags, mode=0660 )
62
- sftp_flags, desired_access = case
63
- when flags & IO::WRONLY != 0 then
64
- [ F_CREATE_TRUNCATE,
65
- ACE::F_WRITE_DATA | ACE::F_WRITE_ATTRIBUTES ]
66
- when flags & IO::RDWR != 0 then
67
- [ F_OPEN_OR_CREATE,
68
- ACE::F_READ_DATA | ACE::F_READ_ATTRIBUTES |
69
- ACE::F_WRITE_DATA | ACE::F_WRITE_ATTRIBUTES ]
70
- when flags & IO::APPEND != 0 then
71
- [ F_OPEN_OR_CREATE | F_APPEND_DATA,
72
- ACE::F_WRITE_DATA | ACE::F_WRITE_ATTRIBUTES |
73
- ACE::F_APPEND_DATA ]
74
- else
75
- [ F_OPEN_EXISTING,
76
- ACE::F_READ_DATA | ACE::F_READ_ATTRIBUTES ]
77
- end
78
-
79
- sftp_flags |= F_OPEN_OR_CREATE if flags & IO::CREAT != 0
80
- sftp_flags |= F_TRUNCATE_EXISTING if flags & IO::TRUNC != 0
81
-
82
- attributes = @attr_factory.empty
83
- attributes.permissions = mode
84
-
85
- open_raw id, path, desired_access, sftp_flags, attributes
86
- end
87
-
88
- end
89
-
90
- end ; end ; end ; end
@@ -1,34 +0,0 @@
1
- #--
2
- # =============================================================================
3
- # Copyright (c) 2004, Jamis Buck (jamis@37signals.com)
4
- # All rights reserved.
5
- #
6
- # This source file is distributed as part of the Net::SFTP Secure FTP Client
7
- # library for Ruby. This file (and the library as a whole) may be used only as
8
- # allowed by either the BSD license, or the Ruby license (or, by association
9
- # with the Ruby license, the GPL). See the "doc" subdirectory of the Net::SFTP
10
- # distribution for the texts of these licenses.
11
- # -----------------------------------------------------------------------------
12
- # net-sftp website: http://net-ssh.rubyforge.org/sftp
13
- # project website : http://rubyforge.org/projects/net-ssh
14
- # =============================================================================
15
- #++
16
-
17
- require 'net/sftp/protocol/04/packet-assistant'
18
-
19
- module Net ; module SFTP ; module Protocol ; module V_05
20
-
21
- # Version 5 of the SFTP protocol changed the number of parameters to several
22
- # different packet types:
23
- #
24
- # * open( id, path, access, flags, attrs )
25
- class PacketAssistant < V_04::PacketAssistant
26
-
27
- packet :open, :string, # path
28
- :long, # access
29
- :long, # flags
30
- :attrs # file attributes
31
-
32
- end
33
-
34
- end ; end ; end ; end
@@ -1,44 +0,0 @@
1
- #--
2
- # =============================================================================
3
- # Copyright (c) 2004, Jamis Buck (jamis@37signals.com)
4
- # All rights reserved.
5
- #
6
- # This source file is distributed as part of the Net::SFTP Secure FTP Client
7
- # library for Ruby. This file (and the library as a whole) may be used only as
8
- # allowed by either the BSD license, or the Ruby license (or, by association
9
- # with the Ruby license, the GPL). See the "doc" subdirectory of the Net::SFTP
10
- # distribution for the texts of these licenses.
11
- # -----------------------------------------------------------------------------
12
- # net-sftp website: http://net-ssh.rubyforge.org/sftp
13
- # project website : http://rubyforge.org/projects/net-ssh
14
- # =============================================================================
15
- #++
16
-
17
- module Net ; module SFTP ; module Protocol ; module V_05
18
-
19
- def register_services( container )
20
- container.namespace_define :v_05 do |ns|
21
-
22
- ns.packet_assistant do |c,|
23
- require 'net/sftp/protocol/05/packet-assistant'
24
- PacketAssistant.new( c[:transport][:buffers],
25
- c[:driver] )
26
- end
27
-
28
- ns.attr_factory do |c,|
29
- require 'net/sftp/protocol/04/attributes'
30
- V_04::Attributes.init( c[:transport][:buffers] )
31
- end
32
-
33
- ns.impl do |c,|
34
- require 'net/sftp/protocol/05/impl'
35
- Impl.new( c[:transport][:buffers],
36
- c[:driver], c[:packet_assistant],
37
- c[:attr_factory] )
38
- end
39
-
40
- end
41
- end
42
- module_function :register_services
43
-
44
- end ; end ; end ; end
@@ -1,60 +0,0 @@
1
- #--
2
- # =============================================================================
3
- # Copyright (c) 2004, Jamis Buck (jamis@37signals.com)
4
- # All rights reserved.
5
- #
6
- # This source file is distributed as part of the Net::SFTP Secure FTP Client
7
- # library for Ruby. This file (and the library as a whole) may be used only as
8
- # allowed by either the BSD license, or the Ruby license (or, by association
9
- # with the Ruby license, the GPL). See the "doc" subdirectory of the Net::SFTP
10
- # distribution for the texts of these licenses.
11
- # -----------------------------------------------------------------------------
12
- # net-sftp website: http://net-ssh.rubyforge.org/sftp
13
- # project website : http://rubyforge.org/projects/net-ssh
14
- # =============================================================================
15
- #++
16
-
17
- module Net ; module SFTP ; module Protocol
18
-
19
- module Constants
20
-
21
- FXP_INIT = 1
22
- FXP_VERSION = 2
23
- FXP_OPEN = 3
24
- FXP_CLOSE = 4
25
- FXP_READ = 5
26
- FXP_WRITE = 6
27
- FXP_LSTAT = 7
28
- FXP_FSTAT = 8
29
- FXP_SETSTAT = 9
30
- FXP_FSETSTAT = 10
31
- FXP_OPENDIR = 11
32
- FXP_READDIR = 12
33
- FXP_REMOVE = 13
34
- FXP_MKDIR = 14
35
- FXP_RMDIR = 15
36
- FXP_REALPATH = 16
37
- FXP_STAT = 17
38
- FXP_RENAME = 18
39
- FXP_READLINK = 19
40
- FXP_SYMLINK = 20
41
-
42
- FXP_STATUS = 101
43
- FXP_HANDLE = 102
44
- FXP_DATA = 103
45
- FXP_NAME = 104
46
- FXP_ATTRS = 105
47
-
48
- FXP_EXTENDED = 106
49
- FXP_EXTENDED_REPLY = 107
50
-
51
- FXP_RENAME_OVERWRITE = 0x00000001
52
- FXP_RENAME_ATOMIC = 0x00000002
53
- FXP_RENAME_NATIVE = 0x00000004
54
-
55
- FX_OK = 0
56
- FX_EOF = 1
57
-
58
- end
59
-
60
- end ; end ; end
@@ -1,235 +0,0 @@
1
- #--
2
- # =============================================================================
3
- # Copyright (c) 2004, Jamis Buck (jamis@37signals.com)
4
- # All rights reserved.
5
- #
6
- # This source file is distributed as part of the Net::SFTP Secure FTP Client
7
- # library for Ruby. This file (and the library as a whole) may be used only as
8
- # allowed by either the BSD license, or the Ruby license (or, by association
9
- # with the Ruby license, the GPL). See the "doc" subdirectory of the Net::SFTP
10
- # distribution for the texts of these licenses.
11
- # -----------------------------------------------------------------------------
12
- # net-sftp website: http://net-ssh.rubyforge.org/sftp
13
- # project website : http://rubyforge.org/projects/net-ssh
14
- # =============================================================================
15
- #++
16
-
17
- require 'thread'
18
- require 'net/sftp/errors'
19
- require 'net/sftp/protocol/constants'
20
-
21
- module Net ; module SFTP ; module Protocol
22
-
23
- # This is the driver object for the SFTP protocol. It manages the SSH channel
24
- # used to communicate with the server, as well as the negotiation of the
25
- # protocol. The operations themselves are specific to the protocol version
26
- # in use, and are handled by protocol-version-specific dispatcher objects.
27
- class Driver
28
- include Constants
29
-
30
- # The current state of the driver. This will be one of +unconfirmed+,
31
- # +init+, +version+, +open+, or +closed+.
32
- attr_reader :state
33
-
34
- # The underlying SSH channel supporting this SFTP connection.
35
- attr_reader :channel
36
-
37
- # Create a new SFTP protocol driver object on the given SSH connection.
38
- # +buffers+ is a reference to a buffer factory, +version+ is the highest
39
- # supported SFTP protocol version, +dispatchers+ is a Proc object that
40
- # returns a dispatcher instance for a specific protocol version, and +log+
41
- # is a logger instance.
42
- #
43
- # The new protocol driver will be in an +unconfirmed+ state, initially.
44
- # When the server validates the requested channel, the driver goes to the
45
- # +init+ state, and requests the SFTP subsystem. When the subsystem has
46
- # been accepted, the driver sends its supported protocol version to the
47
- # server, and goes to the +version+ state. Lastly, when the server
48
- # responds with its supported protocol version and the version to use has
49
- # been successfully negotiated, the driver will go to the +open+ state,
50
- # after which SFTP operations may be successfully performed on the driver.
51
- def initialize( connection, buffers, version, dispatchers, log )
52
- @buffers = buffers
53
- @version = version
54
- @dispatchers = dispatchers
55
- @log = log
56
-
57
- @next_request_id = 0
58
- @next_request_mutex = Mutex.new
59
- @parsed_data = nil
60
- @on_open = nil
61
-
62
- @state = :unconfirmed
63
-
64
- @log.debug "opening channel for sftp" if @log.debug?
65
- @channel = connection.open_channel( "session", &method( :do_confirm ) )
66
- end
67
-
68
- # Closes the underlying SSH channel that the SFTP session uses to
69
- # communicate with the server. This moves the driver to the +closed+
70
- # state. If the driver is already closed, this does nothing.
71
- def close
72
- if @state != :closed
73
- @log.debug "closing sftp channel" if @log.debug?
74
- @channel.close
75
- @state = :closed
76
- end
77
- end
78
-
79
- # Returns the next available request id in a thread-safe manner. The
80
- # request-id is used to identify packets associated with request sequences.
81
- def next_request_id
82
- @next_request_mutex.synchronize do
83
- request_id = @next_request_id
84
- @next_request_id += 1
85
- return request_id
86
- end
87
- end
88
-
89
- # Specify the callback to invoke when the session has been successfully
90
- # opened (i.e., once the driver's state has moved to +open+). The callback
91
- # should accept a single parameter--the driver itself.
92
- def on_open( &block )
93
- @on_open = block
94
- end
95
-
96
- # The callback used internally to indicate that the requested channel has
97
- # been confirmed. This will request the SFTP subsystem, register some
98
- # request callbacks, and move the driver's state to +init+. This may only
99
- # be called when the driver's state is +unconfirmed+.
100
- def do_confirm( channel )
101
- assert_state :unconfirmed
102
- @log.debug "requesting sftp subsystem" if @log.debug?
103
-
104
- channel.subsystem "sftp"
105
- channel.on_success &method( :do_success )
106
- channel.on_data &method( :do_data )
107
-
108
- @state = :init
109
- end
110
-
111
- # The callback used internally to indicate that the SFTP subsystem was
112
- # successfully requested. This may only be called when the driver's state
113
- # is +init+. It sends an INIT packet containing the highest supported
114
- # SFTP protocol version to the server, and moves the driver's state to
115
- # +version+.
116
- def do_success( channel )
117
- assert_state :init
118
- @log.debug "initializing sftp subsystem" if @log.debug?
119
-
120
- packet = @buffers.writer
121
- packet.write_long @version
122
- send_data FXP_INIT, packet
123
-
124
- @state = :version
125
- end
126
-
127
- # This is used internally to indicate that a VERSION packet was received
128
- # from the server. This may only be called when the driver's state is
129
- # +version+. It determines the highest possible protocol version supported
130
- # by both the client and the server, selects the dispatcher that handles
131
- # that protocol version, moves the state to +open+, and then invokes the
132
- # +on_open+ callback (if one was registered).
133
- def do_version( content )
134
- assert_state :version
135
- @log.debug "negotiating sftp protocol version" if @log.debug?
136
- @log.debug "my sftp version is #{@version}" if @log.debug?
137
-
138
- server_version = content.read_long
139
- @log.debug "server reports sftp version #{server_version}" if @log.debug?
140
-
141
- negotiated_version = [ @version, server_version ].min
142
- @log.info "negotiated version is #{negotiated_version}" if @log.info?
143
-
144
- extensions = Hash.new
145
- until content.eof?
146
- ext_name = content.read_string
147
- ext_data = content.read_string
148
- extensions[ ext_name ] = ext_data
149
- end
150
-
151
- @dispatcher = @dispatchers[ negotiated_version, extensions ]
152
-
153
- @state = :open
154
-
155
- @on_open.call( self ) if @on_open
156
- end
157
-
158
- # This is called internally when a data packet is received from the server.
159
- # All SFTP packets are transfered as SSH data packets, so this parses the
160
- # data packet to determine the SFTP packet type, and then sends the contents
161
- # on to the active dispatcher for further processing. This routine correctly
162
- # handles SFTP packets that span multiple SSH data packets.
163
- def do_data( channel, data )
164
- if @parsed_data
165
- @parsed_data[:content].append data
166
- return if @parsed_data[:length] > @parsed_data[:content].length
167
-
168
- type = @parsed_data[:type]
169
- content = @parsed_data[:content]
170
- @parsed_data = nil
171
- else
172
- reader = @buffers.reader( data )
173
- length = reader.read_long-1
174
- type = reader.read_byte
175
- content = reader.remainder_as_buffer
176
-
177
- if length > content.length
178
- @parsed_data = { :length => length,
179
- :type => type,
180
- :content => content }
181
- return
182
- end
183
- end
184
-
185
- if type == FXP_VERSION
186
- do_version content
187
- else
188
- assert_state :open
189
- @dispatcher.dispatch channel, type, content
190
- end
191
- end
192
-
193
- # Delegates missing methods to the current dispatcher (if the state is
194
- # +open+). This allows clients to register callbacks for the supported
195
- # operations of the negotiated protocol version.
196
- def method_missing( sym, *args, &block )
197
- if @state == :open && @dispatcher.respond_to?( sym )
198
- assert_state :open
199
- @dispatcher.__send__( sym, *args, &block )
200
- else
201
- super
202
- end
203
- end
204
-
205
- # Returns true if the driver responds to the given message, or if the
206
- # state is +open+ and the active dispatcher responds to the given
207
- # message.
208
- def respond_to?( sym )
209
- super || @state == :open && @dispatcher.respond_to?( sym )
210
- end
211
-
212
- # A convenience method for sending an SFTP packet of the given type,
213
- # with the given payload. This repackages the data as an SSH data packet
214
- # and sends it across the channel.
215
- def send_data( type, data )
216
- data = data.to_s
217
-
218
- msg = @buffers.writer
219
- msg.write_long data.length + 1
220
- msg.write_byte type
221
- msg.write data
222
-
223
- @channel.send_data msg
224
- end
225
-
226
- # A sanity checker, to ensure that an operation is invoked only when the
227
- # appropriate state is active.
228
- def assert_state( state )
229
- raise Net::SFTP::Bug, "invalid state `#{state}'" if state != @state
230
- end
231
- private :assert_state
232
-
233
- end
234
-
235
- end ; end ; end