/*
 * partitions - partition tables parsing
 *
 * Copyright (C) 2008-2009 Karel Zak <kzak@redhat.com>
 *
 * This file may be redistributed under the terms of the
 * GNU Lesser General Public License.
 *
 */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <stdint.h>
#include <inttypes.h>
#include <stdarg.h>

#include "partitions.h"
#include "sysfs.h"

/**
 * SECTION: partitions
 * @title: Partitions probing
 * @short_description: partitions tables detection and parsing
 *
 * This chain supports binary and NAME=value interfaces, but complete PT
 * description is provided by binary interface only. The libblkid prober is
 * compatible with kernel partition tables parser. The parser does not return
 * empty (size=0) partitions or special hidden partitions.
 *
 * NAME=value interface, supported tags:
 *
 * @PTTYPE: partition table type (dos, gpt, etc.).
 *
 * @PTUUID: partition table id (uuid for gpt, hex for dos).

 * @PART_ENTRY_SCHEME: partition table type
 *
 * @PART_ENTRY_NAME: partition name (gpt and mac only)
 *
 * @PART_ENTRY_UUID: partition UUID (gpt, or pseudo IDs for MBR)
 *
 * @PART_ENTRY_TYPE: partition type, 0xNN (e.g 0x82) or type UUID (gpt only) or type string (mac)
 *
 * @PART_ENTRY_FLAGS: partition flags (e.g. boot_ind) or  attributes (e.g. gpt attributes)
 *
 * @PART_ENTRY_NUMBER: partition number
 *
 * @PART_ENTRY_OFFSET: the begin of the partition
 *
 * @PART_ENTRY_SIZE: size of the partition
 *
 * @PART_ENTRY_DISK: whole-disk maj:min
 *
 * Example:
 *
 * <informalexample>
 *  <programlisting>
 * blkid_probe pr;
 * const char *ptname;
 *
 * pr = blkid_new_probe_from_filename(devname);
 * if (!pr)
 *	err("%s: failed to open device", devname);
 *
 * blkid_probe_enable_partitions(pr, TRUE);
 * blkid_do_fullprobe(pr);
 *
 * blkid_probe_lookup_value(pr, "PTTYPE", &ptname, NULL);
 * printf("%s partition type detected\n", pttype);
 *
 * blkid_free_probe(pr);
 *
 * // don't forget to check return codes in your code!
 *  </programlisting>
 * </informalexample>
 *
 * Binary interface:
 *
 * <informalexample>
 *  <programlisting>
 * blkid_probe pr;
 * blkid_partlist ls;
 * int nparts, i;
 *
 * pr = blkid_new_probe_from_filename(devname);
 * if (!pr)
 *	err("%s: failed to open device", devname);
 *
 * ls = blkid_probe_get_partitions(pr);
 * nparts = blkid_partlist_numof_partitions(ls);
 *
 * for (i = 0; i < nparts; i++) {
 *      blkid_partition par = blkid_partlist_get_partition(ls, i);
 *      printf("#%d: %llu %llu  0x%x",
 *               blkid_partition_get_partno(par),
 *               blkid_partition_get_start(par),
 *               blkid_partition_get_size(par),
 *               blkid_partition_get_type(par));
 * }
 *
 * blkid_free_probe(pr);
 *
 * // don't forget to check return codes in your code!
 *  </programlisting>
 * </informalexample>
 */

/*
 * Chain driver function
 */
static int partitions_probe(blkid_probe pr, struct blkid_chain *chn);
static void partitions_free_data(blkid_probe pr, void *data);

/*
 * Partitions chain probing functions
 */
static const struct blkid_idinfo *idinfos[] =
{
	&aix_pt_idinfo,
	&sgi_pt_idinfo,
	&sun_pt_idinfo,
	&dos_pt_idinfo,
	&gpt_pt_idinfo,
	&pmbr_pt_idinfo,	/* always after GPT */
	&mac_pt_idinfo,
	&ultrix_pt_idinfo,
	&bsd_pt_idinfo,
	&unixware_pt_idinfo,
	&solaris_x86_pt_idinfo,
	&minix_pt_idinfo
};

/*
 * Driver definition
 */
const struct blkid_chaindrv partitions_drv = {
	.id           = BLKID_CHAIN_PARTS,
	.name         = "partitions",
	.dflt_enabled = FALSE,
	.idinfos      = idinfos,
	.nidinfos     = ARRAY_SIZE(idinfos),
	.has_fltr     = TRUE,
	.probe        = partitions_probe,
	.safeprobe    = partitions_probe,
	.free_data    = partitions_free_data
};


/*
 * For compatibility with the rest of libblkid API (with the old high-level
 * API) we use completely opaque typedefs for all structs. Don't forget that
 * the final blkid_* types are pointers! See blkid.h.
 *
 * [Just for the record, I hate typedef for pointers --kzak]
 */

/* exported as opaque type "blkid_parttable" */
struct blkid_struct_parttable {
	const char	*type;		/* partition table type */
	uint64_t	offset;		/* begin of the partition table (in bytes) */
	int		nparts;		/* number of partitions */
	blkid_partition	parent;		/* parent of nested partition table */
	char		id[37];		/* PT identifier (e.g. UUID for GPT) */

	struct list_head t_tabs;	/* all tables */
};

/* exported as opaque type "blkid_partition" */
struct blkid_struct_partition {
	uint64_t	start;		/* begin of the partition (512-bytes sectors) */
	uint64_t	size;		/* size of the partitions (512-bytes sectors) */

	int		type;		/* partition type */
	char		typestr[37];	/* partition type string (GPT and Mac) */

	unsigned long long flags;	/* partition flags / attributes */

	int		partno;		/* partition number */
	char		uuid[37];	/* UUID (when supported by PT), e.g GPT */
	unsigned char	name[128];	/* Partition in UTF8 name (when supported by PT), e.g. Mac */

	blkid_parttable	tab;		/* partition table */
};

/* exported as opaque type "blkid_partlist" */
struct blkid_struct_partlist {
	int		next_partno;	/* next partition number */
	blkid_partition next_parent;	/* next parent if parsing nested PT */

	int		nparts;		/* number of partitions */
	int		nparts_max;	/* max.number of partitions */
	blkid_partition	parts;		/* array of partitions */

	struct list_head l_tabs;	/* list of partition tables */
};

static int blkid_partitions_probe_partition(blkid_probe pr);

/**
 * blkid_probe_enable_partitions:
 * @pr: probe
 * @enable: TRUE/FALSE
 *
 * Enables/disables the partitions probing for non-binary interface.
 *
 * Returns: 0 on success, or -1 in case of error.
 */
int blkid_probe_enable_partitions(blkid_probe pr, int enable)
{
	pr->chains[BLKID_CHAIN_PARTS].enabled = enable;
	return 0;
}

/**
 * blkid_probe_set_partitions_flags:
 * @pr: prober
 * @flags: BLKID_PARTS_* flags
 *
 * Sets probing flags to the partitions prober. This function is optional.
 *
 * Returns: 0 on success, or -1 in case of error.
 */
int blkid_probe_set_partitions_flags(blkid_probe pr, int flags)
{
	pr->chains[BLKID_CHAIN_PARTS].flags = flags;
	return 0;
}

/**
 * blkid_probe_reset_partitions_filter:
 * @pr: prober
 *
 * Resets partitions probing filter
 *
 * Returns: 0 on success, or -1 in case of error.
 */
int blkid_probe_reset_partitions_filter(blkid_probe pr)
{
	return __blkid_probe_reset_filter(pr, BLKID_CHAIN_PARTS);
}

/**
 * blkid_probe_invert_partitions_filter:
 * @pr: prober
 *
 * Inverts partitions probing filter
 *
 * Returns: 0 on success, or -1 in case of error.
 */
int blkid_probe_invert_partitions_filter(blkid_probe pr)
{
	return __blkid_probe_invert_filter(pr, BLKID_CHAIN_PARTS);
}

/**
 * blkid_probe_filter_partitions_type:
 * @pr: prober
 * @flag: filter BLKID_FLTR_{NOTIN,ONLYIN} flag
 * @names: NULL terminated array of probing function names (e.g. "vfat").
 *
 *  %BLKID_FLTR_NOTIN  - probe for all items which are NOT IN @names
 *
 *  %BLKID_FLTR_ONLYIN - probe for items which are IN @names
 *
 * Returns: 0 on success, or -1 in case of error.
 */
int blkid_probe_filter_partitions_type(blkid_probe pr, int flag, char *names[])
{
	return __blkid_probe_filter_types(pr, BLKID_CHAIN_PARTS, flag, names);
}

/**
 * blkid_probe_get_partitions:
 * @pr: probe
 *
 * This is a binary interface for partitions. See also blkid_partlist_*
 * functions.
 *
 * This function is independent on blkid_do_[safe,full]probe() and
 * blkid_probe_enable_partitions() calls.
 *
 * WARNING: the returned object will be overwritten by the next
 *          blkid_probe_get_partitions() call for the same @pr. If you want to
 *          use more blkid_partlist objects in the same time you have to create
 *          more blkid_probe handlers (see blkid_new_probe()).
 *
 * Returns: list of partitions, or NULL in case of error.
 */
blkid_partlist blkid_probe_get_partitions(blkid_probe pr)
{
	return (blkid_partlist) blkid_probe_get_binary_data(pr,
			&pr->chains[BLKID_CHAIN_PARTS]);
}

/* for internal usage only */
blkid_partlist blkid_probe_get_partlist(blkid_probe pr)
{
	return (blkid_partlist) pr->chains[BLKID_CHAIN_PARTS].data;
}

static void blkid_probe_set_partlist(blkid_probe pr, blkid_partlist ls)
{
	pr->chains[BLKID_CHAIN_PARTS].data = ls;
}

static void ref_parttable(blkid_parttable tab)
{
	tab->nparts++;
}

static void unref_parttable(blkid_parttable tab)
{
	tab->nparts--;

	if (tab->nparts <= 0) {
		list_del(&tab->t_tabs);
		free(tab);
	}
}

/* free all allocated parttables */
static void free_parttables(blkid_partlist ls)
{
	if (!ls || !ls->l_tabs.next)
		return;

	/* remove unassigned partition tables */
	while (!list_empty(&ls->l_tabs)) {
		blkid_parttable tab = list_entry(ls->l_tabs.next,
					struct blkid_struct_parttable, t_tabs);
		unref_parttable(tab);
	}
}

static void reset_partlist(blkid_partlist ls)
{
	if (!ls)
		return;

	free_parttables(ls);

	if (ls->next_partno) {
		/* already initialized - reset */
		int tmp_nparts = ls->nparts_max;
		blkid_partition tmp_parts = ls->parts;

		memset(ls, 0, sizeof(struct blkid_struct_partlist));

		ls->nparts_max = tmp_nparts;
		ls->parts = tmp_parts;
	}

	ls->nparts = 0;
	ls->next_partno = 1;
	INIT_LIST_HEAD(&ls->l_tabs);

	DBG(LOWPROBE, ul_debug("partlist reset"));
}

static blkid_partlist partitions_init_data(struct blkid_chain *chn)
{
	blkid_partlist ls;

	if (chn->data)
		ls = (blkid_partlist) chn->data;
	else {
		/* allocate the new list of partitions */
		ls = calloc(1, sizeof(struct blkid_struct_partlist));
		if (!ls)
			return NULL;
		chn->data = (void *) ls;
	}

	reset_partlist(ls);

	DBG(LOWPROBE, ul_debug("parts: initialized partitions list (%p, size=%d)",
		ls, ls->nparts_max));
	return ls;
}

static void partitions_free_data(blkid_probe pr __attribute__((__unused__)),
				 void *data)
{
	blkid_partlist ls = (blkid_partlist) data;

	if (!ls)
		return;

	free_parttables(ls);

	/* deallocate partitions and partlist */
	free(ls->parts);
	free(ls);
}

blkid_parttable blkid_partlist_new_parttable(blkid_partlist ls,
				const char *type, uint64_t offset)
{
	blkid_parttable tab;

	tab = calloc(1, sizeof(struct blkid_struct_parttable));
	if (!tab)
		return NULL;
	tab->type = type;
	tab->offset = offset;
	tab->parent = ls->next_parent;

	INIT_LIST_HEAD(&tab->t_tabs);
	list_add_tail(&tab->t_tabs, &ls->l_tabs);

	DBG(LOWPROBE, ul_debug("parts: create a new partition table "
		       "(%p, type=%s, offset=%"PRId64")", tab, type, offset));
	return tab;
}

static blkid_partition new_partition(blkid_partlist ls, blkid_parttable tab)
{
	blkid_partition par;

	if (ls->nparts + 1 > ls->nparts_max) {
		/* Linux kernel has DISK_MAX_PARTS=256, but it's too much for
		 * generic Linux machine -- let start with 32 partitions.
		 */
		void *tmp = realloc(ls->parts, (ls->nparts_max + 32) *
					sizeof(struct blkid_struct_partition));
		if (!tmp)
			return NULL;
		ls->parts = tmp;
		ls->nparts_max += 32;
	}

	par = &ls->parts[ls->nparts++];
	memset(par, 0, sizeof(struct blkid_struct_partition));

	ref_parttable(tab);
	par->tab = tab;
	par->partno = blkid_partlist_increment_partno(ls);

	return par;
}

blkid_partition blkid_partlist_add_partition(blkid_partlist ls,
					blkid_parttable tab, uint64_t start, uint64_t size)
{
	blkid_partition par = new_partition(ls, tab);

	if (!par)
		return NULL;

	par->start = start;
	par->size = size;

	DBG(LOWPROBE, ul_debug("parts: add partition (%p start=%"
		PRIu64 ", size=%" PRIu64 ", table=%p)",
		par, par->start, par->size, tab));
	return par;
}

/* allows to modify used partitions numbers (for example for logical partitions) */
int blkid_partlist_set_partno(blkid_partlist ls, int partno)
{
	if (!ls)
		return -1;
	ls->next_partno = partno;
	return 0;
}

int blkid_partlist_increment_partno(blkid_partlist ls)
{
	return ls ? ls->next_partno++ : -1;
}

/* allows to set "parent" for the next nested partition */
static int blkid_partlist_set_parent(blkid_partlist ls, blkid_partition par)
{
	if (!ls)
		return -1;
	ls->next_parent = par;
	return 0;
}

blkid_partition blkid_partlist_get_parent(blkid_partlist ls)
{
	if (!ls)
		return NULL;
	return ls->next_parent;
}

int blkid_partitions_need_typeonly(blkid_probe pr)
{
	struct blkid_chain *chn = blkid_probe_get_chain(pr);

	return chn && chn->data && chn->binary ? FALSE : TRUE;
}

/* get private chain flags */
int blkid_partitions_get_flags(blkid_probe pr)
{
	struct blkid_chain *chn = blkid_probe_get_chain(pr);

	return chn ? chn->flags : 0;
}

/* check if @start and @size are within @par partition */
int blkid_is_nested_dimension(blkid_partition par,
			uint64_t start, uint64_t size)
{
	uint64_t pstart;
	uint64_t psize;

	if (!par)
		return 0;

	pstart = blkid_partition_get_start(par);
	psize = blkid_partition_get_size(par);

	if (start < pstart || start + size > pstart + psize)
		return 0;

	return 1;
}

static int idinfo_probe(blkid_probe pr, const struct blkid_idinfo *id,
			struct blkid_chain *chn)
{
	const struct blkid_idmag *mag = NULL;
	uint64_t off;
	int rc = BLKID_PROBE_NONE;		/* default is nothing */

	if (pr->size <= 0 || (id->minsz && (unsigned)id->minsz > pr->size))
		goto nothing;	/* the device is too small */
	if (pr->flags & BLKID_FL_NOSCAN_DEV)
		goto nothing;

	rc = blkid_probe_get_idmag(pr, id, &off, &mag);
	if (rc != BLKID_PROBE_OK)
		goto nothing;

	/* final check by probing function */
	if (id->probefunc) {
		DBG(LOWPROBE, ul_debug(
			"%s: ---> call probefunc()", id->name));
		rc = id->probefunc(pr, mag);
		if (rc < 0) {
			/* reset after error */
			reset_partlist(blkid_probe_get_partlist(pr));
			if (chn && !chn->binary)
				blkid_probe_chain_reset_values(pr, chn);
			DBG(LOWPROBE, ul_debug("%s probefunc failed, rc %d",
						  id->name, rc));
		}
		if (rc == BLKID_PROBE_OK && mag && chn && !chn->binary)
			rc = blkid_probe_set_magic(pr, off, mag->len,
					(unsigned char *) mag->magic);

		DBG(LOWPROBE, ul_debug("%s: <--- (rc = %d)", id->name, rc));
	}

	return rc;

nothing:
	return BLKID_PROBE_NONE;
}

/*
 * The blkid_do_probe() backend.
 */
static int partitions_probe(blkid_probe pr, struct blkid_chain *chn)
{
	int rc = BLKID_PROBE_NONE;
	size_t i;

	if (!pr || chn->idx < -1)
		return -EINVAL;

	blkid_probe_chain_reset_values(pr, chn);

	if (pr->flags & BLKID_FL_NOSCAN_DEV)
		return BLKID_PROBE_NONE;

	if (chn->binary)
		partitions_init_data(chn);

	if (!pr->wipe_size && (pr->prob_flags & BLKID_PROBE_FL_IGNORE_PT))
		goto details_only;

	DBG(LOWPROBE, ul_debug("--> starting probing loop [PARTS idx=%d]",
		chn->idx));

	i = chn->idx < 0 ? 0 : chn->idx + 1U;

	for ( ; i < ARRAY_SIZE(idinfos); i++) {
		const char *name;

		chn->idx = i;

		/* apply filter */
		if (chn->fltr && blkid_bmp_get_item(chn->fltr, i))
			continue;

		/* apply checks from idinfo */
		rc = idinfo_probe(pr, idinfos[i], chn);
		if (rc < 0)
			break;
		if (rc != BLKID_PROBE_OK)
			continue;

		name = idinfos[i]->name;

		if (!chn->binary)
			/*
			 * Non-binary interface, set generic variables. Note
			 * that the another variables could be set in prober
			 * functions.
			 */
			blkid_probe_set_value(pr, "PTTYPE",
						(unsigned char *) name,
						strlen(name) + 1);

		DBG(LOWPROBE, ul_debug("<-- leaving probing loop (type=%s) [PARTS idx=%d]",
			name, chn->idx));
		rc = BLKID_PROBE_OK;
		break;
	}

	if (rc != BLKID_PROBE_OK) {
		DBG(LOWPROBE, ul_debug("<-- leaving probing loop (failed=%d) [PARTS idx=%d]",
			rc, chn->idx));
	}

details_only:
	/*
	 * Gather PART_ENTRY_* values if the current device is a partition.
	 */
	if ((rc == BLKID_PROBE_OK || rc == BLKID_PROBE_NONE) && !chn->binary &&
	    (blkid_partitions_get_flags(pr) & BLKID_PARTS_ENTRY_DETAILS)) {

		int xrc = blkid_partitions_probe_partition(pr);

		/* partition entry probing is optional, and "not-found" from
		 * this sub-probing must not to overwrite previous success. */
		if (xrc < 0)
			rc = xrc;			/* always propagate errors */
		else if (rc == BLKID_PROBE_NONE)
			rc = xrc;
	}

	DBG(LOWPROBE, ul_debug("partitions probe done [rc=%d]",	rc));
	return rc;
}

/* Probe for nested partition table within the parental partition */
int blkid_partitions_do_subprobe(blkid_probe pr, blkid_partition parent,
		const struct blkid_idinfo *id)
{
	blkid_probe prc;
	int rc;
	blkid_partlist ls;
	uint64_t sz, off;

	DBG(LOWPROBE, ul_debug(
		"parts: ----> %s subprobe requested (parent=%p)",
		id->name, parent));

	if (!pr || !parent || !parent->size)
		return -EINVAL;
	if (pr->flags & BLKID_FL_NOSCAN_DEV)
		return BLKID_PROBE_NONE;

	/* range defined by parent */
	sz = parent->size << 9;
	off = parent->start << 9;

	if (off < pr->off || pr->off + pr->size < off + sz) {
		DBG(LOWPROBE, ul_debug(
			"ERROR: parts: <---- '%s' subprobe: overflow detected.",
			id->name));
		return -ENOSPC;
	}

	/* create private prober */
	prc = blkid_clone_probe(pr);
	if (!prc)
		return -ENOMEM;

	blkid_probe_set_dimension(prc, off, sz);

	/* clone is always with reset chain, fix it */
	prc->cur_chain = blkid_probe_get_chain(pr);

	/*
	 * Set 'parent' to the current list of the partitions and use the list
	 * in cloned prober (so the cloned prober will extend the current list
	 * of partitions rather than create a new).
	 */
	ls = blkid_probe_get_partlist(pr);
	blkid_partlist_set_parent(ls, parent);

	blkid_probe_set_partlist(prc, ls);

	rc = idinfo_probe(prc, id, blkid_probe_get_chain(pr));

	blkid_probe_set_partlist(prc, NULL);
	blkid_partlist_set_parent(ls, NULL);

	blkid_free_probe(prc);	/* free cloned prober */

	DBG(LOWPROBE, ul_debug(
		"parts: <---- %s subprobe done (parent=%p, rc=%d)",
		id->name, parent, rc));

	return rc;
}

static int blkid_partitions_probe_partition(blkid_probe pr)
{
	blkid_probe disk_pr = NULL;
	blkid_partlist ls;
	blkid_partition par;
	dev_t devno;

	DBG(LOWPROBE, ul_debug("parts: start probing for partition entry"));

	if (pr->flags & BLKID_FL_NOSCAN_DEV)
		goto nothing;

	devno = blkid_probe_get_devno(pr);
	if (!devno)
		goto nothing;

	disk_pr = blkid_probe_get_wholedisk_probe(pr);
	if (!disk_pr)
		goto nothing;

	/* parse PT */
	ls = blkid_probe_get_partitions(disk_pr);
	if (!ls)
		goto nothing;

	par = blkid_partlist_devno_to_partition(ls, devno);
	if (!par)
		goto nothing;
	else {
		const char *v;
		blkid_parttable tab = blkid_partition_get_table(par);
		dev_t disk = blkid_probe_get_devno(disk_pr);

		if (tab) {
			v = blkid_parttable_get_type(tab);
			if (v)
				blkid_probe_set_value(pr, "PART_ENTRY_SCHEME",
					(unsigned char *) v, strlen(v) + 1);
		}

		v = blkid_partition_get_name(par);
		if (v)
			blkid_probe_set_value(pr, "PART_ENTRY_NAME",
				(unsigned char *) v, strlen(v) + 1);

		v = blkid_partition_get_uuid(par);
		if (v)
			blkid_probe_set_value(pr, "PART_ENTRY_UUID",
				(unsigned char *) v, strlen(v) + 1);

		/* type */
		v = blkid_partition_get_type_string(par);
		if (v)
			blkid_probe_set_value(pr, "PART_ENTRY_TYPE",
				(unsigned char *) v, strlen(v) + 1);
		else
			blkid_probe_sprintf_value(pr, "PART_ENTRY_TYPE",
				"0x%x", blkid_partition_get_type(par));

		if (blkid_partition_get_flags(par))
			blkid_probe_sprintf_value(pr, "PART_ENTRY_FLAGS",
				"0x%llx", blkid_partition_get_flags(par));

		blkid_probe_sprintf_value(pr, "PART_ENTRY_NUMBER",
				"%d", blkid_partition_get_partno(par));

		blkid_probe_sprintf_value(pr, "PART_ENTRY_OFFSET", "%jd",
				(intmax_t)blkid_partition_get_start(par));
		blkid_probe_sprintf_value(pr, "PART_ENTRY_SIZE", "%jd",
				(intmax_t)blkid_partition_get_size(par));

		blkid_probe_sprintf_value(pr, "PART_ENTRY_DISK", "%u:%u",
				major(disk), minor(disk));
	}

	DBG(LOWPROBE, ul_debug("parts: end probing for partition entry [success]"));
	return BLKID_PROBE_OK;

nothing:
	DBG(LOWPROBE, ul_debug("parts: end probing for partition entry [nothing]"));
	return BLKID_PROBE_NONE;


}

/*
 * Returns 1 if the device is whole-disk and the area specified by @offset and
 * @size is covered by any partition.
 */
int blkid_probe_is_covered_by_pt(blkid_probe pr,
				 uint64_t offset, uint64_t size)
{
	blkid_probe prc = NULL;
	blkid_partlist ls = NULL;
	uint64_t start, end;
	int nparts, i, rc = 0;

	DBG(LOWPROBE, ul_debug(
		"=> checking if off=%"PRIu64" size=%"PRIu64" covered by PT",
		offset, size));

	if (pr->flags & BLKID_FL_NOSCAN_DEV)
		goto done;

	prc = blkid_clone_probe(pr);
	if (!prc)
		goto done;

	ls = blkid_probe_get_partitions(prc);
	if (!ls)
		goto done;

	nparts = blkid_partlist_numof_partitions(ls);
	if (!nparts)
		goto done;

	end = (offset + size) >> 9;
	start = offset >> 9;

	/* check if the partition table fits into the device */
	for (i = 0; i < nparts; i++) {
		blkid_partition par = &ls->parts[i];

		if (par->start + par->size > (pr->size >> 9)) {
			DBG(LOWPROBE, ul_debug("partition #%d overflows "
				"device (off=%" PRId64 " size=%" PRId64 ")",
				par->partno, par->start, par->size));
			goto done;
		}
	}

	/* check if the requested area is covered by PT */
	for (i = 0; i < nparts; i++) {
		blkid_partition par = &ls->parts[i];

		if (start >= par->start && end <= par->start + par->size) {
			rc = 1;
			break;
		}
	}
done:
	blkid_free_probe(prc);

	DBG(LOWPROBE, ul_debug("<= %s covered by PT", rc ? "IS" : "NOT"));
	return rc;
}

/**
 * blkid_known_pttype:
 * @pttype: partition name
 *
 * Returns: 1 for known or 0 for unknown partition type.
 */
int blkid_known_pttype(const char *pttype)
{
	size_t i;

	if (!pttype)
		return 0;

	for (i = 0; i < ARRAY_SIZE(idinfos); i++) {
		const struct blkid_idinfo *id = idinfos[i];
		if (strcmp(id->name, pttype) == 0)
			return 1;
	}
	return 0;
}

/**
 * blkid_partlist_numof_partitions:
 * @ls: partitions list
 *
 * Returns: number of partitions in the list or -1 in case of error.
 */
int blkid_partlist_numof_partitions(blkid_partlist ls)
{
	return ls->nparts;
}

/**
 * blkid_partlist_get_table:
 * @ls: partitions list
 *
 * Returns: top-level partition table or NULL of there is not a partition table
 * on the device.
 */
blkid_parttable blkid_partlist_get_table(blkid_partlist ls)
{
	if (list_empty(&ls->l_tabs))
		return NULL;

	return list_entry(ls->l_tabs.next,
			struct blkid_struct_parttable, t_tabs);
}


/**
 * blkid_partlist_get_partition:
 * @ls: partitions list
 * @n: partition number in range 0..N, where 'N' is blkid_partlist_numof_partitions().
 *
 * It's possible that the list of partitions is *empty*, but there is a valid
 * partition table on the disk. This happen when on-disk details about
 * partitions are unknown or the partition table is empty.
 *
 * See also blkid_partlist_get_table().
 *
 * Returns: partition object or NULL in case or error.
 */
blkid_partition blkid_partlist_get_partition(blkid_partlist ls, int n)
{
	if (n < 0 || n >= ls->nparts)
		return NULL;

	return &ls->parts[n];
}

blkid_partition blkid_partlist_get_partition_by_start(blkid_partlist ls, uint64_t start)
{
	int i, nparts;
	blkid_partition par;

	nparts = blkid_partlist_numof_partitions(ls);
	for (i = 0; i < nparts; i++) {
		par = blkid_partlist_get_partition(ls, i);
		if ((uint64_t) blkid_partition_get_start(par) == start)
			return par;
	}
	return NULL;
}

/**
 * blkid_partlist_get_partition_by_partno
 * @ls: partitions list
 * @n: the partition number (e.g. 'N' from sda'N')
 *
 * This does not assume any order of the input blkid_partlist.  And correctly
 * handles "out of order" partition tables.  partition N is located after
 * partition N+1 on the disk.
 *
 * Returns: partition object or NULL in case or error.
 */
blkid_partition blkid_partlist_get_partition_by_partno(blkid_partlist ls, int n)
{
	int i, nparts;
	blkid_partition par;

	nparts = blkid_partlist_numof_partitions(ls);
	for (i = 0; i < nparts; i++) {
		par = blkid_partlist_get_partition(ls, i);
		if (n == blkid_partition_get_partno(par))
			return par;
	}
	return NULL;
}


/**
 * blkid_partlist_devno_to_partition:
 * @ls: partitions list
 * @devno: requested partition
 *
 * This function tries to get start and size for @devno from sysfs and
 * returns a partition from @ls which matches with the values from sysfs.
 *
 * This function is necessary when you want to make a relation between an entry
 * in the partition table (@ls) and block devices in your system.
 *
 * Returns: partition object or NULL in case or error.
 */
blkid_partition blkid_partlist_devno_to_partition(blkid_partlist ls, dev_t devno)
{
	struct sysfs_cxt sysfs;
	uint64_t start, size;
	int i, rc, partno = 0;

	DBG(LOWPROBE, ul_debug("trying to convert devno 0x%llx to partition",
			(long long) devno));

	if (sysfs_init(&sysfs, devno, NULL)) {
		DBG(LOWPROBE, ul_debug("failed t init sysfs context"));
		return NULL;
	}
	rc = sysfs_read_u64(&sysfs, "size", &size);
	if (!rc) {
		rc = sysfs_read_u64(&sysfs, "start", &start);
		if (rc) {
			/* try to get partition number from DM uuid.
			 */
			char *uuid = sysfs_strdup(&sysfs, "dm/uuid");
			char *tmp = uuid;
			char *prefix = uuid ? strsep(&tmp, "-") : NULL;

			if (prefix && strncasecmp(prefix, "part", 4) == 0) {
				char *end = NULL;

				partno = strtol(prefix + 4, &end, 10);
				if (prefix == end || (end && *end))
					partno = 0;
				else
					rc = 0;		/* success */
			}
			free(uuid);
		}
	}

	sysfs_deinit(&sysfs);

	if (rc)
		return NULL;

	if (partno) {
		DBG(LOWPROBE, ul_debug("mapped by DM, using partno %d", partno));

		/*
		 * Partition mapped by kpartx does not provide "start" offset
		 * in /sys, but if we know partno and size of the partition
		 * that we can probably make the relation between the device
		 * and an entry in partition table.
		 */
		 for (i = 0; i < ls->nparts; i++) {
			 blkid_partition par = &ls->parts[i];

			 if (partno != blkid_partition_get_partno(par))
				 continue;

			 if (size == (uint64_t)blkid_partition_get_size(par) ||
			     (blkid_partition_is_extended(par) && size <= 1024ULL))
				 return par;

		 }
		 return NULL;
	}

	DBG(LOWPROBE, ul_debug("searching by offset/size"));

	for (i = 0; i < ls->nparts; i++) {
		blkid_partition par = &ls->parts[i];

		if ((uint64_t)blkid_partition_get_start(par) == start &&
		    (uint64_t)blkid_partition_get_size(par) == size)
			return par;

		/* exception for extended dos partitions */
		if ((uint64_t)blkid_partition_get_start(par) == start &&
		    blkid_partition_is_extended(par) && size <= 1024ULL)
			return par;

	}

	DBG(LOWPROBE, ul_debug("not found partition for device"));
	return NULL;
}


int blkid_parttable_set_uuid(blkid_parttable tab, const unsigned char *id)
{
	if (!tab)
		return -1;

	blkid_unparse_uuid(id, tab->id, sizeof(tab->id));
	return 0;
}

int blkid_parttable_set_id(blkid_parttable tab, const unsigned char *id)
{
	if (!tab)
		return -1;

	strncpy(tab->id, (const char *) id, sizeof(tab->id));
	return 0;
}

/* set PTUUID variable for non-binary API */
int blkid_partitions_set_ptuuid(blkid_probe pr, unsigned char *uuid)
{
	struct blkid_chain *chn = blkid_probe_get_chain(pr);
	struct blkid_prval *v;

	if (chn->binary || blkid_uuid_is_empty(uuid, 16))
		return 0;

	v = blkid_probe_assign_value(pr, "PTUUID");
	if (!v)
		return -ENOMEM;

	v->len = 37;
	v->data = calloc(1, v->len);
	if (v->data) {
		blkid_unparse_uuid(uuid, (char *) v->data, v->len);
		return 0;
	}

	blkid_probe_free_value(v);
	return -ENOMEM;
}

/* set PTUUID variable for non-binary API for tables where
 * the ID is just a string */
int blkid_partitions_strcpy_ptuuid(blkid_probe pr, char *str)
{
	struct blkid_chain *chn = blkid_probe_get_chain(pr);

	if (chn->binary || !str || !*str)
		return 0;

	if (!blkid_probe_set_value(pr, "PTUUID", (unsigned char *) str, strlen(str) + 1))
		return -ENOMEM;

	return 0;
}

/**
 * blkid_parttable_get_id:
 * @tab: partition table
 *
 * The ID is GPT disk UUID or DOS disk ID (in hex format).
 *
 * Returns: partition table ID (for example GPT disk UUID) or NULL
 */
const char *blkid_parttable_get_id(blkid_parttable tab)
{
	return *tab->id ? tab->id : NULL;
}


int blkid_partition_set_type(blkid_partition par, int type)
{
	par->type = type;
	return 0;
}

/**
 * blkid_parttable_get_type:
 * @tab: partition table
 *
 * Returns: partition table type (type name, e.g. "dos", "gpt", ...)
 */
const char *blkid_parttable_get_type(blkid_parttable tab)
{
	return tab->type;
}

/**
 * blkid_parttable_get_parent:
 * @tab: partition table
 *
 * Returns: parent for nested partition tables or NULL.
 */
blkid_partition blkid_parttable_get_parent(blkid_parttable tab)
{
	return tab->parent;
}

/**
 * blkid_parttable_get_offset:
 * @tab: partition table
 *
 * Note the position is relative to begin of the device as defined by
 * blkid_probe_set_device() for primary partition table, and relative
 * to parental partition for nested partition tables.
 *
 * <informalexample>
 *   <programlisting>
 * off_t offset;
 * blkid_partition parent = blkid_parttable_get_parent(tab);
 *
 * offset = blkid_parttable_get_offset(tab);
 *
 * if (parent)
 *      / * 'tab' is nested partition table * /
 *	offset += blkid_partition_get_start(parent);
 *   </programlisting>
 * </informalexample>

 * Returns: position (in bytes) of the partition table or -1 in case of error.
 *
 */
blkid_loff_t blkid_parttable_get_offset(blkid_parttable tab)
{
	return (blkid_loff_t)tab->offset;
}

/**
 * blkid_partition_get_table:
 * @par: partition
 *
 * The "parttable" describes partition table. The table is usually the same for
 * all partitions -- except nested partition tables.
 *
 * For example bsd, solaris, etc. use a nested partition table within
 * standard primary dos partition:
 *
 * <informalexample>
 *   <programlisting>
 *
 *  -- dos partition table
 *  0: sda1     dos primary partition
 *  1: sda2     dos primary partition
 *     -- bsd partition table (with in sda2)
 *  2:    sda5  bds partition
 *  3:    sda6  bds partition
 *
 *   </programlisting>
 * </informalexample>
 *
 * The library does not to use a separate partition table object for dos logical
 * partitions (partitions within extended partition). It's possible to
 * differentiate between logical, extended and primary partitions by
 *
 *	blkid_partition_is_{extended,primary,logical}().
 *
 * Returns: partition table object or NULL in case of error.
 */
blkid_parttable blkid_partition_get_table(blkid_partition par)
{
	return par->tab;
}

static int partition_get_logical_type(blkid_partition par)
{
	blkid_parttable tab;

	if (!par)
		return -1;

	tab = blkid_partition_get_table(par);
	if (!tab || !tab->type)
		return -1;

	if (tab->parent)
		return 'L';  /* report nested partitions as logical */

	if (!strcmp(tab->type, "dos")) {
		if (par->partno > 4)
			return 'L';	/* logical */

	        if(par->type == MBR_DOS_EXTENDED_PARTITION ||
                   par->type == MBR_W95_EXTENDED_PARTITION ||
		   par->type == MBR_LINUX_EXTENDED_PARTITION)
			return 'E';
	}
	return 'P';
}

/**
 * blkid_partition_is_primary:
 * @par: partition
 *
 * Note, this function returns FALSE for DOS extended partitions and
 * all partitions in nested partition tables.
 *
 * Returns: 1 if the partitions is primary partition or 0 if not.
 */
int blkid_partition_is_primary(blkid_partition par)
{
	return partition_get_logical_type(par) == 'P' ? TRUE : FALSE;
}

/**
 * blkid_partition_is_extended:
 * @par: partition
 *
 * Returns: 1 if the partitions is extended (dos, windows or linux)
 * partition or 0 if not.
 */
int blkid_partition_is_extended(blkid_partition par)
{
	return partition_get_logical_type(par) == 'E' ? TRUE : FALSE;
}

/**
 * blkid_partition_is_logical:
 * @par: partition
 *
 * Note that this function returns TRUE for all partitions in all
 * nested partition tables (e.g. BSD labels).
 *
 * Returns: 1 if the partitions is logical partition or 0 if not.
 */
int blkid_partition_is_logical(blkid_partition par)
{
	return partition_get_logical_type(par) == 'L' ? TRUE : FALSE;
}

static void set_string(unsigned char *item, size_t max,
				const unsigned char *data, size_t len)
{
	if (len >= max)
		len = max - 1;

	memcpy(item, data, len);
	item[len] = '\0';

	blkid_rtrim_whitespace(item);
}

int blkid_partition_set_name(blkid_partition par,
		const unsigned char *name, size_t len)
{
	if (!par)
		return -1;

	set_string(par->name, sizeof(par->name), name, len);
	return 0;
}

int blkid_partition_set_utf8name(blkid_partition par, const unsigned char *name,
		size_t len, int enc)
{
	if (!par)
		return -1;

	blkid_encode_to_utf8(enc, par->name, sizeof(par->name), name, len);
	blkid_rtrim_whitespace(par->name);
	return 0;
}

int blkid_partition_set_uuid(blkid_partition par, const unsigned char *uuid)
{
	if (!par)
		return -1;

	blkid_unparse_uuid(uuid, par->uuid, sizeof(par->uuid));
	return 0;
}

int blkid_partition_gen_uuid(blkid_partition par)
{
	if (!par || !par->tab || !*par->tab->id)
		return -1;

	snprintf(par->uuid, sizeof(par->uuid), "%s-%02x",
			par->tab->id, par->partno);
	return 0;
}

/**
 * blkid_partition_get_name:
 * @par: partition
 *
 * Returns: partition name string if supported by PT (e.g. Mac) or NULL.
 */
const char *blkid_partition_get_name(blkid_partition par)
{
	return *par->name ? (char *) par->name : NULL;
}

/**
 * blkid_partition_get_uuid:
 * @par: partition
 *
 * Returns: partition UUID string if supported by PT (e.g. GPT) or NULL.
 */
const char *blkid_partition_get_uuid(blkid_partition par)
{
	return *par->uuid ? par->uuid : NULL;
}

/**
 * blkid_partition_get_partno:
 * @par: partition
 *
 * Returns: proposed partition number (e.g. 'N' from sda'N') or -1 in case of
 * error. Note that the number is generate by library independently on your OS.
 */
int blkid_partition_get_partno(blkid_partition par)
{
	return par->partno;
}

/**
 * blkid_partition_get_start:
 * @par: partition
 *
 * Be careful if you _not_ probe whole disk:
 *
 * 1) the offset is usually relative to begin of the disk -- but if you probe a
 *    fragment of the disk only -- then the offset could be still relative to
 *    the begin of the disk rather that relative to the fragment.
 *
 * 2) the offset for nested partitions could be relative to parent (e.g. Solaris)
 *    _or_ relative to the begin of the whole disk (e.g. bsd).
 *
 * You don't have to care about such details if you probe whole disk. In such
 * a case libblkid always returns the offset relative to the begin of the disk.
 *
 * Returns: start of the partition (in 512-sectors).
 */
blkid_loff_t blkid_partition_get_start(blkid_partition par)
{
	return (blkid_loff_t)par->start;
}

/**
 * blkid_partition_get_size:
 * @par: partition
 *
 * WARNING: be very careful when you work with MS-DOS extended partitions. The
 *          library always returns full size of the partition. If you want add
 *          the partition to the Linux system (BLKPG_ADD_PARTITION ioctl) you
 *          need to reduce the size of the partition to 1 or 2 blocks. The
 *          rest of the partition has to be inaccessible for mkfs or mkswap
 *          programs, we need a small space for boot loaders only.
 *
 *          For some unknown reason this (safe) practice is not to used for
 *          nested BSD, Solaris, ..., partition tables in Linux kernel.
 *
 * Returns: size of the partition (in 512-sectors).
 */
blkid_loff_t blkid_partition_get_size(blkid_partition par)
{
	return (blkid_loff_t)par->size;
}

/**
 * blkid_partition_get_type:
 * @par: partition
 *
 * Returns: partition type.
 */
int blkid_partition_get_type(blkid_partition par)
{
	return par->type;
}

/* Sets partition 'type' for PT where the type is defined by string rather
 * than by number
 */
int blkid_partition_set_type_string(blkid_partition par,
		const unsigned char *type, size_t len)
{
	set_string((unsigned char *) par->typestr,
			sizeof(par->typestr), type, len);
	return 0;
}

/* Sets partition 'type' for PT where the type is defined by UUIDrather
 * than by number
 */
int blkid_partition_set_type_uuid(blkid_partition par, const unsigned char *uuid)
{
	blkid_unparse_uuid(uuid, par->typestr, sizeof(par->typestr));
	return 0;
}

/**
 * blkid_partition_get_type_string:
 * @par: partition
 *
 * The type string is supported by a small subset of partition tables (e.g Mac
 * and EFI GPT).  Note that GPT uses type UUID and this function returns this
 * UUID as string.
 *
 * Returns: partition type string or NULL.
 */
const char *blkid_partition_get_type_string(blkid_partition par)
{
	return *par->typestr ? par->typestr : NULL;
}


int blkid_partition_set_flags(blkid_partition par, unsigned long long flags)
{
	par->flags = flags;
	return 0;
}

/**
 * blkid_partition_get_flags
 * @par: partition
 *
 * Returns: partition flags (or attributes for gpt).
 */
unsigned long long blkid_partition_get_flags(blkid_partition par)
{
	return par->flags;
}

