// SPDX-License-Identifier: GPL-2.0
/*
 * Boot config tool for initrd image
 */
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <endian.h>
#include <assert.h>

#include <linux/bootconfig.h>

#define pr_err(fmt, ...) fprintf(stderr, fmt, ##__VA_ARGS__)

/* Bootconfig footer is [size][csum][BOOTCONFIG_MAGIC]. */
#define BOOTCONFIG_FOOTER_SIZE	\
	(sizeof(uint32_t) * 2 + BOOTCONFIG_MAGIC_LEN)

static int xbc_show_value(struct xbc_node *node, bool semicolon)
{
	const char *val, *eol;
	char q;
	int i = 0;

	eol = semicolon ? ";\n" : "\n";
	xbc_array_for_each_value(node, val) {
		if (strchr(val, '"'))
			q = '\'';
		else
			q = '"';
		printf("%c%s%c%s", q, val, q, xbc_node_is_array(node) ? ", " : eol);
		i++;
	}
	return i;
}

static void xbc_show_compact_tree(void)
{
	struct xbc_node *node, *cnode = NULL, *vnode;
	int depth = 0, i;

	node = xbc_root_node();
	while (node && xbc_node_is_key(node)) {
		for (i = 0; i < depth; i++)
			printf("\t");
		if (!cnode)
			cnode = xbc_node_get_child(node);
		while (cnode && xbc_node_is_key(cnode) && !cnode->next) {
			vnode = xbc_node_get_child(cnode);
			/*
			 * If @cnode has value and subkeys, this
			 * should show it as below.
			 *
			 * key(@node) {
			 *      key(@cnode) = value;
			 *      key(@cnode) {
			 *          subkeys;
			 *      }
			 * }
			 */
			if (vnode && xbc_node_is_value(vnode) && vnode->next)
				break;
			printf("%s.", xbc_node_get_data(node));
			node = cnode;
			cnode = vnode;
		}
		if (cnode && xbc_node_is_key(cnode)) {
			printf("%s {\n", xbc_node_get_data(node));
			depth++;
			node = cnode;
			cnode = NULL;
			continue;
		} else if (cnode && xbc_node_is_value(cnode)) {
			printf("%s = ", xbc_node_get_data(node));
			xbc_show_value(cnode, true);
			/*
			 * If @node has value and subkeys, continue
			 * looping on subkeys with same node.
			 */
			if (cnode->next) {
				cnode = xbc_node_get_next(cnode);
				continue;
			}
		} else {
			printf("%s;\n", xbc_node_get_data(node));
		}
		cnode = NULL;

		if (node->next) {
			node = xbc_node_get_next(node);
			continue;
		}
		while (!node->next) {
			node = xbc_node_get_parent(node);
			if (!node)
				return;
			if (!xbc_node_get_child(node)->next)
				continue;
			if (depth) {
				depth--;
				for (i = 0; i < depth; i++)
					printf("\t");
				printf("}\n");
			}
		}
		node = xbc_node_get_next(node);
	}
}

static void xbc_show_list(void)
{
	char key[XBC_KEYLEN_MAX];
	struct xbc_node *leaf;
	const char *val;
	int ret;

	xbc_for_each_key_value(leaf, val) {
		ret = xbc_node_compose_key(leaf, key, XBC_KEYLEN_MAX);
		if (ret < 0) {
			fprintf(stderr, "Failed to compose key %d\n", ret);
			break;
		}
		printf("%s = ", key);
		if (!val || val[0] == '\0') {
			printf("\"\"\n");
			continue;
		}
		xbc_show_value(xbc_node_get_child(leaf), false);
	}
}

#define PAGE_SIZE	4096

static int load_xbc_fd(int fd, char **buf, int size)
{
	int ret;

	if (size < 0 || size > XBC_DATA_MAX)
		return -EINVAL;

	*buf = malloc(size + 1);
	if (!*buf)
		return -ENOMEM;

	ret = read(fd, *buf, size);
	if (ret < 0)
		return -errno;
	(*buf)[size] = '\0';

	return ret;
}

/* Return the read size or -errno */
static int load_xbc_file(const char *path, char **buf)
{
	struct stat stat;
	int fd, ret;

	fd = open(path, O_RDONLY);
	if (fd < 0)
		return -errno;
	ret = fstat(fd, &stat);
	if (ret < 0) {
		ret = -errno;
		close(fd);
		return ret;
	}

	if (stat.st_size > XBC_DATA_MAX) {
		pr_err("%s size is too big\n", path);
		ret = -E2BIG;
		close(fd);
		return ret;
	}

	ret = load_xbc_fd(fd, buf, stat.st_size);

	close(fd);

	return ret;
}

static int pr_errno(const char *msg, int err)
{
	pr_err("%s: %d\n", msg, err);
	return err;
}

static int load_xbc_from_initrd(int fd, char **buf)
{
	struct stat stat;
	int ret;
	uint32_t size = 0, csum = 0, rcsum;
	char magic[BOOTCONFIG_MAGIC_LEN];
	const char *msg;

	ret = fstat(fd, &stat);
	if (ret < 0)
		return -errno;

	if (stat.st_size < BOOTCONFIG_FOOTER_SIZE)
		return 0;

	if (lseek(fd, -(off_t)BOOTCONFIG_MAGIC_LEN, SEEK_END) < 0)
		return pr_errno("Failed to lseek for magic", -errno);

	if (read(fd, magic, BOOTCONFIG_MAGIC_LEN) < 0)
		return pr_errno("Failed to read", -errno);

	/* Check the bootconfig magic bytes */
	if (memcmp(magic, BOOTCONFIG_MAGIC, BOOTCONFIG_MAGIC_LEN) != 0)
		return 0;

	if (lseek(fd, -(off_t)BOOTCONFIG_FOOTER_SIZE, SEEK_END) < 0)
		return pr_errno("Failed to lseek for size", -errno);

	if (read(fd, &size, sizeof(uint32_t)) < 0)
		return pr_errno("Failed to read size", -errno);
	size = le32toh(size);

	if (read(fd, &csum, sizeof(uint32_t)) < 0)
		return pr_errno("Failed to read checksum", -errno);
	csum = le32toh(csum);

	/* Wrong size error  */
	if (size > XBC_DATA_MAX ||
	    size > stat.st_size - BOOTCONFIG_FOOTER_SIZE) {
		pr_err("bootconfig size is too big\n");
		return -E2BIG;
	}

	if (lseek(fd, stat.st_size - (size + BOOTCONFIG_FOOTER_SIZE),
		  SEEK_SET) < 0)
		return pr_errno("Failed to lseek", -errno);

	ret = load_xbc_fd(fd, buf, size);
	if (ret < 0)
		return ret;

	/* Wrong Checksum */
	rcsum = xbc_calc_checksum(*buf, size);
	if (csum != rcsum) {
		pr_err("checksum error: %u != %u\n", csum, rcsum);
		return -EINVAL;
	}

	ret = xbc_init(*buf, size, &msg, NULL);
	/* Wrong data */
	if (ret < 0) {
		pr_err("parse error: %s.\n", msg);
		return ret;
	}

	return size;
}

static void show_xbc_error(const char *data, const char *msg, int pos)
{
	int lin = 1, col, i;

	if (pos < 0) {
		pr_err("Error: %s.\n", msg);
		return;
	}

	/* Note that pos starts from 0 but lin and col should start from 1. */
	col = pos + 1;
	for (i = 0; i < pos; i++) {
		if (data[i] == '\n') {
			lin++;
			col = pos - i;
		}
	}
	pr_err("Parse Error: %s at %d:%d\n", msg, lin, col);

}

static int init_xbc_with_error(char *buf, int len)
{
	char *copy = strdup(buf);
	const char *msg;
	int ret, pos;

	if (!copy)
		return -ENOMEM;

	ret = xbc_init(buf, len, &msg, &pos);
	if (ret < 0)
		show_xbc_error(copy, msg, pos);
	free(copy);

	return ret;
}

static int show_xbc_kernel_cmdline(void)
{
	struct xbc_node *root;
	char *buf = NULL;
	int len, ret;

	root = xbc_find_node("kernel");
	if (!root)
		return 0;	/* no kernel.* keys: emit empty output */

	len = xbc_snprint_cmdline(NULL, 0, root);
	if (len < 0) {
		pr_err("Failed to size cmdline output: %d\n", len);
		return len;
	}
	if (len == 0)
		return 0;

	buf = malloc(len + 1);
	if (!buf)
		return -ENOMEM;

	ret = xbc_snprint_cmdline(buf, len + 1, root);
	if (ret < 0) {
		pr_err("Failed to render cmdline output: %d\n", ret);
		free(buf);
		return ret;
	}

	fputs(buf, stdout);
	free(buf);
	return 0;
}

static int show_xbc(const char *path, bool list, bool render_cmdline)
{
	int ret, fd;
	char *buf = NULL;
	struct stat st;

	ret = stat(path, &st);
	if (ret < 0) {
		ret = -errno;
		pr_err("Failed to stat %s: %d\n", path, ret);
		return ret;
	}

	fd = open(path, O_RDONLY);
	if (fd < 0) {
		ret = -errno;
		pr_err("Failed to open initrd %s: %d\n", path, ret);
		return ret;
	}

	ret = load_xbc_from_initrd(fd, &buf);
	close(fd);
	if (ret < 0) {
		pr_err("Failed to load a boot config from initrd: %d\n", ret);
		goto out;
	}
	/* Assume a bootconfig file if it is enough small */
	if (ret == 0 && st.st_size <= XBC_DATA_MAX) {
		ret = load_xbc_file(path, &buf);
		if (ret < 0) {
			pr_err("Failed to load a boot config: %d\n", ret);
			goto out;
		}
		if (init_xbc_with_error(buf, ret) < 0)
			goto out;
	}
	if (render_cmdline)
		ret = show_xbc_kernel_cmdline();
	else if (list)
		xbc_show_list();
	else
		xbc_show_compact_tree();
	if (ret > 0)
		ret = 0;
out:
	free(buf);

	return ret;
}

static int delete_xbc(const char *path)
{
	struct stat stat;
	int ret = 0, fd, size;
	char *buf = NULL;

	fd = open(path, O_RDWR);
	if (fd < 0) {
		ret = -errno;
		pr_err("Failed to open initrd %s: %d\n", path, ret);
		return ret;
	}

	size = load_xbc_from_initrd(fd, &buf);
	if (size < 0) {
		ret = size;
		pr_err("Failed to load a boot config from initrd: %d\n", ret);
	} else if (size > 0) {
		ret = fstat(fd, &stat);
		if (!ret)
			ret = ftruncate(fd, stat.st_size
					- size - BOOTCONFIG_FOOTER_SIZE);
		if (ret)
			ret = -errno;
	} /* Ignore if there is no boot config in initrd */

	close(fd);
	free(buf);

	return ret;
}

static int apply_xbc(const char *path, const char *xbc_path)
{
	struct {
		uint32_t size;
		uint32_t csum;
		char magic[BOOTCONFIG_MAGIC_LEN];
	} footer;
	char *buf, *data;
	size_t total_size;
	struct stat stat;
	const char *msg;
	uint32_t size, csum;
	int pos, pad;
	int ret, fd;

	ret = load_xbc_file(xbc_path, &buf);
	if (ret < 0) {
		pr_err("Failed to load %s : %d\n", xbc_path, ret);
		return ret;
	}
	size = strlen(buf) + 1;
	csum = xbc_calc_checksum(buf, size);

	/* Backup the bootconfig data */
	data = calloc(size + BOOTCONFIG_ALIGN + BOOTCONFIG_FOOTER_SIZE, 1);
	if (!data) {
		free(buf);
		return -ENOMEM;
	}
	memcpy(data, buf, size);

	/* Check the data format */
	ret = xbc_init(buf, size, &msg, &pos);
	if (ret < 0) {
		show_xbc_error(data, msg, pos);
		free(data);
		free(buf);

		return ret;
	}
	printf("Apply %s to %s\n", xbc_path, path);
	xbc_get_info(&ret, NULL);
	printf("\tNumber of nodes: %d\n", ret);
	printf("\tSize: %u bytes\n", (unsigned int)size);
	printf("\tChecksum: %u\n", (unsigned int)csum);

	/* TODO: Check the options by schema */
	xbc_exit();
	free(buf);

	/* Remove old boot config if exists */
	ret = delete_xbc(path);
	if (ret < 0) {
		pr_err("Failed to delete previous boot config: %d\n", ret);
		free(data);
		return ret;
	}

	/* Apply new one */
	fd = open(path, O_RDWR | O_APPEND);
	if (fd < 0) {
		ret = -errno;
		pr_err("Failed to open %s: %d\n", path, ret);
		free(data);
		return ret;
	}
	/* TODO: Ensure the @path is initramfs/initrd image */
	if (fstat(fd, &stat) < 0) {
		ret = -errno;
		pr_err("Failed to get the size of %s\n", path);
		goto out;
	}

	/* To align up the total size to BOOTCONFIG_ALIGN, get padding size */
	total_size = stat.st_size + size + BOOTCONFIG_FOOTER_SIZE;
	pad = ((total_size + BOOTCONFIG_ALIGN - 1) & (~BOOTCONFIG_ALIGN_MASK)) - total_size;
	size += pad;

	/* Add a footer */
	footer.size = htole32(size);
	footer.csum = htole32(csum);
	memcpy(footer.magic, BOOTCONFIG_MAGIC, BOOTCONFIG_MAGIC_LEN);
	static_assert(sizeof(footer) == BOOTCONFIG_FOOTER_SIZE);
	memcpy(data + size, &footer, BOOTCONFIG_FOOTER_SIZE);

	total_size = size + BOOTCONFIG_FOOTER_SIZE;

	ret = write(fd, data, total_size);
	if (ret < total_size) {
		if (ret < 0)
			ret = -errno;
		pr_err("Failed to apply a boot config: %d\n", ret);
		if (ret >= 0)
			goto out_rollback;
	} else
		ret = 0;

out:
	close(fd);
	free(data);

	return ret;

out_rollback:
	/* Map the partial write to -ENOSPC */
	if (ret >= 0)
		ret = -ENOSPC;
	if (ftruncate(fd, stat.st_size) < 0) {
		ret = -errno;
		pr_err("Failed to rollback the write error: %d\n", ret);
		pr_err("The initrd %s may be corrupted. Recommend to rebuild.\n", path);
	}
	goto out;
}

static int usage(void)
{
	printf("Usage: bootconfig [OPTIONS] <INITRD>\n"
		"Or     bootconfig <CONFIG>\n"
		" Apply, delete or show boot config to initrd.\n"
		" Options:\n"
		"		-a <config>: Apply boot config to initrd\n"
		"		-d : Delete boot config file from initrd\n"
		"		-l : list boot config in initrd or file\n"
		"		-C : render the kernel.* subtree as a flat cmdline\n"
		"		     string (suitable for embedding in a kernel image)\n"
		"		     and print it to stdout\n\n"
		" If no option is given, show the bootconfig in the given file.\n");
	return -1;
}

int main(int argc, char **argv)
{
	char *path = NULL;
	char *apply = NULL;
	bool render_cmdline = false;
	bool delete = false, list = false;
	int opt;

	while ((opt = getopt(argc, argv, "hda:lC")) != -1) {
		switch (opt) {
		case 'd':
			delete = true;
			break;
		case 'a':
			apply = optarg;
			break;
		case 'l':
			list = true;
			break;
		case 'C':
			render_cmdline = true;
			break;
		case 'h':
		default:
			return usage();
		}
	}

	if ((!!apply + !!delete + !!list + !!render_cmdline) > 1) {
		pr_err("Error: You can give one of -a, -d, -l or -C at once.\n");
		return usage();
	}

	if (optind >= argc) {
		pr_err("Error: No initrd is specified.\n");
		return usage();
	}

	path = argv[optind];

	if (apply)
		return apply_xbc(path, apply);
	else if (delete)
		return delete_xbc(path);

	return show_xbc(path, list, render_cmdline);
}
