• Widen the 16-bit index fields (to/from/subject CRC and mail user numbe

    From Rob Swindell@1:103/705 to GitLab issue in main/sbbs on Wed Sep 30 14:55:01 2026
    open https://gitlab.synchro.net/main/sbbs/-/work_items/1274

    ## Summary

    The message index record (`idxrec_t`, `src/smblib/smbdefs.h`) stores the recipient, sender and subject as 16-bit values: CRC-16 of the lowercased name or subject for posts, or the user number for mail. Widening these to 32 bits is a `.sid` format change. The collision rate of the hashes is not by itself a reason to do it, but the fields impose limits that are.

    ## Why the hash width is not the motivation

    The collision rate is set by the width, not by the function. Any 16-bit hash places a title against roughly N/65536 others in a base of N distinct titles, so replacing CRC-16 with a 16-bit FNV would change nothing. CRC-16 distributes short text about as evenly as anything else; "bad hash" here means "16 bits".

    Since #1208 was fixed (the readers verify the actual subject or name after an index-CRC match), a collision is no longer a correctness problem anywhere. All of the consumers treat the CRC as a candidate filter and confirm by string, so a false positive costs one header read per search step, which is not
    measurable at a few percent of titles in a large sub.

    ## What widening does buy

    The union arm holding these fields is 6 bytes of the packed 20-byte record (`SIZEOF_SMB_IDXREC_T`). Widening the three fields to 32 bits gives:

    - **The mail user-number cap.** `idx.to` and `idx.from` hold user numbers for
    mail, and the mail loader filters on them (`getmail.c`, the `idx.to ==
    usernumber` and `idx.to != usernumber` tests). A user number above 65535
    truncates, so that user can never match their own mail, and user 1 would see
    it. No other 16-bit cap on user numbers was found in `sbbsdefs.h` or
    `userdat.c`, so the index is what imposes this limit.
    - Room in the `FILE` arm of the same union for a real 48- or 64-bit file size,
    instead of `size` plus `size_ext`.
    - Fewer false-positive header reads in the name and title checks (minor).

    `fnv1a32()` (`src/hash/fnv1a.h`) is already in the tree and is the better choice over CRC-32 for the name and subject fields.

    ## What it costs

    - A `.sid` format change with no downgrade path. Every base on every install
    needs its index regenerated. `fixsmb` already rebuilds the whole index from
    the `.shd` headers, so the data risk is low: nothing in the `.sid` is
    authoritative.
    - Readers must handle both layouts by `smbhdr_t.version` (currently `0x0310`;
    the only gate today rejects below `0x110`), or the upgrade must convert every
    base before the new binaries run, the way the v3.19 and v3.20 upgraders did
    for other files.
    - Every in-tree tool that reads `idxrec_t` directly (`smbutil`, `chksmb`,
    `fixsmb`, `sbbsecho`, the mail server) follows automatically. Anything
    third-party that parses `.sid` files raw would break; those cannot be
    enumerated from here.

    ## Recommendation

    Do this only as a deliberate index-format revision, not as a hash swap: widen all three fields to 32 bits at once, switch the name and subject hashes to `fnv1a32()`, and take the file-size cleanup in the same format bump so the version gate is paid once. The user-number cap is the headline reason. Whether and when to do it is open.

    -- *Authored by Claude (Claude Code), on behalf of @rswindell*
    --- SBBSecho 3.38-Linux
    * Origin: Vertrauen - [vert/cvs/bbs].synchro.net (1:103/705)