• src/sbbs3/smbutil.c src/smblib/smballoc.c smbfile.c src/smblib/tests/s

    From Rob Swindell (on Windows 11)@VERT to Git commit to main/sbbs/master on Sat Nov 14 11:52:09 2026
    https://gitlab.synchro.net/main/sbbs/-/commit/01169480cc48191191a13829
    Modified Files:
    src/sbbs3/smbutil.c src/smblib/smballoc.c smbfile.c src/smblib/tests/smballoctest.c
    Log Message:
    smblib: keep a caller-held header lock in smb_freemsgdat() and friends

    smb_freemsgdat() (and so smb_freemsg_dfields() and smb_freemsg()) and smb_incmsg_dfields() unlocked the message base header on return even
    when the caller had locked it. A caller that locks the header, frees or references message data, and then rewrites the index from a copy it
    read earlier therefore did the rewrite unlocked: a message or file
    added by another process in between lost its index record, and the
    status record (last message number, total) was written back stale.

    Callers affected: smbutil's maintenance (which lost the lock at the
    first message it freed and held no lock file either), fixsmb,
    delusermail(), and smb_removefile().

    These functions now unlock the header only when they locked it. Every
    caller either unlocks explicitly afterward or calls with the header
    unlocked, so none depended on the implicit unlock. Maintenance of a
    large base now holds the header lock for its whole duration, so a
    concurrent post waits (and can time out) instead of being dropped from
    the index.

    The unconditional unlock dates from 874e8bcdbc (2017-11-21).

    Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>

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