open
https://gitlab.synchro.net/main/sbbs/-/work_items/1305
When packing a QWKnet hub's outbound REP fails at the compression step while an older, unsent `data/<HUBID>.REP` is still present, `pack_rep()` reports success. Its caller then saves the hub's export pointers, `data/qnet/<hubid>.out/` is emptied and the packed netmail is deleted, so this pass's messages, netmail and outbound files end up in no packet.
Code references are as of master 3881be3f01 (souls-11-unit, 2026-10-26).
## Where
`sbbs_t::pack_rep()` (`src/sbbs3/pack_rep.cpp`):
1. If `data/<HUBID>.REP` exists (a previous REP not yet sent, e.g. after a failed call-out), it is extracted into the temp dir to be updated (`:67-87`).
2. New messages are appended and `subscan[].ptr` is advanced in memory (`:211`).
3. The packet is recompressed to the same path (`:293-308`): `create_archive()` for a built-in format, otherwise the hub's external `pack` command. A failure is only logged (`libarchive error ...` or `ERR_EXEC`).
4. The only success check is `if (!fexistcase(str))` (`:309`), which passes when the old REP is still there (or a partial file was left).
5. Execution continues: `qnet/<hubid>.out/` is emptied (`:314-315`), packed netmail is deleted from the mail base (`:319` onward), and it returns `true`.
The callers (the event thread's QNET handling in `main.cpp`, and `qwkjob_pack_rep()` in `qwkjob.cpp`) then write the hub's pointer file (`data/qnet/<HUBID>.ptr`).
The result is one of: the previous REP sent again without this pass's messages, or (if the archiver left a truncated file) a corrupt REP. Either way the new echomail is skipped by the advanced pointers and the netmail is gone from the mail base.
## Suggested fix
Have the compression step itself decide success: treat `create_archive()` < 0 or a non-zero external `pack` exit as failure and return `false` before touching `qnet/<hubid>.out/`, the mail base or the pointers. Better, compress to a temporary name in `data/` and replace-rename it over `<HUBID>.REP` only on success, so a failed pass leaves the previous REP intact and the next pass repeats this one's messages.
*Authored by Claude (Claude Code), on behalf of @rswindell*
--- SBBSecho 3.38-Linux
* Origin: Vertrauen - [vert/cvs/bbs].synchro.net (1:103/705)