#!/bin/bash # List peers — JSON array, one row per peer. Used by the WebUI generator and # the CLI's `libreportal peer list` command. Output is one line of JSON. peerList() { local out='[' local first=1 local row while IFS='|' read -r id name kind config_json status last_seen created_at; do [[ -z "$id" ]] && continue # Each field is sqlite-escaped (single-quote-doubled) and JSON-encoded # on the way out — and config_json is already JSON so we paste it raw. local name_e="${name//\\/\\\\}"; name_e="${name_e//\"/\\\"}" local kind_e="${kind//\\/\\\\}"; kind_e="${kind_e//\"/\\\"}" local status_e="${status//\\/\\\\}"; status_e="${status_e//\"/\\\"}" local last_e="${last_seen//\\/\\\\}"; last_e="${last_e//\"/\\\"}" local created_e="${created_at//\\/\\\\}"; created_e="${created_e//\"/\\\"}" local cfg="${config_json:-{\}}" (( first )) || out+="," first=0 out+="{\"id\":$id,\"name\":\"$name_e\",\"kind\":\"$kind_e\",\"config\":$cfg,\"status\":\"$status_e\",\"last_seen\":\"$last_e\",\"created_at\":\"$created_e\"}" done < <(sqlite3 "$(_peerDb)" "SELECT id, name, kind, config_json, COALESCE(status,''), COALESCE(last_seen,''), COALESCE(created_at,'') FROM peers ORDER BY name;" 2>/dev/null) out+=']' echo "$out" } peerGet() { local name="$1" if [[ -z "$name" ]]; then echo "null"; return 1; fi local row row=$(sqlite3 "$(_peerDb)" "SELECT id, name, kind, config_json, COALESCE(status,''), COALESCE(last_seen,''), COALESCE(created_at,'') FROM peers WHERE name='$(peerSqlEscape "$name")';" 2>/dev/null) [[ -z "$row" ]] && { echo "null"; return 1; } local id n k cfg s last created IFS='|' read -r id n k cfg s last created <<< "$row" local name_e="${n//\\/\\\\}"; name_e="${name_e//\"/\\\"}" local kind_e="${k//\\/\\\\}"; kind_e="${kind_e//\"/\\\"}" printf '{"id":%s,"name":"%s","kind":"%s","config":%s,"status":"%s","last_seen":"%s","created_at":"%s"}\n' \ "$id" "$name_e" "$kind_e" "${cfg:-{\}}" "$s" "$last" "$created" } # Lookup peer name by hostname. Walks the backup-channel peers, parses their # config.hostname, returns the matching peer name (or empty). Cheap; small N. peerNameForHostname() { local hostname="$1" [[ -z "$hostname" ]] && return 1 local row while IFS='|' read -r name cfg; do [[ -z "$name" ]] && continue local h h=$(printf '%s' "$cfg" | grep -o '"hostname":"[^"]*"' | head -1 | cut -d'"' -f4) if [[ "$h" == "$hostname" ]]; then echo "$name" return 0 fi done < <(sqlite3 "$(_peerDb)" "SELECT name, config_json FROM peers WHERE kind='backup-channel';" 2>/dev/null) return 1 }