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 _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 pub bitmap_block: u32,
85 pub bitmap_inode: u32,
87 pub inode_table_block: u64,
89 pub unallocated_blocks: u16,
91 pub unallocated_inodes: u16,
93 pub directories: u16,
95 pub block_group_flags: Vec<BlockFlags>,
96 pub exclude_bitmap_block: u32,
98 pub block_bitmap_checksum: u16,
100 pub inode_bitmap_checksum: u16,
102 pub unused_inodes: u16,
104 pub checksum: u16,
105 pub upper_bitmap_block: u32,
107 pub upper_bitmap_inode: u32,
109 pub upper_inode_table_block: u32,
111 pub upper_unallocated_blocks: u16,
113 pub upper_unallocated_inodes: u16,
115 pub upper_directories: u16,
117 pub upper_unused_inodes: u16,
119 pub upper_exclude_bitmap_block: u32,
121 pub upper_block_bitmap_checksum: u16,
123 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 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}