aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md138
1 files changed, 115 insertions, 23 deletions
diff --git a/README.md b/README.md
index b5fc3fe..f91a64a 100644
--- a/README.md
+++ b/README.md
@@ -4,11 +4,11 @@ A lean XMPP AI chatbot in C. It joins MUC rooms, logs messages,
answers `@bot` commands via an OpenAI-compatible LLM HTTP API, and runs
`@scriptname` commands backed by local scripts.
-A C reimplementation of the Python `bot.py` in the parent directory,
-written in the suckless spirit: one source file, one library
+
+Inspired by the suckless spirit: one source file, one library
dependency (OpenSSL), fixed buffers, no runtime config parser.
-There is **no end-to-end / OMEMO encryption**. Transport is still
+There is **no end-to-end OMEMO/OTR encryption**. Transport is still
encrypted: STARTTLS for the XMPP connection, HTTPS for the LLM API.
## Build
@@ -27,13 +27,23 @@ Edit `config.h` (not the `.def`) to set your server, rooms and model.
Non-secret settings live in `config.h`. Recompile after changing it.
-Secrets are read from the environment, never stored on disk by the bot:
+Secrets are read from the environment, never stored on disk by the bot.
+Export them by hand:
```sh
export XMPP_PASSWORD='the-bot-account-password'
export LLM_API_KEY='sk-...'
```
+Or use the bundled `start` script, which sets both variables and then
+execs the bot. Copy the template, fill in your secrets, and lock it
+down so only you can read it:
+
+```sh
+cp start.sample start
+chmod 700 start
+```
+
`instruction.md` holds the system prompt; it is read once at startup.
On a fresh checkout, copy `instruction.md.sample` to `instruction.md`,
then edit it and restart to change the bot's behaviour.
@@ -80,6 +90,9 @@ Run from the directory containing `instruction.md` and `config.h`:
./xmppcb
```
+If you set up the `start` script above, run `./start` instead — it
+exports the secrets, `cd`s into this directory and execs the bot.
+
It reconnects automatically after a dropped connection. On an
authentication failure it exits with status 1 (no retry loop).
Logs go to stderr. Per-room chat history is appended to
@@ -143,29 +156,110 @@ do not let scripts print secrets. `CMD_DIR` and `CMD_TIMEOUT_SEC` are in
## Run under a supervisor
-The bot does not daemonise. Use a process supervisor so it restarts
-and starts at boot.
+The bot does not daemonise and does not restart itself after it exits.
+Use a process supervisor so it restarts on crash and comes up at boot.
+Each example runs the `start` script, so no secrets land in the
+supervisor config. Replace `/home/xmppcb/xmppcb` and the `xmppcb`
+user/group with yours.
+
+The scripts below are example templates, not tested on every release —
+check them against your OS version before relying on them.
+
+### FreeBSD (rc.d)
+
+`/usr/local/etc/rc.d/xmppcb`:
+
+```sh
+#!/bin/sh
+# PROVIDE: xmppcb
+# REQUIRE: NETWORKING
+# KEYWORD: shutdown
+. /etc/rc.subr
+
+name=xmppcb
+rcvar=xmppcb_enable
+load_rc_config $name
+
+: ${xmppcb_enable:="NO"}
+: ${xmppcb_user:="xmppcb"}
+: ${xmppcb_dir:="/home/xmppcb/xmppcb"}
+
+pidfile="/var/run/${name}.pid"
+command="/usr/sbin/daemon"
+command_args="-r -P ${pidfile} -u ${xmppcb_user} ${xmppcb_dir}/start"
+
+run_rc_command "$1"
+```
-systemd (`/etc/systemd/system/xmppcb.service`):
+`chmod +x` it, then `sysrc xmppcb_enable=YES` and
+`service xmppcb start`. `daemon -r` restarts the bot if it dies.
-```ini
-[Unit]
-Description=xmppcb XMPP AI bot
-After=network-online.target
+### OpenBSD (rc.d)
+
+`/etc/rc.d/xmppcb`:
+
+```sh
+#!/bin/ksh
+daemon="/home/xmppcb/xmppcb/start"
+daemon_user="_xmppcb"
+
+. /etc/rc.d/rc.subr
+rc_bg=YES
+rc_cmd $1
+```
-[Service]
-WorkingDirectory=/home/youruser/xmpp-bot/xmppcb
-ExecStart=/home/youruser/xmpp-bot/xmppcb/xmppcb
-Environment=XMPP_PASSWORD=...
-Environment=LLM_API_KEY=...
-Restart=always
-RestartSec=10
+`chmod +x` it, then `rcctl enable xmppcb` and `rcctl start xmppcb`.
+OpenBSD's rc.d starts the bot at boot but does not respawn it on
+crash; pair it with a cron check or a supervisor if you need that.
-[Install]
-WantedBy=multi-user.target
+### OpenRC
+
+`/etc/init.d/xmppcb`:
+
+```sh
+#!/sbin/openrc-run
+description="xmppcb XMPP AI bot"
+command="/home/xmppcb/xmppcb/start"
+command_user="xmppcb:xmppcb"
+supervisor="supervise-daemon"
+respawn_delay=10
+
+depend() {
+ need net
+}
+```
+
+`chmod +x` it, then `rc-update add xmppcb default` and
+`rc-service xmppcb start`. `supervise-daemon` handles the restart.
+
+### sysvinit
+
+sysvinit respawns processes listed in `/etc/inittab`. Add one line:
+
+```
+xb:2345:respawn:/bin/su -s /bin/sh -c /home/xmppcb/xmppcb/start xmppcb
+```
+
+Then run `telinit q` to reload. The `respawn` action gives you both
+boot start and restart-on-crash without a separate init script.
+
+### runit
+
+`/etc/sv/xmppcb/run`:
+
+```sh
+#!/bin/sh
+exec chpst -u xmppcb:xmppcb /home/xmppcb/xmppcb/start
+```
+
+`chmod +x` it, then link the service into the scan directory:
+
+```sh
+ln -s /etc/sv/xmppcb /var/service/
```
-Prefer an `EnvironmentFile=` with mode 600 over inline secrets.
+(some distributions use `/etc/service` or `/run/runit/service`).
+runit supervises and restarts the bot automatically.
## Notes and limitations
@@ -184,9 +278,7 @@ xmppcb/
├── config.def.h config template (committed)
├── config.h your config (copied from .def, gitignored)
├── instruction.md.sample system prompt template (committed)
-├── instruction.md system prompt in use (gitignored)
├── start.sample run-script template (committed)
-├── start run script exporting the secrets (gitignored)
├── cmd/ @scriptname command scripts (weather, uptime, fx)
├── makefile
└── history/ per-room chat logs (generated, gitignored)