use super::Installer;
use std::path::PathBuf;
use std::process::{Command, ExitCode};
use anyhow::{ensure, Result};
use clap::Parser;
const LAUNCH_PATH: &str = "/usr/local/etc/rc.d/malwaredb";
#[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 exec_opt = 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!("run load {config}")
} else {
"run".to_string()
};
Ok(format!(
"#!/bin/sh
#
# PROVIDE: malwaredb
# REQUIRE: DAEMON netif
# KEYWORD: shutdown
. /etc/rc.subr
name=malwaredb
rcvar=malwaredb_enable
command=\"{exec}\"
command_args=\"{exec_opt}\"
malwaredb_user=\"nobody\"
pidfile=\"/var/run/${{name}}.pid\"
start_cmd=\"malwaredb_start\"
stop_cmd=\"malwaredb_stop\"
status_cmd=\"malwaredb_status\"
malwaredb_start() {{
/usr/sbin/daemon -P ${{pidfile}} -r -f -u ${{malwaredb_user}} ${{command}} ${{command_args}}
}}
malwaredb_stop() {{
if [ -e \"${{pidfile}}\" ]; then
kill -s TERM `cat ${{pidfile}}`
else
echo \"${{name}} is not running\"
fi
}}
malwaredb_status() {{
if [ -e \"${{pidfile}}\" ]; then
echo \"${{name}} is running as pid `cat ${{pidfile}}`\"
else
echo \"${{name}} is not running\"
fi
}}
load_rc_config $name
: ${{malwaredb_enable:=no}}
run_rc_command \"$1\"
"
))
}
}
impl Installer for Install {
fn do_install(&self) -> Result<ExitCode> {
let config = self.gen_config()?;
std::fs::write(LAUNCH_PATH, config)?;
Command::new("chmod")
.arg("+x")
.arg(LAUNCH_PATH)
.output()
.expect("failed to make the config file executable");
Ok(ExitCode::SUCCESS)
}
}