diff options
Diffstat (limited to 'cmd/part')
| -rw-r--r-- | cmd/part/part.ha | 126 |
1 files changed, 126 insertions, 0 deletions
diff --git a/cmd/part/part.ha b/cmd/part/part.ha new file mode 100644 index 0000000..a4b114f --- /dev/null +++ b/cmd/part/part.ha @@ -0,0 +1,126 @@ +use fmt; +use io; +use os; +use strconv; + +use gpt; +use cmd; + +export fn part(vol: str, args: []str) void = { + if (len(args) <= 1) { + partlist(vol, args[1..]); + return; + }; + + match (strconv::stou(args[1])) { + case let i: uint => + const vol = cmd::opengpt(vol); + defer gpt::finish(vol); + partno(vol, i, args[2..]); + return; + case => + yield; + }; + + switch (args[1]) { + case "new" => partnew(vol, args[1..]); + case "list" => partlist(vol, args[1..]); + }; +}; + +export fn partnew(vol: str, args: []str) void = { + const vol = cmd::opengpt(vol); + defer { + gpt::chksums(vol); + gpt::commit(vol)!; + gpt::finish(vol); + }; + + const sz = 71z; + + const entry = match (gpt::allocate(vol, sz)) { + case let e: *gpt::entry => + yield e; + case => + fmt::fatalf("gpt.part: could not allocate entry of size {}", sz); + }; +}; + +export fn partlist(vol: str, args: []str) void = { + const vol = cmd::opengpt(vol); + defer gpt::finish(vol); + const header = vol.primary.header; + const entries = vol.primary.entries; + + for (let i = 0z; i < header.entries_len; i += 1) { + const entry = &entries[i]; + if (entry.lba_begin == 0 && entry.lba_end == 0) + continue; + + partinfo(vol, i); + }; +}; + +fn partinfo(vol: *gpt::gpt, i: size) void = { + const entry = &vol.primary.entries[i]; + + fmt::printfln("# Partition {}", i)!; + fmt::printfln("entries[{}].part_type([{},{}])", i, entry.part_type[0], entry.part_type[1])!; + fmt::printfln("entries[{}].part([{},{}])", i, entry.part[0], entry.part[1])!; + fmt::printfln("entries[{}].lba_begin({})", i, entry.lba_begin)!; + fmt::printfln("entries[{}].lba_end({})", i, entry.lba_end)!; + fmt::printfln("entries[{}].attributes({})", i, entry.attributes)!; + + // XXX name +}; + +fn partno(vol: *gpt::gpt, i: size, args: []str) void = { + const header = vol.primary.header; + + if (i >= header.entries_len) + fmt::fatalf("gpt.part: invalid partition number"); + + if (len(args) == 0) { + partinfo(vol, i); + return; + }; + + switch (args[0]) { + case "fill" => + partfill(vol, i); + case "dump" => + partdump(vol, i); + }; +}; + +fn partfill(vol: *gpt::gpt, i: size) void = { + const entry = &vol.primary.entries[i]; + + if (entry.lba_begin == 0 && entry.lba_end == 0) + fmt::fatalf("gpt.part: partition {} is not allocated", i); + + const writer = match (gpt::partstream_writer(vol, entry)) { + case let l: io::limitstream => + yield l; + case => + fmt::fatalf("gpt.part: could not create a writing stream"); + }; + + io::copy(&writer, os::stdin)!; +}; + +fn partdump(vol: *gpt::gpt, i: size) void = { + const entry = &vol.primary.entries[i]; + + if (entry.lba_begin == 0 && entry.lba_end == 0) + fmt::fatalf("gpt.part: partition {} is not allocated", i); + + const reader = match (gpt::partstream_reader(vol, entry)) { + case let l: io::limitstream => + yield l; + case => + fmt::fatalf("gpt.part: could not create a reading stream"); + }; + + io::copy(os::stdout, &reader)!; +}; |
