use crate::services::lifecycle::site::SiteError;
use rustix::fs::{Mode, OFlags, open, openat};
use std::path::{Component, Path};
pub(in super::super) fn open_command(path: &Path) -> Result<std::fs::File, SiteError> {
let flags = OFlags::RDONLY | OFlags::CLOEXEC | OFlags::NOFOLLOW;
let mut directory = open("/", flags | OFlags::DIRECTORY, Mode::empty())
.map_err(|_| SiteError::Invalid("template root descriptor"))?;
let mut components = path.components().peekable();
if components.next() != Some(Component::RootDir) {
return Err(SiteError::Invalid("template canonical path"));
}
while let Some(component) = components.next() {
let Component::Normal(name) = component else {
return Err(SiteError::Invalid("template canonical component"));
};
if components.peek().is_none() {
return openat(&directory, name, flags | OFlags::NONBLOCK, Mode::empty())
.map(std::fs::File::from)
.map_err(|_| SiteError::Invalid("template command read"));
}
directory = openat(&directory, name, flags | OFlags::DIRECTORY, Mode::empty())
.map_err(|_| SiteError::Invalid("template command directory"))?;
}
Err(SiteError::Invalid("template command path"))
}