Fixed a handful of errors when extracting.
Fixed issues with unsquashfs
This commit is contained in:
@@ -34,6 +34,7 @@ pub fn main() !void {
|
||||
fn handleArgs(alloc: std.mem.Allocator, out: *Writer) !void {
|
||||
var args = try std.process.argsWithAllocator(alloc);
|
||||
defer args.deinit();
|
||||
_ = args.next(); // args[0] is the application launch command.
|
||||
while (args.next()) |arg| {
|
||||
if (std.mem.eql(u8, arg, "-o")) {
|
||||
const nxt = args.next();
|
||||
@@ -45,6 +46,7 @@ fn handleArgs(alloc: std.mem.Allocator, out: *Writer) !void {
|
||||
try out.print("-o must be followed by a number\n", .{});
|
||||
return errors.InvalidArguments;
|
||||
};
|
||||
continue;
|
||||
} else if (std.mem.eql(u8, arg, "-d")) {
|
||||
const nxt = args.next();
|
||||
if (nxt == null or nxt.?.len == 0) {
|
||||
@@ -52,6 +54,7 @@ fn handleArgs(alloc: std.mem.Allocator, out: *Writer) !void {
|
||||
return errors.InvalidArguments;
|
||||
}
|
||||
extLoc = nxt.?;
|
||||
continue;
|
||||
}
|
||||
if (archive.len > 0) {
|
||||
try out.print("you can only provide one file at a time\n", .{});
|
||||
|
||||
+9
-5
@@ -18,9 +18,10 @@ pub const DecompFn = *const fn (alloc: std.mem.Allocator, in: []u8, out: []u8) a
|
||||
// };
|
||||
|
||||
pub fn gzipDecompress(alloc: std.mem.Allocator, in: []u8, out: []u8) anyerror!usize {
|
||||
_ = alloc;
|
||||
var rdr: Reader = .fixed(in);
|
||||
var decomp = std.compress.flate.Decompress.init(&rdr, .zlib, &[0]u8{});
|
||||
const buf = try alloc.alloc(u8, out.len);
|
||||
defer alloc.free(buf);
|
||||
var decomp = std.compress.flate.Decompress.init(&rdr, .zlib, buf);
|
||||
return decomp.reader.readSliceShort(out);
|
||||
}
|
||||
|
||||
@@ -37,8 +38,11 @@ pub fn xzDecompress(alloc: std.mem.Allocator, in: []u8, out: []u8) anyerror!usiz
|
||||
}
|
||||
|
||||
pub fn zstdDecompress(alloc: std.mem.Allocator, in: []u8, out: []u8) anyerror!usize {
|
||||
_ = alloc;
|
||||
var rdr: Reader = .fixed(in);
|
||||
var decomp = std.compress.zstd.Decompress.init(&rdr, &[0]u8{}, .{});
|
||||
return decomp.reader.readSliceShort(out);
|
||||
const buf = try alloc.alloc(u8, std.compress.zstd.default_window_len + std.compress.zstd.block_size_max);
|
||||
defer alloc.free(buf);
|
||||
var decomp = std.compress.zstd.Decompress.init(&rdr, buf, .{});
|
||||
return decomp.reader.readSliceShort(out) catch |err| {
|
||||
return decomp.err orelse err;
|
||||
};
|
||||
}
|
||||
|
||||
+3
-7
@@ -30,17 +30,13 @@ pub fn readDir(alloc: std.mem.Allocator, rdr: *Reader, size: u32) ![]Entry {
|
||||
var cur_red: u32 = 3; // start at 3 due to "." & ".." being counted in the dir size.
|
||||
var hdr: Header = undefined;
|
||||
var raw: RawEntry = undefined;
|
||||
var out: std.ArrayList(Entry) = try .initCapacity(alloc, 25); // Start out with capacity instead of needing to allocate per header.
|
||||
var out: std.ArrayList(Entry) = try .initCapacity(alloc, 100); // Start out with a decent capacity instead of needing to allocate per header.
|
||||
errdefer out.deinit(alloc);
|
||||
while (cur_red < size) {
|
||||
try rdr.readSliceEndian(Header, @ptrCast(&hdr), .little);
|
||||
cur_red += @sizeOf(Header);
|
||||
const count = hdr.count + 1;
|
||||
if (out.capacity < count) {
|
||||
// Make sure we have at least 25 capacity past current count.
|
||||
try out.ensureUnusedCapacity(alloc, ((count % 25) + 2) * 25);
|
||||
}
|
||||
for (0..count) |_| {
|
||||
try out.ensureUnusedCapacity(alloc, hdr.count + 1);
|
||||
for (0..hdr.count + 1) |_| {
|
||||
try rdr.readSliceEndian(RawEntry, @ptrCast(&raw), .little);
|
||||
const name = try alloc.alloc(u8, raw.name_size + 1);
|
||||
errdefer alloc.free(name);
|
||||
|
||||
+1
-1
@@ -42,7 +42,7 @@ pub fn init(archive: *Archive, inode: Inode, name: []const u8) !SfsFile {
|
||||
}
|
||||
pub fn fromEntry(archive: *Archive, entry: DirEntry) !SfsFile {
|
||||
var rdr = try archive.fil.readerAt(entry.block_start + archive.super.inode_start, &[0]u8{});
|
||||
var meta: MetadataReader = .init(archive.allocator(), &rdr.interface, &archive.decomp);
|
||||
var meta: MetadataReader = .init(archive.allocator(), &rdr.interface, archive.decomp);
|
||||
try meta.interface.discardAll(entry.block_offset);
|
||||
const inode: Inode = try .read(archive.allocator(), &meta.interface, archive.super.block_size);
|
||||
errdefer inode.deinit(archive.allocator());
|
||||
|
||||
+4
-1
@@ -138,6 +138,9 @@ pub fn extractTo(self: Inode, archive: *Archive, path: []const u8, options: Extr
|
||||
.dir, .ext_dir => {
|
||||
// Removing any trailing separators since that's the easiest path forward.
|
||||
if (path[path.len - 1] == '/') return self.extractTo(archive, path[0 .. path.len - 1], options);
|
||||
std.fs.cwd().makeDir(path) catch |err| {
|
||||
if (err != std.fs.Dir.MakeError.PathAlreadyExists) return err;
|
||||
};
|
||||
var alloc = archive.allocator();
|
||||
const entries = try self.dirEntries(archive);
|
||||
defer {
|
||||
@@ -218,7 +221,7 @@ fn extractRegFile(self: Inode, archive: *Archive, path: []const u8, options: Ext
|
||||
_ = try dat_rdr.interface.streamRemaining(&wrt.interface);
|
||||
try wrt.interface.flush();
|
||||
// updateTime is in nanoseconds (a billionth of a second). mod_time is in seconds.
|
||||
try fil.updateTimes(self.hdr.mod_time * (10 ^ 9), self.hdr.mod_time * (10 ^ 9));
|
||||
try fil.updateTimes(self.hdr.mod_time, self.hdr.mod_time);
|
||||
if (!options.ignore_permissions) {
|
||||
try fil.chmod(self.hdr.permissions);
|
||||
try fil.chown(try archive.id(self.hdr.uid_idx), try archive.id(self.hdr.gid_idx));
|
||||
|
||||
+2
-2
@@ -28,7 +28,7 @@ test "ExtractSingleFile" {
|
||||
defer sfs.deinit();
|
||||
var test_fil = try sfs.open(TestFile);
|
||||
defer test_fil.deinit();
|
||||
try test_fil.extract(TestFileExtractLocation, .VerboseDefault);
|
||||
try test_fil.extract(TestFileExtractLocation, .Default);
|
||||
//TODO: validate extracted file.
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ test "ExtractCompleteArchive" {
|
||||
defer fil.close();
|
||||
var sfs: Archive = try .init(std.testing.allocator, fil);
|
||||
defer sfs.deinit();
|
||||
try sfs.extract(TestFullExtractLocation, .VerboseDefault);
|
||||
try sfs.extract(TestFullExtractLocation, .Default);
|
||||
}
|
||||
|
||||
const LinuxPATestCorrectSuperblock: Superblock = .{
|
||||
|
||||
@@ -111,6 +111,7 @@ fn advance(self: *DataReader) !void {
|
||||
}
|
||||
const tmp_buf = try self.alloc.alloc(u8, block.size);
|
||||
defer self.alloc.free(tmp_buf);
|
||||
try rdr.interface.readSliceAll(tmp_buf);
|
||||
_ = try self.decomp(self.alloc, tmp_buf, self.interface.buffer);
|
||||
}
|
||||
/// Does not guarentee that data currently in the buffer is retained.
|
||||
|
||||
Reference in New Issue
Block a user