Six crates were still unguarded, and all six are OURS — none vendored: pf-console-ui, pf-gpu, punktfunk-tray, clients/windows, tools/display-disturb, wdk-probe. Two of them ship (the tray and the Windows client), so "small" was about item count, not exposure. Five are closed here. Only 17 of their 75 unsafe items actually lacked a proof — pf-gpu, punktfunk-tray and display-disturb were already fully documented and needed nothing but the deny, which is the good case: the convention was being followed, just not enforced. The 17 that were missing are the usual Win32/COM shapes, and two were worth stating properly. `clients/windows`'s `GetCurrentPackageFullName` is called with `len = 0` and no buffer — that is the documented identity PROBE, which writes nothing, and reading it as a normal query would be a mistake. `pf-console-ui`'s two `destroy_image_view` calls are the load-bearing ones: the comment above one already argued that in-flight sampling of that slot ended two presents ago (the ring alternates and the presenter waits its fence before each record), which is exactly the kind of reasoning a `// SAFETY:` should carry and it was sitting there unlabelled. Also fixes a real Windows-only clippy error this uncovered: `pf-gpu` had a `#[cfg(target_os = "windows")]` fn AFTER its `mod tests`, tripping `items_after_test_module`. It never fired on Linux (the item does not exist there) and no CI job clippies pf-gpu on Windows, so it sat unseen. Moved above the test module. Remaining: `wdk-probe` (26 items) alone, and only because it needs the WDK to build — .47 cannot, so nothing here can verify a deny on it. Verified: Linux .21 fmt + both CI clippy steps rc=0; Windows .47 the four Windows-relevant crates at `-D warnings` rc=0.
100 lines
3.8 KiB
Rust
100 lines
3.8 KiB
Rust
//! punktfunk-tray — a small per-user system-tray companion for the punktfunk host service.
|
|
//!
|
|
//! Shows at a glance whether the host is running / stopped / degraded / failed (no more digging
|
|
//! through logs after a reboot or an update), and offers the common one-click actions: open the
|
|
//! web console, start/stop/restart the service (UAC-elevated per action on Windows,
|
|
//! `systemctl --user` on Linux), review a pending pairing request, exit.
|
|
//!
|
|
//! Status comes from two sources, service manager FIRST (a fake listener on the mgmt port can
|
|
//! never make a stopped service look running): the SCM / systemd user unit for the process state,
|
|
//! then the host's loopback-only unauthenticated `GET /api/v1/local/summary` for the streaming
|
|
//! details. Windows-subsystem binary — a console exe in the HKLM Run key would flash a terminal
|
|
//! window at every sign-in.
|
|
// Unsafe-proof program: every `unsafe {}` in the tray carries a `// SAFETY:` proof.
|
|
#![deny(clippy::undocumented_unsafe_blocks)]
|
|
#![cfg_attr(windows, windows_subsystem = "windows")]
|
|
|
|
#[cfg(target_os = "linux")]
|
|
mod linux;
|
|
#[cfg(any(windows, target_os = "linux"))]
|
|
mod status;
|
|
#[cfg(windows)]
|
|
mod win;
|
|
|
|
/// CLI configuration (hand-rolled parse, house style). The mgmt address/port default to the
|
|
/// host's defaults; they are flags because the tray cannot read `host.env` on Windows (it is
|
|
/// DACL-locked to SYSTEM/Administrators), so an operator who moved `--mgmt-bind` adjusts the
|
|
/// autostart command line instead.
|
|
pub struct Args {
|
|
/// Ask an already-running tray instance to exit (Windows; used by the uninstaller).
|
|
pub quit: bool,
|
|
/// Launched from the desktop autostart entry: exit silently when this box doesn't run a host
|
|
/// (Linux; the package installs the autostart file for every desktop user).
|
|
pub autostart: bool,
|
|
/// Management API address to poll (loopback only; the summary route rejects anything else).
|
|
pub mgmt_addr: String,
|
|
pub mgmt_port: u16,
|
|
/// Web console port for the "Open web console" action.
|
|
pub web_port: u16,
|
|
}
|
|
|
|
impl Default for Args {
|
|
fn default() -> Self {
|
|
Args {
|
|
quit: false,
|
|
autostart: false,
|
|
mgmt_addr: "127.0.0.1".into(),
|
|
mgmt_port: 47990,
|
|
web_port: 47992,
|
|
}
|
|
}
|
|
}
|
|
|
|
fn parse_args() -> anyhow::Result<Args> {
|
|
let mut args = Args::default();
|
|
let mut it = std::env::args().skip(1);
|
|
while let Some(a) = it.next() {
|
|
let mut value = |flag: &str| {
|
|
it.next()
|
|
.ok_or_else(|| anyhow::anyhow!("{flag} needs a value"))
|
|
};
|
|
match a.as_str() {
|
|
"--quit" => args.quit = true,
|
|
"--autostart" => args.autostart = true,
|
|
"--mgmt-addr" => args.mgmt_addr = value("--mgmt-addr")?,
|
|
"--mgmt-port" => args.mgmt_port = value("--mgmt-port")?.parse()?,
|
|
"--web-port" => args.web_port = value("--web-port")?.parse()?,
|
|
"--version" | "-V" => {
|
|
println!("punktfunk-tray {}", env!("CARGO_PKG_VERSION"));
|
|
std::process::exit(0);
|
|
}
|
|
other => anyhow::bail!(
|
|
"unknown argument '{other}'\n\nUSAGE:\n punktfunk-tray [--autostart] [--quit] \
|
|
[--mgmt-addr <IP>] [--mgmt-port <N>] [--web-port <N>]"
|
|
),
|
|
}
|
|
}
|
|
Ok(args)
|
|
}
|
|
|
|
fn main() -> anyhow::Result<()> {
|
|
let args = parse_args()?;
|
|
run(args)
|
|
}
|
|
|
|
#[cfg(windows)]
|
|
fn run(args: Args) -> anyhow::Result<()> {
|
|
win::run(args)
|
|
}
|
|
|
|
#[cfg(target_os = "linux")]
|
|
fn run(args: Args) -> anyhow::Result<()> {
|
|
linux::run(args)
|
|
}
|
|
|
|
#[cfg(not(any(windows, target_os = "linux")))]
|
|
fn run(_args: Args) -> anyhow::Result<()> {
|
|
// Workspace-stub build (macOS CI etc.) — the tray ships on Windows and Linux only.
|
|
anyhow::bail!("punktfunk-tray supports Windows and Linux hosts only")
|
|
}
|