From e7ec3d4ef7e5cdd3338eaa84f328b64c05dc7156 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Sat, 21 Nov 2020 18:32:47 +0000 Subject: [PATCH] thunkify and move local directory finding Signed-off-by: Ian Jackson --- src/bin/daemon-otter.rs | 2 +- src/bin/otter.rs | 41 +++------------------------ src/config.rs | 63 +++++++++++++++++++++++++++++++++++++++-- 3 files changed, 65 insertions(+), 41 deletions(-) diff --git a/src/bin/daemon-otter.rs b/src/bin/daemon-otter.rs index 76104cc8..95e2fa8c 100644 --- a/src/bin/daemon-otter.rs +++ b/src/bin/daemon-otter.rs @@ -106,7 +106,7 @@ fn main() { // todo test suite for web api let config_filename = env::args().nth(1); - ServerConfig::read(config_filename.as_ref().map(String::as_str))?; + ServerConfig::read(config_filename.as_ref().map(String::as_str), true)?; std::env::set_var("ROCKET_CLI_COLORS","off"); diff --git a/src/bin/otter.rs b/src/bin/otter.rs index 3dfb8162..672639c2 100644 --- a/src/bin/otter.rs +++ b/src/bin/otter.rs @@ -58,15 +58,6 @@ impl<'x, T, F: FnMut(&str) -> Result> } } -mod exits { - #![allow(dead_code)] - pub const EXIT_SPACE : i32 = 2; - pub const EXIT_SITUATION : i32 = 8; - pub const EXIT_USAGE : i32 = 12; - pub const EXIT_DISASTER : i32 = 16; -} -use exits::*; - #[derive(Debug)] struct MainOpts { account: AccountName, @@ -272,35 +263,11 @@ fn main() { subaccount: "".into(), }) })?; - let config_filename = config_filename.or_else(||{ - match match env::current_exe() - .map(|p| p.to_str().map(|s| s.to_string())) - { - Err(e) => Err(format!( - "could not find current executable ({})", &e - )), - Ok(None) => Err(format!( - "current executable has non-UTF8 filename!" - )), - Ok(Some(basedir)) if basedir.rsplit('/').nth(1) == Some("bin") => Ok( - format!("{}/etc/{}", basedir, DEFAULT_CONFIG_FILENAME) - ), - Ok(_) => Err(format!( - "current executable is not in a directory called bin" - )), - } { - Err(whynot) => { - if verbose > 1 { - eprintln!("{}: looking for {} in current directory", - &whynot, DEFAULT_CONFIG_FILENAME); - } - None - }, - Ok(f) => Some(f), - } - }); let config = Thunk::new(||{ - ServerConfig::read(config_filename.as_ref().map(String::as_str)) + ServerConfig::read( + config_filename.as_ref().map(String::as_str), + verbose > 1 + ) .context("read config file")?; Ok::<_,AE>(otter::config::config()) }); diff --git a/src/config.rs b/src/config.rs index 7498dfa9..eece6441 100644 --- a/src/config.rs +++ b/src/config.rs @@ -4,6 +4,11 @@ use crate::imports::*; +pub const EXIT_SPACE : i32 = 2; +pub const EXIT_SITUATION : i32 = 8; +pub const EXIT_USAGE : i32 = 12; +pub const EXIT_DISASTER : i32 = 16; + pub const DEFAULT_CONFIG_FILENAME : &str = "server.toml"; const DEFAULT_SAVE_DIRECTORY : &str = "save"; @@ -109,11 +114,63 @@ fn set_config(config: ServerConfig) { *GLOBAL.config.write().unwrap() = Arc::new(config) } +fn default_basedir_from_executable(verbose: bool) -> Option { + #[throws(StartupError)] + fn inner(verbose: bool) -> Option { + match match env::current_exe() + .map(|p| p.to_str().map(|s| s.to_string())) + { + Err(e) => Err(format!( + "could not find current executable ({})", &e + )), + Ok(None) => Err(format!( + "current executable has non-UTF8 filename!" + )), + Ok(Some(basedir)) if basedir.rsplit('/').nth(1) == Some("bin") => Ok( + format!("{}/", basedir) + ), + Ok(_) => Err(format!( + "current executable is not in a directory called bin" + )), + } { + Err(whynot) => { + if verbose { + eprintln!("{}: looking for ancillary files in current directory", + &whynot); + } + None + }, + Ok(f) => Some(f), + } + } + + inner(verbose).unwrap_or_else(|e|{ + eprintln!("startup error finding installation pieces: {}", &e); + exit(EXIT_DISASTER) + }) +} + +fn in_basedir Option> + (basedir: &mut Thunk,F>, + subdir: &str, + localdir: &str, + leaf: &str) -> String +{ + match basedir.as_ref() { + Some(basedir) => format!("{}/{}/{}", basedir, subdir, leaf), + None => format!( "{}/{}", localdir, leaf), + } +} + impl ServerConfig { #[throws(StartupError)] - pub fn read(config_filename: Option<&str>) { - let config_filename = config_filename - .unwrap_or_else(|| DEFAULT_CONFIG_FILENAME); + pub fn read(config_filename: Option<&str>, verbose: bool) { + let mut basedir = Thunk::new( + move || default_basedir_from_executable(verbose) + ); + let config_filename = config_filename.map(|s| s.to_string()).unwrap_or_else( + || in_basedir(&mut basedir, "etc", "", DEFAULT_CONFIG_FILENAME) + ); let mut buf = String::new(); File::open(&config_filename).with_context(||config_filename.to_string())? .read_to_string(&mut buf)?; -- 2.30.2