• exec/load/filecontents_li

    From Rob Swindell (on Debian L@VERT to Git commit to main/sbbs/m on Sun Sep 20 03:31:00 2026
    https://gitlab.synchro.net/main/sbbs/-/commit/043587351c9f3c6f0078c857
    Added Files:
    exec/load/filecontents_lib.js exec/tests/filecontents_test.js
    Modified Files:
    exec/archive.js
    Log Message:
    Store archive content listings per file area in data/dirs/<code>.contents

    Viewers re-opened and enumerated an archive on every view. On a public file base under crawler load that is nearly all wasted work: across six days, 72%
    of ?view= requests were the first ever for that URL, so an expiring cache
    would sit near a 28% hit rate. It is also repeated exposure to the mozjs185 out-of-memory failure that d777bda5c5 (2026-06-01) only deflects crawlers
    away from.

    filecontents_lib.js keeps the extraction outcome in a per-area JSON file
    beside the base it derives from, keyed by filename and validated against the file's size and mtime. Records carry a format version and an extractor-set version. The second guards the verdict rather than the encoding, so a stored failure is re-examined when the extractor set changes while a stored listing
    is not. Whole-base projection is about 82 MB, so listings are stored uncapped.

    Failures are stored too. 171 of 600 sampled archive-extension files are .arc, which libarchive cannot read at all, so each one re-attempted a doomed extraction on every view. Those now fall back to lsar, which read 80 of 80 sampled .arc files, and are enumerated once.

    The external tool runs via system.exec() with its output redirected to a file rather than system.popen(), whose _popen() needs a console and so fails inside a Windows service. ILLEGAL_FILENAME_CHARS already excludes " and \, but $ and
    a backtick are legal in a file-base filename and are still expanded by sh inside double quotes, so a path containing either is never handed to a shell.

    archive.js is given a path and cannot know which area holds it, and cmdstr() has no specifier that could pass one, so the library maps the path back to an area itself. A file outside every area is enumerated but not stored, there being nowhere to persist it. Verbose listings still read the archive, since
    CRC and compression format are not stored.

    #1247

    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net
  • From Rob Swindell (on Debian L@VERT to Git commit to main/sbbs/m on Sun Sep 20 03:31:00 2026
    https://gitlab.synchro.net/main/sbbs/-/commit/32d4aaf66581350ee596b795
    Modified Files:
    exec/load/filecontents_lib.js exec/tests/filecontents_test.js
    Log Message:
    filecontents: record which external lister reached a failure verdict

    The store is shared between hosts, and those hosts do not necessarily have
    the same tools installed. A host with no external lister would record "unreadable" for an ARC, which libarchive cannot read in any form, and a host that does have one would then trust that verdict and refuse to list a file it could read perfectly well.

    A negative record now carries the external lister that reached it, and a
    record whose lister differs from what this host has is treated as stale.
    The version is part of the identity, since builds years apart are in the wild (1.8.1 and 1.10.8 both are) and a format the older one rejects may be one the newer one reads. Successful listings are unaffected: a listing is a listing whoever produced it.

    Detection redirects stdout only, so a missing command reports on stderr and leaves the probe file empty, which holds for both /bin/sh and cmd.exe. The result is cached, and a host with no lister now skips the per-file shell it used to spawn only to fail.

    #1247

    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net
  • From Rob Swindell (on Debian L@VERT to Git commit to main/sbbs/m on Sun Sep 20 03:31:00 2026
    https://gitlab.synchro.net/main/sbbs/-/commit/5c3806d896c2de5b9d373ea0
    Modified Files:
    exec/load/filecontents_lib.js exec/tests/filecontents_test.js
    Log Message:
    filecontents: qualify a successful listing with the extractor version too

    The failure path recorded the external lister with its version while the success path recorded a bare "lsar", on the reasoning that a listing is never re-examined so the version cannot matter. That misses the one thing the field is good for: identifying, after the fact, listings produced by a build that turned out to be untrustworthy. lsar returns a partial listing for a truncated archive rather than failing, and builds years apart differ on where they draw that line.

    Both paths now use the same identity string. libarchive exposes no version to JavaScript, so the native path stays unqualified, which is honest rather than tidy.

    #1247

    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net