1use std::fs;
4use std::path::Path;
5
6use crate::constants::{CHROOTS, CRON, KEYS, MAILBOX, SQLITE};
7use crate::error::{Error, Result};
8use crate::scope::validate_chroot_name;
9
10pub fn init_chroot(global_root: &Path, name: &str) -> Result<()> {
11 validate_chroot_name(name)?;
12 let base = global_root.join(CHROOTS).join(name);
13 if base.exists() {
14 return Err(Error::msg(format!("chroot already exists: {name}")));
15 }
16 for sub in [KEYS, MAILBOX, CRON, SQLITE] {
17 fs::create_dir_all(base.join(sub))?;
18 }
19 Ok(())
20}
21
22pub fn list_chroots(global_root: &Path) -> Result<Vec<String>> {
23 let dir = global_root.join(CHROOTS);
24 if !dir.is_dir() {
25 return Ok(Vec::new());
26 }
27 let mut names = Vec::new();
28 for entry in fs::read_dir(&dir)? {
29 let entry = entry?;
30 if entry.file_type()?.is_dir() {
31 names.push(entry.file_name().to_string_lossy().into_owned());
32 }
33 }
34 names.sort();
35 Ok(names)
36}