https://gitlab.synchro.net/main/sbbs/-/commit/8e5f359a05d0bfb7f6f0689b
Modified Files:
exec/load/door_deploy.js src/doors/syncconquer/build.bat build.sh src/doors/syncdoom/build.bat build.sh src/doors/syncduke/build.bat build.sh src/doors/syncmoo1/build.bat build.sh src/doors/syncretro/deploy.js
Log Message:
doors: stop deploy.js from truncating the binary it deploys
The deploy step could copy a door binary onto itself and destroy it. The
usual dev install has the door's live entry SYMLINKED to the build output (./build.sh and the change is live, no deploy step) -- and file_copy()
opens the destination for writing, which through that symlink IS the
source. It truncated the binary to zero bytes before reading a byte of
it, leaving a 0-byte door and a 0-byte "copy". The build system then saw
a target newer than its sources and declined to relink, so the next
build.sh reported success over a corpse.
Both guards that were supposed to prevent it are blind to a symlink:
* fullpath(dst) == fullpath(exe) -- fullpath() NORMALIZES a path, it
does not RESOLVE it, so a symlink never compares equal to its target.
* size + mtime -- right on one filesystem, wrong across the SMB mount a
live install is usually reached through: CIFS reports the same file's
mtime a second off from the local view, the guard misses, the copy
runs.
The deploy.sh scripts this replaced got it right with `[ "$EXE" -ef
"$DST" ]`, a device+inode identity test. Synchronet's JS has no stat(),
so compare CONTENT instead: it answers a strictly stronger question, and answers it through symlinks, mounts and clock skew alike. If dst's bytes
ARE exe's bytes there is nothing to copy -- and the destructive case (dst resolves to exe) is identical BY CONSTRUCTION, so it is always taken by
that branch and the copy can never eat its own source.
Also add a post-copy tripwire: if the source's size changed across the
copy, say so loudly. It cannot undo the damage, but a 0-byte door dies at
the player's first keystroke and the build that produced it looks clean.
syncretro/deploy.js had grown a private copy of the same broken guard
while its comment claimed it shared the common one; it now calls door_deploy_file(). It also only ever scanned this checkout's xtrn/, so
the live install was never deployed to at all -- it now scans both, and
keeps an existing flat binary in step with the <os>-<arch> one so a
removed sub-dir cannot silently resurrect a stale door.
The build scripts still pointed at the deploy.sh/deploy.bat pair that
deploy.js replaced.
---
þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net