redcar 0.3.8.3 → 0.3.8.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (172) hide show
  1. data/CHANGES +6 -0
  2. data/Rakefile +1 -1
  3. data/lib/redcar.rb +1 -1
  4. data/lib/redcar/installer.rb +14 -4
  5. metadata +1 -168
  6. data/lib/openssl/Manifest.txt +0 -99
  7. data/lib/openssl/build.properties +0 -7
  8. data/lib/plugin_manager/plugin_manager.gemspec +0 -33
  9. data/plugins/project/vendor/net-sftp/Manifest +0 -55
  10. data/plugins/project/vendor/net-sftp/Rakefile +0 -30
  11. data/plugins/project/vendor/net-sftp/lib/net/sftp.rb +0 -70
  12. data/plugins/project/vendor/net-sftp/lib/net/sftp/constants.rb +0 -187
  13. data/plugins/project/vendor/net-sftp/lib/net/sftp/errors.rb +0 -39
  14. data/plugins/project/vendor/net-sftp/lib/net/sftp/operations/dir.rb +0 -93
  15. data/plugins/project/vendor/net-sftp/lib/net/sftp/operations/download.rb +0 -364
  16. data/plugins/project/vendor/net-sftp/lib/net/sftp/operations/file.rb +0 -176
  17. data/plugins/project/vendor/net-sftp/lib/net/sftp/operations/file_factory.rb +0 -60
  18. data/plugins/project/vendor/net-sftp/lib/net/sftp/operations/upload.rb +0 -387
  19. data/plugins/project/vendor/net-sftp/lib/net/sftp/packet.rb +0 -21
  20. data/plugins/project/vendor/net-sftp/lib/net/sftp/protocol.rb +0 -32
  21. data/plugins/project/vendor/net-sftp/lib/net/sftp/protocol/01/attributes.rb +0 -315
  22. data/plugins/project/vendor/net-sftp/lib/net/sftp/protocol/01/base.rb +0 -268
  23. data/plugins/project/vendor/net-sftp/lib/net/sftp/protocol/01/name.rb +0 -43
  24. data/plugins/project/vendor/net-sftp/lib/net/sftp/protocol/02/base.rb +0 -31
  25. data/plugins/project/vendor/net-sftp/lib/net/sftp/protocol/03/base.rb +0 -35
  26. data/plugins/project/vendor/net-sftp/lib/net/sftp/protocol/04/attributes.rb +0 -152
  27. data/plugins/project/vendor/net-sftp/lib/net/sftp/protocol/04/base.rb +0 -94
  28. data/plugins/project/vendor/net-sftp/lib/net/sftp/protocol/04/name.rb +0 -67
  29. data/plugins/project/vendor/net-sftp/lib/net/sftp/protocol/05/base.rb +0 -66
  30. data/plugins/project/vendor/net-sftp/lib/net/sftp/protocol/06/attributes.rb +0 -107
  31. data/plugins/project/vendor/net-sftp/lib/net/sftp/protocol/06/base.rb +0 -63
  32. data/plugins/project/vendor/net-sftp/lib/net/sftp/protocol/base.rb +0 -50
  33. data/plugins/project/vendor/net-sftp/lib/net/sftp/request.rb +0 -91
  34. data/plugins/project/vendor/net-sftp/lib/net/sftp/response.rb +0 -76
  35. data/plugins/project/vendor/net-sftp/lib/net/sftp/session.rb +0 -951
  36. data/plugins/project/vendor/net-sftp/lib/net/sftp/version.rb +0 -18
  37. data/plugins/project/vendor/net-sftp/setup.rb +0 -1331
  38. data/plugins/project/vendor/net-sftp/test/common.rb +0 -171
  39. data/plugins/project/vendor/net-sftp/test/protocol/01/test_attributes.rb +0 -97
  40. data/plugins/project/vendor/net-sftp/test/protocol/01/test_base.rb +0 -210
  41. data/plugins/project/vendor/net-sftp/test/protocol/01/test_name.rb +0 -27
  42. data/plugins/project/vendor/net-sftp/test/protocol/02/test_base.rb +0 -26
  43. data/plugins/project/vendor/net-sftp/test/protocol/03/test_base.rb +0 -27
  44. data/plugins/project/vendor/net-sftp/test/protocol/04/test_attributes.rb +0 -148
  45. data/plugins/project/vendor/net-sftp/test/protocol/04/test_base.rb +0 -74
  46. data/plugins/project/vendor/net-sftp/test/protocol/04/test_name.rb +0 -53
  47. data/plugins/project/vendor/net-sftp/test/protocol/05/test_base.rb +0 -62
  48. data/plugins/project/vendor/net-sftp/test/protocol/06/test_attributes.rb +0 -124
  49. data/plugins/project/vendor/net-sftp/test/protocol/06/test_base.rb +0 -51
  50. data/plugins/project/vendor/net-sftp/test/protocol/test_base.rb +0 -42
  51. data/plugins/project/vendor/net-sftp/test/test_all.rb +0 -7
  52. data/plugins/project/vendor/net-sftp/test/test_dir.rb +0 -47
  53. data/plugins/project/vendor/net-sftp/test/test_download.rb +0 -252
  54. data/plugins/project/vendor/net-sftp/test/test_file.rb +0 -159
  55. data/plugins/project/vendor/net-sftp/test/test_file_factory.rb +0 -48
  56. data/plugins/project/vendor/net-sftp/test/test_packet.rb +0 -9
  57. data/plugins/project/vendor/net-sftp/test/test_protocol.rb +0 -17
  58. data/plugins/project/vendor/net-sftp/test/test_request.rb +0 -71
  59. data/plugins/project/vendor/net-sftp/test/test_response.rb +0 -53
  60. data/plugins/project/vendor/net-sftp/test/test_session.rb +0 -741
  61. data/plugins/project/vendor/net-sftp/test/test_upload.rb +0 -219
  62. data/plugins/project/vendor/net-ssh/Manifest +0 -110
  63. data/plugins/project/vendor/net-ssh/Rakefile +0 -85
  64. data/plugins/project/vendor/net-ssh/Rudyfile +0 -96
  65. data/plugins/project/vendor/net-ssh/lib/net/ssh.rb +0 -215
  66. data/plugins/project/vendor/net-ssh/lib/net/ssh/authentication/agent.rb +0 -179
  67. data/plugins/project/vendor/net-ssh/lib/net/ssh/authentication/constants.rb +0 -18
  68. data/plugins/project/vendor/net-ssh/lib/net/ssh/authentication/key_manager.rb +0 -193
  69. data/plugins/project/vendor/net-ssh/lib/net/ssh/authentication/methods/abstract.rb +0 -60
  70. data/plugins/project/vendor/net-ssh/lib/net/ssh/authentication/methods/hostbased.rb +0 -71
  71. data/plugins/project/vendor/net-ssh/lib/net/ssh/authentication/methods/keyboard_interactive.rb +0 -66
  72. data/plugins/project/vendor/net-ssh/lib/net/ssh/authentication/methods/password.rb +0 -39
  73. data/plugins/project/vendor/net-ssh/lib/net/ssh/authentication/methods/publickey.rb +0 -92
  74. data/plugins/project/vendor/net-ssh/lib/net/ssh/authentication/pageant.rb +0 -183
  75. data/plugins/project/vendor/net-ssh/lib/net/ssh/authentication/session.rb +0 -134
  76. data/plugins/project/vendor/net-ssh/lib/net/ssh/buffer.rb +0 -340
  77. data/plugins/project/vendor/net-ssh/lib/net/ssh/buffered_io.rb +0 -198
  78. data/plugins/project/vendor/net-ssh/lib/net/ssh/config.rb +0 -202
  79. data/plugins/project/vendor/net-ssh/lib/net/ssh/connection/channel.rb +0 -630
  80. data/plugins/project/vendor/net-ssh/lib/net/ssh/connection/constants.rb +0 -33
  81. data/plugins/project/vendor/net-ssh/lib/net/ssh/connection/session.rb +0 -597
  82. data/plugins/project/vendor/net-ssh/lib/net/ssh/connection/term.rb +0 -178
  83. data/plugins/project/vendor/net-ssh/lib/net/ssh/errors.rb +0 -85
  84. data/plugins/project/vendor/net-ssh/lib/net/ssh/key_factory.rb +0 -102
  85. data/plugins/project/vendor/net-ssh/lib/net/ssh/known_hosts.rb +0 -129
  86. data/plugins/project/vendor/net-ssh/lib/net/ssh/loggable.rb +0 -61
  87. data/plugins/project/vendor/net-ssh/lib/net/ssh/packet.rb +0 -102
  88. data/plugins/project/vendor/net-ssh/lib/net/ssh/prompt.rb +0 -93
  89. data/plugins/project/vendor/net-ssh/lib/net/ssh/proxy/command.rb +0 -75
  90. data/plugins/project/vendor/net-ssh/lib/net/ssh/proxy/errors.rb +0 -14
  91. data/plugins/project/vendor/net-ssh/lib/net/ssh/proxy/http.rb +0 -94
  92. data/plugins/project/vendor/net-ssh/lib/net/ssh/proxy/socks4.rb +0 -70
  93. data/plugins/project/vendor/net-ssh/lib/net/ssh/proxy/socks5.rb +0 -142
  94. data/plugins/project/vendor/net-ssh/lib/net/ssh/ruby_compat.rb +0 -43
  95. data/plugins/project/vendor/net-ssh/lib/net/ssh/service/forward.rb +0 -288
  96. data/plugins/project/vendor/net-ssh/lib/net/ssh/test.rb +0 -89
  97. data/plugins/project/vendor/net-ssh/lib/net/ssh/test/channel.rb +0 -129
  98. data/plugins/project/vendor/net-ssh/lib/net/ssh/test/extensions.rb +0 -152
  99. data/plugins/project/vendor/net-ssh/lib/net/ssh/test/kex.rb +0 -44
  100. data/plugins/project/vendor/net-ssh/lib/net/ssh/test/local_packet.rb +0 -51
  101. data/plugins/project/vendor/net-ssh/lib/net/ssh/test/packet.rb +0 -81
  102. data/plugins/project/vendor/net-ssh/lib/net/ssh/test/remote_packet.rb +0 -38
  103. data/plugins/project/vendor/net-ssh/lib/net/ssh/test/script.rb +0 -157
  104. data/plugins/project/vendor/net-ssh/lib/net/ssh/test/socket.rb +0 -64
  105. data/plugins/project/vendor/net-ssh/lib/net/ssh/transport/algorithms.rb +0 -384
  106. data/plugins/project/vendor/net-ssh/lib/net/ssh/transport/cipher_factory.rb +0 -97
  107. data/plugins/project/vendor/net-ssh/lib/net/ssh/transport/constants.rb +0 -30
  108. data/plugins/project/vendor/net-ssh/lib/net/ssh/transport/hmac.rb +0 -31
  109. data/plugins/project/vendor/net-ssh/lib/net/ssh/transport/hmac/abstract.rb +0 -79
  110. data/plugins/project/vendor/net-ssh/lib/net/ssh/transport/hmac/md5.rb +0 -12
  111. data/plugins/project/vendor/net-ssh/lib/net/ssh/transport/hmac/md5_96.rb +0 -11
  112. data/plugins/project/vendor/net-ssh/lib/net/ssh/transport/hmac/none.rb +0 -15
  113. data/plugins/project/vendor/net-ssh/lib/net/ssh/transport/hmac/sha1.rb +0 -13
  114. data/plugins/project/vendor/net-ssh/lib/net/ssh/transport/hmac/sha1_96.rb +0 -11
  115. data/plugins/project/vendor/net-ssh/lib/net/ssh/transport/identity_cipher.rb +0 -55
  116. data/plugins/project/vendor/net-ssh/lib/net/ssh/transport/kex.rb +0 -13
  117. data/plugins/project/vendor/net-ssh/lib/net/ssh/transport/kex/diffie_hellman_group1_sha1.rb +0 -208
  118. data/plugins/project/vendor/net-ssh/lib/net/ssh/transport/kex/diffie_hellman_group_exchange_sha1.rb +0 -77
  119. data/plugins/project/vendor/net-ssh/lib/net/ssh/transport/openssl.rb +0 -128
  120. data/plugins/project/vendor/net-ssh/lib/net/ssh/transport/packet_stream.rb +0 -235
  121. data/plugins/project/vendor/net-ssh/lib/net/ssh/transport/server_version.rb +0 -71
  122. data/plugins/project/vendor/net-ssh/lib/net/ssh/transport/session.rb +0 -276
  123. data/plugins/project/vendor/net-ssh/lib/net/ssh/transport/state.rb +0 -206
  124. data/plugins/project/vendor/net-ssh/lib/net/ssh/verifiers/lenient.rb +0 -30
  125. data/plugins/project/vendor/net-ssh/lib/net/ssh/verifiers/null.rb +0 -12
  126. data/plugins/project/vendor/net-ssh/lib/net/ssh/verifiers/strict.rb +0 -53
  127. data/plugins/project/vendor/net-ssh/lib/net/ssh/version.rb +0 -62
  128. data/plugins/project/vendor/net-ssh/net-ssh.gemspec +0 -138
  129. data/plugins/project/vendor/net-ssh/setup.rb +0 -1585
  130. data/plugins/project/vendor/net-ssh/support/arcfour_check.rb +0 -20
  131. data/plugins/project/vendor/net-ssh/support/ssh_tunnel_bug.rb +0 -65
  132. data/plugins/project/vendor/net-ssh/test/README.txt +0 -42
  133. data/plugins/project/vendor/net-ssh/test/authentication/methods/common.rb +0 -28
  134. data/plugins/project/vendor/net-ssh/test/authentication/methods/test_abstract.rb +0 -51
  135. data/plugins/project/vendor/net-ssh/test/authentication/methods/test_hostbased.rb +0 -114
  136. data/plugins/project/vendor/net-ssh/test/authentication/methods/test_keyboard_interactive.rb +0 -98
  137. data/plugins/project/vendor/net-ssh/test/authentication/methods/test_password.rb +0 -50
  138. data/plugins/project/vendor/net-ssh/test/authentication/methods/test_publickey.rb +0 -127
  139. data/plugins/project/vendor/net-ssh/test/authentication/test_agent.rb +0 -205
  140. data/plugins/project/vendor/net-ssh/test/authentication/test_key_manager.rb +0 -105
  141. data/plugins/project/vendor/net-ssh/test/authentication/test_session.rb +0 -93
  142. data/plugins/project/vendor/net-ssh/test/common.rb +0 -107
  143. data/plugins/project/vendor/net-ssh/test/configs/eqsign +0 -3
  144. data/plugins/project/vendor/net-ssh/test/configs/exact_match +0 -8
  145. data/plugins/project/vendor/net-ssh/test/configs/host_plus +0 -10
  146. data/plugins/project/vendor/net-ssh/test/configs/multihost +0 -4
  147. data/plugins/project/vendor/net-ssh/test/configs/nohost +0 -19
  148. data/plugins/project/vendor/net-ssh/test/configs/numeric_host +0 -4
  149. data/plugins/project/vendor/net-ssh/test/configs/wild_cards +0 -14
  150. data/plugins/project/vendor/net-ssh/test/connection/test_channel.rb +0 -467
  151. data/plugins/project/vendor/net-ssh/test/connection/test_session.rb +0 -488
  152. data/plugins/project/vendor/net-ssh/test/manual/test_forward.rb +0 -185
  153. data/plugins/project/vendor/net-ssh/test/test_all.rb +0 -9
  154. data/plugins/project/vendor/net-ssh/test/test_buffer.rb +0 -336
  155. data/plugins/project/vendor/net-ssh/test/test_buffered_io.rb +0 -63
  156. data/plugins/project/vendor/net-ssh/test/test_config.rb +0 -117
  157. data/plugins/project/vendor/net-ssh/test/test_key_factory.rb +0 -67
  158. data/plugins/project/vendor/net-ssh/test/transport/hmac/test_md5.rb +0 -39
  159. data/plugins/project/vendor/net-ssh/test/transport/hmac/test_md5_96.rb +0 -25
  160. data/plugins/project/vendor/net-ssh/test/transport/hmac/test_none.rb +0 -34
  161. data/plugins/project/vendor/net-ssh/test/transport/hmac/test_sha1.rb +0 -34
  162. data/plugins/project/vendor/net-ssh/test/transport/hmac/test_sha1_96.rb +0 -25
  163. data/plugins/project/vendor/net-ssh/test/transport/kex/test_diffie_hellman_group1_sha1.rb +0 -146
  164. data/plugins/project/vendor/net-ssh/test/transport/kex/test_diffie_hellman_group_exchange_sha1.rb +0 -92
  165. data/plugins/project/vendor/net-ssh/test/transport/test_algorithms.rb +0 -302
  166. data/plugins/project/vendor/net-ssh/test/transport/test_cipher_factory.rb +0 -213
  167. data/plugins/project/vendor/net-ssh/test/transport/test_hmac.rb +0 -34
  168. data/plugins/project/vendor/net-ssh/test/transport/test_identity_cipher.rb +0 -40
  169. data/plugins/project/vendor/net-ssh/test/transport/test_packet_stream.rb +0 -441
  170. data/plugins/project/vendor/net-ssh/test/transport/test_server_version.rb +0 -78
  171. data/plugins/project/vendor/net-ssh/test/transport/test_session.rb +0 -315
  172. data/plugins/project/vendor/net-ssh/test/transport/test_state.rb +0 -173
@@ -1,176 +0,0 @@
1
- require 'net/ssh/loggable'
2
- require 'net/sftp/operations/file'
3
-
4
- module Net; module SFTP; module Operations
5
-
6
- # A wrapper around an SFTP file handle, that exposes an IO-like interface
7
- # for interacting with the remote file. All operations are synchronous
8
- # (blocking), making this a very convenient way to deal with remote files.
9
- #
10
- # A wrapper is usually created via the Net::SFTP::Session#file factory:
11
- #
12
- # file = sftp.file.open("/path/to/remote")
13
- # puts file.gets
14
- # file.close
15
- class File
16
- # A reference to the Net::SFTP::Session instance that drives this wrapper
17
- attr_reader :sftp
18
-
19
- # The SFTP file handle object that this object wraps
20
- attr_reader :handle
21
-
22
- # The current position within the remote file
23
- attr_reader :pos
24
-
25
- # Creates a new wrapper that encapsulates the given +handle+ (such as
26
- # would be returned by Net::SFTP::Session#open!). The +sftp+ parameter
27
- # must be the same Net::SFTP::Session instance that opened the file.
28
- def initialize(sftp, handle)
29
- @sftp = sftp
30
- @handle = handle
31
- @pos = 0
32
- @real_pos = 0
33
- @real_eof = false
34
- @buffer = ""
35
- end
36
-
37
- # Repositions the file pointer to the given offset (relative to the
38
- # start of the file). This will also reset the EOF flag.
39
- def pos=(offset)
40
- @real_pos = @pos = offset
41
- @buffer = ""
42
- @real_eof = false
43
- end
44
-
45
- # Closes the underlying file and sets the handle to +nil+. Subsequent
46
- # operations on this object will fail.
47
- def close
48
- sftp.close!(handle)
49
- @handle = nil
50
- end
51
-
52
- # Returns true if the end of the file has been encountered by a previous
53
- # read. Setting the current file position via #pos= will reset this
54
- # flag (useful if the file's contents have changed since the EOF was
55
- # encountered).
56
- def eof?
57
- @real_eof && @buffer.empty?
58
- end
59
-
60
- # Reads up to +n+ bytes of data from the stream. Fewer bytes will be
61
- # returned if EOF is encountered before the requested number of bytes
62
- # could be read. Without an argument (or with a nil argument) all data
63
- # to the end of the file will be read and returned.
64
- #
65
- # This will advance the file pointer (#pos).
66
- def read(n=nil)
67
- loop do
68
- break if n && @buffer.length >= n
69
- break unless fill
70
- end
71
-
72
- if n
73
- result, @buffer = @buffer[0,n], (@buffer[n..-1] || "")
74
- else
75
- result, @buffer = @buffer, ""
76
- end
77
-
78
- @pos += result.length
79
- return result
80
- end
81
-
82
- # Reads up to the next instance of +sep_string+ in the stream, and
83
- # returns the bytes read (including +sep_string+). If +sep_string+ is
84
- # omitted, it defaults to +$/+. If EOF is encountered before any data
85
- # could be read, #gets will return +nil+.
86
- def gets(sep_string=$/)
87
- delim = if sep_string.length == 0
88
- "#{$/}#{$/}"
89
- else
90
- sep_string
91
- end
92
-
93
- loop do
94
- at = @buffer.index(delim)
95
- if at
96
- offset = at + delim.length
97
- @pos += offset
98
- line, @buffer = @buffer[0,offset], @buffer[offset..-1]
99
- return line
100
- elsif !fill
101
- return nil if @buffer.empty?
102
- @pos += @buffer.length
103
- line, @buffer = @buffer, ""
104
- return line
105
- end
106
- end
107
- end
108
-
109
- # Same as #gets, but raises EOFError if EOF is encountered before any
110
- # data could be read.
111
- def readline(sep_string=$/)
112
- line = gets(sep_string)
113
- raise EOFError if line.nil?
114
- return line
115
- end
116
-
117
- # Writes the given data to the stream, incrementing the file position and
118
- # returning the number of bytes written.
119
- def write(data)
120
- data = data.to_s
121
- sftp.write!(handle, @real_pos, data)
122
- @real_pos += data.length
123
- @pos = @real_pos
124
- data.length
125
- end
126
-
127
- # Writes each argument to the stream. If +$\+ is set, it will be written
128
- # after all arguments have been written.
129
- def print(*items)
130
- items.each { |item| write(item) }
131
- write($\) if $\
132
- nil
133
- end
134
-
135
- # Writes each argument to the stream, appending a newline to any item
136
- # that does not already end in a newline. Array arguments are flattened.
137
- def puts(*items)
138
- items.each do |item|
139
- if Array === item
140
- puts(*item)
141
- else
142
- write(item)
143
- write("\n") unless item[-1] == ?\n
144
- end
145
- end
146
- nil
147
- end
148
-
149
- # Performs an fstat operation on the handle and returns the attribute
150
- # object (Net::SFTP::Protocol::V01::Attributes, Net::SFTP::Protool::V04::Attributes,
151
- # or Net::SFTP::Protocol::V06::Attributes, depending on the SFTP protocol
152
- # version in use).
153
- def stat
154
- sftp.fstat!(handle)
155
- end
156
-
157
- private
158
-
159
- # Fills the buffer. Returns +true+ if it succeeded, and +false+ if
160
- # EOF was encountered before any data was read.
161
- def fill
162
- data = sftp.read!(handle, @real_pos, 8192)
163
-
164
- if data.nil?
165
- @real_eof = true
166
- return false
167
- else
168
- @real_pos += data.length
169
- @buffer << data
170
- end
171
-
172
- !@real_eof
173
- end
174
- end
175
-
176
- end; end; end
@@ -1,60 +0,0 @@
1
- require 'net/ssh/loggable'
2
- require 'net/sftp/operations/file'
3
-
4
- module Net; module SFTP; module Operations
5
-
6
- # A factory class for opening files and returning Operations::File instances
7
- # that wrap the SFTP handles that represent them. This is a convenience
8
- # class for use when working with files synchronously. Rather than relying
9
- # on the programmer to provide callbacks that define a state machine that
10
- # describes the behavior of the program, this class (and Operations::File)
11
- # provide an interface where calls will block until they return, mimicking
12
- # the IO class' interface.
13
- class FileFactory
14
- # The SFTP session object that drives this file factory.
15
- attr_reader :sftp
16
-
17
- # Create a new instance on top of the given SFTP session instance.
18
- def initialize(sftp)
19
- @sftp = sftp
20
- end
21
-
22
- # :call-seq:
23
- # open(name, flags="r", mode=nil) -> file
24
- # open(name, flags="r", mode=nil) { |file| ... }
25
- #
26
- # Attempt to open a file on the remote server. The +flags+ parameter
27
- # accepts the same values as the standard Ruby ::File#open method. The
28
- # +mode+ parameter must be an integer describing the permissions to use
29
- # if a new file is being created.
30
- #
31
- # If a block is given, the new Operations::File instance will be yielded
32
- # to it, and closed automatically when the block terminates. Otherwise
33
- # the object will be returned, and it is the caller's responsibility to
34
- # close the file.
35
- #
36
- # sftp.file.open("/tmp/names.txt", "w") do |f|
37
- # # ...
38
- # end
39
- def open(name, flags="r", mode=nil, &block)
40
- handle = sftp.open!(name, flags, :permissions => mode)
41
- file = Operations::File.new(sftp, handle)
42
-
43
- if block_given?
44
- begin
45
- yield file
46
- ensure
47
- file.close
48
- end
49
- else
50
- return file
51
- end
52
- end
53
-
54
- # Returns +true+ if the argument refers to a directory on the remote host.
55
- def directory?(path)
56
- sftp.lstat!(path).directory?
57
- end
58
- end
59
-
60
- end; end; end
@@ -1,387 +0,0 @@
1
- require 'net/ssh/loggable'
2
-
3
- module Net; module SFTP; module Operations
4
-
5
- # A general purpose uploader module for Net::SFTP. It can upload IO objects,
6
- # files, and even entire directory trees via SFTP, and provides a flexible
7
- # progress reporting mechanism.
8
- #
9
- # To upload a single file to the remote server, simply specify both the
10
- # local and remote paths:
11
- #
12
- # uploader = sftp.upload("/path/to/local.txt", "/path/to/remote.txt")
13
- #
14
- # By default, this operates asynchronously, so if you want to block until
15
- # the upload finishes, you can use the 'bang' variant:
16
- #
17
- # sftp.upload!("/path/to/local.txt", "/path/to/remote.txt")
18
- #
19
- # Or, if you have multiple uploads that you want to run in parallel, you can
20
- # employ the #wait method of the returned object:
21
- #
22
- # uploads = %w(file1 file2 file3).map { |f| sftp.upload(f, "remote/#{f}") }
23
- # uploads.each { |u| u.wait }
24
- #
25
- # To upload an entire directory tree, recursively, simply pass the directory
26
- # path as the first parameter:
27
- #
28
- # sftp.upload!("/path/to/directory", "/path/to/remote")
29
- #
30
- # This will upload "/path/to/directory", it's contents, it's subdirectories,
31
- # and their contents, recursively, to "/path/to/remote" on the remote server.
32
- #
33
- # If you want to send data to a file on the remote server, but the data is
34
- # in memory, you can pass an IO object and upload it's contents:
35
- #
36
- # require 'stringio'
37
- # io = StringIO.new(data)
38
- # sftp.upload!(io, "/path/to/remote")
39
- #
40
- # The following options are supported:
41
- #
42
- # * <tt>:progress</tt> - either a block or an object to act as a progress
43
- # callback. See the discussion of "progress monitoring" below.
44
- # * <tt>:requests</tt> - the number of pending SFTP requests to allow at
45
- # any given time. When uploading an entire directory tree recursively,
46
- # this will default to 16, otherwise it will default to 2. Setting this
47
- # higher might improve throughput. Reducing it will reduce throughput.
48
- # * <tt>:read_size</tt> - the maximum number of bytes to read at a time
49
- # from the source. Increasing this value might improve throughput. It
50
- # defaults to 32,000 bytes.
51
- # * <tt>:name</tt> - the filename to report to the progress monitor when
52
- # an IO object is given as +local+. This defaults to "<memory>".
53
- #
54
- # == Progress Monitoring
55
- #
56
- # Sometimes it is desirable to track the progress of an upload. There are
57
- # two ways to do this: either using a callback block, or a special custom
58
- # object.
59
- #
60
- # Using a block it's pretty straightforward:
61
- #
62
- # sftp.upload!("local", "remote") do |event, uploader, *args|
63
- # case event
64
- # when :open then
65
- # # args[0] : file metadata
66
- # puts "starting upload: #{args[0].local} -> #{args[0].remote} (#{args[0].size} bytes}"
67
- # when :put then
68
- # # args[0] : file metadata
69
- # # args[1] : byte offset in remote file
70
- # # args[2] : data being written (as string)
71
- # puts "writing #{args[2].length} bytes to #{args[0].remote} starting at #{args[1]}"
72
- # when :close then
73
- # # args[0] : file metadata
74
- # puts "finished with #{args[0].remote}"
75
- # when :mkdir then
76
- # # args[0] : remote path name
77
- # puts "creating directory #{args[0]}"
78
- # when :finish then
79
- # puts "all done!"
80
- # end
81
- #
82
- # However, for more complex implementations (e.g., GUI interfaces and such)
83
- # a block can become cumbersome. In those cases, you can create custom
84
- # handler objects that respond to certain methods, and then pass your handler
85
- # to the uploader:
86
- #
87
- # class CustomHandler
88
- # def on_open(uploader, file)
89
- # puts "starting upload: #{file.local} -> #{file.remote} (#{file.size} bytes)"
90
- # end
91
- #
92
- # def on_put(uploader, file, offset, data)
93
- # puts "writing #{data.length} bytes to #{file.remote} starting at #{offset}"
94
- # end
95
- #
96
- # def on_close(uploader, file)
97
- # puts "finished with #{file.remote}"
98
- # end
99
- #
100
- # def on_mkdir(uploader, path)
101
- # puts "creating directory #{path}"
102
- # end
103
- #
104
- # def on_finish(uploader)
105
- # puts "all done!"
106
- # end
107
- # end
108
- #
109
- # sftp.upload!("local", "remote", :progress => CustomHandler.new)
110
- #
111
- # If you omit any of those methods, the progress updates for those missing
112
- # events will be ignored. You can create a catchall method named "call" for
113
- # those, instead.
114
- class Upload
115
- include Net::SSH::Loggable
116
-
117
- # The source of the upload (on the local server)
118
- attr_reader :local
119
-
120
- # The destination of the upload (on the remote server)
121
- attr_reader :remote
122
-
123
- # The hash of options that were given when the object was instantiated
124
- attr_reader :options
125
-
126
- # The SFTP session object used by this upload instance
127
- attr_reader :sftp
128
-
129
- # The properties hash for this object
130
- attr_reader :properties
131
-
132
- # Instantiates a new uploader process on top of the given SFTP session.
133
- # +local+ is either an IO object containing data to upload, or a string
134
- # identifying a file or directory on the local host. +remote+ is a string
135
- # identifying the location on the remote host that the upload should
136
- # target.
137
- #
138
- # This will return immediately, and requires that the SSH event loop be
139
- # run in order to effect the upload. (See #wait.)
140
- def initialize(sftp, local, remote, options={}, &progress) #:nodoc:
141
- @sftp = sftp
142
- @local = local
143
- @remote = remote
144
- @progress = progress || options[:progress]
145
- @options = options
146
- @properties = options[:properties] || {}
147
- @active = 0
148
-
149
- self.logger = sftp.logger
150
-
151
- @uploads = []
152
- @recursive = local.respond_to?(:read) ? false : ::File.directory?(local)
153
-
154
- if recursive?
155
- @stack = [entries_for(local)]
156
- @local_cwd = local
157
- @remote_cwd = remote
158
-
159
- @active += 1
160
- sftp.mkdir(remote) do |response|
161
- @active -= 1
162
- raise StatusException.new(response, "mkdir `#{remote}'") unless response.ok?
163
- (options[:requests] || RECURSIVE_READERS).to_i.times do
164
- break unless process_next_entry
165
- end
166
- end
167
- else
168
- raise ArgumentError, "expected a file to upload" unless local.respond_to?(:read) || ::File.exists?(local)
169
- @stack = [[local]]
170
- process_next_entry
171
- end
172
- end
173
-
174
- # Returns true if a directory tree is being uploaded, and false if only a
175
- # single file is being uploaded.
176
- def recursive?
177
- @recursive
178
- end
179
-
180
- # Returns true if the uploader is currently running. When this is false,
181
- # the uploader has finished processing.
182
- def active?
183
- @active > 0 || @stack.any?
184
- end
185
-
186
- # Forces the transfer to stop.
187
- def abort!
188
- @active = 0
189
- @stack.clear
190
- @uploads.clear
191
- end
192
-
193
- # Blocks until the upload has completed.
194
- def wait
195
- sftp.loop { active? }
196
- self
197
- end
198
-
199
- # Returns the property with the given name. This allows Upload instances
200
- # to store their own state when used as part of a state machine.
201
- def [](name)
202
- @properties[name.to_sym]
203
- end
204
-
205
- # Sets the given property to the given name. This allows Upload instances
206
- # to store their own state when used as part of a state machine.
207
- def []=(name, value)
208
- @properties[name.to_sym] = value
209
- end
210
-
211
- private
212
-
213
- #--
214
- # "ruby -w" hates private attributes, so we have to do this longhand.
215
- #++
216
-
217
- # The progress handler for this instance. Possibly nil.
218
- def progress; @progress; end
219
-
220
- # A simple struct for recording metadata about the file currently being
221
- # uploaded.
222
- LiveFile = Struct.new(:local, :remote, :io, :size, :handle)
223
-
224
- # The default # of bytes to read from disk at a time.
225
- DEFAULT_READ_SIZE = 32_000
226
-
227
- # The number of readers to use when uploading a single file.
228
- SINGLE_FILE_READERS = 2
229
-
230
- # The number of readers to use when uploading a directory.
231
- RECURSIVE_READERS = 16
232
-
233
- # Examines the stack and determines what action to take. This is the
234
- # starting point of the state machine.
235
- def process_next_entry
236
- if @stack.empty?
237
- if @uploads.any?
238
- write_next_chunk(@uploads.first)
239
- elsif !active?
240
- update_progress(:finish)
241
- end
242
- return false
243
- elsif @stack.last.empty?
244
- @stack.pop
245
- @local_cwd = ::File.dirname(@local_cwd)
246
- @remote_cwd = ::File.dirname(@remote_cwd)
247
- process_next_entry
248
- elsif recursive?
249
- entry = @stack.last.shift
250
- lpath = ::File.join(@local_cwd, entry)
251
- rpath = ::File.join(@remote_cwd, entry)
252
-
253
- if ::File.directory?(lpath)
254
- @stack.push(entries_for(lpath))
255
- @local_cwd = lpath
256
- @remote_cwd = rpath
257
-
258
- @active += 1
259
- update_progress(:mkdir, rpath)
260
- request = sftp.mkdir(rpath, &method(:on_mkdir))
261
- request[:dir] = rpath
262
- else
263
- open_file(lpath, rpath)
264
- end
265
- else
266
- open_file(@stack.pop.first, remote)
267
- end
268
- return true
269
- end
270
-
271
- # Prepares to send +local+ to +remote+.
272
- def open_file(local, remote)
273
- @active += 1
274
-
275
- if local.respond_to?(:read)
276
- file = local
277
- name = options[:name] || "<memory>"
278
- else
279
- file = ::File.open(local, "rb")
280
- name = local
281
- end
282
-
283
- if file.respond_to?(:stat)
284
- size = file.stat.size
285
- else
286
- size = file.size
287
- end
288
-
289
- metafile = LiveFile.new(name, remote, file, size)
290
- update_progress(:open, metafile)
291
-
292
- request = sftp.open(remote, "w", &method(:on_open))
293
- request[:file] = metafile
294
- end
295
-
296
- # Called when a +mkdir+ request finishes, successfully or otherwise.
297
- # If the request failed, this will raise a StatusException, otherwise
298
- # it will call #process_next_entry to continue the state machine.
299
- def on_mkdir(response)
300
- @active -= 1
301
- dir = response.request[:dir]
302
- raise StatusException.new(response, "mkdir #{dir}") unless response.ok?
303
-
304
- process_next_entry
305
- end
306
-
307
- # Called when an +open+ request finishes. Raises StatusException if the
308
- # open failed, otherwise it calls #write_next_chunk to begin sending
309
- # data to the remote server.
310
- def on_open(response)
311
- @active -= 1
312
- file = response.request[:file]
313
- raise StatusException.new(response, "open #{file.remote}") unless response.ok?
314
-
315
- file.handle = response[:handle]
316
-
317
- @uploads << file
318
- write_next_chunk(file)
319
-
320
- if !recursive?
321
- (options[:requests] || SINGLE_FILE_READERS).to_i.times { write_next_chunk(file) }
322
- end
323
- end
324
-
325
- # Called when a +write+ request finishes. Raises StatusException if the
326
- # write failed, otherwise it calls #write_next_chunk to continue the
327
- # write.
328
- def on_write(response)
329
- @active -= 1
330
- file = response.request[:file]
331
- raise StatusException.new(response, "write #{file.remote}") unless response.ok?
332
- write_next_chunk(file)
333
- end
334
-
335
- # Called when a +close+ request finishes. Raises a StatusException if the
336
- # close failed, otherwise it calls #process_next_entry to continue the
337
- # state machine.
338
- def on_close(response)
339
- @active -= 1
340
- file = response.request[:file]
341
- raise StatusException.new(response, "close #{file.remote}") unless response.ok?
342
- process_next_entry
343
- end
344
-
345
- # Attempts to send the next chunk from the given file (where +file+ is
346
- # a LiveFile instance).
347
- def write_next_chunk(file)
348
- if file.io.nil?
349
- process_next_entry
350
- else
351
- @active += 1
352
- offset = file.io.pos
353
- data = file.io.read(options[:read_size] || DEFAULT_READ_SIZE)
354
- if data.nil?
355
- update_progress(:close, file)
356
- request = sftp.close(file.handle, &method(:on_close))
357
- request[:file] = file
358
- file.io.close
359
- file.io = nil
360
- @uploads.delete(file)
361
- else
362
- update_progress(:put, file, offset, data)
363
- request = sftp.write(file.handle, offset, data, &method(:on_write))
364
- request[:file] = file
365
- end
366
- end
367
- end
368
-
369
- # Returns all directory entries for the given path, removing the '.'
370
- # and '..' relative paths.
371
- def entries_for(local)
372
- ::Dir.entries(local).reject { |v| %w(. ..).include?(v) }
373
- end
374
-
375
- # Attempts to notify the progress monitor (if one was given) about
376
- # progress made for the given event.
377
- def update_progress(event, *args)
378
- on = "on_#{event}"
379
- if progress.respond_to?(on)
380
- progress.send(on, self, *args)
381
- elsif progress.respond_to?(:call)
382
- progress.call(event, self, *args)
383
- end
384
- end
385
- end
386
-
387
- end; end; end