whyno-core 0.5.0

Permission check pipeline, fix engine, and state types
Documentation
//! Internal helpers for [`StateBuilder`](super::StateBuilder).

use std::path::PathBuf;

use crate::state::mount::MountOptions;
use crate::state::path::{FileType, PathComponent, StatResult};
use crate::state::Probe;

/// Creates [`PathComponent`] with `Known` stat, `Unknown` ACL, and `Unknown` flags.
pub(super) fn make_component(
    path: &str,
    uid: u32,
    gid: u32,
    mode: u32,
    file_type: FileType,
    nlink: u64,
) -> PathComponent {
    PathComponent {
        path: PathBuf::from(path),
        stat: Probe::Known(StatResult {
            mode,
            uid,
            gid,
            dev: 0,
            nlink,
            file_type,
        }),
        acl: Probe::Unknown,
        flags: Probe::Unknown,
        mount: None,
    }
}

/// Parses comma-separated mount options string into [`MountOptions`].
pub(super) fn parse_mount_options(options_str: &str) -> MountOptions {
    let mut opts = MountOptions {
        read_only: false,
        noexec: false,
        nosuid: false,
    };
    for token in options_str.split(',') {
        match token.trim() {
            "ro" => opts.read_only = true,
            "noexec" => opts.noexec = true,
            "nosuid" => opts.nosuid = true,
            _ => {}
        }
    }
    opts
}

/// Links each component to best-matching mount (longest prefix),
/// copies mount's device ID into component's `StatResult.dev`.
pub(super) fn link_mounts(
    components: &mut [PathComponent],
    mounts: &[crate::state::mount::MountEntry],
) {
    for comp in components.iter_mut() {
        let best = mounts
            .iter()
            .enumerate()
            .filter(|(_, m)| comp.path.starts_with(&m.mountpoint))
            .max_by_key(|(_, m)| m.mountpoint.as_os_str().len());
        if let Some((idx, mount)) = best {
            comp.mount = Some(idx);
            if let Probe::Known(ref mut stat) = comp.stat {
                stat.dev = mount.device;
            }
        }
    }
}