Started work on file extraction

This commit is contained in:
Caleb Gardner
2025-07-17 22:17:58 -05:00
parent 4d52627d5d
commit b4af1233e5
4 changed files with 87 additions and 12 deletions
+10 -11
View File
@@ -9,16 +9,15 @@ dereference_symlinks: bool = false,
unbreak_symlinks: bool = false,
/// Do not set file's permissions & owner when extracted.
ignore_permissions: bool = false,
/// Verbose logging
verbose: bool = false,
/// Verbose logging writer. If not set, stdout is used.
verbose_logger: ?std.io.AnyWriter = null,
/// Number of threads used during extraction. Defualts to std.Thread.getCpuCount().
thread_count: u32,
// max_memory: u64,
pol: std.Thread.Pool = undefined,
pub fn init(alloc: std.mem.Allocator, thread_count: u16) !Self {
var out: Self = .{};
out.pol.init(.{
.allocator = alloc,
.n_jobs = thread_count,
});
return out;
pub fn init() !Self {
return .{
.thread_count = try std.Thread.getCpuCount(),
};
}
+66
View File
@@ -121,6 +121,17 @@ pub fn File(comptime T: type) type {
}
}
const Reader = std.io.GenericReader(*DataReader(T), anyerror, DataReader(T).read);
pub fn read(self: *Self, buf: []u8) !usize {
if (self.data_reader == null) return FileError.NotRegular;
return self.data_reader.?.read(buf);
}
pub fn reader(self: *Self) !Reader {
if (self.data_reader == null) return FileError.NotRegular;
return self.data_reader.?.reader();
}
pub fn open(self: Self, path: []const u8) !Self {
if (self.entries == null) return FileError.NotDirectory;
if (path.len == 0) return self;
@@ -160,5 +171,60 @@ pub fn File(comptime T: type) type {
self.idx = 0;
}
};
pub fn extract(self: Self, op: *ExtractionOptions, path: []const u8) !void {
if(op.verbose and op.verbose_logger == null){
op.verbose_logger = std.io.getStdOut().writer().any();
}
var wg: std.Thread.WaitGroup = .{};
var pol: std.Thread.Pool = undefined;
try pol.init(.{
.n_jobs = op.thread_count,
.allocator = self.rdr.alloc,
});
}
fn extractReal(self: Self, op: *ExtractionOptions, path: []const u8) !void{
switch (self.inode.hdr.type) {
.dir, .ext_dir => self.extractDir(path),
.file, .ext_file => self.extractReg(op, path),
.symlink, .ext_symlink => self.extractSymlink(op, path),
.block_dev,
.ext_block_dev,
.char_dev,
.ext_char_dev,
.fifo,
.ext_fifo,
=> self.extractDev(path),
else => {
if(op.verbose){
std.fmt.format(op.verbose_logger.?, "inode {} \"{}\" is a socket. Ignoring.\n");
return;
}
}
}
}
fn extractDir(self: Self, op: *ExtractionOptions, path: []const u8) !void {}
fn extractReg(self: Self, op: *ExtractionOptions, path: []const u8) !void {}
fn extractSymlink(self: Self, op: *ExtractionOptions, path: []const u8) !void {}
fn extractDev(self: Self, op: *ExtractionOptions, path: []const u8) !void {
if (exists) return ExtractError.FileExists;
comptime if (builtin.os.tag != .linux) {
if(op.ver)
return;
}
const mode: u32 = switch (self.inode.header.inode_type) {
.block, .ext_block => std.posix.S.IFBLK,
.char, .ext_char => std.posix.S.IFCHR,
.fifo, .ext_fifo => std.posix.S.IFIFO,
else => unreachable,
};
const dev = switch (self.inode.data) {
.block, .char => |b| b.device,
.ext_block, .ext_char => |b| b.device,
.fifo, .ext_fifo => 0,
else => unreachable,
};
_ = std.os.linux.mknod(@ptrCast(real_path), mode, dev);
}
};
}
+8
View File
@@ -59,6 +59,7 @@ pub fn DataReader(comptime T: type) type {
pub fn deinit(self: Self) void {
self.alloc.free(self.offsets);
self.alloc.free(self.frag);
if (self.read_idx < self.sizes.len) self.alloc.free(self.read_block);
}
pub fn addFragment(self: *Self, entry: FragEntry, offset: u32) !void {
@@ -115,6 +116,8 @@ pub fn DataReader(comptime T: type) type {
return out;
}
const Reader = std.io.GenericReader(*Self, anyerror, read);
pub fn read(self: *Self, buf: []u8) !usize {
var cur_red: usize = 0;
var to_read: usize = 0;
@@ -136,6 +139,9 @@ pub fn DataReader(comptime T: type) type {
}
return cur_red;
}
pub fn reader(self: *Self) Reader {
return .{ .context = self };
}
/// Write the entire file's contents to the writer.
/// If availble, pwrite will be used.
@@ -165,12 +171,14 @@ pub fn DataReader(comptime T: type) type {
},
);
}
std.Thread.yield();
wg.wait();
if (completed.items.len > 0) {
return completed.items.get(0);
}
return self.file_size;
}
pub fn writeToThreaded(self: Self, errs: *std.ArrayList(anyerror), wg: *std.Thread.WaitGroup, writer: anytype) void {}
fn extractThreaded(
self: Self,
mut: *std.Thread.Mutex,
+3 -1
View File
@@ -20,8 +20,10 @@ test "OpenFile" {
defer f.deinit();
std.debug.print("{s}\n", .{f.name});
}
const start = try root.open("Start.exe");
var start = try root.open("Start.exe");
defer start.deinit();
const startReader = try start.reader();
_ = startReader;
}
test "ReadFile" {