intel_crashlog/collateral/
fs.rs1use super::{CollateralManager, CollateralTree, ItemPath, PVSS};
5use crate::Error;
6use std::io::Read;
7use std::path::{Path, PathBuf};
8
9pub struct FileSystemTree {
17 root: PathBuf,
18}
19
20impl FileSystemTree {
21 fn new(root: &Path) -> Self {
22 Self {
23 root: root.to_path_buf(),
24 }
25 }
26
27 fn build_path(&self, pvss: &PVSS, item: &ItemPath) -> Option<PathBuf> {
28 let mut relative_base = self.root.clone();
29 let pvss: PathBuf = pvss.into();
30 relative_base.extend(&pvss);
31 relative_base.push("crashlog");
32
33 let base = relative_base.canonicalize().ok()?;
34
35 let mut path = base.clone();
36 let item: PathBuf = item.into();
37 path.extend(&item);
38
39 path.canonicalize()
40 .ok()
41 .filter(|path| path.starts_with(&base))
42 }
43}
44
45impl CollateralTree for FileSystemTree {
46 fn get(&self, pvss: &PVSS, item: &ItemPath) -> Result<Vec<u8>, Error> {
47 let Some(path) = self.build_path(pvss, item) else {
48 return Err(Error::MissingCollateral(pvss.clone(), item.clone()));
49 };
50
51 let mut file = std::fs::File::open(path)?;
52 let mut buf = Vec::new();
53 file.read_to_end(&mut buf)?;
54 Ok(buf)
55 }
56
57 fn search(&self, item: &ItemPath) -> Result<Vec<PVSS>, Error> {
58 let mut hits = Vec::new();
59
60 for product in std::fs::read_dir(&self.root)? {
61 let product = product?;
62 for variant in std::fs::read_dir(product.path())? {
63 let variant = variant?;
64 for stepping in std::fs::read_dir(variant.path())? {
65 let stepping = stepping?;
66 for security in std::fs::read_dir(stepping.path())? {
67 let security = security?;
68 let mut path = security.path();
69 path.push("crashlog");
70 path.push::<PathBuf>(item.into());
71 if path.exists() {
72 hits.push(PVSS {
73 product: product.file_name().into_string()?,
74 variant: variant.file_name().into_string()?,
75 stepping: stepping.file_name().into_string()?,
76 security: security.file_name().into_string()?,
77 });
78 }
79 }
80 }
81 }
82 }
83
84 Ok(hits)
85 }
86}
87
88impl CollateralManager<FileSystemTree> {
89 pub fn file_system_tree(root: &Path) -> Result<Self, Error> {
103 Self::new(FileSystemTree::new(root))
104 }
105}