Getting Started
OxideBBS is a local Rust BBS server with:
- Telnet caller runtime
- ANSI/CP437 rendering
- DecentDB persistence
- DOS door launch support
- CLI-first sysop operations
Prerequisites
- Rust stable with
rustfmtandclippy - Node.js 20 or newer (documentation site only)
- Native DecentDB headers:
sudo apt-get install -y clang libclang-devFrom repository root, the normal validation command is:
./scripts/dev-check.shFor Windows, macOS, or sysops who want the packaged Linux runtime with DOSEMU2 included, start with Docker Deployment instead of installing native build prerequisites.
1) Create a board
cargo run -p oxidebbs-server -- setupsetup creates config/oxidebbs.toml, initializes data/oxidebbs.ddb, creates the initial sysop account, and prepares runtime/asset directories.
For unattended setup, pass required values:
cargo run -p oxidebbs-server -- setup \
--board-name "My BBS" \
--sysop-alias sysop \
--sysop-password "change-this" \
--nodes 42) Validate config and runtime paths
cargo run -p oxidebbs-server -- check
cargo run -p oxidebbs-server -- config checkValidation checks:
- socket address parsing
- config paths and screen assets
- door definitions and runner availability
- drop-file format and timeout constraints
- runtime directory writability
check errors on missing/invalid configuration and reports warnings for optional but missing directories or assets.
Install your distribution's DOSEMU2 package before live door testing. The runtime executable is commonly named dosemu, but legacy dosemu-1.x is not supported because it does not accept OxideBBS's run-local pts <path> COM1 mapping.
dosemu --versionThe version output should identify DOSEMU2, not dosemu-1.x.
Fedora users should follow the DOSEMU2 on Fedora guide because the validated package set requires the stsp/dosemu2 Copr packages and a DJ64 loader-path check.
For Debian 13 LXC hosts, verify PTYs are present and writable by the runtime user; DOSEMU2 uses this for COM1 bridging:
test -d /dev/pts && ls -ld /dev/ptsValidate the bundled test door without DOSEMU2:
cargo run -p oxidebbs-server -- --config config/oxidebbs.example.toml doors check oxide-check
cargo run -p oxidebbs-server -- --config config/oxidebbs.example.toml doors dropfile oxide-check --user sysop --node 1 --format DORINFO1.DEF
cargo run -p oxidebbs-server -- --config config/oxidebbs.example.toml doors test oxide-check --user sysop --dry-runFree Pascal (i8086-msdos) is only needed when maintaining tools/doors/oxide-door-check/src/oxidechk.pas. check, dropfile, and --dry-run validation do not need it.
The v1 live model does not use DOS console I/O. During a caller door session, OxideBBS pauses normal menu parsing and forwards raw bytes through this path:
caller telnet client
<-> OxideBBS caller transport
<-> OxideBBS PTY byte bridge
<-> DOSEMU2 COM1 pts backend
<-> DOSEMU2-emulated COM1 UART
<-> DOS door programOxideBBS starts DOSEMU2 with COM1 mapped to the per-node PTY path:
$_com1 = "pts <absolute/path/to/runtime/node-001/OXCOM1.PTY>"Per-run DOSEMU2 config is written to OXDOSEMU2.CONF and includes:
$_cpu_vm = "emulated"
$_cpu_vm_dpmi = "emulated"
$_sound = (off)
$_mouse_internal = (off)
$_joy_device = ""
$_pktdriver = (off)
$_tcpdriver = (off)
$_ttylocks = ""When the caller presses a key, OxideBBS reads that byte from telnet and writes it to the PTY bridge. DOSEMU2 receives it on COM1 and passes it to the door. When the door writes to COM1, DOSEMU2 emits those bytes on the PTY bridge, and OxideBBS writes them to the caller's telnet connection. That means an end-to-end smoke test validates both launch and serial transport behavior, not just console I/O.
DOSEMU2 maps COM1 directly to the host PTY, so this is not a Rust-hosted FOSSIL driver. The host bridge is byte transport only. A DOS-side FOSSIL TSR can be loaded inside DOSEMU2 if a specific door explicitly requires FOSSIL APIs.
In this model there is no SDL window and no display-server requirement for door runtime.
3) Start serving
cargo run -p oxidebbs-server -- serveserve binds telnet, accepts caller sessions, persists session/audit rows, and starts the local Unix control socket:
runtime/oxidebbs-control.sockIf that socket path is already active, startup fails to avoid clobbering an already-running server.
4) Confirm runtime
cargo run -p oxidebbs-server -- status
cargo run -p oxidebbs-server -- nodes list
cargo run -p oxidebbs-server -- nodes watchWhile running, node status comes from live runtime registry and includes heartbeat age. If the socket is unreachable, status/list/watch read through active session rows from DecentDB.
5) Use local sysop controls
cargo run -p oxidebbs-server -- nodes message 1 "Maintenance in 10 minutes."
cargo run -p oxidebbs-server -- nodes disconnect 1
cargo run -p oxidebbs-server -- nodes broadcast "Server restart at 00:00 UTC."
cargo run -p oxidebbs-server -- nodes reset-staleWhen the control socket is unavailable, these commands still record explicit sysop intent in audit rows and return explicit messaging explaining the delivery gap.
6) Doors and data safety checks
cargo run -p oxidebbs-server -- doors check oxide-check
cargo run -p oxidebbs-server -- doors test oxide-check --user sysop --dry-runCaller Doors menu launch uses live door execution in the caller path and records door run rows with timeout and byte counters. With DOSEMU2 configured and oxide-check enabled, run the door from the caller Doors menu to complete an end-to-end live test and confirm:
- caller keystrokes reach the door through DOSEMU2 COM1,
- door output written to COM1 reaches the caller telnet session,
- the door responds to keyboard input,
- and
OXIDECHK.RPT/OXNODE.TXTare created under the node runtime directory.
Optional live smoke test command:
OXIDE_DOOR_INTERACTIVE=1 ./scripts/test-oxide-door-dosemu2.sh7) Backup, export, and restore
cargo run -p oxidebbs-server -- db backup backups/oxidebbs.ddb
cargo run -p oxidebbs-server -- db export --format json > backups/oxidebbs.json
cargo run -p oxidebbs-server -- db import --format json backups/oxidebbs.jsondb import --format json is a full restore into schema-only targets only. It is transactional and validates IDs, relationships, and schema compatibility.
db compact is explicitly unsupported in this release because DecentDB has no safe compaction API contract.
8) Local-only boundary
There is no remote web or TCP admin interface in this phase. All operational control is local to the host running oxidebbs-server.