### Starting HrrRbSftp Server Source: https://context7.com/hirura/hrr_rb_sftp/llms.txt Initialize and start the HrrRbSftp server, providing it with a logger and standard input/output/error streams. The server handles SFTP protocol negotiation and packet framing automatically. ```ruby server = HrrRbSftp::Server.new(logger: logger) server.start($stdin, $stdout, $stderr) ``` -------------------------------- ### Install hrr_rb_sftp Gem Source: https://github.com/hirura/hrr_rb_sftp/blob/master/README.md Add the gem to your application's Gemfile for installation via Bundler, or install it directly using the gem command. ```ruby gem 'hrr_rb_sftp' ``` ```bash $ bundle install ``` ```bash $ gem install hrr_rb_sftp ``` -------------------------------- ### Initialize HrrRbSftp Logging Source: https://context7.com/hirura/hrr_rb_sftp/llms.txt Demonstrates how to initialize the standard Logger and set its level for use with the HrrRbSftp::Loggable module. This setup is required for logging to function. ```ruby require "logger" require "hrr_rb_sftp" logger = Logger.new($stdout) logger.level = Logger::DEBUG ``` -------------------------------- ### Start HrrRbSftp Server in Standalone Mode Source: https://context7.com/hirura/hrr_rb_sftp/llms.txt Starts the SFTP server request/response loop, processing requests from stdin and writing responses to stdout. This script is intended to be used as a standalone SFTP subsystem. ```ruby #!/usr/bin/env ruby # hrr_rb_sftp_server.rb — standalone executable used as an SFTP subsystem require "logger" require "hrr_rb_sftp" logger = Logger.new("/var/log/hrr_rb_sftp.log") logger.level = Logger::INFO server = HrrRbSftp::Server.new(logger: logger) # Blocks until the SSH client disconnects; raises on unrecoverable errors server.start($stdin, $stdout, $stderr) ``` -------------------------------- ### HrrRbSftp::Server#start Source: https://context7.com/hirura/hrr_rb_sftp/llms.txt Starts the SFTP server request/response loop. Negotiates the SFTP protocol version with the client, then continuously reads requests from `io_in`, processes them, and writes responses to `io_out`. Blocks until the client closes the connection. ```APIDOC ## HrrRbSftp::Server#start ### Description Starts the SFTP server request/response loop. Negotiates the SFTP protocol version with the client, then continuously reads requests from `io_in`, processes them, and writes responses to `io_out`. Blocks until the client closes the connection. `io_err` is optional and used only for debug output. ### Usage ```ruby #!/usr/bin/env ruby # hrr_rb_sftp_server.rb — standalone executable used as an SFTP subsystem require "logger" require "hrr_rb_sftp" logger = Logger.new("/var/log/hrr_rb_sftp.log") logger.level = Logger::INFO server = HrrRbSftp::Server.new(logger: logger) # Blocks until the SSH client disconnects; raises on unrecoverable errors server.start($stdin, $stdout, $stderr) ``` ``` -------------------------------- ### Standalone SFTP Server Script Source: https://github.com/hirura/hrr_rb_sftp/blob/master/README.md A minimal script to run the hrr_rb_sftp server, designed to be executed as a child process. It requires the 'hrr_rb_sftp' gem and starts the server using standard I/O streams. ```ruby #!/usr/bin/env ruby require "hrr_rb_sftp" server = HrrRbSftp::Server.new(logger: nil) server.start($stdin, $stdout, $stderr) ``` -------------------------------- ### Get Supported SFTP Protocol Versions Source: https://context7.com/hirura/hrr_rb_sftp/llms.txt Use `HrrRbSftp::Protocol.versions` to retrieve a list of supported SFTP protocol version integers. The highest supported version is used as the local offer during the handshake. ```ruby require "hrr_rb_sftp" puts HrrRbSftp::Protocol.versions.inspect # => [1, 2, 3] puts HrrRbSftp::Protocol.versions.max # => 3 (highest supported version, used as the local offer) ``` -------------------------------- ### Get SFTP Protocol Extension Pairs Source: https://context7.com/hirura/hrr_rb_sftp/llms.txt Use `HrrRbSftp::Protocol.extension_pairs` to get extension name/data pairs for a given protocol version. Only version 3 supports extensions; versions 1 and 2 return an empty array. ```ruby require "hrr_rb_sftp" puts HrrRbSftp::Protocol.extension_pairs(3).inspect # => [ # { :"extension-name" => "hardlink@openssh.com", :"extension-data" => "1" }, # { :"extension-name" => "fsync@openssh.com", :"extension-data" => "1" }, # { :"extension-name" => "posix-rename@openssh.com", :"extension-data" => "1" }, # { :"extension-name" => "lsetstat@openssh.com", :"extension-data" => "1" }, # ] puts HrrRbSftp::Protocol.extension_pairs(1).inspect # => [] ``` -------------------------------- ### Instantiate HrrRbSftp::Server with Logging Source: https://context7.com/hirura/hrr_rb_sftp/llms.txt Instantiates an SFTP server object with a logger. Pass nil for logger to disable logging. ```ruby require "logger" require "hrr_rb_sftp" # With logging logger = Logger.new($stdout) logger.level = Logger::INFO server = HrrRbSftp::Server.new(logger: logger) # Without logging server_no_log = HrrRbSftp::Server.new(logger: nil) ``` -------------------------------- ### HrrRbSftp::Server.new Source: https://context7.com/hirura/hrr_rb_sftp/llms.txt Instantiates an SFTP server object. Accepts an optional Logger-compatible object; passing nil disables all logging. The server relies on external IO streams. ```APIDOC ## HrrRbSftp::Server.new ### Description Instantiates an SFTP server object. Accepts an optional `Logger`-compatible object; passing `nil` disables all logging. The server does not bind to any port itself — it relies on an external SSH layer to provide `IO` streams. ### Usage ```ruby require "logger" require "hrr_rb_sftp" # With logging logger = Logger.new($stdout) logger.level = Logger::INFO server = HrrRbSftp::Server.new(logger: logger) # Without logging server_no_log = HrrRbSftp::Server.new(logger: nil) ``` ``` -------------------------------- ### Spawn SFTP Server as Child Process with hrr_rb_ssh Source: https://github.com/hirura/hrr_rb_sftp/blob/master/README.md Configure hrr_rb_ssh to spawn hrr_rb_sftp as a child process. This allows hrr_rb_sftp to run independently, communicating via standard input/output/error streams. ```ruby subsys = HrrRbSsh::Connection::RequestHandler.new { |ctx| ctx.chain_proc { case ctx.subsystem_name when 'sftp' pid = spawn("/path/to/hrr_rb_sftp_server.rb", {in: ctx.io[0], out: ctx.io[1], err: ctx.io[2]}) exitstatus = Process.waitpid(pid).to_i else # Do something for other subsystem, or just return exitstatus exitstatus = 0 end exitstatus } } options['connection_channel_request_subsystem'] = subsys ``` -------------------------------- ### Configure OpenSSH to Use HrrRbSftp Source: https://context7.com/hirura/hrr_rb_sftp/llms.txt This is a configuration snippet for OpenSSH's `sshd_config` file. It replaces the default `sftp-server` binary with `hrr_rb_sftp_server.rb`. ```bash # /etc/ssh/sshd_config ``` -------------------------------- ### Integrating with hrr_rb_ssh (in-process mode) Source: https://context7.com/hirura/hrr_rb_sftp/llms.txt Runs the SFTP server on the same Ruby process as the SSH server by hooking into `hrr_rb_ssh`'s subsystem request handler. The SFTP server receives `IO`s directly from the SSH channel context. ```APIDOC ## Integrating with `hrr_rb_ssh` — in-process mode ### Description Runs the SFTP server on the same Ruby process as the SSH server by hooking into `hrr_rb_ssh`'s subsystem request handler. The SFTP server receives `IO`s directly from the SSH channel context. ### Usage ```ruby require "socket" require "logger" require "hrr_rb_ssh" require "hrr_rb_sftp" logger = Logger.new($stdout) logger.level = Logger::INFO # Accept any public-key authentication auth_publickey = HrrRbSsh::Authentication::Authenticator.new { |ctx| true } # Handle the "sftp" subsystem request in-process conn_subsys = HrrRbSsh::Connection::RequestHandler.new { |ctx| ctx.chain_proc { |chain| case ctx.subsystem_name when "sftp" begin sftp_server = HrrRbSftp::Server.new(logger: logger) sftp_server.start(ctx.io[0], ctx.io[1], ctx.io[2]) exitstatus = 0 rescue => e logger.error { e.message } exitstatus = 1 end else exitstatus = 1 end exitstatus } } options = {} options["authentication_publickey_authenticator"] = auth_publickey options["connection_channel_request_subsystem"] = conn_subsys tcp = TCPServer.new(10022) loop do Thread.new(tcp.accept) do |io| pid = fork do ssh_server = HrrRbSsh::Server.new(options, logger: logger) ssh_server.start(io) end io.close Process.waitpid2(pid) end end ``` ``` -------------------------------- ### Integrate HrrRbSftp with hrr_rb_ssh (Spawned Child Process) Source: https://context7.com/hirura/hrr_rb_sftp/llms.txt Spawns `hrr_rb_sftp_server.rb` as a separate child process for each SFTP session. The child process's standard streams are connected to the SSH channel's IO objects. ```ruby require "socket" require "hrr_rb_ssh" SFTP_SERVER_PATH = "/usr/local/bin/hrr_rb_sftp_server.rb" conn_subsys = HrrRbSsh::Connection::RequestHandler.new { |ctx| ctx.chain_proc { |chain| case ctx.subsystem_name when "sftp" pid = spawn(SFTP_SERVER_PATH, in: ctx.io[0], out: ctx.io[1], err: ctx.io[2]) exitstatus = Process.waitpid(pid).to_i else exitstatus = 1 end exitstatus } } options = {} options["authentication_publickey_authenticator"] = HrrRbSsh::Authentication::Authenticator.new { |ctx| true } options["connection_channel_request_subsystem"] = conn_subsys tcp = TCPServer.new(10022) loop do Thread.new(tcp.accept) do |io| pid = fork { HrrRbSsh::Server.new(options).start(io) } io.close Process.waitpid2(pid) end end ``` -------------------------------- ### Integrating with hrr_rb_ssh (spawned child process mode) Source: https://context7.com/hirura/hrr_rb_sftp/llms.txt Spawns `hrr_rb_sftp_server.rb` as a separate child process for each SFTP session. The child's `$stdin`/`$stdout`/`$stderr` are connected to the SSH channel's IO objects. ```APIDOC ## Integrating with `hrr_rb_ssh` — spawned child process mode ### Description Spawns `hrr_rb_sftp_server.rb` as a separate child process for each SFTP session. The child's `$stdin`/`$stdout`/`$stderr` are connected to the SSH channel's IO objects. ### Usage ```ruby require "socket" require "hrr_rb_ssh" SFTP_SERVER_PATH = "/usr/local/bin/hrr_rb_sftp_server.rb" conn_subsys = HrrRbSsh::Connection::RequestHandler.new { |ctx| ctx.chain_proc { |chain| case ctx.subsystem_name when "sftp" pid = spawn(SFTP_SERVER_PATH, in: ctx.io[0], out: ctx.io[1], err: ctx.io[2]) exitstatus = Process.waitpid(pid).to_i else exitstatus = 1 end exitstatus } } options = {} options["authentication_publickey_authenticator"] = HrrRbSsh::Authentication::Authenticator.new { |ctx| true } options["connection_channel_request_subsystem"] = conn_subsys tcp = TCPServer.new(10022) loop do Thread.new(tcp.accept) do |io| pid = fork { HrrRbSsh::Server.new(options).start(io) } io.close Process.waitpid2(pid) end end ``` ``` -------------------------------- ### Integrate HrrRbSftp with hrr_rb_ssh (In-Process) Source: https://context7.com/hirura/hrr_rb_sftp/llms.txt Runs the SFTP server within the same Ruby process as the SSH server by hooking into hrr_rb_ssh's subsystem request handler. IO streams are provided directly from the SSH channel context. ```ruby require "socket" require "logger" require "hrr_rb_ssh" require "hrr_rb_sftp" logger = Logger.new($stdout) logger.level = Logger::INFO # Accept any public-key authentication auth_publickey = HrrRbSsh::Authentication::Authenticator.new { |ctx| true } # Handle the "sftp" subsystem request in-process conn_subsys = HrrRbSsh::Connection::RequestHandler.new { |ctx| ctx.chain_proc { |chain| case ctx.subsystem_name when "sftp" begin sftp_server = HrrRbSftp::Server.new(logger: logger) sftp_server.start(ctx.io[0], ctx.io[1], ctx.io[2]) exitstatus = 0 rescue => e logger.error { e.message } exitstatus = 1 end else exitstatus = 1 end exitstatus } } options = {} options["authentication_publickey_authenticator"] = auth_publickey options["connection_channel_request_subsystem"] = conn_subsys tcp = TCPServer.new(10022) loop do Thread.new(tcp.accept) do |io| pid = fork do ssh_server = HrrRbSsh::Server.new(options, logger: logger) ssh_server.start(io) end io.close Process.waitpid2(pid) end end ``` -------------------------------- ### Configure OpenSSH to Use hrr_rb_sftp Source: https://github.com/hirura/hrr_rb_sftp/blob/master/README.md Replace the default OpenSSH SFTP server with hrr_rb_sftp by modifying the sshd_config file. Ensure to comment out the original line and add the path to your hrr_rb_sftp_server.rb script. ```bash #Subsystem sftp /usr/lib/openssh/sftp-server # Comment out the original line Subsystem sftp /path/to/hrr_rb_sftp_server.rb ``` -------------------------------- ### List SFTP Protocol Version 3 Extensions Source: https://context7.com/hirura/hrr_rb_sftp/llms.txt Retrieve a list of advertised extensions for SFTP protocol version 3. This is automatically handled during the SSH_FXP_VERSION handshake. ```ruby # Version 3 is selected automatically when both sides support it. # Advertised extensions are sent in the SSH_FXP_VERSION handshake response: HrrRbSftp::Protocol.extension_pairs(3).map { |ep| ep[:"extension-name"] } # => ["hardlink@openssh.com", "fsync@openssh.com", # "posix-rename@openssh.com", "lsetstat@openssh.com"] ``` -------------------------------- ### Check SFTP Protocol Version Support Source: https://context7.com/hirura/hrr_rb_sftp/llms.txt Verify if SFTP protocol version 2 is supported by the library. This is a simple boolean check. ```ruby HrrRbSftp::Protocol.versions.include?(2) # => true ``` -------------------------------- ### Configure sshd to use HrrRbSftp Server Source: https://context7.com/hirura/hrr_rb_sftp/llms.txt Modify the sshd configuration file to use the HrrRbSftp server. Reload the sshd service after making changes. Test the connection using the sftp command. ```bash # Comment out (or remove) the original line: #Subsystem sftp /usr/lib/openssh/sftp-server # Add the hrr_rb_sftp replacement: Subsystem sftp /path/to/hrr_rb_sftp_server.rb ``` ```ruby # /path/to/hrr_rb_sftp_server.rb #!/usr/bin/env ruby require "hrr_rb_sftp" server = HrrRbSftp::Server.new(logger: nil) server.start($stdin, $stdout, $stderr) ``` ```bash # Reload sshd (systemd systems) sudo systemctl reload sshd # Test the connection sftp -P 22 user@host ``` -------------------------------- ### Run SFTP Server in Same Process with hrr_rb_ssh Source: https://github.com/hirura/hrr_rb_sftp/blob/master/README.md Integrate hrr_rb_sftp as an SFTP subsystem handler within the same process as hrr_rb_ssh. This approach uses hrr_rb_ssh's request handler mechanism. ```ruby subsys = HrrRbSsh::Connection::RequestHandler.new { |ctx| ctx.chain_proc { case ctx.subsystem_name when 'sftp' begin sftp_server = HrrRbSftp::Server.new(logger: nil) sftp_server.start(ctx.io[0], ctx.io[1], ctx.io[2]) exitstatus = 0 rescue exitstatus = 1 end else # Do something for other subsystem, or just return exitstatus exitstatus = 0 end exitstatus } } options['connection_channel_request_subsystem'] = subsys ``` -------------------------------- ### SSH_FXP_SYMLINK Argument Order Source: https://github.com/hirura/hrr_rb_sftp/blob/master/README.md Note on the argument order for SSH_FXP_SYMLINK requests. This library follows the convention used by OpenSSH's sftp-server, where linkpath and targetpath are provided in a specific order. ```plaintext uint32 id string targetpath string linkpath ``` -------------------------------- ### SFTP Extension: fsync@openssh.com Source: https://context7.com/hirura/hrr_rb_sftp/llms.txt Constants and server-side behavior for the 'fsync@openssh.com' extension, used to flush kernel buffers to disk for an open file handle. Available only in protocol version 3. ```ruby HrrRbSftp::Protocol::Version3::Extensions::FsyncAtOpensshCom::EXTENSION_NAME # => "fsync@openssh.com" HrrRbSftp::Protocol::Version3::Extensions::FsyncAtOpensshCom::EXTENSION_DATA # => "1" # Server-side behaviour: # file = handles[request[:handle]] # file.fsync # # Possible SSH_FXP_STATUS response codes: # SSH_FX_OK — fsync completed # SSH_FX_FAILURE — handle not found in the open-handles map ``` -------------------------------- ### HrrRbSftp::Protocol.extension_pairs Source: https://context7.com/hirura/hrr_rb_sftp/llms.txt Fetches the list of extension name/data pairs advertised for a specific protocol version. Only version 3 supports extensions; versions 1 and 2 return an empty array. ```APIDOC ## HrrRbSftp::Protocol.extension_pairs Returns the list of extension name/data pairs advertised for a given protocol version. Only version 3 carries extensions; versions 1 and 2 return an empty array. ```ruby require "hrr_rb_sftp" puts HrrRbSftp::Protocol.extension_pairs(3).inspect # => [ # { :"extension-name" => "hardlink@openssh.com", :"extension-data" => "1" }, # { :"extension-name" => "fsync@openssh.com", :"extension-data" => "1" }, # { :"extension-name" => "posix-rename@openssh.com", :"extension-data" => "1" }, # { :"extension-name" => "lsetstat@openssh.com", :"extension-data" => "1" }, # ] puts HrrRbSftp::Protocol.extension_pairs(1).inspect # => [] ``` ``` -------------------------------- ### SFTP Extension: posix-rename@openssh.com Source: https://context7.com/hirura/hrr_rb_sftp/llms.txt Constants and server-side behavior for the 'posix-rename@openssh.com' extension, which performs an atomic POSIX rename operation, replacing the destination if it exists. Available only in protocol version 3. ```ruby HrrRbSftp::Protocol::Version3::Extensions::PosixRenameAtOpensshCom::EXTENSION_NAME # => "posix-rename@openssh.com" HrrRbSftp::Protocol::Version3::Extensions::PosixRenameAtOpensshCom::EXTENSION_DATA # => "1" # Server-side behaviour: # File.rename(request[:oldpath], request[:newpath]) # # Possible SSH_FXP_STATUS response codes: # SSH_FX_OK — rename succeeded # SSH_FX_NO_SUCH_FILE — oldpath does not exist # SSH_FX_PERMISSION_DENIED — insufficient permissions ``` -------------------------------- ### SFTP Extension: lsetstat@openssh.com Source: https://context7.com/hirura/hrr_rb_sftp/llms.txt Constants and server-side behavior for the 'lsetstat@openssh.com' extension, used to set attributes on a symbolic link itself without following it. Available only in protocol version 3. ```ruby HrrRbSftp::Protocol::Version3::Extensions::LsetstatAtOpensshCom::EXTENSION_NAME # => "lsetstat@openssh.com" HrrRbSftp::Protocol::Version3::Extensions::LsetstatAtOpensshCom::EXTENSION_DATA # => "1" # Server-side behaviour depending on attrs fields present: # File.lutime(attrs[:atime], attrs[:mtime], path) — set timestamps (requires Ruby >= 2.x lutime support) # File.lchown(attrs[:uid], attrs[:gid], path) — set ownership # File.lchmod(attrs[:permissions], path) — set permissions # # Possible SSH_FXP_STATUS response codes: # SSH_FX_OK — all requested attrs applied # SSH_FX_BAD_MESSAGE — :size attribute provided (not supported by lsetstat) # SSH_FX_FAILURE — File.lutime not supported by this Ruby build # SSH_FX_NO_SUCH_FILE — path does not exist # SSH_FX_PERMISSION_DENIED — insufficient permissions ``` -------------------------------- ### HrrRbSftp::Protocol.versions Source: https://context7.com/hirura/hrr_rb_sftp/llms.txt Retrieves the list of SFTP protocol version integers supported by the library. This is used during the handshake to determine the highest common version. ```APIDOC ## HrrRbSftp::Protocol.versions Returns the list of SFTP protocol version integers that the library supports. During the handshake, the server selects `min(remote_version, local_version)`. ```ruby require "hrr_rb_sftp" puts HrrRbSftp::Protocol.versions.inspect # => [1, 2, 3] puts HrrRbSftp::Protocol.versions.max # => 3 (highest supported version, used as the local offer) ``` ``` -------------------------------- ### SFTP Protocol Version 1 — Core Packet Types Source: https://context7.com/hirura/hrr_rb_sftp/llms.txt Details the core packet types for SFTP Protocol Version 1, including their TYPE constants and purposes. These packets form the foundation for all subsequent versions. ```APIDOC ## SFTP Protocol Version 1 — Core Packet Types Version 1 implements the foundational SFTP packet set. All subsequent versions inherit and extend this set. The packets and their TYPE constants are: | Packet | TYPE | Direction | Purpose | |---|---|---|---| | `SSH_FXP_OPEN` | 3 | request | Open or create a file | | `SSH_FXP_CLOSE` | 4 | request | Close a file or directory handle | | `SSH_FXP_READ` | 5 | request | Read bytes from an open file | | `SSH_FXP_WRITE` | 6 | request | Write bytes to an open file | | `SSH_FXP_LSTAT` | 7 | request | Stat a path without following symlinks | | `SSH_FXP_FSTAT` | 8 | request | Stat an open handle | | `SSH_FXP_SETSTAT` | 9 | request | Set attributes on a path | | `SSH_FXP_FSETSTAT` | 10 | request | Set attributes on an open handle | | `SSH_FXP_OPENDIR` | 11 | request | Open a directory | | `SSH_FXP_READDIR` | 12 | request | Read directory entries | | `SSH_FXP_REMOVE` | 13 | request | Remove a file | | `SSH_FXP_MKDIR` | 14 | request | Create a directory | | `SSH_FXP_RMDIR` | 15 | request | Remove a directory | | `SSH_FXP_REALPATH` | 16 | request | Canonicalize a path | | `SSH_FXP_STAT` | 17 | request | Stat a path following symlinks | | `SSH_FXP_STATUS` | 101 | response | Operation status | | `SSH_FXP_HANDLE` | 102 | response | File/directory handle | | `SSH_FXP_DATA` | 103 | response | File data | | `SSH_FXP_NAME` | 104 | response | File name list | | `SSH_FXP_ATTRS` | 105 | response | File attributes | ```ruby # Open flags used in SSH_FXP_OPEN pflags field (version 1+) HrrRbSftp::Protocol::Version1::Packets::SSH_FXP_OPEN::SSH_FXF_READ # => 0x00000001 HrrRbSftp::Protocol::Version1::Packets::SSH_FXP_OPEN::SSH_FXF_WRITE # => 0x00000002 HrrRbSftp::Protocol::Version1::Packets::SSH_FXP_OPEN::SSH_FXF_APPEND # => 0x00000004 HrrRbSftp::Protocol::Version1::Packets::SSH_FXP_OPEN::SSH_FXF_CREAT # => 0x00000008 HrrRbSftp::Protocol::Version1::Packets::SSH_FXP_OPEN::SSH_FXF_TRUNC # => 0x00000010 HrrRbSftp::Protocol::Version1::Packets::SSH_FXP_OPEN::SSH_FXF_EXCL # => 0x00000020 # SSH_FXP_STATUS response codes (version 1+) HrrRbSftp::Protocol::Version1::Packets::SSH_FXP_STATUS::SSH_FX_OK # => 0 HrrRbSftp::Protocol::Version1::Packets::SSH_FXP_STATUS::SSH_FX_EOF # => 1 HrrRbSftp::Protocol::Version1::Packets::SSH_FXP_STATUS::SSH_FX_NO_SUCH_FILE # => 2 HrrRbSftp::Protocol::Version1::Packets::SSH_FXP_STATUS::SSH_FX_PERMISSION_DENIED # => 3 HrrRbSftp::Protocol::Version1::Packets::SSH_FXP_STATUS::SSH_FX_FAILURE # => 4 HrrRbSftp::Protocol::Version1::Packets::SSH_FXP_STATUS::SSH_FX_BAD_MESSAGE # => 5 HrrRbSftp::Protocol::Version1::Packets::SSH_FXP_STATUS::SSH_FX_NO_CONNECTION # => 6 HrrRbSftp::Protocol::Version1::Packets::SSH_FXP_STATUS::SSH_FX_CONNECTION_LOST # => 7 HrrRbSftp::Protocol::Version1::Packets::SSH_FXP_STATUS::SSH_FX_OP_UNSUPPORTED # => 8 ``` ``` -------------------------------- ### SFTP Extension: hardlink@openssh.com Source: https://context7.com/hirura/hrr_rb_sftp/llms.txt Constants and server-side behavior for the 'hardlink@openssh.com' extension, used to create hard links on the server. Available only in protocol version 3. ```ruby # Extension constants HrrRbSftp::Protocol::Version3::Extensions::HardlinkAtOpensshCom::EXTENSION_NAME # => "hardlink@openssh.com" HrrRbSftp::Protocol::Version3::Extensions::HardlinkAtOpensshCom::EXTENSION_DATA # => "1" # Server-side behaviour (internally executed when the extension request arrives): # File.link(request[:oldpath], request[:newpath]) # # Possible SSH_FXP_STATUS response codes: # SSH_FX_OK — link created successfully # SSH_FX_NO_SUCH_FILE — oldpath does not exist (Errno::ENOENT) # SSH_FX_PERMISSION_DENIED — insufficient permissions (Errno::EACCES) # SSH_FX_FAILURE — link already exists (Errno::EEXIST) ``` -------------------------------- ### SFTP Protocol Version 2 — SSH_FXP_RENAME Source: https://context7.com/hirura/hrr_rb_sftp/llms.txt Introduces the `SSH_FXP_RENAME` packet (TYPE 18) for version 2, allowing clients to rename files and directories. This version is automatically negotiated if supported by both client and server. ```APIDOC ## SFTP Protocol Version 2 — `SSH_FXP_RENAME` Version 2 adds the `SSH_FXP_RENAME` packet (TYPE 18), enabling clients to rename files and directories. All version 1 packets are also available. ```ruby # Version 2 is selected automatically when both client and server support it. # No application-level code is needed — the server negotiates the version # in the SSH_FXP_INIT / SSH_FXP_VERSION handshake and routes packets accordingly. ``` ``` -------------------------------- ### Custom Logger Formatter for HrrRbSftp Source: https://context7.com/hirura/hrr_rb_sftp/llms.txt Define a custom logger formatter to control the output format of log messages. This is useful for integrating with existing logging systems or for custom log analysis. ```ruby class MyLoggerFormatter < Logger::Formatter def call(severity, time, progname, msg) "%s, [%s#%d.%x] %5s -- %s: %s\n" % [ severity[0], format_datetime(time), Process.pid, Thread.current.object_id, severity, progname, msg2str(msg) ] end end logger.formatter = MyLoggerFormatter.new ``` -------------------------------- ### SFTP Version 1 Core Packet Type Constants Source: https://context7.com/hirura/hrr_rb_sftp/llms.txt Access constants for SFTP protocol version 1 packet types, including open flags and status codes. These constants are used for defining and interpreting SFTP packets. ```ruby # Open flags used in SSH_FXP_OPEN pflags field (version 1+) HrrRbSftp::Protocol::Version1::Packets::SSH_FXP_OPEN::SSH_FXF_READ # => 0x00000001 HrrRbSftp::Protocol::Version1::Packets::SSH_FXP_OPEN::SSH_FXF_WRITE # => 0x00000002 HrrRbSftp::Protocol::Version1::Packets::SSH_FXP_OPEN::SSH_FXF_APPEND # => 0x00000004 HrrRbSftp::Protocol::Version1::Packets::SSH_FXP_OPEN::SSH_FXF_CREAT # => 0x00000008 HrrRbSftp::Protocol::Version1::Packets::SSH_FXP_OPEN::SSH_FXF_TRUNC # => 0x00000010 HrrRbSftp::Protocol::Version1::Packets::SSH_FXP_OPEN::SSH_FXF_EXCL # => 0x00000020 # SSH_FXP_STATUS response codes (version 1+) HrrRbSftp::Protocol::Version1::Packets::SSH_FXP_STATUS::SSH_FX_OK # => 0 HrrRbSftp::Protocol::Version1::Packets::SSH_FXP_STATUS::SSH_FX_EOF # => 1 HrrRbSftp::Protocol::Version1::Packets::SSH_FXP_STATUS::SSH_FX_NO_SUCH_FILE # => 2 HrrRbSftp::Protocol::Version1::Packets::SSH_FXP_STATUS::SSH_FX_PERMISSION_DENIED # => 3 HrrRbSftp::Protocol::Version1::Packets::SSH_FXP_STATUS::SSH_FX_FAILURE # => 4 HrrRbSftp::Protocol::Version1::Packets::SSH_FXP_STATUS::SSH_FX_BAD_MESSAGE # => 5 HrrRbSftp::Protocol::Version1::Packets::SSH_FXP_STATUS::SSH_FX_NO_CONNECTION # => 6 HrrRbSftp::Protocol::Version1::Packets::SSH_FXP_STATUS::SSH_FX_CONNECTION_LOST # => 7 HrrRbSftp::Protocol::Version1::Packets::SSH_FXP_STATUS::SSH_FX_OP_UNSUPPORTED # => 8 ``` -------------------------------- ### SFTP Protocol Version 2 - SSH_FXP_RENAME Packet Source: https://context7.com/hirura/hrr_rb_sftp/llms.txt Version 2 of the SFTP protocol introduces the `SSH_FXP_RENAME` packet (TYPE 18) for renaming files and directories. This functionality is automatically negotiated during the SSH handshake. ```ruby # Version 2 is selected automatically when both client and server support it. # No application-level code is needed — the server negotiates the version # in the SSH_FXP_INIT / SSH_FXP_VERSION handshake and routes packets accordingly. ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.