
#include "c.h"
#include "strutils.h"

#ifdef HAVE_LIBBLKID
# include <blkid.h>
#endif

#include "fdiskP.h"

/**
 * SECTION: partition
 * @title: Partition
 * @short_description: generic label independent partition abstraction
 *
 * The fdisk_partition provides label independent abstraction. The partitions
 * are not directly connected with partition table (label) data. Any change to
 * fdisk_partition does not affects in-memory or on-disk label data.
 *
 * The fdisk_partition is possible to use as a template for
 * fdisk_add_partition() or fdisk_set_partition() operations.
 */

static void init_partition(struct fdisk_partition *pa)
{
	FDISK_INIT_UNDEF(pa->size);
	FDISK_INIT_UNDEF(pa->start);
	FDISK_INIT_UNDEF(pa->partno);
	FDISK_INIT_UNDEF(pa->parent_partno);
	FDISK_INIT_UNDEF(pa->boot);

	INIT_LIST_HEAD(&pa->parts);
}

/**
 * fdisk_new_partition:
 *
 * Returns: new instance.
 */
struct fdisk_partition *fdisk_new_partition(void)
{
	struct fdisk_partition *pa = calloc(1, sizeof(*pa));

	pa->refcount = 1;
	init_partition(pa);
	DBG(PART, ul_debugobj(pa, "alloc"));
	return pa;
}

/**
 * fdisk_reset_partition:
 * @pa: partition
 *
 * Resets partition content.
 */
void fdisk_reset_partition(struct fdisk_partition *pa)
{
	int ref;

	if (!pa)
		return;

	DBG(PART, ul_debugobj(pa, "reset"));
	ref = pa->refcount;

	fdisk_unref_parttype(pa->type);
	free(pa->name);
	free(pa->uuid);
	free(pa->attrs);
	free(pa->fstype);
	free(pa->fsuuid);
	free(pa->fslabel);

	memset(pa, 0, sizeof(*pa));
	pa->refcount = ref;

	init_partition(pa);
}

static struct fdisk_partition *__copy_partition(struct fdisk_partition *o)
{
	struct fdisk_partition *n = fdisk_new_partition();

	if (!n)
		return NULL;
	memcpy(n, o, sizeof(*n));
	if (n->type)
		fdisk_ref_parttype(n->type);
	if (o->name)
		n->name = strdup(o->name);
	if (o->uuid)
		n->uuid = strdup(o->uuid);
	if (o->attrs)
		n->attrs = strdup(o->attrs);
	if (o->fstype)
		n->fstype = strdup(o->fstype);
	if (o->fsuuid)
		n->fsuuid = strdup(o->fsuuid);
	if (o->fslabel)
		n->fslabel = strdup(o->fslabel);

	return n;
}

/**
 * fdisk_ref_partition:
 * @pa: partition pointer
 *
 * Increments reference counter.
 */
void fdisk_ref_partition(struct fdisk_partition *pa)
{
	if (pa)
		pa->refcount++;
}

/**
 * fdisk_unref_partition:
 * @pa: partition pointer
 *
 * Decrements reference counter, on zero the @pa is automatically
 * deallocated.
 */
void fdisk_unref_partition(struct fdisk_partition *pa)
{
	if (!pa)
		return;

	pa->refcount--;
	if (pa->refcount <= 0) {
		fdisk_reset_partition(pa);
		list_del(&pa->parts);
		DBG(PART, ul_debugobj(pa, "free"));
		free(pa);
	}
}

/**
 * fdisk_partition_set_start:
 * @pa: partition
 * @off: offset in sectors, maximal is UINT64_MAX-1
 *
 * Note that zero is valid offset too. Use fdisk_partition_unset_start() to
 * undefine the offset.
 *
 * Returns: 0 on success, <0 on error.
 */
int fdisk_partition_set_start(struct fdisk_partition *pa, fdisk_sector_t off)
{
	if (!pa)
		return -EINVAL;
	if (FDISK_IS_UNDEF(off))
		return -ERANGE;
	pa->start = off;
	pa->fs_probed = 0;
	return 0;
}

/**
 * fdisk_partition_unset_start:
 * @pa: partition
 *
 * Sets the size as undefined. See fdisk_partition_has_start().
 *
 * Returns: 0 on success, <0 on error.
 */
int fdisk_partition_unset_start(struct fdisk_partition *pa)
{
	if (!pa)
		return -EINVAL;
	FDISK_INIT_UNDEF(pa->start);
	pa->fs_probed = 0;
	return 0;
}

/**
 * fdisk_partition_get_start:
 * @pa: partition
 *
 * The zero is also valid offset. The function may return random undefined
 * value when start offset is undefined (for example after
 * fdisk_partition_unset_start()). Always use fdisk_partition_has_start() to be
 * sure that you work with valid numbers.
 *
 * Returns: start offset in sectors
 */
fdisk_sector_t fdisk_partition_get_start(struct fdisk_partition *pa)
{
	return pa->start;
}

/**
 * fdisk_partition_has_start:
 * @pa: partition
 *
 * Returns: 1 or 0
 */
int fdisk_partition_has_start(struct fdisk_partition *pa)
{
	return pa && !FDISK_IS_UNDEF(pa->start);
}


/**
 * fdisk_partition_cmp_start:
 * @a: partition
 * @b: partition
 *
 * Compares partitions according to start offset, See fdisk_table_sort_partitions().
 *
 * Return: 0 if the same, <0 if @b greater, >0 if @a greater.
 */
int fdisk_partition_cmp_start(struct fdisk_partition *a,
			      struct fdisk_partition *b)
{
	int no_a = FDISK_IS_UNDEF(a->start),
	    no_b = FDISK_IS_UNDEF(b->start);

	if (no_a && no_b)
		return 0;
	if (no_a)
		return -1;
	if (no_b)
		return 1;

	return cmp_numbers(a->start, b->start);
}

/**
 * fdisk_partition_start_follow_default
 * @pa: partition
 * @enable: 0|1
 *
 * When @pa used as a template for fdisk_add_partition() when force label driver
 * to use the first possible space for the new partition.
 *
 * Returns: 0 on success, <0 on error.
 */
int fdisk_partition_start_follow_default(struct fdisk_partition *pa, int enable)
{
	if (!pa)
		return -EINVAL;
	pa->start_follow_default = enable ? 1 : 0;
	return 0;
}

/**
 * fdisk_partition_start_is_default:
 * @pa: partition
 *
 * See fdisk_partition_start_follow_default().
 *
 * Returns: 1 if the partition follows default
 */
int fdisk_partition_start_is_default(struct fdisk_partition *pa)
{
	assert(pa);
	return pa->start_follow_default;
}

/**
 * fdisk_partition_set_size:
 * @pa: partition
 * @sz: size in sectors, maximal is UIN64_MAX-1
 *
 * Note that zero is valid size too. Use fdisk_partition_unset_size() to
 * undefine the size.
 *
 * Returns: 0 on success, <0 on error.
 */
int fdisk_partition_set_size(struct fdisk_partition *pa, fdisk_sector_t sz)
{
	if (!pa)
		return -EINVAL;
	if (FDISK_IS_UNDEF(sz))
		return -ERANGE;
	pa->size = sz;
	pa->fs_probed = 0;
	return 0;
}

/**
 * fdisk_partition_unset_size:
 * @pa: partition
 *
 * Sets the size as undefined. See fdisk_partition_has_size().
 *
 * Returns: 0 on success, <0 on error.
 */
int fdisk_partition_unset_size(struct fdisk_partition *pa)
{
	if (!pa)
		return -EINVAL;
	FDISK_INIT_UNDEF(pa->size);
	pa->fs_probed = 0;
	return 0;
}

/**
 * fdisk_partition_get_size:
 * @pa: partition
 *
 * The zero is also valid size. The function may return random undefined
 * value when size is undefined (for example after fdisk_partition_unset_size()).
 * Always use fdisk_partition_has_size() to be sure that you work with valid
 * numbers.
 *
 * Returns: size offset in sectors
 */
fdisk_sector_t fdisk_partition_get_size(struct fdisk_partition *pa)
{
	return pa->size;
}

/**
 * fdisk_partition_has_size:
 * @pa: partition
 *
 * Returns: 1 or 0
 */
int fdisk_partition_has_size(struct fdisk_partition *pa)
{
	return pa && !FDISK_IS_UNDEF(pa->size);
}

/**
 * fdisk_partition_size_explicit:
 * @pa: partition
 * @enable: 0|1
 *
 * By default libfdisk aligns the size when add the new partition (by
 * fdisk_add_partition()). If you want to disable this functionality use
 * @enable = 1.
 *
 * Returns: 0 on success, <0 on error.
 */
int fdisk_partition_size_explicit(struct fdisk_partition *pa, int enable)
{
	if (!pa)
		return -EINVAL;
	pa->size_explicit = enable ? 1 : 0;
	return 0;
}

/**
 * fdisk_partition_set_partno:
 * @pa: partition
 * @num: partition number (0 is the first partition, maximal is SIZE_MAX-1)
 *
 * Note that zero is valid partno too. Use fdisk_partition_unset_partno() to
 * undefine the partno.
 *
 * Returns: 0 on success, <0 on error.
 */
int fdisk_partition_set_partno(struct fdisk_partition *pa, size_t num)
{
	if (!pa)
		return -EINVAL;
	if (FDISK_IS_UNDEF(num))
		return -ERANGE;
	pa->partno = num;
	return 0;
}

/**
 * fdisk_partition_unset_partno:
 * @pa: partition
 *
 * Sets the partno as undefined. See fdisk_partition_has_partno().
 *
 * Returns: 0 on success, <0 on error.
 */
int fdisk_partition_unset_partno(struct fdisk_partition *pa)
{
	if (!pa)
		return -EINVAL;
	FDISK_INIT_UNDEF(pa->partno);
	return 0;
}

/**
 * fdisk_partition_get_partno:
 * @pa: partition
 *
 * The zero is also valid partition number. The function may return random
 * value when partno is undefined (for example after fdisk_partition_unset_partno()).
 * Always use fdisk_partition_has_partno() to be sure that you work with valid
 * numbers.
 *
 * Returns: partition number (0 is the first partition)
 */
size_t fdisk_partition_get_partno(struct fdisk_partition *pa)
{
	return pa->partno;
}

/**
 * fdisk_partition_has_partno:
 * @pa: partition
 *
 * Returns: 1 or 0
 */
int fdisk_partition_has_partno(struct fdisk_partition *pa)
{
	return pa && !FDISK_IS_UNDEF(pa->partno);
}


/**
 * fdisk_partition_cmp_partno:
 * @a: partition
 * @b: partition
 *
 * Compares partitions according to partition number See fdisk_table_sort_partitions().
 *
 * Return: 0 if the same, <0 if @b greater, >0 if @a greater.
 */
int fdisk_partition_cmp_partno(struct fdisk_partition *a,
			       struct fdisk_partition *b)
{
	return a->partno - b->partno;
}

/**
 * fdisk_partition_partno_follow_default
 * @pa: partition
 * @enable: 0|1
 *
 * When @pa used as a template for fdisk_add_partition() when force label driver
 * to add a new partition to the default (next) position.
 *
 * Returns: 0 on success, <0 on error.
 */
int fdisk_partition_partno_follow_default(struct fdisk_partition *pa, int enable)
{
	if (!pa)
		return -EINVAL;
	pa->partno_follow_default = enable ? 1 : 0;
	return 0;
}

/**
 * fdisk_partition_set_type:
 * @pa: partition
 * @type: partition type
 *
 * Sets partition type.
 *
 * Returns: 0 on success, <0 on error.
 */
int fdisk_partition_set_type(struct fdisk_partition *pa,
			     struct fdisk_parttype *type)
{
	if (!pa)
		return -EINVAL;

	fdisk_ref_parttype(type);
	fdisk_unref_parttype(pa->type);
	pa->type = type;

	return 0;
}

/**
 * fdisk_partition_get_type:
 * @pa: partition
 *
 * Returns: pointer to partition type.
 */
struct fdisk_parttype *fdisk_partition_get_type(struct fdisk_partition *pa)
{
	return pa ? pa->type : NULL;
}

int fdisk_partition_set_name(struct fdisk_partition *pa, const char *name)
{
	char *p = NULL;

	if (!pa)
		return -EINVAL;
	if (name) {
	       p = strdup(name);
	       if (!p)
		       return -ENOMEM;
	}
	free(pa->name);
	pa->name = p;
	return 0;
}

const char *fdisk_partition_get_name(struct fdisk_partition *pa)
{
	return pa ? pa->name : NULL;
}

int fdisk_partition_set_uuid(struct fdisk_partition *pa, const char *uuid)
{
	char *p = NULL;

	if (!pa)
		return -EINVAL;
	if (uuid) {
	       p = strdup(uuid);
	       if (!p)
		       return -ENOMEM;
	}
	free(pa->uuid);
	pa->uuid = p;
	return 0;
}

/**
 * fdisk_partition_has_end:
 * @pa: partition
 *
 * Returns: 1 if the partition has defined last sector
 */
int fdisk_partition_has_end(struct fdisk_partition *pa)
{
	return pa && !FDISK_IS_UNDEF(pa->start) && !FDISK_IS_UNDEF(pa->size);
}

/**
 * fdisk_partition_get_end:
 * @pa: partition
 *
 * This function may returns absolute non-sense, always check
 * fdisk_partition_has_end().
 *
 * Note that partition end is defined by fdisk_partition_set_start() and
 * fdisk_partition_set_size().
 *
 * Returns: last partition sector LBA.
 */
fdisk_sector_t fdisk_partition_get_end(struct fdisk_partition *pa)
{
	return pa->start + pa->size - (pa->size == 0 ? 0 : 1);
}

/**
 * fdisk_partition_end_follow_default
 * @pa: partition
 * @enable: 0|1
 *
 * When @pa used as a template for fdisk_add_partition() when force label
 * driver to use all the possible space for the new partition.
 *
 * Returns: 0 on success, <0 on error.
 */
int fdisk_partition_end_follow_default(struct fdisk_partition *pa, int enable)
{
	if (!pa)
		return -EINVAL;
	pa->end_follow_default = enable ? 1 : 0;
	return 0;
}

/**
 * fdisk_partition_end_is_default:
 * @pa: partition
 *
 * Returns: 1 if the partition follows default
 */
int fdisk_partition_end_is_default(struct fdisk_partition *pa)
{
	assert(pa);
	return pa->end_follow_default;
}

/**
 * fdisk_partition_get_uuid:
 * @pa: partition
 *
 * Returns: partition UUID as string
 */
const char *fdisk_partition_get_uuid(struct fdisk_partition *pa)
{
	return pa ? pa->uuid : NULL;
}

/**
 * fdisk_partition_get_attrs:
 * @pa: partition
 *
 * Returns: partition attributes in string format
 */
const char *fdisk_partition_get_attrs(struct fdisk_partition *pa)
{
	return pa ? pa->attrs : NULL;
}

/**
 * fdisk_partition_set_attrs:
 * @pa: partition
 * @attrs: attributes
 *
 * Sets @attrs to @pa.
 *
 * Return: 0 on success, <0 on error.
 */
int fdisk_partition_set_attrs(struct fdisk_partition *pa, const char *attrs)
{
	char *p = NULL;

	if (!pa)
		return -EINVAL;
	if (attrs) {
	       p = strdup(attrs);
	       if (!p)
		       return -ENOMEM;
	}
	free(pa->attrs);
	pa->attrs = p;
	return 0;
}

/**
 * fdisk_partition_is_nested:
 * @pa: partition
 *
 * Returns: 1 if the partition is nested (e.g. MBR logical partition)
 */
int fdisk_partition_is_nested(struct fdisk_partition *pa)
{
	return pa && !FDISK_IS_UNDEF(pa->parent_partno);
}

/**
 * fdisk_partition_is_container:
 * @pa: partition
 *
 * Returns: 1 if the partition is container (e.g. MBR extended partition)
 */
int fdisk_partition_is_container(struct fdisk_partition *pa)
{
	return pa && pa->container;
}

/**
 * fdisk_partition_get_parent:
 * @pa: partition
 * @parent: parent parno
 *
 * Returns: returns devno of the parent
 */
int fdisk_partition_get_parent(struct fdisk_partition *pa, size_t *parent)
{
	if (pa && parent)
		*parent = pa->parent_partno;
	else
		return -EINVAL;
	return 0;
}

/**
 * fdisk_partition_is_used:
 * @pa: partition
 *
 * Returns: 1 if the partition points to some area
 */
int fdisk_partition_is_used(struct fdisk_partition *pa)
{
	return pa && pa->used;
}

/**
 * fdisk_partition_is_bootable:
 * @pa: partition
 *
 * Returns: 1 if the partition has enabled boot flag
 */
int fdisk_partition_is_bootable(struct fdisk_partition *pa)
{
	return pa && pa->boot == 1;
}

/**
 * fdisk_partition_is_freespace:
 * @pa: partition
 *
 * Returns: 1 if @pa points to freespace
 */
int fdisk_partition_is_freespace(struct fdisk_partition *pa)
{
	return pa && pa->freespace;
}

/**
 * fdisk_partition_is_wholedisk:
 * @pa: partition
 *
 * Returns: 1 if the partition is special whole-disk (e.g. SUN) partition
 */
int fdisk_partition_is_wholedisk(struct fdisk_partition *pa)
{
	return pa && pa->wholedisk;
}

/**
 * fdisk_partition_next_partno:
 * @pa: partition
 * @cxt: context
 * @n: returns partition number
 *
 * If partno-follow-default (see fdisk_partition_partno_follow_default())
 * enabled then returns next expected partno, otherwise use Ask API to ask user
 * for the next partno.
 *
 * Returns: 0 on success, <0 on error
 */
int fdisk_partition_next_partno(
		struct fdisk_partition *pa,
		struct fdisk_context *cxt,
		size_t *n)
{
	if (!cxt || !n)
		return -EINVAL;

	if (pa && pa->partno_follow_default) {
		size_t i;

		DBG(PART, ul_debugobj(pa, "next partno (follow default)"));

		for (i = 0; i < cxt->label->nparts_max; i++) {
			if (!fdisk_is_partition_used(cxt, i)) {
				*n = i;
				return 0;
			}
		}
		return -ERANGE;

	} else if (pa && fdisk_partition_has_partno(pa)) {

		DBG(PART, ul_debugobj(pa, "next partno (specified=%zu)", pa->partno));

		if (pa->partno >= cxt->label->nparts_max)
			return -ERANGE;
		*n = pa->partno;
	} else
		return fdisk_ask_partnum(cxt, n, 1);

	return 0;
}

static int probe_partition_content(struct fdisk_context *cxt, struct fdisk_partition *pa)
{
	int rc = 1;	/* nothing */

	DBG(PART, ul_debugobj(pa, "start probe #%zu partition [cxt %p] >>>", pa->partno, cxt));

	/* zeroize the current setting */
	strdup_to_struct_member(pa, fstype, NULL);
	strdup_to_struct_member(pa, fsuuid, NULL);
	strdup_to_struct_member(pa, fslabel, NULL);

	if (!fdisk_partition_has_start(pa) ||
	    !fdisk_partition_has_size(pa))
		goto done;

#ifdef HAVE_LIBBLKID
	else {
		uintmax_t start, size;

		blkid_probe pr = blkid_new_probe();
		if (!pr)
			goto done;

		DBG(PART, ul_debugobj(pa, "blkid prober: %p", pr));

		start = fdisk_partition_get_start(pa) * fdisk_get_sector_size(cxt);
		size = fdisk_partition_get_size(pa) * fdisk_get_sector_size(cxt);

		if (blkid_probe_set_device(pr, cxt->dev_fd, start, size) == 0
		    && blkid_do_fullprobe(pr) == 0) {

			const char *data;
			rc = 0;

			if (!blkid_probe_lookup_value(pr, "TYPE",  &data, NULL))
				rc = strdup_to_struct_member(pa, fstype, data);

			if (!rc && !blkid_probe_lookup_value(pr, "LABEL", &data, NULL))
				rc = strdup_to_struct_member(pa, fslabel, data);

			if (!rc && !blkid_probe_lookup_value(pr, "UUID",  &data, NULL))
				rc = strdup_to_struct_member(pa, fsuuid, data);
		}

		blkid_free_probe(pr);
		pa->fs_probed = 1;
	}
#endif /* HAVE_LIBBLKID */

done:
	DBG(PART, ul_debugobj(pa, "<<< end probe #%zu partition[cxt %p, rc=%d]", pa->partno, cxt, rc));
	return rc;
}

/**
 * fdisk_partition_to_string:
 * @pa: partition
 * @cxt: context
 * @id: field (FDISK_FIELD_*)
 * @data: returns string with allocated data
 *
 * Returns info about partition converted to printable string.
 *
 * For example
 * <informalexample>
 *   <programlisting>
 *      struct fdisk_partition *pa;
 *
 *      fdisk_get_partition(cxt, 0, &pa);
 *	fdisk_partition_to_string(pa, FDISK_FIELD_UUID, &data);
 *	printf("first partition uuid: %s\n", data);
 *	free(data);
 *	fdisk_unref_partition(pa);
 *   </programlisting>
 * </informalexample>
 *
 * returns UUID for the first partition.
 *
 * Returns: 0 on success, otherwise, a corresponding error.
 */
int fdisk_partition_to_string(struct fdisk_partition *pa,
			      struct fdisk_context *cxt,
			      int id,
			      char **data)
{
	char *p = NULL;
	int rc = 0;
	uint64_t x;

	if (!pa || !cxt || !data)
		return -EINVAL;

	switch (id) {
	case FDISK_FIELD_DEVICE:
		if (pa->freespace)
			p = strdup(_("Free space"));
		else if (fdisk_partition_has_partno(pa) && cxt->dev_path) {
			if (cxt->label->flags & FDISK_LABEL_FL_INCHARS_PARTNO)
				rc = asprintf(&p, "%c", (int) pa->partno + 'a');
			else
				p = fdisk_partname(cxt->dev_path, pa->partno + 1);
		}
		break;
	case FDISK_FIELD_BOOT:
		p = fdisk_partition_is_bootable(pa) ? strdup("*") : NULL;
		break;
	case FDISK_FIELD_START:
		if (fdisk_partition_has_start(pa)) {
			x = fdisk_cround(cxt, pa->start);
			rc = pa->start_post ?
				asprintf(&p, "%"PRIu64"%c", x, pa->start_post) :
				asprintf(&p, "%"PRIu64, x);
		}
		break;
	case FDISK_FIELD_END:
		if (fdisk_partition_has_end(pa)) {
			x = fdisk_cround(cxt, fdisk_partition_get_end(pa));
			rc = pa->end_post ?
					asprintf(&p, "%"PRIu64"%c", x, pa->end_post) :
					asprintf(&p, "%"PRIu64, x);
		}
		break;
	case FDISK_FIELD_SIZE:
		if (fdisk_partition_has_size(pa)) {
			uint64_t sz = pa->size * cxt->sector_size;

			switch (cxt->sizeunit) {
			case FDISK_SIZEUNIT_BYTES:
				rc = asprintf(&p, "%"PRIu64"", sz);
				break;
			case FDISK_SIZEUNIT_HUMAN:
				if (fdisk_is_details(cxt))
					rc = pa->size_post ?
							asprintf(&p, "%"PRIu64"%c", sz, pa->size_post) :
							asprintf(&p, "%"PRIu64, sz);
				else {
					p = size_to_human_string(SIZE_SUFFIX_1LETTER, sz);
					if (!p)
						rc = -ENOMEM;
				}
				break;
			}
		}
		break;
	case FDISK_FIELD_CYLINDERS:
	{
		uintmax_t sz = fdisk_partition_has_size(pa) ? pa->size : 0;
		if (sz)
			/* Why we need to cast that to uintmax_t? */
			rc = asprintf(&p, "%ju", (uintmax_t)(sz / (cxt->geom.heads * cxt->geom.sectors)) + 1);
		break;
	}
	case FDISK_FIELD_SECTORS:
		rc = asprintf(&p, "%ju",
			fdisk_partition_has_size(pa) ? (uintmax_t) pa->size : 0);
		break;
	case FDISK_FIELD_BSIZE:
		rc = asprintf(&p, "%"PRIu64, pa->bsize);
		break;
	case FDISK_FIELD_FSIZE:
		rc = asprintf(&p, "%"PRIu64, pa->fsize);
		break;
	case FDISK_FIELD_CPG:
		rc = asprintf(&p, "%"PRIu64, pa->cpg);
		break;
	case FDISK_FIELD_TYPE:
		p = pa->type && pa->type->name ? strdup(_(pa->type->name)) : NULL;
		break;
	case FDISK_FIELD_TYPEID:
		if (pa->type && fdisk_parttype_get_string(pa->type))
			rc = asprintf(&p, "%s", fdisk_parttype_get_string(pa->type));
		else if (pa->type)
			rc = asprintf(&p, "%x", fdisk_parttype_get_code(pa->type));
		break;
	case FDISK_FIELD_UUID:
		p = pa->uuid && *pa->uuid? strdup(pa->uuid) : NULL;
		break;
	case FDISK_FIELD_NAME:
		p = pa->name && *pa->name ? strdup(pa->name) : NULL;
		break;
	case FDISK_FIELD_ATTR:
		p = pa->attrs && *pa->attrs ? strdup(pa->attrs) : NULL;
		break;
	case FDISK_FIELD_SADDR:
		p = pa->start_chs && *pa->start_chs ? strdup(pa->start_chs) : NULL;
		break;
	case FDISK_FIELD_EADDR:
		p = pa->end_chs && *pa->end_chs? strdup(pa->end_chs) : NULL;
		break;
	case FDISK_FIELD_FSUUID:
		if (pa->fs_probed || probe_partition_content(cxt, pa) == 0)
			p = pa->fsuuid && *pa->fsuuid ? strdup(pa->fsuuid) : NULL;
		break;
	case FDISK_FIELD_FSLABEL:
		if (pa->fs_probed || probe_partition_content(cxt, pa) == 0)
			p = pa->fslabel && *pa->fslabel ? strdup(pa->fslabel) : NULL;
		break;
	case FDISK_FIELD_FSTYPE:
		if (pa->fs_probed || probe_partition_content(cxt, pa) == 0)
			p = pa->fstype && *pa->fstype ? strdup(pa->fstype) : NULL;
		break;
	default:
		return -EINVAL;
	}

	if (rc < 0) {
		rc = -ENOMEM;
		free(p);
		p = NULL;

	} else if (rc > 0)
		rc = 0;

	*data = p;

	return rc;
}


/**
 * fdisk_get_partition:
 * @cxt: context
 * @partno: partition number (0 is the first partition)
 * @pa: returns data about partition
 *
 * Reads disklabel and fills in @pa with data about partition @n.
 *
 * Note that partno may address unused partition and then this function does
 * not fill anything to @pa.  See fdisk_is_partition_used(). If @pa points to
 * NULL then the function allocates a newly allocated fdisk_partition struct,
 * use fdisk_unref_partition() to deallocate.
 *
 * Returns: 0 on success, otherwise, a corresponding error.
 */
int fdisk_get_partition(struct fdisk_context *cxt, size_t partno,
			struct fdisk_partition **pa)
{
	int rc;
	struct fdisk_partition *np = NULL;

	if (!cxt || !cxt->label || !pa)
		return -EINVAL;
	if (!cxt->label->op->get_part)
		return -ENOSYS;
	if (!fdisk_is_partition_used(cxt, partno))
		return -EINVAL;

	if (!*pa) {
		np = *pa = fdisk_new_partition();
		if (!*pa)
			return -ENOMEM;
	} else
		fdisk_reset_partition(*pa);

	(*pa)->partno = partno;
	rc = cxt->label->op->get_part(cxt, partno, *pa);

	if (rc) {
		if (np) {
			fdisk_unref_partition(np);
			*pa = NULL;
		} else
			fdisk_reset_partition(*pa);
	} else
		(*pa)->size_explicit = 1;
	return rc;
}

static struct fdisk_partition *resize_get_by_offset(
			struct fdisk_table *tb, fdisk_sector_t off)
{
	struct fdisk_partition *pa = NULL;
	struct fdisk_iter itr;

	fdisk_reset_iter(&itr, FDISK_ITER_FORWARD);

	while (fdisk_table_next_partition(tb, &itr, &pa) == 0) {
		if (!fdisk_partition_has_start(pa) || !fdisk_partition_has_size(pa))
			continue;
		if (off >= pa->start && off < pa->start + pa->size)
			return pa;
	}

	return NULL;
}

/*
 * Verify that area addressed by @start is freespace or the @cur[rent]
 * partition and continue to the next table entries until it's freespace, and
 * counts size of all this space.
 *
 * This is core of the partition start offset move operation. We can move the
 * start within the current partition of to the another free space. It's
 * forbidden to move start of the partition to another already defined
 * partition.
 */
static int resize_get_last_possible(
			struct fdisk_table *tb,
			struct fdisk_partition *cur,
			fdisk_sector_t start,
			fdisk_sector_t *maxsz)
{
	struct fdisk_partition *pa = NULL, *last = NULL;
	struct fdisk_iter itr;

	fdisk_reset_iter(&itr, FDISK_ITER_FORWARD);

	*maxsz = 0;

	while (fdisk_table_next_partition(tb, &itr, &pa) == 0) {
		if (!fdisk_partition_has_start(pa) ||
		    !fdisk_partition_has_size(pa) ||
		    fdisk_partition_is_container(pa))
			continue;

		DBG(PART, ul_debugobj(pa, "checking start=%ju, size=%ju",
		                      (uintmax_t)pa->start, (uintmax_t)pa->size));

		if (!last) {
			if (start >= pa->start &&  start < pa->start + pa->size) {
				if (fdisk_partition_is_freespace(pa) || pa == cur)
					last = pa;
				else
					break;

				*maxsz = pa->size - (start - pa->start);
			}
		} else if (!fdisk_partition_is_freespace(pa) && pa != cur) {
			break;
		} else {
			last = pa;
			*maxsz += pa->size;
		}
	}

	if (last)
		DBG(PART, ul_debugobj(cur, "resize: max size=%ju", (uintmax_t) *maxsz));
	else
		DBG(PART, ul_debugobj(cur, "resize: nothing usable after %ju", (uintmax_t) start));

	return last ? 0 : -1;
}

/*
 * Uses template @tpl to recount start and size change of the partition @res. The
 * @tpl->size and @tpl->start are interpreted as relative to the current setting.
 */
static int recount_resize(
			struct fdisk_context *cxt, size_t partno,
			struct fdisk_partition *res, struct fdisk_partition *tpl)
{
	fdisk_sector_t start, size, xsize;
	struct fdisk_partition *cur = NULL;
	struct fdisk_table *tb = NULL;
	int rc;

	DBG(PART, ul_debugobj(tpl, ">>> resize requested"));

	FDISK_INIT_UNDEF(start);
	FDISK_INIT_UNDEF(size);

	rc = fdisk_get_partitions(cxt, &tb);
	if (!rc)
		rc = fdisk_get_freespaces(cxt, &tb);
	if (rc)
		return rc;

	cur = fdisk_table_get_partition_by_partno(tb, partno);
	if (!cur) {
		fdisk_unref_table(tb);
		return -EINVAL;
	}

	/* 1a) set new start - change relative to the current on-disk setting */
	if (tpl->movestart && fdisk_partition_has_start(tpl)) {
		start = fdisk_partition_get_start(cur);
		if (tpl->movestart == FDISK_MOVE_DOWN) {
			if (fdisk_partition_get_start(tpl) > start)
				goto erange;
			start -= fdisk_partition_get_start(tpl);
		} else
			start += fdisk_partition_get_start(tpl);

		DBG(PART, ul_debugobj(tpl, "resize: moving start %s relative, new start: %ju",
				tpl->movestart == FDISK_MOVE_DOWN  ? "DOWN" : "UP", (uintmax_t)start));

	/* 1b) set new start - absolute number */
	} else if (fdisk_partition_has_start(tpl)) {
		start = fdisk_partition_get_start(tpl);
		DBG(PART, ul_debugobj(tpl, "resize: moving start to absolute offset: %ju",
		                      (uintmax_t)start));
	}

	/* 2) verify that start is within the current partition or any freespace area */
	if (!FDISK_IS_UNDEF(start)) {
		struct fdisk_partition *area = resize_get_by_offset(tb, start);
		if (area == cur)
			DBG(PART, ul_debugobj(tpl, "resize: start points to the current partition"));
		else if (area && fdisk_partition_is_freespace(area))
			DBG(PART, ul_debugobj(tpl, "resize: start points to freespace"));
		else if (!area && start >= cxt->first_lba && start < cxt->first_lba + (cxt->grain / cxt->sector_size))
			DBG(PART, ul_debugobj(tpl, "resize: start points before first partition"));
		else
			goto erange;
	} else {
		/* no change, start points to the current partition */
		DBG(PART, ul_debugobj(tpl, "resize: start unchanged"));
		start = fdisk_partition_get_start(cur);
	}

	/* 3a) set new size -- reduce */
	if (tpl->resize == FDISK_RESIZE_REDUCE && fdisk_partition_has_size(tpl)) {
		DBG(PART, ul_debugobj(tpl, "resize: reduce"));
		size = fdisk_partition_get_size(cur);
		if (fdisk_partition_get_size(tpl) > size)
			goto erange;
		size -= fdisk_partition_get_size(tpl);

	/* 3b) set new size -- enlarge */
	} else if (tpl->resize == FDISK_RESIZE_ENLARGE && fdisk_partition_has_size(tpl)) {
		DBG(PART, ul_debugobj(tpl, "resize: enlarge"));
		size = fdisk_partition_get_size(cur);
		size += fdisk_partition_get_size(tpl);

	/* 3c) set new size -- no size specified, enlarge to all freespace */
	} else if (tpl->resize == FDISK_RESIZE_ENLARGE) {
		DBG(PART, ul_debugobj(tpl, "resize: enlarge to all possible"));
		if (resize_get_last_possible(tb, cur, start, &size))
			goto erange;

	/* 3d) set new size -- absolute number */
	} else if (fdisk_partition_has_size(tpl)) {
		DBG(PART, ul_debugobj(tpl, "resize: new absolute size"));
		size = fdisk_partition_get_size(tpl);
	}

	/* 4) verify that size is within the current partition or next free space */
	xsize = !FDISK_IS_UNDEF(size) ? size : fdisk_partition_get_size(cur);

	if (fdisk_partition_has_size(cur)) {
		fdisk_sector_t maxsz;

		if (resize_get_last_possible(tb, cur, start, &maxsz))
			goto erange;
		DBG(PART, ul_debugobj(tpl, "resize: size=%ju, max=%ju",
					(uintmax_t) xsize, (uintmax_t) maxsz));
		if (xsize > maxsz)
			goto erange;
	}

	if (!FDISK_IS_UNDEF(size)) {
		DBG(PART, ul_debugobj(tpl, "resize: size unchanged (undefined)"));
	}


	DBG(PART, ul_debugobj(tpl, "<<< resize: SUCCESS: start %ju->%ju; size %ju->%ju",
			(uintmax_t) fdisk_partition_get_start(cur), (uintmax_t) start,
			(uintmax_t) fdisk_partition_get_size(cur), (uintmax_t) size));
	res->start = start;
	res->size = size;
	fdisk_unref_table(tb);
	return 0;
erange:
	DBG(PART, ul_debugobj(tpl, "<<< resize: FAILED"));
	fdisk_warnx(cxt, _("Failed to resize partition #%zu."), partno + 1);
	fdisk_unref_table(tb);
	return -ERANGE;

}

/**
 * fdisk_set_partition:
 * @cxt: context
 * @partno: partition number (0 is the first partition)
 * @pa: new partition setting
 *
 * Modifies disklabel according to setting with in @pa.
 *
 * Returns: 0 on success, <0 on error.
 */
int fdisk_set_partition(struct fdisk_context *cxt, size_t partno,
			struct fdisk_partition *pa)
{
	struct fdisk_partition *xpa = pa, *tmp = NULL;
	int rc, wipe = 0;

	if (!cxt || !cxt->label || !pa)
		return -EINVAL;
	if (!cxt->label->op->set_part)
		return -ENOSYS;

	pa->fs_probed = 0;

	if (!fdisk_is_partition_used(cxt, partno)) {
		pa->partno = partno;
		return fdisk_add_partition(cxt, pa, NULL);
	}

	if (pa->resize || fdisk_partition_has_start(pa) || fdisk_partition_has_size(pa)) {
		xpa = __copy_partition(pa);
		xpa->movestart = 0;
		xpa->resize = 0;
		FDISK_INIT_UNDEF(xpa->size);
		FDISK_INIT_UNDEF(xpa->start);

		rc = recount_resize(cxt, partno, xpa, pa);
		if (rc)
			goto done;
	}

	DBG(CXT, ul_debugobj(cxt, "setting partition %zu %p (start=%ju, end=%ju, size=%ju)",
		    partno, xpa,
		    (uintmax_t) fdisk_partition_get_start(xpa),
		    (uintmax_t) fdisk_partition_get_end(xpa),
		    (uintmax_t) fdisk_partition_get_size(xpa)));

	/* disable wipe for old offset/size setting */
	if (fdisk_get_partition(cxt, partno, &tmp) == 0 && tmp) {
		wipe = fdisk_set_wipe_area(cxt, fdisk_partition_get_start(tmp),
						fdisk_partition_get_size(tmp), FALSE);
		fdisk_unref_partition(tmp);
	}

	/* call label driver */
	rc = cxt->label->op->set_part(cxt, partno, xpa);

	/* enable wipe for new offset/size */
	if (!rc && wipe)
		fdisk_wipe_partition(cxt, partno, TRUE);
done:
	DBG(CXT, ul_debugobj(cxt, "set_partition() rc=%d", rc));
	if (xpa != pa)
		fdisk_unref_partition(xpa);
	return rc;
}

/**
 * fdisk_wipe_partition:
 * @cxt: fdisk context
 * @partno: partition number
 * @enable: 0 or 1
 *
 * Enable/disable filesystems/RAIDs wiping in area defined by partition start and size.
 *
 * Returns: <0 in case of error, 0 on success
 * Since: 2.29
 */
int fdisk_wipe_partition(struct fdisk_context *cxt, size_t partno, int enable)
{
	struct fdisk_partition *pa = NULL;
	int rc;

	rc = fdisk_get_partition(cxt, partno, &pa);
	if (rc)
		return rc;

	rc = fdisk_set_wipe_area(cxt, fdisk_partition_get_start(pa),
				      fdisk_partition_get_size(pa), enable);
	fdisk_unref_partition(pa);
	return rc < 0 ? rc : 0;
}


/**
 * fdisk_add_partition:
 * @cxt: fdisk context
 * @pa: template for the partition (or NULL)
 * @partno: NULL or returns new partition number
 *
 * If @pa is not specified or any @pa item is missing the libfdisk will ask by
 * fdisk_ask_ API.
 *
 * Adds a new partition to disklabel.
 *
 * Returns: 0 on success, <0 on error.
 */
int fdisk_add_partition(struct fdisk_context *cxt,
			struct fdisk_partition *pa,
			size_t *partno)
{
	int rc;

	if (!cxt || !cxt->label)
		return -EINVAL;
	if (!cxt->label->op->add_part)
		return -ENOSYS;
	if (fdisk_missing_geometry(cxt))
		return -EINVAL;

	if (pa) {
		pa->fs_probed = 0;
		DBG(CXT, ul_debugobj(cxt, "adding new partition %p (start=%ju, end=%ju, size=%ju, "
			    "defaults(start=%s, end=%s, partno=%s)",
			    pa,
			    (uintmax_t) fdisk_partition_get_start(pa),
			    (uintmax_t) fdisk_partition_get_end(pa),
			    (uintmax_t) fdisk_partition_get_size(pa),
			    pa->start_follow_default ? "yes" : "no",
			    pa->end_follow_default ? "yes" : "no",
			    pa->partno_follow_default ? "yes" : "no"));
	} else
		DBG(CXT, ul_debugobj(cxt, "adding partition"));

	rc = cxt->label->op->add_part(cxt, pa, partno);

	DBG(CXT, ul_debugobj(cxt, "add partition done (rc=%d)", rc));
	return rc;
}

/**
 * fdisk_delete_partition:
 * @cxt: fdisk context
 * @partno: partition number to delete (0 is the first partition)
 *
 * Deletes a @partno partition from disklabel.
 *
 * Returns: 0 on success, <0 on error
 */
int fdisk_delete_partition(struct fdisk_context *cxt, size_t partno)
{
	if (!cxt || !cxt->label)
		return -EINVAL;
	if (!cxt->label->op->del_part)
		return -ENOSYS;

	fdisk_wipe_partition(cxt, partno, 0);

	DBG(CXT, ul_debugobj(cxt, "deleting %s partition number %zd",
				cxt->label->name, partno));
	return cxt->label->op->del_part(cxt, partno);
}

/**
 * fdisk_delete_all_partitions:
 * @cxt: fdisk context
 *
 * Delete all used partitions from disklabel.
 *
 * Returns: 0 on success, otherwise, a corresponding error.
 */
int fdisk_delete_all_partitions(struct fdisk_context *cxt)
{
	size_t i;
	int rc = 0;

	if (!cxt || !cxt->label)
		return -EINVAL;

	for (i = 0; i < cxt->label->nparts_max; i++) {

		if (!fdisk_is_partition_used(cxt, i))
			continue;
		rc = fdisk_delete_partition(cxt, i);
		if (rc)
			break;
	}

	return rc;
}

/**
 * fdisk_is_partition_used:
 * @cxt: context
 * @n: partition number (0 is the first partition)
 *
 * This is faster than fdisk_get_partition() + fdisk_partition_is_used().
 *
 * Returns: 0 or 1
 */
int fdisk_is_partition_used(struct fdisk_context *cxt, size_t n)
{
	if (!cxt || !cxt->label)
		return -EINVAL;
	if (!cxt->label->op->part_is_used)
		return -ENOSYS;

	return cxt->label->op->part_is_used(cxt, n);
}

