diff --git a/src/config.rs b/src/config.rs index 761068e..fa603c8 100644 --- a/src/config.rs +++ b/src/config.rs @@ -93,7 +93,12 @@ impl TryFrom for Config { bc.auth.insert(s); } Element::Fork => bc.fork = true, - Element::Include(_) => { /* no-op */ } + Element::Include(_) => { + // NO-OP: removed during `Document::resolve_includes` + } + Element::Includedir(_) => { + // NO-OP: removed during `Document::resolve_includedirs` + } Element::KeepUmask => bc.keep_umask = true, Element::Limit => { warn!("warning: busd does not implement ``"); diff --git a/src/config/xml.rs b/src/config/xml.rs index 10c0d67..908b3d4 100644 --- a/src/config/xml.rs +++ b/src/config/xml.rs @@ -1,6 +1,7 @@ use std::{ env::current_dir, - fs::read_to_string, + ffi::OsString, + fs::{read_dir, read_to_string}, path::{Path, PathBuf}, str::FromStr, }; @@ -36,7 +37,47 @@ impl Document { let mut doc = Document::from_str(&text)?; doc.file_path = Some(file_path.as_ref().to_path_buf()); - doc.resolve_includes() + doc.resolve_includedirs()?.resolve_includes() + } + + fn resolve_includedirs(self) -> Result { + let base_path = self.base_path()?; + let Document { + busconfig, + file_path, + } = self; + + let mut doc = Document { + busconfig: vec![], + file_path: None, + }; + + for el in busconfig { + match el { + Element::Includedir(dir_path) => { + let dir_path = match resolve_include_path(&base_path, &dir_path) { + Ok(ok) => ok, + Err(err) => { + error!("'{}' should be a valid file path", dir_path.display()); + return Err(err); + } + }; + for entry in read_dir(dir_path)? { + let path = entry?.path(); + if path.extension() == Some(&OsString::from("conf")) && path.is_file() { + doc.busconfig.push(Element::Include(IncludeElement { + file_path: path, + ..Default::default() + })); + } + } + } + _ => doc.busconfig.push(el), + } + } + + doc.file_path = file_path; + Ok(doc) } fn resolve_includes(self) -> Result { @@ -117,7 +158,7 @@ pub enum Element { Auth(String), Fork, Include(IncludeElement), - // TODO: support `` + Includedir(PathBuf), KeepUmask, Listen(String), Limit, diff --git a/tests/config.rs b/tests/config.rs index 83a283f..1643a56 100644 --- a/tests/config.rs +++ b/tests/config.rs @@ -12,8 +12,11 @@ fn config_read_file_with_includes_ok() { Config { auth: HashSet::from_iter(vec![String::from("ANONYMOUS"), String::from("EXTERNAL"),]), listen: HashSet::from_iter(vec![ + String::from("unix:path=/tmp/a"), // via + String::from("unix:path=/tmp/b"), // via + // should be no "unix:path=/tmp/not_included" as that file ends in .xml String::from("unix:path=/tmp/foo"), - String::from("tcp:host=localhost,port=1234"), + String::from("tcp:host=localhost,port=1234"), // via ]), policies: vec![ Policy::DefaultContext(vec![ @@ -63,3 +66,10 @@ fn config_read_file_with_transitive_missing_include_err() { Config::read_file("./tests/fixtures/transitive_missing_include.conf") .expect("should read and parse XML input"); } + +#[should_panic] +#[test] +fn config_read_file_with_missing_includedir_err() { + Config::read_file("./tests/fixtures/missing_includedir.conf") + .expect("should read and parse XML input"); +} diff --git a/tests/fixtures/includedir/a.conf b/tests/fixtures/includedir/a.conf new file mode 100644 index 0000000..d602268 --- /dev/null +++ b/tests/fixtures/includedir/a.conf @@ -0,0 +1,5 @@ + + + unix:path=/tmp/a + diff --git a/tests/fixtures/includedir/b.conf b/tests/fixtures/includedir/b.conf new file mode 100644 index 0000000..d351cfe --- /dev/null +++ b/tests/fixtures/includedir/b.conf @@ -0,0 +1,5 @@ + + + unix:path=/tmp/b + diff --git a/tests/fixtures/includedir/not_included.xml b/tests/fixtures/includedir/not_included.xml new file mode 100644 index 0000000..5af9363 --- /dev/null +++ b/tests/fixtures/includedir/not_included.xml @@ -0,0 +1,5 @@ + + + unix:path=/tmp/not_included + diff --git a/tests/fixtures/missing_includedir.conf b/tests/fixtures/missing_includedir.conf new file mode 100644 index 0000000..01e2df1 --- /dev/null +++ b/tests/fixtures/missing_includedir.conf @@ -0,0 +1,5 @@ + + + ./missing + diff --git a/tests/fixtures/valid.conf b/tests/fixtures/valid.conf index 7a20a08..f8e2a00 100644 --- a/tests/fixtures/valid.conf +++ b/tests/fixtures/valid.conf @@ -9,4 +9,5 @@ ./valid_included.conf ./valid_missing.conf + ./includedir