Tweaking to get stuff workign

This commit is contained in:
Caleb Gardner
2025-05-15 05:59:38 -05:00
parent e010763fc6
commit fc068fdbd9
6 changed files with 103 additions and 61 deletions
+13 -9
View File
@@ -15,8 +15,8 @@ const RawDirEntry = struct {
name_size: u16, name_size: u16,
name: []u8, name: []u8,
fn init(rdr: std.io.AnyReader, alloc: std.mem.Allocator) !DirEntry { fn init(rdr: std.io.AnyReader, alloc: std.mem.Allocator) !RawDirEntry {
var out: DirEntry = .{ var out: RawDirEntry = .{
.inode_offset = try rdr.readInt(u16, std.builtin.Endian.little), .inode_offset = try rdr.readInt(u16, std.builtin.Endian.little),
.inode_num_difference = try rdr.readInt(i16, std.builtin.Endian.little), .inode_num_difference = try rdr.readInt(i16, std.builtin.Endian.little),
.inode_type = try rdr.readInt(u16, std.builtin.Endian.little), .inode_type = try rdr.readInt(u16, std.builtin.Endian.little),
@@ -39,7 +39,7 @@ pub const DirEntry = struct {
return .{ return .{
.inode_offset = raw.inode_offset, .inode_offset = raw.inode_offset,
.inode_block_start = hdr.inode_block_start, .inode_block_start = hdr.inode_block_start,
.inode_num = hdr.inode_num - raw.inode_num_difference, .inode_num = hdr.inode_num + @as(u32, @intCast(raw.inode_num_difference)),
.name = raw.name, .name = raw.name,
}; };
} }
@@ -52,25 +52,29 @@ pub fn readDirEntries(alloc: std.mem.Allocator, comp: CompressionType, rdr: std.
var meta_hdr: MetadataHeader = undefined; var meta_hdr: MetadataHeader = undefined;
var dir_hdr: DirHeader = undefined; var dir_hdr: DirHeader = undefined;
var buf: []u8 = 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); defer alloc.free(buf);
var buf_rdr: std.io.FixedBufferStream([]u8) = undefined;
var i: u32 = 0;
var entries: std.ArrayList(DirEntry) = .init(alloc);
var raw: RawDirEntry = undefined;
while (total_size < size) { while (total_size < size) {
meta_hdr = try rdr.readStruct(MetadataHeader); meta_hdr = try rdr.readStruct(MetadataHeader);
if (meta_hdr.not_compressed) { if (meta_hdr.not_compressed) {
buf = try alloc.realloc(buf, meta_hdr.size); buf = try alloc.realloc(buf, meta_hdr.size);
_ = try rdr.readAll(rdr); _ = try rdr.readAll(buf);
} else { } else {
alloc.free(buf); alloc.free(buf);
buf = try comp.Decompress(alloc, std.io.limitedReader(rdr, meta_hdr.size)); var limit = std.io.limitedReader(rdr, meta_hdr.size);
buf = try comp.decompress(alloc, limit.reader().any());
} }
buf_rdr = std.io.fixedBufferStream(buf); buf_rdr = std.io.fixedBufferStream(buf);
dir_hdr = try buf_rdr.reader().readStruct(DirHeader); dir_hdr = try buf_rdr.reader().readStruct(DirHeader);
total_size += 12; total_size += 12;
i = 0; i = 0;
while (i < dir_hdr.count) : (i += 1) { while (i < dir_hdr.count) : (i += 1) {
entries.append(try .init(try .init(buf_rdr, alloc), dir_hdr)); raw = try .init(buf_rdr.reader().any(), alloc);
total_size += @sizeOf(RawDirEntry);
try entries.append(.init(raw, dir_hdr));
} }
} }
return try entries.toOwnedSlice(); return try entries.toOwnedSlice();
+48 -16
View File
@@ -4,7 +4,7 @@ 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 dir = @import("directory.zig");
const FileOpenError = error{ const FileOpenError = error{
NotFound, NotFound,
@@ -15,10 +15,10 @@ pub const File = struct {
rdr: *Reader, rdr: *Reader,
inode: inode.Inode, inode: inode.Inode,
name: []const u8, name: []const u8,
dir_entries: []DirEntry = undefined, dir_entries: []dir.DirEntry = &[0]dir.DirEntry{},
pub fn fromRef(rdr: *Reader, ref: inode.InodeRef, name: []const u8) !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.rdr, 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);
const in = try inode.readInode(meta_rdr, rdr.super.block_size, rdr.alloc.allocator()); const in = try inode.readInode(meta_rdr, rdr.super.block_size, rdr.alloc.allocator());
@@ -29,15 +29,15 @@ pub const File = struct {
}; };
} }
pub fn fromDirEntry(rdr: *Reader, ent: DirEntry) !File { pub fn fromDirEntry(rdr: *Reader, ent: dir.DirEntry) !File {
var offset_rdr: FileOffsetReader = .init(rdr.file, rdr.super.inode_table + ent.inode_block_start); var offset_rdr: FileOffsetReader = .init(&rdr.rdr, rdr.super.inode_table + ent.inode_block_start);
var meta_rdr: MetadataReader = .init( var meta_rdr: MetadataReader = try .init(
rdr.super.comp, rdr.super.comp,
offset_rdr.any(), offset_rdr.any(),
rdr.alloc, rdr.alloc.allocator(),
); );
try meta_rdr.skip(ent.inode_offset); try meta_rdr.skip(ent.inode_offset);
const in = try inode.readInode(meta_rdr, rdr.super.block_size, rdr.alloc.allocator()); const in = try inode.readInode(meta_rdr.any(), rdr.super.block_size, rdr.alloc.allocator());
return .{ return .{
.rdr = rdr, .rdr = rdr,
.inode = in, .inode = in,
@@ -45,18 +45,50 @@ pub const File = struct {
}; };
} }
pub fn open(self: File, path: []const u8) (anyerror || FileOpenError)!File { pub fn open(self: *File, path: []const u8) (anyerror || FileOpenError)!File {
if (path.len == 0) return self.*;
const clean_path: []const u8 = std.mem.trimLeft(u8, path, "/");
if (clean_path.len == 0 or std.mem.eql(u8, clean_path, ".")) {
return self.*;
}
switch (self.inode.header.inode_type) { switch (self.inode.header.inode_type) {
.dir, .ext_dir => {}, .dir, .ext_dir => {},
else => return FileOpenError.NotDirectory, else => return FileOpenError.NotDirectory,
} }
const clean_path: []const u8 = if (std.mem.startsWith(u8, path, "/")) { try self.readDirEntries();
return path[1..]; const file_name = std.mem.sliceTo(clean_path, '/');
} else { for (self.dir_entries) |ent| {
return path; std.debug.print("yo {}\n", .{ent});
}; if (std.mem.eql(u8, file_name, ent.name)) {
const path_split = std.mem.splitAny(u8, clean_path, "/"); return try File.fromDirEntry(self.rdr, ent);
}
}
return FileOpenError.NotFound;
} }
fn readDirEntries(self: *File) (anyerror || FileOpenError)!File {} fn readDirEntries(self: *File) (anyerror || FileOpenError)!void {
if (self.dir_entries.len != 0) {
return;
}
var dir_block_offset: u32 = undefined;
var dir_block_start: u32 = undefined;
var size: u32 = undefined;
switch (self.inode.data) {
.dir => |d| {
dir_block_start = d.dir_block_start;
dir_block_offset = d.dir_block_offset;
size = d.dir_table_size;
},
.ext_dir => |d| {
dir_block_start = d.dir_block_start;
dir_block_offset = d.dir_block_offset;
size = d.dir_table_size;
},
else => return FileOpenError.NotDirectory,
}
std.debug.print("{}\n", .{self.rdr});
var offset_rdr: FileOffsetReader = .init(&self.rdr.rdr, self.rdr.super.dir_table + dir_block_start);
var meta_rdr: MetadataReader = try .init(self.rdr.super.comp, offset_rdr.any(), self.rdr.alloc.allocator());
self.dir_entries = try dir.readDirEntries(self.rdr.alloc.allocator(), self.rdr.super.comp, meta_rdr.any(), size);
}
}; };
+2 -2
View File
@@ -1,10 +1,10 @@
const std = @import("std"); const std = @import("std");
pub const FileOffsetReader = struct { pub const FileOffsetReader = struct {
file: std.fs.File, file: *std.fs.File,
offset: u64, offset: u64,
pub fn init(file: std.fs.File, initial_offset: u64) FileOffsetReader { pub fn init(file: *std.fs.File, initial_offset: u64) FileOffsetReader {
return .{ return .{
.file = file, .file = file,
.offset = initial_offset, .offset = initial_offset,
+1 -2
View File
@@ -14,7 +14,6 @@ pub const MetadataReader = struct {
decomp: CompressionType, decomp: CompressionType,
curBlock: []u8, curBlock: []u8,
curOffset: u16, curOffset: u16,
free: bool = false,
pub fn init(decomp: CompressionType, rdr: io.AnyReader, alloc: std.mem.Allocator) !MetadataReader { pub fn init(decomp: CompressionType, rdr: io.AnyReader, alloc: std.mem.Allocator) !MetadataReader {
var out: MetadataReader = .{ var out: MetadataReader = .{
@@ -58,7 +57,7 @@ pub const MetadataReader = struct {
_ = try self.rdr.readAll(self.curBlock); _ = try self.rdr.readAll(self.curBlock);
} else { } else {
var limit_rdr = std.io.limitedReader(self.rdr, hdr.size); var limit_rdr = std.io.limitedReader(self.rdr, hdr.size);
self.curBlock = try self.decomp.Decompress(self.alloc, limit_rdr.reader().any()); self.curBlock = try self.decomp.decompress(self.alloc, limit_rdr.reader().any());
} }
} }
+21 -16
View File
@@ -11,22 +11,16 @@ pub const Reader = struct {
super: Superblock, super: Superblock,
rdr: fs.File, rdr: fs.File,
root: File, root: File,
alloc: std.heap.GeneralPurposeAllocator(.{}), alloc: std.heap.ArenaAllocator,
pub fn deinit(self: *Reader) void { pub fn init(filename: []const u8) !Reader {
self.rdr.close(); var file = try std.fs.cwd().openFile(filename, .{});
// _ = self.alloc.deinit();
}
};
pub fn newReader(filename: []const u8) !Reader {
const file = try std.fs.cwd().openFile(filename, .{});
errdefer file.close(); errdefer file.close();
var alloc: std.heap.GeneralPurposeAllocator(.{}) = .init; var alloc: std.heap.ArenaAllocator = .init(std.heap.smp_allocator);
errdefer _ = alloc.deinit(); errdefer _ = alloc.deinit();
const super = try file.reader().readStruct(Superblock); const super = try file.reader().readStruct(Superblock);
try super.valid(); try super.valid();
var offset_rdr: FileOffsetReader = .init(file, super.inode_table + super.root_inode.block_start); var offset_rdr: FileOffsetReader = .init(&file, super.inode_table + super.root_inode.block_start);
var root_reader: MetadataReader = try .init( var root_reader: MetadataReader = try .init(
super.comp, super.comp,
offset_rdr.any(), offset_rdr.any(),
@@ -34,16 +28,27 @@ pub fn newReader(filename: []const u8) !Reader {
); );
defer root_reader.deinit(); defer root_reader.deinit();
try root_reader.skip(super.root_inode.offset); try root_reader.skip(super.root_inode.offset);
var out: Reader = undefined; var out: Reader = .{
out = Reader{
.super = super, .super = super,
.rdr = file, .rdr = file,
.root = .{ .root = undefined,
.alloc = alloc,
};
out.root = .{
.inode = try inode.readInode(root_reader.any(), super.block_size, alloc.allocator()), .inode = try inode.readInode(root_reader.any(), super.block_size, alloc.allocator()),
.name = "", .name = "",
.rdr = &out, .rdr = &out,
},
.alloc = alloc,
}; };
std.debug.print("init {}\n", .{out});
return out; return out;
} }
pub fn deinit(self: *Reader) void {
self.rdr.close();
self.alloc.deinit();
}
pub fn open(self: *Reader, path: []const u8) !File {
return self.root.open(path);
}
};
+2
View File
@@ -8,4 +8,6 @@ const testFileName = "testing/LinuxPATest.sfs";
test "open test file" { test "open test file" {
var reader = try squashfs.newReader(testFileName); var reader = try squashfs.newReader(testFileName);
defer reader.deinit(); defer reader.deinit();
const fil = try reader.open("PortableApps/Desktop.ini");
std.debug.print("{s}\n", .{fil.name});
} }