From 5f440f11ffd161c706fb264308c4e032959ccfcf Mon Sep 17 00:00:00 2001 From: kokopi-dev Date: Thu, 9 Apr 2026 00:44:47 +0900 Subject: [PATCH] fix:send func --- internal/services/commands.go | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/internal/services/commands.go b/internal/services/commands.go index 174435c..30d92e3 100644 --- a/internal/services/commands.go +++ b/internal/services/commands.go @@ -6,7 +6,7 @@ import ( ) const defaultPort = "22" -const defaultStoragePath = "~/.filepass_storage" +const defaultStoragePath = ".filepass_storage" // shellQuote wraps s in single quotes, escaping any single quotes within it. // This is safe for use in remote shell commands passed over SSH. @@ -35,7 +35,8 @@ func SSHCmd(s Server, remoteCmd string) *exec.Cmd { } // RsyncCmd returns an exec.Cmd for an rsync transfer. -// src and dst follow standard rsync syntax (local path or user@host:path). +// --protect-args (-s) prevents rsync from shell-expanding the remote path, +// which correctly handles filenames with spaces and special characters. func RsyncCmd(s Server, src, dst string) *exec.Cmd { sshFlag := "ssh -i " + s.PrivateKey + " -p " + serverPort(s) + " -o StrictHostKeyChecking=no -o BatchMode=yes" @@ -43,6 +44,7 @@ func RsyncCmd(s Server, src, dst string) *exec.Cmd { "rsync", "-avz", "--partial", + "--protect-args", "-e", sshFlag, src, dst, @@ -50,9 +52,9 @@ func RsyncCmd(s Server, src, dst string) *exec.Cmd { } // RemotePath returns the full remote rsync path for a filename inside storage. -// Only the filename is shell-quoted so ~ expands correctly on the remote shell. +// No shell quoting needed — --protect-args in RsyncCmd handles special characters. func RemotePath(s Server, filename string) string { - return s.User + "@" + s.Host + ":" + defaultStoragePath + "/" + shellQuote(filename) + return s.User + "@" + s.Host + ":" + defaultStoragePath + "/" + filename } // RemoteStorageRoot returns the remote storage root for rsync operations.