diff --git a/src/channel.cr b/src/channel.cr index b1eab2a..1b00b9f 100644 --- a/src/channel.cr +++ b/src/channel.cr @@ -109,7 +109,15 @@ class SSH2::Channel < IO return 0 if eof? read(0, slice) end - + def read(slice : Slice(UInt32)) + return 0 if eof? + read(0, slice) + end + def read(slice : Slice(UInt64)) + return 0 if eof? + read(0, slice) + end + def write(slice : Slice(UInt8)) write(0, slice) end diff --git a/src/session.cr b/src/session.cr index 3f0d64e..78861b8 100644 --- a/src/session.cr +++ b/src/session.cr @@ -282,14 +282,14 @@ class SSH2::Session # Send a file to the remote host via SCP. def scp_send(path, mode, size, mtime, atime) handle = LibSSH2.scp_send(self, path, mode.to_i32, size.to_u64, - LibC::TimeT.new(mtime), LibC::TimeT.new(atime)) +mtime,atime) #LibC::TimeT.new(mtime), LibC::TimeT.new(atime)) check_error(LibSSH2.session_last_errno(self)) Channel.new self, handle end # Send a file to the remote host via SCP. # A new channel is passed to the block and closed afterwards. - def scp_send(path, mode, size, mtime = Time.now.epoch, atime = Time.now.epoch) + def scp_send(path, mode, size, mtime = Time.now.to_unix, atime = Time.now.to_unix) channel = scp_send(path, mode, size, mtime, atime) begin yield channel @@ -310,6 +310,17 @@ class SSH2::Session end end end + # Send a file from a local filesystem to the remote host via SCP. + def scp_send_file(path,localpath) + if LibC.stat(localpath, out stat) != 0 + raise Errno.new("Unable to get stat for '#{path}'") + end + scp_send(path, (stat.st_mode & 0x3ff).to_i32, stat.st_size.to_u64) do |ch| + File.open(localpath, "r") do |f| + IO.copy(f, ch) + end + end + end # Request a file from the remote host via SCP. def scp_recv(path) @@ -331,7 +342,7 @@ class SSH2::Session # Download a file from the remote host via SCP to the local filesystem. def scp_recv_file(path, local_path = path) - min = -> (x : Int32|Int64, y : Int32|Int64) { x < y ? x : y} + min = -> (x : Int64|Int32, y : Int64|Int32) { x < y ? x : y} # libssh2 scp_recv method has a bug where its channel's read method doesn't # return 0 value to indicate the end of file(EOF). The only way to find EOF @@ -341,12 +352,13 @@ class SSH2::Session file_size = stat.st_size read_bytes = 0 File.open(local_path, "w") do |f| - buf = uninitialized UInt8[1024] + buf = StaticArray(UInt8, 1024).new(0) # => 42#uninitialized UInt8[1024] while read_bytes < file_size - bytes_to_read = min.call(buf.length, file_size - read_bytes) - len = ch.read(buf.to_slice, bytes_to_read).to_i32 - f.write(buf.to_slice, len) +bytes_to_read = min.call(buf.size, file_size - read_bytes).to_i32 +buf2 = Slice(UInt8).new( bytes_to_read) + len = ch.read(buf2).to_i32 break if len <= 0 + f.write buf2.to_slice read_bytes += len end end