diff options
Diffstat (limited to 'cmd/convert/convert.ha')
| -rw-r--r-- | cmd/convert/convert.ha | 91 |
1 files changed, 66 insertions, 25 deletions
diff --git a/cmd/convert/convert.ha b/cmd/convert/convert.ha index 807ae7f..b3cfd38 100644 --- a/cmd/convert/convert.ha +++ b/cmd/convert/convert.ha @@ -1,36 +1,76 @@ use fmt; - -use cmd; -use mbr; -use gpt; -use sector; - use os; use io; use fs; use strings; use errors; use rt; +use getopt; + +use cmd; +use mbr; +use gpt; +use sector; + -export fn convert(vol: str, args: []str) void = { - if (len(args) < 2) { - fmt::fatalf("convert: needs disk"); +export fn convert(args: []str) void = { + let nombr = false; + let notranslation = false; + let nohybrid = false; + + const c = getopt::parse(args, + ('m', "do not overwrite the MBR bootstrap"), + ('t', "do not translate partitions to GPT"), + ('H', "do not create a hybrid MBR"), + "disk file" + ); + defer getopt::finish(&c); + + for (let i = 0z; i < len(c.opts); i += 1) { + const opt = c.opts[i]; + switch (opt.0) { + case 'm' => nombr = true; + case 't' => notranslation = true; + case 'H' => nohybrid = true; + }; + }; + + if (len(c.args) < 1) + fmt::fatalf("gpt.convert: need a disk file"); + + let sourcefd = match (os::open(c.args[0], fs::flags::RDONLY)) { + case let f: io::file => + yield f; + case => fmt::fatalf("gpt.convert: could not open file {}", args[1]); }; + defer io::close(sourcefd)!; - let source = os::open(args[1], fs::flags::RDONLY)!; - defer io::close(source)!; + const source = mbr::from(sourcefd)!; + // XXX need mbr::finish() - const source = mbr::from(source)!; + let fd = cmd::openfile(); + defer io::close(fd)!; - const vol = cmd::openvol(vol); - let vol = gpt::from(vol)!; + let vol = cmd::opengpt(fd); defer { + vol.mbr.entries[3] = mbr::entry { + part_type = 0xEE, + lba_begin = 0, + length = -1: u32, + ... + }; + gpt::chksums(vol); gpt::commit(vol)!; gpt::finish(vol); }; - rt::memcpy(vol.mbr, source.bootsector, size(mbr::bootsector)); + if (!nombr) + rt::memcpy(vol.mbr, source.bootsector, size(mbr::bootsector)); + + if (notranslation) + return; + for (let i = 0z; i < 4; i += 1) { const entry = &source.bootsector.entries[i]; if (entry.lba_begin == 0 && entry.length == 0) @@ -39,20 +79,21 @@ export fn convert(vol: str, args: []str) void = { const reader = mbr::partstream_reader(source, entry)!; const partlength = entry.length; - const part = gpt::allocate(vol, partlength) as *gpt::entry; + const part = match (gpt::allocate(vol, partlength)) { + case let e: *gpt::entry => + yield e; + case => + fmt::errorfln("gpt.convert: could not allocate size needed for MBR partition {}", i)!; + continue; + }; const writer = gpt::partstream_writer(vol, part)!; io::copy(&writer, &reader)!; - vol.mbr.entries[i].lba_begin = part.lba_begin: u32; - vol.mbr.entries[i].length = (part.lba_end - part.lba_begin + 1): u32; - }; - - vol.mbr.entries[3] = mbr::entry { - part_type = 0xEE, - lba_begin = 0, - length = -1: u32, - ... + if (!nohybrid) { + vol.mbr.entries[i].lba_begin = part.lba_begin: u32; + vol.mbr.entries[i].length = (part.lba_end - part.lba_begin + 1): u32; + }; }; }; |
