• src/smblib/smblib.c

    From Rob Swindell (on Windows 11)@VERT to Git commit to main/sbbs/master on Fri Jan 16 20:45:33 2026
    https://gitlab.synchro.net/main/sbbs/-/commit/5bd46a2ed2ff6bbc4aa2fb8a
    Modified Files:
    src/smblib/smblib.c
    Log Message:
    smb_lock(): Confirm the lock file exists after closing it and a short delay

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net
  • From Rob Swindell (on Debian Linux)@VERT to Git commit to main/sbbs/master on Mon May 11 23:57:27 2026
    https://gitlab.synchro.net/main/sbbs/-/commit/931d45a1c1bd411af6c1c16c
    Modified Files:
    src/smblib/smblib.c
    Log Message:
    smb_new_msghdr: auto-repair small .sid/.shd status mismatches; check smb_putstatus return value

    Problem: if the .sid index file length didn't exactly match total_msgs * idxreclen, smb_new_msghdr returned SMB_ERR_FILE_LEN (-206) hard, blocking
    all further message adds until the msgbase was manually repaired. On 2026-05-09 this caused the mail SMB to reject every incoming message for
    ~14 hours (647 logged errors), resulting in SMTP "452 Insufficient system storage" responses.

    Root cause of the corruption: smb_putstatus() was called but its return
    value was silently discarded. If the status write failed after the index record was already appended to .sid, the two files diverged: .sid had one
    more record than total_msgs reflected (or vice-versa).

    Fix 1 Ä propagate smb_putstatus() failures: the return value is now
    assigned back to i and returned to the caller, so a failed status write is
    no longer silent.

    Fix 2 Ä auto-repair small discrepancies in smb_new_msghdr (rather than hard-failing) when the mismatch is 1-2 records and the .sid length is an
    exact multiple of idxreclen:
    - LONG by 1 (.sid has one orphan record): truncate the extra record with
    chsize() and continue. This was the May 9 failure mode.
    - SHORT by 1-2 (.sid is missing 1-2 records): reduce total_msgs to match
    the actual index length, persist the correction with smb_putstatus(),
    and continue. The orphaned header/data space is harmless and can be
    reclaimed by smbpack.
    - Mismatch of 3+ records, or non-aligned length: still returns
    SMB_ERR_FILE_LEN as before.

    Test cases (smblib/smbidxtest.c, using CuTest framework):
    Test_NoCorruption - baseline: normal add still works
    Test_ShortIndexByOne - .sid truncated by 1 record: auto-repairs
    Test_ShortIndexByTwo - .sid truncated by 2 records: auto-repairs
    Test_LongIndexByOne - .sid extended by 1 record: truncates and proceeds
    Test_LargeCorruptionFails - .sid truncated by 3 records: still returns -206

    All 5 tests pass with the fix; 3 of 5 fail against the original code.

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net
  • From Rob Swindell (on Debian Linux)@VERT to Git commit to main/sbbs/master on Sat Jul 4 18:24:37 2026
    https://gitlab.synchro.net/main/sbbs/-/commit/7b48c6a6bb234217b80c2695
    Modified Files:
    src/smblib/smblib.c
    Log Message:
    Prevent votes/polls from corrupting hyper-allocated message bases

    smb_addmsg() has always forced hyper-allocated storage when the base's status.attr has SMB_HYPERALLOC set, but smb_addvote(), smb_addpoll() and smb_addpollclosure() passed the caller's storage mode (typically derived
    from the sub's configured storage setting via smb_storage_mode()) straight through to smb_addmsghdr(). On a message base whose header file carries
    the SMB_HYPERALLOC attribute while the sub is configured for fast or
    self-pack allocation, a vote/poll header was then allocated via
    smb_fallochdr() or smb_allochdr() against allocation files that hyper-allocation deliberately does not maintain, yielding an offset inside existing headers: the new header overwrote a live message header and
    (spanning two blocks) overran the following one, destroying two messages
    per vote and leaving the base unreadable (smb_getmsghdr "corrupt message
    header ID" errors; chksmb "Duplicate Index Offsets" and "Overlapping
    Headers").

    Guard the header-storage branch in smb_new_msghdr() instead: if the base's persisted attr says hyper-allocated, force SMB_HYPERALLOC storage no
    matter what the caller passed. This protects every header-adding path, including any direct smb_addmsghdr() caller.

    Observed in the wild on the DEBATE sub of Vertrauen (its msgs.ini config selects fast allocation, but the 26-year-old base file is branded SMB_HYPERALLOC): the first votes cast on it destroyed messages #16-#19.

    Fixes issue #1181

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

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