#![forbid(unsafe_code)]
use std::collections::HashMap;
pub const ROOT_INO: u64 = 2;
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Artifact {
Dir,
SysOsInfo,
SysProcesses,
SysModules,
SysNetwork,
SysDmesg,
}
pub struct Node {
pub name: Vec<u8>,
pub artifact: Artifact,
pub children: Vec<u64>,
}
impl Node {
fn dir(name: &str) -> Self {
Self {
name: name.as_bytes().to_vec(),
artifact: Artifact::Dir,
children: vec![],
}
}
pub fn is_dir(&self) -> bool {
matches!(self.artifact, Artifact::Dir)
}
}
pub struct Registry {
nodes: HashMap<u64, Node>,
index: HashMap<(u64, Vec<u8>), u64>,
}
impl Registry {
pub fn skeleton() -> Self {
let mut nodes = HashMap::new();
nodes.insert(
ROOT_INO,
Node {
name: b"/".to_vec(),
artifact: Artifact::Dir,
children: vec![],
},
);
let mut registry = Self {
nodes,
index: HashMap::new(),
};
for (ino, name) in [(3, "sys"), (4, "proc"), (5, "forensic"), (6, "mem")] {
registry.add_dir(ROOT_INO, ino, name);
}
registry.add_file(3, 7, "os-info.txt", Artifact::SysOsInfo);
registry.add_file(3, 8, "processes.txt", Artifact::SysProcesses);
registry.add_file(3, 9, "modules.txt", Artifact::SysModules);
registry.add_file(3, 10, "network.txt", Artifact::SysNetwork);
registry.add_file(3, 11, "dmesg.txt", Artifact::SysDmesg);
registry
}
fn add_dir(&mut self, parent: u64, ino: u64, name: &str) {
self.add_node(parent, ino, Node::dir(name));
}
fn add_file(&mut self, parent: u64, ino: u64, name: &str, artifact: Artifact) {
self.add_node(
parent,
ino,
Node {
name: name.as_bytes().to_vec(),
artifact,
children: vec![],
},
);
}
fn add_node(&mut self, parent: u64, ino: u64, node: Node) {
let key = (parent, node.name.clone());
self.nodes.insert(ino, node);
self.index.insert(key, ino);
if let Some(p) = self.nodes.get_mut(&parent) {
p.children.push(ino);
}
}
pub fn node(&self, ino: u64) -> Option<&Node> {
self.nodes.get(&ino)
}
pub fn lookup(&self, parent: u64, name: &[u8]) -> Option<u64> {
self.index.get(&(parent, name.to_vec())).copied()
}
}