Skip to main content

ext4_fs/
structs.rs

1use serde::{Deserialize, Serialize};
2use std::collections::{BTreeMap, HashMap};
3
4#[derive(Debug)]
5pub struct Inode {
6    pub inode_type: InodeType,
7    pub permissions: Vec<InodePermissions>,
8    pub uid: u16,
9    pub size: u64,
10    pub accessed: i64,
11    pub changed: i64,
12    pub modified: i64,
13    pub deleted: i32,
14    pub gid: u16,
15    pub hard_links: u16,
16    pub blocks_count: u32,
17    pub flags: Vec<InodeFlags>,
18    pub direct_blocks: Vec<u32>,
19    pub indirect_block: u32,
20    pub double_indirect: u32,
21    pub triple_indirect: u32,
22    pub extents: Option<Extents>,
23    pub file_entry: Vec<u8>,
24    pub nfs: u32,
25    pub acl_block: u32,
26    pub upper_size: u32,
27    pub fragment_offset: u32,
28    pub upper_block_count: u16,
29    pub upper_acl_block: u16,
30    pub upper_uid: u16,
31    pub upper_gid: u16,
32    pub checksum: u16,
33    pub extended_inode_size: u16,
34    pub upper_checksum: u16,
35    pub changed_precision: u32,
36    pub modified_precision: u32,
37    pub accessed_precision: u32,
38    pub created: i64,
39    pub created_precision: u32,
40    pub extended_attributes: HashMap<String, String>,
41    pub symoblic_link: String,
42    pub is_sparse: bool,
43}
44
45#[derive(Debug, PartialEq)]
46pub enum InodeFlags {
47    SecureDelete,
48    Undelete,
49    Compressed,
50    SynchronousUpdates,
51    Immutable,
52    AppendOnly,
53    NoDump,
54    NoAtime,
55    Dirty,
56    CompressedClusters,
57    NoCompression,
58    /**Only used on Ext2 and Ext3 */
59    _CompressionError,
60    Encrypted,
61    Index,
62    Imagic,
63    Journal,
64    NoTail,
65    TopDirectory,
66    DirectorySync,
67    HugeFile,
68    Extents,
69    Verity,
70    ExtendedAttribute,
71    BlocksEof,
72    Snapshot,
73    Dax,
74    SnapshotDeleted,
75    SnapshotShrink,
76    Inline,
77    ProjectInherit,
78    Casefold,
79    Reserved,
80}
81#[derive(Debug, Clone)]
82pub struct Descriptor {
83    /**If IncompatFlags.Bit64 enabled then contains lower 32 bit value */
84    pub bitmap_block: u32,
85    /**If IncompatFlags.Bit64 enabled then contains lower 32 bit value */
86    pub bitmap_inode: u32,
87    /**If IncompatFlags.Bit64 enabled then contains lower 32 bit value */
88    pub inode_table_block: u64,
89    /**Count of unallocated blocks. If IncompatFlags.Bit64 enabled then contains lower 16 bit value  */
90    pub unallocated_blocks: u16,
91    /**Count of unallocated inodes. If IncompatFlags.Bit64 enabled then contains lower 16 bit value */
92    pub unallocated_inodes: u16,
93    /**Count of directories. If IncompatFlags.Bit64 enabled then contains lower 16 bit value */
94    pub directories: u16,
95    pub block_group_flags: Vec<BlockFlags>,
96    /**If IncompatFlags.Bit64 enabled then contains lower 32 bit value */
97    pub exclude_bitmap_block: u32,
98    /**If IncompatFlags.Bit64 enabled then contains lower 16 bit value */
99    pub block_bitmap_checksum: u16,
100    /**If IncompatFlags.Bit64 enabled then contains lower 16 bit value */
101    pub inode_bitmap_checksum: u16,
102    /**If IncompatFlags.Bit64 enabled then contains lower 16 bit value */
103    pub unused_inodes: u16,
104    pub checksum: u16,
105    /**If IncompatFlags.Bit64 enabled and descriptors > 32 bytes */
106    pub upper_bitmap_block: u32,
107    /**If IncompatFlags.Bit64 enabled and descriptors > 32 bytes */
108    pub upper_bitmap_inode: u32,
109    /**If IncompatFlags.Bit64 enabled and descriptors > 32 bytes */
110    pub upper_inode_table_block: u32,
111    /**If IncompatFlags.Bit64 enabled and descriptors > 32 bytes */
112    pub upper_unallocated_blocks: u16,
113    /**If IncompatFlags.Bit64 enabled and descriptors > 32 bytes */
114    pub upper_unallocated_inodes: u16,
115    /**If IncompatFlags.Bit64 enabled and descriptors > 32 bytes */
116    pub upper_directories: u16,
117    /**If IncompatFlags.Bit64 enabled and descriptors > 32 bytes */
118    pub upper_unused_inodes: u16,
119    /**If IncompatFlags.Bit64 enabled and descriptors > 32 bytes */
120    pub upper_exclude_bitmap_block: u32,
121    /**If IncompatFlags.Bit64 enabled and descriptors > 32 bytes */
122    pub upper_block_bitmap_checksum: u16,
123    /**If IncompatFlags.Bit64 enabled and descriptors > 32 bytes */
124    pub upper_inode_bitmap_checksum: u16,
125}
126
127#[derive(Debug, Clone)]
128pub struct Extents {
129    pub signature: u16,
130    pub number_of_extents_or_indexes: u16,
131    pub max_extents_or_indexes: u16,
132    pub depth: u16,
133    pub generation: u32,
134    pub extent_descriptors: Vec<ExtentDescriptor>,
135    pub index_descriptors: Vec<IndexDescriptor>,
136    pub extent_descriptor_list: BTreeMap<u32, ExtentDescriptor>,
137}
138
139#[derive(Debug, Clone)]
140pub struct ExtentDescriptor {
141    pub logical_block_number: u32,
142    pub number_of_blocks: u16,
143    pub block_number: u64,
144    pub next_logical_block_number: u32,
145    pub block_diff: u32,
146    pub upper_part_physical_block_number: u16,
147    pub lower_part_physical_block_number: u32,
148}
149
150#[derive(Debug, Clone)]
151pub struct IndexDescriptor {
152    pub logical_block_number: u32,
153    pub block_number: u64,
154    pub lower_part_physical_block_number: u32,
155    pub upper_part_physical_block_number: u16,
156}
157
158#[derive(Debug, Clone)]
159pub enum BlockFlags {
160    InodeBitmapUnused,
161    BlockBitmapUnused,
162    /**Bitmap is zeroed */
163    InodeTableEmpty,
164}
165
166pub struct Ext4Hash {
167    pub md5: bool,
168    pub sha1: bool,
169    pub sha256: bool,
170}
171
172#[derive(Debug, PartialEq)]
173pub struct HashValue {
174    pub md5: String,
175    pub sha1: String,
176    pub sha256: String,
177}
178#[derive(Debug, PartialEq, Clone)]
179pub struct Directory {
180    pub inode: u32,
181    pub file_type: FileType,
182    pub name: String,
183}
184
185#[derive(Debug, PartialEq)]
186pub struct FileInfo {
187    pub name: String,
188    pub inode: u64,
189    pub parent_inode: u64,
190    pub size: u64,
191    pub permission: Vec<InodePermissions>,
192    pub inode_type: InodeType,
193    pub accessed: i64,
194    pub changed: i64,
195    pub created: i64,
196    pub modified: i64,
197    pub deleted: i32,
198    pub hard_links: u16,
199    pub children: Vec<Directory>,
200    pub extended_attributes: HashMap<String, String>,
201    pub uid: u16,
202    pub gid: u16,
203    pub is_sparse: bool,
204}
205
206#[derive(Debug, PartialEq, Serialize, Deserialize, Copy, Clone)]
207pub enum InodeType {
208    Pipe,
209    Device,
210    Directory,
211    BlockDevice,
212    File,
213    SymbolicLink,
214    Socket,
215    Unknown,
216}
217
218#[derive(Debug, PartialEq)]
219pub struct Stat {
220    pub inode: u64,
221    pub size: u64,
222    pub permission: Vec<InodePermissions>,
223    pub inode_type: InodeType,
224    pub accessed: i64,
225    pub changed: i64,
226    pub created: i64,
227    pub modified: i64,
228    pub deleted: i32,
229    pub hard_links: u16,
230    pub extended_attributes: HashMap<String, String>,
231    pub uid: u16,
232    pub gid: u16,
233    pub is_sparse: bool,
234}
235#[derive(Debug, PartialEq, Serialize, Clone, Copy, Deserialize)]
236pub enum InodePermissions {
237    ReadOther,
238    WriteOther,
239    ExecuteOther,
240    ReadGroup,
241    WriteGroup,
242    ExecuteGroup,
243    ReadUser,
244    WriteUser,
245    ExecuteUser,
246    Sticky,
247    Suid,
248    Sgid,
249    Unknown,
250}
251
252#[derive(Debug, PartialEq, Clone, Copy, Serialize, Deserialize)]
253pub enum FileType {
254    Unknown,
255    File,
256    Directory,
257    Device,
258    Block,
259    FifoQueue,
260    Socket,
261    SymbolicLink,
262}
263
264impl FileInfo {
265    pub(crate) fn new(
266        inode_info: Inode,
267        dirs: Vec<HashMap<u64, Directory>>,
268        inode: u64,
269    ) -> FileInfo {
270        let mut children = Vec::new();
271        let root = 2;
272        let mut parent_inode = if inode == root { root } else { 0 };
273        let mut name = if inode == root {
274            String::from("/")
275        } else {
276            String::new()
277        };
278        for entry in &dirs {
279            if let Some(dir) = entry.get(&inode)
280                && name.is_empty()
281            {
282                name = dir.name.clone();
283            }
284            for value in entry.values() {
285                children.push(value.clone());
286                if value.name == ".." {
287                    parent_inode = value.inode as u64;
288                }
289            }
290        }
291
292        FileInfo {
293            name,
294            inode,
295            parent_inode,
296            size: inode_info.size,
297            permission: inode_info.permissions,
298            inode_type: inode_info.inode_type,
299            accessed: inode_info.accessed,
300            changed: inode_info.changed,
301            created: inode_info.created,
302            modified: inode_info.modified,
303            deleted: inode_info.deleted,
304            hard_links: inode_info.hard_links,
305            children,
306            extended_attributes: inode_info.extended_attributes,
307            uid: inode_info.uid,
308            gid: inode_info.gid,
309            is_sparse: inode_info.is_sparse,
310        }
311    }
312}
313
314impl Stat {
315    pub(crate) fn new(inode_info: Inode, inode: u64) -> Stat {
316        Stat {
317            inode,
318            size: inode_info.size,
319            permission: inode_info.permissions,
320            inode_type: inode_info.inode_type,
321            accessed: inode_info.accessed,
322            changed: inode_info.changed,
323            created: inode_info.created,
324            modified: inode_info.modified,
325            deleted: inode_info.deleted,
326            hard_links: inode_info.hard_links,
327            extended_attributes: inode_info.extended_attributes,
328            uid: inode_info.uid,
329            gid: inode_info.gid,
330            is_sparse: inode_info.is_sparse,
331        }
332    }
333}