summaryrefslogtreecommitdiff
path: root/src/daemon.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/daemon.rs')
-rw-r--r--src/daemon.rs74
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")
+ }
+}