Directory table parsing

This commit is contained in:
Caleb Gardner
2025-05-14 22:23:17 -05:00
parent 5daffdafc7
commit e010763fc6
5 changed files with 78 additions and 4 deletions
+1 -1
View File
@@ -14,7 +14,7 @@ pub const CompressionType = enum(u16) {
lz4, lz4,
zstd, zstd,
pub fn Decompress(self: CompressionType, alloc: std.mem.Allocator, rdr: std.io.AnyReader) ![]u8 { pub fn decompress(self: CompressionType, alloc: std.mem.Allocator, rdr: std.io.AnyReader) ![]u8 {
var out = std.ArrayList(u8).init(alloc); var out = std.ArrayList(u8).init(alloc);
defer out.deinit(); defer out.deinit();
switch (self) { switch (self) {
+32
View File
@@ -1,5 +1,7 @@
const std = @import("std"); const std = @import("std");
const CompressionType = @import("decompress.zig").CompressionType;
const DirHeader = packed struct { const DirHeader = packed struct {
count: u32, count: u32,
inode_block_start: u32, inode_block_start: u32,
@@ -43,3 +45,33 @@ pub const DirEntry = struct {
} }
}; };
const MetadataHeader = @import("metadata_reader.zig").MetadataHeader;
pub fn readDirEntries(alloc: std.mem.Allocator, comp: CompressionType, rdr: std.io.AnyReader, size: u32) ![]DirEntry {
var total_size: u32 = 3;
var meta_hdr: MetadataHeader = undefined;
var dir_hdr: DirHeader = undefined;
var buf: []u8 = undefined;
var buf_rdr: std.io.FixedBufferStream(u8) = undefined;
var i = 0;
var entries: std.ArrayList(DirEntry) = .init(alloc);
defer alloc.free(buf);
while (total_size < size) {
meta_hdr = try rdr.readStruct(MetadataHeader);
if (meta_hdr.not_compressed) {
buf = try alloc.realloc(buf, meta_hdr.size);
_ = try rdr.readAll(rdr);
} else {
alloc.free(buf);
buf = try comp.Decompress(alloc, std.io.limitedReader(rdr, meta_hdr.size));
}
buf_rdr = std.io.fixedBufferStream(buf);
dir_hdr = try buf_rdr.reader().readStruct(DirHeader);
total_size += 12;
i = 0;
while (i < dir_hdr.count) : (i += 1) {
entries.append(try .init(try .init(buf_rdr, alloc), dir_hdr));
}
}
return try entries.toOwnedSlice();
}
+41 -2
View File
@@ -1,15 +1,23 @@
const std = @import("std");
const inode = @import("inode.zig"); const inode = @import("inode.zig");
const Reader = @import("squashfs.zig").Reader; const Reader = @import("squashfs.zig").Reader;
const MetadataReader = @import("metadata_reader.zig").MetadataReader; const MetadataReader = @import("metadata_reader.zig").MetadataReader;
const FileOffsetReader = @import("file_offset_reader.zig").FileOffsetReader; const FileOffsetReader = @import("file_offset_reader.zig").FileOffsetReader;
const DirEntry = @import("directory.zig").DirEntry;
const FileOpenError = error{
NotFound,
NotDirectory,
};
pub const File = struct { pub const File = struct {
rdr: *Reader, rdr: *Reader,
inode: inode.Inode, inode: inode.Inode,
name: []const u8, name: []const u8,
dir_entries: []const void = undefined, //TODO dir_entries: []DirEntry = undefined,
pub fn fromRef(ref: inode.InodeRef, name: []const u8, rdr: *Reader) !File { pub fn fromRef(rdr: *Reader, ref: inode.InodeRef, name: []const u8) !File {
var offset_rdr: FileOffsetReader = .init(rdr.file, rdr.super.inode_table + ref.block_start); var offset_rdr: FileOffsetReader = .init(rdr.file, rdr.super.inode_table + ref.block_start);
var meta_rdr: MetadataReader = .init(rdr.super.comp, offset_rdr.any(), rdr.alloc.allocator()); var meta_rdr: MetadataReader = .init(rdr.super.comp, offset_rdr.any(), rdr.alloc.allocator());
try meta_rdr.skip(ref.offset); try meta_rdr.skip(ref.offset);
@@ -20,4 +28,35 @@ pub const File = struct {
.name = name, .name = name,
}; };
} }
pub fn fromDirEntry(rdr: *Reader, ent: DirEntry) !File {
var offset_rdr: FileOffsetReader = .init(rdr.file, rdr.super.inode_table + ent.inode_block_start);
var meta_rdr: MetadataReader = .init(
rdr.super.comp,
offset_rdr.any(),
rdr.alloc,
);
try meta_rdr.skip(ent.inode_offset);
const in = try inode.readInode(meta_rdr, rdr.super.block_size, rdr.alloc.allocator());
return .{
.rdr = rdr,
.inode = in,
.name = ent.name,
};
}
pub fn open(self: File, path: []const u8) (anyerror || FileOpenError)!File {
switch (self.inode.header.inode_type) {
.dir, .ext_dir => {},
else => return FileOpenError.NotDirectory,
}
const clean_path: []const u8 = if (std.mem.startsWith(u8, path, "/")) {
return path[1..];
} else {
return path;
};
const path_split = std.mem.splitAny(u8, clean_path, "/");
}
fn readDirEntries(self: *File) (anyerror || FileOpenError)!File {}
}; };
+1 -1
View File
@@ -3,7 +3,7 @@ const io = std.io;
const CompressionType = @import("decompress.zig").CompressionType; const CompressionType = @import("decompress.zig").CompressionType;
const MetadataHeader = packed struct { pub const MetadataHeader = packed struct {
size: u15, size: u15,
not_compressed: bool, not_compressed: bool,
}; };
+3
View File
@@ -0,0 +1,3 @@
pub const Reader = @import("squashfs.zig").Reader;
pub const File = @import("file.zig").File;