Started work on file extraction
This commit is contained in:
+10
-11
@@ -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(),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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
@@ -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" {
|
||||
|
||||
Reference in New Issue
Block a user