1// Copyright 2017 The Fuchsia Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include <dirent.h> 6#include <fcntl.h> 7#include <stdbool.h> 8#include <stddef.h> 9#include <stdlib.h> 10#include <string.h> 11#include <unistd.h> 12 13#include "pave-logging.h" 14#include "pave-lib.h" 15 16namespace { 17 18using paver::Arch; 19using paver::Command; 20using paver::Flags; 21 22void PrintUsage() { 23 ERROR("install-disk-image <command> [options...]\n"); 24 ERROR("Commands:\n"); 25 ERROR(" install-bootloader : Install a BOOTLOADER partition to the device\n"); 26 ERROR(" install-efi : Install an EFI partition to the device\n"); 27 ERROR(" install-kernc : Install a KERN-C CrOS partition to the device\n"); 28 ERROR(" install-zircona : Install a ZIRCON-A partition to the device\n"); 29 ERROR(" install-zirconb : Install a ZIRCON-B partition to the device\n"); 30 ERROR(" install-zirconr : Install a ZIRCON-R partition to the device\n"); 31 ERROR(" install-fvm : Install a sparse FVM to the device\n"); 32 ERROR(" wipe : Clean up the install disk\n"); 33 ERROR("Options:\n"); 34 ERROR(" --file <file>: Read from FILE instead of stdin\n"); 35 ERROR(" --force: Install partition even if inappropriate for the device\n"); 36} 37 38bool ParseFlags(int argc, char** argv, Flags* flags) { 39#define SHIFT_ARGS \ 40 do { \ 41 argc--; \ 42 argv++; \ 43 } while (0) 44 45 // Parse command. 46 if (argc < 2) { 47 ERROR("install-disk-image needs a command\n"); 48 return false; 49 } 50 SHIFT_ARGS; 51 52 if (!strcmp(argv[0], "install-bootloader")) { 53 flags->cmd = Command::kInstallBootloader; 54 } else if (!strcmp(argv[0], "install-efi")) { 55 flags->cmd = Command::kInstallEfi; 56 } else if (!strcmp(argv[0], "install-kernc")) { 57 flags->cmd = Command::kInstallKernc; 58 } else if (!strcmp(argv[0], "install-zircona")) { 59 flags->cmd = Command::kInstallZirconA; 60 } else if (!strcmp(argv[0], "install-zirconb")) { 61 flags->cmd = Command::kInstallZirconB; 62 } else if (!strcmp(argv[0], "install-zirconr")) { 63 flags->cmd = Command::kInstallZirconR; 64 } else if (!strcmp(argv[0], "install-fvm")) { 65 flags->cmd = Command::kInstallFvm; 66 } else if (!strcmp(argv[0], "wipe")) { 67 flags->cmd = Command::kWipe; 68 } else { 69 ERROR("Invalid command: %s\n", argv[0]); 70 return false; 71 } 72 SHIFT_ARGS; 73 74 // Parse options. 75 flags->force = false; 76#if defined(__x86_64__) 77 flags->arch = Arch::X64; 78#elif defined(__aarch64__) 79 flags->arch = Arch::ARM64; 80#endif 81 flags->payload_fd.reset(STDIN_FILENO); 82 while (argc > 0) { 83 if (!strcmp(argv[0], "--file")) { 84 SHIFT_ARGS; 85 if (argc < 1) { 86 ERROR("'--file' argument requires a file\n"); 87 return false; 88 } 89 flags->payload_fd.reset(open(argv[0], O_RDONLY)); 90 if (!flags->payload_fd) { 91 ERROR("Couldn't open supplied file\n"); 92 return false; 93 } 94 } else if (!strcmp(argv[0], "--force")) { 95 flags->force = true; 96 } else { 97 return false; 98 } 99 SHIFT_ARGS; 100 } 101 return true; 102#undef SHIFT_ARGS 103} 104 105} // namespace 106 107int main(int argc, char** argv) { 108 Flags flags; 109 if (!(ParseFlags(argc, argv, &flags))) { 110 PrintUsage(); 111 return -1; 112 } 113 return paver::RealMain(fbl::move(flags)) == ZX_OK ? 0 : -1; 114} 115