/* * Copyright (c) 2021, Luca Fulchir * * This file is part of dfim. * * dfim is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * dfim is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with dfim. If not, see . */ pub mod device; pub mod errors; pub mod gpt; pub mod include; #[derive(::serde::Deserialize, Copy, Clone)] #[serde(deny_unknown_fields)] pub enum LogTime { UTC, Local, } #[derive(::serde::Deserialize, Copy, Clone)] #[serde(deny_unknown_fields)] pub enum LogFacility { Kern, User, Mail, Daemon, Auth, Syslog, Lpr, News, Uucp, Cron, Authpriv, Ftp, Local0, Local1, Local2, Local3, Local4, Local5, Local6, Local7, } #[derive(::serde::Deserialize, Copy, Clone)] #[serde(deny_unknown_fields)] pub enum LogLevel { Critical, Error, Warning, Info, Debug, Trace, } #[derive(::serde::Deserialize, Copy, Clone)] #[serde(deny_unknown_fields)] pub enum LogTermStream { StdErr, StdOut, } #[derive(::serde::Deserialize, Clone)] #[serde(deny_unknown_fields)] #[serde(rename_all = "lowercase")] pub enum LogSyslog { Socket(::std::path::PathBuf), Udp { from: ::std::net::SocketAddr, to: ::std::net::SocketAddr, hostname_id: String, }, Tcp { to: ::std::net::SocketAddr, hostname_id: String, }, } #[derive(::serde::Deserialize, Clone)] #[serde(rename_all = "lowercase")] #[serde(deny_unknown_fields)] pub enum LogDest { Terminal(Option), Syslog { dest: LogSyslog, facility: LogFacility, level: LogLevel, }, } #[derive(::serde::Deserialize, Clone)] #[serde(deny_unknown_fields)] pub struct Logging { pub level: LogLevel, pub time: LogTime, #[serde(flatten)] pub dest: LogDest, } #[derive(::serde::Deserialize, Clone)] #[serde(deny_unknown_fields)] pub struct MainConfig { pub logging: Logging, pub include: ::std::path::PathBuf, /* Todo: only for notifications pub user: String, pub group: String, */ } pub struct Config { pub main: MainConfig, pub gpts: Vec, pub devices: Vec, } pub fn parse( logger: ::std::sync::Arc<::slog::Logger>, conf_path: &::std::path::Path, ) -> std::result::Result { let main: MainConfig = { // parse file in this block so that the fopen is // closed as soon as possible let conf_device = ::std::fs::File::open(conf_path)?; let mut extensions = ::ron::extensions::Extensions::default(); extensions.insert(::ron::extensions::Extensions::IMPLICIT_SOME); extensions.insert(::ron::extensions::Extensions::UNWRAP_NEWTYPES); // TODO: wait for new RON release //match ::ron::Options::default(). // with_default_extensions(extensions).from_reader(&conf_device) { match ::ron::de::from_reader(&conf_device) { Ok(cfg) => cfg, Err(repr) => { ::slog::error!(logger, "on file: {:?}", &conf_path); ::slog::error!(logger, "{}", repr); return Err(errors::ConfigError::Parsing(repr)); } } }; let mut cfg = Config { main: main, gpts: Vec::new(), devices: Vec::new(), }; // now parse all the included device confs if !cfg.main.include.is_dir() { ::std::eprintln!("Error: include conf directory not found"); return Err(errors::ConfigError::IO(::std::io::Error::new( ::std::io::ErrorKind::NotFound, "include conf directory not found", ))); } let re = ::regex::Regex::new(r"^.*\.ron$").unwrap(); for filename in ::std::fs::read_dir(&cfg.main.include)? { let filename = filename?.path(); if !re.is_match(filename.to_str().unwrap()) { continue; } let mut include = match include::parse_include(logger.clone(), &filename) { Ok(include) => include, Err(e) => { return Err(e); } }; cfg.gpts.append(&mut include.gpts); cfg.devices.append(&mut include.devices); } return Ok(cfg); }