• src/sbbs3/nopen.c nopen.h

    From Rob Swindell (on Windows 11)@VERT to Git commit to main/sbbs/master on Fri Jul 24 23:17:57 2026
    https://gitlab.synchro.net/main/sbbs/-/commit/254b876244369ee10695c7d3
    Modified Files:
    src/sbbs3/nopen.c nopen.h
    Log Message:
    backup: copy via a shared (DENYNONE) open rather than CopyFile()

    backup() with ren=false copied through the Win32 CopyFile() API, which
    opens its source GENERIC_READ / FILE_SHARE_READ. That is a deny-write
    share mode: for the duration of the copy no other opener -- on this host
    or, over SMB/CIFS, on any other host sharing the data directory -- can
    open that file for writing.

    Where a data/ directory is shared by several Synchronet hosts, that means
    every daily_maint() user-data backup blocks user-record writes system
    wide until the copy completes: putuserdat() gives up after nopen()'s
    ~10-second retry budget and returns USER_OPEN_ERROR (-102), and the
    record write is discarded rather than queued. A copy that never finishes wedges user-record writes indefinitely, with a log flood as the only
    visible symptom.

    Add fcopy(), opening both source and destination O_DENYNONE via nopen(),
    and call it from backup(). On Windows this restores the behavior that 2b892eae1f (peer-11-drive) replaced: that commit swapped fcopy() for
    CopyFile() to gain throughput (1GB to/from CIFS/SMB: 37s -> 5s), which is
    a real cost, but for a shared data directory a fast backup that locks out writers is the worse trade.

    Also move nopen.h's include guard off the reserved _NOPEN_H form.

    Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>

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