// SPDX-License-Identifier: GPL-2.0+
/*
 * cmd_gpt.c -- GPT (GUID Partition Table) handling command
 *
 * Copyright (C) 2015
 * Lukasz Majewski <l.majewski@majess.pl>
 *
 * Copyright (C) 2012 Samsung Electronics
 * author: Lukasz Majewski <l.majewski@samsung.com>
 * author: Piotr Wilczek <p.wilczek@samsung.com>
 */

#include <blk.h>
#include <env.h>
#include <log.h>
#include <malloc.h>
#include <command.h>
#include <part.h>
#include <part_efi.h>
#include <part.h>
#include <exports.h>
#include <uuid.h>
#include <linux/ctype.h>
#include <div64.h>
#include <memalign.h>
#include <linux/compat.h>
#include <linux/err.h>
#include <linux/sizes.h>
#include <stdlib.h>

static LIST_HEAD(disk_partitions);

/**
 * extract_env(): Expand env name from string format '&{env_name}'
 *                and return pointer to the env (if the env is set)
 *
 * @param str - pointer to string
 * @param env - pointer to pointer to extracted env
 *
 * Return: - zero on successful expand and env is set
 */
static int extract_env(const char *str, char **env)
{
	int ret = -1;
	char *e, *s;
#ifdef CONFIG_RANDOM_UUID
	char uuid_str[UUID_STR_LEN + 1];
#endif

	if (!str || strlen(str) < 4)
		return -1;

	if (!((strncmp(str, "${", 2) == 0) && (str[strlen(str) - 1] == '}')))
		return -1;

	s = strdup(str);
	if (s == NULL)
		return -1;

	memset(s + strlen(s) - 1, '\0', 1);
	memmove(s, s + 2, strlen(s) - 1);

	e = env_get(s);
	if (e == NULL) {
#ifdef CONFIG_RANDOM_UUID
		debug("%s unset. ", str);
		gen_rand_uuid_str(uuid_str, UUID_STR_FORMAT_GUID);
		env_set(s, uuid_str);

		e = env_get(s);
		if (e) {
			debug("Set to random.\n");
			ret = 0;
		} else {
			debug("Can't get random UUID.\n");
		}
#else
		debug("%s unset.\n", str);
#endif
	} else {
		debug("%s get from environment.\n", str);
		ret = 0;
	}

	*env = e;
	free(s);

	return ret;
}

/**
 * extract_val(): Extract value from a key=value pair list (comma separated).
 *                Only value for the given key is returend.
 *                Function allocates memory for the value, remember to free!
 *
 * @param str - pointer to string with key=values pairs
 * @param key - pointer to the key to search for
 *
 * Return: - pointer to allocated string with the value
 */
static char *extract_val(const char *str, const char *key)
{
	char *v, *k;
	char *s, *strcopy;
	char *new = NULL;

	strcopy = strdup(str);
	if (strcopy == NULL)
		return NULL;

	s = strcopy;
	while (s) {
		v = strsep(&s, ",");
		if (!v)
			break;
		k = strsep(&v, "=");
		if (!k)
			break;
		k += strspn(k, " \t");
		if  (strcmp(k, key) == 0) {
			new = strdup(v);
			break;
		}
	}

	free(strcopy);

	return new;
}

/**
 * found_key(): Found key without value in parameter list (comma separated).
 *
 * @param str - pointer to string with key
 * @param key - pointer to the key to search for
 *
 * Return: - true on found key
 */
static bool found_key(const char *str, const char *key)
{
	char *k;
	char *s, *strcopy;
	bool result = false;

	strcopy = strdup(str);
	if (!strcopy)
		return NULL;

	s = strcopy;
	while (s) {
		k = strsep(&s, ",");
		if (!k)
			break;
		k += strspn(k, " \t");
		if  (strcmp(k, key) == 0) {
			result = true;
			break;
		}
	}

	free(strcopy);

	return result;
}

/**
 * calc_parts_list_len() - get size of partition table description
 *
 * @numparts:	number of partitions
 * Return:	string size including terminating NUL
 */
static int calc_parts_list_len(int numparts)
{
	/* number of hexadecimal digits of the lbaint_t representation */
	const int lbaint_size = 2 * sizeof(lbaint_t);
	int partlistlen;

	/* media description including terminating NUL */
	partlistlen = strlen("uuid_disk=;") + UUID_STR_LEN + 1;
	/* per-partition descriptions; numparts */
	partlistlen += numparts * (strlen("name=,") + PART_NAME_LEN);
	/* see part.h for definition of struct disk_partition */
	partlistlen += numparts * (strlen("start=0x,") + lbaint_size);
	partlistlen += numparts * (strlen("size=0x,") + lbaint_size);
	if (IS_ENABLED(CONFIG_PARTITION_UUIDS))
		partlistlen += numparts * (strlen("uuid=,") + UUID_STR_LEN);
	if (IS_ENABLED(CONFIG_PARTITION_TYPE_GUID))
		partlistlen += numparts * (strlen("type=;") + UUID_STR_LEN);
	debug("Length of partitions_list is %d for %d partitions\n",
	      partlistlen, numparts);
	return partlistlen;
}

#ifdef CONFIG_CMD_GPT_RENAME
static void del_gpt_info(void)
{
	struct list_head *pos = &disk_partitions;
	struct disk_part *curr;
	while (!list_empty(pos)) {
		curr = list_entry(pos->next, struct disk_part, list);
		list_del(pos->next);
		free(curr);
	}
}

static struct disk_part *allocate_disk_part(struct disk_partition *info,
					    int partnum)
{
	struct disk_part *newpart;
	newpart = calloc(1, sizeof(struct disk_part));
	if (!newpart)
		return ERR_PTR(-ENOMEM);

	newpart->gpt_part_info.start = info->start;
	newpart->gpt_part_info.size = info->size;
	newpart->gpt_part_info.blksz = info->blksz;
	strncpy((char *)newpart->gpt_part_info.name, (const char *)info->name,
		PART_NAME_LEN);
	newpart->gpt_part_info.name[PART_NAME_LEN - 1] = '\0';
	strncpy((char *)newpart->gpt_part_info.type, (const char *)info->type,
		PART_TYPE_LEN);
	newpart->gpt_part_info.type[PART_TYPE_LEN - 1] = '\0';
	newpart->gpt_part_info.bootable = info->bootable;
	if (IS_ENABLED(CONFIG_PARTITION_UUIDS))
		disk_partition_set_uuid(&newpart->gpt_part_info,
					disk_partition_uuid(info));
	if (IS_ENABLED(CONFIG_PARTITION_TYPE_GUID))
		disk_partition_set_type_guid(&newpart->gpt_part_info,
					     disk_partition_type_guid(info));
	newpart->partnum = partnum;

	return newpart;
}

static void prettyprint_part_size(char *sizestr, lbaint_t partsize,
				  lbaint_t blksize)
{
	unsigned long long partbytes, partmegabytes;

	partbytes = partsize * blksize;
	partmegabytes = lldiv(partbytes, SZ_1M);
	snprintf(sizestr, 16, "%lluMiB", partmegabytes);
}

static void print_gpt_info(void)
{
	struct list_head *pos;
	struct disk_part *curr;
	char partstartstr[16];
	char partsizestr[16];

	list_for_each(pos, &disk_partitions) {
		curr = list_entry(pos, struct disk_part, list);
		prettyprint_part_size(partstartstr, curr->gpt_part_info.start,
				      curr->gpt_part_info.blksz);
		prettyprint_part_size(partsizestr, curr->gpt_part_info.size,
				      curr->gpt_part_info.blksz);

		printf("Partition %d:\n", curr->partnum);
		printf("Start %s, size %s\n", partstartstr, partsizestr);
		printf("Block size %lu, name %s\n", curr->gpt_part_info.blksz,
		       curr->gpt_part_info.name);
		printf("Type %s, bootable %d\n", curr->gpt_part_info.type,
		       curr->gpt_part_info.bootable & PART_BOOTABLE);
		if (CONFIG_IS_ENABLED(PARTITION_UUIDS))
			printf("UUID %s\n",
			       disk_partition_uuid(&curr->gpt_part_info));
		if (IS_ENABLED(CONFIG_PARTITION_TYPE_GUID))
			printf("Type GUID %s\n",
			       disk_partition_type_guid(&curr->gpt_part_info));
		printf("\n");
	}
}

/*
 * create the string that upstream 'gpt write' command will accept as an
 * argument
 *
 * From doc/README.gpt, Format of partitions layout:
 *    "uuid_disk=...;name=u-boot,size=60MiB,uuid=...;
 *	name=kernel,size=60MiB,uuid=...;"
 * The fields 'name' and 'size' are mandatory for every partition.
 * The field 'start' is optional. The fields 'uuid' and 'uuid_disk'
 * are optional if CONFIG_RANDOM_UUID is enabled.
 */
static int create_gpt_partitions_list(int numparts, const char *guid,
				      char *partitions_list)
{
	struct list_head *pos;
	struct disk_part *curr;
	char partstr[PART_NAME_LEN + 1];

	if (!partitions_list)
		return -EINVAL;

	strcpy(partitions_list, "uuid_disk=");
	strncat(partitions_list, guid, UUID_STR_LEN + 1);
	strcat(partitions_list, ";");

	list_for_each(pos, &disk_partitions) {
		curr = list_entry(pos, struct disk_part, list);
		strcat(partitions_list, "name=");
		strncat(partitions_list, (const char *)curr->gpt_part_info.name,
			PART_NAME_LEN + 1);
		sprintf(partstr, ",start=0x%llx",
			(unsigned long long)curr->gpt_part_info.start *
					    curr->gpt_part_info.blksz);
		/* one extra byte for NULL */
		strncat(partitions_list, partstr, PART_NAME_LEN + 1);
		sprintf(partstr, ",size=0x%llx",
			(unsigned long long)curr->gpt_part_info.size *
					    curr->gpt_part_info.blksz);
		strncat(partitions_list, partstr, PART_NAME_LEN + 1);

		if (IS_ENABLED(CONFIG_PARTITION_TYPE_GUID)) {
			strcat(partitions_list, ",type=");
			strncat(partitions_list,
				disk_partition_type_guid(&curr->gpt_part_info),
				UUID_STR_LEN + 1);
		}
		if (CONFIG_IS_ENABLED(PARTITION_UUIDS)) {
			strcat(partitions_list, ",uuid=");
			strncat(partitions_list,
				disk_partition_uuid(&curr->gpt_part_info),
				UUID_STR_LEN + 1);
		}
		if (curr->gpt_part_info.bootable & PART_BOOTABLE)
			strcat(partitions_list, ",bootable");
		strcat(partitions_list, ";");
	}
	return 0;
}

/*
 * read partition info into disk_partitions list where
 * it can be printed or modified
 */
static int get_gpt_info(struct blk_desc *dev_desc)
{
	/* start partition numbering at 1, as U-Boot does */
	int valid_parts = 0, p, ret;
	struct disk_partition info;
	struct disk_part *new_disk_part;

	/*
	 * Always re-read partition info from device, in case
	 * it has changed
	 */
	INIT_LIST_HEAD(&disk_partitions);

	for (p = 1; p <= MAX_SEARCH_PARTITIONS; p++) {
		ret = part_get_info(dev_desc, p, &info);
		if (ret)
			continue;

		/* Add 1 here because counter is zero-based but p1 is
		   the first partition */
		new_disk_part = allocate_disk_part(&info, valid_parts+1);
		if (IS_ERR(new_disk_part))
			goto out;

		list_add_tail(&new_disk_part->list, &disk_partitions);
		valid_parts++;
	}
	if (valid_parts == 0) {
		printf("** No valid partitions found **\n");
		goto out;
	}
	return valid_parts;
 out:
	if (valid_parts >= 1)
		del_gpt_info();
	return -ENODEV;
}

/* a wrapper to test get_gpt_info */
static int do_get_gpt_info(struct blk_desc *dev_desc, char * const namestr)
{
	int numparts;

	numparts = get_gpt_info(dev_desc);

	if (numparts > 0) {
		if (namestr) {
			char disk_guid[UUID_STR_LEN + 1];
			char *partitions_list;
			int partlistlen;
			int ret = -1;

			ret = get_disk_guid(dev_desc, disk_guid);
			if (ret < 0)
				return ret;

			partlistlen = calc_parts_list_len(numparts);
			partitions_list = malloc(partlistlen);
			if (!partitions_list) {
				del_gpt_info();
				return -ENOMEM;
			}
			memset(partitions_list, '\0', partlistlen);

			ret = create_gpt_partitions_list(numparts, disk_guid,
							 partitions_list);
			if (ret < 0)
				printf("Error: Could not create partition list string!\n");
			else
				env_set(namestr, partitions_list);

			free(partitions_list);
		} else {
			print_gpt_info();
		}
		del_gpt_info();
		return 0;
	}
	return numparts;
}
#endif

/**
 * set_gpt_info(): Fill partition information from string
 *		function allocates memory, remember to free!
 *
 * @param dev_desc - pointer block device descriptor
 * @param str_part - pointer to string with partition information
 * @param str_disk_guid - pointer to pointer to allocated string with disk guid
 * @param partitions - pointer to pointer to allocated partitions array
 * @param parts_count - number of partitions
 *
 * Return: - zero on success, otherwise error
 *
 */
static int set_gpt_info(struct blk_desc *dev_desc,
			const char *str_part,
			char **str_disk_guid,
			struct disk_partition **partitions,
			u8 *parts_count)
{
	char *tok, *str, *s;
	int i;
	char *val, *p;
	int p_count;
	struct disk_partition *parts;
	int errno = 0;
	uint64_t size_ll, start_ll;
	lbaint_t offset = 0;
	int max_str_part = calc_parts_list_len(MAX_SEARCH_PARTITIONS);

	debug("%s:  lba num: 0x%x %d\n", __func__,
	      (unsigned int)dev_desc->lba, (unsigned int)dev_desc->lba);

	if (str_part == NULL)
		return -1;

	str = strdup(str_part);
	if (str == NULL)
		return -ENOMEM;

	/* extract disk guid */
	s = str;
	val = extract_val(str, "uuid_disk");
	if (!val) {
#ifdef CONFIG_RANDOM_UUID
		*str_disk_guid = malloc(UUID_STR_LEN + 1);
		if (*str_disk_guid == NULL)
			return -ENOMEM;
		gen_rand_uuid_str(*str_disk_guid, UUID_STR_FORMAT_STD);
#else
		free(str);
		return -2;
#endif
	} else {
		val = strsep(&val, ";");
		if (extract_env(val, &p))
			p = val;
		*str_disk_guid = strdup(p);
		free(val);
		/* Move s to first partition */
		strsep(&s, ";");
	}
	if (s == NULL) {
		printf("Error: is the partitions string NULL-terminated?\n");
		return -EINVAL;
	}
	if (strnlen(s, max_str_part) == 0)
		return -3;

	i = strnlen(s, max_str_part) - 1;
	if (s[i] == ';')
		s[i] = '\0';

	/* calculate expected number of partitions */
	p_count = 1;
	p = s;
	while (*p) {
		if (*p++ == ';')
			p_count++;
	}

	/* allocate memory for partitions */
	parts = calloc(sizeof(struct disk_partition), p_count);
	if (parts == NULL)
		return -ENOMEM;

	/* retrieve partitions data from string */
	for (i = 0; i < p_count; i++) {
		tok = strsep(&s, ";");

		if (tok == NULL)
			break;

		/* uuid */
		val = extract_val(tok, "uuid");
		if (!val) {
			/* 'uuid' is optional if random uuid's are enabled */
#ifdef CONFIG_RANDOM_UUID
			gen_rand_uuid_str(parts[i].uuid, UUID_STR_FORMAT_STD);
#else
			errno = -4;
			goto err;
#endif
		} else {
			if (extract_env(val, &p))
				p = val;
			if (strnlen(p, max_str_part) >= sizeof(parts[i].uuid)) {
				printf("Wrong uuid format for partition %d\n", i);
				errno = -4;
				goto err;
			}
			strncpy((char *)parts[i].uuid, p, max_str_part);
			free(val);
		}
#ifdef CONFIG_PARTITION_TYPE_GUID
		/* guid */
		val = extract_val(tok, "type");
		if (val) {
			/* 'type' is optional */
			if (extract_env(val, &p))
				p = val;
			if (strnlen(p, max_str_part) >= sizeof(parts[i].type_guid)) {
				printf("Wrong type guid format for partition %d\n",
				       i);
				errno = -4;
				goto err;
			}
			strncpy((char *)parts[i].type_guid, p, max_str_part);
			free(val);
		}
#endif
		/* name */
		val = extract_val(tok, "name");
		if (!val) { /* name is mandatory */
			errno = -4;
			goto err;
		}
		if (extract_env(val, &p))
			p = val;
		if (strnlen(p, max_str_part) >= sizeof(parts[i].name)) {
			errno = -4;
			goto err;
		}
		strncpy((char *)parts[i].name, p, max_str_part);
		free(val);

		/* size */
		val = extract_val(tok, "size");
		if (!val) { /* 'size' is mandatory */
			errno = -4;
			goto err;
		}
		if (extract_env(val, &p))
			p = val;
		if ((strcmp(p, "-") == 0)) {
			/* Let part efi module to auto extend the size */
			parts[i].size = 0;
		} else {
			size_ll = ustrtoull(p, &p, 0);
			parts[i].size = lldiv(size_ll, dev_desc->blksz);
		}

		free(val);

		/* start address */
		val = extract_val(tok, "start");
		if (val) { /* start address is optional */
			if (extract_env(val, &p))
				p = val;
			start_ll = ustrtoull(p, &p, 0);
			parts[i].start = lldiv(start_ll, dev_desc->blksz);
			free(val);
		}

		offset += parts[i].size + parts[i].start;

		/* bootable */
		if (found_key(tok, "bootable"))
			parts[i].bootable = PART_BOOTABLE;
	}

	*parts_count = p_count;
	*partitions = parts;
	free(str);

	return 0;
err:
	free(str);
	free(*str_disk_guid);
	free(parts);

	return errno;
}

static int gpt_repair(struct blk_desc *blk_dev_desc)
{
	int ret = 0;

	ret = gpt_repair_headers(blk_dev_desc);

	return ret;
}

static int gpt_default(struct blk_desc *blk_dev_desc, const char *str_part)
{
	int ret;
	char *str_disk_guid;
	u8 part_count = 0;
	struct disk_partition *partitions = NULL;

	/* fill partitions */
	ret = set_gpt_info(blk_dev_desc, str_part,
			&str_disk_guid, &partitions, &part_count);
	if (ret) {
		if (ret == -1)
			printf("No partition list provided\n");
		if (ret == -2)
			printf("Missing disk guid\n");
		if ((ret == -3) || (ret == -4))
			printf("Partition list incomplete\n");
		return -1;
	}

	/* save partitions layout to disk */
	ret = gpt_restore(blk_dev_desc, str_disk_guid, partitions, part_count);
	free(str_disk_guid);
	free(partitions);

	/* initialize partition table */
	if (blk_enabled())
		part_init(blk_dev_desc);

	return ret;
}

static int gpt_verify(struct blk_desc *blk_dev_desc, const char *str_part)
{
	ALLOC_CACHE_ALIGN_BUFFER_PAD(gpt_header, gpt_head, 1,
				     blk_dev_desc->blksz);
	struct disk_partition *partitions = NULL;
	gpt_entry *gpt_pte = NULL;
	char *str_disk_guid;
	u8 part_count = 0;
	int ret = 0;

	/* fill partitions */
	ret = set_gpt_info(blk_dev_desc, str_part,
			&str_disk_guid, &partitions, &part_count);
	if (ret) {
		if (ret == -1) {
			printf("No partition list provided - only basic check\n");
			ret = gpt_verify_headers(blk_dev_desc, gpt_head,
						 &gpt_pte);
			goto out;
		}
		if (ret == -2)
			printf("Missing disk guid\n");
		if ((ret == -3) || (ret == -4))
			printf("Partition list incomplete\n");
		return -1;
	}

	/* Check partition layout with provided pattern */
	ret = gpt_verify_partitions(blk_dev_desc, partitions, part_count,
				    gpt_head, &gpt_pte);
	free(str_disk_guid);
	free(partitions);
 out:
	if (!ret)
		free(gpt_pte);
	return ret;
}

/**
 * gpt_enumerate() - Enumerate partition names into environment variable.
 *
 * Enumerate partition names. Partition names are stored in gpt_partition_list
 * environment variable. Each partition name is delimited by space.
 *
 * @desc: block device descriptor
 *
 * @Return: '0' on success and -ve error on failure
 */
static int gpt_enumerate(struct blk_desc *desc)
{
	struct part_driver *first_drv, *part_drv;
	int str_len = 0, tmp_len;
	char part_list[2048];
	int n_drvs;
	char *ptr;

	part_list[0] = 0;
	n_drvs = part_driver_get_count();
	if (!n_drvs) {
		printf("Failed to get partition driver count\n");
		return -ENOENT;
	}

	first_drv = part_driver_get_first();
	for (part_drv = first_drv; part_drv != first_drv + n_drvs; part_drv++) {
		struct disk_partition pinfo;
		int ret;
		int i;

		if (part_drv->test(desc))
			continue;

		for (i = 1; i < part_drv->max_entries; i++) {
			ret = part_drv->get_info(desc, i, &pinfo);
			if (ret)
				continue;

			ptr = &part_list[str_len];
			tmp_len = strlen((const char *)pinfo.name);
			str_len += tmp_len;
			/* +1 for space */
			str_len++;
			if (str_len > sizeof(part_list)) {
				printf("Error insufficient memory\n");
				return -ENOMEM;
			}
			strcpy(ptr, (const char *)pinfo.name);
			/* One byte for space(" ") delimiter */
			ptr[tmp_len] = ' ';
		}
		if (*part_list)
			part_list[strlen(part_list) - 1] = 0;
		break;
	}
	debug("setenv gpt_partition_list %s\n", part_list);

	return env_set("gpt_partition_list", part_list);
}

/**
 * gpt_setenv_part_variables() - setup partition environmental variables
 *
 * Setup the gpt_partition_name, gpt_partition_entry, gpt_partition_addr
 * and gpt_partition_size, gpt_partition_bootable environment variables.
 *
 * @pinfo: pointer to disk partition
 * @i: partition entry
 *
 * @Return: '0' on success and -ENOENT on failure
 */
static int gpt_setenv_part_variables(struct disk_partition *pinfo, int i)
{
	int ret;

	ret = env_set_hex("gpt_partition_addr", pinfo->start);
	if (ret)
		goto fail;

	ret = env_set_hex("gpt_partition_size", pinfo->size);
	if (ret)
		goto fail;

	ret = env_set_hex("gpt_partition_entry", i);
	if (ret)
		goto fail;

	ret = env_set("gpt_partition_name", (const char *)pinfo->name);
	if (ret)
		goto fail;

	ret = env_set_ulong("gpt_partition_bootable", !!(pinfo->bootable & PART_BOOTABLE));
	if (ret)
		goto fail;

	return 0;

fail:
	return -ENOENT;
}

/**
 * gpt_setenv() - Dynamically setup environment variables.
 *
 * Dynamically setup environment variables for name, index, offset and size
 * for partition in GPT table after running "gpt setenv" for a partition name.
 *
 * @desc: block device descriptor
 * @name: partition name
 *
 * @Return: '0' on success and -ve err on failure
 */
static int gpt_setenv(struct blk_desc *desc, const char *name)
{
	struct part_driver *first_drv, *part_drv;
	int n_drvs;
	int ret = -1;

	n_drvs = part_driver_get_count();
	if (!n_drvs) {
		printf("Failed to get partition driver count\n");
		goto fail;
	}

	first_drv = part_driver_get_first();
	for (part_drv = first_drv; part_drv != first_drv + n_drvs; part_drv++) {
		struct disk_partition pinfo;
		int i;

		for (i = 1; i < part_drv->max_entries; i++) {
			ret = part_drv->get_info(desc, i, &pinfo);
			if (ret)
				continue;

			if (!strcmp(name, (const char *)pinfo.name)) {
				/* match found, setup environment variables */
				ret = gpt_setenv_part_variables(&pinfo, i);
				if (ret)
					goto fail;

				return 0;
			}
		}
	}

fail:
	return ret;
}

static int do_disk_guid(struct blk_desc *dev_desc, char * const namestr)
{
	int ret;
	char disk_guid[UUID_STR_LEN + 1];

	ret = get_disk_guid(dev_desc, disk_guid);
	if (ret < 0)
		return CMD_RET_FAILURE;

	if (namestr)
		env_set(namestr, disk_guid);
	else
		printf("%s\n", disk_guid);

	return ret;
}

#ifdef CONFIG_CMD_GPT_RENAME
static int do_rename_gpt_parts(struct blk_desc *dev_desc, char *subcomm,
			       char *name1, char *name2)
{
	struct list_head *pos;
	struct disk_part *curr;
	struct disk_partition *new_partitions = NULL;
	char disk_guid[UUID_STR_LEN + 1];
	char *partitions_list, *str_disk_guid = NULL;
	u8 part_count = 0;
	int partlistlen, ret, numparts = 0, partnum, i = 1, ctr1 = 0, ctr2 = 0;

	if (!subcomm || !name1 || !name2 ||
	    (strcmp(subcomm, "swap") && strcmp(subcomm, "rename") &&
	     strcmp(subcomm, "transpose")))
		return -EINVAL;

	ret = get_disk_guid(dev_desc, disk_guid);
	if (ret < 0)
		return ret;
	/*
	 * Allocates disk_partitions, requiring matching call to del_gpt_info()
	 * if successful.
	 */
	numparts = get_gpt_info(dev_desc);
	if (numparts <=  0)
		return numparts ? numparts : -ENODEV;

	partlistlen = calc_parts_list_len(numparts);
	partitions_list = malloc(partlistlen);
	if (!partitions_list) {
		del_gpt_info();
		return -ENOMEM;
	}
	memset(partitions_list, '\0', partlistlen);

	ret = create_gpt_partitions_list(numparts, disk_guid, partitions_list);
	if (ret < 0) {
		free(partitions_list);
		return ret;
	}
	/*
	 * Uncomment the following line to print a string that 'gpt write'
	 * or 'gpt verify' will accept as input.
	 */
	debug("OLD partitions_list is %s with %u chars\n", partitions_list,
	      (unsigned)strlen(partitions_list));

	/* set_gpt_info allocates new_partitions and str_disk_guid */
	ret = set_gpt_info(dev_desc, partitions_list, &str_disk_guid,
			   &new_partitions, &part_count);
	if (ret < 0)
		goto out;

	if (!strcmp(subcomm, "swap")) {
		if ((strlen(name1) > PART_NAME_LEN) || (strlen(name2) > PART_NAME_LEN)) {
			printf("Names longer than %d characters are truncated.\n", PART_NAME_LEN);
			ret = -EINVAL;
			goto out;
		}
		list_for_each(pos, &disk_partitions) {
			curr = list_entry(pos, struct disk_part, list);
			if (!strcmp((char *)curr->gpt_part_info.name, name1)) {
				strcpy((char *)curr->gpt_part_info.name, name2);
				ctr1++;
			} else if (!strcmp((char *)curr->gpt_part_info.name, name2)) {
				strcpy((char *)curr->gpt_part_info.name, name1);
				ctr2++;
			}
		}
		if ((ctr1 + ctr2 < 2) || (ctr1 != ctr2)) {
			printf("Cannot swap partition names except in pairs.\n");
			ret = -EINVAL;
			goto out;
		}
	} else if (!strcmp(subcomm, "transpose")) {
		int idx1, idx2;
		struct disk_partition* first = NULL;
		struct disk_partition* second= NULL;
		struct disk_partition tmp_part;

		idx1 = simple_strtoul(name1, NULL, 10);
		idx2 = simple_strtoul(name2, NULL, 10);
		if (idx1 == idx2) {
			printf("Cannot swap partition with itself\n");
			ret = -EINVAL;
			goto out;
		}

		list_for_each(pos, &disk_partitions) {
			curr = list_entry(pos, struct disk_part, list);
			if (curr->partnum == idx1)
				first = &curr->gpt_part_info;
			else if (curr->partnum == idx2)
				second = &curr->gpt_part_info;
		}
		if (!first) {
			printf("Illegal partition number %s\n", name1);
			ret = -EINVAL;
			goto out;
		}
		if (!second) {
			printf("Illegal partition number %s\n", name2);
			ret = -EINVAL;
			goto out;
		}

		tmp_part = *first;
		*first = *second;
		*second = tmp_part;
	} else { /* rename */
		if (strlen(name2) > PART_NAME_LEN) {
			printf("Names longer than %d characters are truncated.\n", PART_NAME_LEN);
			ret = -EINVAL;
			goto out;
		}
		partnum = (int)simple_strtol(name1, NULL, 10);
		if ((partnum < 0) || (partnum > numparts)) {
			printf("Illegal partition number %s\n", name1);
			ret = -EINVAL;
			goto out;
		}
		ret = part_get_info(dev_desc, partnum, new_partitions);
		if (ret < 0)
			goto out;

		/* U-Boot partition numbering starts at 1 */
		list_for_each(pos, &disk_partitions) {
			curr = list_entry(pos, struct disk_part, list);
			if (i == partnum) {
				strcpy((char *)curr->gpt_part_info.name, name2);
				break;
			}
			i++;
		}
	}

	ret = create_gpt_partitions_list(numparts, disk_guid, partitions_list);
	if (ret < 0)
		goto out;
	debug("NEW partitions_list is %s with %u chars\n", partitions_list,
	      (unsigned)strlen(partitions_list));

	ret = set_gpt_info(dev_desc, partitions_list, &str_disk_guid,
			   &new_partitions, &part_count);
	/*
	 * Even though valid pointers are here passed into set_gpt_info(),
	 * it mallocs again, and there's no way to tell which failed.
	 */
	if (ret < 0)
		goto out;

	debug("Writing new partition table\n");
	ret = gpt_restore(dev_desc, disk_guid, new_partitions, numparts);
	if (ret < 0) {
		printf("Writing new partition table failed\n");
		goto out;
	}

	debug("Reading back new partition table\n");
	/*
	 * Empty the existing disk_partitions list, as otherwise the memory in
	 * the original list is unreachable.
	 */
	del_gpt_info();
	numparts = get_gpt_info(dev_desc);
	if (numparts <=  0) {
		ret = numparts ? numparts : -ENODEV;
		goto out;
	}
	printf("new partition table with %d partitions is:\n", numparts);
	print_gpt_info();
 out:
	del_gpt_info();
#ifdef CONFIG_RANDOM_UUID
	free(str_disk_guid);
#endif
	free(new_partitions);
	free(partitions_list);
	return ret;
}

/**
 * gpt_set_bootable() - Set bootable flags for partitions
 *
 * Sets the bootable flag for any partition names in the comma separated list of
 * partition names. Any partitions not in the list have their bootable flag
 * cleared
 *
 * @desc: block device descriptor
 * @name: Comma separated list of partition names
 *
 * @Return: '0' on success and -ve error on failure
 */
static int gpt_set_bootable(struct blk_desc *blk_dev_desc, char *const part_list)
{
	char *name;
	char disk_guid[UUID_STR_LEN + 1];
	struct list_head *pos;
	struct disk_part *curr;
	struct disk_partition *partitions = NULL;
	int part_count = 0;
	int ret = get_disk_guid(blk_dev_desc, disk_guid);

	if (ret < 0)
		return ret;

	ret = get_gpt_info(blk_dev_desc);
	if (ret <= 0)
		goto out;

	part_count = ret;
	partitions = malloc(sizeof(*partitions) * part_count);
	if (!partitions) {
		ret = -ENOMEM;
		goto out;
	}

	/* Copy partitions and clear bootable flag */
	part_count = 0;
	list_for_each(pos, &disk_partitions) {
		curr = list_entry(pos, struct disk_part, list);
		partitions[part_count] = curr->gpt_part_info;
		partitions[part_count].bootable &= ~PART_BOOTABLE;
		part_count++;
	}

	name = strtok(part_list, ",");
	while (name) {
		bool found = false;

		for (int i = 0; i < part_count; i++) {
			if (strcmp((char *)partitions[i].name, name) == 0) {
				partitions[i].bootable |= PART_BOOTABLE;
				found = true;
			}
		}

		if (!found) {
			printf("Warning: No partition matching '%s' found\n",
			       name);
		}

		name = strtok(NULL, ",");
	}

	ret = gpt_restore(blk_dev_desc, disk_guid, partitions, part_count);

out:
	del_gpt_info();

	if (partitions)
		free(partitions);

	return ret;
}
#endif

/**
 * do_gpt(): Perform GPT operations
 *
 * @param cmdtp - command name
 * @param flag
 * @param argc
 * @param argv
 *
 * Return: zero on success; otherwise error
 */
static int do_gpt(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
{
	int ret = CMD_RET_SUCCESS;
	int dev = 0;
	char *ep;
	struct blk_desc *blk_dev_desc = NULL;

#ifndef CONFIG_CMD_GPT_RENAME
	if (argc < 4 || argc > 5)
#else
	if (argc < 4 || argc > 6)
#endif
		return CMD_RET_USAGE;

	dev = (int)dectoul(argv[3], &ep);
	if (!ep || ep[0] != '\0') {
		printf("'%s' is not a number\n", argv[3]);
		return CMD_RET_USAGE;
	}
	blk_dev_desc = blk_get_dev(argv[2], dev);
	if (!blk_dev_desc) {
		printf("%s: %s dev %d NOT available\n",
		       __func__, argv[2], dev);
		return CMD_RET_FAILURE;
	}

	if (strcmp(argv[1], "repair") == 0) {
		printf("Repairing GPT: ");
		ret = gpt_repair(blk_dev_desc);
	} else if ((strcmp(argv[1], "write") == 0) && (argc == 5)) {
		printf("Writing GPT: ");
		ret = gpt_default(blk_dev_desc, argv[4]);
	} else if ((strcmp(argv[1], "verify") == 0)) {
		ret = gpt_verify(blk_dev_desc, argv[4]);
		printf("Verify GPT: ");
	} else if ((strcmp(argv[1], "setenv") == 0)) {
		ret = gpt_setenv(blk_dev_desc, argv[4]);
	} else if ((strcmp(argv[1], "enumerate") == 0)) {
		ret = gpt_enumerate(blk_dev_desc);
	} else if (strcmp(argv[1], "guid") == 0) {
		ret = do_disk_guid(blk_dev_desc, argv[4]);
#ifdef CONFIG_CMD_GPT_RENAME
	} else if (strcmp(argv[1], "read") == 0) {
		ret = do_get_gpt_info(blk_dev_desc, (argc == 5) ? argv[4] : NULL);
	} else if ((strcmp(argv[1], "swap") == 0) ||
		   (strcmp(argv[1], "rename") == 0) ||
		   (strcmp(argv[1], "transpose") == 0)) {
		ret = do_rename_gpt_parts(blk_dev_desc, argv[1], argv[4], argv[5]);
	} else if ((strcmp(argv[1], "set-bootable") == 0)) {
		ret = gpt_set_bootable(blk_dev_desc, argv[4]);
#endif
	} else {
		return CMD_RET_USAGE;
	}

	if (ret) {
		printf("error!\n");
		return CMD_RET_FAILURE;
	}

	printf("success!\n");
	return CMD_RET_SUCCESS;
}

U_BOOT_CMD(gpt, CONFIG_SYS_MAXARGS, 1, do_gpt,
	"GUID Partition Table",
	"<command> <interface> <dev> <partitions_list>\n"
	" - GUID partition table restoration and validity check\n"
	" Restore or verify GPT information on a device connected\n"
	" to interface\n"
	" Example usage:\n"
	" gpt repair mmc 0\n"
	"    - repair the GPT on the device\n"
	" gpt write mmc 0 $partitions\n"
	"    - write the GPT to device\n"
	" gpt verify mmc 0 $partitions\n"
	"    - verify the GPT on device against $partitions\n"
	" gpt setenv mmc 0 $name\n"
	"    - setup environment variables for partition $name:\n"
	"      gpt_partition_addr, gpt_partition_size,\n"
	"      gpt_partition_name, gpt_partition_entry,\n"
	"      gpt_partition_bootable\n"
	" gpt enumerate mmc 0\n"
	"    - store list of partitions to gpt_partition_list environment variable\n"
	" gpt guid <interface> <dev>\n"
	"    - print disk GUID\n"
	" gpt guid <interface> <dev> <varname>\n"
	"    - set environment variable to disk GUID\n"
	" Example usage:\n"
	" gpt guid mmc 0\n"
	" gpt guid mmc 0 varname\n"
#ifdef CONFIG_CMD_GPT_RENAME
	"gpt partition renaming commands:\n"
	" gpt read <interface> <dev> [<varname>]\n"
	"    - read GPT into a data structure for manipulation\n"
	"    - read GPT partitions into environment variable\n"
	" gpt swap <interface> <dev> <name1> <name2>\n"
	"    - change all partitions named name1 to name2\n"
	"      and vice-versa\n"
	" gpt transpose <interface> <dev> <part1> <part2>\n"
	"    - Swap the order of the entries for part1 and part2 in the partition table\n"
	" gpt rename <interface> <dev> <part> <name>\n"
	"    - rename the specified partition\n"
	" gpt set-bootable <interface> <dev> <list>\n"
	"    - make partition names in list bootable\n"
	" Example usage:\n"
	" gpt swap mmc 0 foo bar\n"
	" gpt rename mmc 0 3 foo\n"
	" gpt set-bootable mmc 0 boot_a,boot_b\n"
	" gpt transpose mmc 0 1 2\n"
#endif
);
