net-scp 3.0.0 → 4.1.3
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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/.github/pull_request_template.md +1 -0
- data/.github/workflows/changelog.yml +18 -0
- data/.github/workflows/ci.yml +40 -0
- data/.gitignore +8 -0
- data/CHANGES.txt +32 -0
- data/CONTRIBUTING.md +33 -0
- data/Gemfile +9 -2
- data/Manifest +1 -1
- data/README.md +161 -0
- data/Rakefile +116 -12
- data/SECURITY.md +4 -0
- data/changelog.d/README.md +1 -0
- data/gemfiles/legacy.gemfile +7 -0
- data/lib/net/scp/download.rb +49 -14
- data/lib/net/scp/upload.rb +29 -1
- data/lib/net/scp/version.rb +4 -4
- data/lib/net/scp.rb +73 -13
- data/lib/uri/open-scp.rb +14 -2
- data/lib/uri/scp.rb +18 -7
- data/net-scp-public_cert.pem +19 -18
- data/net-scp.gemspec +5 -4
- data/setup.rb +19 -19
- data.tar.gz.sig +0 -0
- metadata +37 -30
- metadata.gz.sig +0 -0
- data/.travis.yml +0 -16
- data/README.rdoc +0 -124
data/lib/net/scp/upload.rb
CHANGED
|
@@ -49,7 +49,8 @@ module Net; class SCP
|
|
|
49
49
|
directive = "D%04o %d %s\n" % [mode, 0, File.basename(channel[:current])]
|
|
50
50
|
channel.send_data(directive)
|
|
51
51
|
channel[:cwd] = channel[:current]
|
|
52
|
-
|
|
52
|
+
entries = Dir.entries(channel[:current]).reject { |i| i == "." || i == ".." }
|
|
53
|
+
channel[:stack] << entries.reject { |i| skip_broken_symlink(channel, File.join(channel[:current], i)) }
|
|
53
54
|
await_response(channel, :next_item)
|
|
54
55
|
end
|
|
55
56
|
end
|
|
@@ -91,6 +92,7 @@ module Net; class SCP
|
|
|
91
92
|
# upload and moves to #upload_current_state.
|
|
92
93
|
def next_item_state(channel)
|
|
93
94
|
if channel[:stack].empty?
|
|
95
|
+
channel[:state] = :finish
|
|
94
96
|
finish_state(channel)
|
|
95
97
|
else
|
|
96
98
|
next_item = channel[:stack].last.shift
|
|
@@ -118,6 +120,32 @@ module Net; class SCP
|
|
|
118
120
|
end
|
|
119
121
|
|
|
120
122
|
channel[:size] = channel[:stat] ? channel[:stat].size : channel[:current].size
|
|
123
|
+
if channel[:current].respond_to?(:read) && channel[:current].respond_to?(:pos)
|
|
124
|
+
channel[:size] = [channel[:size] - channel[:current].pos, 0].max
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
# Returns true if +path+ is a symlink whose target doesn't exist, after
|
|
129
|
+
# logging a warning and recording it for #raise_if_entries_skipped.
|
|
130
|
+
def skip_broken_symlink(channel, path)
|
|
131
|
+
return false unless File.symlink?(path) && !File.exist?(path)
|
|
132
|
+
|
|
133
|
+
lwarn { "#{path}: broken symlink, skipping" }
|
|
134
|
+
(channel[:skipped] ||= []) << path
|
|
135
|
+
true
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
# Once the remote has closed the channel, raises a Net::SCP::Error listing
|
|
139
|
+
# the entries skipped by #skip_broken_symlink, if any.
|
|
140
|
+
def raise_if_entries_skipped(channel)
|
|
141
|
+
return unless channel.closing? && channel[:skipped]
|
|
142
|
+
|
|
143
|
+
# Cleared so it raises once, as on_process keeps calling this until the close is flushed.
|
|
144
|
+
skipped, channel[:skipped] = channel[:skipped], nil
|
|
145
|
+
# A failed remote scp is reported by start_command's exit-status check instead.
|
|
146
|
+
return unless channel[:exit].to_i.zero?
|
|
147
|
+
|
|
148
|
+
raise Net::SCP::Error, "upload incomplete, skipped broken symlinks: #{skipped.map(&:inspect).join(', ')}"
|
|
121
149
|
end
|
|
122
150
|
|
|
123
151
|
# If the :preserve option is set, send a 'T' directive and wait for the
|
data/lib/net/scp/version.rb
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
module Net
|
|
2
|
-
|
|
2
|
+
class SCP
|
|
3
3
|
# A class for describing the current version of a library. The version
|
|
4
4
|
# consists of three parts: the +major+ number, the +minor+ number, and the
|
|
5
5
|
# +tiny+ (or +patch+) number.
|
|
@@ -46,13 +46,13 @@ module Net
|
|
|
46
46
|
end
|
|
47
47
|
|
|
48
48
|
# The major component of this version of the Net::SSH library
|
|
49
|
-
MAJOR =
|
|
49
|
+
MAJOR = 4
|
|
50
50
|
|
|
51
51
|
# The minor component of this version of the Net::SSH library
|
|
52
|
-
MINOR =
|
|
52
|
+
MINOR = 1
|
|
53
53
|
|
|
54
54
|
# The tiny component of this version of the Net::SSH library
|
|
55
|
-
TINY =
|
|
55
|
+
TINY = 3
|
|
56
56
|
|
|
57
57
|
# The prerelease component of this version of the Net::SSH library
|
|
58
58
|
# nil allowed
|
data/lib/net/scp.rb
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
require 'pathname'
|
|
1
2
|
require 'stringio'
|
|
2
3
|
require 'shellwords'
|
|
3
4
|
|
|
@@ -64,7 +65,7 @@ module Net
|
|
|
64
65
|
# puts "#{name}: #{sent}/#{total}"
|
|
65
66
|
# end
|
|
66
67
|
#
|
|
67
|
-
# Whenever a new chunk of data is
|
|
68
|
+
# Whenever a new chunk of data is received for or sent to a file, the callback
|
|
68
69
|
# will be invoked, indicating the name of the file (local for downloads,
|
|
69
70
|
# remote for uploads), the number of bytes that have been sent or received
|
|
70
71
|
# so far for the file, and the size of the file.
|
|
@@ -258,13 +259,24 @@ module Net
|
|
|
258
259
|
#
|
|
259
260
|
# * :recursive - the +local+ parameter refers to a local directory, which
|
|
260
261
|
# should be uploaded to a new directory named +remote+ on the remote
|
|
261
|
-
# server.
|
|
262
|
+
# server. Broken symlinks in it are skipped with a warning, and once
|
|
263
|
+
# everything else is uploaded a Net::SCP::Error listing them is raised.
|
|
262
264
|
# * :preserve - the atime and mtime of the file should be preserved.
|
|
263
265
|
# * :verbose - the process should result in verbose output on the server
|
|
264
266
|
# end (useful for debugging).
|
|
265
267
|
# * :chunk_size - the size of each "chunk" that should be sent. Defaults
|
|
266
268
|
# to 2048. Changing this value may improve throughput at the expense
|
|
267
269
|
# of decreasing interactivity.
|
|
270
|
+
# * :quote - how +remote+ is quoted in the scp command run by the remote
|
|
271
|
+
# shell. :posix (the default) escapes it for a POSIX shell, leaving a
|
|
272
|
+
# leading "~" or "~/" unescaped so it expands to the remote home
|
|
273
|
+
# directory ("~user/" is not expanded). :windows is for Win32-OpenSSH,
|
|
274
|
+
# whose shell may be cmd.exe or PowerShell: backslashes become "/", the
|
|
275
|
+
# path is wrapped in double quotes, and paths containing a double or curly
|
|
276
|
+
# quote, $, `, %, !, CR, LF or NUL raise ArgumentError. :none sends the
|
|
277
|
+
# path unchanged, for servers that don't run a shell (some routers and
|
|
278
|
+
# appliances); never use it with untrusted input. A callable is given
|
|
279
|
+
# +remote+ and returns the string to send.
|
|
268
280
|
#
|
|
269
281
|
# This method will return immediately, returning the Net::SSH::Connection::Channel
|
|
270
282
|
# object that will support the upload. To wait for the upload to finish,
|
|
@@ -274,6 +286,10 @@ module Net
|
|
|
274
286
|
# channel = scp.upload("/local/path", "/remote/path")
|
|
275
287
|
# channel.wait
|
|
276
288
|
def upload(local, remote, options={}, &progress)
|
|
289
|
+
chunk_size = options[:chunk_size] || Upload::DEFAULT_CHUNK_SIZE
|
|
290
|
+
unless chunk_size.is_a?(Integer) && chunk_size > 0
|
|
291
|
+
raise ArgumentError, ":chunk_size must be a positive Integer"
|
|
292
|
+
end
|
|
277
293
|
start_command(:upload, local, remote, options, &progress)
|
|
278
294
|
end
|
|
279
295
|
|
|
@@ -293,6 +309,7 @@ module Net
|
|
|
293
309
|
# * :preserve - the atime and mtime of the file should be preserved.
|
|
294
310
|
# * :verbose - the process should result in verbose output on the server
|
|
295
311
|
# end (useful for debugging).
|
|
312
|
+
# * :quote - how +remote+ is quoted for the remote shell (see #upload).
|
|
296
313
|
#
|
|
297
314
|
# This method will return immediately, returning the Net::SSH::Connection::Channel
|
|
298
315
|
# object that will support the download. To wait for the download to finish,
|
|
@@ -329,7 +346,7 @@ module Net
|
|
|
329
346
|
# (:verbose, :recursive, :preserve). Returns the command-line as a
|
|
330
347
|
# string, ready to execute.
|
|
331
348
|
def scp_command(mode, options)
|
|
332
|
-
command = "scp "
|
|
349
|
+
command = +"scp "
|
|
333
350
|
command << (mode == :upload ? "-t" : "-f")
|
|
334
351
|
command << " -v" if options[:verbose]
|
|
335
352
|
command << " -r" if options[:recursive]
|
|
@@ -342,15 +359,15 @@ module Net
|
|
|
342
359
|
# sets up a state machine to use to process the upload or download.
|
|
343
360
|
# (See Net::SCP::Upload and Net::SCP::Download).
|
|
344
361
|
def start_command(mode, local, remote, options={}, &callback)
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
end
|
|
362
|
+
local = local.to_path if local.is_a?(Pathname)
|
|
363
|
+
# Kept in channel[:remote] too, so a download's basename check sees "C:/a/b.txt" as b.txt.
|
|
364
|
+
remote = remote.to_s.tr("\\", "/") if options[:quote] == :windows
|
|
365
|
+
command = "#{scp_command(mode, options)} #{quote_remote(remote, options[:quote] || :posix)}"
|
|
366
|
+
if options[:shell]
|
|
367
|
+
command = "#{options[:shell]} -c '#{command.gsub("'") { "'\\''" }}'"
|
|
368
|
+
end
|
|
353
369
|
|
|
370
|
+
session.open_channel do |channel|
|
|
354
371
|
channel.exec(command) do |ch, success|
|
|
355
372
|
if success
|
|
356
373
|
channel[:local ] = local
|
|
@@ -360,9 +377,28 @@ module Net
|
|
|
360
377
|
channel[:buffer ] = Net::SSH::Buffer.new
|
|
361
378
|
channel[:state ] = "#{mode}_start"
|
|
362
379
|
channel[:stack ] = []
|
|
363
|
-
channel[:error_string] = ''
|
|
380
|
+
channel[:error_string] = +''
|
|
364
381
|
|
|
365
|
-
channel.on_close
|
|
382
|
+
channel.on_close do
|
|
383
|
+
begin
|
|
384
|
+
# The close can be dispatched before on_process has consumed data that arrived with it.
|
|
385
|
+
send("#{channel[:state]}_state", channel)
|
|
386
|
+
# If we got an exit-status and it is not 0, something went wrong
|
|
387
|
+
if !channel[:exit].nil? && channel[:exit] != 0
|
|
388
|
+
raise Net::SCP::Error, 'SCP did not finish successfully ' \
|
|
389
|
+
"(#{channel[:exit]}): #{channel[:error_string]}"
|
|
390
|
+
end
|
|
391
|
+
# A zero or missing exit-status does not prove the transfer completed.
|
|
392
|
+
if channel[:state] != :finish
|
|
393
|
+
message = +'SCP did not finish successfully (channel closed before end of transmission)'
|
|
394
|
+
message << ": #{channel[:error_string]}" unless channel[:error_string].empty?
|
|
395
|
+
raise Net::SCP::Error, message
|
|
396
|
+
end
|
|
397
|
+
ensure
|
|
398
|
+
io = channel[:io]
|
|
399
|
+
io.close if io && io != channel[:local] && !io.closed?
|
|
400
|
+
end
|
|
401
|
+
end
|
|
366
402
|
channel.on_data { |ch2, data| channel[:buffer].append(data) }
|
|
367
403
|
channel.on_extended_data { |ch2, type, data| debug { data.chomp } }
|
|
368
404
|
channel.on_request("exit-status") { |ch2, data| channel[:exit] = data.read_long }
|
|
@@ -405,6 +441,7 @@ module Net
|
|
|
405
441
|
# of the pipe, and allows the pipe to drain until the server closes it.
|
|
406
442
|
def finish_state(channel)
|
|
407
443
|
channel.eof!
|
|
444
|
+
raise_if_entries_skipped(channel)
|
|
408
445
|
end
|
|
409
446
|
|
|
410
447
|
# Invoked to report progress back to the client. If a callback was not
|
|
@@ -413,6 +450,29 @@ module Net
|
|
|
413
450
|
channel[:callback].call(channel, name, sent, total) if channel[:callback]
|
|
414
451
|
end
|
|
415
452
|
|
|
453
|
+
# Inside double quotes cmd.exe still expands % and !, PowerShell expands $ and `, and PowerShell also ends a string at U+2018..U+201E.
|
|
454
|
+
WINDOWS_UNSAFE = /["$`%!\r\n\0\u2018-\u201E]/
|
|
455
|
+
|
|
456
|
+
def quote_remote(remote, quote)
|
|
457
|
+
case quote
|
|
458
|
+
when :posix
|
|
459
|
+
remote = remote.to_s
|
|
460
|
+
return remote if remote == "~" || remote == "~/"
|
|
461
|
+
return "~/#{shellescape(remote[2..-1])}" if remote.start_with?("~/")
|
|
462
|
+
shellescape(remote)
|
|
463
|
+
when :windows
|
|
464
|
+
if remote.dup.force_encoding(Encoding::UTF_8) =~ WINDOWS_UNSAFE
|
|
465
|
+
raise ArgumentError, "remote path #{remote.inspect} contains a character that can't be quoted safely for a Windows shell"
|
|
466
|
+
end
|
|
467
|
+
"\"#{remote}\""
|
|
468
|
+
when :none
|
|
469
|
+
remote.to_s
|
|
470
|
+
else
|
|
471
|
+
raise ArgumentError, ":quote must be :posix, :windows, :none or a callable, got #{quote.inspect}" unless quote.respond_to?(:call)
|
|
472
|
+
quote.call(remote).to_s
|
|
473
|
+
end
|
|
474
|
+
end
|
|
475
|
+
|
|
416
476
|
# Imported from ruby 1.9.2 shellwords.rb
|
|
417
477
|
def shellescape(path)
|
|
418
478
|
# Convert path to a string if it isn't already one.
|
data/lib/uri/open-scp.rb
CHANGED
|
@@ -8,9 +8,21 @@ module URI
|
|
|
8
8
|
|
|
9
9
|
class SCP
|
|
10
10
|
def buffer_open(buf, proxy, open_options)
|
|
11
|
-
options = open_options.
|
|
11
|
+
options = open_options.dup
|
|
12
|
+
options[:ssh] = { :port => port }
|
|
13
|
+
options[:ssh][:password] = URI::DEFAULT_PARSER.unescape(password) if password
|
|
14
|
+
options[:ssh].merge!(open_options[:ssh] || {})
|
|
12
15
|
progress = options.delete(:progress_proc)
|
|
13
|
-
|
|
16
|
+
content_length = options.delete(:content_length_proc)
|
|
17
|
+
output = Object.new
|
|
18
|
+
output.define_singleton_method(:write) { |data| buf << data }
|
|
19
|
+
Net::SCP.download!(hostname, user && URI::DEFAULT_PARSER.unescape(user), URI::DEFAULT_PARSER.unescape(path), output, options) do |_channel, _name, received, total|
|
|
20
|
+
if content_length
|
|
21
|
+
content_length.call(total)
|
|
22
|
+
content_length = nil
|
|
23
|
+
end
|
|
24
|
+
progress.call(received) if progress
|
|
25
|
+
end
|
|
14
26
|
buf.io.rewind
|
|
15
27
|
end
|
|
16
28
|
|
data/lib/uri/scp.rb
CHANGED
|
@@ -8,11 +8,9 @@ module URI
|
|
|
8
8
|
:scheme,
|
|
9
9
|
:userinfo,
|
|
10
10
|
:host, :port, :path,
|
|
11
|
-
:query
|
|
11
|
+
:query
|
|
12
12
|
].freeze
|
|
13
13
|
|
|
14
|
-
attr_reader :options
|
|
15
|
-
|
|
16
14
|
def self.new2(user, password, host, port, path, query)
|
|
17
15
|
new('scp', [user, password], host, port, nil, path, nil, query)
|
|
18
16
|
end
|
|
@@ -20,16 +18,29 @@ module URI
|
|
|
20
18
|
def initialize(*args)
|
|
21
19
|
super(*args)
|
|
22
20
|
|
|
21
|
+
options
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def options
|
|
25
|
+
return @options if defined?(@options_query) && @options_query == query
|
|
26
|
+
|
|
27
|
+
@options_query = query && query.dup
|
|
23
28
|
@options = Hash.new
|
|
24
29
|
(query || "").split(/&/).each do |pair|
|
|
30
|
+
next if pair.empty?
|
|
25
31
|
name, value = pair.split(/=/, 2)
|
|
26
32
|
opt_name = name.to_sym
|
|
27
|
-
values = value.split(/,/).map { |v| v.to_i.to_s == v ? v.to_i : v }
|
|
33
|
+
values = value.to_s.split(/,/).map { |v| v.to_i.to_s == v ? v.to_i : v }
|
|
28
34
|
values = values.first if values.length == 1
|
|
29
|
-
options[opt_name] = values
|
|
35
|
+
@options[opt_name] = values
|
|
30
36
|
end
|
|
37
|
+
@options
|
|
31
38
|
end
|
|
32
39
|
end
|
|
33
40
|
|
|
34
|
-
|
|
35
|
-
|
|
41
|
+
if respond_to? :register_scheme
|
|
42
|
+
register_scheme "SCP", SCP
|
|
43
|
+
else
|
|
44
|
+
@@schemes["SCP"] = SCP
|
|
45
|
+
end
|
|
46
|
+
end
|
data/net-scp-public_cert.pem
CHANGED
|
@@ -1,20 +1,21 @@
|
|
|
1
1
|
-----BEGIN CERTIFICATE-----
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
2
|
+
MIIDeDCCAmCgAwIBAgIBATANBgkqhkiG9w0BAQsFADBBMQ8wDQYDVQQDDAZuZXRz
|
|
3
|
+
c2gxGTAXBgoJkiaJk/IsZAEZFglzb2x1dGlvdXMxEzARBgoJkiaJk/IsZAEZFgNj
|
|
4
|
+
b20wHhcNMjYwNTE2MTYyMDUzWhcNMjcwNTE2MTYyMDUzWjBBMQ8wDQYDVQQDDAZu
|
|
5
|
+
ZXRzc2gxGTAXBgoJkiaJk/IsZAEZFglzb2x1dGlvdXMxEzARBgoJkiaJk/IsZAEZ
|
|
6
|
+
FgNjb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDGJ4TbZ9H+qZ08
|
|
7
|
+
pQfJhPJTHaDCyQvCsKTFrL5O9z3tllQ7B/zksMMM+qFBpNYu9HCcg4yBATacE/PB
|
|
8
|
+
qVVyUrpr6lbH/XwoN5ljXm+bdCfmnjZvTCL2FTE6o+bcnaF0IsJyC0Q2B1fbWdXN
|
|
9
|
+
6Off1ZWoUk6We2BIM1bn6QJLxBpGyYhvOPXsYoqSuzDf2SJDDsWFZ8kV5ON13Ohm
|
|
10
|
+
JbBzn0oD8HF8FuYOewwsC0C1q4w7E5GtvHcQ5juweS7+RKsyDcVcVrLuNzoGRttS
|
|
11
|
+
KP4yMn+TzaXijyjRg7gECfJr3TGASaA4bQsILFGG5dAWcwO4OMrZedR7SHj/o0Kf
|
|
12
|
+
3gL7P0axAgMBAAGjezB5MAkGA1UdEwQCMAAwCwYDVR0PBAQDAgSwMB0GA1UdDgQW
|
|
13
|
+
BBQF8qLA7Z4zg0SJGtUbv3eoQ8tjIzAfBgNVHREEGDAWgRRuZXRzc2hAc29sdXRp
|
|
14
|
+
b3VzLmNvbTAfBgNVHRIEGDAWgRRuZXRzc2hAc29sdXRpb3VzLmNvbTANBgkqhkiG
|
|
15
|
+
9w0BAQsFAAOCAQEAVx/yCCX0ZPQ8TFeZe1T+OBEn3Co/AfjAmCdhstf1TF+Jziyx
|
|
16
|
+
dFJ8m8mF4596gru87Mi8mvu+WbPsLlFMOf5LDUkAsgnlvJ+zqNL7jPjGmsh0KOHJ
|
|
17
|
+
0dzPYnTeGcfyrp1AXNN3Z2jWlEInrnqvo376vOmejjTtmDVVlhPjITHQqLSXzRaQ
|
|
18
|
+
e3M8fbJ+nupobti6jpXCYvH86KtpaxF66mwaynfdjzxQAVycV/ilKtL+sHH8zxlg
|
|
19
|
+
vNiMFH5yLu/tlav4xh+HlYscWVdFQIvd7f/Uxa+Vip1Pi16wmhnrE15z/vDX921v
|
|
20
|
+
hukBRIoCEAuUgNVBh+L/C8aETzbf/77WU3Si/w==
|
|
20
21
|
-----END CERTIFICATE-----
|
data/net-scp.gemspec
CHANGED
|
@@ -17,13 +17,14 @@ Gem::Specification.new do |spec|
|
|
|
17
17
|
spec.homepage = "https://github.com/net-ssh/net-scp"
|
|
18
18
|
spec.license = "MIT"
|
|
19
19
|
spec.required_rubygems_version = Gem::Requirement.new(">= 0") if spec.respond_to? :required_rubygems_version=
|
|
20
|
+
spec.required_ruby_version = ">= 2.3"
|
|
20
21
|
spec.metadata = {
|
|
21
22
|
"changelog_uri" => "https://github.com/net-ssh/net-scp/blob/master/CHANGES.txt"
|
|
22
23
|
}
|
|
23
24
|
|
|
24
25
|
spec.extra_rdoc_files = [
|
|
25
26
|
"LICENSE.txt",
|
|
26
|
-
"README.
|
|
27
|
+
"README.md"
|
|
27
28
|
]
|
|
28
29
|
|
|
29
30
|
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
|
@@ -33,16 +34,16 @@ Gem::Specification.new do |spec|
|
|
|
33
34
|
spec.specification_version = 3
|
|
34
35
|
|
|
35
36
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
|
36
|
-
spec.add_runtime_dependency(%q<net-ssh>, [">= 2.6.5", "<
|
|
37
|
+
spec.add_runtime_dependency(%q<net-ssh>, [">= 2.6.5", "< 9.0.0"])
|
|
37
38
|
spec.add_development_dependency(%q<test-unit>, [">= 0"])
|
|
38
39
|
spec.add_development_dependency(%q<mocha>, [">= 0"])
|
|
39
40
|
else
|
|
40
|
-
spec.add_dependency(%q<net-ssh>, [">= 2.6.5", "<
|
|
41
|
+
spec.add_dependency(%q<net-ssh>, [">= 2.6.5", "< 9.0.0"])
|
|
41
42
|
spec.add_dependency(%q<test-unit>, [">= 0"])
|
|
42
43
|
spec.add_dependency(%q<mocha>, [">= 0"])
|
|
43
44
|
end
|
|
44
45
|
else
|
|
45
|
-
spec.add_dependency(%q<net-ssh>, [">= 2.6.5", "<
|
|
46
|
+
spec.add_dependency(%q<net-ssh>, [">= 2.6.5", "< 9.0.0"])
|
|
46
47
|
spec.add_dependency(%q<test-unit>, [">= 0"])
|
|
47
48
|
spec.add_dependency(%q<mocha>, [">= 0"])
|
|
48
49
|
end
|
data/setup.rb
CHANGED
|
@@ -120,7 +120,7 @@ class ConfigTable
|
|
|
120
120
|
((major == 1) and
|
|
121
121
|
((minor >= 5) or
|
|
122
122
|
((minor == 4) and (teeny >= 4)))))
|
|
123
|
-
|
|
123
|
+
|
|
124
124
|
subprefix = lambda {|path|
|
|
125
125
|
path.sub(/\A#{Regexp.quote(c['prefix'])}/o, '$prefix')
|
|
126
126
|
}
|
|
@@ -172,7 +172,7 @@ class ConfigTable
|
|
|
172
172
|
'the directory for ruby scripts' ] ],
|
|
173
173
|
[ 'so-dir', [ sodir,
|
|
174
174
|
'path',
|
|
175
|
-
'the directory for ruby
|
|
175
|
+
'the directory for ruby extensions' ] ],
|
|
176
176
|
[ 'data-dir', [ '$prefix/share',
|
|
177
177
|
'path',
|
|
178
178
|
'the directory for shared data' ] ],
|
|
@@ -184,10 +184,10 @@ class ConfigTable
|
|
|
184
184
|
'the ruby program using for installation' ] ],
|
|
185
185
|
[ 'make-prog', [ makeprog,
|
|
186
186
|
'name',
|
|
187
|
-
'the make program to compile ruby
|
|
187
|
+
'the make program to compile ruby extensions' ] ],
|
|
188
188
|
[ 'without-ext', [ 'no',
|
|
189
189
|
'yes/no',
|
|
190
|
-
'does not compile/install ruby
|
|
190
|
+
'does not compile/install ruby extensions' ] ]
|
|
191
191
|
]
|
|
192
192
|
multipackage_descripters = [
|
|
193
193
|
[ 'with', [ '',
|
|
@@ -303,7 +303,7 @@ class ConfigTable
|
|
|
303
303
|
unless ConfigTable.config_key?(k)
|
|
304
304
|
@table[k] = v
|
|
305
305
|
end
|
|
306
|
-
|
|
306
|
+
|
|
307
307
|
def [](key)
|
|
308
308
|
return nil unless @table[key]
|
|
309
309
|
@table[key].gsub(%r<\$([^/]+)>) { self[$1] }
|
|
@@ -479,7 +479,7 @@ module FileOperations
|
|
|
479
479
|
def ruby(str)
|
|
480
480
|
command config('ruby-prog') + ' ' + str
|
|
481
481
|
end
|
|
482
|
-
|
|
482
|
+
|
|
483
483
|
def make(task = '')
|
|
484
484
|
command config('make-prog') + ' ' + task
|
|
485
485
|
end
|
|
@@ -572,7 +572,7 @@ module HookScriptAPI
|
|
|
572
572
|
def srcdirectory?(path)
|
|
573
573
|
File.dir?(srcfile(path))
|
|
574
574
|
end
|
|
575
|
-
|
|
575
|
+
|
|
576
576
|
def srcfile?(path)
|
|
577
577
|
File.file? srcfile(path)
|
|
578
578
|
end
|
|
@@ -606,10 +606,10 @@ class ToplevelInstaller
|
|
|
606
606
|
TASKS = [
|
|
607
607
|
[ 'config', 'saves your configurations' ],
|
|
608
608
|
[ 'show', 'shows current configuration' ],
|
|
609
|
-
[ 'setup', 'compiles ruby
|
|
609
|
+
[ 'setup', 'compiles ruby extensions and others' ],
|
|
610
610
|
[ 'install', 'installs files' ],
|
|
611
|
-
[ 'clean', "does `make clean' for each
|
|
612
|
-
[ 'distclean',"does `make distclean' for each
|
|
611
|
+
[ 'clean', "does `make clean' for each extension" ],
|
|
612
|
+
[ 'distclean',"does `make distclean' for each extension" ]
|
|
613
613
|
]
|
|
614
614
|
|
|
615
615
|
def ToplevelInstaller.invoke
|
|
@@ -708,7 +708,7 @@ class ToplevelInstaller
|
|
|
708
708
|
when '-v', '--version'
|
|
709
709
|
puts "#{File.basename($0)} version #{Version}"
|
|
710
710
|
exit 0
|
|
711
|
-
|
|
711
|
+
|
|
712
712
|
when '--copyright'
|
|
713
713
|
puts Copyright
|
|
714
714
|
exit 0
|
|
@@ -911,7 +911,7 @@ class ToplevelInstallerMulti < ToplevelInstaller
|
|
|
911
911
|
|
|
912
912
|
def print_usage(f)
|
|
913
913
|
super
|
|
914
|
-
f.puts '
|
|
914
|
+
f.puts 'Included packages:'
|
|
915
915
|
f.puts ' ' + @packages.sort.join(' ')
|
|
916
916
|
f.puts
|
|
917
917
|
end
|
|
@@ -1146,7 +1146,7 @@ class Installer
|
|
|
1146
1146
|
|
|
1147
1147
|
def install_dir_ext(rel)
|
|
1148
1148
|
return unless extdir?(curr_srcdir())
|
|
1149
|
-
install_files
|
|
1149
|
+
install_files ruby_extensions('.'),
|
|
1150
1150
|
"#{config('so-dir')}/#{File.dirname(rel)}",
|
|
1151
1151
|
0555
|
|
1152
1152
|
end
|
|
@@ -1165,9 +1165,9 @@ class Installer
|
|
|
1165
1165
|
def ruby_scripts
|
|
1166
1166
|
collect_filenames_auto().select {|n| /\.rb\z/ =~ n || "module.yml" == n }
|
|
1167
1167
|
end
|
|
1168
|
-
|
|
1168
|
+
|
|
1169
1169
|
# picked up many entries from cvs-1.11.1/src/ignore.c
|
|
1170
|
-
reject_patterns = %w(
|
|
1170
|
+
reject_patterns = %w(
|
|
1171
1171
|
core RCSLOG tags TAGS .make.state
|
|
1172
1172
|
.nse_depinfo #* .#* cvslog.* ,* .del-* *.olb
|
|
1173
1173
|
*~ *.old *.bak *.BAK *.orig *.rej _$* *$
|
|
@@ -1212,14 +1212,14 @@ class Installer
|
|
|
1212
1212
|
}
|
|
1213
1213
|
end
|
|
1214
1214
|
|
|
1215
|
-
def
|
|
1216
|
-
|
|
1217
|
-
raise InstallError, "no ruby
|
|
1215
|
+
def ruby_extensions(dir)
|
|
1216
|
+
_ruby_extensions(dir) or
|
|
1217
|
+
raise InstallError, "no ruby extension exists: 'ruby #{$0} setup' first"
|
|
1218
1218
|
end
|
|
1219
1219
|
|
|
1220
1220
|
DLEXT = /\.#{ ::Config::CONFIG['DLEXT'] }\z/
|
|
1221
1221
|
|
|
1222
|
-
def
|
|
1222
|
+
def _ruby_extensions(dir)
|
|
1223
1223
|
Dir.open(dir) {|d|
|
|
1224
1224
|
return d.select {|fname| DLEXT =~ fname }
|
|
1225
1225
|
}
|
data.tar.gz.sig
CHANGED
|
Binary file
|
metadata
CHANGED
|
@@ -1,37 +1,38 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: net-scp
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 4.1.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Jamis Buck
|
|
8
8
|
- Delano Mandelbaum
|
|
9
9
|
- Miklós Fazekas
|
|
10
|
-
autorequire:
|
|
10
|
+
autorequire:
|
|
11
11
|
bindir: bin
|
|
12
12
|
cert_chain:
|
|
13
13
|
- |
|
|
14
14
|
-----BEGIN CERTIFICATE-----
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
15
|
+
MIIDeDCCAmCgAwIBAgIBATANBgkqhkiG9w0BAQsFADBBMQ8wDQYDVQQDDAZuZXRz
|
|
16
|
+
c2gxGTAXBgoJkiaJk/IsZAEZFglzb2x1dGlvdXMxEzARBgoJkiaJk/IsZAEZFgNj
|
|
17
|
+
b20wHhcNMjYwNTE2MTYyMDUzWhcNMjcwNTE2MTYyMDUzWjBBMQ8wDQYDVQQDDAZu
|
|
18
|
+
ZXRzc2gxGTAXBgoJkiaJk/IsZAEZFglzb2x1dGlvdXMxEzARBgoJkiaJk/IsZAEZ
|
|
19
|
+
FgNjb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDGJ4TbZ9H+qZ08
|
|
20
|
+
pQfJhPJTHaDCyQvCsKTFrL5O9z3tllQ7B/zksMMM+qFBpNYu9HCcg4yBATacE/PB
|
|
21
|
+
qVVyUrpr6lbH/XwoN5ljXm+bdCfmnjZvTCL2FTE6o+bcnaF0IsJyC0Q2B1fbWdXN
|
|
22
|
+
6Off1ZWoUk6We2BIM1bn6QJLxBpGyYhvOPXsYoqSuzDf2SJDDsWFZ8kV5ON13Ohm
|
|
23
|
+
JbBzn0oD8HF8FuYOewwsC0C1q4w7E5GtvHcQ5juweS7+RKsyDcVcVrLuNzoGRttS
|
|
24
|
+
KP4yMn+TzaXijyjRg7gECfJr3TGASaA4bQsILFGG5dAWcwO4OMrZedR7SHj/o0Kf
|
|
25
|
+
3gL7P0axAgMBAAGjezB5MAkGA1UdEwQCMAAwCwYDVR0PBAQDAgSwMB0GA1UdDgQW
|
|
26
|
+
BBQF8qLA7Z4zg0SJGtUbv3eoQ8tjIzAfBgNVHREEGDAWgRRuZXRzc2hAc29sdXRp
|
|
27
|
+
b3VzLmNvbTAfBgNVHRIEGDAWgRRuZXRzc2hAc29sdXRpb3VzLmNvbTANBgkqhkiG
|
|
28
|
+
9w0BAQsFAAOCAQEAVx/yCCX0ZPQ8TFeZe1T+OBEn3Co/AfjAmCdhstf1TF+Jziyx
|
|
29
|
+
dFJ8m8mF4596gru87Mi8mvu+WbPsLlFMOf5LDUkAsgnlvJ+zqNL7jPjGmsh0KOHJ
|
|
30
|
+
0dzPYnTeGcfyrp1AXNN3Z2jWlEInrnqvo376vOmejjTtmDVVlhPjITHQqLSXzRaQ
|
|
31
|
+
e3M8fbJ+nupobti6jpXCYvH86KtpaxF66mwaynfdjzxQAVycV/ilKtL+sHH8zxlg
|
|
32
|
+
vNiMFH5yLu/tlav4xh+HlYscWVdFQIvd7f/Uxa+Vip1Pi16wmhnrE15z/vDX921v
|
|
33
|
+
hukBRIoCEAuUgNVBh+L/C8aETzbf/77WU3Si/w==
|
|
33
34
|
-----END CERTIFICATE-----
|
|
34
|
-
date:
|
|
35
|
+
date: 2026-10-27 00:00:00.000000000 Z
|
|
35
36
|
dependencies:
|
|
36
37
|
- !ruby/object:Gem::Dependency
|
|
37
38
|
name: net-ssh
|
|
@@ -42,7 +43,7 @@ dependencies:
|
|
|
42
43
|
version: 2.6.5
|
|
43
44
|
- - "<"
|
|
44
45
|
- !ruby/object:Gem::Version
|
|
45
|
-
version:
|
|
46
|
+
version: 9.0.0
|
|
46
47
|
type: :runtime
|
|
47
48
|
prerelease: false
|
|
48
49
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -52,7 +53,7 @@ dependencies:
|
|
|
52
53
|
version: 2.6.5
|
|
53
54
|
- - "<"
|
|
54
55
|
- !ruby/object:Gem::Version
|
|
55
|
-
version:
|
|
56
|
+
version: 9.0.0
|
|
56
57
|
- !ruby/object:Gem::Dependency
|
|
57
58
|
name: test-unit
|
|
58
59
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -88,16 +89,22 @@ executables: []
|
|
|
88
89
|
extensions: []
|
|
89
90
|
extra_rdoc_files:
|
|
90
91
|
- LICENSE.txt
|
|
91
|
-
- README.
|
|
92
|
+
- README.md
|
|
92
93
|
files:
|
|
94
|
+
- ".github/pull_request_template.md"
|
|
95
|
+
- ".github/workflows/changelog.yml"
|
|
96
|
+
- ".github/workflows/ci.yml"
|
|
93
97
|
- ".gitignore"
|
|
94
|
-
- ".travis.yml"
|
|
95
98
|
- CHANGES.txt
|
|
99
|
+
- CONTRIBUTING.md
|
|
96
100
|
- Gemfile
|
|
97
101
|
- LICENSE.txt
|
|
98
102
|
- Manifest
|
|
99
|
-
- README.
|
|
103
|
+
- README.md
|
|
100
104
|
- Rakefile
|
|
105
|
+
- SECURITY.md
|
|
106
|
+
- changelog.d/README.md
|
|
107
|
+
- gemfiles/legacy.gemfile
|
|
101
108
|
- lib/net/scp.rb
|
|
102
109
|
- lib/net/scp/download.rb
|
|
103
110
|
- lib/net/scp/errors.rb
|
|
@@ -113,7 +120,7 @@ licenses:
|
|
|
113
120
|
- MIT
|
|
114
121
|
metadata:
|
|
115
122
|
changelog_uri: https://github.com/net-ssh/net-scp/blob/master/CHANGES.txt
|
|
116
|
-
post_install_message:
|
|
123
|
+
post_install_message:
|
|
117
124
|
rdoc_options: []
|
|
118
125
|
require_paths:
|
|
119
126
|
- lib
|
|
@@ -121,15 +128,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
121
128
|
requirements:
|
|
122
129
|
- - ">="
|
|
123
130
|
- !ruby/object:Gem::Version
|
|
124
|
-
version: '
|
|
131
|
+
version: '2.3'
|
|
125
132
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
126
133
|
requirements:
|
|
127
134
|
- - ">="
|
|
128
135
|
- !ruby/object:Gem::Version
|
|
129
136
|
version: '0'
|
|
130
137
|
requirements: []
|
|
131
|
-
rubygems_version: 3.
|
|
132
|
-
signing_key:
|
|
138
|
+
rubygems_version: 3.3.3
|
|
139
|
+
signing_key:
|
|
133
140
|
specification_version: 3
|
|
134
141
|
summary: A pure Ruby implementation of the SCP client protocol.
|
|
135
142
|
test_files: []
|
metadata.gz.sig
CHANGED
|
Binary file
|
data/.travis.yml
DELETED