use binrw::BinRead;
use log::trace;
use size_of_no_padding::SizeOfNoPadding;
use crate::constant::{S_IFMT, S_ISBLK, S_ISCHR, major, minor};
#[derive(BinRead, SizeOfNoPadding)]
#[br(little)]
#[allow(dead_code)]
pub(crate) struct SuperBlock {
pub(crate) magic: u32, pub(crate) size: u32, pub(crate) flags: u32, pub(crate) future: u32, pub(crate) signature: [u8; 16], pub(crate) fsid: Info, pub(crate) name: [u8; 16], pub(crate) root: INode, }
impl SuperBlock {
pub(crate) const CRC_OFFSET: usize = 32;
pub(crate) const CRC_SIZE: usize = 4;
}
#[derive(BinRead, Clone, Copy, SizeOfNoPadding)]
#[br(little)]
pub(crate) struct INode {
pub(crate) uid_mode: u32,
pub(crate) gid_size: u32,
pub(crate) offset_namelen: u32,
}
impl INode {
pub(crate) fn uid(&self) -> u32 {
(self.uid_mode >> 16) & 0xffff
}
pub(crate) fn mode(&self) -> u32 {
self.uid_mode & 0xffff
}
pub(crate) fn gid(&self) -> u32 {
(self.gid_size >> 24) & 0xff
}
pub(crate) fn size(&self) -> u32 {
self.gid_size & 0xffffff
}
pub(crate) fn offset(&self) -> u32 {
(self.offset_namelen >> 6) & 0x03ffffff
}
pub(crate) fn namelen(&self) -> u32 {
self.offset_namelen & 0x3f
}
}
#[derive(BinRead)]
#[allow(dead_code)]
pub(crate) struct Info {
pub(crate) crc: u32,
pub(crate) edition: u32,
pub(crate) blocks: u32,
pub(crate) files: u32,
}
pub(crate) fn print_node(r#type: char, node: &INode, name: impl AsRef<str>) {
let name = name.as_ref();
let info = if S_ISCHR(node.mode()) || S_ISBLK(node.mode()) {
format!("{:4},{:4}", major(node.size()), minor(node.size()))
} else {
format!("{:9}", node.size())
};
trace!(
"{} {:04o} {} {:5}:{:<3} {}",
r#type,
node.mode() & !S_IFMT,
info,
node.uid(),
node.gid(),
name
);
}