diff options
| -rw-r--r-- | README | 6 | ||||
| -rw-r--r-- | app/src/main/java/invalid/lena/rsend/RsyncRunner.kt | 12 | ||||
| -rw-r--r-- | app/src/test/java/invalid/lena/rsend/RsyncRunnerTest.kt | 2 |
3 files changed, 14 insertions, 6 deletions
@@ -64,7 +64,11 @@ and others) otherwise delay or skip background jobs; see dontkillmyapp.com. Server ------ -Any host with sshd and rsync works; rsend pushes over rsync-over-SSH, not SFTP. +Any host with sshd and rsync works, old rsyncs included (stock macOS); rsend +pushes over rsync-over-SSH, not SFTP. rsync creates the final component of a +folder's remote path on its own; create deeper missing parents once with +mkdir -p on the server. + The account is confined to "rsync into one folder and nothing else" by a forced rrsync command, not by its shell. sshd runs that command through the account's login shell, so the shell must be real: /bin/sh works, while /bin/false or diff --git a/app/src/main/java/invalid/lena/rsend/RsyncRunner.kt b/app/src/main/java/invalid/lena/rsend/RsyncRunner.kt index c37e3ce..4d636a6 100644 --- a/app/src/main/java/invalid/lena/rsend/RsyncRunner.kt +++ b/app/src/main/java/invalid/lena/rsend/RsyncRunner.kt @@ -11,16 +11,20 @@ import kotlinx.coroutines.launch object RsyncRunner { // args builds the rsync argument vector for one folder. Flags are tuned for - // media backup: recursive, preserve mtimes, resume partial files, create - // the remote path, and skip the ownership and permission bits that mean - // nothing across Android and a server. + // media backup: recursive, preserve mtimes, resume partial files, and skip + // the ownership and permission bits that mean nothing across Android and a + // server. + // + // No --mkpath: rsync forwards it to the remote when sending, and remotes + // older than 3.2.3 (notably stock macOS) reject it. rsync creates the + // final component of the destination path on its own; deeper missing + // parents need a one-time mkdir on the server (see README). fun args(rsh: String, remote: Remote, f: Folder): List<String> { val a = ArrayList<String>() a.add("-rt") a.add("--partial") // Abort rather than hang if the network stalls for 5 minutes. a.add("--timeout=300") - a.add("--mkpath") a.add("--no-perms") a.add("--no-owner") a.add("--no-group") diff --git a/app/src/test/java/invalid/lena/rsend/RsyncRunnerTest.kt b/app/src/test/java/invalid/lena/rsend/RsyncRunnerTest.kt index ef7958f..8edf9fa 100644 --- a/app/src/test/java/invalid/lena/rsend/RsyncRunnerTest.kt +++ b/app/src/test/java/invalid/lena/rsend/RsyncRunnerTest.kt @@ -13,7 +13,7 @@ class RsyncRunnerTest { val a = RsyncRunner.args("RSH", remote, Folder(name = "n", local = "/a", remote = "/b")) assertEquals( listOf( - "-rt", "--partial", "--timeout=300", "--mkpath", + "-rt", "--partial", "--timeout=300", "--no-perms", "--no-owner", "--no-group", "--omit-dir-times", "-e", "RSH", "/a/", "user@host:/b/", ), |