From d469999c2a542a13712da44a10870d83a304ea7f Mon Sep 17 00:00:00 2001 From: Christian Nennemann Date: Sat, 21 Mar 2026 19:14:01 +0100 Subject: [PATCH] feat: add Termux build/setup scripts and client config example --- qpc.toml.example | 53 +++++++++++++++++ scripts/build-termux.sh | 125 ++++++++++++++++++++++++++++++++++++++++ scripts/termux-setup.sh | 125 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 303 insertions(+) create mode 100644 qpc.toml.example create mode 100755 scripts/build-termux.sh create mode 100755 scripts/termux-setup.sh diff --git a/qpc.toml.example b/qpc.toml.example new file mode 100644 index 0000000..9bfedc8 --- /dev/null +++ b/qpc.toml.example @@ -0,0 +1,53 @@ +# quicprochat client configuration. +# +# Place this file at one of these paths (checked in order): +# 1. Path given by --config +# 2. $QPC_CONFIG env var +# 3. $XDG_CONFIG_HOME/qpc/config.toml (usually ~/.config/qpc/config.toml) +# 4. ~/.qpc.toml +# +# Precedence: CLI flags > environment variables > this file > defaults. +# All fields are optional — only set what you want to change. + +# ── Connection ──────────────────────────────────────────────────────────────── + +# Server address (host:port). +# server = "chat.example.com:7000" + +# TLS server name (must match certificate SAN). +# server_name = "chat.example.com" + +# Path to server's TLS certificate (for self-signed setups). +# ca_cert = "data/server-cert.der" + +# Skip TLS certificate verification (development/self-signed only!). +# danger_accept_invalid_certs = false + +# Don't auto-start a local qpc-server process. +# no_server = true + +# ── Authentication ──────────────────────────────────────────────────────────── + +# OPAQUE username — set this so you don't need to type -u every time. +# username = "alice" + +# OPAQUE password — if omitted, you'll be prompted securely. +# Storing passwords in config files is discouraged for shared devices. +# password = "secret" + +# ── State ───────────────────────────────────────────────────────────────────── + +# Path to client state file (identity keys + MLS state). +# Tip: use an absolute path on mobile (e.g. /data/data/com.termux/.../qpc-state.bin). +# state = "qpc-state.bin" + +# Password to encrypt the state file at rest (Argon2id + ChaCha20-Poly1305). +# state_password = "" + +# ── Advanced ────────────────────────────────────────────────────────────────── + +# Bearer/session token (alternative to OPAQUE login). +# access_token = "" + +# Device identifier (for multi-device setups). +# device_id = "" diff --git a/scripts/build-termux.sh b/scripts/build-termux.sh new file mode 100755 index 0000000..dbaadf7 --- /dev/null +++ b/scripts/build-termux.sh @@ -0,0 +1,125 @@ +#!/usr/bin/env bash +# Cross-compile quicprochat client for Termux (Android). +# +# Produces a statically linked, stripped aarch64 binary that runs on Termux +# without any runtime dependencies. +# +# Requires: cargo-zigbuild (preferred) or cross. +# +# Usage: +# ./scripts/build-termux.sh # aarch64 (default, most Android devices) +# ./scripts/build-termux.sh x86_64 # x86_64 (emulators, Chromebooks) +# ./scripts/build-termux.sh both # build both architectures +# +# Output: target//release/qpc (stripped, static) +# +# After building, copy to your phone: +# adb push target/aarch64-unknown-linux-musl/release/qpc /sdcard/Download/ +# Then in Termux: +# cp /sdcard/Download/qpc ~/../usr/bin/ && chmod +x ~/../usr/bin/qpc +# Or run the setup script: +# ./scripts/termux-setup.sh + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" +cd "$PROJECT_ROOT" + +# ── Target selection ────────────────────────────────────────────────────────── + +ARCH="${1:-aarch64}" + +case "$ARCH" in + aarch64|arm64) + TARGETS=(aarch64-unknown-linux-musl) + ;; + x86_64|x86) + TARGETS=(x86_64-unknown-linux-musl) + ;; + both|all) + TARGETS=(aarch64-unknown-linux-musl x86_64-unknown-linux-musl) + ;; + *) + echo "Usage: $0 [aarch64|x86_64|both]" >&2 + exit 1 + ;; +esac + +# ── Size-optimised release profile ──────────────────────────────────────────── + +export CARGO_PROFILE_RELEASE_OPT_LEVEL=s +export CARGO_PROFILE_RELEASE_LTO=true +export CARGO_PROFILE_RELEASE_CODEGEN_UNITS=1 +export CARGO_PROFILE_RELEASE_STRIP=symbols + +# ── Build tool detection ────────────────────────────────────────────────────── + +if command -v cargo-zigbuild &>/dev/null; then + BUILD_CMD="cargo zigbuild" +elif command -v cross &>/dev/null; then + BUILD_CMD="cross build" +else + echo "ERROR: Install a cross-compilation tool:" >&2 + echo " cargo install cargo-zigbuild # recommended (no Docker)" >&2 + echo " cargo install cross # alternative (needs Docker)" >&2 + exit 1 +fi + +# ── Features to include ────────────────────────────────────────────────────── + +# TUI is great on Termux (full terminal emulation), include it by default. +FEATURES="tui" + +echo "=== quicprochat Termux build ===" +echo "Build tool: $BUILD_CMD" +echo "Targets: ${TARGETS[*]}" +echo "Features: $FEATURES" +echo "" + +# ── Build ───────────────────────────────────────────────────────────────────── + +FAILED=() +OUTPUTS=() + +for target in "${TARGETS[@]}"; do + echo "--- Building qpc for $target ---" + if $BUILD_CMD --release --target "$target" --bin qpc --features "$FEATURES"; then + BINARY="target/$target/release/qpc" + if [ -f "$BINARY" ]; then + SIZE=$(stat -c%s "$BINARY" 2>/dev/null || stat -f%z "$BINARY") + SIZE_MB=$(echo "scale=2; $SIZE / 1048576" | bc) + echo " Binary: $BINARY" + echo " Size: ${SIZE_MB} MB" + OUTPUTS+=("$BINARY") + else + echo " ERROR: Binary not found at $BINARY" >&2 + FAILED+=("$target (binary not found)") + fi + else + echo " ERROR: Build failed for $target" >&2 + FAILED+=("$target (build failed)") + fi + echo "" +done + +# ── Summary ─────────────────────────────────────────────────────────────────── + +if [ ${#FAILED[@]} -gt 0 ]; then + echo "=== FAILURES ===" + for f in "${FAILED[@]}"; do + echo " - $f" + done + exit 1 +fi + +echo "=== Build successful ===" +echo "" +echo "Copy to your Android device:" +for out in "${OUTPUTS[@]}"; do + echo " adb push $out /sdcard/Download/qpc" +done +echo "" +echo "Then in Termux, run the setup script:" +echo " curl -sSL /scripts/termux-setup.sh | bash" +echo " # or copy scripts/termux-setup.sh to the device and run it" diff --git a/scripts/termux-setup.sh b/scripts/termux-setup.sh new file mode 100755 index 0000000..87fe5bc --- /dev/null +++ b/scripts/termux-setup.sh @@ -0,0 +1,125 @@ +#!/data/data/com.termux/files/usr/bin/bash +# Termux setup script for quicprochat. +# +# Run this ON your Android device inside Termux after copying the qpc binary. +# +# What it does: +# 1. Installs the qpc binary to $PREFIX/bin/ +# 2. Creates a default config at ~/.config/qpc/config.toml +# 3. Sets up a data directory for state files +# +# Usage: +# # If you have a pre-built binary on /sdcard: +# bash termux-setup.sh +# +# # If you want to build from source in Termux: +# bash termux-setup.sh --build + +set -euo pipefail + +PREFIX="${PREFIX:-/data/data/com.termux/files/usr}" +CONFIG_DIR="$HOME/.config/qpc" +DATA_DIR="$HOME/.local/share/qpc" + +echo "=== quicprochat Termux setup ===" +echo "" + +# ── Install binary ──────────────────────────────────────────────────────────── + +if [ "${1:-}" = "--build" ]; then + echo "Building from source (this will take a while)..." + pkg install -y rust git + if [ ! -d "$HOME/quicprochat" ]; then + echo "Clone the repository first:" + echo " git clone ~/quicprochat" + exit 1 + fi + cd "$HOME/quicprochat" + cargo build --release --bin qpc --features tui + cp target/release/qpc "$PREFIX/bin/qpc" + echo " Built and installed qpc to $PREFIX/bin/" +else + # Look for pre-built binary in common locations. + FOUND="" + for candidate in \ + /sdcard/Download/qpc \ + /sdcard/qpc \ + "$HOME/qpc" \ + "$HOME/storage/downloads/qpc"; do + if [ -f "$candidate" ]; then + FOUND="$candidate" + break + fi + done + + if [ -z "$FOUND" ]; then + echo "No qpc binary found. Place it in one of:" + echo " /sdcard/Download/qpc" + echo " ~/qpc" + echo "" + echo "Or build from source: bash $0 --build" + exit 1 + fi + + cp "$FOUND" "$PREFIX/bin/qpc" + chmod +x "$PREFIX/bin/qpc" + echo " Installed $FOUND -> $PREFIX/bin/qpc" +fi + +# ── Create directories ──────────────────────────────────────────────────────── + +mkdir -p "$CONFIG_DIR" "$DATA_DIR" + +# ── Create default config ───────────────────────────────────────────────────── + +if [ -f "$CONFIG_DIR/config.toml" ]; then + echo " Config already exists: $CONFIG_DIR/config.toml (not overwriting)" +else + # Prompt for basic settings. + echo "" + read -rp "Server address [127.0.0.1:7000]: " SERVER + SERVER="${SERVER:-127.0.0.1:7000}" + + read -rp "Username: " USERNAME + + # Extract hostname for TLS server_name. + SERVER_HOST="${SERVER%%:*}" + + cat > "$CONFIG_DIR/config.toml" << TOML +# quicprochat client config — generated by termux-setup.sh +# Edit this file instead of passing CLI flags. +# Precedence: CLI flags > env vars > this file > defaults. + +# Server to connect to. +server = "$SERVER" +server_name = "$SERVER_HOST" + +# Your username (OPAQUE login — password is prompted on first run). +username = "$USERNAME" + +# Skip TLS verification for self-signed certs (set false for production). +danger_accept_invalid_certs = true + +# Don't try to auto-start a local server. +no_server = true + +# State/data files are stored here (relative paths resolve from cwd, +# so use absolute paths on Termux). +state = "$DATA_DIR/qpc-state.bin" +# ca_cert = "/path/to/server-cert.der" +TOML + echo " Created config: $CONFIG_DIR/config.toml" +fi + +# ── Done ────────────────────────────────────────────────────────────────────── + +echo "" +echo "=== Setup complete ===" +echo "" +echo "Start chatting:" +echo " qpc" +echo "" +echo "Edit your config:" +echo " nano ~/.config/qpc/config.toml" +echo "" +echo "Your data is stored in: $DATA_DIR"