• docs/v322_new.md src/sbbs3/websrvr.cpp

    From Rob Swindell (on Debian Linux)@VERT to Git commit to main/sbbs/master on Sat Aug 1 20:33:36 2026
    https://gitlab.synchro.net/main/sbbs/-/commit/4de1032086f038890a75559e
    Modified Files:
    docs/v322_new.md src/sbbs3/websrvr.cpp
    Log Message:
    websrvr: load a file's cost before checking download credits (#1192)

    The credit gate added in 72303693ef (2026-07-31) compared against a
    cost that was always zero. resolve_vpath() loaded the file record at file_detail_index, and smb_getfile() skips smb_getmsghdr() entirely at
    that detail level, while cost is only ever set from the SMB_COST header
    field. Every comparison against it therefore passed: costed files
    downloaded free of charge for authenticated users as well as anonymous
    ones, while user_downloaded_file() still billed the account afterward
    (it reloads the record itself at file_detail_normal), so a user could
    go credit-negative.

    Read the header record when the directory's files can cost something. A
    free directory has none to report, since loadfile() zeroes the cost and download_is_free() short-circuits on the same DIR_FREE flag before any
    credit comparison, so the index record alone still suffices there and loadfile() is not asked to open the base twice.

    Verified against a live file base: an unauthenticated request for a 2,639,434-credit file is refused with 401, a zero-cost file in the same non-free directory returns 200, and a file in a free directory
    transfers in full.

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

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