
ssh-chat in modern c

General BBS Software
SSH-Chatter has started from a C reimplementation of the Go ssh-chat server. It mirrors/extends the original behaviour while using modern C patterns and a small, testable core. The server listens for SSH/TELNET connections and places every authenticated user into a shared chat room that exposes the same command surface as the Go reference implementation.
Do you know why it takes so long to understand C? Because it is an instinct.
/rss list, /rss read <tag>, plus /rss add <url> <tag> and /rss del <tag> (operators only) so the room can browse headlines together./delete-msg for targeted chat history cleanup./bbs command unlocking an immersive retro bulletin board system with tags, comments, bumping, and a multi-line composer.
bumped (recent activity), hot (trending by score & comments), top (highest net upvotes score), or new (creation date) using list [hot|top|new|bumped|all].search <query>.▲ 12 💬 5) directly in listings./bbs prefix inside BBS mode./asciiart live composer with a 640-line limit, a ten-minute per-IP cooldown, multi-line output, and keyboard shortcuts for cancelling with Ctrl+A and submitting with Ctrl+S or the locale-aware >/__ARTWORK_END> default./birthday to register birthdays, /grant <ip> so LAN operators can delegate privileges by address, and /revoke <ip> so top LAN admins can reclaim them./ban upgrades that accept raw IP addresses alongside usernames./weather <city> for quick global forecasts.

The codebase is intentionally compact so new contributors can navigate it quickly:
| Path | Description |
|---|---|
src/main.c | Command-line parsing and process bootstrap (bind address, port, MOTD, host key directory). |
src/host_aggregate.c, include/ssh_chatter/host.h | Chat host implementation – session lifecycle, MOTD handling, and hooks for future message broadcast logic. |
src/host | Modular host subsystems that compile into a single translation unit through src/host_aggregate.c. |
include/ssh_chatter | Shared headers for the daemon, stress tools, and the translation backend. |
include/ssh_chatter/contexts | Definitions for session_ctx_t and related structures that encapsulate per-connection state. |
data/banner/banner | Sample welcome banner that can be pointed to with CHATTER_WELCOME_BANNER. |
scripts/install_chatter_service.sh | Convenience installer that builds the binary, installs it under /usr/local/bin, and wires up a systemd unit (chatter.service). |
scripts/install_dependencies.sh | Minimal package installer for build prerequisites on Debian/Ubuntu systems. |

mainThe work branch regularly diverges from upstream development so larger features can
incubate without interrupting production traffic. When it is time to synchronize with
main, pull the latest tree and merge it locally before opening a pull request:
git fetch origin main
git checkout work
git merge --no-ff origin/main
Resolve any conflicts in place (the src/host_aggregate.c helper routines already mirror the
layout used on main, so merges are typically straightforward) and run make to
confirm the build still succeeds before pushing the result.
host_snapshot_last_captcha exposes the most recently generated captcha prompt and answer along with a timestamp so external clients can pass challenges on behalf of unattended automation.scripts/safe_permission.sh tightens the ownership and mode on runtime data files (BBS state, vote state, cooldown snapshots, and general chatter state). Run it after deployment to confine the data directory to ssh-chatter and to ensure each file is set to 0600. Override the targets by passing explicit paths or by exporting STATE_ROOT or the corresponding CHATTER_*_FILE environment variables before execution.CHATTER_SECURITY_AI=on (set GEMINI_API_KEY for Gemini; the daemon automatically falls back to the local Ollama endpoint at http://127.0.0.1:11434). Disable everything with CHATTER_SECURITY_FILTER=off. If every provider fails, the filter automatically disables itself to keep conversations flowing instead of silently dropping content.CHATTER_AUTO_BAN=on (or true/1) to enable them, or leave the variable unset to keep warnings and throttling without writing automatic ban entries.CHATTER_PROTECTED_IPS (comma-separated, defaults to 127.0.0.1,::1,192.168.0.1) so emergency bans never lock the daemon out of its own control plane.