Subj : pack_qwk() ignores write errors and delivers QWK packets with 0-byte M To : GitLab issue in main/sbbs From : Rob Swindell Date : Fri Sep 18 2026 19:16:40 open https://gitlab.synchro.net/main/sbbs/-/issues/1244 ## Summary `sbbs_t::pack_qwk()` does not check for write errors on `MESSAGES.DAT` / `HEADERS.DAT`. When writes to the temp directory fail, it archives the resulting 0-byte files and returns success, so QWK network hubs receive a packet with no usable content. The receiving system then fails to unpack it and renames it to `*.bad`: ``` evnt QNET !ERROR[x2] 2 (No such file or directory) in un_qwk.cpp line 105 (unpack_qwk) checking length ".../temp/event/MESSAGES.DAT" access=0 evnt QNET .../data/VERT.qwk renamed to .../data/VERT.qwk.6aadc6da.bad ``` Reported on IRC by Accession (hub PHARCYDE): 10 such packets (292 bytes zipped, containing a 0-byte `MESSAGES.DAT` and a 0-byte `HEADERS.DAT`) downloaded from VERT on Aug 13-14, 2026. ## What the VERT logs show **All hubs were affected, not just PHARCYDE.** VERT's FTP server logs show 292- or 294-byte QWK packets downloaded only between about 22:00 Aug 12 and 12:00 Aug 14 (VERT local time): | Day | 292/294-byte packets / total QWK downloads | |---|---| | Aug 12 | 3 / 1988 | | Aug 13 | 40 / 1623 | | Aug 14 | 19 / 1791 | No other day in August or September has any. Affected hubs include FREESIDE, ARCADIA, ANDUIN, CITBBS, LRDBBS, CAVEBBS, UNDREDUX, BOOBTUBE, BITSLAIR, SUBCBBS, EMERALD and PHARCYDE. **The failure was intermittent.** PHARCYDE got empty packets at 00:37 and 11:37 on Aug 13 and at 02:37, 04:37 and 06:37 on Aug 14, with normal packets (1-4 KB) in between. **No code change was involved.** VERT ran the same build (`master/~2701a79802`, compiled Aug 9) before, during and after the window, per the Terminal Server's Aug 14 15:35 recycle banner and `error.log` build stamps from Aug 11-16. **Nothing was logged on VERT.** `error.log` has no packQWK/disk/memory errors in the window. The event-thread log (`events.log`) for those dates has since rotated away. ## Analysis A packet with no messages would still have a 128-byte `MESSAGES.DAT`: `pack_qwk()` always writes the "Produced by ..." header block first (`pack_qwk.cpp` around line 314). A **0-byte** `MESSAGES.DAT` therefore means the writes failed. On VERT the packet is assembled in the temp dir on the local C: drive (`c:\sbbstemp\event\`), while the archive is written to `s:\sbbs\data\file\NNNN.qwk` on a different volume. Writes to the temp volume failing while the archive destination was fine would produce this. The likeliest cause is a full or nearly-full C: drive during the window, but that is **unconfirmed** (VERT's Windows System event log would show it). Whatever the environmental cause, the defect is that it goes unnoticed: - `fprintf()`/`fwrite()` calls writing to `MESSAGES.DAT` and `HEADERS.DAT` are not checked. - The `fclose()` return values for those files (around line 613) are ignored, so a failed flush of buffered data is also missed. - The message counters still increase, so the "nothing to pack" early return doesn't trigger, and the empty files are archived and delivered as a successful packet. ## Proposed fix In `pack_qwk()`: 1. Check `ferror()` and the `fclose()` results for `MESSAGES.DAT` and `HEADERS.DAT` (and ideally `VOTING.DAT` and the `*.NDX` files). On failure, log an error (`errormsg()`, so it reaches `error.log`) and return false without creating a packet. 2. Before creating the archive, verify that `MESSAGES.DAT` is at least `QWK_BLOCK_LEN` (128) bytes. If it isn't, log an error and return false. The hub then gets "no packet" (FTP 550) instead of a corrupt one, and the hub's sysop gets a clear `error.log` entry. Hubs holding `.bad` packets from this window can delete them; they contain nothing to recover. - *Authored by Claude (Claude Code), on behalf of @rswindell* --- SBBSecho 3.37-Linux * Origin: Vertrauen - [vert/cvs/bbs].synchro.net (1:103/705) .