diff --git a/src/btrfs_structs.rs b/src/btrfs_structs.rs index 02ca1eb..9131f72 100644 --- a/src/btrfs_structs.rs +++ b/src/btrfs_structs.rs @@ -1,5 +1,5 @@ -use binparse_derive::AllVariants; -use binparse_derive::ParseBin; +use btrfs_parse_derive::AllVariants; +use btrfs_parse_derive::ParseBin; use std::fmt; use std::error; use std::ffi::CString; @@ -94,6 +94,7 @@ pub enum Value { DevExtent(DevExtentItem), ExtentData(ExtentDataItem), Ref(RefItem), + RootRef(RootRefItem), Unknown(Vec), } @@ -409,6 +410,15 @@ pub struct RefItem { pub name: CString, } +#[allow(unused)] +#[derive(Debug,Clone,ParseBin)] +pub struct RootRefItem { + pub directory: u64, + pub index: u64, + pub name_len: u16, + pub name: CString, +} + #[allow(unused)] #[repr(u64)] #[derive(Clone,Copy,Debug)] @@ -530,7 +540,7 @@ impl ParseBin for CString { fn parse_len(bytes: &[u8]) -> Result<(Self, usize), ParseError> { let mut chars = Vec::from(bytes); chars.push(0); - Ok((CString::from_vec_with_nul(chars).unwrap(), bytes.len())) + Ok((CString::from_vec_with_nul(chars).unwrap_or(CString::new("").unwrap()), bytes.len())) } } @@ -563,6 +573,7 @@ impl ParseBin for ItemType { impl ParseBin for Node { fn parse_len(bytes: &[u8]) -> Result<(Node, usize), ParseError> { + if bytes.len() < 0x65 { return err!("Not enough data to parse node header"); } @@ -625,8 +636,13 @@ impl ParseBin for Node { Value::DevExtent(DevExtentItem::parse(data_slice)?), ItemType::ExtentData => Value::ExtentData(ExtentDataItem::parse(data_slice)?), - ItemType::Ref => - Value::Ref(RefItem::parse(data_slice)?), + ItemType::Ref => { + Value::Ref(RefItem::parse(data_slice)?) + } + ItemType::RootRef => + Value::RootRef(RootRefItem::parse(data_slice)?), + ItemType::RootBackRef => + Value::RootRef(RootRefItem::parse(data_slice)?), _ => Value::Unknown(Vec::from(data_slice)), }; diff --git a/src/nodereader.rs b/src/nodereader.rs index f139262..dd1f09e 100644 --- a/src/nodereader.rs +++ b/src/nodereader.rs @@ -29,6 +29,8 @@ impl<'a> NodeReader<'a> { return Ok(Arc::clone(node)) } + println!("Reading node at {:X}", addr); + let node_data = self.addr_map.node_at_log(self.image, addr)?; let node = Arc::new(Node::parse(node_data)?); diff --git a/src/render_tree.rs b/src/render_tree.rs index 6c2f206..7d725c7 100644 --- a/src/render_tree.rs +++ b/src/render_tree.rs @@ -156,8 +156,23 @@ fn item_value_string(tree_id: u64, item: &Item) -> Markup { } } }, - Value::Inode(_) => - html! { "" }, + Value::Inode(inode_item) => { + let file_type = match inode_item.mode / (1<<12) { + 4 => "directory", + 2 => "character device", + 6 => "block device", + 8 => "regular file", + 1 => "FIFO", + 10 => "symbolic link", + 12 => "socket", + _ => "unknown file type", + }; + format_escape!("{}, mode {}{}{}{}", file_type, + (inode_item.mode / (1<<9)) % 8, + (inode_item.mode / (1<<6)) % 8, + (inode_item.mode / (1<<3)) % 8, + (inode_item.mode / (1<<0)) % 8) + }, Value::ExtentData(extent_data_item) => match &extent_data_item.data { ExtentDataBody::Inline(data) => @@ -167,6 +182,8 @@ fn item_value_string(tree_id: u64, item: &Item) -> Markup { }, Value::Ref(ref_item) => html! { (format!("{:?}", &ref_item.name)) }, + Value::RootRef(ref_item) => + html! { (format!("{:?}", &ref_item.name)) }, Value::Extent(extent_item) => PreEscaped(format!("flags: {}, block_refs: {:?}", extent_item.flags, extent_item.block_refs)), Value::BlockGroup(blockgroup_item) => @@ -180,7 +197,7 @@ fn item_value_string(tree_id: u64, item: &Item) -> Markup { Value::Dev(dev_item) => PreEscaped(format!("total_bytes: {}", size_name(dev_item.total_bytes))), Value::Chunk(chunk_item) => - PreEscaped(format!("size: {}", chunk_item.size)), + PreEscaped(format!("size: {}", size_name(chunk_item.size))), _ => { // println!("{:?} {:?}", item.key, item.valu); PreEscaped(String::new()) @@ -260,6 +277,13 @@ fn item_details_string(tree_id: u64, item: &Item) -> Markup { tr { td { "rtime" } td { (root_item.rtime.sec) } } }}} }, + Value::RootRef(root_ref_item) => { + html! { table { tbody { + tr { td { "name" } td { (format!("{:?}", root_ref_item.name)) } } + tr { td { "directory" } td { (root_ref_item.directory) } } + tr { td { "index" } td { (root_ref_item.index) } } + }}} + }, _ => { html! {} }, diff --git a/src/util.rs b/src/util.rs index 6b91f0f..8541139 100644 --- a/src/util.rs +++ b/src/util.rs @@ -5,3 +5,9 @@ macro_rules! error { macro_rules! err { ($($i:expr),*) => { Err(error!($($i),*)) }; } + +macro_rules! format_escape { + ($($arg:tt)*) => { + html! { (format!($($arg)*)) } + }; +}