Skip to content

feat(sftp): tar transfers for Windows OpenSSH hosts (#345) - #352

Merged
kipavy merged 1 commit into
devfrom
feat/sftp-tar-windows-345
Sep 24, 2026
Merged

kipavy merged 1 commit into
devfrom
feat/sftp-tar-windows-345

Conversation

@kipavy

@kipavy kipavy commented Sep 24, 2026 •

Copy link
Copy Markdown
Contributor

Closes #345.

What

Multi-item SFTP transfers to/from Win32-OpenSSH hosts use tar acceleration again, through the host's own tar.exe (bsdtar, shipped since Windows 10 1803), instead of the per-file fallback from #341.

How

  • sftp_tar_available now detects the remote shell once per SFTP session (cached on the session entry):
    1. POSIX probe (unchanged): command -v tar && test -d /tmp
    2. echo __TF_TEMP__:%TEMP% — only cmd.exe expands it
    3. '__TF_TEMP__:' + $env:TEMP — only PowerShell expands it
    4. tar --version in the detected dialect
      All probes are harmless on any shell. The temp value must look like X:\..., otherwise it is rejected.
  • New RemoteShell (commands/sftp/remote_shell.rs) writes tar commands for the detected shell:
    • SFTP /C:/a/b → native C:\a\b. A drive root becomes C:\. because a bare C: means the current directory on that drive.
    • Archives are staged under %TEMP% (in SFTP form for the upload/download step)
    • Exit codes: cmd branches && … || …, because %errorlevel% expands at parse time. PowerShell uses $LASTEXITCODE, captured before cleanup.
    • Symlinks are dereferenced when the extracting end is Windows (local tar for uploads, and the source host for remote→remote)
    • A command that goes over cmd.exe's 8191-character limit fails with a clear message and is not truncated
  • Context-menu compress/extract use the same dialect, so they now work on Windows hosts too.
  • POSIX command strings are byte-identical to before (the existing tests assert them exactly).

Testing

  • cargo test --lib commands::sftp: 22 pass, with new tests for detection parsing, path mapping, quoting and per-shell status/cleanup. cargo clippy --lib is clean.
  • I ran the PowerShell command forms for real in mcr.microsoft.com/powershell (pwsh 7): probe, tar --version with and without tar, create with ' and spaces in names, extract with mkdir and cleanup, and a failed extract reporting exit 2.
  • Not tested against a real Windows host. I couldn't run cmd.exe or Windows PowerShell 5.1 here. This needs a manual check on a Win32-OpenSSH box, with both the cmd and PowerShell DefaultShell, before release.

Known limits

  • In cmd.exe, a name containing %VAR% for a defined variable gets expanded inside the quotes (cmd has no escape for this).
  • If a batch selection from a cmd.exe host goes over 8191 chars, it errors out; it does not fall back to per-file.

Windows 10 1803+ ships bsdtar as tar.exe, so multi-item transfers to and
from Win32-OpenSSH hosts no longer need the per-file fallback #341 put
them on.

The tar probe now identifies the remote shell once per session: POSIX
first, then cmd.exe (`%TEMP%` expands) or PowerShell (`$env:TEMP`
expands), each followed by a `tar --version` check. Tar commands are
written in that shell's dialect: native `C:\...` paths from the SFTP
`/C:/...` form, the archive staged in `%TEMP%`, exit codes reported
without cmd's parse-time `%errorlevel%`, and symlinks dereferenced when
the extracting end is Windows. cmd.exe's 8191-char command line limit
is checked instead of failing with a truncated command.

Compress/extract in the context menu use the same dialect, so they now
work on Windows hosts too.
@kipavy
kipavy merged commit 049fcc6 into dev Sep 24, 2026
4 checks passed
@kipavy
kipavy deleted the feat/sftp-tar-windows-345 branch September 24, 2026 10:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant