redcar 0.3.7.1 → 0.3.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (246) hide show
  1. data/CHANGES +16 -0
  2. data/README.md +5 -0
  3. data/ROADMAP.md +7 -9
  4. data/Rakefile +55 -22
  5. data/lib/redcar.rb +12 -6
  6. data/lib/redcar/installer.rb +119 -44
  7. data/plugins/application/features/step_definitions/speedbar_steps.rb +62 -0
  8. data/plugins/application/features/step_definitions/tree_steps.rb +3 -3
  9. data/plugins/application/features/support/env.rb +2 -1
  10. data/plugins/application/lib/application/notebook.rb +53 -7
  11. data/plugins/application/lib/application/speedbar.rb +12 -0
  12. data/plugins/application/lib/application/tab.rb +16 -5
  13. data/plugins/application/lib/application/treebook.rb +21 -1
  14. data/plugins/application_swt/lib/application_swt.rb +12 -2
  15. data/plugins/application_swt/lib/application_swt/html_tab.rb +4 -0
  16. data/plugins/application_swt/lib/application_swt/notebook.rb +5 -3
  17. data/plugins/application_swt/lib/application_swt/speedbar.rb +15 -27
  18. data/plugins/application_swt/lib/application_swt/swt_wrapper.rb +1 -0
  19. data/plugins/application_swt/lib/application_swt/tab.rb +1 -0
  20. data/plugins/application_swt/lib/application_swt/treebook.rb +36 -8
  21. data/plugins/application_swt/lib/application_swt/window.rb +24 -18
  22. data/plugins/auto_completer/lib/auto_completer.rb +5 -20
  23. data/plugins/core/lib/core.rb +7 -4
  24. data/plugins/core/lib/core/observable_struct.rb +2 -2
  25. data/plugins/declarations/lib/declarations.rb +3 -17
  26. data/plugins/document_search/features/search.feature +163 -0
  27. data/plugins/document_search/features/support/env.rb +4 -0
  28. data/plugins/document_search/lib/document_search.rb +121 -0
  29. data/plugins/document_search/plugin.rb +8 -0
  30. data/plugins/edit_view/features/line_delimiter.feature +7 -0
  31. data/plugins/edit_view/features/step_definitions/editing_steps.rb +49 -1
  32. data/plugins/edit_view/features/step_definitions/tab_steps.rb +10 -11
  33. data/plugins/edit_view/features/switch_tabs.feature +61 -10
  34. data/plugins/edit_view/lib/edit_view.rb +4 -0
  35. data/plugins/edit_view/lib/edit_view/document.rb +56 -0
  36. data/plugins/edit_view/lib/edit_view/document/command.rb +1 -1
  37. data/plugins/edit_view/lib/edit_view/edit_tab.rb +0 -8
  38. data/plugins/edit_view_swt/lib/edit_view_swt.rb +4 -0
  39. data/plugins/html_view/lib/html_controller.rb +19 -1
  40. data/plugins/html_view/lib/html_view.rb +28 -1
  41. data/plugins/html_view/lib/html_view/html_tab.rb +10 -1
  42. data/plugins/plugin_manager_ui/lib/plugin_manager_ui.rb +3 -1
  43. data/plugins/project/features/open_directory_tree.feature +3 -3
  44. data/plugins/project/lib/project.rb +4 -6
  45. data/plugins/project/lib/project/commands.rb +17 -0
  46. data/plugins/project/lib/project/dir_controller.rb +2 -1
  47. data/plugins/project/lib/project/dir_mirror.rb +8 -0
  48. data/plugins/project/lib/project/manager.rb +2 -0
  49. data/plugins/project/plugin.rb +2 -1
  50. data/plugins/project/vendor/net-sftp/Manifest +55 -0
  51. data/plugins/project/vendor/net-sftp/Rakefile +30 -0
  52. data/plugins/project/vendor/net-sftp/lib/net/sftp.rb +70 -0
  53. data/plugins/project/vendor/net-sftp/lib/net/sftp/constants.rb +187 -0
  54. data/plugins/project/vendor/net-sftp/lib/net/sftp/errors.rb +39 -0
  55. data/plugins/project/vendor/net-sftp/lib/net/sftp/operations/dir.rb +93 -0
  56. data/plugins/project/vendor/net-sftp/lib/net/sftp/operations/download.rb +364 -0
  57. data/plugins/project/vendor/net-sftp/lib/net/sftp/operations/file.rb +176 -0
  58. data/plugins/project/vendor/net-sftp/lib/net/sftp/operations/file_factory.rb +60 -0
  59. data/plugins/project/vendor/net-sftp/lib/net/sftp/operations/upload.rb +387 -0
  60. data/plugins/project/vendor/net-sftp/lib/net/sftp/packet.rb +21 -0
  61. data/plugins/project/vendor/net-sftp/lib/net/sftp/protocol.rb +32 -0
  62. data/plugins/project/vendor/net-sftp/lib/net/sftp/protocol/01/attributes.rb +315 -0
  63. data/plugins/project/vendor/net-sftp/lib/net/sftp/protocol/01/base.rb +268 -0
  64. data/plugins/project/vendor/net-sftp/lib/net/sftp/protocol/01/name.rb +43 -0
  65. data/plugins/project/vendor/net-sftp/lib/net/sftp/protocol/02/base.rb +31 -0
  66. data/plugins/project/vendor/net-sftp/lib/net/sftp/protocol/03/base.rb +35 -0
  67. data/plugins/project/vendor/net-sftp/lib/net/sftp/protocol/04/attributes.rb +152 -0
  68. data/plugins/project/vendor/net-sftp/lib/net/sftp/protocol/04/base.rb +94 -0
  69. data/plugins/project/vendor/net-sftp/lib/net/sftp/protocol/04/name.rb +67 -0
  70. data/plugins/project/vendor/net-sftp/lib/net/sftp/protocol/05/base.rb +66 -0
  71. data/plugins/project/vendor/net-sftp/lib/net/sftp/protocol/06/attributes.rb +107 -0
  72. data/plugins/project/vendor/net-sftp/lib/net/sftp/protocol/06/base.rb +63 -0
  73. data/plugins/project/vendor/net-sftp/lib/net/sftp/protocol/base.rb +50 -0
  74. data/plugins/project/vendor/net-sftp/lib/net/sftp/request.rb +91 -0
  75. data/plugins/project/vendor/net-sftp/lib/net/sftp/response.rb +76 -0
  76. data/plugins/project/vendor/net-sftp/lib/net/sftp/session.rb +951 -0
  77. data/plugins/project/vendor/net-sftp/lib/net/sftp/version.rb +18 -0
  78. data/plugins/project/vendor/net-sftp/setup.rb +1331 -0
  79. data/plugins/project/vendor/net-sftp/test/common.rb +171 -0
  80. data/plugins/project/vendor/net-sftp/test/protocol/01/test_attributes.rb +97 -0
  81. data/plugins/project/vendor/net-sftp/test/protocol/01/test_base.rb +210 -0
  82. data/plugins/project/vendor/net-sftp/test/protocol/01/test_name.rb +27 -0
  83. data/plugins/project/vendor/net-sftp/test/protocol/02/test_base.rb +26 -0
  84. data/plugins/project/vendor/net-sftp/test/protocol/03/test_base.rb +27 -0
  85. data/plugins/project/vendor/net-sftp/test/protocol/04/test_attributes.rb +148 -0
  86. data/plugins/project/vendor/net-sftp/test/protocol/04/test_base.rb +74 -0
  87. data/plugins/project/vendor/net-sftp/test/protocol/04/test_name.rb +53 -0
  88. data/plugins/project/vendor/net-sftp/test/protocol/05/test_base.rb +62 -0
  89. data/plugins/project/vendor/net-sftp/test/protocol/06/test_attributes.rb +124 -0
  90. data/plugins/project/vendor/net-sftp/test/protocol/06/test_base.rb +51 -0
  91. data/plugins/project/vendor/net-sftp/test/protocol/test_base.rb +42 -0
  92. data/plugins/project/vendor/net-sftp/test/test_all.rb +7 -0
  93. data/plugins/project/vendor/net-sftp/test/test_dir.rb +47 -0
  94. data/plugins/project/vendor/net-sftp/test/test_download.rb +252 -0
  95. data/plugins/project/vendor/net-sftp/test/test_file.rb +159 -0
  96. data/plugins/project/vendor/net-sftp/test/test_file_factory.rb +48 -0
  97. data/plugins/project/vendor/net-sftp/test/test_packet.rb +9 -0
  98. data/plugins/project/vendor/net-sftp/test/test_protocol.rb +17 -0
  99. data/plugins/project/vendor/net-sftp/test/test_request.rb +71 -0
  100. data/plugins/project/vendor/net-sftp/test/test_response.rb +53 -0
  101. data/plugins/project/vendor/net-sftp/test/test_session.rb +741 -0
  102. data/plugins/project/vendor/net-sftp/test/test_upload.rb +219 -0
  103. data/plugins/project/vendor/net-ssh/Manifest +110 -0
  104. data/plugins/project/vendor/net-ssh/Rakefile +85 -0
  105. data/plugins/project/vendor/net-ssh/Rudyfile +96 -0
  106. data/plugins/project/vendor/net-ssh/lib/net/ssh.rb +215 -0
  107. data/plugins/project/vendor/net-ssh/lib/net/ssh/authentication/agent.rb +179 -0
  108. data/plugins/project/vendor/net-ssh/lib/net/ssh/authentication/constants.rb +18 -0
  109. data/plugins/project/vendor/net-ssh/lib/net/ssh/authentication/key_manager.rb +193 -0
  110. data/plugins/project/vendor/net-ssh/lib/net/ssh/authentication/methods/abstract.rb +60 -0
  111. data/plugins/project/vendor/net-ssh/lib/net/ssh/authentication/methods/hostbased.rb +71 -0
  112. data/plugins/project/vendor/net-ssh/lib/net/ssh/authentication/methods/keyboard_interactive.rb +66 -0
  113. data/plugins/project/vendor/net-ssh/lib/net/ssh/authentication/methods/password.rb +39 -0
  114. data/plugins/project/vendor/net-ssh/lib/net/ssh/authentication/methods/publickey.rb +92 -0
  115. data/plugins/project/vendor/net-ssh/lib/net/ssh/authentication/pageant.rb +183 -0
  116. data/plugins/project/vendor/net-ssh/lib/net/ssh/authentication/session.rb +134 -0
  117. data/plugins/project/vendor/net-ssh/lib/net/ssh/buffer.rb +340 -0
  118. data/plugins/project/vendor/net-ssh/lib/net/ssh/buffered_io.rb +198 -0
  119. data/plugins/project/vendor/net-ssh/lib/net/ssh/config.rb +202 -0
  120. data/plugins/project/vendor/net-ssh/lib/net/ssh/connection/channel.rb +630 -0
  121. data/plugins/project/vendor/net-ssh/lib/net/ssh/connection/constants.rb +33 -0
  122. data/plugins/project/vendor/net-ssh/lib/net/ssh/connection/session.rb +597 -0
  123. data/plugins/project/vendor/net-ssh/lib/net/ssh/connection/term.rb +178 -0
  124. data/plugins/project/vendor/net-ssh/lib/net/ssh/errors.rb +85 -0
  125. data/plugins/project/vendor/net-ssh/lib/net/ssh/key_factory.rb +102 -0
  126. data/plugins/project/vendor/net-ssh/lib/net/ssh/known_hosts.rb +129 -0
  127. data/plugins/project/vendor/net-ssh/lib/net/ssh/loggable.rb +61 -0
  128. data/plugins/project/vendor/net-ssh/lib/net/ssh/packet.rb +102 -0
  129. data/plugins/project/vendor/net-ssh/lib/net/ssh/prompt.rb +93 -0
  130. data/plugins/project/vendor/net-ssh/lib/net/ssh/proxy/command.rb +75 -0
  131. data/plugins/project/vendor/net-ssh/lib/net/ssh/proxy/errors.rb +14 -0
  132. data/plugins/project/vendor/net-ssh/lib/net/ssh/proxy/http.rb +94 -0
  133. data/plugins/project/vendor/net-ssh/lib/net/ssh/proxy/socks4.rb +70 -0
  134. data/plugins/project/vendor/net-ssh/lib/net/ssh/proxy/socks5.rb +142 -0
  135. data/plugins/project/vendor/net-ssh/lib/net/ssh/ruby_compat.rb +43 -0
  136. data/plugins/project/vendor/net-ssh/lib/net/ssh/service/forward.rb +288 -0
  137. data/plugins/project/vendor/net-ssh/lib/net/ssh/test.rb +89 -0
  138. data/plugins/project/vendor/net-ssh/lib/net/ssh/test/channel.rb +129 -0
  139. data/plugins/project/vendor/net-ssh/lib/net/ssh/test/extensions.rb +152 -0
  140. data/plugins/project/vendor/net-ssh/lib/net/ssh/test/kex.rb +44 -0
  141. data/plugins/project/vendor/net-ssh/lib/net/ssh/test/local_packet.rb +51 -0
  142. data/plugins/project/vendor/net-ssh/lib/net/ssh/test/packet.rb +81 -0
  143. data/plugins/project/vendor/net-ssh/lib/net/ssh/test/remote_packet.rb +38 -0
  144. data/plugins/project/vendor/net-ssh/lib/net/ssh/test/script.rb +157 -0
  145. data/plugins/project/vendor/net-ssh/lib/net/ssh/test/socket.rb +64 -0
  146. data/plugins/project/vendor/net-ssh/lib/net/ssh/transport/algorithms.rb +384 -0
  147. data/plugins/project/vendor/net-ssh/lib/net/ssh/transport/cipher_factory.rb +97 -0
  148. data/plugins/project/vendor/net-ssh/lib/net/ssh/transport/constants.rb +30 -0
  149. data/plugins/project/vendor/net-ssh/lib/net/ssh/transport/hmac.rb +31 -0
  150. data/plugins/project/vendor/net-ssh/lib/net/ssh/transport/hmac/abstract.rb +79 -0
  151. data/plugins/project/vendor/net-ssh/lib/net/ssh/transport/hmac/md5.rb +12 -0
  152. data/plugins/project/vendor/net-ssh/lib/net/ssh/transport/hmac/md5_96.rb +11 -0
  153. data/plugins/project/vendor/net-ssh/lib/net/ssh/transport/hmac/none.rb +15 -0
  154. data/plugins/project/vendor/net-ssh/lib/net/ssh/transport/hmac/sha1.rb +13 -0
  155. data/plugins/project/vendor/net-ssh/lib/net/ssh/transport/hmac/sha1_96.rb +11 -0
  156. data/plugins/project/vendor/net-ssh/lib/net/ssh/transport/identity_cipher.rb +55 -0
  157. data/plugins/project/vendor/net-ssh/lib/net/ssh/transport/kex.rb +13 -0
  158. data/plugins/project/vendor/net-ssh/lib/net/ssh/transport/kex/diffie_hellman_group1_sha1.rb +208 -0
  159. data/plugins/project/vendor/net-ssh/lib/net/ssh/transport/kex/diffie_hellman_group_exchange_sha1.rb +77 -0
  160. data/plugins/project/vendor/net-ssh/lib/net/ssh/transport/openssl.rb +128 -0
  161. data/plugins/project/vendor/net-ssh/lib/net/ssh/transport/packet_stream.rb +235 -0
  162. data/plugins/project/vendor/net-ssh/lib/net/ssh/transport/server_version.rb +71 -0
  163. data/plugins/project/vendor/net-ssh/lib/net/ssh/transport/session.rb +276 -0
  164. data/plugins/project/vendor/net-ssh/lib/net/ssh/transport/state.rb +206 -0
  165. data/plugins/project/vendor/net-ssh/lib/net/ssh/verifiers/lenient.rb +30 -0
  166. data/plugins/project/vendor/net-ssh/lib/net/ssh/verifiers/null.rb +12 -0
  167. data/plugins/project/vendor/net-ssh/lib/net/ssh/verifiers/strict.rb +53 -0
  168. data/plugins/project/vendor/net-ssh/lib/net/ssh/version.rb +62 -0
  169. data/plugins/project/vendor/net-ssh/net-ssh.gemspec +138 -0
  170. data/plugins/project/vendor/net-ssh/setup.rb +1585 -0
  171. data/plugins/project/vendor/net-ssh/support/arcfour_check.rb +20 -0
  172. data/plugins/project/vendor/net-ssh/support/ssh_tunnel_bug.rb +65 -0
  173. data/plugins/project/vendor/net-ssh/test/README.txt +42 -0
  174. data/plugins/project/vendor/net-ssh/test/authentication/methods/common.rb +28 -0
  175. data/plugins/project/vendor/net-ssh/test/authentication/methods/test_abstract.rb +51 -0
  176. data/plugins/project/vendor/net-ssh/test/authentication/methods/test_hostbased.rb +114 -0
  177. data/plugins/project/vendor/net-ssh/test/authentication/methods/test_keyboard_interactive.rb +98 -0
  178. data/plugins/project/vendor/net-ssh/test/authentication/methods/test_password.rb +50 -0
  179. data/plugins/project/vendor/net-ssh/test/authentication/methods/test_publickey.rb +127 -0
  180. data/plugins/project/vendor/net-ssh/test/authentication/test_agent.rb +205 -0
  181. data/plugins/project/vendor/net-ssh/test/authentication/test_key_manager.rb +105 -0
  182. data/plugins/project/vendor/net-ssh/test/authentication/test_session.rb +93 -0
  183. data/plugins/project/vendor/net-ssh/test/common.rb +107 -0
  184. data/plugins/project/vendor/net-ssh/test/configs/eqsign +3 -0
  185. data/plugins/project/vendor/net-ssh/test/configs/exact_match +8 -0
  186. data/plugins/project/vendor/net-ssh/test/configs/host_plus +10 -0
  187. data/plugins/project/vendor/net-ssh/test/configs/multihost +4 -0
  188. data/plugins/project/vendor/net-ssh/test/configs/nohost +19 -0
  189. data/plugins/project/vendor/net-ssh/test/configs/numeric_host +4 -0
  190. data/plugins/project/vendor/net-ssh/test/configs/wild_cards +14 -0
  191. data/plugins/project/vendor/net-ssh/test/connection/test_channel.rb +467 -0
  192. data/plugins/project/vendor/net-ssh/test/connection/test_session.rb +488 -0
  193. data/plugins/project/vendor/net-ssh/test/manual/test_forward.rb +185 -0
  194. data/plugins/project/vendor/net-ssh/test/test_all.rb +9 -0
  195. data/plugins/project/vendor/net-ssh/test/test_buffer.rb +336 -0
  196. data/plugins/project/vendor/net-ssh/test/test_buffered_io.rb +63 -0
  197. data/plugins/project/vendor/net-ssh/test/test_config.rb +117 -0
  198. data/plugins/project/vendor/net-ssh/test/test_key_factory.rb +67 -0
  199. data/plugins/project/vendor/net-ssh/test/transport/hmac/test_md5.rb +39 -0
  200. data/plugins/project/vendor/net-ssh/test/transport/hmac/test_md5_96.rb +25 -0
  201. data/plugins/project/vendor/net-ssh/test/transport/hmac/test_none.rb +34 -0
  202. data/plugins/project/vendor/net-ssh/test/transport/hmac/test_sha1.rb +34 -0
  203. data/plugins/project/vendor/net-ssh/test/transport/hmac/test_sha1_96.rb +25 -0
  204. data/plugins/project/vendor/net-ssh/test/transport/kex/test_diffie_hellman_group1_sha1.rb +146 -0
  205. data/plugins/project/vendor/net-ssh/test/transport/kex/test_diffie_hellman_group_exchange_sha1.rb +92 -0
  206. data/plugins/project/vendor/net-ssh/test/transport/test_algorithms.rb +302 -0
  207. data/plugins/project/vendor/net-ssh/test/transport/test_cipher_factory.rb +213 -0
  208. data/plugins/project/vendor/net-ssh/test/transport/test_hmac.rb +34 -0
  209. data/plugins/project/vendor/net-ssh/test/transport/test_identity_cipher.rb +40 -0
  210. data/plugins/project/vendor/net-ssh/test/transport/test_packet_stream.rb +441 -0
  211. data/plugins/project/vendor/net-ssh/test/transport/test_server_version.rb +78 -0
  212. data/plugins/project/vendor/net-ssh/test/transport/test_session.rb +315 -0
  213. data/plugins/project/vendor/net-ssh/test/transport/test_state.rb +173 -0
  214. data/plugins/redcar/plugin.rb +3 -1
  215. data/plugins/redcar/redcar.rb +108 -121
  216. data/plugins/redcar_debug/lib/redcar_debug.rb +2 -0
  217. data/plugins/runnables/lib/runnables.rb +80 -23
  218. data/plugins/runnables/lib/runnables/command_output_controller.rb +102 -0
  219. data/plugins/runnables/lib/runnables/running_process_checker.rb +34 -0
  220. data/plugins/runnables/{plugin_no_load.rb → plugin.rb} +2 -1
  221. data/plugins/runnables/vendor/session-2.4.0/HISTORY +73 -0
  222. data/plugins/runnables/vendor/session-2.4.0/README +89 -0
  223. data/plugins/runnables/vendor/session-2.4.0/TODO +3 -0
  224. data/plugins/runnables/vendor/session-2.4.0/VERSION +1 -0
  225. data/plugins/runnables/vendor/session-2.4.0/gemspec.rb +22 -0
  226. data/plugins/runnables/vendor/session-2.4.0/install.rb +143 -0
  227. data/plugins/runnables/vendor/session-2.4.0/lib/session.rb +757 -0
  228. data/plugins/runnables/vendor/session-2.4.0/sample/bash.rb +60 -0
  229. data/plugins/runnables/vendor/session-2.4.0/sample/driver.rb +47 -0
  230. data/plugins/runnables/vendor/session-2.4.0/sample/session_idl.rb +25 -0
  231. data/plugins/runnables/vendor/session-2.4.0/sample/session_sh.rb +29 -0
  232. data/plugins/runnables/vendor/session-2.4.0/sample/sh0.rb +23 -0
  233. data/plugins/runnables/vendor/session-2.4.0/sample/stdin.rb +17 -0
  234. data/plugins/runnables/vendor/session-2.4.0/sample/threadtest.rb +42 -0
  235. data/plugins/runnables/vendor/session-2.4.0/session-2.4.0.gem +0 -0
  236. data/plugins/runnables/vendor/session-2.4.0/test/session.rb +227 -0
  237. data/plugins/runnables/views/command_output.html.erb +32 -0
  238. data/plugins/task_manager/lib/task_manager.rb +2 -0
  239. data/plugins/textmate/lib/textmate/plist.rb +1 -1
  240. data/plugins/textmate/lib/textmate/snippet.rb +1 -0
  241. data/plugins/tree/lib/tree/mirror.rb +8 -1
  242. data/plugins/tree_view_swt/lib/tree_view_swt.rb +29 -2
  243. metadata +191 -6
  244. data/plugins/declarations/TODO +0 -3
  245. data/plugins/redcar/spec/redcar/redcar_spec.rb +0 -70
  246. data/plugins/redcar/spec/spec_helper.rb +0 -4
@@ -0,0 +1,21 @@
1
+ require 'net/ssh/buffer'
2
+
3
+ module Net; module SFTP
4
+
5
+ # A specialization of the Net::SSH::Buffer class, which simply auto-reads
6
+ # the type byte from the front of every packet it represents.
7
+ class Packet < Net::SSH::Buffer
8
+ # The (intger) type of this packet. See Net::SFTP::Constants for all
9
+ # possible packet types.
10
+ attr_reader :type
11
+
12
+ # Create a new Packet object that wraps the given +data+ (which should be
13
+ # a String). The first byte of the data will be consumed automatically and
14
+ # interpreted as the #type of this packet.
15
+ def initialize(data)
16
+ super
17
+ @type = read_byte
18
+ end
19
+ end
20
+
21
+ 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
@@ -0,0 +1,315 @@
1
+ require 'net/ssh/buffer'
2
+
3
+ module Net; module SFTP; module Protocol; module V01
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
+ #
8
+ # To specify new attributes, just pass a hash as the argument to the
9
+ # constructor. The following keys are supported:
10
+ #
11
+ # * :size:: the size of the file
12
+ # * :uid:: the user-id that owns the file (integer)
13
+ # * :gid:: the group-id that owns the file (integer)
14
+ # * :owner:: the name of the user that owns the file (string)
15
+ # * :group:: the name of the group that owns the file (string)
16
+ # * :permissions:: the permissions on the file (integer, e.g. 0755)
17
+ # * :atime:: the access time of the file (integer, seconds since epoch)
18
+ # * :mtime:: the modification time of the file (integer, seconds since epoch)
19
+ # * :extended:: a hash of name/value pairs identifying extended info
20
+ #
21
+ # Likewise, when the server sends an Attributes object, all of the
22
+ # above attributes are exposed as methods (though not all will be set with
23
+ # non-nil values from the server).
24
+ class Attributes
25
+
26
+ F_SIZE = 0x00000001
27
+ F_UIDGID = 0x00000002
28
+ F_PERMISSIONS = 0x00000004
29
+ F_ACMODTIME = 0x00000008
30
+ F_EXTENDED = 0x80000000
31
+
32
+ T_REGULAR = 1
33
+ T_DIRECTORY = 2
34
+ T_SYMLINK = 3
35
+ T_SPECIAL = 4
36
+ T_UNKNOWN = 5
37
+ T_SOCKET = 6
38
+ T_CHAR_DEVICE = 7
39
+ T_BLOCK_DEVICE = 8
40
+ T_FIFO = 9
41
+
42
+ class <<self
43
+ # Returns the array of attribute meta-data that defines the structure of
44
+ # the attributes packet as described by this version of the protocol.
45
+ def elements #:nodoc:
46
+ @elements ||= [
47
+ [:size, :int64, F_SIZE],
48
+ [:uid, :long, F_UIDGID],
49
+ [:gid, :long, F_UIDGID],
50
+ [:permissions, :long, F_PERMISSIONS],
51
+ [:atime, :long, F_ACMODTIME],
52
+ [:mtime, :long, F_ACMODTIME],
53
+ [:extended, :special, F_EXTENDED]
54
+ ]
55
+ end
56
+
57
+ # Parses the given buffer and returns an Attributes object compsed from
58
+ # the data extracted from it.
59
+ def from_buffer(buffer)
60
+ flags = buffer.read_long
61
+ data = {}
62
+
63
+ elements.each do |name, type, condition|
64
+ if flags & condition == condition
65
+ if type == :special
66
+ data[name] = send("parse_#{name}", buffer)
67
+ else
68
+ data[name] = buffer.send("read_#{type}")
69
+ end
70
+ end
71
+ end
72
+
73
+ new(data)
74
+ end
75
+
76
+ # A convenience method for defining methods that expose specific
77
+ # attributes. This redefines the standard attr_accessor (an admittedly
78
+ # bad practice) because (1) I don't need any "regular" accessors, and
79
+ # (2) because rdoc will automatically pick up and note methods defined
80
+ # via attr_accessor.
81
+ def attr_accessor(name) #:nodoc:
82
+ class_eval <<-CODE
83
+ def #{name}
84
+ attributes[:#{name}]
85
+ end
86
+ CODE
87
+
88
+ attr_writer(name)
89
+ end
90
+
91
+ # A convenience method for defining methods that expose specific
92
+ # attributes. This redefines the standard attr_writer (an admittedly
93
+ # bad practice) because (1) I don't need any "regular" accessors, and
94
+ # (2) because rdoc will automatically pick up and note methods defined
95
+ # via attr_writer.
96
+ def attr_writer(name) #:nodoc:
97
+ class_eval <<-CODE
98
+ def #{name}=(value)
99
+ attributes[:#{name}] = value
100
+ end
101
+ CODE
102
+ end
103
+
104
+ private
105
+
106
+ # Parse the hash of extended data from the buffer.
107
+ def parse_extended(buffer)
108
+ extended = Hash.new
109
+ buffer.read_long.times do
110
+ extended[buffer.read_string] = buffer.read_string
111
+ end
112
+ extended
113
+ end
114
+ end
115
+
116
+ # The hash of name/value pairs that backs this Attributes instance
117
+ attr_reader :attributes
118
+
119
+ # The size of the file.
120
+ attr_accessor :size
121
+
122
+ # The user-id of the user that owns the file
123
+ attr_writer :uid
124
+
125
+ # The group-id of the user that owns the file
126
+ attr_writer :gid
127
+
128
+ # The permissions on the file
129
+ attr_accessor :permissions
130
+
131
+ # The last access time of the file
132
+ attr_accessor :atime
133
+
134
+ # The modification time of the file
135
+ attr_accessor :mtime
136
+
137
+ # The hash of name/value pairs identifying extended information about the file
138
+ attr_accessor :extended
139
+
140
+ # Create a new Attributes instance with the given attributes. The
141
+ # following keys are supported:
142
+ #
143
+ # * :size:: the size of the file
144
+ # * :uid:: the user-id that owns the file (integer)
145
+ # * :gid:: the group-id that owns the file (integer)
146
+ # * :owner:: the name of the user that owns the file (string)
147
+ # * :group:: the name of the group that owns the file (string)
148
+ # * :permissions:: the permissions on the file (integer, e.g. 0755)
149
+ # * :atime:: the access time of the file (integer, seconds since epoch)
150
+ # * :mtime:: the modification time of the file (integer, seconds since epoch)
151
+ # * :extended:: a hash of name/value pairs identifying extended info
152
+ def initialize(attributes={})
153
+ @attributes = attributes
154
+ end
155
+
156
+ # Returns the user-id of the user that owns the file, or +nil+ if that
157
+ # information is not available. If an :owner key exists, but not a :uid
158
+ # key, the Etc module will be used to reverse lookup the id from the name.
159
+ # This might fail on some systems (e.g., Windows).
160
+ def uid
161
+ if attributes[:owner] && !attributes.key?(:uid)
162
+ require 'etc'
163
+ attributes[:uid] = Etc.getpwnam(attributes[:owner]).uid
164
+ end
165
+ attributes[:uid]
166
+ end
167
+
168
+ # Returns the group-id of the group that owns the file, or +nil+ if that
169
+ # information is not available. If a :group key exists, but not a :gid
170
+ # key, the Etc module will be used to reverse lookup the id from the name.
171
+ # This might fail on some systems (e.g., Windows).
172
+ def gid
173
+ if attributes[:group] && !attributes.key?(:gid)
174
+ require 'etc'
175
+ attributes[:gid] = Etc.getgrnam(attributes[:group]).gid
176
+ end
177
+ attributes[:gid]
178
+ end
179
+
180
+ # Returns the username of the user that owns the file, or +nil+ if that
181
+ # information is not available. If the :uid is given, but not the :owner,
182
+ # the Etc module will be used to lookup the name from the id. This might
183
+ # fail on some systems (e.g. Windows).
184
+ def owner
185
+ if attributes[:uid] && !attributes[:owner]
186
+ require 'etc'
187
+ attributes[:owner] = Etc.getpwuid(attributes[:uid].to_i).name
188
+ end
189
+ attributes[:owner]
190
+ end
191
+
192
+ # Returns the group name of the group that owns the file, or +nil+ if that
193
+ # information is not available. If the :gid is given, but not the :group,
194
+ # the Etc module will be used to lookup the name from the id. This might
195
+ # fail on some systems (e.g. Windows).
196
+ def group
197
+ if attributes[:gid] && !attributes[:group]
198
+ require 'etc'
199
+ attributes[:group] = Etc.getgrgid(attributes[:gid].to_i).name
200
+ end
201
+ attributes[:group]
202
+ end
203
+
204
+ # Inspects the permissions bits to determine what type of entity this
205
+ # attributes object represents. If will return one of the T_ constants.
206
+ def type
207
+ if permissions & 0140000 == 0140000 then
208
+ T_SOCKET
209
+ elsif permissions & 0120000 == 0120000 then
210
+ T_SYMLINK
211
+ elsif permissions & 0100000 == 0100000 then
212
+ T_REGULAR
213
+ elsif permissions & 060000 == 060000 then
214
+ T_BLOCK_DEVICE
215
+ elsif permissions & 040000 == 040000 then
216
+ T_DIRECTORY
217
+ elsif permissions & 020000 == 020000 then
218
+ T_CHAR_DEVICE
219
+ elsif permissions & 010000 == 010000 then
220
+ T_FIFO
221
+ else
222
+ T_UNKNOWN
223
+ end
224
+ end
225
+
226
+ # Returns the type as a symbol, rather than an integer, for easier use in
227
+ # Ruby programs.
228
+ def symbolic_type
229
+ case type
230
+ when T_SOCKET then :socket
231
+ when T_SYMLINK then :symlink
232
+ when T_REGULAR then :regular
233
+ when T_BLOCK_DEVICE then :block_device
234
+ when T_DIRECTORY then :directory
235
+ when T_CHAR_DEVICE then :char_device
236
+ when T_FIFO then :fifo
237
+ when T_SPECIAL then :special
238
+ when T_UNKNOWN then :unknown
239
+ else raise NotImplementedError, "unknown file type #{type} (bug?)"
240
+ end
241
+ end
242
+
243
+ # Returns true if these attributes appear to describe a directory.
244
+ def directory?
245
+ case type
246
+ when T_DIRECTORY then true
247
+ when T_UNKNOWN then nil
248
+ else false
249
+ end
250
+ end
251
+
252
+ # Returns true if these attributes appear to describe a symlink.
253
+ def symlink?
254
+ case type
255
+ when T_SYMLINK then true
256
+ when T_UNKNOWN then nil
257
+ else false
258
+ end
259
+ end
260
+
261
+ # Returns true if these attributes appear to describe a regular file.
262
+ def file?
263
+ case type
264
+ when T_REGULAR then true
265
+ when T_UNKNOWN then nil
266
+ else false
267
+ end
268
+ end
269
+
270
+ # Convert the object to a string suitable for passing in an SFTP
271
+ # packet. This is the raw representation of the attribute packet payload,
272
+ # and is not intended to be human readable.
273
+ def to_s
274
+ prepare_serialization!
275
+
276
+ flags = 0
277
+
278
+ self.class.elements.each do |name, type, condition|
279
+ flags |= condition if attributes[name]
280
+ end
281
+
282
+ buffer = Net::SSH::Buffer.from(:long, flags)
283
+ self.class.elements.each do |name, type, condition|
284
+ if flags & condition == condition
285
+ if type == :special
286
+ send("encode_#{name}", buffer)
287
+ else
288
+ buffer.send("write_#{type}", attributes[name])
289
+ end
290
+ end
291
+ end
292
+
293
+ buffer.to_s
294
+ end
295
+
296
+ private
297
+
298
+ # Perform protocol-version-specific preparations for serialization.
299
+ def prepare_serialization!
300
+ # force the uid/gid to be translated from owner/group, if those keys
301
+ # were given on instantiation
302
+ uid
303
+ gid
304
+ end
305
+
306
+ # Encodes information about the extended info onto the end of the given
307
+ # buffer.
308
+ def encode_extended(buffer)
309
+ buffer.write_long extended.size
310
+ extended.each { |k,v| buffer.write_string k, v }
311
+ end
312
+
313
+ end
314
+
315
+ end ; end ; end ; end
@@ -0,0 +1,268 @@
1
+ require 'net/ssh/loggable'
2
+ require 'net/sftp/constants'
3
+ require 'net/sftp/packet'
4
+ require 'net/sftp/protocol/base'
5
+ require 'net/sftp/protocol/01/attributes'
6
+ require 'net/sftp/protocol/01/name'
7
+
8
+ module Net; module SFTP; module Protocol; module V01
9
+
10
+ # Wraps the low-level SFTP calls for version 1 of the SFTP protocol. Also
11
+ # implements the packet parsing as defined by version 1 of the protocol.
12
+ #
13
+ # None of these protocol methods block--all of them return immediately,
14
+ # requiring the SSH event loop to be run while the server response is
15
+ # pending.
16
+ #
17
+ # You will almost certainly never need to use this driver directly. Please
18
+ # see Net::SFTP::Session for the recommended interface.
19
+ class Base < Protocol::Base
20
+ include Net::SFTP::Constants::OpenFlags
21
+
22
+ # Returns the protocol version implemented by this driver. (1, in this
23
+ # case)
24
+ def version
25
+ 1
26
+ end
27
+
28
+ # Parses the given FXP_HANDLE packet and returns a hash with one key,
29
+ # :handle, which references the handle.
30
+ def parse_handle_packet(packet)
31
+ { :handle => packet.read_string }
32
+ end
33
+
34
+ # Parses the given FXP_STATUS packet and returns a hash with one key,
35
+ # :code, which references the status code returned by the server.
36
+ def parse_status_packet(packet)
37
+ { :code => packet.read_long }
38
+ end
39
+
40
+ # Parses the given FXP_DATA packet and returns a hash with one key,
41
+ # :data, which references the data returned in the packet.
42
+ def parse_data_packet(packet)
43
+ { :data => packet.read_string }
44
+ end
45
+
46
+ # Parses the given FXP_ATTRS packet and returns a hash with one key,
47
+ # :attrs, which references an Attributes object.
48
+ def parse_attrs_packet(packet)
49
+ { :attrs => attribute_factory.from_buffer(packet) }
50
+ end
51
+
52
+ # Parses the given FXP_NAME packet and returns a hash with one key, :names,
53
+ # which references an array of Name objects.
54
+ def parse_name_packet(packet)
55
+ names = []
56
+
57
+ packet.read_long.times do
58
+ filename = packet.read_string
59
+ longname = packet.read_string
60
+ attrs = attribute_factory.from_buffer(packet)
61
+ names << name_factory.new(filename, longname, attrs)
62
+ end
63
+
64
+ { :names => names }
65
+ end
66
+
67
+ # Sends a FXP_OPEN packet to the server and returns the packet identifier.
68
+ # The +flags+ parameter is either an integer (in which case it must be
69
+ # a combination of the IO constants) or a string (in which case it must
70
+ # be one of the mode strings that IO::open accepts). The +options+
71
+ # parameter is a hash that is used to construct a new Attribute object,
72
+ # to pass as part of the FXP_OPEN request.
73
+ def open(path, flags, options)
74
+ flags = normalize_open_flags(flags)
75
+
76
+ if flags & (IO::WRONLY | IO::RDWR) != 0
77
+ sftp_flags = FV1::WRITE
78
+ sftp_flags |= FV1::READ if flags & IO::RDWR != 0
79
+ sftp_flags |= FV1::APPEND if flags & IO::APPEND != 0
80
+ else
81
+ sftp_flags = FV1::READ
82
+ end
83
+
84
+ sftp_flags |= FV1::CREAT if flags & IO::CREAT != 0
85
+ sftp_flags |= FV1::TRUNC if flags & IO::TRUNC != 0
86
+ sftp_flags |= FV1::EXCL if flags & IO::EXCL != 0
87
+
88
+ attributes = attribute_factory.new(options)
89
+
90
+ send_request(FXP_OPEN, :string, path, :long, sftp_flags, :raw, attributes.to_s)
91
+ end
92
+
93
+ # Sends a FXP_CLOSE packet to the server for the given +handle+ (such as
94
+ # would be returned via a FXP_HANDLE packet). Returns the new packet id.
95
+ def close(handle)
96
+ send_request(FXP_CLOSE, :string, handle)
97
+ end
98
+
99
+ # Sends a FXP_READ packet to the server, requesting that +length+ bytes
100
+ # be read from the file identified by +handle+, starting at +offset+ bytes
101
+ # within the file. The handle must be one that was returned via a
102
+ # FXP_HANDLE packet. Returns the new packet id.
103
+ def read(handle, offset, length)
104
+ send_request(FXP_READ, :string, handle, :int64, offset, :long, length)
105
+ end
106
+
107
+ # Sends a FXP_WRITE packet to the server, requesting that +data+ (a string),
108
+ # be written to the file identified by +handle+, starting at +offset+ bytes
109
+ # from the beginning of the file. The handle must be one that was returned
110
+ # via a FXP_HANDLE packet. Returns the new packet id.
111
+ def write(handle, offset, data)
112
+ send_request(FXP_WRITE, :string, handle, :int64, offset, :string, data)
113
+ end
114
+
115
+ # Sends a FXP_LSTAT packet to the server, requesting a FXP_ATTR response
116
+ # for the file at the given remote +path+ (a string). The +flags+ parameter
117
+ # is ignored in this version of the protocol. #lstat will not follow
118
+ # symbolic links; see #stat for a version that will.
119
+ def lstat(path, flags=nil)
120
+ send_request(FXP_LSTAT, :string, path)
121
+ end
122
+
123
+ # Sends a FXP_FSTAT packet to the server, requesting a FXP_ATTR response
124
+ # for the file represented by the given +handle+ (which must have been
125
+ # obtained from a FXP_HANDLE packet). The +flags+ parameter is ignored in
126
+ # this version of the protocol.
127
+ def fstat(handle, flags=nil)
128
+ send_request(FXP_FSTAT, :string, handle)
129
+ end
130
+
131
+ # Sends a FXP_SETSTAT packet to the server, to update the attributes for
132
+ # the file at the given remote +path+ (a string). The +attrs+ parameter is
133
+ # a hash that defines the attributes to set.
134
+ def setstat(path, attrs)
135
+ send_request(FXP_SETSTAT, :string, path, :raw, attribute_factory.new(attrs).to_s)
136
+ end
137
+
138
+ # Sends a FXP_FSETSTAT packet to the server, to update the attributes for
139
+ # the file represented by the given +handle+ (which must have been obtained
140
+ # from a FXP_HANDLE packet). The +attrs+ parameter is a hash that defines
141
+ # the attributes to set.
142
+ def fsetstat(handle, attrs)
143
+ send_request(FXP_FSETSTAT, :string, handle, :raw, attribute_factory.new(attrs).to_s)
144
+ end
145
+
146
+ # Sends a FXP_OPENDIR packet to the server, to request a handle for
147
+ # manipulating the directory at the given remote +path+.
148
+ def opendir(path)
149
+ send_request(FXP_OPENDIR, :string, path)
150
+ end
151
+
152
+ # Sends a FXP_READDIR packet to the server, to request a batch of
153
+ # directory name entries in the directory identified by +handle+ (which
154
+ # must have been obtained via a FXP_OPENDIR request).
155
+ def readdir(handle)
156
+ send_request(FXP_READDIR, :string, handle)
157
+ end
158
+
159
+ # Sends a FXP_REMOTE packet to the server, to request that the given
160
+ # file be deleted from the remote server.
161
+ def remove(filename)
162
+ send_request(FXP_REMOVE, :string, filename)
163
+ end
164
+
165
+ # Sends a FXP_MKDIR packet to the server, to request that a new directory
166
+ # at +path+ on the remote server be created, and with +attrs+ (a hash)
167
+ # describing the attributes of the new directory.
168
+ def mkdir(path, attrs)
169
+ send_request(FXP_MKDIR, :string, path, :raw, attribute_factory.new(attrs).to_s)
170
+ end
171
+
172
+ # Sends a FXP_RMDIR packet to the server, to request that the directory
173
+ # at +path+ on the remote server be deleted.
174
+ def rmdir(path)
175
+ send_request(FXP_RMDIR, :string, path)
176
+ end
177
+
178
+ # Sends a FXP_REALPATH packet to the server, to request that the given
179
+ # +path+ be canonicalized, taking into account path segments like "..".
180
+ def realpath(path)
181
+ send_request(FXP_REALPATH, :string, path)
182
+ end
183
+
184
+ # Sends a FXP_STAT packet to the server, requesting a FXP_ATTR response
185
+ # for the file at the given remote +path+ (a string). The +flags+ parameter
186
+ # is ignored in this version of the protocol. #stat will follow
187
+ # symbolic links; see #lstat for a version that will not.
188
+ def stat(path, flags=nil)
189
+ send_request(FXP_STAT, :string, path)
190
+ end
191
+
192
+ # Not implemented in version 1 of the SFTP protocol. Raises a
193
+ # NotImplementedError if called.
194
+ def rename(name, new_name, flags=nil)
195
+ not_implemented! :rename
196
+ end
197
+
198
+ # Not implemented in version 1 of the SFTP protocol. Raises a
199
+ # NotImplementedError if called.
200
+ def readlink(path)
201
+ not_implemented! :readlink
202
+ end
203
+
204
+ # Not implemented in version 1 of the SFTP protocol. Raises a
205
+ # NotImplementedError if called.
206
+ def symlink(path, target)
207
+ not_implemented! :symlink
208
+ end
209
+
210
+ # Not implemented in version 1 of the SFTP protocol. Raises a
211
+ # NotImplementedError if called.
212
+ def link(*args)
213
+ not_implemented! :link
214
+ end
215
+
216
+ # Not implemented in version 1 of the SFTP protocol. Raises a
217
+ # NotImplementedError if called.
218
+ def block(handle, offset, length, mask)
219
+ not_implemented! :block
220
+ end
221
+
222
+ # Not implemented in version 1 of the SFTP protocol. Raises a
223
+ # NotImplementedError if called.
224
+ def unblock(handle, offset, length)
225
+ not_implemented! :unblock
226
+ end
227
+
228
+ protected
229
+
230
+ # A helper method for implementing wrappers for operations that are
231
+ # not implemented by the current SFTP protocol version. Simply raises
232
+ # NotImplementedError with a message based on the given operation name.
233
+ def not_implemented!(operation)
234
+ raise NotImplementedError, "the #{operation} operation is not available in the version of the SFTP protocol supported by your server"
235
+ end
236
+
237
+ # Normalizes the given flags parameter, converting it into a combination
238
+ # of IO constants.
239
+ def normalize_open_flags(flags)
240
+ if String === flags
241
+ case flags.tr("b", "")
242
+ when "r" then IO::RDONLY
243
+ when "r+" then IO::RDWR
244
+ when "w" then IO::WRONLY | IO::TRUNC | IO::CREAT
245
+ when "w+" then IO::RDWR | IO::TRUNC | IO::CREAT
246
+ when "a" then IO::APPEND | IO::CREAT | IO::WRONLY
247
+ when "a+" then IO::APPEND | IO::CREAT | IO::RDWR
248
+ else raise ArgumentError, "unsupported flags: #{flags.inspect}"
249
+ end
250
+ else
251
+ flags.to_i
252
+ end
253
+ end
254
+
255
+ # Returns the Attributes class used by this version of the protocol
256
+ # (Net::SFTP::Protocol::V01::Attributes, in this case)
257
+ def attribute_factory
258
+ V01::Attributes
259
+ end
260
+
261
+ # Returns the Name class used by this version of the protocol
262
+ # (Net::SFTP::Protocol::V01::Name, in this case)
263
+ def name_factory
264
+ V01::Name
265
+ end
266
+ end
267
+
268
+ end; end; end; end