Basic extraction complete
This commit is contained in:
+110
-7
@@ -201,13 +201,10 @@ pub fn File(comptime T: type) type {
|
|||||||
inode: Inode,
|
inode: Inode,
|
||||||
path: []const u8,
|
path: []const u8,
|
||||||
) !void {
|
) !void {
|
||||||
_ = errs;
|
|
||||||
_ = pol;
|
|
||||||
|
|
||||||
wg.start();
|
wg.start();
|
||||||
defer wg.finish(); //TODO: When everthing is threaded, this will need to be handled by the threads, not here.
|
defer wg.finish(); //TODO: When everthing is threaded, this will need to be handled by the threads, not here.
|
||||||
switch (inode.hdr.type) {
|
switch (inode.hdr.type) {
|
||||||
.file => {
|
.file, .ext_file => {
|
||||||
var fil = try std.fs.cwd().createFile(path, .{});
|
var fil = try std.fs.cwd().createFile(path, .{});
|
||||||
defer fil.close();
|
defer fil.close();
|
||||||
var data: DataReader(T) = try .init(self.rdr, inode);
|
var data: DataReader(T) = try .init(self.rdr, inode);
|
||||||
@@ -239,10 +236,116 @@ pub fn File(comptime T: type) type {
|
|||||||
};
|
};
|
||||||
//TODO: update mtime.
|
//TODO: update mtime.
|
||||||
},
|
},
|
||||||
.dir => {
|
.dir, .ext_dir => {
|
||||||
std.fs.cwd().makeDir(path); //TODO: Check existence
|
std.fs.cwd().makeDir(path) catch |err| {
|
||||||
|
if (err != std.fs.Dir.MakeError.PathAlreadyExists) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var dir_block: u32 = 0;
|
||||||
|
var dir_offset: u16 = 0;
|
||||||
|
var dir_size: u32 = 0;
|
||||||
|
switch (inode.data) {
|
||||||
|
.dir => |d| {
|
||||||
|
dir_block = d.block;
|
||||||
|
dir_offset = d.offset;
|
||||||
|
dir_size = d.size;
|
||||||
|
},
|
||||||
|
.ext_dir => |d| {
|
||||||
|
dir_block = d.block;
|
||||||
|
dir_offset = d.offset;
|
||||||
|
dir_size = d.size;
|
||||||
|
},
|
||||||
|
else => unreachable,
|
||||||
|
}
|
||||||
|
var meta: MetadataReader(T) = .init(self.rdr.alloc, self.rdr.super.comp, self.rdr.rdr, dir_block + self.rdr.super.dir_start);
|
||||||
|
try meta.skip(dir_offset);
|
||||||
|
const entries = try dir.readDirectory(self.rdr.alloc, &meta, dir_size);
|
||||||
|
defer self.rdr.alloc.free(entries);
|
||||||
|
for (entries) |ent| {
|
||||||
|
defer ent.deinit(self.rdr.alloc);
|
||||||
|
var new_path: []u8 = undefined;
|
||||||
|
if (path[path.len - 1] == '/') {
|
||||||
|
new_path = self.rdr.alloc.alloc(u8, path.len + ent.name.len) catch |err| {
|
||||||
|
if (op.verbose) {
|
||||||
|
std.fmt.format(op.verbose_logger, "error allocating memory: {}\n", .{err}) catch {};
|
||||||
|
}
|
||||||
|
errs.append(err) catch {};
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
@memcpy(new_path[0..path.len], path);
|
||||||
|
@memcpy(new_path[path.len..], ent.name);
|
||||||
|
} else {
|
||||||
|
new_path = self.rdr.alloc.alloc(u8, path.len + ent.name.len + 1) catch |err| {
|
||||||
|
if (op.verbose) {
|
||||||
|
std.fmt.format(op.verbose_logger, "error allocating memory: {}\n", .{err}) catch {};
|
||||||
|
}
|
||||||
|
errs.append(err) catch {};
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
@memcpy(new_path[0..path.len], path);
|
||||||
|
new_path[path.len] = '/';
|
||||||
|
@memcpy(new_path[path.len + 1 ..], ent.name);
|
||||||
|
}
|
||||||
|
defer self.rdr.alloc.free(new_path);
|
||||||
|
|
||||||
|
meta = .init(self.rdr.alloc, self.rdr.super.comp, self.rdr.rdr, ent.block + self.rdr.super.inode_start);
|
||||||
|
meta.skip(ent.offset) catch |err| {
|
||||||
|
if (op.verbose) {
|
||||||
|
std.fmt.format(op.verbose_logger, "error reading inode: {}\n", .{err}) catch {};
|
||||||
|
}
|
||||||
|
errs.append(err) catch {};
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
const new_inode = Inode.init(&meta, self.rdr.alloc, self.rdr.super.block_size) catch |err| {
|
||||||
|
if (op.verbose) {
|
||||||
|
std.fmt.format(op.verbose_logger, "error reading inode: {}\n", .{err}) catch {};
|
||||||
|
}
|
||||||
|
errs.append(err) catch {};
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
defer new_inode.deinit(self.rdr.alloc);
|
||||||
|
self.extractInode(op, wg, errs, pol, new_inode, new_path) catch |err| {
|
||||||
|
if (op.verbose) {
|
||||||
|
std.fmt.format(op.verbose_logger, "error extracting {s}: {}\n", .{ new_path, err }) catch {};
|
||||||
|
}
|
||||||
|
errs.append(err) catch {};
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
var fil = std.fs.cwd().openDir(path, .{ .iterate = true }) catch |err| {
|
||||||
|
if (op.verbose) {
|
||||||
|
std.fmt.format(op.verbose_logger, "error openning {s} to set permissions: {}\n", .{ path, err }) catch {};
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
const fil_uid = self.rdr.id_table.get(inode.hdr.uid_idx) catch |err| {
|
||||||
|
if (op.verbose) {
|
||||||
|
std.fmt.format(op.verbose_logger, "error getting uid {} from table: {}\n", .{ inode.hdr.uid_idx, err }) catch {};
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
const fil_gid = self.rdr.id_table.get(inode.hdr.gid_idx) catch |err| {
|
||||||
|
if (op.verbose) {
|
||||||
|
std.fmt.format(op.verbose_logger, "error getting gid {} from table: {}\n", .{ inode.hdr.gid_idx, err }) catch {};
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
fil.chmod(inode.hdr.perm) catch |err| {
|
||||||
|
if (op.verbose) {
|
||||||
|
std.fmt.format(op.verbose_logger, "error chmod {s}: {}\n", .{ path, err }) catch {};
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
fil.chown(fil_uid, fil_gid) catch |err| {
|
||||||
|
if (op.verbose) {
|
||||||
|
std.fmt.format(op.verbose_logger, "error chmod {s}: {}\n", .{ path, err }) catch {};
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
};
|
||||||
},
|
},
|
||||||
.symlink => {},
|
// .symlink, .ext_symlink => {},
|
||||||
else => {
|
else => {
|
||||||
std.debug.print("TODO: {}\n", .{inode.hdr.type});
|
std.debug.print("TODO: {}\n", .{inode.hdr.type});
|
||||||
},
|
},
|
||||||
|
|||||||
+2
-3
@@ -51,8 +51,6 @@ const DecompCompletion = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn getBlock(self: *DecompCompletion, idx: usize) ?[]u8 {
|
fn getBlock(self: *DecompCompletion, idx: usize) ?[]u8 {
|
||||||
self.mut.lock();
|
|
||||||
defer self.mut.unlock();
|
|
||||||
const res = self.map.fetchSwapRemove(idx);
|
const res = self.map.fetchSwapRemove(idx);
|
||||||
if (res == null) return null;
|
if (res == null) return null;
|
||||||
return res.?.value;
|
return res.?.value;
|
||||||
@@ -216,7 +214,8 @@ pub fn DataReader(comptime T: type) type {
|
|||||||
self.completion.condWait();
|
self.completion.condWait();
|
||||||
if (self.completion.hasErrs()) break;
|
if (self.completion.hasErrs()) break;
|
||||||
if (comptime std.meta.hasFn(@TypeOf(wrt), "pwrite")) {
|
if (comptime std.meta.hasFn(@TypeOf(wrt), "pwrite")) {
|
||||||
for (self.completion.map.keys()) |k| {
|
for (self.completion.map.keys()) |_| {
|
||||||
|
const k = self.completion.map.keys()[0];
|
||||||
const blk = self.completion.getBlock(k).?;
|
const blk = self.completion.getBlock(k).?;
|
||||||
defer self.alloc.free(blk);
|
defer self.alloc.free(blk);
|
||||||
if (blk.len > 0) {
|
if (blk.len > 0) {
|
||||||
|
|||||||
+1
-1
@@ -25,7 +25,7 @@ test "OpenFile" {
|
|||||||
defer f.?.deinit();
|
defer f.?.deinit();
|
||||||
std.debug.print("{s}\n", .{f.?.name});
|
std.debug.print("{s}\n", .{f.?.name});
|
||||||
}
|
}
|
||||||
std.debug.print("Finished OpenFile test", .{});
|
std.debug.print("Finished OpenFile test\n", .{});
|
||||||
}
|
}
|
||||||
|
|
||||||
test "ExtractSingleFile" {
|
test "ExtractSingleFile" {
|
||||||
|
|||||||
Reference in New Issue
Block a user