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)!; };