diff --git a/src/main.rs b/src/main.rs index 55c3312..f67560b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -47,6 +47,7 @@ use crate::package::{PackageManager, InstallResult, UpdateResult, RemoveResult, use std::sync::atomic::AtomicBool; use crate::package::git::GitPackageResolver; use crate::package::zip::ZipPackageResolver; +use crate::sysdaemon::{verify, VerifyResult}; mod ui; mod edit; @@ -452,25 +453,33 @@ fn start_daemon(config_set: ConfigSet) { if config_set.default.use_system_agent && !force_unmanaged { // Make sure espanso is currently registered in systemd - let res = Command::new("systemctl") - .args(&["--user", "is-enabled", "espanso.service"]) - .output(); - if !res.unwrap().status.success() { - use dialoguer::Confirmation; - if Confirmation::new() - .with_text("espanso must be registered to systemd (user level) first. Do you want to proceed?") - .default(true) - .show_default(true) - .interact().expect("Unable to read user answer") { - + let res = verify(); + match res { + VerifyResult::EnabledAndValid => { + // Do nothing, everything is ok! + }, + VerifyResult::EnabledButInvalidPath => { + eprintln!("Updating espanso service file with new path..."); + unregister_main(config_set.clone()); register_main(config_set); - }else{ - eprintln!("Please register espanso to systemd with this command:"); - eprintln!(" espanso register"); - // TODO: enable flag to use non-managed daemon mode + }, + VerifyResult::NotEnabled => { + use dialoguer::Confirmation; + if Confirmation::new() + .with_text("espanso must be registered to systemd (user level) first. Do you want to proceed?") + .default(true) + .show_default(true) + .interact().expect("Unable to read user answer") { - std::process::exit(4); - } + register_main(config_set); + }else{ + eprintln!("Please register espanso to systemd with this command:"); + eprintln!(" espanso register"); + // TODO: enable flag to use non-managed daemon mode + + std::process::exit(4); + } + }, } // Start the espanso service diff --git a/src/sysdaemon.rs b/src/sysdaemon.rs index b13e0dc..4bbf06c 100644 --- a/src/sysdaemon.rs +++ b/src/sysdaemon.rs @@ -20,6 +20,7 @@ // This functions are used to register/unregister espanso from the system daemon manager. use crate::config::ConfigSet; +use crate::sysdaemon::VerifyResult::{EnabledAndValid, NotEnabled, EnabledButInvalidPath}; // INSTALLATION @@ -181,6 +182,54 @@ pub fn register(config_set: ConfigSet) { } } +pub enum VerifyResult { + EnabledAndValid, + EnabledButInvalidPath, + NotEnabled, +} + +#[cfg(target_os = "linux")] +pub fn verify() -> VerifyResult { + use regex::Regex; + use std::process::{Command, ExitStatus}; + + // Check if espanso service is already registered + let res = Command::new("systemctl") + .args(&["--user", "is-enabled", "espanso"]) + .output(); + if let Ok(res) = res { + let output = String::from_utf8_lossy(res.stdout.as_slice()); + let output = output.trim(); + if !res.status.success() || output != "enabled" { + return NotEnabled + } + } + + lazy_static! { + static ref ExecPathRegex: Regex = Regex::new("ExecStart=(?P.*?)\\s").unwrap(); + } + + // Check if the currently registered path is valid + let res = Command::new("systemctl") + .args(&["--user", "cat", "espanso"]) + .output(); + if let Ok(res) = res { + let output = String::from_utf8_lossy(res.stdout.as_slice()); + let output = output.trim(); + if res.status.success() { + let caps = ExecPathRegex.captures(output).unwrap(); + let path = caps.get(1).map_or("", |m| m.as_str()); + let espanso_path = std::env::current_exe().expect("Could not get espanso executable path"); + + if espanso_path.to_string_lossy() != path { + return EnabledButInvalidPath + } + } + } + + EnabledAndValid +} + #[cfg(target_os = "linux")] pub fn unregister(config_set: ConfigSet) { use std::process::{Command, ExitStatus};