Skip to content

Latest commit

 

History

5 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

BBSDEV.DRP

BBSDEV.DRP is a line-oriented drop file for passing a BBS session to a door. It keeps the simple, positional interface used by traditional BBS drop files while defining the character encoding, data types, time representation, and extension rules that older formats leave ambiguous.

This document specifies format version 1.0. The key words MUST, MUST NOT, REQUIRED, SHOULD, SHOULD NOT, and MAY are to be interpreted as described by BCP 14.

File name and lifetime

The canonical file name is BBSDEV.DRP.

The BBS MUST create a separate file for each active node and MUST completely write and close it before starting the door. The BBS MUST restrict access to the BBS and door processes and MUST remove the file after the door exits. Per-node directories are RECOMMENDED.

Before starting the door, the BBS MUST set the environment variable BBSDEV_DRP in the door's environment. Its value is the full absolute path, including the BBSDEV.DRP file name, of the drop file for this invocation. For example:

/var/lib/example-bbs/node1/BBSDEV.DRP
C:\BBS\NODE1\BBSDEV.DRP

The value contains only the path: it is not surrounded by quotation marks, even when the path contains spaces, and it contains no command-line escaping. The door MUST read it directly from its environment rather than parse it through a command shell. Environment-variable names are case-sensitive on platforms that distinguish case, so the uppercase spelling is REQUIRED.

The variable uses the operating system's native path syntax and environment encoding; it is not governed by the drop file's UTF-8 representation or by the terminal encoding on line 12. On Windows, producers and consumers SHOULD use the Unicode environment and pathname APIs. A door MAY also accept an explicit path through its own command-line or configuration interface, but BBSDEV_DRP is the standard discovery mechanism.

The file is read-only input to the door. A door MUST NOT use it to return user or session changes to the BBS. Producers MUST NOT put passwords, authentication tokens, or other secrets in it.

File representation

A producer MUST:

  • encode the file as UTF-8 without a byte-order mark;
  • end every line, including the last, with CRLF;
  • write exactly 19 lines for version 1.0;
  • write no NUL, C0/C1 control, or DEL characters in a field; and
  • write no leading or trailing Unicode whitespace in a field value.

A consumer MUST accept CRLF. For interoperability with Unix tools, it MUST also accept LF. It MUST reject bare CR line endings, invalid UTF-8, a UTF-8 byte-order mark, missing required lines, and invalid field values. There is no quoting or escaping mechanism; a value cannot contain a line ending.

Except for the three cases explicitly identified below, empty fields are invalid:

  • line 3 is empty for local and stdio; and
  • line 10 is empty when no CTerm revision was detected; and
  • line 11 is empty when the BBS imposes no forced logoff time.

Line 12 describes the encoding of terminal data exchanged with the caller. It does not change the UTF-8 encoding of BBSDEV.DRP itself.

Version 1.0 fields

Line Field Required representation
1 Format version 1.0
2 Communications type A token from the communications registry below
3 Communications parameters The positional value required by line 2
4 User alias Non-empty UTF-8 text
5 Unique user key Non-empty opaque UTF-8 text
6 Screen width Decimal integer from 1 through 65535
7 Screen height Decimal integer from 1 through 65535
8 ANSI Uppercase Y or N
9 RIP Uppercase Y or N
10 CTerm version Dotted-decimal revision, or empty if unavailable
11 Time of logoff UTC timestamp in YYYY-MM-DDTHH:MM:SSZ form, or empty for no forced logoff
12 Encoding IANA-registered character-set name
13 Language Well-formed BCP 47 language tag
14 BBS software name and version Non-empty UTF-8 text
15 Board name Non-empty UTF-8 text
16 Sysop alias Non-empty UTF-8 text
17 Access level Unsigned decimal integer, cosysop, or sysop
18 Node number Unsigned decimal integer
19 Show local display Uppercase Y or N

Identity fields

The user key on line 5 is case-sensitive and opaque. A producer MUST keep it stable for the lifetime of the user account and MUST NOT assign it to another account on the same BBS. It is unique only within the BBS; consumers MUST NOT assume that it identifies the same person on another board. Consumers MUST NOT case-fold, parse, or Unicode-normalize it.

The software, board, and sysop values on lines 14 through 16 are display text. Their contents have no machine-readable substructure. In particular, a consumer MUST NOT try to split line 14 into separate product and version fields.

An unsigned access level is a BBS-defined ordinal with no portable authorization meaning. A consumer MAY interpret it when it has BBS-specific knowledge, but MUST NOT assume that equal numbers from different BBS packages grant equal privileges. Numeric access levels and node numbers range from 0 through 18446744073709551615.

Two lowercase access-level tokens have portable meanings:

  • sysop identifies the board's system operator; and
  • cosysop identifies a user to whom the sysop has delegated system-operator responsibilities.

The named roles do not establish operating-system privileges, and a door MUST NOT treat possession of this file as authentication. They allow doors to recognize those roles without guessing a BBS package's numeric convention.

Terminal fields

Width and height describe the terminal's usable character-cell area for the door. Status lines or other rows unavailable to the door are not included.

Lines 8 and 9 state whether ANSI and RIP respectively are enabled and available to this door session. They are independent flags.

Line 10 is the detected CTerm protocol revision, such as 1.332. It is not the version of the SyncTERM application. A fork that reports additional CTerm revision components retains them, for example 1.332.1. The field is empty if the BBS did not detect CTerm support.

Line 12 MUST contain the Preferred MIME Name from the IANA character sets registry when the entry has one, or the registered Name otherwise. Matching is case-insensitive, but producers SHOULD use the registry's spelling. Examples include UTF-8 and IBM437.

Line 13 MUST be a well-formed BCP 47 language tag. Language-tag comparison is case-insensitive. Producers SHOULD use the casing recommended by BCP 47, such as en-US.

N on line 19 requires a door that controls a separate operator-side display to suppress that display. Y requests that display when the door supports it. This field never disables the communications channel named on line 2 and has no effect when no separate local display exists.

Logoff deadline

When non-empty, line 11 is an absolute UTC deadline using the Internet date/time form from RFC 3339, restricted to whole seconds and an uppercase Z. Numeric offsets, fractional seconds, and leap-second values are not permitted. An empty line means this drop file imposes no forced logoff time.

When a deadline is present, the door MUST stop accepting interaction and exit when its current UTC time is equal to or later than the deadline. It SHOULD check the deadline during any potentially long operation, not only while waiting for input. The BBS SHOULD enforce the same deadline independently in case a door fails to do so. When line 11 is empty, the door MUST NOT invent a time limit from any other field in this format; the BBS MAY still end the door session externally.

Communications registry

Line 2 selects the door-facing I/O mechanism. It intentionally does not name the caller's original protocol. The BBS is responsible for any SSH, WebSocket, Telnet, or other transport processing necessary to provide the mechanism described here.

Line 2 Line 3 Contract
local Empty The door uses its current local console.
stdio Empty Terminal input arrives on standard input and terminal output is written to standard output. Standard error is not caller output.
socket Unsigned decimal native socket value An inherited, connected, bidirectional socket carrying only terminal bytes. Transport framing and negotiation have been removed.
serial Unsigned decimal file descriptor An inherited, open, preconfigured POSIX serial descriptor used for both reading and writing.
winserial Unsigned decimal handle An inherited, open, preconfigured Win32 COM HANDLE used for both reading and writing.
uart HHHH,I Direct DOS UART access. HHHH is the four-uppercase-hex-digit I/O base without 0x; I is decimal IRQ 0 through 15.
fossil Decimal port 0 through 254 An initialized FOSSIL interface. The value is the zero-based value placed in register DX; 0 selects COM1.

Native descriptors, socket values, and handles have no fixed text width. Their values MUST fit the native unsigned descriptor or handle type of the launched door. The producer is responsible for making the object inheritable, arranging its inheritance, keeping the door's copy valid for the session, and selecting a mode the door supports.

socket is a clean terminal byte stream, not necessarily the caller's original network socket. A BBS can satisfy the contract with a socket pair and a bridge. A raw Telnet socket that can still carry IAC negotiation does not satisfy the contract.

The BBS MUST configure serial framing and speed before launch. A door MUST use the existing configuration; this format deliberately carries neither baud rate nor data/parity/stop-bit settings. For fossil, port 255 is reserved by FSC-0015 and is invalid in this format.

A consumer MUST reject an unknown or unsupported communications type. It MUST NOT guess a fallback mechanism or reinterpret line 3 as another type.

Versioning and extensions

Line 1 is a decimal major.minor format version. Neither component has leading zeroes. Version 1.0 has exactly the 19 lines in this document.

A later minor version MAY append fields after the fields defined by an earlier minor version, add registry values, or relax validation so that a representation which was previously invalid becomes valid. Examples of a relaxation include allowing an existing line to be empty or accepting an additional form of an existing value.

Minor-version changes MUST be monotonic: every file valid under an earlier minor version remains valid, with exactly the same meaning, under every later minor version of the same major. A minor version therefore MUST NOT remove or reorder existing lines, change the interpretation of a previously valid value, or make a previously valid file invalid. Any such change requires a new major version.

A consumer MUST accept supported minor versions of a supported major. When it encounters a newer minor version, it MUST NOT reject the file solely because the minor number is newer. It MUST parse the core it understands and ignore appended lines it does not understand. It MAY reject the file if a known line uses a newly permitted representation or registry value it does not understand, or if it does not support the selected communications mode.

A consumer MUST reject an unknown major version. Producers MUST NOT append private lines to a version 1.0 file; they must use a registered later minor version. A producer SHOULD write the earliest minor version that defines every representation and field it emits.

The companion ABNF grammar defines the byte-level structure of the version 1 core. The files below examples/ are canonical version 1.0 examples for every registered communications mode.

References

About

A drop file format that doesn't suck.

Resources

Stars

4 stars

Watchers

4 watching

Forks

Releases

Packages

Contributors