Further work on inode decoding
This commit is contained in:
@@ -1,3 +1,5 @@
|
|||||||
|
const std = @import("std");
|
||||||
|
|
||||||
pub const InodeRef = packed struct {
|
pub const InodeRef = packed struct {
|
||||||
_: u16,
|
_: u16,
|
||||||
block_start: u32,
|
block_start: u32,
|
||||||
@@ -52,14 +54,14 @@ const file = @import("inode_types/file.zig");
|
|||||||
const sym = @import("inode_types/sym.zig");
|
const sym = @import("inode_types/sym.zig");
|
||||||
const misc = @import("inode_types/misc.zig");
|
const misc = @import("inode_types/misc.zig");
|
||||||
|
|
||||||
const Inode = struct {
|
pub const Inode = struct {
|
||||||
header: InodeHeader,
|
header: InodeHeader,
|
||||||
data: InodeData,
|
data: InodeData,
|
||||||
};
|
};
|
||||||
|
|
||||||
const io = @import("std").io;
|
const io = @import("std").io;
|
||||||
|
|
||||||
pub fn readInode(rdr: io.AnyReader, block_size: u64) !Inode {
|
pub fn readInode(rdr: io.AnyReader, block_size: u64, alloc: std.heap.Allocator) !Inode {
|
||||||
const hdr = try rdr.readStruct(InodeHeader);
|
const hdr = try rdr.readStruct(InodeHeader);
|
||||||
const data: InodeData = undefined;
|
const data: InodeData = undefined;
|
||||||
switch (hdr.inode_type) {
|
switch (hdr.inode_type) {
|
||||||
@@ -67,19 +69,19 @@ pub fn readInode(rdr: io.AnyReader, block_size: u64) !Inode {
|
|||||||
.dir = dir.readDirInode(rdr),
|
.dir = dir.readDirInode(rdr),
|
||||||
},
|
},
|
||||||
.ext_dir => data = .{
|
.ext_dir => data = .{
|
||||||
.ext_dir = try dir.readExtDirInode(rdr),
|
.ext_dir = try dir.readExtDirInode(rdr, alloc),
|
||||||
},
|
},
|
||||||
.file => data = .{
|
.file => data = .{
|
||||||
.file = try file.readFileInode(rdr, block_size),
|
.file = try file.readFileInode(rdr, block_size, alloc),
|
||||||
},
|
},
|
||||||
.ext_file => data = .{
|
.ext_file => data = .{
|
||||||
.ext_file = try file.readExtFileInode(rdr, block_size),
|
.ext_file = try file.readExtFileInode(rdr, block_size, alloc),
|
||||||
},
|
},
|
||||||
.symlink => data = .{
|
.symlink => data = .{
|
||||||
.block_device = try misc.readSymlinkInode(rdr),
|
.block_device = try misc.readSymlinkInode(rdr, alloc),
|
||||||
},
|
},
|
||||||
.ext_symlink => data = .{
|
.ext_symlink => data = .{
|
||||||
.ext_symlink = try sym.readExtSymlinkInode(rdr),
|
.ext_symlink = try sym.readExtSymlinkInode(rdr, alloc),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
return Inode{
|
return Inode{
|
||||||
|
|||||||
+8
-8
@@ -20,17 +20,15 @@ pub const DirIndex = struct {
|
|||||||
name: []const u8,
|
name: []const u8,
|
||||||
};
|
};
|
||||||
|
|
||||||
fn readDirIndex(rdr: io.AnyReader) !DirIndex {
|
fn readDirIndex(rdr: io.AnyReader, alloc: std.heap.Allocator) !DirIndex {
|
||||||
const out = DirIndex{
|
const 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),
|
||||||
.name_size = try rdr.readInt(u32, std.builtin.Endian.little),
|
.name_size = try rdr.readInt(u32, std.builtin.Endian.little),
|
||||||
.name = undefined,
|
.name = undefined,
|
||||||
};
|
};
|
||||||
const buf = try std.heap.page_allocator.alloc(u8, out.name_size);
|
out.name = try alloc.alloc(u8, out.name_size);
|
||||||
defer std.heap.page_allocator.free(buf);
|
try rdr.read(out.name);
|
||||||
try rdr.read(buf);
|
|
||||||
out.name = buf[0..];
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -45,7 +43,7 @@ pub const ExtDirInode = struct {
|
|||||||
indexes: []const DirIndex,
|
indexes: []const DirIndex,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn readExtDirInode(rdr: io.AnyReader) !ExtDirInode {
|
pub fn readExtDirInode(rdr: io.AnyReader, alloc: std.heap.Allocator) !ExtDirInode {
|
||||||
const out = ExtDirInode{
|
const out = ExtDirInode{
|
||||||
.hard_links = rdr.readInt(u32, std.builtin.Endian.little),
|
.hard_links = rdr.readInt(u32, std.builtin.Endian.little),
|
||||||
.dir_table_size = rdr.readInt(u32, std.builtin.Endian.little),
|
.dir_table_size = rdr.readInt(u32, std.builtin.Endian.little),
|
||||||
@@ -56,10 +54,12 @@ pub fn readExtDirInode(rdr: io.AnyReader) !ExtDirInode {
|
|||||||
.xattr_index = rdr.readInt(u32, std.builtin.Endian.little),
|
.xattr_index = rdr.readInt(u32, std.builtin.Endian.little),
|
||||||
.indexes = undefined,
|
.indexes = undefined,
|
||||||
};
|
};
|
||||||
out.indexes = []const DirIndex{undefined} ** out.dir_index_count;
|
const tmp = std.ArrayList(DirIndex).init(alloc);
|
||||||
|
try tmp.resize(out.dir_index_count);
|
||||||
const i: u16 = 0;
|
const i: u16 = 0;
|
||||||
while (i < out.dir_index_count) : (i += 1) {
|
while (i < out.dir_index_count) : (i += 1) {
|
||||||
out.indexes[i] = try readDirIndex(rdr);
|
tmp.items[i] = try readDirIndex(rdr, alloc);
|
||||||
}
|
}
|
||||||
|
out.indexes = tmp.items;
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ pub const FileInode = struct {
|
|||||||
block_sizes: []const u32,
|
block_sizes: []const u32,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn readFileInode(rdr: std.io.AnyReader, block_size: u32) !FileInode {
|
pub fn readFileInode(rdr: std.io.AnyReader, block_size: u32, alloc: std.heap.Allocator) !FileInode {
|
||||||
const out = FileInode{
|
const out = FileInode{
|
||||||
.start = try rdr.readInt(u32, std.builtin.Endian.little),
|
.start = try rdr.readInt(u32, std.builtin.Endian.little),
|
||||||
.frag_index = try rdr.readInt(u32, std.builtin.Endian.little),
|
.frag_index = try rdr.readInt(u32, std.builtin.Endian.little),
|
||||||
@@ -17,9 +17,11 @@ pub fn readFileInode(rdr: std.io.AnyReader, block_size: u32) !FileInode {
|
|||||||
.block_sizes = undefined,
|
.block_sizes = undefined,
|
||||||
};
|
};
|
||||||
var block_num = out.size / block_size;
|
var block_num = out.size / block_size;
|
||||||
if (out.frag_index != 0xFFFFFFFF and out.size % block_size != 0) {
|
if (out.frag_index != 0xFFFFFFFF) {
|
||||||
block_num += 1;
|
block_num += 1;
|
||||||
}
|
}
|
||||||
|
out.block_sizes = try alloc.alloc(u32, block_num);
|
||||||
|
try rdr.read(std.mem.asBytes(&out.block_sizes));
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -34,7 +36,7 @@ pub const ExtFileInode = struct {
|
|||||||
block_sizes: []const u32,
|
block_sizes: []const u32,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn readExtFileInode(rdr: std.io.AnyReader, block_size: u32) !ExtFileInode {
|
pub fn readExtFileInode(rdr: std.io.AnyReader, block_size: u32, alloc: std.heap.Allocator) !ExtFileInode {
|
||||||
const out = ExtFileInode{
|
const out = ExtFileInode{
|
||||||
.start = try rdr.readInt(u64, std.builtin.Endian.little),
|
.start = try rdr.readInt(u64, std.builtin.Endian.little),
|
||||||
.size = try rdr.readInt(u64, std.builtin.Endian.little),
|
.size = try rdr.readInt(u64, std.builtin.Endian.little),
|
||||||
@@ -49,6 +51,7 @@ pub fn readExtFileInode(rdr: std.io.AnyReader, block_size: u32) !ExtFileInode {
|
|||||||
if (out.frag_index != 0xFFFFFFFF and out.size % block_size != 0) {
|
if (out.frag_index != 0xFFFFFFFF and out.size % block_size != 0) {
|
||||||
block_num += 1;
|
block_num += 1;
|
||||||
}
|
}
|
||||||
//TODO: stuff
|
out.block_sizes = try alloc.alloc(u32, block_num);
|
||||||
|
try rdr.read(std.mem.asBytes(&out.block_sizes));
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-4
@@ -7,13 +7,14 @@ pub const SymlinkInode = struct {
|
|||||||
path: []const u8,
|
path: []const u8,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn readSymlinkInode(rdr: io.AnyReader) !SymlinkInode {
|
pub fn readSymlinkInode(rdr: io.AnyReader, alloc: std.heap.Allocator) !SymlinkInode {
|
||||||
const out = SymlinkInode{
|
const out = SymlinkInode{
|
||||||
.hard_links = try rdr.readInt(u32, std.builtin.Endian.little),
|
.hard_links = try rdr.readInt(u32, std.builtin.Endian.little),
|
||||||
.target_size = try rdr.readInt(u32, std.builtin.Endian.little),
|
.target_size = try rdr.readInt(u32, std.builtin.Endian.little),
|
||||||
.path = undefined,
|
.path = undefined,
|
||||||
};
|
};
|
||||||
out.path = (try rdr.readBoundedBytes(out.target_size + 1)).constSlice();
|
out.path = try alloc.alloc(u8, out.target_size + 1);
|
||||||
|
try rdr.read(out.path);
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -24,14 +25,15 @@ pub const ExtSymlinkInode = struct {
|
|||||||
xattr_index: u32,
|
xattr_index: u32,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn readExtSymlinkInode(rdr: io.AnyReader) !SymlinkInode {
|
pub fn readExtSymlinkInode(rdr: io.AnyReader, alloc: std.heap.Allocator) !SymlinkInode {
|
||||||
const out = ExtSymlinkInode{
|
const out = ExtSymlinkInode{
|
||||||
.hard_links = try rdr.readInt(u32, std.builtin.Endian.little),
|
.hard_links = try rdr.readInt(u32, std.builtin.Endian.little),
|
||||||
.target_size = try rdr.readInt(u32, std.builtin.Endian.little),
|
.target_size = try rdr.readInt(u32, std.builtin.Endian.little),
|
||||||
.path = undefined,
|
.path = undefined,
|
||||||
.xattr_index = undefined,
|
.xattr_index = undefined,
|
||||||
};
|
};
|
||||||
out.path = (try rdr.readBoundedBytes(out.target_size + 1)).constSlice();
|
out.path = try alloc.alloc(u8, out.target_size + 1);
|
||||||
|
try rdr.read(out.path);
|
||||||
out.xattr_index = try rdr.readInt(u32, std.builtin.Endian.little);
|
out.xattr_index = try rdr.readInt(u32, std.builtin.Endian.little);
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|||||||
+20
-5
@@ -1,17 +1,32 @@
|
|||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const io = std.io;
|
const fs = std.fs;
|
||||||
|
|
||||||
const Superblock = @import("superblock.zig").Superblock;
|
const Superblock = @import("superblock.zig").Superblock;
|
||||||
|
const Inode = @import("inode.zig").Inode;
|
||||||
|
|
||||||
pub const Reader = struct {
|
pub const Reader = struct {
|
||||||
super: Superblock,
|
super: Superblock,
|
||||||
rdr: io.AnyReader,
|
rdr: fs.File,
|
||||||
|
root: Inode,
|
||||||
|
alloc: std.heap.GeneralPurposeAllocator(.{}),
|
||||||
|
|
||||||
|
pub fn close(self: Reader) void {
|
||||||
|
self.rdr.close();
|
||||||
|
self.alloc.deinit();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn newReader(rdr: io.AnyReader) !Reader {
|
pub fn newReader(filename: []const u8) !Reader {
|
||||||
const super = try rdr.readStruct(Superblock);
|
const file = try std.fs.cwd().openFile(filename, .{});
|
||||||
|
errdefer file.close();
|
||||||
|
const alloc = std.heap.GeneralPurposeAllocator(.{});
|
||||||
|
errdefer alloc.deinit();
|
||||||
|
const super = try file.reader().readStruct(Superblock);
|
||||||
try super.valid();
|
try super.valid();
|
||||||
|
|
||||||
return Reader{
|
return Reader{
|
||||||
.super = super,
|
.super = super,
|
||||||
.rdr = rdr,
|
.rdr = file,
|
||||||
|
.alloc = alloc,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
+2
-7
@@ -5,11 +5,6 @@ const squashfs = @import("squashfs.zig");
|
|||||||
const testFileName = "testing/LinuxPATest.sfs";
|
const testFileName = "testing/LinuxPATest.sfs";
|
||||||
|
|
||||||
test "open test file" {
|
test "open test file" {
|
||||||
const testFile = try std.fs.cwd().openFile(
|
const reader = try squashfs.newReader(testFileName);
|
||||||
testFileName,
|
defer reader.close();
|
||||||
.{},
|
|
||||||
);
|
|
||||||
defer testFile.close();
|
|
||||||
const reader = try squashfs.newReader(testFile.reader().any());
|
|
||||||
_ = reader;
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user