diff --git a/README.md b/README.md new file mode 100644 index 0000000..f9fa655 --- /dev/null +++ b/README.md @@ -0,0 +1,7 @@ +# zig-squashfs + +This is my experiments to learn Zig. Might amount to something. Might not. + +## Current State + +Kinda works as a library, but currently has known memory leaks. `unsquashfs` is missing a lot of features (and will probably never match the official unsquashfs). Extraction is stupidly slow and uses too many resources. diff --git a/build.zig b/build.zig index 688bfb5..0d51302 100644 --- a/build.zig +++ b/build.zig @@ -2,13 +2,17 @@ const std = @import("std"); pub fn build(b: *std.Build) void { const target = b.standardTargetOptions(.{}); - const optimize = b.standardOptimizeOption(.{}); + const optimize = b.standardOptimizeOption(.{ .preferred_optimize_mode = .ReleaseFast }); + const linkage: std.builtin.LinkMode = .static; // TODO: Add argument to set link mode. const mod = b.addModule("zig_squashfs", .{ .root_source_file = b.path("src/root.zig"), .target = target, + .optimize = optimize, + // .imports = &.{}, }); const exe = b.addExecutable(.{ .name = "unsquashfs", + .linkage = linkage, .root_module = b.createModule(.{ .root_source_file = b.path("src/bin/unsquashfs.zig"), .target = target, diff --git a/src/bin/unsquashfs.zig b/src/bin/unsquashfs.zig index 43b93a1..4ff213e 100644 --- a/src/bin/unsquashfs.zig +++ b/src/bin/unsquashfs.zig @@ -1,5 +1,62 @@ const std = @import("std"); +const Writer = std.Io.Writer; const squashfs = @import("zig_squashfs"); -pub fn main() !void {} +//TODO: Add more options +const help_mgs = + \\Usage: unsquashfs [options] + \\ + \\Options: + \\ -o Start reading the archive at the given offset. + \\ -d Extract to the given location instead of "squashfs-root" +; + +const errors = error{InvalidArguments}; + +var archive: []const u8 = ""; +var extLoc: []const u8 = "squashfs-root"; +var offset: u64 = 0; + +pub fn main() !void { + const alloc = std.heap.smp_allocator; + var stdout = std.fs.File.stdout(); + var out = stdout.writer(&[0]u8{}); + defer out.interface.flush() catch {}; + try handleArgs(alloc, &out.interface); + var fil: std.fs.File = try std.fs.cwd().openFile(archive, .{}); //TODO: Handle error gracefully. + defer fil.close(); + var arc: squashfs.Archive = try .initAdvanced(alloc, fil, offset, try std.Thread.getCpuCount(), 0); //TODO: Update when memory size matters. //TODO: Handle error gracefully. + defer arc.deinit(); + try arc.extract(extLoc, .Default); //TODO: Handle error gracefully. +} + +fn handleArgs(alloc: std.mem.Allocator, out: *Writer) !void { + var args = try std.process.argsWithAllocator(alloc); + defer args.deinit(); + while (args.next()) |arg| { + if (std.mem.eql(u8, arg, "-o")) { + const nxt = args.next(); + if (nxt == null or nxt.?.len == 0) { + try out.print("-o must be followed by a number\n", .{}); + return errors.InvalidArguments; + } + offset = std.fmt.parseInt(u64, nxt.?, 10) catch { + try out.print("-o must be followed by a number\n", .{}); + return errors.InvalidArguments; + }; + } else if (std.mem.eql(u8, arg, "-d")) { + const nxt = args.next(); + if (nxt == null or nxt.?.len == 0) { + try out.print("-d must be followed by a location\n", .{}); + return errors.InvalidArguments; + } + extLoc = nxt.?; + } + if (archive.len > 0) { + try out.print("you can only provide one file at a time\n", .{}); + return errors.InvalidArguments; + } + archive = arg; + } +} diff --git a/src/root.zig b/src/root.zig index 9f4c6cd..78c33c4 100644 --- a/src/root.zig +++ b/src/root.zig @@ -1 +1 @@ -const Archive = @import("archive.zig"); +pub const Archive = @import("archive.zig");