diff options
Diffstat (limited to 'src/daemon.rs')
| -rw-r--r-- | src/daemon.rs | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/src/daemon.rs b/src/daemon.rs new file mode 100644 index 0000000..f8588ca --- /dev/null +++ b/src/daemon.rs @@ -0,0 +1,74 @@ +use crate::{ + bus::{NAME, PATH, Service}, + controller::Controller, + runtime::Runtime, + subscription::HttpSource, +}; +use anyhow::{Result, ensure}; +use std::{path::Path, sync::Arc, time::Duration}; +use tokio::sync::Mutex; + +pub fn runtime() -> Result<Box<dyn Runtime>> { + #[cfg(feature = "linux-runtime")] + { + Ok(Box::new(crate::linux::LinuxRuntime::default())) + } + #[cfg(not(feature = "linux-runtime"))] + { + anyhow::bail!("This build has no Linux runtime; rebuild with --features linux-runtime") + } +} + +pub async fn run() -> Result<()> { + ensure!( + unsafe { libc::geteuid() } == 0, + "The controller must run as a root-owned system service" + ); + let _lock = crate::locking::controller_lock()?; + let mut controller = Controller::open_paths( + Path::new("/etc/roentgen"), + Path::new("/var/lib/roentgen"), + runtime()?, + Box::new(HttpSource), + )?; + if let Err(error) = controller.restore().await { + controller.report_runtime_error(&error); + } + let controller = Arc::new(Mutex::new(controller)); + let _connection = zbus::connection::Builder::system()? + .name(NAME)? + .serve_at( + PATH, + Service { + controller: controller.clone(), + cancellation: Arc::new(tokio::sync::Notify::new()), + }, + )? + .build() + .await?; + let mut interval = tokio::time::interval(Duration::from_secs(5)); + interval.set_missed_tick_behavior(tokio::time::MissedTickBehavior::Skip); + loop { + tokio::select! { + _ = tokio::signal::ctrl_c() => break, + _ = interval.tick() => { + let mut controller = controller.lock().await; + if let Err(error) = controller.scheduled_check().await { controller.report_runtime_error(&error); tracing::warn!("{error}"); } + } + } + } + // Exiting the controller never releases enabled protection or stops the core. + Ok(()) +} + +pub async fn guard() -> Result<()> { + ensure!(unsafe { libc::geteuid() } == 0, "The guard requires root"); + #[cfg(feature = "linux-runtime")] + { + crate::linux::restore_guard() + } + #[cfg(not(feature = "linux-runtime"))] + { + anyhow::bail!("Rebuild with --features linux-runtime") + } +} |