Skip to content

QWK.NET ‐ QWK Format Notes

Agent 57951 edited this page Jan 19, 2026 · 2 revisions

QWK Format Notes

Practical notes about real-world QWK packets and how QWK.NET handles common deviations from the specification. This page focuses on quirks observed in historical BBS packets rather than restating the full specification.

Why Format Variations Exist

Historical QWK packets were created by diverse BBS software implementations over several decades. Whilst the QWK specification exists, real-world packets often deviate due to:

  • Implementation differences - Various mail door software interpreted the spec differently
  • Evolution over time - Formats evolved before standards were fully established
  • Storage media issues - Corruption from floppy disks, tape backups, or incomplete transfers
  • Vendor extensions - BBS-specific additions that became common practice

QWK.NET handles these variations gracefully whilst preserving byte fidelity where possible.

CONTROL.DAT Variations

Date Format Variations

Specification: MM-DD-YY,HH:MM:SS (hyphen-delimited, 2-digit year)

Real-World Variations:

  • MM/DD/YY,HH:MM:SS - Slash delimiters (very common, ~40-60% of packets)
  • MM-DD-YYYY,HH:MM:SS - 4-digit year with hyphens (uncommon)
  • MM/DD/YYYY,HH:MM:SS - 4-digit year with slashes (rare, e.g., mvt2.qwk)

QWK.NET Handling:

  • Auto-detects delimiter type (hyphen or slash)
  • Supports both 2-digit and 4-digit years
  • Applies Y2K heuristic for 2-digit years (00-49 → 2000s, 50-99 → 1900s)
  • Validates 4-digit years within 1980-2099 range

Validation Warnings:

  • Lenient/Salvage: Invalid date formats log warnings, date set to DateTime.MinValue
  • Strict: Throws exception on unparseable dates

Empty or Missing Fields

Common Cases:

  • Empty Qmail menu file (line 8) - Often just whitespace or empty string
  • Missing optional files (WELCOME, NEWS, GOODBYE) - Not all BBSes provide these
  • Whitespace-only BBS city/phone fields - Some implementations left these blank

QWK.NET Handling:

  • Strict Mode: Rejects empty required fields (throws exception)
  • Lenient Mode: Warns but continues with empty strings
  • Salvage Mode: Best-effort recovery with sensible defaults

Validation Warnings:

  • Missing required field: Error in Strict, warning in Lenient/Salvage
  • Empty BBS ID: Warning + "UNKNOWN" default in Lenient/Salvage

Incorrect Conference Counts

Issue: ConferenceCountMinusOne (line 11) may not match actual conference definitions.

Examples:

  • Claims 5 conferences but defines 6 pairs
  • Claims 10 conferences but defines 8 pairs
  • Off-by-one errors from counting mistakes

QWK.NET Handling:

  • Parses exactly the claimed number of conference pairs
  • Validation reports mismatches
  • Salvage mode recovers remaining lines as raw data

Validation Warnings:

  • Conference count mismatch: Warning logged, parsed count used

Conference Number Gaps

Issue: Specification implies sequential conference numbers, but many packets have gaps.

Example:

0 - Main Board
1 - General
5 - Off-Topic  ← Gap: no conferences 2, 3, 4
10 - Tech       ← Gap: no conferences 6-9

QWK.NET Handling:

  • Supports non-sequential conference numbers
  • Validates message references against available conferences
  • No requirement for sequential numbering

Validation Warnings:

  • Message references non-existent conference: Warning logged

Field Length Variations

Specification Limits:

  • Conference names: 13 characters (classic QWK)
  • QWKE allows: 255 characters

Real-World Behaviour:

  • BBS names may exceed 60 characters
  • Conference names often exceed 13-character limit
  • Phone numbers vary widely (international formats, extensions)

QWK.NET Handling:

  • No arbitrary length limits enforced
  • Preserves content as-is
  • Full CP437 support for extended characters

Validation Warnings:

  • None - length variations are accepted

Extended ASCII in Text Fields

Issue: Box-drawing characters, accents, or symbols in supposedly ASCII-only fields.

Examples:

  • BBS name with box-drawing borders: ─══ StarLink BBS ══─
  • Sysop name with accents: José Rodriguez
  • Phone with symbols: ☎ 555-1212

QWK.NET Handling:

  • Full CP437 encoding support for all text fields
  • Preserves extended characters without conversion
  • No UTF-8 normalisation

Validation Warnings:

  • None - CP437 characters are expected and preserved

Message Header Variations

Date Format in Message Headers

Specification: MM-DD-YY (8 characters, hyphens at positions 2 and 5)

Real-World Variations:

  • MM/DD/YY - Slash delimiters (common variant)
  • MM-DD-YYYY - 4-digit year with hyphens
  • MM/DD/YYYY - 4-digit year with slashes

QWK.NET Handling:

  • Accepts all observed formats
  • Delimiters must be consistent (both hyphens OR both slashes)
  • Validates date structure for header detection

Validation Warnings:

  • Invalid date format: Warning logged, date parsing may fail
  • Inconsistent delimiters: Warning logged

Incomplete or Truncated Messages

Issue: Messages may have missing body blocks or truncated headers.

Common Causes:

  • Incomplete file transfers
  • Corrupted archives
  • Software bugs in packet generation

QWK.NET Handling:

  • Lenient/Salvage: Logs warnings for missing blocks, returns partial data
  • Strict: Throws exception on structural errors

Validation Warnings:

  • Missing body block: Warning logged, parsing continues
  • Incomplete body block: Warning logged with byte count

Malformed Header Blocks

Issue: Blocks that don't match expected header structure.

QWK.NET Handling:

  • Validates header structure before parsing
  • Checks critical fields: status byte, date delimiters, time colon, alive flag
  • Skips invalid blocks in Lenient/Salvage modes

Validation Warnings:

  • Invalid header structure: Warning logged with diagnostic details
  • Block skipped: Warning indicates offset and reason

Index File (.NDX) Quirks

MSBIN Float Variations

Issue: Index files use Microsoft Binary Format floats, which may have edge cases.

QWK.NET Handling:

  • Handles zero values (four zero bytes)
  • Validates record offsets are non-negative
  • Checks offsets don't exceed MESSAGES.DAT file size

Validation Warnings:

  • Negative record offset: Warning logged, entry skipped
  • Offset exceeds file size: Warning logged, entry skipped in Lenient/Salvage
  • File size not multiple of 4: Error in Strict, warning in Lenient/Salvage

Incorrect Index Entries

Issue: Index entries may point to invalid locations or have incorrect counts.

QWK.NET Handling:

  • Validates each entry against MESSAGES.DAT size
  • Skips invalid entries in Lenient/Salvage modes
  • Maintains sequential message numbering even when entries are skipped

Validation Warnings:

  • Invalid index entry: Warning logged with entry number and reason

Archive Container Variations

Case-Insensitive File Matching

Issue: Some archive formats or BBS implementations use inconsistent case for filenames.

QWK.NET Handling:

  • Case-insensitive file matching for all QWK files
  • CONTROL.DAT, control.dat, and Control.Dat all match
  • Preserves original case when reading

Validation Warnings:

  • None - case variations are handled automatically

Missing Optional Files

Issue: Optional files (WELCOME, NEWS, GOODBYE, DOOR.ID) may be absent.

QWK.NET Handling:

  • Optional files are truly optional
  • OptionalFiles.HasFile() returns false for missing files
  • No errors logged for missing optional files

Validation Warnings:

  • None - missing optional files are expected

When Validation Warnings Are Expected

Common Scenarios Producing Warnings

Date Format Issues:

  • Packets using slash delimiters instead of hyphens (very common)
  • 4-digit years in older packets (rare but valid)

Field Issues:

  • Empty Qmail menu file (common)
  • Missing optional files (expected)
  • Whitespace-only fields (occasional)

Structural Issues:

  • Conference count mismatches (occasional)
  • Non-sequential conference numbers (common)
  • Index entries pointing beyond file (rare, indicates corruption)

Message Issues:

  • Truncated messages (rare, indicates corruption)
  • Malformed headers (rare, indicates corruption)

When Warnings Are Normal

In Lenient mode (recommended default), warnings are expected and normal for:

  • Packets using slash-delimited dates
  • Packets with empty optional fields
  • Packets with non-sequential conference numbers
  • Packets with extended ASCII characters

These warnings indicate format variations, not errors. The packet is still fully usable.

When Warnings Indicate Problems

Warnings that suggest actual problems:

  • Index entries pointing beyond file boundaries
  • Missing required message body blocks
  • Malformed header structures
  • Negative record offsets

These may indicate corruption or software bugs. Consider using Salvage mode for recovery.

Byte Fidelity Preservation

QWK.NET prioritises preserving original packet bytes:

  • CP437 encoding - No UTF-8 conversion, extended characters preserved
  • MSBIN floats - Exact byte representation maintained in index files
  • 128-byte records - Space padding preserved exactly
  • 0xE3 line terminators - QWK-specific newlines maintained
  • Round-trip fidelity - QWK → REP → QWK preserves all bytes

Even when handling format variations, the library preserves the original data structure.

Further Reading

Clone this wiki locally