diff --git a/includes/nips b/includes/nips new file mode 160000 index 00000000..05d3f198 --- /dev/null +++ b/includes/nips @@ -0,0 +1 @@ +Subproject commit 05d3f198c61c2732ccf15ba8005299365dabb8e0 diff --git a/iso/config/hooks/live/0020-enable-services.hook.chroot b/iso/config/hooks/live/0020-enable-services.hook.chroot index a8492406..3ef0860d 100755 --- a/iso/config/hooks/live/0020-enable-services.hook.chroot +++ b/iso/config/hooks/live/0020-enable-services.hook.chroot @@ -1,26 +1,35 @@ #!/bin/sh -# Enable n-OS-tr services so they start automatically on boot. -set -e +# Configure boot-time enable/disable posture for n-OS-tr services. +set -eu # Disable the Debian default site so it doesn't conflict with ours. rm -f /etc/nginx/sites-enabled/default -# Enable our site. +# Enable our site symlink only. Runtime nginx startup is user-selected in TUI. ln -sf /etc/nginx/sites-available/n-os-tr.conf /etc/nginx/sites-enabled/n-os-tr.conf -systemctl enable nginx.service - -# Slice A -systemctl enable ginxsom.service -systemctl enable n-os-tr-firstboot.service - -# Slice B -systemctl enable fips.service || true -systemctl enable fips-dns.service || true - -# Slice C -systemctl enable c-relay.service - -# TUI on tty1 +# TTY handoff: identity TUI owns tty1 before getty. systemctl disable getty@tty1.service || true + +# Always-on boot pipeline. +systemctl enable n-os-tr-firstboot.service +systemctl enable nostr-id.service || true systemctl enable nostr-id-tui.service + +# Explicitly keep optional services disabled at boot. +for unit in \ + c-relay.service \ + ginxsom.service \ + fips.service \ + fips-dns.service \ + nginx.service \ + nostr-config-loader.service \ + nostr-config-writer.service \ + ssh.service \ + tor.service + do + systemctl disable "$unit" 2>/dev/null || true + done + +# Apply preset policy for any additional units. +systemctl preset-all --preset-mode=enable-only 2>/dev/null || true diff --git a/iso/config/includes.chroot/etc/n-os-tr/services.conf b/iso/config/includes.chroot/etc/n-os-tr/services.conf new file mode 100644 index 00000000..6432609c --- /dev/null +++ b/iso/config/includes.chroot/etc/n-os-tr/services.conf @@ -0,0 +1,9 @@ +# key\tunit\tlabel\tdefault\tdeps +r c-relay.service c-relay off nginx.service +g ginxsom.service ginxsom off nginx.service +f fips.service fips off - +n nginx.service nginx off - +l nostr-config-loader.service config-loader off - +w nostr-config-writer.service config-writer off nostr-config-loader.service +s ssh.service ssh off - +t tor.service tor off - diff --git a/iso/config/includes.chroot/etc/systemd/system-preset/50-n-os-tr.preset b/iso/config/includes.chroot/etc/systemd/system-preset/50-n-os-tr.preset new file mode 100644 index 00000000..38adab14 --- /dev/null +++ b/iso/config/includes.chroot/etc/systemd/system-preset/50-n-os-tr.preset @@ -0,0 +1,16 @@ +# n-OS-tr service posture: only identity + firstboot + TUI start automatically. +# Optional services are loaded/installed but disabled by default. + +enable n-os-tr-firstboot.service +enable nostr-id.service +enable nostr-id-tui.service + +disable c-relay.service +disable ginxsom.service +disable fips.service +disable fips-dns.service +disable nginx.service +disable nostr-config-loader.service +disable nostr-config-writer.service +disable ssh.service +disable tor.service diff --git a/iso/config/package-lists/base.list.chroot b/iso/config/package-lists/base.list.chroot index e6b5b6aa..32090112 100644 --- a/iso/config/package-lists/base.list.chroot +++ b/iso/config/package-lists/base.list.chroot @@ -15,3 +15,6 @@ nftables # TUI runtime dependency libncursesw6 + +# Service-menu optional stack +tor diff --git a/n_os_tr.code-workspace b/n_os_tr.code-workspace new file mode 100644 index 00000000..22619dfb --- /dev/null +++ b/n_os_tr.code-workspace @@ -0,0 +1,13 @@ +{ + "folders": [ + { + "path": "." + }, + { + "path": "../aesthetics" + } + ], + "settings": { + "git.ignoreLimitWarning": true + } +} \ No newline at end of file diff --git a/plans/iso_architecture.md b/plans/iso_architecture.md index 5d4f0720..87ee158e 100644 --- a/plans/iso_architecture.md +++ b/plans/iso_architecture.md @@ -7,12 +7,13 @@ survive individual work sessions. ## 1. Big-picture goal A single bootable/installable Debian Live ISO that, the moment it finishes -booting, is running: +booting, has all n-OS-tr services installed and configured, then presents a +boot-time identity + service-selection TUI before login: -- [`fips`](../includes/fips) — Rust mesh-routing daemon, npub-addressed IPv6 overlay -- [`c-relay`](../includes/c-relay) — C Nostr relay with event-based config and embedded admin -- [`ginxsom`](../includes/ginxsom) — C Blossom (blob) server as FastCGI behind nginx -- `nginx` — TLS front door, static blob serving, reverse proxy +- [`fips`](../includes/fips) — Rust mesh-routing daemon, npub-addressed IPv6 overlay (optional start) +- [`c-relay`](../includes/c-relay) — C Nostr relay with event-based config and embedded admin (optional start) +- [`ginxsom`](../includes/ginxsom) — C Blossom (blob) server as FastCGI behind nginx (optional start) +- `nginx` — TLS front door, static blob serving, reverse proxy (optional start) No Docker. No `curl | bash` provisioning. All three apps run as native systemd services directly on the host. @@ -116,28 +117,46 @@ sequenceDiagram participant LB as live-boot / initramfs participant Sd as systemd PID 1 participant Fb as n-os-tr-firstboot.service + participant IA as nostr-id.service + participant TUI as nostr-id-tui.service participant Fp as fips.service participant Cr as c-relay.service participant Gx as ginxsom.service participant Ng as nginx.service + participant GT as getty@tty1.service LB->>Sd: hand off - Sd->>Fb: start oneshot (Before= the app units) + Sd->>Fb: start oneshot (Before= identity + app units) alt First boot Fb->>Fb: mkdir /var/lib/n-os-tr
generate ginxsom key
generate fips key
write EnvironmentFile
touch .provisioned else Already provisioned Fb-->>Sd: exit 0 (ConditionPathExists trip) end Fb-->>Sd: done - par - Sd->>Fp: start (reads /etc/fips/fips.yaml) - and - Sd->>Cr: start (self-provisions admin key to /var/lib/c-relay/) - and - Sd->>Gx: start (spawn-fcgi, reads env file for privkey) - and - Sd->>Ng: start (serves /var/www/blobs, proxies to c-relay and ginxsom) + + Sd->>IA: start identity-agent + IA-->>Sd: active (control socket ready) + + Sd->>TUI: start boot-time identity + services flow on tty1 + TUI->>IA: load_mnemonic / load_bunker / load_amnesia + IA-->>TUI: identity loaded + TUI->>Sd: start/stop selected services via systemctl + + opt User enabled nginx + Sd->>Ng: start end + opt User enabled c-relay + Sd->>Cr: start + end + opt User enabled ginxsom + Sd->>Gx: start + end + opt User enabled fips + Sd->>Fp: start + end + + TUI->>Sd: exit 0 + Sd->>GT: start (after TUI exits) ``` ## 5. Phase 0.A — Gitea artifact fetch diff --git a/plans/tui_login.md b/plans/tui_login.md index 16bc0b98..0c61941f 100644 --- a/plans/tui_login.md +++ b/plans/tui_login.md @@ -185,6 +185,10 @@ stack/nostr-id-tui/ # new subtree │ ├── screen_generate.c # generate + display + 3-position confirm │ ├── screen_import.c # /media/*/mnemonic.txt discovery + wipe │ ├── screen_bunker.c # NIP-46 bunker URL entry +│ ├── screen_services.c # post-identity service selection menu +│ ├── screen_services_confirm.c # commit/apply status + failure handling +│ ├── services_conf.c # /etc/n-os-tr/services.conf parser +│ ├── systemd_client.c # wrapper over /bin/systemctl and journalctl │ ├── screen_error.c # fatal error screen │ ├── curses_helpers.c # small ncurses wrappers (input w/o history) │ ├── agent_client.c # speak nostr-id control socket (see §5) @@ -237,9 +241,12 @@ stateDiagram-v2 Amnesia --> SendAgentAmnesia - SendAgent --> Exit: agent returns ok + SendAgent --> Services: agent returns ok SendAgent --> FatalError: agent returns error - SendAgentAmnesia --> Exit + SendAgentAmnesia --> Services + + Services --> Exit: commit/skip complete + Services --> FatalError: unrecoverable apply error FatalError --> [*] Exit --> [*] @@ -261,7 +268,9 @@ stateDiagram-v2 **Amnesia.** No persistence, no Nostr config projection, ephemeral main key generated via [`nostr_generate_keypair`](../includes/nostr_core_lib/nostr_core/nip006.h:20). Big red banner: "AMNESIA MODE. This identity dies at shutdown." -**FatalError.** A single full-screen error. No recovery — require the user to reboot. This is only reached if ncurses init failed, the agent control socket is unavailable, or memory locking failed (which means the threat-model invariants cannot be enforced). +**Services.** After identity load succeeds, the same TUI presents a service-selection screen (see [`plans/tui_service_menu.md`](tui_service_menu.md)). The user toggles optional services (c-relay, ginxsom, fips, nginx, config-loader, config-writer, ssh, tor) and either commits changes or skips with all services off for that session. + +**FatalError.** A single full-screen error. No recovery — require the user to reboot. This is only reached if ncurses init failed, the agent control socket is unavailable, memory locking failed (which means the threat-model invariants cannot be enforced), or service-apply hits a non-recoverable system state. ### 3.3 Anti-shoulder-surf tradeoffs @@ -408,6 +417,9 @@ sequenceDiagram Note over TUI: user interacts TUI->>IA: load_mnemonic / load_bunker / load_amnesia IA-->>TUI: ok + Note over TUI: service selection menu (same binary) + TUI->>SD: start/stop selected units + SD-->>TUI: unit results TUI->>SD: exit 0 SD->>GT: start (now allowed by ordering) GT->>User: "n-os-tr login:" diff --git a/plans/tui_service_menu.md b/plans/tui_service_menu.md new file mode 100644 index 00000000..de105406 --- /dev/null +++ b/plans/tui_service_menu.md @@ -0,0 +1,538 @@ +# TUI Service Menu — Post-Identity Service Selection + +> **Status:** Design. This document extends [`plans/tui_login.md`](tui_login.md) with a second screen inside the same `nostr-id-tui` binary: after the user has successfully loaded an identity (mnemonic / generated / imported / bunker / amnesia), the TUI presents a menu of **optional services** and lets the user toggle each one on or off **before** `getty@tty1` is allowed to start. +> +> Depends on: [`plans/tui_login.md`](tui_login.md), [`plans/identity_subsystem.md`](identity_subsystem.md), [`plans/iso_architecture.md`](iso_architecture.md), [`plans/nostr_config_projection.md`](nostr_config_projection.md), [`/home/user/lt/aesthetics/TUI.md`](/home/user/lt/aesthetics/TUI.md). + +## 0. Policy + +1. **n-OS-tr always installs and sets up every service.** Binaries, unit files, config templates, data directories — all present on the image. +2. **No service starts automatically at boot except the identity/boot pipeline itself.** Exactly these three are enabled image-wide: [`n-os-tr-firstboot.service`](../iso/config/includes.chroot/etc/systemd/system/n-os-tr-firstboot.service), `nostr-id.service` (identity-agent), [`nostr-id-tui.service`](../iso/config/includes.chroot/etc/systemd/system/nostr-id-tui.service). Everything else ships `disabled` via the live-build preset policy. +3. **The user decides what turns on.** After the user authenticates via `nostr-id-tui`, the TUI presents a service-toggle screen. The user picks what they want running this session. +4. **Selections are session-local in v1.** No persistence across reboots. Every boot starts with the same defaults. A future revision may project selections to a Nostr config slot (§10). +5. **One binary, one ceremony.** The service menu is a new screen inside `nostr-id-tui`, not a separate unit. Rationale discussed in the architect session: the user is already in one authenticated terminal flow; we do not want two back-to-back ceremonies before login. +6. **Default-off by default.** Every toggleable service starts the session in the "off" state. The user must explicitly enable each one they want running. This matches the privacy-forward posture of the project. +7. **Style:** strict adherence to [`/home/user/lt/aesthetics/TUI.md`](/home/user/lt/aesthetics/TUI.md) — single-key actions, terminal-width headers, ANSI underline for hotkeys, canonical menu template (§12 of that doc). + +## 1. Scope + +### 1.1 Services in the menu (v1) + +| Key | Label | systemd unit | Default | What it does | +|-----|-----------------|---------------------------|---------|--------------------------------------------------------| +| `r` | `c-relay` | `c-relay.service` | off | Local Nostr relay (NIP-01/42). Admin key = index 2. | +| `g` | `ginxsom` | `ginxsom.service` | off | Blossom blob server behind nginx. Server key = index 3.| +| `f` | `fips` | `fips.service` | off | Mesh-routing daemon; npub-IPv6 overlay. Key = index 4. | +| `n` | `nginx` | `nginx.service` | off | TLS front door / reverse proxy. Needed by c-relay ws, ginxsom uploads. | +| `l` | `config-loader` | `nostr-config-loader.service` | off | Fetch + materialize user config slots (§ [`nostr_config_projection.md`](nostr_config_projection.md#3-boot-flow)). | +| `w` | `config-writer` | `nostr-config-writer.service` | off | Save tracked home paths back to Nostr on shutdown. | +| `s` | `ssh` | `ssh.service` | off | OpenSSH server. Keys regenerated at firstboot. | +| `t` | `tor` | `tor.service` | off | Tor daemon. Default posture = SOCKS-only (client), not exit/relay. | + +### 1.2 Services explicitly NOT in the menu + +- `nostr-id.service` — identity-agent is always required; it's the thing the TUI talks to. +- `n-os-tr-firstboot.service` — oneshot, runs before the TUI, not user-controlled. +- `nostr-id-tui.service` — the TUI itself. +- `systemd-networkd`/`NetworkManager`/`dbus` — core system plumbing; managed by distro defaults. + +### 1.3 Service dependencies the TUI must respect + +Some services only make sense together. The TUI enforces these dependencies at toggle time (not at the systemd level — systemd's own `Requires=`/`Wants=` handles the actual startup ordering): + +| Service | Implicit deps (auto-enabled when this is turned on) | +|---------------|-------------------------------------------------------------| +| `c-relay` | `nginx` (wss termination and cert) | +| `ginxsom` | `nginx` (serves blobs, proxies uploads) | +| `config-writer` | `config-loader` (must have run at boot to know the slots) | + +If the user toggles `c-relay` on and `nginx` is off, the TUI: +- Shows a one-line prompt: `c-relay needs nginx. Turn nginx on too? [Y/n]`. +- Default `y` on Enter. If `n`, the toggle is cancelled (we do not start a service that won't be reachable). + +Reverse direction (turning `nginx` off while `c-relay` is on): prompt `c-relay will become unreachable without nginx. Stop c-relay too? [Y/n]`. + +## 2. Placement in the existing TUI flow + +### 2.1 Updated state diagram + +```mermaid +stateDiagram-v2 + [*] --> Menu + + Menu --> Enter: 1 / E + Menu --> Generate: 2 / G + Menu --> Import: 3 / I + Menu --> Bunker: 4 / B + Menu --> Amnesia: 5 / A + + Enter --> SendAgent: BIP-39 ok + Generate --> SendAgent: confirm words ok + Import --> SendAgent: file read + wiped + Bunker --> SendAgent: NIP-46 connected + Amnesia --> SendAgent: ephemeral key + + SendAgent --> Services: agent returns ok + SendAgent --> FatalError: agent returns error + + Services --> Services: user toggles + Services --> Confirm: user presses C (commit) + Services --> Services: user presses X (skip, all off) + + Confirm --> Apply: user presses Y + Confirm --> Services: user presses N + + Apply --> Apply: start/stop each selected unit + Apply --> Exit: all units reached terminal state + Apply --> ApplyError: any unit failed + + ApplyError --> Services: user reviews, retries + + FatalError --> [*] + Exit --> [*] +``` + +The only new states are `Services`, `Confirm`, `Apply`, and `ApplyError`. Everything before `SendAgent` is unchanged from [`plans/tui_login.md §3.1`](tui_login.md#31-state-diagram). + +### 2.2 Updated boot sequence + +```mermaid +sequenceDiagram + participant SD as systemd + participant IA as nostr-id.service + participant TUI as nostr-id-tui.service + participant Svc as toggleable services + participant GT as getty@tty1.service + + SD->>IA: start + IA-->>SD: listening on control.sock + SD->>TUI: start (owns tty1) + Note over TUI: identity screens + TUI->>IA: load_mnemonic/bunker/amnesia + IA-->>TUI: ok, main_npub + Note over TUI: service menu + TUI->>TUI: user toggles, presses Commit + TUI->>SD: StartUnit/StopUnit via dbus + SD->>Svc: start selected services + Svc-->>SD: active + SD-->>TUI: job results + TUI->>SD: exit 0 + SD->>GT: start (ordering allows) + GT->>User: n-os-tr login: +``` + +## 3. Screen design + +Strict compliance with [`/home/user/lt/aesthetics/TUI.md`](/home/user/lt/aesthetics/TUI.md). Every screen follows the canonical template in §12 of that doc. + +### 3.1 Main services screen + +```text +===================== SERVICES ===================== + (expands to terminal width) + +Identity: npub1abcd…wxyz (main, index 0) +Session: live (in-memory, no persistence) + + Key Service State Default Depends on + --- ------------- --------- ------- ----------- + R c-relay [ off ] off nginx + G ginxsom [ off ] off nginx + F fips [ off ] off — + N nginx [ off ] off — + L config-loader [ off ] off — + W config-writer [ off ] off config-loader + S ssh [ off ] off — + T tor [ off ] off — + +Actions: + R/G/F/N/L/W/S/T) Toggle service + A) Turn All on + Z) Turn all off (reset) + C) Commit and continue + X) Skip (all off, continue) + +Select action: > +``` + +Formatting rules (all from [TUI.md](/home/user/lt/aesthetics/TUI.md)): + +- Header expands to full terminal width using the `=== SERVICES ===` pattern from [`ui.c:print_centered_header`](/home/user/lt/aesthetics/TUI.md:88). +- Column widths are fixed; when terminal is narrower than 60 cols, drop the "Default" and "Depends on" columns (the state is what matters). +- State column is either `[ off ]` or `[ on ]`. A third transient state `[ ... ]` appears during the Apply phase. +- The first letter of each service name in the Key column is rendered with ANSI underline via `\033[4m\033[0m`, matching [TUI.md §7](/home/user/lt/aesthetics/TUI.md). +- Prompt at bottom is `Select action: >` per the canonical template. + +### 3.2 Confirm screen + +Before actually doing anything, we show what will happen: + +```text +===================== CONFIRM ===================== + +The following changes will be applied: + + START nginx.service + START c-relay.service + START fips.service + + (5 services remain off) + +Proceed? [Y/n] > +``` + +Only services whose session state differs from their default appear. Pure-default sessions (no changes) go straight from the services screen's `C`/`X` directly to `Apply` with an empty plan and exit. + +### 3.3 Apply screen + +Live progress. We iterate the plan serially (not concurrently — systemd handles that anyway, and serial output is easier to read): + +```text +===================== APPLYING ===================== + + [ OK ] nginx.service started in 0.42s + [ OK ] c-relay.service started in 1.14s + [ ... ] fips.service starting... + [ ] (waiting) + +Press Ctrl-C to abort remaining jobs (already-started services stay up). +``` + +Each row shows one of: +- `[ ]` queued +- `[ ... ]` in progress (animated dot after 250 ms; ANSI cursor save/restore to re-render only the affected row) +- `[ OK ]` finished successfully +- `[FAIL ]` finished with an error +- `[SKIP ]` not applied (e.g. dependency refused earlier) + +After all jobs complete: + +- All green → advance to Exit immediately (print `All services started. Handing control to login...` for 1 second, then the TUI exits and getty takes over). +- Any failures → advance to **ApplyError** screen. + +### 3.4 Apply-error screen + +```text +===================== PARTIAL FAILURE ===================== + +Some services did not start cleanly: + + [FAIL ] ginxsom.service + SubState: failed + ExecMainStatus: 1 + Last log line: "/usr/local/bin/ginxsom/ginxsom-fcgi: socket bind failed" + +Actions: + V) View journal for failed services + R) Retry failed services only + B) Back to service menu + I) Ignore and continue to login anyway + +Select action: > +``` + +The journal view (`V`) shells out to `journalctl -u -n 50 --no-pager` via a pipe (we do not embed a log viewer). `less`-style paging is acceptable if available; otherwise we just print and prompt to continue. + +## 4. Service manifest + +The TUI does not hard-code the service list in C. It reads `/etc/n-os-tr/services.conf` at startup. This lets us add/remove services (especially tor, which lands later) without rebuilding the binary. + +### 4.1 File format + +A small line-based format, one record per service, fields tab-separated: + +``` +# key unit label default deps +r c-relay.service c-relay off nginx.service +g ginxsom.service ginxsom off nginx.service +f fips.service fips off - +n nginx.service nginx off - +l nostr-config-loader.service config-loader off - +w nostr-config-writer.service config-writer off nostr-config-loader.service +s ssh.service ssh off - +t tor.service tor off - +``` + +Comments start with `#`. Blank lines ignored. Unknown fields ignored for forward compatibility. Multiple deps separated by `,`. A literal `-` means no deps. + +Parsing happens in `stack/nostr-id-tui/src/services_conf.c`. On parse error the TUI falls back to a hardcoded minimal list (c-relay, ginxsom, fips, nginx) and logs the parse error to stderr (captured by journald, per the service unit's `StandardError=journal`). + +### 4.2 Install location + +Shipped in the chroot at [`iso/config/includes.chroot/etc/n-os-tr/services.conf`](../iso/config/includes.chroot/etc/n-os-tr/services.conf). Mode `0644`, owner `root:root`. + +## 5. Control path: talking to systemd + +### 5.1 Transport choice + +The TUI needs to: +1. Query each unit's current state (`LoadState`, `ActiveState`, `SubState`). +2. Start and stop units. +3. Receive job-completion signals. + +Two realistic options in a static musl C binary with no glibc: + +| Option | Notes | Verdict | +|----------------------------------------------------------------|---------------------------------------------------------------------------------------------|---------------------| +| **Shell out to `systemctl`** via `fork` + `execve` | Simple. Exit codes are well-defined. Parse `show --property=ActiveState=`. No linking. | **v1 default.** | +| **Speak the D-Bus wire protocol directly** to `/run/dbus/system_bus_socket` | Avoids forking. Enables real-time `JobRemoved` signals. Needs a tiny D-Bus marshaller (~1 KLOC) or the vendored cjson-style lib. | Later optimization. | +| **Link `libsystemd.a`** | Would pull in a chunk of systemd source into Alpine build, and libsystemd isn't available as `-static` in Alpine. | Rejected. | + +v1 uses `systemctl`. The binary path is hardcoded to `/bin/systemctl` (present on every Debian live image — `systemctl` itself is part of `systemd` which is in base). The wrapper module is `stack/nostr-id-tui/src/systemd_client.c` and exposes: + +```c +typedef enum { + SVC_INACTIVE = 0, + SVC_ACTIVATING, + SVC_ACTIVE, + SVC_DEACTIVATING, + SVC_FAILED, + SVC_UNKNOWN +} svc_state_t; + +svc_state_t systemd_active_state(const char *unit); /* systemctl show -p ActiveState */ +int systemd_start(const char *unit, int timeout_ms, char *err_out, size_t err_len); +int systemd_stop (const char *unit, int timeout_ms, char *err_out, size_t err_len); +int systemd_journal_tail(const char *unit, int n_lines, FILE *out); /* exec journalctl */ +``` + +Each call spawns `systemctl` / `journalctl` with `posix_spawn` into a pipe, waits with a timeout, captures stdout/stderr, and returns. + +### 5.2 Privilege + +`nostr-id-tui.service` currently runs as root on `tty1` (see the service unit). That gives it direct `systemctl` privilege — no polkit rule needed. This matches the existing threat-model stance in [`plans/tui_login.md §6.1`](tui_login.md#61-etcsystemdsystemnostr-id-tuiservice): the TUI is already privileged because it owns the tty and talks to identity-agent over a root-only socket. + +If we ever demote the TUI to run as the `nostr-id` user, we'll need `/etc/polkit-1/rules.d/50-n-os-tr-services.rules` granting that user the `org.freedesktop.systemd1.manage-units` action **only for the whitelisted units listed in `services.conf`**. That's future work. + +### 5.3 Timeouts and cancellation + +- Per-unit start/stop timeout: 30 s (covers nginx startup, fips mesh ready, etc.). Larger than any real service needs. +- TUI-level overall budget: 2 minutes. If exceeded, Apply falls through to ApplyError with any unfinished jobs marked `[TIME]` and the user is prompted. +- Ctrl-C in the Apply screen sends SIGINT to the current `systemctl` child, marks the remaining jobs `[SKIP ]`, and goes to ApplyError. + +## 6. Source tree changes + +Extending the layout declared in [`plans/tui_login.md §2.2`](tui_login.md#22-code-that-lives-in-this-repo-n_os_tr): + +``` +stack/nostr-id-tui/ +├── src/ +│ ├── main.c # now dispatches identity→services→exit +│ ├── screen_menu.c # unchanged +│ ├── screen_enter.c # unchanged +│ ├── screen_generate.c # unchanged +│ ├── screen_import.c # unchanged +│ ├── screen_bunker.c # unchanged +│ ├── screen_services.c # NEW: main service toggle screen +│ ├── screen_services_confirm.c # NEW: confirm + apply screens +│ ├── services_conf.c # NEW: parser for /etc/n-os-tr/services.conf +│ ├── systemd_client.c # NEW: fork/exec systemctl + journalctl +│ ├── curses_helpers.c # unchanged +│ ├── agent_client.c # unchanged +│ └── memhygiene.c # unchanged +├── include/ +│ └── n_os_tr_tui.h # adds svc_* decls + ui_backend hooks +└── tests/ + ├── test_screen_services.c # NEW: state-machine unit test + ├── test_services_conf.c # NEW: parser fuzz/table tests + ├── test_systemd_client.c # NEW: runs against a fake systemctl shim + └── test_integration.sh # extended to toggle a service in QEMU +``` + +No ncurses API leaks into the new state machines. All rendering goes through the same `ui_backend_t` abstraction established in [`plans/tui_login.md §7`](tui_login.md#7-per-flavor-abstraction). The Pi LCD port will get a stripped service menu for free. + +## 7. Systemd preset policy + +### 7.1 What "installed but not enabled" means + +For each toggleable unit we ship: +- The unit file in `iso/config/includes.chroot/etc/systemd/system/` or (for distro-packaged units like `ssh`, `tor`, `nginx`) in the package itself. +- **No symlink in `multi-user.target.wants/`** — i.e. no `systemctl enable`. +- A preset file that explicitly forbids enabling at image-build time. + +### 7.2 Preset file + +New file: [`iso/config/includes.chroot/etc/systemd/system-preset/50-n-os-tr.preset`](../iso/config/includes.chroot/etc/systemd/system-preset/50-n-os-tr.preset): + +``` +# n-OS-tr service posture: only the identity/boot pipeline auto-starts. +# Everything else is explicitly disabled. The TUI turns them on at the +# user's request after identity load. +enable nostr-id.service +enable nostr-id-tui.service +enable n-os-tr-firstboot.service + +disable c-relay.service +disable ginxsom.service +disable fips.service +disable nginx.service +disable nostr-config-loader.service +disable nostr-config-writer.service +disable ssh.service +disable tor.service +``` + +The `50-` prefix lands before Debian defaults (typically `90-*.preset`), so our `disable` lines override e.g. nginx's upstream preset-enable. + +### 7.3 Rework of the enable-services hook + +Current hook [`iso/config/hooks/live/0020-enable-services.hook.chroot`](../iso/config/hooks/live/0020-enable-services.hook.chroot) enables the services directly. Rework it to be explicit about the new posture: + +```sh +#!/bin/sh +set -eu + +# Enable the always-on trio +systemctl enable n-os-tr-firstboot.service +systemctl enable nostr-id.service +systemctl enable nostr-id-tui.service + +# Explicitly disable everything else in the service manifest. +# Idempotent; safe to re-run. `systemctl disable` is a no-op for units +# that aren't enabled yet, which is what we want. +for unit in \ + c-relay.service \ + ginxsom.service \ + fips.service \ + nginx.service \ + nostr-config-loader.service \ + nostr-config-writer.service \ + ssh.service \ + tor.service ; do + systemctl disable "$unit" 2>/dev/null || true +done + +# Run the preset policy for anything we didn't list above (defensive). +systemctl preset-all --preset-mode=enable-only 2>/dev/null || true +``` + +### 7.4 Package-list additions + +`tor` is new to the image. Add to [`iso/config/package-lists/base.list.chroot`](../iso/config/package-lists/base.list.chroot): + +``` +tor +``` + +No other new packages: nginx, openssh-server, ca-certificates, systemd, etc. are already pulled. + +## 8. Interaction with identity modes + +### 8.1 Normal, Bunker, and Amnesia modes + +- **Normal (mnemonic loaded)**: full menu, full defaults as in §1.1. +- **Bunker mode**: services that require a raw local nsec are **disabled in the menu** (greyed out with `[ n/a ]` in the state column). Those are: + - `c-relay` — admin key comes from identity-agent via NIP-46 signing for event-based config only; for the admin nsec path the service fails. The menu shows `[ n/a ]` with a tooltip line "requires local key; bunker mode cannot provide". + - `ginxsom` — same. Key material is needed at process start (`--server-privkey` in [`ginxsom.service`](../iso/config/includes.chroot/etc/systemd/system/ginxsom.service)). + - `fips` — same. + - `nginx`, `config-loader`, `config-writer`, `ssh`, `tor` — available in bunker mode. +- **Amnesia mode**: all services available, but `config-loader`/`config-writer` are explicitly disabled with label "amnesia session — config not persisted" (we don't pull anything from Nostr for an ephemeral identity). + +The rules live in `services_conf.c` as a small matrix; the file format in §4.1 can be extended later with `modes=normal,bunker,amnesia` but v1 hardcodes the matrix in C. + +### 8.2 Re-entry + +A future option from the Services menu: `Q) Reset identity and return to identity menu`. Deferred — not in v1. For v1 the only path out of Services is `C` (commit) or `X` (skip), both of which lead to Exit. + +## 9. Testing + +### 9.1 Unit (in Alpine/musl builder) + +- `test_services_conf` — feeds valid and malformed manifests, asserts parser produces correct structs and correct fallback on bad input. +- `test_systemd_client` — sets `$PATH` to a directory with a shim `systemctl` that records its argv and emits canned output; asserts our client parses `ActiveState=active|inactive|failed` correctly and times out when the shim sleeps. +- `test_screen_services` — drives the services state machine through a mock `ui_backend_t`; asserts: + - Default state is all-off. + - Toggling `R` then `G` then `R` ends with `G` on and `R` off. + - Toggling `R` prompts for `N` enable; answering `y` enables both. + - `Z` (reset) returns to defaults. + - `X` (skip) goes directly to Apply with an empty plan. + - `C` (commit) goes to Confirm. + +### 9.2 Integration (QEMU) + +Extend [`stack/nostr-id-tui/tests/test_integration.sh`](../stack/nostr-id-tui/tests/test_integration.sh) with a new scripted run: +1. Boot the ISO. +2. At the identity screen, feed the Trezor test-vector mnemonic. +3. At the services screen, press `N` (enable nginx), then `C`, then `Y`. +4. After the TUI exits and getty appears, log in as the default user. +5. Assert `systemctl is-active nginx` = `active` and `systemctl is-active c-relay` = `inactive`. + +### 9.3 Smoketest extensions + +Extend [`iso/config/includes.chroot/usr/local/bin/n-os-tr-smoketest`](../iso/config/includes.chroot/usr/local/bin/n-os-tr-smoketest) to also verify: + +- Preset posture at **image build time**: for each toggleable unit, `systemctl is-enabled ` returns `disabled`. +- The manifest file `/etc/n-os-tr/services.conf` exists and parses (re-invoke the parser from a test helper). +- `/bin/systemctl` is present (the TUI depends on it). + +## 10. Non-persistence and the future Nostr slot + +v1: selections are session-local. Reboot → all services back to off, user re-selects. + +Future: one new entry in the manifest scheme from [`plans/nostr_config_projection.md §2.1`](nostr_config_projection.md#21-slots): + +```json +{ + "name": "n-os-tr/services", + "path": "/run/nostr-id/services.state.json", + "mode": "0600", + "encrypted": true +} +``` + +Content schema (draft): + +```json +{ + "version": 1, + "enabled": ["nginx.service", "c-relay.service", "fips.service"] +} +``` + +When a session starts, if a services slot exists, the TUI pre-loads the toggle state from it. User still has to press `C` to commit — we don't auto-apply without the user seeing the menu. This preserves the "the user decides when to turn them on" rule. + +Out of scope for v1 implementation. + +## 11. Failure modes + +| Failure | Behavior | +|-------------------------------------------------|--------------------------------------------------------------------------| +| `/etc/n-os-tr/services.conf` missing or unparseable | Log to stderr, fall back to hardcoded minimal list (c-relay, ginxsom, fips, nginx). | +| `/bin/systemctl` missing | FatalError (as in [`plans/tui_login.md §9`](tui_login.md#9-failure-modes-summary)). The ISO is malformed. | +| Unit start returns non-zero | Row shows `[FAIL ]`, ApplyError screen is reached after all jobs settle. | +| Unit start hangs past 30 s | Timeout, row shows `[TIME]`, ApplyError. | +| User hits Ctrl-C during Apply | SIGINT to current `systemctl`, remaining jobs `[SKIP ]`, ApplyError. | +| Bunker mode, user tries to toggle `c-relay` | Toggle is ignored; status line shows "requires local key; bunker mode". | +| User toggles all off and presses Commit | Apply plan is empty; TUI prints `No services requested. Handing control to login...` and exits. | +| Identity agent dies during service menu | We're not calling the agent during this phase — selections are in TUI memory only. User is unaffected until they finish service menu and the TUI exits; if the agent is dead when services start, those services will fail on their own dependency chain. | + +## 12. Docs to update + +- [`plans/tui_login.md`](tui_login.md) — add a one-line reference in §3.1 to the new `Services` state after `SendAgent`; add `screen_services.c`, `screen_services_confirm.c`, `services_conf.c`, `systemd_client.c` to the source tree listing in §2.2; update §13 implementation order with the service-menu steps. +- [`plans/iso_architecture.md`](iso_architecture.md) — update §4 boot sequence to show the identity+services TUI phase before the parallel `fips/c-relay/ginxsom/nginx` block, and note that those services are started by the TUI, not auto-started by systemd. +- [`iso/config/includes.chroot/usr/share/doc/n-os-tr/README`](../iso/config/includes.chroot/usr/share/doc/n-os-tr/README) — describe the new login→services flow for end users. +- [`docs/RUNNING.md`](../docs/RUNNING.md) — add a section showing the service menu and how to toggle. + +## 13. Implementation order (Phase 3a.2) + +Small, independently verifiable steps. Each one leaves the repo in a runnable state. + +1. **Land the preset file and rework the enable hook.** After this commit, a fresh ISO boots to a system where only `nostr-id`, `nostr-id-tui`, and `firstboot` are enabled; every other service is present on disk but inactive. Verify with `systemctl list-unit-files --state=disabled` in a QEMU boot. +2. **Add the service manifest file.** Ship `/etc/n-os-tr/services.conf` with the v1 table from §1.1. No TUI change yet; verifies that the file reaches the image. +3. **Add `tor` to the base package list.** Confirm the built ISO includes `tor.service` as a disabled unit. +4. **Implement `services_conf.c` + tests.** Parser plus a 40-line sanity test in the Alpine builder. +5. **Implement `systemd_client.c` + tests.** Fork/exec + pipe capture + shim-based test. +6. **Implement `screen_services.c` state machine + `test_screen_services`.** No rendering yet — verifies transitions against a mock backend. +7. **Render the services screen in `ui_backend_curses.c`.** First visible new screen. +8. **Implement `screen_services_confirm.c` — confirm/apply/apply-error screens.** Wire them to `systemd_client`. +9. **Hook into `main.c`.** After `agent_client` returns from `load_mnemonic`/`load_bunker`/`load_amnesia` with ok, transition to the services screen. Skip the screen entirely if `/etc/n-os-tr/services.conf` is missing *and* fallback is disabled via a `--no-services` flag (useful for tests that want only the identity flow). +10. **Extend the QEMU integration test.** Script a toggle of one service, assert post-login that the chosen service is active and the others are not. +11. **Extend the smoketest.** Add the preset-state check. +12. **Doc passes.** Update [`plans/tui_login.md`](tui_login.md), [`plans/iso_architecture.md`](iso_architecture.md), [`docs/RUNNING.md`](../docs/RUNNING.md), and the in-ISO README. + +## 14. Open questions + +- **`tor.service` posture out of the box.** We ship the distro default `torrc` (SOCKS 9050 only, no relay). Do we want a second unit drop-in that enables the hidden-service onion for nginx when the user turns both on? Probably yes, as a follow-up; keep v1 minimal. +- **GUI flavor.** Image flavor with a GUI will run the TUI on a text VT during early boot. Does it also allow the user to re-run the services menu later from the GUI? Probably yes via a GTK wrapper around the same `systemd_client` module, but that's post-v1. +- **Per-user vs system.** All services here are system-level. "Which user's `ssh/authorized_keys` does `ssh` serve" is answered by the config-loader slot scheme. No per-user service toggles in v1. +- **Should toggling the menu's state affect *default* behavior for future reboots?** Today: no; v1 is stateless. A future Nostr slot (§10) could record the last committed state and let the TUI show it as a "remembered" default, but that's explicit future work. diff --git a/stack/nostr-id-tui/CMakeLists.txt b/stack/nostr-id-tui/CMakeLists.txt index 5040e42b..3d2c61ef 100644 --- a/stack/nostr-id-tui/CMakeLists.txt +++ b/stack/nostr-id-tui/CMakeLists.txt @@ -18,6 +18,8 @@ endif() add_executable(nostr-id-tui src/main.c + src/services_conf.c + src/systemd_client.c ) target_include_directories(nostr-id-tui PRIVATE diff --git a/stack/nostr-id-tui/build-host/CMakeFiles/Makefile2 b/stack/nostr-id-tui/build-host/CMakeFiles/Makefile2 index b47d7281..b92caa74 100644 --- a/stack/nostr-id-tui/build-host/CMakeFiles/Makefile2 +++ b/stack/nostr-id-tui/build-host/CMakeFiles/Makefile2 @@ -85,12 +85,12 @@ clean: CMakeFiles/nostr-id-tui.dir/clean CMakeFiles/nostr-id-tui.dir/all: $(MAKE) $(MAKESILENT) -f CMakeFiles/nostr-id-tui.dir/build.make CMakeFiles/nostr-id-tui.dir/depend $(MAKE) $(MAKESILENT) -f CMakeFiles/nostr-id-tui.dir/build.make CMakeFiles/nostr-id-tui.dir/build - @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/user/lt/n_os_tr/stack/nostr-id-tui/build-host/CMakeFiles --progress-num=1,2 "Built target nostr-id-tui" + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/user/lt/n_os_tr/stack/nostr-id-tui/build-host/CMakeFiles --progress-num=1,2,3,4 "Built target nostr-id-tui" .PHONY : CMakeFiles/nostr-id-tui.dir/all # Build rule for subdir invocation for target. CMakeFiles/nostr-id-tui.dir/rule: cmake_check_build_system - $(CMAKE_COMMAND) -E cmake_progress_start /home/user/lt/n_os_tr/stack/nostr-id-tui/build-host/CMakeFiles 2 + $(CMAKE_COMMAND) -E cmake_progress_start /home/user/lt/n_os_tr/stack/nostr-id-tui/build-host/CMakeFiles 4 $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/nostr-id-tui.dir/all $(CMAKE_COMMAND) -E cmake_progress_start /home/user/lt/n_os_tr/stack/nostr-id-tui/build-host/CMakeFiles 0 .PHONY : CMakeFiles/nostr-id-tui.dir/rule @@ -102,7 +102,7 @@ nostr-id-tui: CMakeFiles/nostr-id-tui.dir/rule # codegen rule for target. CMakeFiles/nostr-id-tui.dir/codegen: $(MAKE) $(MAKESILENT) -f CMakeFiles/nostr-id-tui.dir/build.make CMakeFiles/nostr-id-tui.dir/codegen - @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/user/lt/n_os_tr/stack/nostr-id-tui/build-host/CMakeFiles --progress-num=1,2 "Finished codegen for target nostr-id-tui" + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/user/lt/n_os_tr/stack/nostr-id-tui/build-host/CMakeFiles --progress-num=1,2,3,4 "Finished codegen for target nostr-id-tui" .PHONY : CMakeFiles/nostr-id-tui.dir/codegen # clean rule for target. diff --git a/stack/nostr-id-tui/build-host/CMakeFiles/nostr-id-tui.dir/DependInfo.cmake b/stack/nostr-id-tui/build-host/CMakeFiles/nostr-id-tui.dir/DependInfo.cmake index 08ff9f6e..30e2f271 100644 --- a/stack/nostr-id-tui/build-host/CMakeFiles/nostr-id-tui.dir/DependInfo.cmake +++ b/stack/nostr-id-tui/build-host/CMakeFiles/nostr-id-tui.dir/DependInfo.cmake @@ -9,6 +9,8 @@ set(CMAKE_DEPENDS_LANGUAGES # The set of dependency files which are needed: set(CMAKE_DEPENDS_DEPENDENCY_FILES "/home/user/lt/n_os_tr/stack/nostr-id-tui/src/main.c" "CMakeFiles/nostr-id-tui.dir/src/main.c.o" "gcc" "CMakeFiles/nostr-id-tui.dir/src/main.c.o.d" + "/home/user/lt/n_os_tr/stack/nostr-id-tui/src/services_conf.c" "CMakeFiles/nostr-id-tui.dir/src/services_conf.c.o" "gcc" "CMakeFiles/nostr-id-tui.dir/src/services_conf.c.o.d" + "/home/user/lt/n_os_tr/stack/nostr-id-tui/src/systemd_client.c" "CMakeFiles/nostr-id-tui.dir/src/systemd_client.c.o" "gcc" "CMakeFiles/nostr-id-tui.dir/src/systemd_client.c.o.d" "" "nostr-id-tui" "gcc" "CMakeFiles/nostr-id-tui.dir/link.d" ) diff --git a/stack/nostr-id-tui/build-host/CMakeFiles/nostr-id-tui.dir/build.make b/stack/nostr-id-tui/build-host/CMakeFiles/nostr-id-tui.dir/build.make index 8bc426e5..901e6df6 100644 --- a/stack/nostr-id-tui/build-host/CMakeFiles/nostr-id-tui.dir/build.make +++ b/stack/nostr-id-tui/build-host/CMakeFiles/nostr-id-tui.dir/build.make @@ -86,21 +86,53 @@ CMakeFiles/nostr-id-tui.dir/src/main.c.s: cmake_force @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling C source to assembly CMakeFiles/nostr-id-tui.dir/src/main.c.s" /usr/bin/cc $(C_DEFINES) $(C_INCLUDES) $(C_FLAGS) -S /home/user/lt/n_os_tr/stack/nostr-id-tui/src/main.c -o CMakeFiles/nostr-id-tui.dir/src/main.c.s +CMakeFiles/nostr-id-tui.dir/src/services_conf.c.o: CMakeFiles/nostr-id-tui.dir/flags.make +CMakeFiles/nostr-id-tui.dir/src/services_conf.c.o: /home/user/lt/n_os_tr/stack/nostr-id-tui/src/services_conf.c +CMakeFiles/nostr-id-tui.dir/src/services_conf.c.o: CMakeFiles/nostr-id-tui.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/user/lt/n_os_tr/stack/nostr-id-tui/build-host/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Building C object CMakeFiles/nostr-id-tui.dir/src/services_conf.c.o" + /usr/bin/cc $(C_DEFINES) $(C_INCLUDES) $(C_FLAGS) -MD -MT CMakeFiles/nostr-id-tui.dir/src/services_conf.c.o -MF CMakeFiles/nostr-id-tui.dir/src/services_conf.c.o.d -o CMakeFiles/nostr-id-tui.dir/src/services_conf.c.o -c /home/user/lt/n_os_tr/stack/nostr-id-tui/src/services_conf.c + +CMakeFiles/nostr-id-tui.dir/src/services_conf.c.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing C source to CMakeFiles/nostr-id-tui.dir/src/services_conf.c.i" + /usr/bin/cc $(C_DEFINES) $(C_INCLUDES) $(C_FLAGS) -E /home/user/lt/n_os_tr/stack/nostr-id-tui/src/services_conf.c > CMakeFiles/nostr-id-tui.dir/src/services_conf.c.i + +CMakeFiles/nostr-id-tui.dir/src/services_conf.c.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling C source to assembly CMakeFiles/nostr-id-tui.dir/src/services_conf.c.s" + /usr/bin/cc $(C_DEFINES) $(C_INCLUDES) $(C_FLAGS) -S /home/user/lt/n_os_tr/stack/nostr-id-tui/src/services_conf.c -o CMakeFiles/nostr-id-tui.dir/src/services_conf.c.s + +CMakeFiles/nostr-id-tui.dir/src/systemd_client.c.o: CMakeFiles/nostr-id-tui.dir/flags.make +CMakeFiles/nostr-id-tui.dir/src/systemd_client.c.o: /home/user/lt/n_os_tr/stack/nostr-id-tui/src/systemd_client.c +CMakeFiles/nostr-id-tui.dir/src/systemd_client.c.o: CMakeFiles/nostr-id-tui.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/user/lt/n_os_tr/stack/nostr-id-tui/build-host/CMakeFiles --progress-num=$(CMAKE_PROGRESS_3) "Building C object CMakeFiles/nostr-id-tui.dir/src/systemd_client.c.o" + /usr/bin/cc $(C_DEFINES) $(C_INCLUDES) $(C_FLAGS) -MD -MT CMakeFiles/nostr-id-tui.dir/src/systemd_client.c.o -MF CMakeFiles/nostr-id-tui.dir/src/systemd_client.c.o.d -o CMakeFiles/nostr-id-tui.dir/src/systemd_client.c.o -c /home/user/lt/n_os_tr/stack/nostr-id-tui/src/systemd_client.c + +CMakeFiles/nostr-id-tui.dir/src/systemd_client.c.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing C source to CMakeFiles/nostr-id-tui.dir/src/systemd_client.c.i" + /usr/bin/cc $(C_DEFINES) $(C_INCLUDES) $(C_FLAGS) -E /home/user/lt/n_os_tr/stack/nostr-id-tui/src/systemd_client.c > CMakeFiles/nostr-id-tui.dir/src/systemd_client.c.i + +CMakeFiles/nostr-id-tui.dir/src/systemd_client.c.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling C source to assembly CMakeFiles/nostr-id-tui.dir/src/systemd_client.c.s" + /usr/bin/cc $(C_DEFINES) $(C_INCLUDES) $(C_FLAGS) -S /home/user/lt/n_os_tr/stack/nostr-id-tui/src/systemd_client.c -o CMakeFiles/nostr-id-tui.dir/src/systemd_client.c.s + # Object files for target nostr-id-tui nostr__id__tui_OBJECTS = \ -"CMakeFiles/nostr-id-tui.dir/src/main.c.o" +"CMakeFiles/nostr-id-tui.dir/src/main.c.o" \ +"CMakeFiles/nostr-id-tui.dir/src/services_conf.c.o" \ +"CMakeFiles/nostr-id-tui.dir/src/systemd_client.c.o" # External object files for target nostr-id-tui nostr__id__tui_EXTERNAL_OBJECTS = nostr-id-tui: CMakeFiles/nostr-id-tui.dir/src/main.c.o +nostr-id-tui: CMakeFiles/nostr-id-tui.dir/src/services_conf.c.o +nostr-id-tui: CMakeFiles/nostr-id-tui.dir/src/systemd_client.c.o nostr-id-tui: CMakeFiles/nostr-id-tui.dir/build.make nostr-id-tui: CMakeFiles/nostr-id-tui.dir/compiler_depend.ts nostr-id-tui: /home/user/lt/n_os_tr/stack/nostr-id-tui/../../includes/nostr_core_lib/libnostr_core_x64.a nostr-id-tui: /usr/lib/x86_64-linux-gnu/libcurses.so nostr-id-tui: /usr/lib/x86_64-linux-gnu/libform.so nostr-id-tui: CMakeFiles/nostr-id-tui.dir/link.txt - @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/user/lt/n_os_tr/stack/nostr-id-tui/build-host/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking C executable nostr-id-tui" + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/user/lt/n_os_tr/stack/nostr-id-tui/build-host/CMakeFiles --progress-num=$(CMAKE_PROGRESS_4) "Linking C executable nostr-id-tui" $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/nostr-id-tui.dir/link.txt --verbose=$(VERBOSE) # Rule to build all files generated by this target. diff --git a/stack/nostr-id-tui/build-host/CMakeFiles/nostr-id-tui.dir/cmake_clean.cmake b/stack/nostr-id-tui/build-host/CMakeFiles/nostr-id-tui.dir/cmake_clean.cmake index 2f33a374..a34ab38d 100644 --- a/stack/nostr-id-tui/build-host/CMakeFiles/nostr-id-tui.dir/cmake_clean.cmake +++ b/stack/nostr-id-tui/build-host/CMakeFiles/nostr-id-tui.dir/cmake_clean.cmake @@ -2,6 +2,10 @@ file(REMOVE_RECURSE "CMakeFiles/nostr-id-tui.dir/link.d" "CMakeFiles/nostr-id-tui.dir/src/main.c.o" "CMakeFiles/nostr-id-tui.dir/src/main.c.o.d" + "CMakeFiles/nostr-id-tui.dir/src/services_conf.c.o" + "CMakeFiles/nostr-id-tui.dir/src/services_conf.c.o.d" + "CMakeFiles/nostr-id-tui.dir/src/systemd_client.c.o" + "CMakeFiles/nostr-id-tui.dir/src/systemd_client.c.o.d" "nostr-id-tui" "nostr-id-tui.pdb" ) diff --git a/stack/nostr-id-tui/build-host/CMakeFiles/nostr-id-tui.dir/compiler_depend.internal b/stack/nostr-id-tui/build-host/CMakeFiles/nostr-id-tui.dir/compiler_depend.internal index d9f3dac4..369bea3e 100644 --- a/stack/nostr-id-tui/build-host/CMakeFiles/nostr-id-tui.dir/compiler_depend.internal +++ b/stack/nostr-id-tui/build-host/CMakeFiles/nostr-id-tui.dir/compiler_depend.internal @@ -52,12 +52,11 @@ CMakeFiles/nostr-id-tui.dir/src/main.c.o /usr/include/x86_64-linux-gnu/bits/floatn.h /usr/include/x86_64-linux-gnu/bits/libc-header-start.h /usr/include/x86_64-linux-gnu/bits/long-double.h + /usr/include/x86_64-linux-gnu/bits/select.h /usr/include/x86_64-linux-gnu/bits/stdint-intn.h /usr/include/x86_64-linux-gnu/bits/stdint-least.h /usr/include/x86_64-linux-gnu/bits/stdint-uintn.h - /usr/include/x86_64-linux-gnu/bits/stdio.h /usr/include/x86_64-linux-gnu/bits/stdio_lim.h - /usr/include/x86_64-linux-gnu/bits/stdlib-bsearch.h /usr/include/x86_64-linux-gnu/bits/stdlib-float.h /usr/include/x86_64-linux-gnu/bits/time.h /usr/include/x86_64-linux-gnu/bits/time64.h @@ -68,8 +67,11 @@ CMakeFiles/nostr-id-tui.dir/src/main.c.o /usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h /usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h /usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h + /usr/include/x86_64-linux-gnu/bits/types/__sigset_t.h /usr/include/x86_64-linux-gnu/bits/types/clock_t.h + /usr/include/x86_64-linux-gnu/bits/types/sigset_t.h /usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h + /usr/include/x86_64-linux-gnu/bits/types/struct_timeval.h /usr/include/x86_64-linux-gnu/bits/types/struct_tm.h /usr/include/x86_64-linux-gnu/bits/types/time_t.h /usr/include/x86_64-linux-gnu/bits/typesizes.h @@ -78,11 +80,93 @@ CMakeFiles/nostr-id-tui.dir/src/main.c.o /usr/include/x86_64-linux-gnu/gnu/stubs-64.h /usr/include/x86_64-linux-gnu/gnu/stubs.h /usr/include/x86_64-linux-gnu/sys/cdefs.h + /usr/include/x86_64-linux-gnu/sys/select.h + /usr/include/x86_64-linux-gnu/sys/time.h /usr/lib/gcc/x86_64-linux-gnu/14/include/stdarg.h /usr/lib/gcc/x86_64-linux-gnu/14/include/stdbool.h /usr/lib/gcc/x86_64-linux-gnu/14/include/stddef.h /usr/lib/gcc/x86_64-linux-gnu/14/include/stdint.h +CMakeFiles/nostr-id-tui.dir/src/services_conf.c.o + /home/user/lt/n_os_tr/stack/nostr-id-tui/src/services_conf.c + /home/user/lt/n_os_tr/stack/nostr-id-tui/include/n_os_tr_tui.h + /usr/include/ctype.h + /usr/include/features-time64.h + /usr/include/features.h + /usr/include/stdc-predef.h + /usr/include/stdio.h + /usr/include/stdlib.h + /usr/include/string.h + /usr/include/x86_64-linux-gnu/bits/endian.h + /usr/include/x86_64-linux-gnu/bits/endianness.h + /usr/include/x86_64-linux-gnu/bits/floatn-common.h + /usr/include/x86_64-linux-gnu/bits/floatn.h + /usr/include/x86_64-linux-gnu/bits/libc-header-start.h + /usr/include/x86_64-linux-gnu/bits/long-double.h + /usr/include/x86_64-linux-gnu/bits/stdio_lim.h + /usr/include/x86_64-linux-gnu/bits/stdlib-float.h + /usr/include/x86_64-linux-gnu/bits/time64.h + /usr/include/x86_64-linux-gnu/bits/timesize.h + /usr/include/x86_64-linux-gnu/bits/types.h + /usr/include/x86_64-linux-gnu/bits/types/FILE.h + /usr/include/x86_64-linux-gnu/bits/types/__FILE.h + /usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h + /usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h + /usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h + /usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h + /usr/include/x86_64-linux-gnu/bits/typesizes.h + /usr/include/x86_64-linux-gnu/bits/wordsize.h + /usr/include/x86_64-linux-gnu/gnu/stubs-64.h + /usr/include/x86_64-linux-gnu/gnu/stubs.h + /usr/include/x86_64-linux-gnu/sys/cdefs.h + /usr/lib/gcc/x86_64-linux-gnu/14/include/stdarg.h + /usr/lib/gcc/x86_64-linux-gnu/14/include/stddef.h + +CMakeFiles/nostr-id-tui.dir/src/systemd_client.c.o + /home/user/lt/n_os_tr/stack/nostr-id-tui/src/systemd_client.c + /home/user/lt/n_os_tr/stack/nostr-id-tui/include/n_os_tr_tui.h + /usr/include/asm-generic/errno-base.h + /usr/include/asm-generic/errno.h + /usr/include/errno.h + /usr/include/features-time64.h + /usr/include/features.h + /usr/include/linux/errno.h + /usr/include/stdc-predef.h + /usr/include/stdio.h + /usr/include/stdlib.h + /usr/include/string.h + /usr/include/unistd.h + /usr/include/x86_64-linux-gnu/bits/confname.h + /usr/include/x86_64-linux-gnu/bits/errno.h + /usr/include/x86_64-linux-gnu/bits/floatn-common.h + /usr/include/x86_64-linux-gnu/bits/floatn.h + /usr/include/x86_64-linux-gnu/bits/libc-header-start.h + /usr/include/x86_64-linux-gnu/bits/long-double.h + /usr/include/x86_64-linux-gnu/bits/posix_opt.h + /usr/include/x86_64-linux-gnu/bits/stdio_lim.h + /usr/include/x86_64-linux-gnu/bits/stdlib-float.h + /usr/include/x86_64-linux-gnu/bits/time64.h + /usr/include/x86_64-linux-gnu/bits/timesize.h + /usr/include/x86_64-linux-gnu/bits/types.h + /usr/include/x86_64-linux-gnu/bits/types/FILE.h + /usr/include/x86_64-linux-gnu/bits/types/__FILE.h + /usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h + /usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h + /usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h + /usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h + /usr/include/x86_64-linux-gnu/bits/typesizes.h + /usr/include/x86_64-linux-gnu/bits/unistd_ext.h + /usr/include/x86_64-linux-gnu/bits/waitflags.h + /usr/include/x86_64-linux-gnu/bits/waitstatus.h + /usr/include/x86_64-linux-gnu/bits/wordsize.h + /usr/include/x86_64-linux-gnu/gnu/stubs-64.h + /usr/include/x86_64-linux-gnu/gnu/stubs.h + /usr/include/x86_64-linux-gnu/sys/cdefs.h + /usr/include/x86_64-linux-gnu/sys/wait.h + /usr/lib/gcc/x86_64-linux-gnu/14/include/stdarg.h + /usr/lib/gcc/x86_64-linux-gnu/14/include/stddef.h + /usr/lib/linux/uapi/x86/asm/errno.h + nostr-id-tui /home/user/lt/n_os_tr/includes/nostr_core_lib/libnostr_core_x64.a /lib/x86_64-linux-gnu/libc.so.6 @@ -112,4 +196,6 @@ nostr-id-tui /usr/lib/x86_64-linux-gnu/libc_nonshared.a /usr/lib/x86_64-linux-gnu/libform.so /home/user/lt/n_os_tr/stack/nostr-id-tui/build-host/CMakeFiles/nostr-id-tui.dir/src/main.c.o + /home/user/lt/n_os_tr/stack/nostr-id-tui/build-host/CMakeFiles/nostr-id-tui.dir/src/services_conf.c.o + /home/user/lt/n_os_tr/stack/nostr-id-tui/build-host/CMakeFiles/nostr-id-tui.dir/src/systemd_client.c.o diff --git a/stack/nostr-id-tui/build-host/CMakeFiles/nostr-id-tui.dir/compiler_depend.make b/stack/nostr-id-tui/build-host/CMakeFiles/nostr-id-tui.dir/compiler_depend.make index cfd084e6..dac911f3 100644 --- a/stack/nostr-id-tui/build-host/CMakeFiles/nostr-id-tui.dir/compiler_depend.make +++ b/stack/nostr-id-tui/build-host/CMakeFiles/nostr-id-tui.dir/compiler_depend.make @@ -51,12 +51,11 @@ CMakeFiles/nostr-id-tui.dir/src/main.c.o: /home/user/lt/n_os_tr/stack/nostr-id-t /usr/include/x86_64-linux-gnu/bits/floatn.h \ /usr/include/x86_64-linux-gnu/bits/libc-header-start.h \ /usr/include/x86_64-linux-gnu/bits/long-double.h \ + /usr/include/x86_64-linux-gnu/bits/select.h \ /usr/include/x86_64-linux-gnu/bits/stdint-intn.h \ /usr/include/x86_64-linux-gnu/bits/stdint-least.h \ /usr/include/x86_64-linux-gnu/bits/stdint-uintn.h \ - /usr/include/x86_64-linux-gnu/bits/stdio.h \ /usr/include/x86_64-linux-gnu/bits/stdio_lim.h \ - /usr/include/x86_64-linux-gnu/bits/stdlib-bsearch.h \ /usr/include/x86_64-linux-gnu/bits/stdlib-float.h \ /usr/include/x86_64-linux-gnu/bits/time.h \ /usr/include/x86_64-linux-gnu/bits/time64.h \ @@ -67,8 +66,11 @@ CMakeFiles/nostr-id-tui.dir/src/main.c.o: /home/user/lt/n_os_tr/stack/nostr-id-t /usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h \ /usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h \ /usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__sigset_t.h \ /usr/include/x86_64-linux-gnu/bits/types/clock_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/sigset_t.h \ /usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_timeval.h \ /usr/include/x86_64-linux-gnu/bits/types/struct_tm.h \ /usr/include/x86_64-linux-gnu/bits/types/time_t.h \ /usr/include/x86_64-linux-gnu/bits/typesizes.h \ @@ -77,11 +79,91 @@ CMakeFiles/nostr-id-tui.dir/src/main.c.o: /home/user/lt/n_os_tr/stack/nostr-id-t /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ /usr/include/x86_64-linux-gnu/gnu/stubs.h \ /usr/include/x86_64-linux-gnu/sys/cdefs.h \ + /usr/include/x86_64-linux-gnu/sys/select.h \ + /usr/include/x86_64-linux-gnu/sys/time.h \ /usr/lib/gcc/x86_64-linux-gnu/14/include/stdarg.h \ /usr/lib/gcc/x86_64-linux-gnu/14/include/stdbool.h \ /usr/lib/gcc/x86_64-linux-gnu/14/include/stddef.h \ /usr/lib/gcc/x86_64-linux-gnu/14/include/stdint.h +CMakeFiles/nostr-id-tui.dir/src/services_conf.c.o: /home/user/lt/n_os_tr/stack/nostr-id-tui/src/services_conf.c \ + /home/user/lt/n_os_tr/stack/nostr-id-tui/include/n_os_tr_tui.h \ + /usr/include/ctype.h \ + /usr/include/features-time64.h \ + /usr/include/features.h \ + /usr/include/stdc-predef.h \ + /usr/include/stdio.h \ + /usr/include/stdlib.h \ + /usr/include/string.h \ + /usr/include/x86_64-linux-gnu/bits/endian.h \ + /usr/include/x86_64-linux-gnu/bits/endianness.h \ + /usr/include/x86_64-linux-gnu/bits/floatn-common.h \ + /usr/include/x86_64-linux-gnu/bits/floatn.h \ + /usr/include/x86_64-linux-gnu/bits/libc-header-start.h \ + /usr/include/x86_64-linux-gnu/bits/long-double.h \ + /usr/include/x86_64-linux-gnu/bits/stdio_lim.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib-float.h \ + /usr/include/x86_64-linux-gnu/bits/time64.h \ + /usr/include/x86_64-linux-gnu/bits/timesize.h \ + /usr/include/x86_64-linux-gnu/bits/types.h \ + /usr/include/x86_64-linux-gnu/bits/types/FILE.h \ + /usr/include/x86_64-linux-gnu/bits/types/__FILE.h \ + /usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h \ + /usr/include/x86_64-linux-gnu/bits/typesizes.h \ + /usr/include/x86_64-linux-gnu/bits/wordsize.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs.h \ + /usr/include/x86_64-linux-gnu/sys/cdefs.h \ + /usr/lib/gcc/x86_64-linux-gnu/14/include/stdarg.h \ + /usr/lib/gcc/x86_64-linux-gnu/14/include/stddef.h + +CMakeFiles/nostr-id-tui.dir/src/systemd_client.c.o: /home/user/lt/n_os_tr/stack/nostr-id-tui/src/systemd_client.c \ + /home/user/lt/n_os_tr/stack/nostr-id-tui/include/n_os_tr_tui.h \ + /usr/include/asm-generic/errno-base.h \ + /usr/include/asm-generic/errno.h \ + /usr/include/errno.h \ + /usr/include/features-time64.h \ + /usr/include/features.h \ + /usr/include/linux/errno.h \ + /usr/include/stdc-predef.h \ + /usr/include/stdio.h \ + /usr/include/stdlib.h \ + /usr/include/string.h \ + /usr/include/unistd.h \ + /usr/include/x86_64-linux-gnu/bits/confname.h \ + /usr/include/x86_64-linux-gnu/bits/errno.h \ + /usr/include/x86_64-linux-gnu/bits/floatn-common.h \ + /usr/include/x86_64-linux-gnu/bits/floatn.h \ + /usr/include/x86_64-linux-gnu/bits/libc-header-start.h \ + /usr/include/x86_64-linux-gnu/bits/long-double.h \ + /usr/include/x86_64-linux-gnu/bits/posix_opt.h \ + /usr/include/x86_64-linux-gnu/bits/stdio_lim.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib-float.h \ + /usr/include/x86_64-linux-gnu/bits/time64.h \ + /usr/include/x86_64-linux-gnu/bits/timesize.h \ + /usr/include/x86_64-linux-gnu/bits/types.h \ + /usr/include/x86_64-linux-gnu/bits/types/FILE.h \ + /usr/include/x86_64-linux-gnu/bits/types/__FILE.h \ + /usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h \ + /usr/include/x86_64-linux-gnu/bits/typesizes.h \ + /usr/include/x86_64-linux-gnu/bits/unistd_ext.h \ + /usr/include/x86_64-linux-gnu/bits/waitflags.h \ + /usr/include/x86_64-linux-gnu/bits/waitstatus.h \ + /usr/include/x86_64-linux-gnu/bits/wordsize.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs.h \ + /usr/include/x86_64-linux-gnu/sys/cdefs.h \ + /usr/include/x86_64-linux-gnu/sys/wait.h \ + /usr/lib/gcc/x86_64-linux-gnu/14/include/stdarg.h \ + /usr/lib/gcc/x86_64-linux-gnu/14/include/stddef.h \ + /usr/lib/linux/uapi/x86/asm/errno.h + nostr-id-tui: /home/user/lt/n_os_tr/includes/nostr_core_lib/libnostr_core_x64.a \ /lib/x86_64-linux-gnu/libc.so.6 \ /lib/x86_64-linux-gnu/libm.so.6 \ @@ -109,219 +191,263 @@ nostr-id-tui: /home/user/lt/n_os_tr/includes/nostr_core_lib/libnostr_core_x64.a /usr/lib/gcc/x86_64-linux-gnu/14/libgcc_s.so \ /usr/lib/x86_64-linux-gnu/libc_nonshared.a \ /usr/lib/x86_64-linux-gnu/libform.so \ - CMakeFiles/nostr-id-tui.dir/src/main.c.o + CMakeFiles/nostr-id-tui.dir/src/main.c.o \ + CMakeFiles/nostr-id-tui.dir/src/services_conf.c.o \ + CMakeFiles/nostr-id-tui.dir/src/systemd_client.c.o -/usr/lib/x86_64-linux-gnu/libform.so: - -/usr/lib/x86_64-linux-gnu/libc_nonshared.a: - -/usr/lib/gcc/x86_64-linux-gnu/14/libgcc.a: - -/usr/lib/gcc/x86_64-linux-gnu/14/crtendS.o: - -/usr/lib/x86_64-linux-gnu/libz.so: - -/usr/lib/x86_64-linux-gnu/libtinfo.so: - -/usr/lib/x86_64-linux-gnu/libssl.so: - -/usr/lib/x86_64-linux-gnu/libpthread.a: - -/usr/lib/x86_64-linux-gnu/libncurses.so.6: - -/usr/lib/x86_64-linux-gnu/libdl.a: - -/usr/lib/x86_64-linux-gnu/libcrypto.so: - -/usr/lib/x86_64-linux-gnu/libc.so: - -/usr/lib/x86_64-linux-gnu/crti.o: - -/usr/lib/x86_64-linux-gnu/Scrt1.o: - -/lib/x86_64-linux-gnu/libmvec.so.1: - -/usr/lib/gcc/x86_64-linux-gnu/14/include/stdint.h: - -/usr/lib/gcc/x86_64-linux-gnu/14/include/stdbool.h: - -/usr/include/x86_64-linux-gnu/sys/cdefs.h: - -/usr/include/x86_64-linux-gnu/gnu/stubs-64.h: - -/usr/include/x86_64-linux-gnu/bits/wordsize.h: - -/usr/include/x86_64-linux-gnu/bits/typesizes.h: - -CMakeFiles/nostr-id-tui.dir/src/main.c.o: - -/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h: - -/usr/lib/x86_64-linux-gnu/libm.so: - -/lib/x86_64-linux-gnu/libc.so.6: - -/usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h: - -/usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h: - -/usr/include/x86_64-linux-gnu/bits/types.h: - -/home/user/lt/n_os_tr/includes/nostr_core_lib/nostr_core/nostr_secure_memory.h: - -/home/user/lt/n_os_tr/includes/nostr_core_lib/nostr_core/nostr_fips_ipv6.h: - -/usr/lib/gcc/x86_64-linux-gnu/14/include/stdarg.h: - -/usr/include/ctype.h: - -/home/user/lt/n_os_tr/includes/nostr_core_lib/nostr_core/nostr_bip39_ui.h: - -/usr/include/curses.h: - -/home/user/lt/n_os_tr/includes/nostr_core_lib/nostr_core/nip060.h: - -/home/user/lt/n_os_tr/includes/nostr_core_lib/cjson/cJSON.h: - -/home/user/lt/n_os_tr/includes/nostr_core_lib/nostr_core/nip021.h: - -/usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h: - -/home/user/lt/n_os_tr/includes/nostr_core_lib/nostr_core/nip013.h: - -/home/user/lt/n_os_tr/includes/nostr_core_lib/nostr_core/request_validator.h: - -/usr/include/x86_64-linux-gnu/bits/libc-header-start.h: - -/home/user/lt/n_os_tr/includes/nostr_core_lib/nostr_core/nip004.h: - -/home/user/lt/n_os_tr/includes/nostr_core_lib/nostr_core/nostr_core.h: - -/home/user/lt/n_os_tr/includes/nostr_core_lib/nostr_core/nip061.h: - -/usr/include/x86_64-linux-gnu/bits/stdint-least.h: - -/usr/lib/x86_64-linux-gnu/libcurses.so: - -/usr/include/x86_64-linux-gnu/bits/time.h: - -/usr/include/x86_64-linux-gnu/gnu/stubs.h: - -/home/user/lt/n_os_tr/includes/nostr_core_lib/nostr_core/blossom_client.h: - -/usr/lib/x86_64-linux-gnu/libsecp256k1.so: - -/usr/include/x86_64-linux-gnu/bits/floatn-common.h: - -/usr/include/x86_64-linux-gnu/bits/wchar.h: - -/home/user/lt/n_os_tr/includes/nostr_core_lib/nostr_core/nostr_common.h: - -/home/user/lt/n_os_tr/stack/nostr-id-tui/src/main.c: - -/home/user/lt/n_os_tr/includes/nostr_core_lib/nostr_core/nostr_http.h: - -/home/user/lt/n_os_tr/includes/nostr_core_lib/nostr_core/nip046.h: - -/lib/x86_64-linux-gnu/libm.so.6: - -/usr/include/x86_64-linux-gnu/bits/types/time_t.h: - -/home/user/lt/n_os_tr/includes/nostr_core_lib/nostr_core/nip006.h: - -/usr/include/x86_64-linux-gnu/bits/types/clock_t.h: - -/usr/include/x86_64-linux-gnu/bits/types/__FILE.h: - -/home/user/lt/n_os_tr/includes/nostr_core_lib/nostr_core/cashu_mint.h: - -/home/user/lt/n_os_tr/includes/nostr_core_lib/nostr_core/nip011.h: - -/lib64/ld-linux-x86-64.so.2: - -/home/user/lt/n_os_tr/includes/nostr_core_lib/nostr_core/nip042.h: - -/home/user/lt/n_os_tr/includes/nostr_core_lib/nostr_core/nip005.h: - -/usr/include/x86_64-linux-gnu/bits/long-double.h: - -/home/user/lt/n_os_tr/includes/nostr_core_lib/nostr_core/nip019.h: - -/home/user/lt/n_os_tr/includes/nostr_core_lib/nostr_core/nip003.h: - -/usr/include/x86_64-linux-gnu/bits/floatn.h: - -/home/user/lt/n_os_tr/stack/nostr-id-tui/include/n_os_tr_tui.h: - -/usr/lib/x86_64-linux-gnu/crtn.o: - -/usr/include/unctrl.h: - -/home/user/lt/n_os_tr/includes/nostr_core_lib/nostr_core/utils.h: - -/usr/include/x86_64-linux-gnu/bits/time64.h: - -/usr/include/features-time64.h: - -/usr/include/features.h: - -/home/user/lt/n_os_tr/includes/nostr_core_lib/nostr_core/nip017.h: - -/usr/include/ncurses_dll.h: - -/usr/lib/gcc/x86_64-linux-gnu/14/libgcc_s.so: - -/usr/include/stdint.h: - -/usr/include/x86_64-linux-gnu/bits/timesize.h: - -/usr/include/stdio.h: - -/usr/include/stdlib.h: - -/usr/lib/x86_64-linux-gnu/libgcc_s.so.1: - -/home/user/lt/n_os_tr/includes/nostr_core_lib/nostr_core/nostr_log.h: - -/usr/include/x86_64-linux-gnu/bits/endian.h: - -/usr/include/string.h: - -/home/user/lt/n_os_tr/includes/nostr_core_lib/libnostr_core_x64.a: - -/usr/lib/gcc/x86_64-linux-gnu/14/include/stddef.h: - -/home/user/lt/n_os_tr/includes/nostr_core_lib/nostr_core/nip044.h: - -/usr/include/x86_64-linux-gnu/bits/stdint-uintn.h: - -/home/user/lt/n_os_tr/includes/nostr_core_lib/nostr_core/nip001.h: - -/usr/include/time.h: - -/usr/include/x86_64-linux-gnu/bits/stdio_lim.h: - -/usr/include/sqlite3.h: +CMakeFiles/nostr-id-tui.dir/src/systemd_client.c.o: /usr/include/x86_64-linux-gnu/bits/endianness.h: +/usr/include/sqlite3.h: + /usr/include/x86_64-linux-gnu/bits/stdint-intn.h: -/usr/include/x86_64-linux-gnu/bits/types/struct_tm.h: +/usr/include/x86_64-linux-gnu/bits/types.h: -/usr/include/x86_64-linux-gnu/bits/types/FILE.h: +/usr/include/time.h: -/usr/include/x86_64-linux-gnu/bits/stdio.h: +/home/user/lt/n_os_tr/includes/nostr_core_lib/nostr_core/nip001.h: -/usr/lib/gcc/x86_64-linux-gnu/14/crtbeginS.o: +/usr/lib/gcc/x86_64-linux-gnu/14/include/stddef.h: -/usr/lib/x86_64-linux-gnu/libcurl.so: +/home/user/lt/n_os_tr/includes/nostr_core_lib/libnostr_core_x64.a: -/home/user/lt/n_os_tr/includes/nostr_core_lib/nostr_core/nip059.h: +/usr/include/string.h: + +/home/user/lt/n_os_tr/includes/nostr_core_lib/nostr_core/nostr_log.h: + +/usr/lib/x86_64-linux-gnu/libgcc_s.so.1: + +/usr/include/x86_64-linux-gnu/bits/timesize.h: + +/usr/include/stdint.h: + +/usr/lib/gcc/x86_64-linux-gnu/14/libgcc_s.so: /usr/include/x86_64-linux-gnu/bits/stdlib-float.h: /usr/include/stdc-predef.h: -/usr/include/x86_64-linux-gnu/bits/stdlib-bsearch.h: +/home/user/lt/n_os_tr/includes/nostr_core_lib/nostr_core/nip059.h: + +/usr/lib/x86_64-linux-gnu/libcurl.so: + +/usr/include/ncurses_dll.h: + +/usr/include/features.h: + +/usr/include/features-time64.h: + +/usr/include/x86_64-linux-gnu/bits/select.h: + +/home/user/lt/n_os_tr/includes/nostr_core_lib/nostr_core/utils.h: + +/usr/include/x86_64-linux-gnu/bits/types/sigset_t.h: + +/usr/include/unctrl.h: + +/usr/lib/x86_64-linux-gnu/crtn.o: + +/home/user/lt/n_os_tr/stack/nostr-id-tui/include/n_os_tr_tui.h: + +/home/user/lt/n_os_tr/includes/nostr_core_lib/nostr_core/nip017.h: + +/usr/include/x86_64-linux-gnu/bits/floatn.h: + +/home/user/lt/n_os_tr/includes/nostr_core_lib/nostr_core/nip003.h: + +/home/user/lt/n_os_tr/includes/nostr_core_lib/nostr_core/nip019.h: + +/usr/include/x86_64-linux-gnu/bits/long-double.h: + +/usr/include/x86_64-linux-gnu/bits/types/__sigset_t.h: + +/home/user/lt/n_os_tr/includes/nostr_core_lib/nostr_core/nip005.h: + +/usr/include/x86_64-linux-gnu/bits/errno.h: + +/home/user/lt/n_os_tr/includes/nostr_core_lib/nostr_core/nip011.h: + +/home/user/lt/n_os_tr/includes/nostr_core_lib/nostr_core/cashu_mint.h: + +/usr/include/x86_64-linux-gnu/bits/types/__FILE.h: + +/usr/include/x86_64-linux-gnu/bits/types/clock_t.h: + +/home/user/lt/n_os_tr/includes/nostr_core_lib/nostr_core/nip006.h: + +/lib64/ld-linux-x86-64.so.2: + +/usr/include/x86_64-linux-gnu/bits/types/time_t.h: + +/lib/x86_64-linux-gnu/libm.so.6: + +/home/user/lt/n_os_tr/stack/nostr-id-tui/src/main.c: + +/usr/include/x86_64-linux-gnu/bits/wchar.h: + +/usr/include/x86_64-linux-gnu/bits/floatn-common.h: + +/home/user/lt/n_os_tr/includes/nostr_core_lib/nostr_core/nostr_http.h: + +/home/user/lt/n_os_tr/includes/nostr_core_lib/nostr_core/blossom_client.h: + +/usr/include/x86_64-linux-gnu/bits/endian.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs.h: + +/usr/include/x86_64-linux-gnu/bits/time.h: + +/usr/lib/x86_64-linux-gnu/libcurses.so: + +/usr/include/x86_64-linux-gnu/bits/stdint-least.h: + +/usr/include/x86_64-linux-gnu/bits/time64.h: + +/home/user/lt/n_os_tr/includes/nostr_core_lib/nostr_core/nip004.h: + +/usr/include/stdio.h: + +/home/user/lt/n_os_tr/stack/nostr-id-tui/src/services_conf.c: + +/usr/include/x86_64-linux-gnu/bits/libc-header-start.h: + +/home/user/lt/n_os_tr/includes/nostr_core_lib/nostr_core/request_validator.h: + +/home/user/lt/n_os_tr/includes/nostr_core_lib/nostr_core/nip013.h: + +/usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h: + +/home/user/lt/n_os_tr/includes/nostr_core_lib/nostr_core/nip021.h: + +/usr/include/x86_64-linux-gnu/bits/waitstatus.h: + +/home/user/lt/n_os_tr/includes/nostr_core_lib/cjson/cJSON.h: + +/home/user/lt/n_os_tr/includes/nostr_core_lib/nostr_core/nip060.h: + +/usr/include/curses.h: + +/usr/lib/gcc/x86_64-linux-gnu/14/crtbeginS.o: + +/home/user/lt/n_os_tr/includes/nostr_core_lib/nostr_core/nostr_bip39_ui.h: + +/usr/include/ctype.h: + +/usr/lib/gcc/x86_64-linux-gnu/14/include/stdarg.h: + +/usr/include/stdlib.h: + +/home/user/lt/n_os_tr/includes/nostr_core_lib/nostr_core/nostr_fips_ipv6.h: + +/home/user/lt/n_os_tr/stack/nostr-id-tui/src/systemd_client.c: + +/home/user/lt/n_os_tr/includes/nostr_core_lib/nostr_core/nip044.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_tm.h: + +/usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h: + +/lib/x86_64-linux-gnu/libc.so.6: + +/home/user/lt/n_os_tr/includes/nostr_core_lib/nostr_core/nostr_common.h: + +/usr/lib/x86_64-linux-gnu/libm.so: + +/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h: + +/usr/include/x86_64-linux-gnu/sys/cdefs.h: + +/home/user/lt/n_os_tr/includes/nostr_core_lib/nostr_core/nip046.h: + +/usr/include/x86_64-linux-gnu/bits/typesizes.h: + +/usr/include/x86_64-linux-gnu/bits/wordsize.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs-64.h: + +/usr/include/x86_64-linux-gnu/sys/time.h: + +/home/user/lt/n_os_tr/includes/nostr_core_lib/nostr_core/nip042.h: + +/usr/lib/gcc/x86_64-linux-gnu/14/include/stdbool.h: + +/usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h: + +/usr/include/x86_64-linux-gnu/sys/wait.h: + +/usr/lib/gcc/x86_64-linux-gnu/14/include/stdint.h: + +/usr/include/asm-generic/errno-base.h: + +/home/user/lt/n_os_tr/includes/nostr_core_lib/nostr_core/nip061.h: + +/usr/lib/x86_64-linux-gnu/libncurses.so.6: + +/usr/lib/x86_64-linux-gnu/libsecp256k1.so: + +/usr/include/asm-generic/errno.h: + +/usr/include/linux/errno.h: + +/usr/include/x86_64-linux-gnu/bits/stdint-uintn.h: + +/usr/include/x86_64-linux-gnu/sys/select.h: + +/usr/include/unistd.h: + +/home/user/lt/n_os_tr/includes/nostr_core_lib/nostr_core/nostr_secure_memory.h: + +/usr/include/x86_64-linux-gnu/bits/confname.h: + +/usr/include/x86_64-linux-gnu/bits/posix_opt.h: + +/usr/include/x86_64-linux-gnu/bits/waitflags.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_timeval.h: + +/usr/lib/linux/uapi/x86/asm/errno.h: + +/lib/x86_64-linux-gnu/libmvec.so.1: + +/usr/lib/x86_64-linux-gnu/Scrt1.o: + +/usr/lib/x86_64-linux-gnu/libc.so: + +CMakeFiles/nostr-id-tui.dir/src/main.c.o: + +/usr/lib/x86_64-linux-gnu/libcrypto.so: + +/usr/lib/x86_64-linux-gnu/libdl.a: + +/usr/lib/x86_64-linux-gnu/libpthread.a: + +/usr/lib/x86_64-linux-gnu/libssl.so: + +/home/user/lt/n_os_tr/includes/nostr_core_lib/nostr_core/nostr_core.h: + +/usr/include/errno.h: + +/usr/lib/x86_64-linux-gnu/libtinfo.so: + +/usr/lib/x86_64-linux-gnu/crti.o: + +/usr/lib/x86_64-linux-gnu/libz.so: + +/usr/include/x86_64-linux-gnu/bits/stdio_lim.h: + +/usr/include/x86_64-linux-gnu/bits/types/FILE.h: + +/usr/lib/gcc/x86_64-linux-gnu/14/crtendS.o: + +/usr/lib/gcc/x86_64-linux-gnu/14/libgcc.a: + +/usr/include/x86_64-linux-gnu/bits/unistd_ext.h: + +/usr/lib/x86_64-linux-gnu/libc_nonshared.a: + +/usr/lib/x86_64-linux-gnu/libform.so: + +CMakeFiles/nostr-id-tui.dir/src/services_conf.c.o: diff --git a/stack/nostr-id-tui/build-host/CMakeFiles/nostr-id-tui.dir/link.d b/stack/nostr-id-tui/build-host/CMakeFiles/nostr-id-tui.dir/link.d index 17eaf57c..bd824f80 100644 --- a/stack/nostr-id-tui/build-host/CMakeFiles/nostr-id-tui.dir/link.d +++ b/stack/nostr-id-tui/build-host/CMakeFiles/nostr-id-tui.dir/link.d @@ -3,6 +3,8 @@ nostr-id-tui: \ /usr/lib/gcc/x86_64-linux-gnu/14/../../../x86_64-linux-gnu/crti.o \ /usr/lib/gcc/x86_64-linux-gnu/14/crtbeginS.o \ CMakeFiles/nostr-id-tui.dir/src/main.c.o \ + CMakeFiles/nostr-id-tui.dir/src/services_conf.c.o \ + CMakeFiles/nostr-id-tui.dir/src/systemd_client.c.o \ /home/user/lt/n_os_tr/stack/nostr-id-tui/../../includes/nostr_core_lib/libnostr_core_x64.a \ /usr/lib/gcc/x86_64-linux-gnu/14/../../../x86_64-linux-gnu/libcurses.so \ /usr/lib/gcc/x86_64-linux-gnu/14/../../../x86_64-linux-gnu/libcurses.so \ @@ -52,6 +54,10 @@ nostr-id-tui: \ CMakeFiles/nostr-id-tui.dir/src/main.c.o: +CMakeFiles/nostr-id-tui.dir/src/services_conf.c.o: + +CMakeFiles/nostr-id-tui.dir/src/systemd_client.c.o: + /home/user/lt/n_os_tr/stack/nostr-id-tui/../../includes/nostr_core_lib/libnostr_core_x64.a: /usr/lib/gcc/x86_64-linux-gnu/14/../../../x86_64-linux-gnu/libcurses.so: diff --git a/stack/nostr-id-tui/build-host/CMakeFiles/nostr-id-tui.dir/link.txt b/stack/nostr-id-tui/build-host/CMakeFiles/nostr-id-tui.dir/link.txt index 569f51d2..248577d5 100644 --- a/stack/nostr-id-tui/build-host/CMakeFiles/nostr-id-tui.dir/link.txt +++ b/stack/nostr-id-tui/build-host/CMakeFiles/nostr-id-tui.dir/link.txt @@ -1 +1 @@ -/usr/bin/cc -g -Wl,--dependency-file=CMakeFiles/nostr-id-tui.dir/link.d "CMakeFiles/nostr-id-tui.dir/src/main.c.o" -o nostr-id-tui /home/user/lt/n_os_tr/stack/nostr-id-tui/../../includes/nostr_core_lib/libnostr_core_x64.a -lcurses /usr/lib/x86_64-linux-gnu/libform.so -lsecp256k1 -lssl -lcrypto -lcurl -lz -lpthread -lm -ldl +/usr/bin/cc -g -Wl,--dependency-file=CMakeFiles/nostr-id-tui.dir/link.d "CMakeFiles/nostr-id-tui.dir/src/main.c.o" "CMakeFiles/nostr-id-tui.dir/src/services_conf.c.o" "CMakeFiles/nostr-id-tui.dir/src/systemd_client.c.o" -o nostr-id-tui /home/user/lt/n_os_tr/stack/nostr-id-tui/../../includes/nostr_core_lib/libnostr_core_x64.a -lcurses /usr/lib/x86_64-linux-gnu/libform.so -lsecp256k1 -lssl -lcrypto -lcurl -lz -lpthread -lm -ldl diff --git a/stack/nostr-id-tui/build-host/CMakeFiles/nostr-id-tui.dir/progress.make b/stack/nostr-id-tui/build-host/CMakeFiles/nostr-id-tui.dir/progress.make index abadeb0c..a69a57e8 100644 --- a/stack/nostr-id-tui/build-host/CMakeFiles/nostr-id-tui.dir/progress.make +++ b/stack/nostr-id-tui/build-host/CMakeFiles/nostr-id-tui.dir/progress.make @@ -1,3 +1,5 @@ CMAKE_PROGRESS_1 = 1 CMAKE_PROGRESS_2 = 2 +CMAKE_PROGRESS_3 = 3 +CMAKE_PROGRESS_4 = 4 diff --git a/stack/nostr-id-tui/build-host/CMakeFiles/nostr-id-tui.dir/src/main.c.o b/stack/nostr-id-tui/build-host/CMakeFiles/nostr-id-tui.dir/src/main.c.o index 2d119fc9..7f3b5af8 100644 Binary files a/stack/nostr-id-tui/build-host/CMakeFiles/nostr-id-tui.dir/src/main.c.o and b/stack/nostr-id-tui/build-host/CMakeFiles/nostr-id-tui.dir/src/main.c.o differ diff --git a/stack/nostr-id-tui/build-host/CMakeFiles/nostr-id-tui.dir/src/main.c.o.d b/stack/nostr-id-tui/build-host/CMakeFiles/nostr-id-tui.dir/src/main.c.o.d index 99146bb6..0e77d3a1 100644 --- a/stack/nostr-id-tui/build-host/CMakeFiles/nostr-id-tui.dir/src/main.c.o.d +++ b/stack/nostr-id-tui/build-host/CMakeFiles/nostr-id-tui.dir/src/main.c.o.d @@ -34,6 +34,13 @@ CMakeFiles/nostr-id-tui.dir/src/main.c.o: \ /usr/lib/gcc/x86_64-linux-gnu/14/include/stdbool.h /usr/include/unctrl.h \ /usr/include/curses.h /usr/include/stdlib.h \ /usr/include/x86_64-linux-gnu/bits/stdlib-float.h /usr/include/string.h \ + /usr/include/x86_64-linux-gnu/sys/time.h \ + /usr/include/x86_64-linux-gnu/bits/types/time_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_timeval.h \ + /usr/include/x86_64-linux-gnu/sys/select.h \ + /usr/include/x86_64-linux-gnu/bits/select.h \ + /usr/include/x86_64-linux-gnu/bits/types/sigset_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__sigset_t.h \ /home/user/lt/n_os_tr/stack/nostr-id-tui/include/n_os_tr_tui.h \ /home/user/lt/n_os_tr/stack/nostr-id-tui/../../includes/nostr_core_lib/nostr_core/nostr_core.h \ /home/user/lt/n_os_tr/stack/nostr-id-tui/../../includes/nostr_core_lib/nostr_core/nostr_common.h \ @@ -44,7 +51,6 @@ CMakeFiles/nostr-id-tui.dir/src/main.c.o: \ /home/user/lt/n_os_tr/stack/nostr-id-tui/../../includes/nostr_core_lib/nostr_core/nip001.h \ /usr/include/time.h /usr/include/x86_64-linux-gnu/bits/time.h \ /usr/include/x86_64-linux-gnu/bits/types/clock_t.h \ - /usr/include/x86_64-linux-gnu/bits/types/time_t.h \ /usr/include/x86_64-linux-gnu/bits/types/struct_tm.h \ /home/user/lt/n_os_tr/stack/nostr-id-tui/../../includes/nostr_core_lib/nostr_core/../cjson/cJSON.h \ /home/user/lt/n_os_tr/stack/nostr-id-tui/../../includes/nostr_core_lib/nostr_core/nip003.h \ diff --git a/stack/nostr-id-tui/build-host/CMakeFiles/nostr-id-tui.dir/src/services_conf.c.o b/stack/nostr-id-tui/build-host/CMakeFiles/nostr-id-tui.dir/src/services_conf.c.o new file mode 100644 index 00000000..6519e394 Binary files /dev/null and b/stack/nostr-id-tui/build-host/CMakeFiles/nostr-id-tui.dir/src/services_conf.c.o differ diff --git a/stack/nostr-id-tui/build-host/CMakeFiles/nostr-id-tui.dir/src/services_conf.c.o.d b/stack/nostr-id-tui/build-host/CMakeFiles/nostr-id-tui.dir/src/services_conf.c.o.d new file mode 100644 index 00000000..2e51fcc7 --- /dev/null +++ b/stack/nostr-id-tui/build-host/CMakeFiles/nostr-id-tui.dir/src/services_conf.c.o.d @@ -0,0 +1,29 @@ +CMakeFiles/nostr-id-tui.dir/src/services_conf.c.o: \ + /home/user/lt/n_os_tr/stack/nostr-id-tui/src/services_conf.c \ + /usr/include/stdc-predef.h /usr/include/ctype.h /usr/include/features.h \ + /usr/include/features-time64.h \ + /usr/include/x86_64-linux-gnu/bits/wordsize.h \ + /usr/include/x86_64-linux-gnu/bits/timesize.h \ + /usr/include/x86_64-linux-gnu/sys/cdefs.h \ + /usr/include/x86_64-linux-gnu/bits/long-double.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ + /usr/include/x86_64-linux-gnu/bits/types.h \ + /usr/include/x86_64-linux-gnu/bits/typesizes.h \ + /usr/include/x86_64-linux-gnu/bits/time64.h \ + /usr/include/x86_64-linux-gnu/bits/endian.h \ + /usr/include/x86_64-linux-gnu/bits/endianness.h /usr/include/stdio.h \ + /usr/include/x86_64-linux-gnu/bits/libc-header-start.h \ + /usr/lib/gcc/x86_64-linux-gnu/14/include/stddef.h \ + /usr/lib/gcc/x86_64-linux-gnu/14/include/stdarg.h \ + /usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__FILE.h \ + /usr/include/x86_64-linux-gnu/bits/types/FILE.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h \ + /usr/include/x86_64-linux-gnu/bits/stdio_lim.h \ + /usr/include/x86_64-linux-gnu/bits/floatn.h \ + /usr/include/x86_64-linux-gnu/bits/floatn-common.h /usr/include/stdlib.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib-float.h /usr/include/string.h \ + /home/user/lt/n_os_tr/stack/nostr-id-tui/include/n_os_tr_tui.h diff --git a/stack/nostr-id-tui/build-host/CMakeFiles/nostr-id-tui.dir/src/systemd_client.c.o b/stack/nostr-id-tui/build-host/CMakeFiles/nostr-id-tui.dir/src/systemd_client.c.o new file mode 100644 index 00000000..56e3dc8b Binary files /dev/null and b/stack/nostr-id-tui/build-host/CMakeFiles/nostr-id-tui.dir/src/systemd_client.c.o differ diff --git a/stack/nostr-id-tui/build-host/CMakeFiles/nostr-id-tui.dir/src/systemd_client.c.o.d b/stack/nostr-id-tui/build-host/CMakeFiles/nostr-id-tui.dir/src/systemd_client.c.o.d new file mode 100644 index 00000000..b2a24994 --- /dev/null +++ b/stack/nostr-id-tui/build-host/CMakeFiles/nostr-id-tui.dir/src/systemd_client.c.o.d @@ -0,0 +1,36 @@ +CMakeFiles/nostr-id-tui.dir/src/systemd_client.c.o: \ + /home/user/lt/n_os_tr/stack/nostr-id-tui/src/systemd_client.c \ + /usr/include/stdc-predef.h /usr/include/errno.h /usr/include/features.h \ + /usr/include/features-time64.h \ + /usr/include/x86_64-linux-gnu/bits/wordsize.h \ + /usr/include/x86_64-linux-gnu/bits/timesize.h \ + /usr/include/x86_64-linux-gnu/sys/cdefs.h \ + /usr/include/x86_64-linux-gnu/bits/long-double.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ + /usr/include/x86_64-linux-gnu/bits/errno.h /usr/include/linux/errno.h \ + /usr/lib/linux/uapi/x86/asm/errno.h /usr/include/asm-generic/errno.h \ + /usr/include/asm-generic/errno-base.h /usr/include/stdio.h \ + /usr/include/x86_64-linux-gnu/bits/libc-header-start.h \ + /usr/lib/gcc/x86_64-linux-gnu/14/include/stddef.h \ + /usr/lib/gcc/x86_64-linux-gnu/14/include/stdarg.h \ + /usr/include/x86_64-linux-gnu/bits/types.h \ + /usr/include/x86_64-linux-gnu/bits/typesizes.h \ + /usr/include/x86_64-linux-gnu/bits/time64.h \ + /usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__FILE.h \ + /usr/include/x86_64-linux-gnu/bits/types/FILE.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h \ + /usr/include/x86_64-linux-gnu/bits/stdio_lim.h \ + /usr/include/x86_64-linux-gnu/bits/floatn.h \ + /usr/include/x86_64-linux-gnu/bits/floatn-common.h /usr/include/stdlib.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib-float.h /usr/include/string.h \ + /usr/include/x86_64-linux-gnu/sys/wait.h \ + /usr/include/x86_64-linux-gnu/bits/waitflags.h \ + /usr/include/x86_64-linux-gnu/bits/waitstatus.h /usr/include/unistd.h \ + /usr/include/x86_64-linux-gnu/bits/posix_opt.h \ + /usr/include/x86_64-linux-gnu/bits/confname.h \ + /usr/include/x86_64-linux-gnu/bits/unistd_ext.h \ + /home/user/lt/n_os_tr/stack/nostr-id-tui/include/n_os_tr_tui.h diff --git a/stack/nostr-id-tui/build-host/CMakeFiles/progress.marks b/stack/nostr-id-tui/build-host/CMakeFiles/progress.marks index 0cfbf088..b8626c4c 100644 --- a/stack/nostr-id-tui/build-host/CMakeFiles/progress.marks +++ b/stack/nostr-id-tui/build-host/CMakeFiles/progress.marks @@ -1 +1 @@ -2 +4 diff --git a/stack/nostr-id-tui/build-host/Makefile b/stack/nostr-id-tui/build-host/Makefile index 249f5817..73cb8ca6 100644 --- a/stack/nostr-id-tui/build-host/Makefile +++ b/stack/nostr-id-tui/build-host/Makefile @@ -153,6 +153,54 @@ src/main.c.s: $(MAKE) $(MAKESILENT) -f CMakeFiles/nostr-id-tui.dir/build.make CMakeFiles/nostr-id-tui.dir/src/main.c.s .PHONY : src/main.c.s +src/services_conf.o: src/services_conf.c.o +.PHONY : src/services_conf.o + +# target to build an object file +src/services_conf.c.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/nostr-id-tui.dir/build.make CMakeFiles/nostr-id-tui.dir/src/services_conf.c.o +.PHONY : src/services_conf.c.o + +src/services_conf.i: src/services_conf.c.i +.PHONY : src/services_conf.i + +# target to preprocess a source file +src/services_conf.c.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/nostr-id-tui.dir/build.make CMakeFiles/nostr-id-tui.dir/src/services_conf.c.i +.PHONY : src/services_conf.c.i + +src/services_conf.s: src/services_conf.c.s +.PHONY : src/services_conf.s + +# target to generate assembly for a file +src/services_conf.c.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/nostr-id-tui.dir/build.make CMakeFiles/nostr-id-tui.dir/src/services_conf.c.s +.PHONY : src/services_conf.c.s + +src/systemd_client.o: src/systemd_client.c.o +.PHONY : src/systemd_client.o + +# target to build an object file +src/systemd_client.c.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/nostr-id-tui.dir/build.make CMakeFiles/nostr-id-tui.dir/src/systemd_client.c.o +.PHONY : src/systemd_client.c.o + +src/systemd_client.i: src/systemd_client.c.i +.PHONY : src/systemd_client.i + +# target to preprocess a source file +src/systemd_client.c.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/nostr-id-tui.dir/build.make CMakeFiles/nostr-id-tui.dir/src/systemd_client.c.i +.PHONY : src/systemd_client.c.i + +src/systemd_client.s: src/systemd_client.c.s +.PHONY : src/systemd_client.s + +# target to generate assembly for a file +src/systemd_client.c.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/nostr-id-tui.dir/build.make CMakeFiles/nostr-id-tui.dir/src/systemd_client.c.s +.PHONY : src/systemd_client.c.s + # Help Target help: @echo "The following are some of the valid targets for this Makefile:" @@ -165,6 +213,12 @@ help: @echo "... src/main.o" @echo "... src/main.i" @echo "... src/main.s" + @echo "... src/services_conf.o" + @echo "... src/services_conf.i" + @echo "... src/services_conf.s" + @echo "... src/systemd_client.o" + @echo "... src/systemd_client.i" + @echo "... src/systemd_client.s" .PHONY : help diff --git a/stack/nostr-id-tui/build-host/nostr-id-tui b/stack/nostr-id-tui/build-host/nostr-id-tui index 93e52c3f..dd6affcb 100755 Binary files a/stack/nostr-id-tui/build-host/nostr-id-tui and b/stack/nostr-id-tui/build-host/nostr-id-tui differ diff --git a/stack/nostr-id-tui/build-host/test-services-sim.out b/stack/nostr-id-tui/build-host/test-services-sim.out new file mode 100644 index 00000000..04351b45 --- /dev/null +++ b/stack/nostr-id-tui/build-host/test-services-sim.out @@ -0,0 +1,2 @@ +[?1049h(B[?7h[?1h=[?25l= n-OS-tr Identity ==TUI version: 0.2.0^[[4m1^[[0m) Enter existing mnemonic^[[4m2^[[0m) Generate new mnemonicE^[[4mx^[[0mitSelect option: > = n-OS-tr Identity ==TUI version: 0.2.0^[[4m1^[[0m) Enter existing mnemonic^[[4m2^[[0m) Generate new mnemonicE^[[4mx^[[0mitSelect option: > +Session terminated, killing shell... ...killed. diff --git a/stack/nostr-id-tui/include/n_os_tr_tui.h b/stack/nostr-id-tui/include/n_os_tr_tui.h index 45e932fc..3acec662 100644 --- a/stack/nostr-id-tui/include/n_os_tr_tui.h +++ b/stack/nostr-id-tui/include/n_os_tr_tui.h @@ -1,9 +1,32 @@ #ifndef N_OS_TR_TUI_H #define N_OS_TR_TUI_H -#define N_OS_TR_TUI_VERSION "0.1.0" +#include + +#define N_OS_TR_TUI_VERSION "0.2.0" #define NOSTR_TUI_MAX_MNEMONIC 256 #define NOSTR_TUI_MAX_NPUB 128 +#define N_OS_TR_TUI_MAX_SERVICES 16 + +#define N_OS_TR_TUI_OK 0 +#define N_OS_TR_TUI_ERR 1 + +typedef struct { + char key; + char unit[64]; + char label[64]; + int default_on; + char deps[128]; + int desired_on; +} service_entry_t; + +int services_conf_load(const char* path, service_entry_t* out, size_t max, size_t* out_count); +int services_conf_load_fallback(service_entry_t* out, size_t max, size_t* out_count); + +int systemd_is_simulation_mode(void); +int systemd_unit_is_active(const char* unit, int* is_active); +int systemd_unit_start(const char* unit, char* err_out, size_t err_out_len); +int systemd_unit_stop(const char* unit, char* err_out, size_t err_out_len); #endif /* N_OS_TR_TUI_H */ diff --git a/stack/nostr-id-tui/src/main.c b/stack/nostr-id-tui/src/main.c index f570ee37..4ab0f7a5 100644 --- a/stack/nostr-id-tui/src/main.c +++ b/stack/nostr-id-tui/src/main.c @@ -4,6 +4,8 @@ #include #include +#include + #include "n_os_tr_tui.h" #include "nostr_core/nostr_core.h" @@ -11,29 +13,180 @@ typedef enum { SCREEN_MENU = 0, SCREEN_ENTER = 1, SCREEN_GENERATE = 2, - SCREEN_EXIT = 3 + SCREEN_SERVICES = 3, + SCREEN_EXIT = 4 } screen_t; -static void clear_and_title(const char* title) { - clear(); - mvprintw(0, 2, "n-OS-tr nostr-id-tui v%s", N_OS_TR_TUI_VERSION); - mvprintw(1, 2, "%s", title); - mvhline(2, 1, ACS_HLINE, 76); +typedef struct { + int identity_loaded; + char main_npub[NOSTR_TUI_MAX_NPUB]; + service_entry_t services[N_OS_TR_TUI_MAX_SERVICES]; + size_t service_count; +} app_state_t; + +#define BANNER_HEIGHT 9 +#define BANNER_IN_MS 3000LL +#define BANNER_HOLD_MS 3000LL +#define BANNER_OUT_MS 3000LL +#define BANNER_PAUSE_MS 3000LL +#define BANNER_CYCLE_MS (BANNER_IN_MS + BANNER_HOLD_MS + BANNER_OUT_MS + BANNER_PAUSE_MS) + + + + +static const char* BANNER_ART[BANNER_HEIGHT] = { + "____________________________/\\\\\\\\\\__________/\\\\\\\\\\\\\\\\\\\\\\______________________________________________", + "___________________________/\\\\\\///\\\\\\______/\\\\\\/////////\\\\\\___________________________________________", + "__________________________/\\\\\\/__\\///\\\\\\___\\//\\\\\\______\\///_________________/\\\\\\______________________", + "_/\\\\/\\\\\\\\\\\\_______________/\\\\\\______\\//\\\\\\___\\////\\\\\\_____________________/\\\\\\\\\\\\\\\\\\\\\\__/\\\\/\\\\\\\\\\\\\\___", + "_\\/\\\\\\////\\\\\\_____________\\/\\\\\\_______\\/\\\\\\______\\////\\\\\\_________________\\////\\\\\\////__\\/\\\\\\/////\\\\\\_", + "__\\/\\\\\\__\\//\\\\\\____________\\//\\\\\\______/\\\\\\__________\\////\\\\\\_________________\\/\\\\\\______\\/\\\\\\___\\///_", + "___\\/\\\\\\___\\/\\\\\\_____________\\///\\\\\\__/\\\\\\_____/\\\\\\______\\//\\\\\\________________\\/\\\\\\_/\\\\__\\/\\\\\\_______", + "____\\/\\\\\\___\\/\\\\\\__/\\\\\\\\\\\\\\\\____\\///\\\\\\\\\\/_____\\///\\\\\\\\\\\\\\\\\\\\\\/____/\\\\\\\\\\\\\\\\____\\//\\\\\\\\\\___\\/\\\\\\______", + "_____\\///____\\///__\\////////_______\\/////_________\\///////////_____\\////////______\\/////____\\///______" +}; + +// Unescaped editable banner reference (do not compile directly): +// +// ____________________________/\\\\\__________/\\\\\\\\\\\______________________________________________ +// ___________________________/\\\///\\\______/\\\/////////\\\___________________________________________ +// __________________________/\\\/__\///\\\___\//\\\______\///_________________/\\\______________________ +// _/\\/\\\\\\_______________/\\\______\//\\\___\////\\\_____________________/\\\\\\\\\\\__/\\/\\\\\\\___ +// _\/\\\////\\\_____________\/\\\_______\/\\\______\////\\\_________________\////\\\////__\/\\\/////\\\_ +//___\/\\\__\//\\\____________\//\\\______/\\\__________\////\\\_________________\/\\\______\/\\\___\///_ +// ___\/\\\___\/\\\_____________\///\\\__/\\\_____/\\\______\//\\\________________\/\\\_/\\__\/\\\_______ +// ____\/\\\___\/\\\__/\\\\\\\\____\///\\\\\/_____\///\\\\\\\\\\\/____/\\\\\\\\____\//\\\\\___\/\\\______ +// _____\///____\///__\////////_______\/////_________\///////////_____\////////______\/////____\///______ + + + + + + + + + +static int ui_row(int y) { + return y + BANNER_HEIGHT + 1; +} + +static long long monotonic_ms(void) { + struct timeval tv; + if (gettimeofday(&tv, NULL) != 0) { + return 0; + } + return ((long long)tv.tv_sec * 1000LL) + ((long long)tv.tv_usec / 1000LL); +} + +static int banner_art_width(void) { + int i; + int max_width = 0; + + for (i = 0; i < BANNER_HEIGHT; ++i) { + int w = (int)strlen(BANNER_ART[i]); + if (w > max_width) { + max_width = w; + } + } + + return max_width; +} + +static void render_banner_frame(void) { + int row; + int col; + int screen_w = COLS; + int art_w = banner_art_width(); + int center_x = (screen_w - art_w) / 2; + long long t = monotonic_ms() % BANNER_CYCLE_MS; + int show_art = 1; + int art_x = center_x; + + for (row = 0; row < BANNER_HEIGHT; ++row) { + move(row, 0); + for (col = 0; col < screen_w; ++col) { + addch('_'); + } + } + + if (t < BANNER_IN_MS) { + int delta = center_x + art_w; + art_x = -art_w + (int)((delta * t) / BANNER_IN_MS); + } else if (t < (BANNER_IN_MS + BANNER_HOLD_MS)) { + art_x = center_x; + } else if (t < (BANNER_IN_MS + BANNER_HOLD_MS + BANNER_OUT_MS)) { + long long out_t = t - (BANNER_IN_MS + BANNER_HOLD_MS); + int delta = (screen_w + 1) - center_x; + art_x = center_x + (int)((delta * out_t) / BANNER_OUT_MS); + } else { + show_art = 0; + } + + if (!show_art) { + return; + } + + for (row = 0; row < BANNER_HEIGHT; ++row) { + const char* line = BANNER_ART[row]; + int len = (int)strlen(line); + for (col = 0; col < len; ++col) { + int x = art_x + col; + char ch = line[col]; + if (x < 0 || x >= screen_w) continue; + mvaddch(row, x, ch); + } + } } static void trim_line(char* s) { size_t len; if (!s) return; + len = strlen(s); while (len > 0 && (s[len - 1] == '\n' || s[len - 1] == '\r' || isspace((unsigned char)s[len - 1]))) { s[len - 1] = '\0'; len--; } + while (*s && isspace((unsigned char)*s)) { memmove(s, s + 1, strlen(s)); } } +static void draw_centered_header(const char* title) { + int width = COLS; + int title_len = (int)strlen(title); + int min_required = title_len + 4; + int left_pad, right_pad, i; + int r; + + /* Clear UI body when entering/redrawing a screen to avoid stale text + from previous screens (menu/generate/services overlays). */ + for (r = ui_row(1); r < LINES; ++r) { + move(r, 0); + clrtoeol(); + } + + /* Header line stays independently drawn below the banner. */ + move(ui_row(0), 0); + for (i = 0; i < COLS; ++i) addch(' '); + + if (width < min_required) { + mvprintw(ui_row(0), 0, "=== %s ===", title); + return; + } + + left_pad = (width - title_len - 2) / 2; + right_pad = width - title_len - 2 - left_pad; + + move(ui_row(0), 0); + for (i = 0; i < left_pad; ++i) addch('='); + addch(' '); + addstr(title); + addch(' '); + for (i = 0; i < right_pad; ++i) addch('='); +} + static int read_line_at(int y, int x, char* out, size_t out_size) { int rc; if (!out || out_size < 2) return NOSTR_ERROR_INVALID_INPUT; @@ -52,8 +205,15 @@ static int read_line_at(int y, int x, char* out, size_t out_size) { } static void wait_key(void) { + timeout(60); mvprintw(LINES - 2, 2, "Press any key to continue..."); - getch(); + refresh(); + while (getch() == ERR) { + render_banner_frame(); + mvprintw(LINES - 2, 2, "Press any key to continue..."); + refresh(); + } + timeout(-1); } static int derive_from_mnemonic(const char* mnemonic, char* npub_out, size_t npub_size) { @@ -73,9 +233,7 @@ static int derive_from_mnemonic(const char* mnemonic, char* npub_out, size_t npu memset(priv, 0, sizeof(priv)); memset(pub, 0, sizeof(pub)); - if (rc != NOSTR_SUCCESS) { - return rc; - } + if (rc != NOSTR_SUCCESS) return rc; npub_out[npub_size - 1] = '\0'; return NOSTR_SUCCESS; @@ -91,49 +249,193 @@ static void render_prefix_hint(const char* word_prefix) { return; } - mvprintw(11, 2, "Suggestions for '%s':", word_prefix); + mvprintw(ui_row(11), 2, "Suggestions for '%s':", word_prefix); for (size_t i = 0; i < count && i < 6; ++i) { - mvprintw(12 + (int)i, 4, "- %s", matches[i]); + mvprintw(ui_row(12 + (int)i), 4, "- %s", matches[i]); } } +static void load_services_if_needed(app_state_t* app) { + const char* path; + if (!app || app->service_count > 0) return; + + path = getenv("NOSTR_TUI_SERVICES_CONF"); + if (!path || path[0] == '\0') { + path = "/etc/n-os-tr/services.conf"; + } + + if (services_conf_load(path, app->services, N_OS_TR_TUI_MAX_SERVICES, &app->service_count) != N_OS_TR_TUI_OK) { + (void)services_conf_load_fallback(app->services, N_OS_TR_TUI_MAX_SERVICES, &app->service_count); + } +} + +static void refresh_service_states(app_state_t* app, int* active_states) { + size_t i; + int active = 0; + + for (i = 0; i < app->service_count; ++i) { + if (systemd_unit_is_active(app->services[i].unit, &active) != N_OS_TR_TUI_OK) { + active = 0; + } + active_states[i] = active; + } +} + +static void apply_dependency_rules(app_state_t* app, size_t idx) { + size_t i; + if (!app || idx >= app->service_count) return; + + if (strcmp(app->services[idx].deps, "-") == 0 || app->services[idx].deps[0] == '\0') { + return; + } + + if (!app->services[idx].desired_on) return; + + for (i = 0; i < app->service_count; ++i) { + if (strcmp(app->services[i].unit, app->services[idx].deps) == 0) { + app->services[i].desired_on = 1; + } + } +} + +static int apply_services(app_state_t* app) { + int y = ui_row(9); + size_t i; + int active_states[N_OS_TR_TUI_MAX_SERVICES]; + char err[256] = {0}; + int had_error = 0; + + refresh_service_states(app, active_states); + + mvprintw(ui_row(7), 2, "Applying selection..."); + for (i = 0; i < app->service_count; ++i) { + int rc; + const char* action = NULL; + + if (app->services[i].desired_on && !active_states[i]) { + action = "START"; + rc = systemd_unit_start(app->services[i].unit, err, sizeof(err)); + } else if (!app->services[i].desired_on && active_states[i]) { + action = "STOP "; + rc = systemd_unit_stop(app->services[i].unit, err, sizeof(err)); + } else { + action = "SKIP "; + rc = N_OS_TR_TUI_OK; + } + + if (rc == N_OS_TR_TUI_OK) { + mvprintw(y++, 4, "[ OK ] %s %s", action, app->services[i].unit); + } else { + mvprintw(y++, 4, "[FAIL] %s %s", action, app->services[i].unit); + mvprintw(y++, 6, "%s", err[0] ? err : "systemctl error"); + had_error = 1; + } + + if (y >= LINES - 4) break; + } + + if (had_error) { + mvprintw(LINES - 4, 2, "One or more unit operations failed."); + return N_OS_TR_TUI_ERR; + } + + mvprintw(LINES - 4, 2, "Service selection applied."); + return N_OS_TR_TUI_OK; +} + +static void render_menu_static(void) { + draw_centered_header("n_OS_tr"); + + move(ui_row(4), 2); + attron(A_UNDERLINE); + addch('E'); + attroff(A_UNDERLINE); + addstr("nter existing mnemonic"); + + move(ui_row(5), 2); + attron(A_UNDERLINE); + addch('G'); + attroff(A_UNDERLINE); + addstr("enerate new mnemonic"); + + move(ui_row(6), 2); + addch('E'); + attron(A_UNDERLINE); + addch('x'); + attroff(A_UNDERLINE); + addstr("it"); + + mvprintw(ui_row(8), 2, "Select action: > "); +} + static screen_t screen_menu(void) { int ch; - clear_and_title("Main Menu"); - mvprintw(4, 2, "1) Enter existing mnemonic"); - mvprintw(5, 2, "2) Generate new mnemonic"); - mvprintw(6, 2, "q) Quit"); - mvprintw(8, 2, "Select option: "); + int last_cols = COLS; + int last_lines = LINES; + + render_menu_static(); + render_banner_frame(); refresh(); - ch = getch(); - if (ch == '1') return SCREEN_ENTER; - if (ch == '2') return SCREEN_GENERATE; - if (ch == 'q' || ch == 'Q') return SCREEN_EXIT; - return SCREEN_MENU; + timeout(60); + while (1) { + ch = getch(); + if (ch == ERR) { + if (COLS != last_cols || LINES != last_lines) { + last_cols = COLS; + last_lines = LINES; + render_menu_static(); + } + render_banner_frame(); + refresh(); + continue; + } + + if (ch == KEY_RESIZE) { + last_cols = COLS; + last_lines = LINES; + render_menu_static(); + render_banner_frame(); + refresh(); + continue; + } + + ch = tolower(ch); + if (ch == 'e') { + timeout(-1); + return SCREEN_ENTER; + } + if (ch == 'g') { + timeout(-1); + return SCREEN_GENERATE; + } + if (ch == 'x' || ch == 'q') { + timeout(-1); + return SCREEN_EXIT; + } + } } -static screen_t screen_enter(void) { +static screen_t screen_enter(app_state_t* app) { char line[NOSTR_TUI_MAX_MNEMONIC] = {0}; - char npub[NOSTR_TUI_MAX_NPUB] = {0}; nostr_secure_buf_t secure = {0}; int rc; - clear_and_title("Enter mnemonic"); - mvprintw(4, 2, "Paste your 12/15/18/21/24-word mnemonic and press Enter."); - mvprintw(5, 2, "Mnemonic: "); + draw_centered_header("Enter Mnemonic"); + mvprintw(ui_row(3), 2, "Paste your 12/15/18/21/24-word mnemonic and press Enter."); + mvprintw(ui_row(5), 2, "Mnemonic: "); refresh(); rc = nostr_secure_buf_init(&secure, NOSTR_TUI_MAX_MNEMONIC); if (rc != NOSTR_SUCCESS) { - mvprintw(7, 2, "secure memory init failed: %d", rc); + mvprintw(ui_row(7), 2, "secure memory init failed: %d", rc); wait_key(); return SCREEN_MENU; } - rc = read_line_at(5, 12, line, sizeof(line)); + rc = read_line_at(ui_row(5), 12, line, sizeof(line)); if (rc != NOSTR_SUCCESS) { - mvprintw(7, 2, "input error"); + mvprintw(ui_row(7), 2, "input error"); nostr_secure_buf_destroy(&secure); wait_key(); return SCREEN_MENU; @@ -141,98 +443,261 @@ static screen_t screen_enter(void) { rc = nostr_secure_buf_append(&secure, line, strlen(line)); if (rc != NOSTR_SUCCESS) { - mvprintw(7, 2, "secure buffer append failed: %d", rc); + mvprintw(ui_row(7), 2, "secure buffer append failed: %d", rc); nostr_secure_buf_destroy(&secure); wait_key(); return SCREEN_MENU; } if (nostr_bip39_mnemonic_validate((const char*)secure.bytes) != NOSTR_SUCCESS) { - mvprintw(7, 2, "Invalid mnemonic."); char first_word[32] = {0}; size_t i = 0; + mvprintw(ui_row(7), 2, "Invalid mnemonic."); + while (i < sizeof(first_word) - 1 && line[i] && !isspace((unsigned char)line[i])) { first_word[i] = line[i]; i++; } first_word[i] = '\0'; + render_prefix_hint(first_word); nostr_secure_buf_destroy(&secure); wait_key(); return SCREEN_MENU; } - rc = derive_from_mnemonic((const char*)secure.bytes, npub, sizeof(npub)); - if (rc != NOSTR_SUCCESS) { - mvprintw(7, 2, "Key derivation failed: %d", rc); - nostr_secure_buf_destroy(&secure); - wait_key(); - return SCREEN_MENU; - } - - mvprintw(7, 2, "Mnemonic accepted."); - mvprintw(8, 2, "Derived main npub:"); - mvprintw(9, 2, "%s", npub); - + rc = derive_from_mnemonic((const char*)secure.bytes, app->main_npub, sizeof(app->main_npub)); nostr_secure_buf_destroy(&secure); memset(line, 0, sizeof(line)); - wait_key(); - return SCREEN_MENU; + if (rc != NOSTR_SUCCESS) { + mvprintw(ui_row(7), 2, "Key derivation failed: %d", rc); + wait_key(); + return SCREEN_MENU; + } + + app->identity_loaded = 1; + return SCREEN_SERVICES; } -static screen_t screen_generate(void) { +static screen_t screen_generate(app_state_t* app) { char mnemonic[NOSTR_TUI_MAX_MNEMONIC] = {0}; - char npub[NOSTR_TUI_MAX_NPUB] = {0}; + char main_nsec[NOSTR_TUI_MAX_NPUB] = {0}; unsigned char priv[32] = {0}; unsigned char pub[32] = {0}; - uint8_t picks[NOSTR_BIP39_CONFIRM_PICK_COUNT] = {0}; int rc; - clear_and_title("Generate mnemonic"); + draw_centered_header("Generate Mnemonic"); rc = nostr_generate_mnemonic_and_keys(mnemonic, sizeof(mnemonic), 0, priv, pub); if (rc != NOSTR_SUCCESS) { - mvprintw(4, 2, "Generation failed: %d", rc); + mvprintw(ui_row(4), 2, "Generation failed: %d", rc); wait_key(); return SCREEN_MENU; } - rc = nostr_key_to_bech32(pub, "npub", npub); + rc = nostr_key_to_bech32(pub, "npub", app->main_npub); if (rc != NOSTR_SUCCESS) { - mvprintw(4, 2, "npub conversion failed: %d", rc); + mvprintw(ui_row(4), 2, "npub conversion failed: %d", rc); memset(priv, 0, sizeof(priv)); memset(pub, 0, sizeof(pub)); wait_key(); return SCREEN_MENU; } - rc = nostr_bip39_ui_random_confirm_positions(12, picks); + rc = nostr_key_to_bech32(priv, "nsec", main_nsec); if (rc != NOSTR_SUCCESS) { - mvprintw(4, 2, "confirm-position generation failed: %d", rc); + mvprintw(ui_row(4), 2, "nsec conversion failed: %d", rc); memset(priv, 0, sizeof(priv)); memset(pub, 0, sizeof(pub)); wait_key(); return SCREEN_MENU; } - mvprintw(4, 2, "Write this mnemonic down now:"); - mvprintw(6, 2, "%s", mnemonic); - mvprintw(8, 2, "Derived main npub:"); - mvprintw(9, 2, "%s", npub); - mvprintw(11, 2, "Confirmation check words: #%u, #%u, #%u", - (unsigned)picks[0], (unsigned)picks[1], (unsigned)picks[2]); + mvprintw(ui_row(4), 2, "Write this mnemonic down now:"); + mvprintw(ui_row(5), 2, "Mnemonic (index 0):"); + mvprintw(ui_row(6), 2, "%s", mnemonic); + mvprintw(ui_row(8), 2, "Derived keys (mnemonic index 0):"); + mvprintw(ui_row(9), 2, "npub: %s", app->main_npub); + mvprintw(ui_row(10), 2, "nsec: %s", main_nsec); memset(priv, 0, sizeof(priv)); memset(pub, 0, sizeof(pub)); memset(mnemonic, 0, sizeof(mnemonic)); + app->identity_loaded = 1; wait_key(); - return SCREEN_MENU; + return SCREEN_SERVICES; +} + +static void render_underlined_hotkey_service_row(int y, + const service_entry_t* svc, + int active_state) { + int x = 3; + const char* label; + const char* key_pos; + size_t prefix_len; + + if (!svc) return; + + label = svc->label; + key_pos = strchr(label, (int)tolower((unsigned char)svc->key)); + + if (!key_pos) { + key_pos = strchr(label, (int)toupper((unsigned char)svc->key)); + } + + if (!key_pos) { + mvprintw(y, x, "%-16s [ %s ] [ %s ] %s", + label, + svc->desired_on ? "on " : "off", + active_state ? "on " : "off", + svc->unit); + return; + } + + prefix_len = (size_t)(key_pos - label); + + move(y, x); + addnstr(label, (int)prefix_len); + x += (int)prefix_len; + + move(y, x); + attron(A_UNDERLINE); + addch(*key_pos); + attroff(A_UNDERLINE); + x += 1; + + move(y, x); + addstr(key_pos + 1); + + mvprintw(y, 22, "[ %s ] [ %s ] %s", + svc->desired_on ? "on " : "off", + active_state ? "on " : "off", + svc->unit); +} + +static void render_services_table(app_state_t* app, const int* active_states) { + size_t i; + int y = ui_row(6); + + mvprintw(ui_row(4), 2, "Service Desired Active Unit"); + mvprintw(ui_row(5), 2, "----------------- ------- ------ ------------------------------"); + + for (i = 0; i < app->service_count && y < LINES - 8; ++i) { + render_underlined_hotkey_service_row(y++, &app->services[i], active_states[i]); + } +} + +static screen_t screen_services(app_state_t* app) { + int ch; + int active_states[N_OS_TR_TUI_MAX_SERVICES] = {0}; + size_t i; + int needs_redraw = 1; + int last_cols = COLS; + int last_lines = LINES; + + if (!app || !app->identity_loaded) { + return SCREEN_MENU; + } + + load_services_if_needed(app); + for (i = 0; i < app->service_count; ++i) { + app->services[i].desired_on = app->services[i].default_on; + } + + timeout(60); + while (1) { + if (needs_redraw) { + draw_centered_header("Services"); + refresh_service_states(app, active_states); + + mvprintw(ui_row(2), 2, "Identity: %.22s...", app->main_npub[0] ? app->main_npub : "(unknown)"); + mvprintw(ui_row(3), 2, "Simulation mode: %s", systemd_is_simulation_mode() ? "ON" : "OFF"); + + render_services_table(app, active_states); + + mvprintw(LINES - 6, 2, "Actions:"); + mvprintw(LINES - 5, 2, " R/G/F/N/L/W/S/T toggle | A all on | Z all off"); + mvprintw(LINES - 4, 2, " C commit/apply | X skip (leave unchanged) | Q quit"); + mvprintw(LINES - 2, 2, "Select action: > "); + render_banner_frame(); + refresh(); + needs_redraw = 0; + } + + ch = getch(); + if (ch == ERR) { + if (COLS != last_cols || LINES != last_lines) { + last_cols = COLS; + last_lines = LINES; + needs_redraw = 1; + } + render_banner_frame(); + refresh(); + continue; + } + + if (ch == KEY_RESIZE) { + last_cols = COLS; + last_lines = LINES; + needs_redraw = 1; + continue; + } + + ch = tolower(ch); + if (ch == 'q') { + timeout(-1); + return SCREEN_EXIT; + } + + if (ch == 'x') { + timeout(-1); + return SCREEN_EXIT; + } + + if (ch == 'a') { + for (i = 0; i < app->service_count; ++i) app->services[i].desired_on = 1; + needs_redraw = 1; + continue; + } + + if (ch == 'z') { + for (i = 0; i < app->service_count; ++i) app->services[i].desired_on = 0; + needs_redraw = 1; + continue; + } + + if (ch == 'c') { + draw_centered_header("Applying Services"); + render_banner_frame(); + mvprintw(ui_row(2), 2, "Committing selected service states..."); + if (apply_services(app) != N_OS_TR_TUI_OK) { + wait_key(); + needs_redraw = 1; + continue; + } + wait_key(); + timeout(-1); + return SCREEN_EXIT; + } + + for (i = 0; i < app->service_count; ++i) { + if (ch == tolower((unsigned char)app->services[i].key)) { + app->services[i].desired_on = !app->services[i].desired_on; + apply_dependency_rules(app, i); + needs_redraw = 1; + break; + } + } + } } int main(void) { screen_t screen = SCREEN_MENU; + app_state_t app; + + memset(&app, 0, sizeof(app)); if (nostr_init() != NOSTR_SUCCESS) { fprintf(stderr, "nostr_init failed\n"); @@ -254,10 +719,13 @@ int main(void) { screen = screen_menu(); break; case SCREEN_ENTER: - screen = screen_enter(); + screen = screen_enter(&app); break; case SCREEN_GENERATE: - screen = screen_generate(); + screen = screen_generate(&app); + break; + case SCREEN_SERVICES: + screen = screen_services(&app); break; case SCREEN_EXIT: default: diff --git a/stack/nostr-id-tui/src/services_conf.c b/stack/nostr-id-tui/src/services_conf.c new file mode 100644 index 00000000..8060c7fa --- /dev/null +++ b/stack/nostr-id-tui/src/services_conf.c @@ -0,0 +1,131 @@ +#include +#include +#include +#include + +#include "n_os_tr_tui.h" + +static void copy_str(char* dst, size_t dst_len, const char* src) { + if (!dst || dst_len == 0) return; + if (!src) { + dst[0] = '\0'; + return; + } + snprintf(dst, dst_len, "%s", src); +} + +static void trim(char* s) { + size_t len; + if (!s) return; + + while (*s && isspace((unsigned char)*s)) { + memmove(s, s + 1, strlen(s)); + } + + len = strlen(s); + while (len > 0 && isspace((unsigned char)s[len - 1])) { + s[len - 1] = '\0'; + len--; + } +} + +static int parse_default(const char* v) { + if (!v) return 0; + if (strcmp(v, "on") == 0 || strcmp(v, "1") == 0 || strcmp(v, "true") == 0) return 1; + return 0; +} + +static void set_entry(service_entry_t* e, + char key, + const char* unit, + const char* label, + int default_on, + const char* deps) { + if (!e) return; + memset(e, 0, sizeof(*e)); + e->key = key; + copy_str(e->unit, sizeof(e->unit), unit); + copy_str(e->label, sizeof(e->label), label); + e->default_on = default_on; + copy_str(e->deps, sizeof(e->deps), deps ? deps : "-"); + e->desired_on = default_on; +} + +int services_conf_load_fallback(service_entry_t* out, size_t max, size_t* out_count) { + size_t i = 0; + if (!out || !out_count || max < 8) return N_OS_TR_TUI_ERR; + + set_entry(&out[i++], 'r', "c-relay.service", "c-relay", 0, "nginx.service"); + set_entry(&out[i++], 'g', "ginxsom.service", "ginxsom", 0, "nginx.service"); + set_entry(&out[i++], 'f', "fips.service", "fips", 0, "-"); + set_entry(&out[i++], 'n', "nginx.service", "nginx", 0, "-"); + set_entry(&out[i++], 'l', "nostr-config-loader.service", "config-loader", 0, "-"); + set_entry(&out[i++], 'w', "nostr-config-writer.service", "config-writer", 0, "nostr-config-loader.service"); + set_entry(&out[i++], 's', "ssh.service", "ssh", 0, "-"); + set_entry(&out[i++], 't', "tor.service", "tor", 0, "-"); + + *out_count = i; + return N_OS_TR_TUI_OK; +} + +int services_conf_load(const char* path, service_entry_t* out, size_t max, size_t* out_count) { + FILE* fp; + char line[512]; + size_t n = 0; + + if (!path || !out || !out_count || max == 0) return N_OS_TR_TUI_ERR; + + fp = fopen(path, "r"); + if (!fp) return N_OS_TR_TUI_ERR; + + while (fgets(line, sizeof(line), fp) != NULL) { + char* tok; + char local[512]; + char* key_s; + char* unit_s; + char* label_s; + char* def_s; + char* deps_s; + char key; + + copy_str(local, sizeof(local), line); + trim(local); + if (local[0] == '\0' || local[0] == '#') continue; + + tok = strtok(local, "\t "); + if (!tok) continue; + key_s = tok; + + tok = strtok(NULL, "\t "); + if (!tok) continue; + unit_s = tok; + + tok = strtok(NULL, "\t "); + if (!tok) continue; + label_s = tok; + + tok = strtok(NULL, "\t "); + if (!tok) continue; + def_s = tok; + + tok = strtok(NULL, "\t "); + deps_s = tok ? tok : "-"; + + key = (char)tolower((unsigned char)key_s[0]); + if (!isprint((unsigned char)key)) continue; + + if (n >= max) { + fclose(fp); + return N_OS_TR_TUI_ERR; + } + + set_entry(&out[n], key, unit_s, label_s, parse_default(def_s), deps_s); + n++; + } + + fclose(fp); + + if (n == 0) return N_OS_TR_TUI_ERR; + *out_count = n; + return N_OS_TR_TUI_OK; +} diff --git a/stack/nostr-id-tui/src/systemd_client.c b/stack/nostr-id-tui/src/systemd_client.c new file mode 100644 index 00000000..f9e18edc --- /dev/null +++ b/stack/nostr-id-tui/src/systemd_client.c @@ -0,0 +1,100 @@ +#include +#include +#include +#include +#include +#include + +#include "n_os_tr_tui.h" + +static int run_systemctl(char* const argv[]) { + pid_t pid; + int status = 0; + + if (systemd_is_simulation_mode()) { + return 0; + } + + if (access("/bin/systemctl", X_OK) != 0) { + return -1; + } + + pid = fork(); + if (pid < 0) { + return -1; + } + + if (pid == 0) { + execv("/bin/systemctl", argv); + _exit(127); + } + + if (waitpid(pid, &status, 0) < 0) { + return -1; + } + + if (WIFEXITED(status)) { + return WEXITSTATUS(status); + } + + return -1; +} + +int systemd_is_simulation_mode(void) { + const char* v = getenv("NOSTR_TUI_SIMULATE_SYSTEMCTL"); + return (v && strcmp(v, "1") == 0) ? 1 : 0; +} + +int systemd_unit_is_active(const char* unit, int* is_active) { + char* const argv[] = { + "/bin/systemctl", "is-active", "--quiet", (char*)unit, NULL + }; + int rc; + + if (!unit || !is_active) return N_OS_TR_TUI_ERR; + + if (systemd_is_simulation_mode()) { + *is_active = 0; + return N_OS_TR_TUI_OK; + } + + rc = run_systemctl(argv); + if (rc < 0) return N_OS_TR_TUI_ERR; + + *is_active = (rc == 0) ? 1 : 0; + return N_OS_TR_TUI_OK; +} + +int systemd_unit_start(const char* unit, char* err_out, size_t err_out_len) { + char* const argv[] = { + "/bin/systemctl", "start", (char*)unit, NULL + }; + int rc; + + if (!unit) return N_OS_TR_TUI_ERR; + + rc = run_systemctl(argv); + if (rc == 0) return N_OS_TR_TUI_OK; + + if (err_out && err_out_len > 0) { + snprintf(err_out, err_out_len, "systemctl start failed for %s (rc=%d, errno=%d)", unit, rc, errno); + } + return N_OS_TR_TUI_ERR; +} + +int systemd_unit_stop(const char* unit, char* err_out, size_t err_out_len) { + char* const argv[] = { + "/bin/systemctl", "stop", (char*)unit, NULL + }; + int rc; + + if (!unit) return N_OS_TR_TUI_ERR; + + rc = run_systemctl(argv); + if (rc == 0) return N_OS_TR_TUI_OK; + + if (err_out && err_out_len > 0) { + snprintf(err_out, err_out_len, "systemctl stop failed for %s (rc=%d, errno=%d)", unit, rc, errno); + } + return N_OS_TR_TUI_ERR; +} diff --git a/stack/nostr-id-tui/tests/test_services_sim.sh b/stack/nostr-id-tui/tests/test_services_sim.sh new file mode 100755 index 00000000..d397710e --- /dev/null +++ b/stack/nostr-id-tui/tests/test_services_sim.sh @@ -0,0 +1,35 @@ +#!/usr/bin/env bash +set -euo pipefail + +ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd)" +BIN="$ROOT_DIR/stack/nostr-id-tui/build-host/nostr-id-tui" +SERVICES_CONF="$ROOT_DIR/iso/config/includes.chroot/etc/n-os-tr/services.conf" + +if [[ ! -x "$BIN" ]]; then + echo "error: missing binary $BIN" + echo "build first: cmake -S stack/nostr-id-tui -B stack/nostr-id-tui/build-host && cmake --build stack/nostr-id-tui/build-host -j" + exit 1 +fi + +if [[ ! -f "$SERVICES_CONF" ]]; then + echo "error: missing services config $SERVICES_CONF" + exit 1 +fi + +OUT="$ROOT_DIR/stack/nostr-id-tui/build-host/test-services-sim.out" + +# Simulated run (no real systemctl operations). We just verify the TUI launches and renders. +timeout 2s env TERM=xterm-256color \ + NOSTR_TUI_SIMULATE_SYSTEMCTL=1 \ + NOSTR_TUI_SERVICES_CONF="$SERVICES_CONF" \ + script -q -c "$BIN" /dev/null > "$OUT" 2>&1 || true + +if grep -q "n-OS-tr Identity" "$OUT"; then + echo "ok: TUI launched and rendered header" +else + echo "error: expected TUI header not found in output" + echo "see $OUT" + exit 1 +fi + +echo "ok: simulated services smoke test passed"