Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b22e4d003d | |||
| a41c37fef4 | |||
| 2d079d77f7 | |||
| 48f4235875 |
+3
-4
@@ -61,9 +61,8 @@ pub fn init(alloc: std.mem.Allocator, fil: File) !Archive {
|
|||||||
try std.Thread.getCpuCount(),
|
try std.Thread.getCpuCount(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
/// Create the Archive dictating the amount of threads & memory used.
|
/// Create the Archive dictating the amount of threads used for extraction.
|
||||||
/// If trying to extract a full archive, a large memory size & thread count could help.
|
/// If you're planning on only interacting with a small number of files, it should be fine to use few (or one) threads.
|
||||||
/// If you're planning on only interacting with a small number of files, it should be fine to use few threads and a small memory size.
|
|
||||||
pub fn initAdvanced(alloc: std.mem.Allocator, fil: File, offset: u64, threads: usize) !Archive {
|
pub fn initAdvanced(alloc: std.mem.Allocator, fil: File, offset: u64, threads: usize) !Archive {
|
||||||
var super: Superblock = undefined;
|
var super: Superblock = undefined;
|
||||||
const red = try fil.pread(@ptrCast(&super), offset);
|
const red = try fil.pread(@ptrCast(&super), offset);
|
||||||
@@ -74,7 +73,7 @@ pub fn initAdvanced(alloc: std.mem.Allocator, fil: File, offset: u64, threads: u
|
|||||||
.parent_alloc = alloc,
|
.parent_alloc = alloc,
|
||||||
.alloc = .{ .child_allocator = alloc },
|
.alloc = .{ .child_allocator = alloc },
|
||||||
// .fixed_buf = fixed_buf,
|
// .fixed_buf = fixed_buf,
|
||||||
.thread_count = threads,
|
.thread_count = if (threads > 0) threads else try std.Thread.getCpuCount(),
|
||||||
.fil = .init(fil, offset),
|
.fil = .init(fil, offset),
|
||||||
.decomp = switch (super.compression) {
|
.decomp = switch (super.compression) {
|
||||||
.gzip => Decomp.gzipDecompress,
|
.gzip => Decomp.gzipDecompress,
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ const help_mgs =
|
|||||||
\\
|
\\
|
||||||
\\ -o <offset> Start reading the archive at the given offset.
|
\\ -o <offset> Start reading the archive at the given offset.
|
||||||
\\
|
\\
|
||||||
\\ -p <threads> Specify how many threads to use. If no present, the system's logical cores count is used.
|
\\ -p <threads> Specify how many threads to use. If no present or zero, the system's logical cores count is used.
|
||||||
\\
|
\\
|
||||||
\\ --help Display this messages
|
\\ --help Display this messages
|
||||||
\\ --version Display the version
|
\\ --version Display the version
|
||||||
@@ -83,9 +83,9 @@ fn handleArgs(alloc: std.mem.Allocator, out: *Writer) !void {
|
|||||||
};
|
};
|
||||||
continue;
|
continue;
|
||||||
} else if (std.mem.eql(u8, arg, "--version")) {
|
} else if (std.mem.eql(u8, arg, "--version")) {
|
||||||
try out.print("zig-unsquashfs version ", .{});
|
try out.print("zig-unsquashfs v", .{});
|
||||||
try config.version.format(out);
|
try config.version.format(out);
|
||||||
try out.print("\nBuilt using Zig {s} with {} backend in {} mode.\n", .{ builtin.zig_version_string, builtin.zig_backend, builtin.mode });
|
try out.print("\nBuilt using Zig {s} in {} mode\n", .{ builtin.zig_version_string, builtin.mode });
|
||||||
std.process.exit(0);
|
std.process.exit(0);
|
||||||
return;
|
return;
|
||||||
} else if (std.mem.eql(u8, arg, "--help")) {
|
} else if (std.mem.eql(u8, arg, "--help")) {
|
||||||
|
|||||||
+21
-13
@@ -232,6 +232,9 @@ pub fn extractToThreaded(self: Inode, archive: *Archive, path: []const u8, optio
|
|||||||
if (perms != null) {
|
if (perms != null) {
|
||||||
for (perms.?.items) |p| {
|
for (perms.?.items) |p| {
|
||||||
var fil = try std.fs.cwd().openFile(p.path, .{});
|
var fil = try std.fs.cwd().openFile(p.path, .{});
|
||||||
|
defer fil.close();
|
||||||
|
const time = @as(i128, self.hdr.mod_time) * 1000000000;
|
||||||
|
try fil.updateTimes(time, time);
|
||||||
try fil.chmod(p.perm);
|
try fil.chmod(p.perm);
|
||||||
try fil.chown(p.uid, p.gid);
|
try fil.chown(p.uid, p.gid);
|
||||||
}
|
}
|
||||||
@@ -246,8 +249,11 @@ pub fn extractToThreaded(self: Inode, archive: *Archive, path: []const u8, optio
|
|||||||
|
|
||||||
try self.extractRegFileThreaded(alloc, archive, path, options, &pool);
|
try self.extractRegFileThreaded(alloc, archive, path, options, &pool);
|
||||||
|
|
||||||
|
var fil = try std.fs.cwd().openFile(path, .{});
|
||||||
|
defer fil.close();
|
||||||
|
const time = @as(i128, self.hdr.mod_time) * 1000000000;
|
||||||
|
try fil.updateTimes(time, time);
|
||||||
if (!options.ignore_permissions) {
|
if (!options.ignore_permissions) {
|
||||||
var fil = try std.fs.cwd().openFile(path, .{});
|
|
||||||
try fil.chmod(self.hdr.permissions);
|
try fil.chmod(self.hdr.permissions);
|
||||||
try fil.chown(try archive.id(self.hdr.uid_idx), try archive.id(self.hdr.gid_idx));
|
try fil.chown(try archive.id(self.hdr.uid_idx), try archive.id(self.hdr.gid_idx));
|
||||||
}
|
}
|
||||||
@@ -300,11 +306,9 @@ fn extractThread(
|
|||||||
if (out_err.* != null) return;
|
if (out_err.* != null) return;
|
||||||
switch (self.hdr.inode_type) {
|
switch (self.hdr.inode_type) {
|
||||||
.dir, .ext_dir => {
|
.dir, .ext_dir => {
|
||||||
std.fs.cwd().makeDir(path) catch |err| {
|
_ = std.fs.cwd().makePathStatus(path) catch |err| {
|
||||||
if (err != std.fs.Dir.MakeError.PathAlreadyExists) {
|
out_err.* = err;
|
||||||
out_err.* = err;
|
return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const entries = self.dirEntries(alloc, archive.*) catch |err| {
|
const entries = self.dirEntries(alloc, archive.*) catch |err| {
|
||||||
@@ -378,16 +382,16 @@ fn extractThread(
|
|||||||
///
|
///
|
||||||
/// Assumes the inode is a file or ext_file type.
|
/// Assumes the inode is a file or ext_file type.
|
||||||
fn extractRegFile(self: Inode, alloc: std.mem.Allocator, archive: *Archive, path: []const u8, options: ExtractionOptions) !void {
|
fn extractRegFile(self: Inode, alloc: std.mem.Allocator, archive: *Archive, path: []const u8, options: ExtractionOptions) !void {
|
||||||
var fil = try std.fs.cwd().createFile(path, .{});
|
var fil = try std.fs.cwd().createFile(path, .{ .exclusive = true });
|
||||||
defer fil.close();
|
defer fil.close();
|
||||||
var wrt = fil.writer(&[0]u8{});
|
var wrt = fil.writer(&[0]u8{});
|
||||||
var dat_rdr = try self.dataReader(alloc, archive);
|
var dat_rdr = try self.dataReader(alloc, archive);
|
||||||
defer dat_rdr.deinit();
|
defer dat_rdr.deinit();
|
||||||
_ = try dat_rdr.interface.streamRemaining(&wrt.interface);
|
_ = try dat_rdr.interface.streamRemaining(&wrt.interface);
|
||||||
try wrt.interface.flush();
|
try wrt.interface.flush();
|
||||||
// updateTime is in nanoseconds (a billionth of a second). mod_time is in seconds.
|
|
||||||
// TODO: fix
|
const time = @as(i128, self.hdr.mod_time) * 1000000000;
|
||||||
// try fil.updateTimes(self.hdr.mod_time, self.hdr.mod_time);
|
try fil.updateTimes(time, time);
|
||||||
if (!options.ignore_permissions) {
|
if (!options.ignore_permissions) {
|
||||||
try fil.chmod(self.hdr.permissions);
|
try fil.chmod(self.hdr.permissions);
|
||||||
try fil.chown(try archive.id(self.hdr.uid_idx), try archive.id(self.hdr.gid_idx));
|
try fil.chown(try archive.id(self.hdr.uid_idx), try archive.id(self.hdr.gid_idx));
|
||||||
@@ -399,8 +403,12 @@ fn extractRegFile(self: Inode, alloc: std.mem.Allocator, archive: *Archive, path
|
|||||||
/// Assumes the inode is a file or ext_file type.
|
/// Assumes the inode is a file or ext_file type.
|
||||||
fn extractRegFileThreaded(self: Inode, alloc: std.mem.Allocator, archive: *Archive, path: []const u8, options: ExtractionOptions, pool: *Pool) !void {
|
fn extractRegFileThreaded(self: Inode, alloc: std.mem.Allocator, archive: *Archive, path: []const u8, options: ExtractionOptions, pool: *Pool) !void {
|
||||||
var fil = try std.fs.cwd().createFile(path, .{});
|
var fil = try std.fs.cwd().createFile(path, .{});
|
||||||
|
defer fil.close();
|
||||||
var data = try self.threadedDataReader(alloc, archive);
|
var data = try self.threadedDataReader(alloc, archive);
|
||||||
try data.extractThreaded(fil, pool);
|
try data.extractThreaded(fil, pool);
|
||||||
|
|
||||||
|
const time = @as(i128, self.hdr.mod_time) * 1000000000;
|
||||||
|
try fil.updateTimes(time, time);
|
||||||
if (!options.ignore_permissions) {
|
if (!options.ignore_permissions) {
|
||||||
try fil.chmod(self.hdr.permissions);
|
try fil.chmod(self.hdr.permissions);
|
||||||
try fil.chown(try archive.id(self.hdr.uid_idx), try archive.id(self.hdr.gid_idx));
|
try fil.chown(try archive.id(self.hdr.uid_idx), try archive.id(self.hdr.gid_idx));
|
||||||
@@ -465,9 +473,9 @@ fn extractDevice(self: Inode, archive: *Archive, path: []const u8, options: Extr
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
var fil = try std.fs.cwd().openFile(path, .{});
|
var fil = try std.fs.cwd().openFile(path, .{});
|
||||||
// updateTime is in nanoseconds (a billionth of a second). mod_time is in seconds.
|
defer fil.close();
|
||||||
// TODO: fix
|
const time = @as(i128, self.hdr.mod_time) * 1000000000;
|
||||||
// try fil.updateTimes(self.hdr.mod_time, self.hdr.mod_time);
|
try fil.updateTimes(time, time);
|
||||||
if (!options.ignore_permissions) {
|
if (!options.ignore_permissions) {
|
||||||
try fil.chmod(self.hdr.permissions);
|
try fil.chmod(self.hdr.permissions);
|
||||||
try fil.chown(try archive.id(self.hdr.uid_idx), try archive.id(self.hdr.gid_idx));
|
try fil.chown(try archive.id(self.hdr.uid_idx), try archive.id(self.hdr.gid_idx));
|
||||||
|
|||||||
Reference in New Issue
Block a user