blob: 6fc3b1750b41304c0e6c2cd617a482da33c1f6cb [file] [log] [blame]
// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <dirent.h>
#include <fcntl.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <utility>
#include "pave-lib.h"
#include "pave-logging.h"
namespace {
using paver::Arch;
using paver::Command;
using paver::Flags;
void PrintUsage() {
ERROR("install-disk-image <command> [options...]\n");
ERROR("Commands:\n");
ERROR(" install-bootloader : Install a BOOTLOADER partition to the device\n");
ERROR(" install-efi : Install an EFI partition to the device\n");
ERROR(" install-kernc : Install a KERN-C CrOS partition to the device\n");
ERROR(" install-zircona : Install a ZIRCON-A partition to the device\n");
ERROR(" install-zirconb : Install a ZIRCON-B partition to the device\n");
ERROR(" install-zirconr : Install a ZIRCON-R partition to the device\n");
ERROR(" install-vbmetaa : Install a VBMETA-A partition to the device\n");
ERROR(" install-vbmetab : Install a VBMETA-B partition to the device\n");
ERROR(" install-fvm : Install a sparse FVM to the device\n");
ERROR(" install-data-file : Install a file to DATA (--path required)\n");
ERROR(" wipe : Clean up the install disk\n");
ERROR("Options:\n");
ERROR(" --file <file>: Read from FILE instead of stdin\n");
ERROR(" --force: Install partition even if inappropriate for the device\n");
ERROR(" --path <path>: Install DATA file to path\n");
}
bool ParseFlags(int argc, char** argv, Flags* flags) {
#define SHIFT_ARGS \
do { \
argc--; \
argv++; \
} while (0)
// Parse command.
if (argc < 2) {
ERROR("install-disk-image needs a command\n");
return false;
}
SHIFT_ARGS;
if (!strcmp(argv[0], "install-bootloader")) {
flags->cmd = Command::kInstallBootloader;
} else if (!strcmp(argv[0], "install-efi")) {
flags->cmd = Command::kInstallEfi;
} else if (!strcmp(argv[0], "install-kernc")) {
flags->cmd = Command::kInstallKernc;
} else if (!strcmp(argv[0], "install-zircona")) {
flags->cmd = Command::kInstallZirconA;
} else if (!strcmp(argv[0], "install-zirconb")) {
flags->cmd = Command::kInstallZirconB;
} else if (!strcmp(argv[0], "install-zirconr")) {
flags->cmd = Command::kInstallZirconR;
} else if (!strcmp(argv[0], "install-vbmetaa")) {
flags->cmd = Command::kInstallVbMetaA;
} else if (!strcmp(argv[0], "install-vbmetab")) {
flags->cmd = Command::kInstallVbMetaB;
} else if (!strcmp(argv[0], "install-data-file")) {
flags->cmd = Command::kInstallDataFile;
} else if (!strcmp(argv[0], "install-fvm")) {
flags->cmd = Command::kInstallFvm;
} else if (!strcmp(argv[0], "wipe")) {
flags->cmd = Command::kWipe;
} else {
ERROR("Invalid command: %s\n", argv[0]);
return false;
}
SHIFT_ARGS;
// Parse options.
flags->force = false;
#if defined(__x86_64__)
flags->arch = Arch::X64;
#elif defined(__aarch64__)
flags->arch = Arch::ARM64;
#endif
flags->payload_fd.reset(STDIN_FILENO);
while (argc > 0) {
if (!strcmp(argv[0], "--file")) {
SHIFT_ARGS;
if (argc < 1) {
ERROR("'--file' argument requires a file\n");
return false;
}
flags->payload_fd.reset(open(argv[0], O_RDONLY));
if (!flags->payload_fd) {
ERROR("Couldn't open supplied file\n");
return false;
}
} else if (!strcmp(argv[0], "--path")) {
SHIFT_ARGS;
if (argc < 1) {
ERROR("'--path' argument requires a path\n");
return false;
}
flags->path = argv[0];
} else if (!strcmp(argv[0], "--force")) {
flags->force = true;
} else {
return false;
}
SHIFT_ARGS;
}
if (flags->cmd == Command::kInstallDataFile && flags->path == nullptr) {
ERROR("install-data-file requires --path\n");
return false;
}
return true;
#undef SHIFT_ARGS
}
} // namespace
int main(int argc, char** argv) {
Flags flags;
if (!(ParseFlags(argc, argv, &flags))) {
PrintUsage();
return -1;
}
return paver::RealMain(std::move(flags)) == ZX_OK ? 0 : 1;
}