From b468289de8d8b04a8cfcc351b1dc13b116e96563 Mon Sep 17 00:00:00 2001 From: JamesWrigley Date: Fri, 6 Dec 2024 14:52:43 +0100 Subject: [PATCH 1/4] Don't store a copy of SSH_OPTIONS_KNOWNHOSTS --- docs/src/changelog.md | 5 +++++ src/session.jl | 5 ++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/docs/src/changelog.md b/docs/src/changelog.md index 2d82772..1a0c8e7 100644 --- a/docs/src/changelog.md +++ b/docs/src/changelog.md @@ -7,6 +7,11 @@ CurrentModule = LibSSH This documents notable changes in LibSSH.jl. The format is based on [Keep a Changelog](https://keepachangelog.com). +## Unreleased + +### Fixed +- Fixed behaviour of the [`Session`](@ref)`.known_hosts` property ([#30]). + ## [v0.7.0] - 2024-10-25 ### Added diff --git a/src/session.jl b/src/session.jl index 6d6efef..35aabae 100644 --- a/src/session.jl +++ b/src/session.jl @@ -24,7 +24,6 @@ mutable struct Session log_verbosity::Int ssh_dir::Union{String, Nothing} - known_hosts::Union{String, Nothing} gssapi_server_identity::Union{String, Nothing} process_config::Bool @@ -69,7 +68,7 @@ mutable struct Session lib.ssh_set_blocking(ptr, 0) session = new(ptr, own, [], nothing, - -1, nothing, nothing, nothing, true, + -1, nothing, nothing, true, ReentrantLock(), nothing, AuthMethod[], true, Threads.Event(true), CloseableCondition(), false) @@ -311,7 +310,7 @@ const SESSION_PROPERTY_OPTIONS = Dict(:host => (SSH_OPTIONS_HOST, Cstring), :process_config => (SSH_OPTIONS_PROCESS_CONFIG, Bool)) # These properties cannot be retrieved from the libssh API (i.e. with # ssh_options_get()), so we store them in the Session object instead. -const SAVED_PROPERTIES = (:log_verbosity, :gssapi_server_identity, :ssh_dir, :known_hosts, :process_config) +const SAVED_PROPERTIES = (:log_verbosity, :gssapi_server_identity, :ssh_dir, :process_config) function Base.propertynames(::Session, private::Bool=false) fields = fieldnames(Session) From 305150e0a890206e0e1a3c4cb7d272a927dbbac6 Mon Sep 17 00:00:00 2001 From: JamesWrigley Date: Fri, 6 Dec 2024 14:53:41 +0100 Subject: [PATCH 2/4] Allow AuthStatus_Success within the authenticate_cli() loop This should be allowed but never happened before. --- src/session.jl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/session.jl b/src/session.jl index 35aabae..5b11990 100644 --- a/src/session.jl +++ b/src/session.jl @@ -868,6 +868,8 @@ function authenticate_cli(session::Session) # We can't continue if they don't accept the key return ret end + elseif ret == AuthStatus_Success + # Do nothing else error("Unsupported return value from authenticate(): $(ret)") end From e7bff5058e0684b63bf2dace93ccab1e46a8e547 Mon Sep 17 00:00:00 2001 From: JamesWrigley Date: Fri, 6 Dec 2024 14:59:30 +0100 Subject: [PATCH 3/4] Implement Base.mkpath() for SFTP --- docs/src/changelog.md | 3 +++ docs/src/sftp.md | 1 + src/sftp.jl | 31 +++++++++++++++++++++++++++++++ test/LibSSHTests.jl | 16 ++++++++++++++++ 4 files changed, 51 insertions(+) diff --git a/docs/src/changelog.md b/docs/src/changelog.md index 1a0c8e7..5b11cbe 100644 --- a/docs/src/changelog.md +++ b/docs/src/changelog.md @@ -9,6 +9,9 @@ Changelog](https://keepachangelog.com). ## Unreleased +### Added +- Implemented [`Base.mkpath(::AbstractString, ::SftpSession)`](@ref) ([#30]). + ### Fixed - Fixed behaviour of the [`Session`](@ref)`.known_hosts` property ([#30]). diff --git a/docs/src/sftp.md b/docs/src/sftp.md index ec1a702..aa4cb00 100644 --- a/docs/src/sftp.md +++ b/docs/src/sftp.md @@ -45,6 +45,7 @@ Base.unlock(::SftpSession) Base.readdir(::AbstractString, ::SftpSession) Base.rm(::AbstractString, ::SftpSession) Base.mkdir(::AbstractString, ::SftpSession) +Base.mkpath(::AbstractString, ::SftpSession) Base.mv(::AbstractString, ::AbstractString, ::SftpSession) Base.stat(::String, ::SftpSession) get_extensions(::SftpSession) diff --git a/src/sftp.jl b/src/sftp.jl index f735502..8351566 100644 --- a/src/sftp.jl +++ b/src/sftp.jl @@ -526,6 +526,37 @@ end """ $(TYPEDSIGNATURES) +Create a remote path. This behaves in exactly the same way as `Base.mkpath()`. + +# Throws +- `ArgumentError`: If `sftp` is closed. +- [`SftpException`](@ref): If making the path fails for some reason, such as + part of `path` being an existing file. +""" +function Base.mkpath(path::AbstractString, sftp::SftpSession; mode=0o777) + if !isopen(sftp) + throw(ArgumentError("$(sftp) is closed, cannot use it to mkpath()")) + end + + parts = splitpath(path) + for i in eachindex(parts) + part= joinpath(parts[1:i]) + + try + mkdir(part, sftp; mode) + catch ex + if !(ex isa SftpException && ex.error_code == SftpError_FileAlreadyExists && isdir(part, sftp)) + rethrow() + end + end + end + + return path +end + +""" +$(TYPEDSIGNATURES) + Move `src` to `dst` remotely. Has the same behaviour as `Base.mv()`. # Throws diff --git a/test/LibSSHTests.jl b/test/LibSSHTests.jl index 46652e1..066e768 100644 --- a/test/LibSSHTests.jl +++ b/test/LibSSHTests.jl @@ -954,6 +954,21 @@ end @test_throws ssh.SftpException mkdir(path, sftp) end + # Test mkpath() + mktempdir() do tmpdir + parent_dir = joinpath(tmpdir, "foo") + path = joinpath(parent_dir, "bar") + + # Creating a path with no existing files in the name should work + @test mkpath(path, sftp) == path + @test isdir(path) + + # But if there's a file already in there we should get an exception + rm(parent_dir; force=true, recursive=true) + touch(parent_dir) + @test_throws ssh.SftpException mkpath(path, sftp) + end + # Test mv() mktempdir() do tmpdir src = joinpath(tmpdir, "foo") @@ -984,6 +999,7 @@ end @test_throws ArgumentError readdir("/tmp", sftp) @test_throws ArgumentError rm("/tmp", sftp) @test_throws ArgumentError mkdir("/tmp", sftp) + @test_throws ArgumentError mkpath("/tmp", sftp) @test_throws ArgumentError mv("foo", "bar", sftp) end end From bb1989cab55ce43cf53a3955e5ed80d2d6a1541d Mon Sep 17 00:00:00 2001 From: JamesWrigley Date: Fri, 6 Dec 2024 15:06:26 +0100 Subject: [PATCH 4/4] Bump version --- Project.toml | 2 +- docs/src/changelog.md | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Project.toml b/Project.toml index 7172c15..b90da93 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "LibSSH" uuid = "00483490-30f8-4353-8aba-35b82f51f4d0" authors = ["James Wrigley and contributors"] -version = "0.7.0" +version = "0.8.0" [deps] CEnum = "fa961155-64e5-5f13-b03f-caf6b980ea82" diff --git a/docs/src/changelog.md b/docs/src/changelog.md index 5b11cbe..201f37c 100644 --- a/docs/src/changelog.md +++ b/docs/src/changelog.md @@ -7,10 +7,12 @@ CurrentModule = LibSSH This documents notable changes in LibSSH.jl. The format is based on [Keep a Changelog](https://keepachangelog.com). -## Unreleased +## [v0.8.0] - 2024-12-06 ### Added - Implemented [`Base.mkpath(::AbstractString, ::SftpSession)`](@ref) ([#30]). +- Added support for 32-bit platforms, though only Linux is tested with that in + CI ([#29]). ### Fixed - Fixed behaviour of the [`Session`](@ref)`.known_hosts` property ([#30]).