diff --git a/src/extract_options.zig b/src/extract_options.zig index 4658940..604d9cf 100644 --- a/src/extract_options.zig +++ b/src/extract_options.zig @@ -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(), + }; } diff --git a/src/file.zig b/src/file.zig index 461c147..dc465af 100644 --- a/src/file.zig +++ b/src/file.zig @@ -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); + } }; } diff --git a/src/reader/data.zig b/src/reader/data.zig index abf1f76..2541ace 100644 --- a/src/reader/data.zig +++ b/src/reader/data.zig @@ -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, diff --git a/src/root.zig b/src/root.zig index ae7a282..c65635e 100644 --- a/src/root.zig +++ b/src/root.zig @@ -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" {