/*
 * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 *
 * Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * Neither the name of ARM nor the names of its contributors may be used
 * to endorse or promote products derived from this software without specific
 * prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#include <sys/types.h>
#include <sys/stat.h>

#include <assert.h>
#include <errno.h>
#include <getopt.h>
#include <limits.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <openssl/sha.h>

#include "fiptool.h"
#include "firmware_image_package.h"
#include "tbbr_config.h"

#define OPT_TOC_ENTRY 0
#define OPT_PLAT_TOC_FLAGS 1

static image_desc_t *lookup_image_desc_from_uuid(const uuid_t *uuid);
static image_t *lookup_image_from_uuid(const uuid_t *uuid);
static int info_cmd(int argc, char *argv[]);
static void info_usage(void);
static int create_cmd(int argc, char *argv[]);
static void create_usage(void);
static int update_cmd(int argc, char *argv[]);
static void update_usage(void);
static int unpack_cmd(int argc, char *argv[]);
static void unpack_usage(void);
static int remove_cmd(int argc, char *argv[]);
static void remove_usage(void);
static int version_cmd(int argc, char *argv[]);
static void version_usage(void);
static int help_cmd(int argc, char *argv[]);
static void usage(void);

/* Available subcommands. */
static cmd_t cmds[] = {
	{ .name = "info",    .handler = info_cmd,    .usage = info_usage    },
	{ .name = "create",  .handler = create_cmd,  .usage = create_usage  },
	{ .name = "update",  .handler = update_cmd,  .usage = update_usage  },
	{ .name = "unpack",  .handler = unpack_cmd,  .usage = unpack_usage  },
	{ .name = "remove",  .handler = remove_cmd,  .usage = remove_usage  },
	{ .name = "version", .handler = version_cmd, .usage = version_usage },
	{ .name = "help",    .handler = help_cmd,    .usage = NULL          },
};

static image_desc_t *image_desc_head;
static size_t nr_image_descs;
static image_t *image_head;
static size_t nr_images;
static uuid_t uuid_null = { 0 };
static int verbose;

static void vlog(int prio, const char *msg, va_list ap)
{
	char *prefix[] = { "DEBUG", "WARN", "ERROR" };

	fprintf(stderr, "%s: ", prefix[prio]);
	vfprintf(stderr, msg, ap);
	fputc('\n', stderr);
}

static void log_dbgx(const char *msg, ...)
{
	va_list ap;

	va_start(ap, msg);
	vlog(LOG_DBG, msg, ap);
	va_end(ap);
}

static void log_warnx(const char *msg, ...)
{
	va_list ap;

	va_start(ap, msg);
	vlog(LOG_WARN, msg, ap);
	va_end(ap);
}

static void log_err(const char *msg, ...)
{
	char buf[512];
	va_list ap;

	va_start(ap, msg);
	snprintf(buf, sizeof(buf), "%s: %s", msg, strerror(errno));
	vlog(LOG_ERR, buf, ap);
	va_end(ap);
	exit(1);
}

static void log_errx(const char *msg, ...)
{
	va_list ap;

	va_start(ap, msg);
	vlog(LOG_ERR, msg, ap);
	va_end(ap);
	exit(1);
}

static char *xstrdup(const char *s, const char *msg)
{
	char *d;

	d = strdup(s);
	if (d == NULL)
		log_errx("strdup: %s", msg);
	return d;
}

static void *xmalloc(size_t size, const char *msg)
{
	void *d;

	d = malloc(size);
	if (d == NULL)
		log_errx("malloc: %s", msg);
	return d;
}

static image_desc_t *new_image_desc(const uuid_t *uuid,
    const char *name, const char *cmdline_name)
{
	image_desc_t *desc;

	desc = xmalloc(sizeof(*desc),
	    "failed to allocate memory for image descriptor");
	memcpy(&desc->uuid, uuid, sizeof(uuid_t));
	desc->name = xstrdup(name,
	    "failed to allocate memory for image name");
	desc->cmdline_name = xstrdup(cmdline_name,
	    "failed to allocate memory for image command line name");
	desc->action = DO_UNSPEC;
	desc->action_arg = NULL;
	return desc;
}

static void free_image_desc(image_desc_t *desc)
{
	free(desc->name);
	free(desc->cmdline_name);
	free(desc->action_arg);
	free(desc);
}

static void add_image_desc(image_desc_t *desc)
{
	assert(lookup_image_desc_from_uuid(&desc->uuid) == NULL);
	desc->next = image_desc_head;
	image_desc_head = desc;
	nr_image_descs++;
}

static void free_image_descs(void)
{
	image_desc_t *desc = image_desc_head, *tmp;

	while (desc != NULL) {
		tmp = desc->next;
		free_image_desc(desc);
		desc = tmp;
		nr_image_descs--;
	}
	assert(nr_image_descs == 0);
}

static void fill_image_descs(void)
{
	toc_entry_t *toc_entry;

	for (toc_entry = toc_entries;
	     toc_entry->cmdline_name != NULL;
	     toc_entry++) {
		image_desc_t *desc;

		desc = new_image_desc(&toc_entry->uuid,
		    toc_entry->name,
		    toc_entry->cmdline_name);
		add_image_desc(desc);
	}
}

static void add_image(image_t *image)
{
	assert(lookup_image_from_uuid(&image->uuid) == NULL);
	image->next = image_head;
	image_head = image;
	nr_images++;
}

static void free_image(image_t *image)
{
	free(image->buffer);
	free(image);
}

static void remove_image(image_t *image)
{
	image_t *tmp = image_head, *prev;

	if (tmp == image) {
		image_head = tmp->next;
		free_image(tmp);
	} else {
		while (tmp != NULL && tmp != image) {
			prev = tmp;
			tmp = tmp->next;
		}
		assert(tmp != NULL);
		prev->next = tmp->next;
		free_image(tmp);
	}
	nr_images--;
}

static void free_images(void)
{
	image_t *image = image_head, *tmp;

	while (image != NULL) {
		tmp = image->next;
		free_image(image);
		image = tmp;
		nr_images--;
	}
	assert(nr_images == 0);
}

static image_desc_t *lookup_image_desc_from_uuid(const uuid_t *uuid)
{
	image_desc_t *desc;

	for (desc = image_desc_head; desc != NULL; desc = desc->next)
		if (memcmp(&desc->uuid, uuid, sizeof(uuid_t)) == 0)
			return desc;
	return NULL;
}

static image_desc_t *lookup_image_desc_from_opt(const char *opt)
{
	image_desc_t *desc;

	for (desc = image_desc_head; desc != NULL; desc = desc->next)
		if (strcmp(desc->cmdline_name, opt) == 0)
			return desc;
	return NULL;
}

static image_t *lookup_image_from_uuid(const uuid_t *uuid)
{
	image_t *image;

	for (image = image_head; image != NULL; image = image->next)
		if (memcmp(&image->uuid, uuid, sizeof(uuid_t)) == 0)
			return image;
	return NULL;
}

static void uuid_to_str(char *s, size_t len, const uuid_t *u)
{
	assert(len >= (_UUID_STR_LEN + 1));

	snprintf(s, len, "%08X-%04X-%04X-%04X-%04X%04X%04X",
	    u->time_low,
	    u->time_mid,
	    u->time_hi_and_version,
	    ((uint16_t)u->clock_seq_hi_and_reserved << 8) | u->clock_seq_low,
	    ((uint16_t)u->node[0] << 8) | u->node[1],
	    ((uint16_t)u->node[2] << 8) | u->node[3],
	    ((uint16_t)u->node[4] << 8) | u->node[5]);
}

static void uuid_from_str(uuid_t *u, const char *s)
{
	int n;

	if (s == NULL)
		log_errx("UUID cannot be NULL");
	if (strlen(s) != _UUID_STR_LEN)
		log_errx("Invalid UUID: %s", s);

	n = sscanf(s,
	    "%8x-%4hx-%4hx-%2hhx%2hhx-%2hhx%2hhx%2hhx%2hhx%2hhx%2hhx",
	    &u->time_low, &u->time_mid, &u->time_hi_and_version,
	    &u->clock_seq_hi_and_reserved, &u->clock_seq_low, &u->node[0],
	    &u->node[1], &u->node[2], &u->node[3], &u->node[4], &u->node[5]);
	/*
	 * Given the format specifier above, we expect 11 items to be scanned
	 * for a properly formatted UUID.
	 */
	if (n != 11)
		log_errx("Invalid UUID: %s", s);
}

static int parse_fip(const char *filename, fip_toc_header_t *toc_header_out)
{
	struct stat st;
	FILE *fp;
	char *buf, *bufend;
	fip_toc_header_t *toc_header;
	fip_toc_entry_t *toc_entry;
	int terminated = 0;

	fp = fopen(filename, "r");
	if (fp == NULL)
		log_err("fopen %s", filename);

	if (fstat(fileno(fp), &st) == -1)
		log_err("fstat %s", filename);

	buf = xmalloc(st.st_size, "failed to load file into memory");
	if (fread(buf, 1, st.st_size, fp) != st.st_size)
		log_errx("Failed to read %s", filename);
	bufend = buf + st.st_size;
	fclose(fp);

	if (st.st_size < sizeof(fip_toc_header_t))
		log_errx("FIP %s is truncated", filename);

	toc_header = (fip_toc_header_t *)buf;
	toc_entry = (fip_toc_entry_t *)(toc_header + 1);

	if (toc_header->name != TOC_HEADER_NAME)
		log_errx("%s is not a FIP file", filename);

	/* Return the ToC header if the caller wants it. */
	if (toc_header_out != NULL)
		*toc_header_out = *toc_header;

	/* Walk through each ToC entry in the file. */
	while ((char *)toc_entry + sizeof(*toc_entry) - 1 < bufend) {
		image_t *image;
		image_desc_t *desc;

		/* Found the ToC terminator, we are done. */
		if (memcmp(&toc_entry->uuid, &uuid_null, sizeof(uuid_t)) == 0) {
			terminated = 1;
			break;
		}

		/*
		 * Build a new image out of the ToC entry and add it to the
		 * table of images.
		 */
		image = xmalloc(sizeof(*image),
		    "failed to allocate memory for image");
		memcpy(&image->uuid, &toc_entry->uuid, sizeof(uuid_t));
		image->buffer = xmalloc(toc_entry->size,
		    "failed to allocate image buffer, is FIP file corrupted?");
		/* Overflow checks before memory copy. */
		if (toc_entry->size > (uint64_t)-1 - toc_entry->offset_address)
			log_errx("FIP %s is corrupted", filename);
		if (toc_entry->size + toc_entry->offset_address > st.st_size)
			log_errx("FIP %s is corrupted", filename);

		memcpy(image->buffer, buf + toc_entry->offset_address,
		    toc_entry->size);
		image->size = toc_entry->size;

		/* If this is an unknown image, create a descriptor for it. */
		desc = lookup_image_desc_from_uuid(&image->uuid);
		if (desc == NULL) {
			char name[_UUID_STR_LEN + 1], filename[PATH_MAX];

			uuid_to_str(name, sizeof(name), &image->uuid);
			snprintf(filename, sizeof(filename), "%s%s",
			    name, ".bin");
			desc = new_image_desc(&image->uuid, name, "blob");
			desc->action = DO_UNPACK;
			desc->action_arg = xstrdup(filename,
			    "failed to allocate memory for blob filename");
			add_image_desc(desc);
		}

		add_image(image);

		toc_entry++;
	}

	if (terminated == 0)
		log_errx("FIP %s does not have a ToC terminator entry",
		    filename);
	free(buf);
	return 0;
}

static image_t *read_image_from_file(const uuid_t *uuid, const char *filename)
{
	struct stat st;
	image_t *image;
	FILE *fp;

	assert(uuid != NULL);

	fp = fopen(filename, "r");
	if (fp == NULL)
		log_err("fopen %s", filename);

	if (fstat(fileno(fp), &st) == -1)
		log_errx("fstat %s", filename);

	image = xmalloc(sizeof(*image), "failed to allocate memory for image");
	memcpy(&image->uuid, uuid, sizeof(uuid_t));
	image->buffer = xmalloc(st.st_size, "failed to allocate image buffer");
	if (fread(image->buffer, 1, st.st_size, fp) != st.st_size)
		log_errx("Failed to read %s", filename);
	image->size = st.st_size;

	fclose(fp);
	return image;
}

static int write_image_to_file(const image_t *image, const char *filename)
{
	FILE *fp;

	fp = fopen(filename, "w");
	if (fp == NULL)
		log_err("fopen");
	if (fwrite(image->buffer, 1, image->size, fp) != image->size)
		log_errx("Failed to write %s", filename);
	fclose(fp);
	return 0;
}

static struct option *add_opt(struct option *opts, size_t *nr_opts,
    const char *name, int has_arg, int val)
{
	opts = realloc(opts, (*nr_opts + 1) * sizeof(*opts));
	if (opts == NULL)
		log_err("realloc");
	opts[*nr_opts].name = name;
	opts[*nr_opts].has_arg = has_arg;
	opts[*nr_opts].flag = NULL;
	opts[*nr_opts].val = val;
	++*nr_opts;
	return opts;
}

static struct option *fill_common_opts(struct option *opts, size_t *nr_opts,
    int has_arg)
{
	image_desc_t *desc;

	for (desc = image_desc_head; desc != NULL; desc = desc->next)
		opts = add_opt(opts, nr_opts, desc->cmdline_name, has_arg,
		    OPT_TOC_ENTRY);
	return opts;
}

static void md_print(const unsigned char *md, size_t len)
{
	size_t i;

	for (i = 0; i < len; i++)
		printf("%02x", md[i]);
}

static int info_cmd(int argc, char *argv[])
{
	image_t *image;
	uint64_t image_offset;
	uint64_t image_size;
	fip_toc_header_t toc_header;

	if (argc != 2)
		info_usage();
	argc--, argv++;

	parse_fip(argv[0], &toc_header);

	if (verbose) {
		log_dbgx("toc_header[name]: 0x%llX",
		    (unsigned long long)toc_header.name);
		log_dbgx("toc_header[serial_number]: 0x%llX",
		    (unsigned long long)toc_header.serial_number);
		log_dbgx("toc_header[flags]: 0x%llX",
		    (unsigned long long)toc_header.flags);
	}

	image_offset = sizeof(fip_toc_header_t) +
	    (sizeof(fip_toc_entry_t) * (nr_images + 1));

	for (image = image_head; image != NULL; image = image->next) {
		image_desc_t *desc;

		desc = lookup_image_desc_from_uuid(&image->uuid);
		assert(desc != NULL);
		printf("%s: ", desc->name);
		image_size = image->size;
		printf("offset=0x%llX, size=0x%llX",
		    (unsigned long long)image_offset,
		    (unsigned long long)image_size);
		if (desc != NULL)
			printf(", cmdline=\"--%s\"",
			    desc->cmdline_name);
		if (verbose) {
			unsigned char md[SHA256_DIGEST_LENGTH];

			SHA256(image->buffer, image_size, md);
			printf(", sha256=");
			md_print(md, sizeof(md));
		}
		putchar('\n');
		image_offset += image_size;
	}

	free_images();
	return 0;
}

static void info_usage(void)
{
	printf("fiptool info FIP_FILENAME\n");
	exit(1);
}

static int pack_images(const char *filename, uint64_t toc_flags)
{
	FILE *fp;
	image_t *image;
	fip_toc_header_t *toc_header;
	fip_toc_entry_t *toc_entry;
	char *buf;
	uint64_t entry_offset, buf_size, payload_size;

	/* Calculate total payload size and allocate scratch buffer. */
	payload_size = 0;
	for (image = image_head; image != NULL; image = image->next)
		payload_size += image->size;

	buf_size = sizeof(fip_toc_header_t) +
	    sizeof(fip_toc_entry_t) * (nr_images + 1);
	buf = calloc(1, buf_size);
	if (buf == NULL)
		log_err("calloc");

	/* Build up header and ToC entries from the image table. */
	toc_header = (fip_toc_header_t *)buf;
	toc_header->name = TOC_HEADER_NAME;
	toc_header->serial_number = TOC_HEADER_SERIAL_NUMBER;
	toc_header->flags = toc_flags;

	toc_entry = (fip_toc_entry_t *)(toc_header + 1);

	entry_offset = buf_size;
	for (image = image_head; image != NULL; image = image->next) {
		memcpy(&toc_entry->uuid, &image->uuid, sizeof(uuid_t));
		toc_entry->offset_address = entry_offset;
		toc_entry->size = image->size;
		toc_entry->flags = 0;
		entry_offset += toc_entry->size;
		toc_entry++;
	}

	/* Append a null uuid entry to mark the end of ToC entries. */
	memcpy(&toc_entry->uuid, &uuid_null, sizeof(uuid_t));
	toc_entry->offset_address = entry_offset;
	toc_entry->size = 0;
	toc_entry->flags = 0;

	/* Generate the FIP file. */
	fp = fopen(filename, "w");
	if (fp == NULL)
		log_err("fopen %s", filename);

	if (verbose)
		log_dbgx("Metadata size: %zu bytes", buf_size);

	if (fwrite(buf, 1, buf_size, fp) != buf_size)
		log_errx("Failed to write image to %s", filename);
	free(buf);

	if (verbose)
		log_dbgx("Payload size: %zu bytes", payload_size);

	for (image = image_head; image != NULL; image = image->next)
		if (fwrite(image->buffer, 1, image->size, fp) != image->size)
			log_errx("Failed to write image to %s", filename);

	fclose(fp);
	return 0;
}

/*
 * This function is shared between the create and update subcommands.
 * The difference between the two subcommands is that when the FIP file
 * is created, the parsing of an existing FIP is skipped.  This results
 * in update_fip() creating the new FIP file from scratch because the
 * internal image table is not populated.
 */
static void update_fip(void)
{
	image_desc_t *desc;

	/* Add or replace images in the FIP file. */
	for (desc = image_desc_head; desc != NULL; desc = desc->next) {
		image_t *new_image, *old_image;

		if (desc->action != DO_PACK)
			continue;

		new_image = read_image_from_file(&desc->uuid,
		    desc->action_arg);
		old_image = lookup_image_from_uuid(&desc->uuid);
		if (old_image != NULL) {
			if (verbose) {
				log_dbgx("Replacing %s with %s",
				    desc->cmdline_name,
				    desc->action_arg);
			}
			remove_image(old_image);
			add_image(new_image);
		} else {
			if (verbose)
				log_dbgx("Adding image %s",
				    desc->action_arg);
			add_image(new_image);
		}
	}
}

static void parse_plat_toc_flags(const char *arg, unsigned long long *toc_flags)
{
	unsigned long long flags;
	char *endptr;

	errno = 0;
	flags = strtoull(arg, &endptr, 16);
	if (*endptr != '\0' || flags > UINT16_MAX || errno != 0)
		log_errx("Invalid platform ToC flags: %s", arg);
	/* Platform ToC flags is a 16-bit field occupying bits [32-47]. */
	*toc_flags |= flags << 32;
}

static void parse_blob_opt(char *arg, uuid_t *uuid, char *filename, size_t len)
{
	char *p;

	for (p = strtok(arg, ","); p != NULL; p = strtok(NULL, ",")) {
		if (strncmp(p, "uuid=", strlen("uuid=")) == 0) {
			p += strlen("uuid=");
			uuid_from_str(uuid, p);
		} else if (strncmp(p, "file=", strlen("file=")) == 0) {
			p += strlen("file=");
			snprintf(filename, len, "%s", p);
		}
	}
}

static int create_cmd(int argc, char *argv[])
{
	struct option *opts = NULL;
	size_t nr_opts = 0;
	unsigned long long toc_flags = 0;

	if (argc < 2)
		create_usage();

	opts = fill_common_opts(opts, &nr_opts, required_argument);
	opts = add_opt(opts, &nr_opts, "plat-toc-flags", required_argument,
	    OPT_PLAT_TOC_FLAGS);
	opts = add_opt(opts, &nr_opts, "blob", required_argument, 'b');
	opts = add_opt(opts, &nr_opts, NULL, 0, 0);

	while (1) {
		int c, opt_index = 0;

		c = getopt_long(argc, argv, "b:", opts, &opt_index);
		if (c == -1)
			break;

		switch (c) {
		case OPT_TOC_ENTRY: {
			image_desc_t *desc;

			desc = lookup_image_desc_from_opt(opts[opt_index].name);
			assert(desc != NULL);
			if (desc->action != DO_UNSPEC)
				free(desc->action_arg);
			desc->action = DO_PACK;
			desc->action_arg = xstrdup(optarg,
			    "failed to allocate memory for argument");
			break;
		}
		case OPT_PLAT_TOC_FLAGS:
			parse_plat_toc_flags(optarg, &toc_flags);
			break;
		case 'b': {
			char name[_UUID_STR_LEN + 1];
			char filename[PATH_MAX] = { 0 };
			uuid_t uuid = { 0 };
			image_desc_t *desc;

			parse_blob_opt(optarg, &uuid,
			    filename, sizeof(filename));

			if (memcmp(&uuid, &uuid_null, sizeof(uuid_t)) == 0 ||
			    filename[0] == '\0')
				create_usage();

			desc = lookup_image_desc_from_uuid(&uuid);
			if (desc != NULL) {
				if (desc->action != DO_UNSPEC)
					free(desc->action_arg);
				desc->action = DO_PACK;
				desc->action_arg = xstrdup(filename,
				    "failed to allocate memory for argument");
			} else {
				uuid_to_str(name, sizeof(name), &uuid);
				desc = new_image_desc(&uuid, name, "blob");
				desc->action = DO_PACK;
				desc->action_arg = xstrdup(filename,
				    "failed to allocate memory for argument");
				add_image_desc(desc);
			}
			break;
		}
		default:
			create_usage();
		}
	}
	argc -= optind;
	argv += optind;
	free(opts);

	if (argc == 0)
		create_usage();

	update_fip();

	pack_images(argv[0], toc_flags);
	free_images();
	return 0;
}

static void create_usage(void)
{
	toc_entry_t *toc_entry = toc_entries;

	printf("fiptool create [--blob uuid=...,file=...] "
	    "[--plat-toc-flags <value>] [opts] FIP_FILENAME\n");
	printf("  --blob uuid=...,file=...\tAdd an image with the given UUID "
	    "pointed to by file.\n");
	printf("  --plat-toc-flags <value>\t16-bit platform specific flag field "
	    "occupying bits 32-47 in 64-bit ToC header.\n");
	fputc('\n', stderr);
	printf("Specific images are packed with the following options:\n");
	for (; toc_entry->cmdline_name != NULL; toc_entry++)
		printf("  --%-16s FILENAME\t%s\n", toc_entry->cmdline_name,
		    toc_entry->name);
	exit(1);
}

static int update_cmd(int argc, char *argv[])
{
	struct option *opts = NULL;
	size_t nr_opts = 0;
	char outfile[PATH_MAX] = { 0 };
	fip_toc_header_t toc_header = { 0 };
	unsigned long long toc_flags = 0;
	int pflag = 0;

	if (argc < 2)
		update_usage();

	opts = fill_common_opts(opts, &nr_opts, required_argument);
	opts = add_opt(opts, &nr_opts, "blob", required_argument, 'b');
	opts = add_opt(opts, &nr_opts, "out", required_argument, 'o');
	opts = add_opt(opts, &nr_opts, "plat-toc-flags", required_argument,
	    OPT_PLAT_TOC_FLAGS);
	opts = add_opt(opts, &nr_opts, NULL, 0, 0);

	while (1) {
		int c, opt_index = 0;

		c = getopt_long(argc, argv, "b:o:", opts, &opt_index);
		if (c == -1)
			break;

		switch (c) {
		case OPT_TOC_ENTRY: {
			image_desc_t *desc;

			desc = lookup_image_desc_from_opt(opts[opt_index].name);
			assert(desc != NULL);
			if (desc->action != DO_UNSPEC)
				free(desc->action_arg);
			desc->action = DO_PACK;
			desc->action_arg = xstrdup(optarg,
			    "failed to allocate memory for argument");
			break;
		}
		case OPT_PLAT_TOC_FLAGS:
			parse_plat_toc_flags(optarg, &toc_flags);
			pflag = 1;
			break;
		case 'b': {
			char name[_UUID_STR_LEN + 1];
			char filename[PATH_MAX] = { 0 };
			uuid_t uuid = { 0 };
			image_desc_t *desc;

			parse_blob_opt(optarg, &uuid,
			    filename, sizeof(filename));

			if (memcmp(&uuid, &uuid_null, sizeof(uuid_t)) == 0 ||
			    filename[0] == '\0')
				update_usage();

			desc = lookup_image_desc_from_uuid(&uuid);
			if (desc != NULL) {
				if (desc->action != DO_UNSPEC)
					free(desc->action_arg);
				desc->action = DO_PACK;
				desc->action_arg = xstrdup(filename,
				    "failed to allocate memory for argument");
			} else {
				uuid_to_str(name, sizeof(name), &uuid);
				desc = new_image_desc(&uuid, name, "blob");
				desc->action = DO_PACK;
				desc->action_arg = xstrdup(filename,
				    "failed to allocate memory for argument");
				add_image_desc(desc);
			}
			break;
		}
		case 'o':
			snprintf(outfile, sizeof(outfile), "%s", optarg);
			break;
		default:
			update_usage();
		}
	}
	argc -= optind;
	argv += optind;
	free(opts);

	if (argc == 0)
		update_usage();

	if (outfile[0] == '\0')
		snprintf(outfile, sizeof(outfile), "%s", argv[0]);

	if (access(outfile, F_OK) == 0)
		parse_fip(argv[0], &toc_header);

	if (pflag)
		toc_header.flags &= ~(0xffffULL << 32);
	toc_flags = (toc_header.flags |= toc_flags);

	update_fip();

	pack_images(outfile, toc_flags);
	free_images();
	return 0;
}

static void update_usage(void)
{
	toc_entry_t *toc_entry = toc_entries;

	printf("fiptool update [--blob uuid=...,file=...] [--out FIP_FILENAME] "
	    "[--plat-toc-flags <value>] [opts] FIP_FILENAME\n");
	printf("  --blob uuid=...,file=...\tAdd or update an image "
	    "with the given UUID pointed to by file.\n");
	printf("  --out FIP_FILENAME\t\tSet an alternative output FIP file.\n");
	printf("  --plat-toc-flags <value>\t16-bit platform specific flag field "
	    "occupying bits 32-47 in 64-bit ToC header.\n");
	fputc('\n', stderr);
	printf("Specific images are packed with the following options:\n");
	for (; toc_entry->cmdline_name != NULL; toc_entry++)
		printf("  --%-16s FILENAME\t%s\n", toc_entry->cmdline_name,
		    toc_entry->name);
	exit(1);
}

static int unpack_cmd(int argc, char *argv[])
{
	struct option *opts = NULL;
	size_t nr_opts = 0;
	char outdir[PATH_MAX] = { 0 };
	image_desc_t *desc;
	int fflag = 0;
	int unpack_all = 1;

	if (argc < 2)
		unpack_usage();

	opts = fill_common_opts(opts, &nr_opts, required_argument);
	opts = add_opt(opts, &nr_opts, "blob", required_argument, 'b');
	opts = add_opt(opts, &nr_opts, "force", no_argument, 'f');
	opts = add_opt(opts, &nr_opts, "out", required_argument, 'o');
	opts = add_opt(opts, &nr_opts, NULL, 0, 0);

	while (1) {
		int c, opt_index = 0;

		c = getopt_long(argc, argv, "b:fo:", opts, &opt_index);
		if (c == -1)
			break;

		switch (c) {
		case OPT_TOC_ENTRY: {
			image_desc_t *desc;

			desc = lookup_image_desc_from_opt(opts[opt_index].name);
			assert(desc != NULL);
			if (desc->action != DO_UNSPEC)
				free(desc->action_arg);
			desc->action = DO_UNPACK;
			desc->action_arg = xstrdup(optarg,
			    "failed to allocate memory for argument");
			unpack_all = 0;
			break;
		}
		case 'b': {
			char name[_UUID_STR_LEN + 1];
			char filename[PATH_MAX] = { 0 };
			uuid_t uuid = { 0 };
			image_desc_t *desc;

			parse_blob_opt(optarg, &uuid,
			    filename, sizeof(filename));

			if (memcmp(&uuid, &uuid_null, sizeof(uuid_t)) == 0 ||
			    filename[0] == '\0')
				unpack_usage();

			desc = lookup_image_desc_from_uuid(&uuid);
			if (desc != NULL) {
				if (desc->action != DO_UNSPEC)
					free(desc->action_arg);
				desc->action = DO_UNPACK;
				desc->action_arg = xstrdup(filename,
				    "failed to allocate memory for argument");
			} else {
				uuid_to_str(name, sizeof(name), &uuid);
				desc = new_image_desc(&uuid, name, "blob");
				desc->action = DO_UNPACK;
				desc->action_arg = xstrdup(filename,
				    "failed to allocate memory for argument");
				add_image_desc(desc);
			}
			unpack_all = 0;
			break;
		}
		case 'f':
			fflag = 1;
			break;
		case 'o':
			snprintf(outdir, sizeof(outdir), "%s", optarg);
			break;
		default:
			unpack_usage();
		}
	}
	argc -= optind;
	argv += optind;
	free(opts);

	if (argc == 0)
		unpack_usage();

	parse_fip(argv[0], NULL);

	if (outdir[0] != '\0')
		if (chdir(outdir) == -1)
			log_err("chdir %s", outdir);

	/* Unpack all specified images. */
	for (desc = image_desc_head; desc != NULL; desc = desc->next) {
		char file[PATH_MAX];
		image_t *image;

		if (!unpack_all && desc->action != DO_UNPACK)
			continue;

		/* Build filename. */
		if (desc->action_arg == NULL)
			snprintf(file, sizeof(file), "%s.bin",
			    desc->cmdline_name);
		else
			snprintf(file, sizeof(file), "%s",
			    desc->action_arg);

		image = lookup_image_from_uuid(&desc->uuid);
		if (image == NULL) {
			if (!unpack_all)
				log_warnx("%s does not exist in %s",
				    file, argv[0]);
			continue;
		}

		if (access(file, F_OK) != 0 || fflag) {
			if (verbose)
				log_dbgx("Unpacking %s", file);
			write_image_to_file(image, file);
		} else {
			log_warnx("File %s already exists, use --force to overwrite it",
			    file);
		}
	}

	free_images();
	return 0;
}

static void unpack_usage(void)
{
	toc_entry_t *toc_entry = toc_entries;

	printf("fiptool unpack [--blob uuid=...,file=...] [--force] "
	    "[--out <path>] [opts] FIP_FILENAME\n");
	printf("  --blob uuid=...,file=...\tUnpack an image with the given UUID "
	    "to file.\n");
	printf("  --force\t\t\tIf the output file already exists, use --force to "
	    "overwrite it.\n");
	printf("  --out path\t\t\tSet the output directory path.\n");
	fputc('\n', stderr);
	printf("Specific images are unpacked with the following options:\n");
	for (; toc_entry->cmdline_name != NULL; toc_entry++)
		printf("  --%-16s FILENAME\t%s\n", toc_entry->cmdline_name,
		    toc_entry->name);
	fputc('\n', stderr);
	printf("If no options are provided, all images will be unpacked.\n");
	exit(1);
}

static int remove_cmd(int argc, char *argv[])
{
	struct option *opts = NULL;
	size_t nr_opts = 0;
	char outfile[PATH_MAX] = { 0 };
	fip_toc_header_t toc_header;
	image_desc_t *desc;
	int fflag = 0;

	if (argc < 2)
		remove_usage();

	opts = fill_common_opts(opts, &nr_opts, no_argument);
	opts = add_opt(opts, &nr_opts, "blob", required_argument, 'b');
	opts = add_opt(opts, &nr_opts, "force", no_argument, 'f');
	opts = add_opt(opts, &nr_opts, "out", required_argument, 'o');
	opts = add_opt(opts, &nr_opts, NULL, 0, 0);

	while (1) {
		int c, opt_index = 0;

		c = getopt_long(argc, argv, "b:fo:", opts, &opt_index);
		if (c == -1)
			break;

		switch (c) {
		case OPT_TOC_ENTRY: {
			image_desc_t *desc;

			desc = lookup_image_desc_from_opt(opts[opt_index].name);
			assert(desc != NULL);
			desc->action = DO_REMOVE;
			desc->action_arg = NULL;
			break;
		}
		case 'b': {
			char name[_UUID_STR_LEN + 1], filename[PATH_MAX];
			uuid_t uuid = { 0 };
			image_desc_t *desc;

			parse_blob_opt(optarg, &uuid,
			    filename, sizeof(filename));

			if (memcmp(&uuid, &uuid_null, sizeof(uuid_t)) == 0)
				remove_usage();

			desc = lookup_image_desc_from_uuid(&uuid);
			if (desc != NULL) {
				desc->action = DO_REMOVE;
				desc->action_arg = NULL;
			} else {
				uuid_to_str(name, sizeof(name), &uuid);
				desc = new_image_desc(&uuid, name, "blob");
				desc->action = DO_REMOVE;
				desc->action_arg = NULL;
				add_image_desc(desc);
			}
			break;
		}
		case 'f':
			fflag = 1;
			break;
		case 'o':
			snprintf(outfile, sizeof(outfile), "%s", optarg);
			break;
		default:
			remove_usage();
		}
	}
	argc -= optind;
	argv += optind;
	free(opts);

	if (argc == 0)
		remove_usage();

	if (outfile[0] != '\0' && access(outfile, F_OK) == 0 && !fflag)
		log_errx("File %s already exists, use --force to overwrite it",
		    outfile);

	if (outfile[0] == '\0')
		snprintf(outfile, sizeof(outfile), "%s", argv[0]);

	parse_fip(argv[0], &toc_header);

	for (desc = image_desc_head; desc != NULL; desc = desc->next) {
		image_t *image;

		if (desc->action != DO_REMOVE)
			continue;

		image = lookup_image_from_uuid(&desc->uuid);
		if (image != NULL) {
			if (verbose)
				log_dbgx("Removing %s",
				    desc->cmdline_name);
			remove_image(image);
		} else {
			log_warnx("%s does not exist in %s",
			    desc->cmdline_name, argv[0]);
		}
	}

	pack_images(outfile, toc_header.flags);
	free_images();
	return 0;
}

static void remove_usage(void)
{
	toc_entry_t *toc_entry = toc_entries;

	printf("fiptool remove [--blob uuid=...] [--force] "
	    "[--out FIP_FILENAME] [opts] FIP_FILENAME\n");
	printf("  --blob uuid=...\tRemove an image with the given UUID.\n");
	printf("  --force\t\tIf the output FIP file already exists, use --force to "
	    "overwrite it.\n");
	printf("  --out FIP_FILENAME\tSet an alternative output FIP file.\n");
	fputc('\n', stderr);
	printf("Specific images are removed with the following options:\n");
	for (; toc_entry->cmdline_name != NULL; toc_entry++)
		printf("  --%-16s\t%s\n", toc_entry->cmdline_name,
		    toc_entry->name);
	exit(1);
}

static int version_cmd(int argc, char *argv[])
{
#ifdef VERSION
	puts(VERSION);
#else
	/* If built from fiptool directory, VERSION is not set. */
	puts("Unknown version");
#endif
	return 0;
}

static void version_usage(void)
{
	printf("fiptool version\n");
	exit(1);
}

static int help_cmd(int argc, char *argv[])
{
	int i;

	if (argc < 2)
		usage();
	argc--, argv++;

	for (i = 0; i < NELEM(cmds); i++) {
		if (strcmp(cmds[i].name, argv[0]) == 0 &&
		    cmds[i].usage != NULL)
			cmds[i].usage();
	}
	if (i == NELEM(cmds))
		printf("No help for subcommand '%s'\n", argv[0]);
	return 0;
}

static void usage(void)
{
	printf("usage: [--verbose] fiptool <command> [<args>]\n");
	printf("Global options supported:\n");
	printf("  --verbose\tEnable verbose output for all commands.\n");
	fputc('\n', stderr);
	printf("Commands supported:\n");
	printf("  info\t\tList images contained in FIP.\n");
	printf("  create\tCreate a new FIP with the given images.\n");
	printf("  update\tUpdate an existing FIP with the given images.\n");
	printf("  unpack\tUnpack images from FIP.\n");
	printf("  remove\tRemove images from FIP.\n");
	printf("  version\tShow fiptool version.\n");
	printf("  help\t\tShow help for given command.\n");
	exit(1);
}

int main(int argc, char *argv[])
{
	int i, ret = 0;

	while (1) {
		int c, opt_index = 0;
		static struct option opts[] = {
			{ "verbose", no_argument, NULL, 'v' },
			{ NULL, no_argument, NULL, 0 }
		};

		/*
		 * Set POSIX mode so getopt stops at the first non-option
		 * which is the subcommand.
		 */
		c = getopt_long(argc, argv, "+v", opts, &opt_index);
		if (c == -1)
			break;

		switch (c) {
		case 'v':
			verbose = 1;
			break;
		default:
			usage();
		}
	}
	argc -= optind;
	argv += optind;
	/* Reset optind for subsequent getopt processing. */
	optind = 0;

	if (argc == 0)
		usage();

	fill_image_descs();
	for (i = 0; i < NELEM(cmds); i++) {
		if (strcmp(cmds[i].name, argv[0]) == 0) {
			ret = cmds[i].handler(argc, argv);
			break;
		}
	}
	if (i == NELEM(cmds))
		usage();
	free_image_descs();
	return ret;
}
