• src/sbbs3/bat_xfer.cpp ftpsrvr.cpp main.cpp qwkjob.cpp sbbs.h sbbsecho

    From Rob Swindell (on Windows 11)@VERT to Git commit to main/sbbs/master on Wednesday, November 11, 2026 19:56:28
    https://gitlab.synchro.net/main/sbbs/-/commit/b3c22130c778f33a80a4a978
    Modified Files:
    src/sbbs3/bat_xfer.cpp ftpsrvr.cpp main.cpp qwkjob.cpp sbbs.h sbbsecho.c smbutil.c upload.cpp src/xpdev/filewrap.c filewrap.h
    Log Message:
    Retry renames and removals that another process briefly blocks

    A QWK pack over FTP on vert.synchro.net failed with a sharing violation (WinError 32) renaming its just-written temp packet to <user#>.qwk, and
    again removing it. The same error has been logged removing PERSONAL.NDX
    from a pack's temp directory on a local disk. In each case we had closed
    the file a moment earlier and it was free again soon after, as when a
    virus scanner or indexer opens a newly written file. The packet rename
    has been a single attempt since bfab7b8c2b (2026-10-25).

    Add three functions to xpdev (filewrap) that retry while the file is
    busy - ERROR_SHARING_VIOLATION on Windows, EBUSY elsewhere - up to 8
    times, 250 ms apart, and fail at once on any other error:

    - xp_rename_file(): rename()
    - xp_replace_file(): rename that replaces an existing destination on
    every platform
    - xp_remove_file(): remove()

    Use them where a file we just wrote or received is renamed or removed:

    - qwkjob: the packet rename, replacing qwkjob_replace_file()
    - sbbs_t::fremove(), which now also returns whether the file was removed
    - sbbs_t::mv() and sbbsecho's mv() and delfile()
    - sbbsecho: the new area file and bad-bundle renames
    - ftpsrvr: queue_rep(), ftp_remove() and the empty-REP removal
    - smbutil: swapping the packed files into place
    - upload/bat_xfer: removal of a rejected or redundant received file

    Both mv() functions fall back to copying when the rename fails, then
    remove the source. With the source held open, the copy succeeded and the removal failed, leaving the file in both places; sbbsecho's mv() then
    returned success. A source that cannot be removed now has the copy
    removed and the move fails, so the file remains only where it was.

    filewrap.h's include guard no longer uses a reserved identifier.

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

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