• src/sbbs3/CLAUDE.md ftpsrvr.cpp ftpsrvr.h mailsrvr.cpp mailsrvr.h rate

    From Rob Swindell (on Windows 11)@VERT to Git commit to main/sbbs/master on Sun May 24 15:55:13 2026
    https://gitlab.synchro.net/main/sbbs/-/commit/fac6a39c3a6dfe92e1d1e65a
    Modified Files:
    src/sbbs3/CLAUDE.md ftpsrvr.cpp ftpsrvr.h mailsrvr.cpp mailsrvr.h ratelimit_filter.hpp sbbs_ini.c src/sbbs3/scfg/scfgsrvr.c src/sbbs3/services.cpp services.h startup.h websrvr.cpp websrvr.h
    Log Message:
    startup: consolidate per-server rate_limit_* fields into struct rate_limit_settings

    The six rate-limit knobs (prefix4, prefix6, filter, filter_duration, filter_silent, filter_subnet_threshold) added to all four per-server
    startup_t structs by d7c823c9d landed as identical 6-field blocks
    repeated verbatim across websrvr.h, ftpsrvr.h, mailsrvr.h, services.h.
    Lift them into a shared `struct rate_limit_settings` in startup.h next
    to the existing `struct max_concurrent_settings` / `struct login_attempt_settings` patterns, and embed by value
    (`struct rate_limit_settings rate_limit;`) in each *_startup_t.

    ABI is preserved: a nested struct is byte-contiguous in declared order,
    so the on-disk/in-memory layout of each *_startup_t is unchanged.
    sbbsctrl (which doesn't reference any of these fields by name -- only
    checks the outer struct size) is unaffected and does not need to be
    rebuilt for this change.

    Downstream consolidations enabled by the new struct:

    - sbbs_ini.c: 8 copies of the 6-field block (4 read + 4 write) collapse
    into one get_rate_limit_settings() + one set_rate_limit_settings()
    helper pair, mirroring the existing get/set_login_attempt_settings.

    - scfg/scfgsrvr.c: rate_limit_cfg_view shrinks from 11 fields to 6 (the
    6 individual rate-limit scalar pointers become one
    `struct rate_limit_settings* rl`). The per-field NULL guards inside
    rate_limit_cfg() for those knobs collapse out (they are always
    populated now); the three autofilter_on-guarded blocks merge for the
    same reason. The four per-server wrappers drop from 11-line to 6-line
    designated initializers.

    - ratelimit_filter.hpp: rate_limit_key() and rate_limit_filter() take a
    `const struct rate_limit_settings*` instead of 2 and 4 scalar args
    respectively, simplifying the call sites in all four server .cpp
    files (web request + connect paths, ftp request, mail SMTP + POP3,
    services connect).

    Net: -77 lines across the touched files, no functional change. Tested: Release|Win32 build clean for sbbs.dll, ftpsrvr.dll, mailsrvr.dll, services.dll, websrvr.dll, scfg.exe; user-verified SCFG menus and
    runtime behavior.

    Also document the consolidation pattern in src/sbbs3/CLAUDE.md (new
    "Prefer consolidation when the same lines repeat" section, citing the sub-struct / ini-helper / scfg-view / shared-hpp recipes with concrete Synchronet references) so the next per-server block that starts to
    accumulate the same N-line cluster gets folded the same way.

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

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