A chat server written in C++
  • C++ 79.8%
  • HTML 4.9%
  • Go Template 3.2%
  • Shell 3.1%
  • Makefile 2.4%
  • Other 6.6%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2026-08-02 17:35:50 +03:00
ychat Bump version to 0.9.3 for ychat, yhttpd, ycurses 2026-08-02 17:35:50 +03:00
ycurses Bump version to 0.9.3 for ychat, yhttpd, ycurses 2026-08-02 17:35:50 +03:00
yhttpd Bump version to 0.9.3 for ychat, yhttpd, ycurses 2026-08-02 17:35:50 +03:00
AGENTS.md docs: move f3s/k8s deployment details out to homelab skill 2026-07-07 16:42:47 +03:00
CLAUDE.md docs: add AGENTS.md (with f3s skill pointer) and CLAUDE.md 2026-07-03 23:20:15 +03:00
README.md Bump version to 0.9.3 for ychat, yhttpd, ycurses 2026-08-02 17:35:50 +03:00

ychat / yhttpd / ycurses

This repository collects three small, legacy C++ projects by Paul C. Buetow (originally ~20032007). They share a common socket/event/template engine and are kept here as historical/revival code.

Subproject What it is Status
./ychat An HTTP-based web chat server (browsers are the clients; CSS/HTML/JS only). Revived, builds in Docker with a mandatory embedded-SQLite backend (real, persistent registered accounts) — see ychat/DOCKER.md.
./yhttpd A tiny standalone http server derived from ychat's socket/threading engine. Builds and serves reliably in Docker (verified under concurrent load) — not deployed. See ./yhttpd/DOCKER.md.
./ycurses A curses front-end experiment. Builds and runs in Docker (a demo, not a service, so nothing to deploy) — see ./ycurses/BUILD.md.

The detailed, up-to-date build/deploy notes for the chat live in ./ychat/DOCKER.md. The rest of this file is a quickstart for running ychat locally in Docker and accessing it.

The ychat tree has been substantially fixed during this revival (legacy-C++ build fixes, a from-scratch streaming-chat layer, and a security/bug sweep). See git log under ./ychat and ./ychat/DOCKER.md for the full list.


Quickstart: run ychat locally in Docker

You need a container runtime (podman or docker). The build is a multi-stage Dockerfile (Rocky Linux 9 builder + slim Rocky 9 runtime) that compiles ychat entirely inside the container — no host toolchain required.

1. Build the image

From the repository root:

cd ychat
podman build -t ychat:dev .
# or:  docker build -t ychat:dev .

The build configures ychat with SSL and readline off, but a database is not optional: ./configure always requires SQLite (sqlite3.h/libsqlite3), so registration/login persist in a SQLite file across container restarts. The default chat port is 2000.

2. Run it

mkdir -p /tmp/ychat-data && chmod 777 /tmp/ychat-data   # see DOCKER.md for why
podman run --rm -p 2000:2000 --name ychat -v /tmp/ychat-data:/app/data:Z ychat:dev
# or:  docker run --rm -p 2000:2000 --name ychat -v /tmp/ychat-data:/app/data ychat:dev

The server logs to stdout. You should see something like:

yChat 0.9.3-CURRENT Build ...
Sock: Created socket on localhost:2000
Sock: Server socket is ready
Initializing sock events (1)

3. Access it

Open http://localhost:2000/ in a browser.

  • You'll get the full login page (password field + "Register" link). You can register a nick/password (persisted in the SQLite file under /app/data), or leave the password blank and log in as an unregistered guest — chat.enableguest=true allows that regardless of the database.
  • Enter any alphanumeric nick (e.g. alice), leave the room as Lounge, and click login.
  • The chat frameset loads: a streaming message view, the online-user list, and an input box. Type a message and hit Send — it appears in the stream.
  • Open a second browser/window with a different nick in the same room to see messages delivered to both clients in real time.

Quick CLI checks:

# the login page (HTTP/1.1, 200):
curl -sS http://localhost:2000/ -o /dev/null -w '%{http_code}\n'

# log in and grab a session tmpid:
curl -sS -X POST -d 'event=login&nick=alice&room=Lounge&end=end' \
     http://localhost:2000/frameset.html

4. Stop it

podman rm -f ychat
# (Ctrl-C also stops the foreground `run` above)

Notes on the local run

  • Registered accounts persist; guest sessions don't. The SQLite file at /app/data/ychat.db (bind-mount it, as above, to survive container restarts) holds registered users. Sessions/rooms/online-state are still in-memory, and unregistered chat.enableguest=true guest chatters are wiped on restart same as before — only the accounts table persists.
  • Logs go to /app/log/ inside the container (access_log, system_log, rooms/<room>). They're a container-local dir locally, so they don't persist after rm.
  • Configuration is ychat/etc/ychat.conf, baked into the image at /app/etc/ychat.conf. You can override any config key at runtime with -o <key> <value> (the image already does this for chat.session.md5hash=false and chat.database.dbname=data/ychat.db). Example: podman run --rm -p 2000:2000 ychat:dev /app/bin/ychat -o chat.idle.timeout 300.
  • The /exec command module is removed from the image entirely (defense-in-depth against its shell-injection RCE), and operator status via chat.defaultop now requires a database-authenticated registered account — an unregistered guest can never claim it. Other privileged commands (/ko, /ban, …) work normally for a registered operator.

License

GPL-2.0 (see ./ychat/COPYING). Source: https://codeberg.org/snonux/ychat