mod daemon; #[cfg(target_os = "linux")] mod dbus; use log::LevelFilter; use std::future; use daemon::Daemon; fn initialize_logging() { // Weird: is this the best way to do this? let log_level = std::env::var("RUST_LOG") .map(|s| s.parse::().unwrap_or(LevelFilter::Info)) .unwrap_or(LevelFilter::Info); env_logger::Builder::from_default_env() .format_timestamp_millis() .filter_level(log_level) .init(); } #[cfg(target_os = "linux")] async fn start_ipc_agent(daemon: &mut Daemon) { use dbus::agent::DBusAgent; // Start the D-Bus agent (events in, signals out). let agent = DBusAgent::new(daemon.event_sender.clone(), daemon.obtain_signal_receiver()); tokio::spawn(async move { agent.run().await; }); } #[cfg(target_os = "macos")] async fn start_ipc_agent(daemon: &mut Daemon) { // TODO: Implement macOS IPC agent. } #[cfg(not(any(target_os = "linux", target_os = "macos")))] async fn start_ipc_agent(daemon: &mut Daemon) { panic!("Unsupported IPC platform"); } #[tokio::main] async fn main() { initialize_logging(); // Create the daemon let mut daemon = Daemon::new() .map_err(|e| { log::error!("Failed to initialize daemon: {}", e); std::process::exit(1); }) .unwrap(); // Start the IPC agent. start_ipc_agent(&mut daemon).await; // Run the main daemon loop. daemon.run().await; // Keep the process alive as long as any background tasks are running. future::pending::<()>().await; }