use super::Installer;
use std::path::PathBuf;
use std::process::ExitCode;
use anyhow::{ensure, Result};
use clap::Parser;
const LAUNCH_PATH: &str = "/Library/LaunchDaemons/malwaredb.plist";
#[derive(Parser, Debug, Clone, PartialEq)]
pub struct Install {
#[arg(value_hint = clap::ValueHint::FilePath)]
pub config: Option<PathBuf>,
}
impl Install {
pub(crate) fn gen_config(&self) -> Result<String> {
let exec = std::env::current_exe().unwrap();
let exec = exec.to_str().unwrap();
let optional_config = if let Some(config) = &self.config {
let config = config.to_str().unwrap();
ensure!(
config.starts_with('/'),
"Must use an absolute path for the config file"
);
format!(
"
<string>load</string>
<string>{config}</string>
"
)
} else {
String::new()
};
Ok(format!(
"<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\"
\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">
<plist version='1.0'>
<dict>
<key>EnvironmentVariables</key>
<dict>
<key>SERVICE_RUN_MODE</key>
<string>1</string>
</dict>
<key>Label</key>
<string>MalwareDB</string>
<key>ProgramArguments</key>
<array>
<string>{exec}</string>
<string>run</string>{optional_config}
</array>
<key>KeepAlive</key>
<true/>
<key>RunAtLoad</key>
<true/>
<key>Disabled</key>
<false/>
</dict>
</plist>
",
))
}
}
impl Installer for Install {
fn do_install(&self) -> Result<ExitCode> {
let config = self.gen_config()?;
std::fs::write(LAUNCH_PATH, config)?;
Ok(ExitCode::SUCCESS)
}
}