Skip to content
This repository was archived by the owner on Aug 21, 2023. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion src/channel.cr
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
def read(slice : Slice(UInt64))
def read(slice : Slice(UInt64))

return 0 if eof?
read(0, slice)
end

def write(slice : Slice(UInt8))
write(0, slice)
end
Expand Down
26 changes: 19 additions & 7 deletions src/session.cr
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)
Expand All @@ -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
Expand All @@ -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
Expand Down