Inode parsing works!
This commit is contained in:
@@ -1,9 +1,9 @@
|
|||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
|
||||||
pub const InodeRef = packed struct {
|
pub const InodeRef = packed struct {
|
||||||
_: u16,
|
|
||||||
block_start: u32,
|
|
||||||
offset: u16,
|
offset: u16,
|
||||||
|
block_start: u32,
|
||||||
|
_: u16,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const InodeType = enum(u16) {
|
pub const InodeType = enum(u16) {
|
||||||
@@ -67,10 +67,10 @@ pub fn readInode(rdr: io.AnyReader, block_size: u32, alloc: std.mem.Allocator) !
|
|||||||
.header = hdr,
|
.header = hdr,
|
||||||
.data = switch (hdr.inode_type) {
|
.data = switch (hdr.inode_type) {
|
||||||
.dir => .{
|
.dir => .{
|
||||||
.dir = try dir.readDirInode(rdr),
|
.dir = try .init(rdr),
|
||||||
},
|
},
|
||||||
.ext_dir => .{
|
.ext_dir => .{
|
||||||
.ext_dir = try dir.readExtDirInode(rdr, alloc),
|
.ext_dir = try .init(rdr, alloc),
|
||||||
},
|
},
|
||||||
.file => .{
|
.file => .{
|
||||||
.file = try file.readFileInode(rdr, block_size, alloc),
|
.file = try file.readFileInode(rdr, block_size, alloc),
|
||||||
|
|||||||
+7
-7
@@ -7,20 +7,19 @@ pub const DirInode = packed struct {
|
|||||||
dir_table_size: u16,
|
dir_table_size: u16,
|
||||||
dir_block_offset: u16,
|
dir_block_offset: u16,
|
||||||
parent_inode_num: u32,
|
parent_inode_num: u32,
|
||||||
};
|
|
||||||
|
|
||||||
pub fn readDirInode(rdr: io.AnyReader) !DirInode {
|
pub fn init(rdr: io.AnyReader) !DirInode {
|
||||||
return try rdr.readStruct(DirInode);
|
return try rdr.readStruct(DirInode);
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
pub const DirIndex = struct {
|
pub const DirIndex = struct {
|
||||||
dir_header_offset: u32,
|
dir_header_offset: u32,
|
||||||
dir_table_offset: u32,
|
dir_table_offset: u32,
|
||||||
name_size: u32,
|
name_size: u32,
|
||||||
name: []u8,
|
name: []u8,
|
||||||
};
|
|
||||||
|
|
||||||
fn readDirIndex(rdr: io.AnyReader, alloc: std.mem.Allocator) !DirIndex {
|
pub fn init(rdr: io.AnyReader, alloc: std.mem.Allocator) !DirIndex {
|
||||||
var out = DirIndex{
|
var out = DirIndex{
|
||||||
.dir_header_offset = try rdr.readInt(u32, std.builtin.Endian.little),
|
.dir_header_offset = try rdr.readInt(u32, std.builtin.Endian.little),
|
||||||
.dir_table_offset = try rdr.readInt(u32, std.builtin.Endian.little),
|
.dir_table_offset = try rdr.readInt(u32, std.builtin.Endian.little),
|
||||||
@@ -31,6 +30,7 @@ fn readDirIndex(rdr: io.AnyReader, alloc: std.mem.Allocator) !DirIndex {
|
|||||||
_ = try rdr.readAll(out.name);
|
_ = try rdr.readAll(out.name);
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
pub const ExtDirInode = struct {
|
pub const ExtDirInode = struct {
|
||||||
hard_links: u32,
|
hard_links: u32,
|
||||||
@@ -41,9 +41,8 @@ pub const ExtDirInode = struct {
|
|||||||
dir_block_offset: u16,
|
dir_block_offset: u16,
|
||||||
xattr_index: u32,
|
xattr_index: u32,
|
||||||
indexes: []DirIndex,
|
indexes: []DirIndex,
|
||||||
};
|
|
||||||
|
|
||||||
pub fn readExtDirInode(rdr: io.AnyReader, alloc: std.mem.Allocator) !ExtDirInode {
|
pub fn init(rdr: io.AnyReader, alloc: std.mem.Allocator) !ExtDirInode {
|
||||||
var out = ExtDirInode{
|
var out = ExtDirInode{
|
||||||
.hard_links = try rdr.readInt(u32, std.builtin.Endian.little),
|
.hard_links = try rdr.readInt(u32, std.builtin.Endian.little),
|
||||||
.dir_table_size = try rdr.readInt(u32, std.builtin.Endian.little),
|
.dir_table_size = try rdr.readInt(u32, std.builtin.Endian.little),
|
||||||
@@ -58,8 +57,9 @@ pub fn readExtDirInode(rdr: io.AnyReader, alloc: std.mem.Allocator) !ExtDirInode
|
|||||||
try tmp.resize(out.dir_index_count);
|
try tmp.resize(out.dir_index_count);
|
||||||
var i: u16 = 0;
|
var i: u16 = 0;
|
||||||
while (i < out.dir_index_count) : (i += 1) {
|
while (i < out.dir_index_count) : (i += 1) {
|
||||||
tmp.items[i] = try readDirIndex(rdr, alloc);
|
tmp.items[i] = try .init(rdr, alloc);
|
||||||
}
|
}
|
||||||
out.indexes = tmp.items;
|
out.indexes = tmp.items;
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|||||||
+15
-3
@@ -4,8 +4,8 @@ const io = std.io;
|
|||||||
const CompressionType = @import("decompress.zig").CompressionType;
|
const CompressionType = @import("decompress.zig").CompressionType;
|
||||||
|
|
||||||
const MetadataHeader = packed struct {
|
const MetadataHeader = packed struct {
|
||||||
not_compressed: bool,
|
|
||||||
size: u15,
|
size: u15,
|
||||||
|
not_compressed: bool,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const MetadataReader = struct {
|
pub const MetadataReader = struct {
|
||||||
@@ -14,6 +14,7 @@ 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 = .{
|
||||||
@@ -26,12 +27,25 @@ pub const MetadataReader = struct {
|
|||||||
try out.readNextBlock();
|
try out.readNextBlock();
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
pub fn deinit(self: *MetadataReader) void {
|
||||||
|
self.alloc.free(self.curBlock);
|
||||||
|
}
|
||||||
pub fn any(self: *MetadataReader) io.AnyReader {
|
pub fn any(self: *MetadataReader) io.AnyReader {
|
||||||
return .{
|
return .{
|
||||||
.context = @ptrCast(self),
|
.context = @ptrCast(self),
|
||||||
.readFn = readOpaque,
|
.readFn = readOpaque,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
pub fn skip(self: *MetadataReader, offset: u16) !void {
|
||||||
|
var to_skip = offset;
|
||||||
|
var cur_left = self.curBlock.len - self.curOffset;
|
||||||
|
while (to_skip > cur_left) {
|
||||||
|
to_skip -= @intCast(cur_left);
|
||||||
|
try self.readNextBlock();
|
||||||
|
cur_left = self.curBlock.len;
|
||||||
|
}
|
||||||
|
self.curOffset = to_skip;
|
||||||
|
}
|
||||||
|
|
||||||
fn readNextBlock(self: *MetadataReader) !void {
|
fn readNextBlock(self: *MetadataReader) !void {
|
||||||
if (self.curBlock.len != 0) {
|
if (self.curBlock.len != 0) {
|
||||||
@@ -52,12 +66,10 @@ pub const MetadataReader = struct {
|
|||||||
var cur_read: usize = 0;
|
var cur_read: usize = 0;
|
||||||
var to_read: usize = 0;
|
var to_read: usize = 0;
|
||||||
while (cur_read < bytes.len) {
|
while (cur_read < bytes.len) {
|
||||||
std.debug.print("hello there!, {}\n", .{cur_read});
|
|
||||||
if (self.curOffset + 1 == self.curBlock.len) {
|
if (self.curOffset + 1 == self.curBlock.len) {
|
||||||
try self.readNextBlock();
|
try self.readNextBlock();
|
||||||
}
|
}
|
||||||
to_read = @min(bytes.len - cur_read, self.curBlock.len - self.curOffset);
|
to_read = @min(bytes.len - cur_read, self.curBlock.len - self.curOffset);
|
||||||
std.debug.print("{} {} {}\n", .{ cur_read, to_read, self.curOffset });
|
|
||||||
std.mem.copyForwards(u8, bytes[cur_read..], self.curBlock[self.curOffset .. self.curOffset + to_read]);
|
std.mem.copyForwards(u8, bytes[cur_read..], self.curBlock[self.curOffset .. self.curOffset + to_read]);
|
||||||
self.curOffset += @truncate(to_read);
|
self.curOffset += @truncate(to_read);
|
||||||
cur_read += to_read;
|
cur_read += to_read;
|
||||||
|
|||||||
+6
-4
@@ -9,23 +9,25 @@ pub const Reader = struct {
|
|||||||
super: Superblock,
|
super: Superblock,
|
||||||
rdr: fs.File,
|
rdr: fs.File,
|
||||||
root: inode.Inode,
|
root: inode.Inode,
|
||||||
alloc: std.heap.GeneralPurposeAllocator(.{}),
|
alloc: std.heap.ArenaAllocator,
|
||||||
|
|
||||||
pub fn close(self: *Reader) void {
|
pub fn deinit(self: *Reader) void {
|
||||||
self.rdr.close();
|
self.rdr.close();
|
||||||
_ = self.alloc.deinit();
|
self.alloc.deinit();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn newReader(filename: []const u8) !Reader {
|
pub fn newReader(filename: []const u8) !Reader {
|
||||||
const file = try std.fs.cwd().openFile(filename, .{});
|
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.page_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();
|
||||||
try file.seekTo(super.inode_table + super.root_inode.block_start);
|
try file.seekTo(super.inode_table + super.root_inode.block_start);
|
||||||
var root_reader: MetadataReader = try .init(super.comp, file.reader().any(), alloc.allocator());
|
var root_reader: MetadataReader = try .init(super.comp, file.reader().any(), alloc.allocator());
|
||||||
|
defer root_reader.deinit();
|
||||||
|
try root_reader.skip(super.root_inode.offset);
|
||||||
const root_inode = try inode.readInode(root_reader.any(), super.block_size, alloc.allocator());
|
const root_inode = try inode.readInode(root_reader.any(), super.block_size, alloc.allocator());
|
||||||
return Reader{
|
return Reader{
|
||||||
.super = super,
|
.super = super,
|
||||||
|
|||||||
+3
-1
@@ -1,10 +1,12 @@
|
|||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const debug = std.debug;
|
const debug = std.debug;
|
||||||
const squashfs = @import("squashfs.zig");
|
const squashfs = @import("squashfs.zig");
|
||||||
|
const print = std.debug.print;
|
||||||
|
|
||||||
const testFileName = "testing/LinuxPATest.sfs";
|
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.close();
|
defer reader.deinit();
|
||||||
|
print("{}\n", .{reader.root});
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user