-
Notifications
You must be signed in to change notification settings - Fork 0
QWK.NET ‐ QWKE Observations
QWKE (QWK Extended) is an extension to the QWK format that adds enhanced features for offline mail readers and BBS doors. This page covers QWKE-specific files, long headers, and common real-world variations.
QWKE was developed to address limitations in the original QWK format:
- Extended header fields - TO, FROM, and SUBJECT fields can exceed the 25-character QWK limit
- Reader configuration - BBS can send preferences and filtering rules to offline readers
- File attachments - Support for file uploads and downloads
- Conference management - Subscribe/unsubscribe commands for conferences
- Backward compatibility - QWKE packets remain readable by classic QWK readers
QWKE packets are identified by the presence of TOREADER.EXT or TODOOR.EXT files, though packets may mix classic QWK and QWKE features.
Purpose: Commands sent from the BBS to the offline reader.
Location: Root of QWK archive (same level as CONTROL.DAT)
Format: Plain text file, one command per line
Common Commands:
-
AREA <conference-number>- Select conference for area-specific filtering -
KEYWORD <words>- Filter messages by keywords (space-separated list) -
TWIT <usernames>- Block messages from specified users (space-separated list) -
RESET- Reset read pointers (no parameters)
Example:
AREA 5
KEYWORD programming csharp dotnet
TWIT spammer1 spammer2
RESET
QWK.NET Handling:
- Parses commands into structured
ToReaderCommandobjects - Preserves unknown commands verbatim (maintains
RawLineproperty) - Skips empty or whitespace-only lines
- Uses CP437 encoding for all text
- Handles both Windows (CR+LF) and Unix (LF) line endings
Common Quirks:
- Case variations - Command types may be uppercase, lowercase, or mixed case
- Extra whitespace - Multiple spaces between command type and parameters
- Unknown commands - Vendor-specific or custom commands not in specification
- Missing parameters - Some commands may have empty parameter strings
Purpose: Commands sent from the offline reader to the BBS door.
Location: Root of QWK archive in REP (reply) packets
Format: Plain text file, one command per line
Common Commands:
-
ATTACH <filename>- Upload file attachment with message -
REQUEST <filename>- Request file download from BBS -
ADD <conference-number>- Subscribe to conference -
DROP <conference-number>- Unsubscribe from conference
Example:
ATTACH screenshot.png
REQUEST latest.zip
ADD 10
DROP 5
QWK.NET Handling:
- Parses commands into structured
ToDoorCommandobjects - Preserves unknown commands verbatim (maintains
RawLineproperty) - Skips empty or whitespace-only lines
- Uses CP437 encoding for all text
- Handles both Windows (CR+LF) and Unix (LF) line endings
Common Quirks:
- File path variations - Filenames may include paths, spaces, or special characters
-
Multiple attachments - Multiple
ATTACHcommands for one message - Case sensitivity - Command types and filenames may vary in case
- Custom commands - Vendor-specific extensions beyond standard commands
QWKE allows TO, FROM, and SUBJECT fields to exceed the 25-character limit of standard QWK headers by using kludge lines at the beginning of message bodies.
Standard QWK Limitation:
- TO field: 25 characters (bytes 21-45 in header)
- FROM field: 25 characters (bytes 46-70 in header)
- SUBJECT field: 25 characters (bytes 71-95 in header)
QWKE Solution: When a field exceeds 25 characters:
- Header field is truncated to 25 characters (space-padded)
- Full value is placed as a kludge line at the start of the message body
- Format:
To: extended recipient name(with colon separator)
Example:
Standard QWK header:
TO: "John Doe" <john.doe@exam
FROM: "Jane Smith" <jane.smith@ex
SUBJECT: Re: Very long subject line that
QWKE with long headers:
Header (truncated):
TO: "John Doe" <john.doe@exam
FROM: "Jane Smith" <jane.smith@ex
SUBJECT: Re: Very long subject line that
Body (with kludges):
To: "John Doe" <john.doe@example.com>
From: "Jane Smith" <jane.smith@example.com>
Subject: Re: Very long subject line that exceeds 25 characters
[Message body continues...]
Structure:
- Key:
To,From, orSubject(case-insensitive) - Separator: Colon (
:) followed by space - Value: Extended field content
- Terminator: 0xE3 (QWK newline) or ASCII CR (13)
QWK.NET Handling:
- Extracts kludges from message body during parsing
- Stores kludges in
Message.Kludgescollection - Provides
QwkeLongHeaderParserto extract extended headers - Case-insensitive key matching (
To,TO,toall match) - Preserves raw kludge lines for round-trip fidelity
Standard QWK:
- Fixed 25-character limits enforced
- No kludge support
- Headers are complete in 128-byte record
QWKE:
- 25-character header fields may be truncated
- Kludge lines provide extended values
- Headers and body work together for complete information
- QWKE-aware readers use kludges, classic readers see truncated headers
Issue: Packet may have QWKE features (long headers) but no TOREADER.EXT or TODOOR.EXT files.
Causes:
- Partial QWKE implementation
- Files omitted during packet creation
- Archive extraction errors
QWK.NET Handling:
- Missing extension files are not errors
- Long headers still detected and parsed from message kludges
- Packet treated as QWKE if long headers are present
Issue: Packet mixes classic QWK and QWKE features.
Examples:
- Some messages have long headers, others don't
-
TOREADER.EXTpresent but no long headers in messages - Long headers present but no extension files
QWK.NET Handling:
- Handles mixed behaviour gracefully
- Each message parsed independently
- Extension files parsed if present, ignored if absent
Common Variations:
-
Case differences -
To:,TO:,to:all accepted - Whitespace - Extra spaces around colon or in value
- Terminators - 0xE3 (QWK) or CR (QWKE) both accepted
- Missing colons - Some implementations omit colon separator
- Multiple values - Duplicate kludges (first one used)
QWK.NET Handling:
- Case-insensitive key matching
- Whitespace preserved in values
- Both terminator types handled
- Colon separator required for parsing
- First matching kludge used if duplicates exist
Issue: Extension files contain commands not in the QWKE specification.
Causes:
- Vendor-specific extensions
- Custom BBS features
- Future specification additions
QWK.NET Handling:
- Unknown commands preserved verbatim
-
RawLineproperty contains original text -
CommandTypeextracted from first word -
Parameterscontains remainder of line - No interpretation or validation of unknown commands
Issue: Extension files may use different line endings.
Variations:
- Windows: CR+LF (
\r\n) - Unix: LF (
\n) - Classic Mac: CR (
\r) - Mixed line endings in same file
QWK.NET Handling:
- Handles CR+LF and LF automatically
- CR-only handled as line terminator
- Mixed endings processed correctly
- Original line endings preserved in
RawLine
Issue: Extension files may contain extended ASCII characters.
Common Cases:
- Accented characters in usernames
- Special characters in filenames
- Box-drawing characters in command output
QWK.NET Handling:
- Uses CP437 encoding for all extension files
- Extended ASCII characters preserved correctly
- See Encoding and CP437 for details
Extension Files:
- Parsed when present in archive
- Missing files are not errors
- Commands stored as structured objects
- Raw lines preserved for fidelity
Long Headers:
- Extracted during message body parsing
- Stored in
Message.Kludgescollection - Accessible via
QwkeLongHeaderParser - Original kludge lines preserved in
RawLine
Backward Compatibility:
- Classic QWK packets work without QWKE support
- QWKE features detected automatically
- No configuration required
Byte Fidelity:
- Raw command lines preserved in
RawLineproperties - Kludge lines preserved exactly as written
- Encoding maintained (CP437)
- Line endings preserved in raw text
Round-Trip Support:
- QWKE → REP → QWK preserves all QWKE features
- Extension files regenerated with original commands
- Long headers written back as kludges
- Unknown commands preserved verbatim
Extension Files:
- No structural validation (files are optional)
- Unknown commands accepted without warnings
- Empty files are valid (no commands)
Long Headers:
- Kludge parsing is permissive
- Invalid kludge format doesn't prevent message parsing
- Missing kludges don't cause errors
- See Validation Modes for validation behaviour
- Missing
TOREADER.EXTorTODOOR.EXTfiles - Empty extension files
- Unknown commands in extension files
- Messages without long headers
- Mixed QWK/QWKE packets
- Malformed kludge lines - May not be parsed correctly (no error, just ignored)
- Encoding problems - Extended ASCII may display incorrectly if wrong encoding used
- Line ending issues - Rare, but mixed endings may cause parsing problems
See Validation Modes for how validation modes handle QWKE-specific issues.
-
Check for extension files - Use
OptionalFiles.HasFile()to detect QWKE features -
Extract long headers - Use
QwkeLongHeaderParserfor extended header fields -
Preserve raw data - Access
RawLineproperties when byte fidelity is critical
-
Generate extension files - Create
TOREADER.EXTorTODOOR.EXTwhen needed - Use long headers - Add kludge lines for fields exceeding 25 characters
-
Preserve unknown commands - Include
RawLinewhen regenerating extension files
- Case-insensitive matching - Don't rely on exact case for command types or kludge keys
- Unknown commands - Preserve verbatim, don't attempt interpretation
- Mixed packets - Handle both QWK and QWKE features in same packet
- QWK Format Observations - General QWK format variations and quirks
- Validation Modes - How validation modes handle QWKE features
- Encoding and CP437 - Character encoding in QWKE files
- API Overview - QWKE-related API methods and usage