aboutsummaryrefslogtreecommitdiff
AgeCommit message (Collapse)AuthorFilesLines
7 daysapp: report config limits instead of crashingLena4-1/+85
The remote and folder counts and the serialized config size are enforced only inside save, which throws. Every other rule an editor can break is reported in the form, so a config that outgrew a limit crashed the activity instead of saying so. overLimit answers before the entry is added, and the editors report the answer. hostKeyAllowed reconstructs the known_hosts address that rsh writes with knownhosts.Normalize, and nothing recorded or tested that coupling. Normalize leaves the host bare on port 22 for IPv6 literals too, so bracketing them here looks right and would reject every IPv6 pin.
7 daysci: check the Kotlin pin and refuse a dirty repro buildLena2-2/+1
Every other version repeated outside ./versions is asserted in test.sh. KOTLIN_VERSION was not, so bumping it would leave a stale version in a license notice with nothing to catch it. In verify-repro the two git diff calls preceded the status check, so under set -eu a dirty tree exited 1 with no output and the message below was never reached. git status --porcelain already covers staged, unstaged and untracked changes.
7 daysbuild: pin the build host and the shipped ABIsLena3-29/+24
The native scripts picked an NDK host tag for macOS as well, but ci/setup-toolchain.sh provisions nothing outside Linux x86_64 and no pipeline exercises the other branch. Fail with the message setup already gives instead of naming a toolchain nobody can obtain here. The armeabi-v7a and x86 cases were never reachable either: ABIS ships arm64-v8a and x86_64, and ci/verify-apk.sh has no machine check for the other two, so adding one to ABIS failed the build it was meant to enable. Record what a new ABI actually costs instead of inviting a one-line edit that cannot work.
7 daysrsh: pass the resolved port to dialLena1-7/+3
Both callers already read and used RSH_PORT before dialling. Reading it a third time inside dial hid the data flow and duplicated the error path.
14 daysapp: release 0.2.00.2.0Lena12-57/+201
Document the multi-remote release, publish matching store metadata, and advance the version once from the released 0.1.3 base.
14 daysbuild: pin and verify release inputsLena18-106/+4474
Support Alpine/musl and Debian/glibc hosts, lock downloaded and Gradle artifacts, and verify native and APK security properties.
14 daysapp: harden backup executionLena32-508/+2088
Validate persisted state and destination boundaries, make interruption and mirror deletion explicit, and keep scheduled work singular.
14 daysnative: harden rsync and SSH transportLena11-88/+685
Update rsync to 3.5.0 and Go to 1.26.6. Bound SSH handshakes, pin host-key types, and build 16 KB-aligned hardened executables.
14 daysapp: support multiple named remotesLena14-170/+507
Let each folder select a named SSH endpoint and migrate the published 0.1.x configuration without discarding its folders or host pin.
2026-07-01ci: drop the Codeberg release scriptLena1-103/+0
Migrating the project off Codeberg to GitLab. The release publisher was written against the Forgejo API and hardcodes codeberg.org; remove it rather than port it for now.
2026-07-01app: release 0.1.30.1.3Lena2-2/+6
versionCode 4. Bound the SSH handshake so a stalled server cannot hang a sync. Persist config, key, and host pin atomically so an interrupted write cannot corrupt state. Replace the chained one-time jobs with periodic work that survives reboots; the schedule floor is now WorkManager's 15-minute minimum.
2026-07-13ci: pin toolchains and verify release artifactsLena10-77/+183
Checksum-pin every downloaded toolchain archive. Before publishing, verify the APK was built from HEAD, the tag matches versionName, apksigner passes, and the tree is clean; publish a sha256 sidecar and treat published assets as immutable. Compare full unsigned APKs in verify-repro and run the Android unit tests in CI.
2026-07-13app: harden sync execution and persisted stateLena17-171/+212
Persist config, key blob, and host pin via AtomicFile so an interrupted write cannot corrupt state. Validate the port, clear the host pin when the remote changes, cap imported key size, time out native helpers, and escalate rsync termination to destroyForcibly. Serialize manual and scheduled syncs behind a mutex. Replace the chained one-time jobs with plain periodic work: it survives reboots without a boot receiver and cannot silently die like a broken chain. Costs the sub-15-minute interval, which photo backup does not need. Document the floor and that syncs run on any unmetered network, not only WiFi.
2026-07-01rsh: bound the SSH handshakeLena1-1/+18
ssh.Dial applies its Timeout only to the TCP connect, so a host that accepts the connection and then stalls the SSH handshake hangs the sync forever. Dial with a timeout, run the handshake under a deadline, and clear the deadline once the connection is established.
2026-07-01app: release 0.1.20.1.2Lena2-2/+7
versionCode 3. Drop --mkpath so remotes with an rsync older than 3.2.3 (stock macOS included) can receive syncs; rsync still creates the final remote path component on its own. NDK host toolchain detection so the native build also runs on macOS hosts.
2026-07-01native: pick the NDK host toolchain tag by build hostjsvk2-2/+26
The NDK names its prebuilt toolchain directory after the build host, not the target. Hardcoding linux-x86_64 broke rsync/build.sh and rsh/build.sh on macOS, which ships the toolchain under darwin-x86_64 (x86_64 binaries, run under Rosetta on Apple Silicon). Detect the host with uname and fail loud on anything else. Link: https://codeberg.org/0xlena/rsend/pulls/1
2026-07-01app: drop --mkpath for compatibility with old remote rsyncsLena3-6/+14
rsync forwards --mkpath to the remote side when sending, so a remote rsync older than 3.2.3 (notably stock macOS, whose openrsync is "rsync 2.6.9 compatible") rejects every sync with "unrecognized option '--mkpath'". rsync creates the final component of the destination path on its own, so flat remote paths keep working everywhere, including the documented rrsync setup whose root is pre-created. Only a nested remote path with missing parents now needs a one-time mkdir -p on the server; the log shows rsync's error when it is missing. Reported-by: jsvk Link: https://codeberg.org/0xlena/rsend/pulls/1
2026-07-01app: release 0.1.10.1.1Lena2-2/+6
versionCode 2. Empty-path and config-corruption fixes, rsync process cleanup on stopped syncs, keygen error reporting, and the store icon.
2026-07-01metadata: add the fastlane store iconLena1-0/+0
The app ships only an adaptive vector launcher icon, which F-Droid cannot render, so the store listing showed no icon. Ship a 512x512 raster of the same mark where F-Droid looks for it (fastlane images/ icon.png).
2026-07-01ci: remove unused testsshdLena3-162/+0
Nothing referenced it: the rsh tests run their own in-process SSH server (sshserver_test.go), which testsshd largely duplicated.
2026-07-01ci: make release.sh idempotentLena1-9/+24
Re-running on the same tag died creating a release that already existed. Reuse the tag's release when present, replace a stale asset before uploading, and parse API responses with python3 instead of sed.
2026-07-01ci: fail when gradle pins drift from versionsLena2-2/+18
The gradle files and go.mod repeat pins from versions because gradle cannot source a shell file. Compare them in ci/test.sh so a bump that misses a copy fails loud instead of silently building with the old version.
2026-07-01ci: pin the exact JDK releaseLena2-3/+6
The Adoptium "latest 17 GA" endpoint floats while versions promises never to float. Pin the full Temurin build and fetch it by version.
2026-07-01app: anchor the picker start path at the storage rootLena1-2/+6
The containment check was a bare prefix match, so a sibling such as /storage/emulated/0-evil passed for a root of /storage/emulated/0.
2026-07-01app: write config atomicallyLena1-1/+7
A crash mid-write corrupted config.json, and every later load then threw on parse, crash-looping the app until its data was cleared, losing the key and pinned host. Write to a temp file and rename.
2026-07-01app: kill rsync when a sync is stoppedLena2-4/+19
A stopped worker (schedule replaced, constraints lost) left rsync running detached until its own network timeout, including a window where a WiFi-only sync kept pushing on another network. A watchdog coroutine destroys the process on cancellation, which also closes its pipes and unblocks the log reader; the worker rethrows cancellation instead of logging it as a folder error.
2026-07-01app: refuse folder mappings with empty pathsLena2-4/+16
The trailing-slash fix-up turns an empty local path into /, so a blank folder row would rsync the entire filesystem; an empty remote path pushes into the rrsync root. Reject both when saving a folder, skip and log them at run time in case the config was edited by hand, and log why a sync was skipped when the app is not configured yet.
2026-07-01rsh: reject an invalid RSH_PORTLena1-8/+19
A garbage or out-of-range port silently fell back to 22 and connected to the wrong place; fail loud instead.
2026-07-01keys: never write the plaintext private key to diskLena4-42/+41
rsh -keygen printed the pubkey but wrote the key pair into a directory, so generating a key briefly left the plaintext private key on flash, contradicting the documented invariant that it only ever exists in memory. -keygen now emits the private key PEM on stdout and nothing else; the app encrypts it immediately and derives the public key via -pubkey, reusing the validated import path. Keygen failures now surface as an error dialog instead of crashing the app from a bare thread.
2026-06-01app: add a folder picker for local paths0.1.0Lena6-5/+223
Typing absolute paths is error-prone; let the user browse real filesystem folders and pick one. Stays on real paths (no SAF) so rsync keeps operating on POSIX paths.
2026-01-01rsend: push phone folders to a home SSH host over rsyncLena85-0/+4772
A small Android app for one-way folder backup, a KISS alternative to Syncthing. It bundles rsync (built from pinned source via the NDK) and a pure-Go SSH transport, both shipped in the APK as lib*.so and run from the native library directory. rsend pins the host key, stores the ed25519 identity Keystore-encrypted, pushes each folder additively or as a mirror, and runs on demand or on a WiFi-only schedule. The build is self-contained and reproducible: make setup provisions the toolchain, make builds rsync, rsh, and the APK.