/*
 * Low-level libblkid probing API
 *
 * Copyright (C) 2008-2009 Karel Zak <kzak@redhat.com>
 *
 * This file may be redistributed under the terms of the
 * GNU Lesser General Public License.
 */

/**
 * SECTION: lowprobe
 * @title: Low-level probing
 * @short_description: low-level prober initialization
 *
 * The low-level probing routines always and directly read information from
 * the selected (see blkid_probe_set_device()) device.
 *
 * The probing routines are grouped together into separate chains. Currently,
 * the library provides superblocks, partitions and topology chains.
 *
 * The probing routines is possible to filter (enable/disable) by type (e.g.
 * fstype "vfat" or partype "gpt") or by usage flags (e.g. BLKID_USAGE_RAID).
 * These filters are per-chain. Note that always when you touch the chain
 * filter the current probing position is reset and probing starts from
 * scratch.  It means that the chain filter should not be modified during
 * probing, for example in loop where you call blkid_do_probe().
 *
 * For more details see the chain specific documentation.
 *
 * The low-level API provides two ways how access to probing results.
 *
 *   1. The NAME=value (tag) interface. This interface is older and returns all data
 *      as strings. This interface is generic for all chains.
 *
 *   2. The binary interfaces. These interfaces return data in the native formats.
 *      The interface is always specific to the probing chain.
 *
 *  Note that the previous probing result (binary or NAME=value) is always
 *  zeroized when a chain probing function is called. For example:
 *
 * <informalexample>
 *   <programlisting>
 *     blkid_probe_enable_partitions(pr, TRUE);
 *     blkid_probe_enable_superblocks(pr, FALSE);
 *
 *     blkid_do_safeprobe(pr);
 *   </programlisting>
 * </informalexample>
 *
 * overwrites the previous probing result for the partitions chain, the superblocks
 * result is not modified.
 */

/**
 * SECTION: lowprobe-tags
 * @title: Low-level tags
 * @short_description: generic NAME=value interface.
 *
 * The probing routines inside the chain are mutually exclusive by default --
 * only few probing routines are marked as "tolerant". The "tolerant" probing
 * routines are used for filesystem which can share the same device with any
 * other filesystem. The blkid_do_safeprobe() checks for the "tolerant" flag.
 *
 * The SUPERBLOCKS chain is enabled by default. The all others chains is
 * necessary to enable by blkid_probe_enable_'CHAINNAME'(). See chains specific
 * documentation.
 *
 * The blkid_do_probe() function returns a result from only one probing
 * routine, and the next call from the next probing routine. It means you need
 * to call the function in loop, for example:
 *
 * <informalexample>
 *   <programlisting>
 *	while((blkid_do_probe(pr) == 0)
 *		... use result ...
 *   </programlisting>
 * </informalexample>
 *
 * The blkid_do_safeprobe() is the same as blkid_do_probe(), but returns only
 * first probing result for every enabled chain. This function checks for
 * ambivalent results (e.g. more "intolerant" filesystems superblocks on the
 * device).
 *
 * The probing result is set of NAME=value pairs (the NAME is always unique).
 */

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <ctype.h>
#include <sys/types.h>
#ifdef HAVE_LINUX_CDROM_H
#include <linux/cdrom.h>
#endif
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
#include <inttypes.h>
#include <stdint.h>
#include <stdarg.h>
#include <limits.h>

#ifdef HAVE_LIBUUID
# include <uuid.h>
#endif

#include "blkidP.h"
#include <blkid.h>
#include "all-io.h"
#include "sysfs.h"
#include "strutils.h"

/* chains */
extern const struct blkid_chaindrv superblocks_drv;
extern const struct blkid_chaindrv topology_drv;
extern const struct blkid_chaindrv partitions_drv;

/*
 * All supported chains
 */
static const struct blkid_chaindrv *chains_drvs[] = {
	[BLKID_CHAIN_SUBLKS] = &superblocks_drv,
	[BLKID_CHAIN_TOPLGY] = &topology_drv,
	[BLKID_CHAIN_PARTS] = &partitions_drv
};

static void blkid_probe_reset_vals(blkid_probe pr);
static void blkid_probe_reset_buffer(blkid_probe pr);

/**
 * blkid_new_probe:
 *
 * Returns: a pointer to the newly allocated probe struct or NULL in case of error.
 */
blkid_probe blkid_new_probe(void)
{
	int i;
	blkid_probe pr;

	blkid_init_debug(0);
	pr = calloc(1, sizeof(struct blkid_struct_probe));
	if (!pr)
		return NULL;

	DBG(LOWPROBE, ul_debug("allocate a new probe %p", pr));

	/* initialize chains */
	for (i = 0; i < BLKID_NCHAINS; i++) {
		pr->chains[i].driver = chains_drvs[i];
		pr->chains[i].flags = chains_drvs[i]->dflt_flags;
		pr->chains[i].enabled = chains_drvs[i]->dflt_enabled;
	}
	INIT_LIST_HEAD(&pr->buffers);
	return pr;
}

/*
 * Clone @parent, the new clone shares all, but except:
 *
 *	- probing result
 *	- bufferes if another device (or offset) is set to the prober
 */
blkid_probe blkid_clone_probe(blkid_probe parent)
{
	blkid_probe pr;

	if (!parent)
		return NULL;

	DBG(LOWPROBE, ul_debug("allocate a probe clone"));

	pr = blkid_new_probe();
	if (!pr)
		return NULL;

	pr->fd = parent->fd;
	pr->off = parent->off;
	pr->size = parent->size;
	pr->devno = parent->devno;
	pr->disk_devno = parent->disk_devno;
	pr->blkssz = parent->blkssz;
	pr->flags = parent->flags;
	pr->parent = parent;

	pr->flags &= ~BLKID_FL_PRIVATE_FD;

	return pr;
}



/**
 * blkid_new_probe_from_filename:
 * @filename: device or regular file
 *
 * This function is same as call open(filename), blkid_new_probe() and
 * blkid_probe_set_device(pr, fd, 0, 0).
 *
 * The @filename is closed by blkid_free_probe() or by the
 * blkid_probe_set_device() call.
 *
 * Returns: a pointer to the newly allocated probe struct or NULL in case of
 * error.
 */
blkid_probe blkid_new_probe_from_filename(const char *filename)
{
	int fd = -1;
	blkid_probe pr = NULL;

	if (!filename)
		return NULL;

	fd = open(filename, O_RDONLY|O_CLOEXEC);
	if (fd < 0)
		return NULL;

	pr = blkid_new_probe();
	if (!pr)
		goto err;

	if (blkid_probe_set_device(pr, fd, 0, 0))
		goto err;

	pr->flags |= BLKID_FL_PRIVATE_FD;
	return pr;
err:
	if (fd >= 0)
		close(fd);
	blkid_free_probe(pr);
	return NULL;
}

/**
 * blkid_free_probe:
 * @pr: probe
 *
 * Deallocates the probe struct, buffers and all allocated
 * data that are associated with this probing control struct.
 */
void blkid_free_probe(blkid_probe pr)
{
	int i;

	if (!pr)
		return;

	for (i = 0; i < BLKID_NCHAINS; i++) {
		struct blkid_chain *ch = &pr->chains[i];

		if (ch->driver->free_data)
			ch->driver->free_data(pr, ch->data);
		free(ch->fltr);
	}

	if ((pr->flags & BLKID_FL_PRIVATE_FD) && pr->fd >= 0)
		close(pr->fd);
	blkid_probe_reset_buffer(pr);
	blkid_free_probe(pr->disk_probe);

	DBG(LOWPROBE, ul_debug("free probe %p", pr));
	free(pr);
}


/*
 * Removes chain values from probing result.
 */
void blkid_probe_chain_reset_vals(blkid_probe pr, struct blkid_chain *chn)
{
	int nvals = pr->nvals;
	int i, x;

	for (x = 0, i = 0; i < pr->nvals; i++) {
		struct blkid_prval *v = &pr->vals[i];

		if (v->chain != chn && x == i) {
			x++;
			continue;
		}
		if (v->chain == chn) {
			--nvals;
			continue;
		}
		memcpy(&pr->vals[x++], v, sizeof(struct blkid_prval));
	}
	pr->nvals = nvals;
}

static void blkid_probe_chain_reset_position(struct blkid_chain *chn)
{
	if (chn)
		chn->idx = -1;
}

/*
 * Copies chain values from probing result to @vals, the max size of @vals is
 * @nvals and returns real number of values.
 */
int blkid_probe_chain_copy_vals(blkid_probe pr, struct blkid_chain *chn,
		struct blkid_prval *vals, int nvals)
{
	int i, x;

	for (x = 0, i = 0; i < pr->nvals && x < nvals; i++) {
		struct blkid_prval *v = &pr->vals[i];

		if (v->chain != chn)
			continue;
		memcpy(&vals[x++], v, sizeof(struct blkid_prval));
	}
	return x;
}

/*
 * Appends values from @vals to the probing result
 */
void blkid_probe_append_vals(blkid_probe pr, struct blkid_prval *vals, int nvals)
{
	int i = 0;

	while (i < nvals && pr->nvals < BLKID_NVALS) {
		memcpy(&pr->vals[pr->nvals++], &vals[i++],
				sizeof(struct blkid_prval));
	}
}

static void blkid_probe_reset_vals(blkid_probe pr)
{
	memset(pr->vals, 0, sizeof(pr->vals));
	pr->nvals = 0;
}

struct blkid_chain *blkid_probe_get_chain(blkid_probe pr)
{
	return pr->cur_chain;
}

static const char *blkid_probe_get_probername(blkid_probe pr)
{
	struct blkid_chain *chn = blkid_probe_get_chain(pr);

	if (chn && chn->idx >= 0 && chn->idx < chn->driver->nidinfos)
		return chn->driver->idinfos[chn->idx]->name;

	return NULL;
}

void *blkid_probe_get_binary_data(blkid_probe pr, struct blkid_chain *chn)
{
	int rc, org_prob_flags;
	struct blkid_chain *org_chn;

	/* save the current setting -- the binary API has to be completely
	 * independent on the current probing status
	 */
	org_chn = pr->cur_chain;
	org_prob_flags = pr->prob_flags;

	pr->cur_chain = chn;
	pr->prob_flags = 0;
	chn->binary = TRUE;
	blkid_probe_chain_reset_position(chn);

	rc = chn->driver->probe(pr, chn);

	chn->binary = FALSE;
	blkid_probe_chain_reset_position(chn);

	/* restore the original setting
	 */
	pr->cur_chain = org_chn;
	pr->prob_flags = org_prob_flags;

	if (rc != 0)
		return NULL;

	DBG(LOWPROBE, ul_debug("returning %s binary data", chn->driver->name));
	return chn->data;
}


/**
 * blkid_reset_probe:
 * @pr: probe
 *
 * Zeroize probing results and resets the current probing (this has impact to
 * blkid_do_probe() only). This function does not touch probing filters and
 * keeps assigned device.
 */
void blkid_reset_probe(blkid_probe pr)
{
	int i;

	if (!pr)
		return;

	blkid_probe_reset_vals(pr);
	blkid_probe_set_wiper(pr, 0, 0);

	pr->cur_chain = NULL;

	for (i = 0; i < BLKID_NCHAINS; i++)
		blkid_probe_chain_reset_position(&pr->chains[i]);
}

/***
static int blkid_probe_dump_filter(blkid_probe pr, int chain)
{
	struct blkid_chain *chn;
	int i;

	if (!pr || chain < 0 || chain >= BLKID_NCHAINS)
		return -1;

	chn = &pr->chains[chain];

	if (!chn->fltr)
		return -1;

	for (i = 0; i < chn->driver->nidinfos; i++) {
		const struct blkid_idinfo *id = chn->driver->idinfos[i];

		DBG(LOWPROBE, ul_debug("%d: %s: %s",
			i,
			id->name,
			blkid_bmp_get_item(chn->fltr, i)
				? "disabled" : "enabled <--"));
	}
	return 0;
}
***/

/*
 * Returns properly initialized chain filter
 */
unsigned long *blkid_probe_get_filter(blkid_probe pr, int chain, int create)
{
	struct blkid_chain *chn;

	if (chain < 0 || chain >= BLKID_NCHAINS)
		return NULL;

	chn = &pr->chains[chain];

	/* always when you touch the chain filter all indexes are reset and
	 * probing starts from scratch
	 */
	blkid_probe_chain_reset_position(chn);
	pr->cur_chain = NULL;

	if (!chn->driver->has_fltr || (!chn->fltr && !create))
		return NULL;

	if (!chn->fltr)
		chn->fltr = calloc(1, blkid_bmp_nbytes(chn->driver->nidinfos));
	else
		memset(chn->fltr, 0, blkid_bmp_nbytes(chn->driver->nidinfos));

	/* blkid_probe_dump_filter(pr, chain); */
	return chn->fltr;
}

/*
 * Generic private functions for filter setting
 */
int __blkid_probe_invert_filter(blkid_probe pr, int chain)
{
	size_t i;
	struct blkid_chain *chn;

	chn = &pr->chains[chain];

	if (!chn->driver->has_fltr || !chn->fltr)
		return -1;

	for (i = 0; i < blkid_bmp_nwords(chn->driver->nidinfos); i++)
		chn->fltr[i] = ~chn->fltr[i];

	DBG(LOWPROBE, ul_debug("probing filter inverted"));
	/* blkid_probe_dump_filter(pr, chain); */
	return 0;
}

int __blkid_probe_reset_filter(blkid_probe pr, int chain)
{
	return blkid_probe_get_filter(pr, chain, FALSE) ? 0 : -1;
}

int __blkid_probe_filter_types(blkid_probe pr, int chain, int flag, char *names[])
{
	unsigned long *fltr;
	struct blkid_chain *chn;
	size_t i;

	fltr = blkid_probe_get_filter(pr, chain, TRUE);
	if (!fltr)
		return -1;

	chn = &pr->chains[chain];

	for (i = 0; i < chn->driver->nidinfos; i++) {
		int has = 0;
		const struct blkid_idinfo *id = chn->driver->idinfos[i];
		char **n;

		for (n = names; *n; n++) {
			if (!strcmp(id->name, *n)) {
				has = 1;
				break;
			}
		}
		if (flag & BLKID_FLTR_ONLYIN) {
		       if (!has)
				blkid_bmp_set_item(fltr, i);
		} else if (flag & BLKID_FLTR_NOTIN) {
			if (has)
				blkid_bmp_set_item(fltr, i);
		}
	}

	DBG(LOWPROBE, ul_debug("%s: a new probing type-filter initialized",
		chn->driver->name));
	/* blkid_probe_dump_filter(pr, chain); */
	return 0;
}

unsigned char *blkid_probe_get_buffer(blkid_probe pr,
				blkid_loff_t off, blkid_loff_t len)
{
	struct list_head *p;
	struct blkid_bufinfo *bf = NULL;

	if (pr->size <= 0) {
		errno = EINVAL;
		return NULL;
	}

	if (pr->parent &&
	    pr->parent->devno == pr->devno &&
	    pr->parent->off <= pr->off &&
	    pr->parent->off + pr->parent->size >= pr->off + pr->size) {
		/*
		 * This is a cloned prober and points to the same area as
		 * parent. Let's use parent's buffers.
		 *
		 * Note that pr->off (and pr->parent->off) is always from the
		 * beginig of the device.
		 */
		return blkid_probe_get_buffer(pr->parent,
				pr->off + off - pr->parent->off, len);
	}

	list_for_each(p, &pr->buffers) {
		struct blkid_bufinfo *x =
				list_entry(p, struct blkid_bufinfo, bufs);

		if (x->off <= off && off + len <= x->off + x->len) {
			DBG(LOWPROBE, ul_debug("\treuse buffer: off=%jd len=%jd pr=%p",
							x->off, x->len, pr));
			bf = x;
			break;
		}
	}
	if (!bf) {
		ssize_t ret;

		if (blkid_llseek(pr->fd, pr->off + off, SEEK_SET) < 0) {
			errno = 0;
			return NULL;
		}

		/* someone trying to overflow some buffers? */
		if (len > ULONG_MAX - sizeof(struct blkid_bufinfo)) {
			errno = ENOMEM;
			return NULL;
		}

		/* allocate info and space for data by why call */
		bf = calloc(1, sizeof(struct blkid_bufinfo) + len);
		if (!bf) {
			errno = ENOMEM;
			return NULL;
		}

		bf->data = ((unsigned char *) bf) + sizeof(struct blkid_bufinfo);
		bf->len = len;
		bf->off = off;
		INIT_LIST_HEAD(&bf->bufs);

		DBG(LOWPROBE, ul_debug("\tbuffer read: off=%jd len=%jd pr=%p",
				off, len, pr));

		ret = read(pr->fd, bf->data, len);
		if (ret != (ssize_t) len) {
			DBG(LOWPROBE, ul_debug("\tbuffer read: return %zd error %m", ret));
			free(bf);
			if (ret >= 0)
				errno = 0;
			return NULL;
		}
		list_add_tail(&bf->bufs, &pr->buffers);
	}

	errno = 0;
	return off ? bf->data + (off - bf->off) : bf->data;
}


static void blkid_probe_reset_buffer(blkid_probe pr)
{
	uint64_t read_ct = 0, len_ct = 0;

	if (!pr || list_empty(&pr->buffers))
		return;

	DBG(LOWPROBE, ul_debug("reseting probing buffers pr=%p", pr));

	while (!list_empty(&pr->buffers)) {
		struct blkid_bufinfo *bf = list_entry(pr->buffers.next,
						struct blkid_bufinfo, bufs);
		read_ct++;
		len_ct += bf->len;
		list_del(&bf->bufs);
		free(bf);
	}

	DBG(LOWPROBE, ul_debug("buffers summary: %"PRIu64" bytes "
			"by %"PRIu64" read() call(s)",
			len_ct, read_ct));

	INIT_LIST_HEAD(&pr->buffers);
}

/*
 * Small devices need a special care.
 */
int blkid_probe_is_tiny(blkid_probe pr)
{
	return pr->flags & BLKID_FL_TINY_DEV;
}

/*
 * CDROMs may fail when probed for RAID (last sector problem)
 */
int blkid_probe_is_cdrom(blkid_probe pr)
{
	return pr->flags & BLKID_FL_CDROM_DEV;
}

/**
 * blkid_probe_set_device:
 * @pr: probe
 * @fd: device file descriptor
 * @off: begin of probing area
 * @size: size of probing area (zero means whole device/file)
 *
 * Assigns the device to probe control struct, resets internal buffers and
 * resets the current probing.
 *
 * Returns: -1 in case of failure, or 0 on success.
 */
int blkid_probe_set_device(blkid_probe pr, int fd,
		blkid_loff_t off, blkid_loff_t size)
{
	struct stat sb;

	if (!pr)
		return -1;

	blkid_reset_probe(pr);
	blkid_probe_reset_buffer(pr);

	if ((pr->flags & BLKID_FL_PRIVATE_FD) && pr->fd >= 0)
		close(pr->fd);

	pr->flags &= ~BLKID_FL_PRIVATE_FD;
	pr->flags &= ~BLKID_FL_TINY_DEV;
	pr->flags &= ~BLKID_FL_CDROM_DEV;
	pr->prob_flags = 0;
	pr->fd = fd;
	pr->off = off;
	pr->size = 0;
	pr->devno = 0;
	pr->disk_devno = 0;
	pr->mode = 0;
	pr->blkssz = 0;
	pr->wipe_off = 0;
	pr->wipe_size = 0;
	pr->wipe_chain = NULL;

#if defined(POSIX_FADV_RANDOM) && defined(HAVE_POSIX_FADVISE)
	/* Disable read-ahead */
	posix_fadvise(fd, 0, 0, POSIX_FADV_RANDOM);
#endif
	if (fstat(fd, &sb))
		goto err;

	if (!S_ISBLK(sb.st_mode) && !S_ISCHR(sb.st_mode) && !S_ISREG(sb.st_mode))
		goto err;


	pr->mode = sb.st_mode;
	if (S_ISBLK(sb.st_mode) || S_ISCHR(sb.st_mode))
		pr->devno = sb.st_rdev;

	if (size)
		pr->size = size;
	else {
		if (S_ISBLK(sb.st_mode)) {
			if (blkdev_get_size(fd, (unsigned long long *) &pr->size)) {
				DBG(LOWPROBE, ul_debug("failed to get device size"));
				goto err;
			}
		} else if (S_ISCHR(sb.st_mode))
			pr->size = 1;		/* UBI devices are char... */
		else if (S_ISREG(sb.st_mode))
			pr->size = sb.st_size;	/* regular file */

		if (pr->off > pr->size)
			goto err;

		/* The probing area cannot be larger than whole device, pr->off
		 * is offset within the device */
		pr->size -= pr->off;
	}

	if (pr->size <= 1440 * 1024 && !S_ISCHR(sb.st_mode))
		pr->flags |= BLKID_FL_TINY_DEV;

	if (S_ISBLK(sb.st_mode) && sysfs_devno_is_lvm_private(sb.st_rdev)) {
		DBG(LOWPROBE, ul_debug("ignore private LVM device"));
		pr->flags |= BLKID_FL_NOSCAN_DEV;
	}

#ifdef CDROM_GET_CAPABILITY
	else if (S_ISBLK(sb.st_mode) &&
	    !blkid_probe_is_tiny(pr) &&
	    blkid_probe_is_wholedisk(pr) &&
	    ioctl(fd, CDROM_GET_CAPABILITY, NULL) >= 0)
		pr->flags |= BLKID_FL_CDROM_DEV;
#endif

	DBG(LOWPROBE, ul_debug("ready for low-probing, offset=%jd, size=%jd",
				pr->off, pr->size));
	DBG(LOWPROBE, ul_debug("whole-disk: %s, regfile: %s",
		blkid_probe_is_wholedisk(pr) ?"YES" : "NO",
		S_ISREG(pr->mode) ? "YES" : "NO"));

	return 0;
err:
	DBG(LOWPROBE, ul_debug("failed to prepare a device for low-probing"));
	return -1;

}

int blkid_probe_get_dimension(blkid_probe pr,
		blkid_loff_t *off, blkid_loff_t *size)
{
	*off = pr->off;
	*size = pr->size;
	return 0;
}

int blkid_probe_set_dimension(blkid_probe pr,
		blkid_loff_t off, blkid_loff_t size)
{
	DBG(LOWPROBE, ul_debug(
		"changing probing area pr=%p: size=%llu, off=%llu "
		"-to-> size=%llu, off=%llu",
		pr,
		(unsigned long long) pr->size,
		(unsigned long long) pr->off,
		(unsigned long long) size,
		(unsigned long long) off));

	pr->off = off;
	pr->size = size;
	pr->flags &= ~BLKID_FL_TINY_DEV;

	if (pr->size <= 1440 * 1024 && !S_ISCHR(pr->mode))
		pr->flags |= BLKID_FL_TINY_DEV;

	blkid_probe_reset_buffer(pr);

	return 0;
}

/*
 * Check for matching magic value.
 * Returns BLKID_PROBE_OK if found, BLKID_PROBE_NONE if not found
 * or no magic present, or negative value on error.
 */
int blkid_probe_get_idmag(blkid_probe pr, const struct blkid_idinfo *id,
			blkid_loff_t *offset, const struct blkid_idmag **res)
{
	const struct blkid_idmag *mag = NULL;
	blkid_loff_t off = 0;

	if (id)
		mag = &id->magics[0];
	if (res)
		*res = NULL;

	/* try to detect by magic string */
	while(mag && mag->magic) {
		unsigned char *buf;

		off = (mag->kboff + (mag->sboff >> 10)) << 10;
		buf = blkid_probe_get_buffer(pr, off, 1024);

		if (!buf && errno)
			return -errno;
		if (buf && !memcmp(mag->magic,
				buf + (mag->sboff & 0x3ff), mag->len)) {
			DBG(LOWPROBE, ul_debug("\tmagic sboff=%u, kboff=%ld",
				mag->sboff, mag->kboff));
			if (offset)
				*offset = off + (mag->sboff & 0x3ff);
			if (res)
				*res = mag;
			return BLKID_PROBE_OK;
		}
		mag++;
	}

	if (id && id->magics[0].magic)
		/* magic string(s) defined, but not found */
		return BLKID_PROBE_NONE;

	return BLKID_PROBE_OK;
}

static inline void blkid_probe_start(blkid_probe pr)
{
	if (pr) {
		DBG(LOWPROBE, ul_debug("%p: start probe", pr));
		pr->cur_chain = NULL;
		pr->prob_flags = 0;
		blkid_probe_set_wiper(pr, 0, 0);
	}
}

static inline void blkid_probe_end(blkid_probe pr)
{
	if (pr) {
		DBG(LOWPROBE, ul_debug("%p: end probe", pr));
		pr->cur_chain = NULL;
		pr->prob_flags = 0;
		blkid_probe_set_wiper(pr, 0, 0);
	}
}

/**
 * blkid_do_probe:
 * @pr: prober
 *
 * Calls probing functions in all enabled chains. The superblocks chain is
 * enabled by default. The blkid_do_probe() stores result from only one
 * probing function. It's necessary to call this routine in a loop to get
 * results from all probing functions in all chains. The probing is reset
 * by blkid_reset_probe() or by filter functions.
 *
 * This is string-based NAME=value interface only.
 *
 * <example>
 *   <title>basic case - use the first result only</title>
 *   <programlisting>
 *
 *	if (blkid_do_probe(pr) == 0) {
 *		int nvals = blkid_probe_numof_values(pr);
 *		for (n = 0; n < nvals; n++) {
 *			if (blkid_probe_get_value(pr, n, &name, &data, &len) == 0)
 *				printf("%s = %s\n", name, data);
 *		}
 *	}
 *  </programlisting>
 * </example>
 *
 * <example>
 *   <title>advanced case - probe for all signatures</title>
 *   <programlisting>
 *
 *	while (blkid_do_probe(pr) == 0) {
 *		int nvals = blkid_probe_numof_values(pr);
 *		...
 *	}
 *  </programlisting>
 * </example>
 *
 * See also blkid_reset_probe().
 *
 * Returns: 0 on success, 1 when probing is done and -1 in case of error.
 */
int blkid_do_probe(blkid_probe pr)
{
	int rc = 1;

	if (!pr)
		return -1;

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

	do {
		struct blkid_chain *chn = pr->cur_chain;

		if (!chn) {
			blkid_probe_start(pr);
			chn = pr->cur_chain = &pr->chains[0];
		}
		/* we go to the next chain only when the previous probing
		 * result was nothing (rc == 1) and when the current chain is
		 * disabled or we are at end of the current chain (chain->idx +
		 * 1 == sizeof chain) or the current chain bailed out right at
		 * the start (chain->idx == -1)
		 */
		else if (rc == 1 && (chn->enabled == FALSE ||
				     chn->idx + 1 == (int) chn->driver->nidinfos ||
				     chn->idx == -1)) {

			size_t idx = chn->driver->id + 1;

			if (idx < BLKID_NCHAINS)
				chn = pr->cur_chain = &pr->chains[idx];
			else {
				blkid_probe_end(pr);
				return 1;	/* all chains already probed */
			}
		}

		chn->binary = FALSE;		/* for sure... */

		DBG(LOWPROBE, ul_debug("chain probe %s %s (idx=%d)",
				chn->driver->name,
				chn->enabled? "ENABLED" : "DISABLED",
				chn->idx));

		if (!chn->enabled)
			continue;

		/* rc: -1 = error, 0 = success, 1 = no result */
		rc = chn->driver->probe(pr, chn);

	} while (rc == 1);

	return rc;
}

/**
 * blkid_do_wipe:
 * @pr: prober
 * @dryrun: if TRUE then don't touch the device.
 *
 * This function erases the current signature detected by @pr. The @pr has to
 * be open in O_RDWR mode, BLKID_SUBLKS_MAGIC or/and BLKID_PARTS_MAGIC flags
 * has to be enabled (if you want to errase also superblock with broken check
 * sums then use BLKID_SUBLKS_BADCSUM too).
 *
 * After successful signature removing the @pr prober will be moved one step
 * back and the next blkid_do_probe() call will again call previously called
 * probing function.
 *
 *  <example>
 *  <title>wipe all filesystems or raids from the device</title>
 *   <programlisting>
 *      fd = open(devname, O_RDWR|O_CLOEXEC);
 *      blkid_probe_set_device(pr, fd, 0, 0);
 *
 *      blkid_probe_enable_superblocks(pr, 1);
 *      blkid_probe_set_superblocks_flags(pr, BLKID_SUBLKS_MAGIC);
 *
 *	while (blkid_do_probe(pr) == 0)
 *		blkid_do_wipe(pr, FALSE);
 *  </programlisting>
 * </example>
 *
 * See also blkid_probe_step_back() if you cannot use this build-in wipe
 * function, but you want to use libblkid probing as a source for wiping.
 *
 * Returns: 0 on success, and -1 in case of error.
 */
int blkid_do_wipe(blkid_probe pr, int dryrun)
{
	const char *off = NULL;
	size_t len = 0;
	loff_t offset, l;
	char buf[BUFSIZ];
	int fd, rc = 0;
	struct blkid_chain *chn;

	if (!pr)
		return -1;

	chn = pr->cur_chain;
	if (!chn)
		return -1;

	switch (chn->driver->id) {
	case BLKID_CHAIN_SUBLKS:
		rc = blkid_probe_lookup_value(pr, "SBMAGIC_OFFSET", &off, NULL);
		if (!rc)
			rc = blkid_probe_lookup_value(pr, "SBMAGIC", NULL, &len);
		break;
	case BLKID_CHAIN_PARTS:
		rc = blkid_probe_lookup_value(pr, "PTMAGIC_OFFSET", &off, NULL);
		if (!rc)
			rc = blkid_probe_lookup_value(pr, "PTMAGIC", NULL, &len);
		break;
	default:
		return 0;
	}

	if (rc || len == 0 || off == NULL)
		return 0;

	offset = strtoll(off, NULL, 10);
	fd = blkid_probe_get_fd(pr);
	if (fd < 0)
		return -1;

	if (len > sizeof(buf))
		len = sizeof(buf);

	DBG(LOWPROBE, ul_debug(
	    "do_wipe [offset=0x%jx, len=%zd, chain=%s, idx=%d, dryrun=%s]\n",
	    offset, len, chn->driver->name, chn->idx, dryrun ? "yes" : "not"));

	l = lseek(fd, offset, SEEK_SET);
	if (l == (off_t) -1)
		return -1;

	memset(buf, 0, len);

	if (!dryrun && len) {
		if (write_all(fd, buf, len))
			return -1;
		fsync(fd);
		return blkid_probe_step_back(pr);
	}

	return 0;
}

/**
 * blkid_probe_step_back:
 * @pr: prober
 *
 * This function move pointer to the probing chain one step back -- it means
 * that the previously used probing function will be called again in the next
 * blkid_do_probe() call.
 *
 * This is necessary for example if you erase or modify on-disk superblock
 * according to the current libblkid probing result.
 *
 * <example>
 *  <title>wipe all superblock, but use libblkid only for probing</title>
 *  <programlisting>
 *      pr = blkid_new_probe_from_filename(devname);
 *
 *      blkid_probe_enable_superblocks(pr, 1);
 *      blkid_probe_set_superblocks_flags(pr, BLKID_SUBLKS_MAGIC);
 *
 *      blkid_probe_enable_partitions(pr, 1);
 *      blkid_probe_set_partitions_flags(pr, BLKID_PARTS_MAGIC);
 *
 *	while (blkid_do_probe(pr) == 0) {
 *		const char *ostr = NULL;
 *		size_t len = 0;
 *
 *		// superblocks
 *		if (blkid_probe_lookup_value(pr, "SBMAGIC_OFFSET", &ostr, NULL) == 0)
 *			blkid_probe_lookup_value(pr, "SBMAGIC", NULL, &len);
 *
 *		// partition tables
 *		if (len == 0 && blkid_probe_lookup_value(pr, "PTMAGIC_OFFSET", &ostr, NULL) == 0)
 *			blkid_probe_lookup_value(pr, "PTMAGIC", NULL, &len);
 *
 *		if (!len || !str)
 *			continue;
 *
 *		// convert ostr to the real offset by off = strtoll(ostr, NULL, 10);
 *              // use your stuff to errase @len bytes at the @off
 *              ....
 *
 *		// retry the last probing to check for backup superblocks ..etc.
 *              blkid_probe_step_back(pr);
 *	}
 *  </programlisting>
 * </example>
 *
 * Returns: 0 on success, and -1 in case of error.
 */
int blkid_probe_step_back(blkid_probe pr)
{
	struct blkid_chain *chn;

	if (!pr)
		return -1;

	chn = pr->cur_chain;
	if (!chn)
		return -1;

	blkid_probe_reset_buffer(pr);

	if (chn->idx >= 0) {
		chn->idx--;
		DBG(LOWPROBE, ul_debug("step back: moving %s chain index to %d",
			chn->driver->name,
			chn->idx));
	}

	if (chn->idx == -1) {
		/* blkid_do_probe() goes to the next chain if the index
		 * of the current chain is -1, so we have to set the
		 * chain pointer to the previous chain.
		 */
		size_t idx = chn->driver->id > 0 ? chn->driver->id - 1 : 0;

		DBG(LOWPROBE, ul_debug("step back: moving to previous chain"));

		if (idx > 0)
			pr->cur_chain = &pr->chains[idx];
		else if (idx == 0)
			pr->cur_chain = NULL;
	}

	return 0;
}

/**
 * blkid_do_safeprobe:
 * @pr: prober
 *
 * This function gathers probing results from all enabled chains and checks
 * for ambivalent results (e.g. more filesystems on the device).
 *
 * This is string-based NAME=value interface only.
 *
 * Note about suberblocks chain -- the function does not check for filesystems
 * when a RAID signature is detected.  The function also does not check for
 * collision between RAIDs. The first detected RAID is returned. The function
 * checks for collision between partition table and RAID signature -- it's
 * recommended to enable partitions chain together with superblocks chain.
 *
 * Returns: 0 on success, 1 if nothing is detected, -2 if ambivalen result is
 * detected and -1 on case of error.
 */
int blkid_do_safeprobe(blkid_probe pr)
{
	int i, count = 0, rc = 0;

	if (!pr)
		return -1;
	if (pr->flags & BLKID_FL_NOSCAN_DEV)
		return 1;

	blkid_probe_start(pr);

	for (i = 0; i < BLKID_NCHAINS; i++) {
		struct blkid_chain *chn;

		chn = pr->cur_chain = &pr->chains[i];
		chn->binary = FALSE;		/* for sure... */

		DBG(LOWPROBE, ul_debug("chain safeprobe %s %s",
				chn->driver->name,
				chn->enabled? "ENABLED" : "DISABLED"));

		if (!chn->enabled)
			continue;

		blkid_probe_chain_reset_position(chn);

		rc = chn->driver->safeprobe(pr, chn);

		blkid_probe_chain_reset_position(chn);

		/* rc: -2 ambivalent, -1 = error, 0 = success, 1 = no result */
		if (rc < 0)
			goto done;	/* error */
		if (rc == 0)
			count++;	/* success */
	}

done:
	blkid_probe_end(pr);
	if (rc < 0)
		return rc;
	return count ? 0 : 1;
}

/**
 * blkid_do_fullprobe:
 * @pr: prober
 *
 * This function gathers probing results from all enabled chains. Same as
 * blkid_do_safeprobe() but does not check for collision between probing
 * result.
 *
 * This is string-based NAME=value interface only.
 *
 * Returns: 0 on success, 1 if nothing is detected or -1 on case of error.
 */
int blkid_do_fullprobe(blkid_probe pr)
{
	int i, count = 0, rc = 0;

	if (!pr)
		return -1;
	if (pr->flags & BLKID_FL_NOSCAN_DEV)
		return 1;

	blkid_probe_start(pr);

	for (i = 0; i < BLKID_NCHAINS; i++) {
		struct blkid_chain *chn;

		chn = pr->cur_chain = &pr->chains[i];
		chn->binary = FALSE;		/* for sure... */

		DBG(LOWPROBE, ul_debug("chain fullprobe %s: %s",
				chn->driver->name,
				chn->enabled? "ENABLED" : "DISABLED"));

		if (!chn->enabled)
			continue;

		blkid_probe_chain_reset_position(chn);

		rc = chn->driver->probe(pr, chn);

		blkid_probe_chain_reset_position(chn);

		/* rc: -1 = error, 0 = success, 1 = no result */
		if (rc < 0)
			goto done;	/* error */
		if (rc == 0)
			count++;	/* success */
	}

done:
	blkid_probe_end(pr);
	if (rc < 0)
		return rc;
	return count ? 0 : 1;
}

/* same sa blkid_probe_get_buffer() but works with 512-sectors */
unsigned char *blkid_probe_get_sector(blkid_probe pr, unsigned int sector)
{
	return blkid_probe_get_buffer(pr, ((blkid_loff_t) sector) << 9, 0x200);
}

struct blkid_prval *blkid_probe_assign_value(
			blkid_probe pr, const char *name)
{
	struct blkid_prval *v;

	if (pr->nvals >= BLKID_NVALS)
		return NULL;

	v = &pr->vals[pr->nvals];
	v->name = name;
	v->chain = pr->cur_chain;
	pr->nvals++;

	DBG(LOWPROBE, ul_debug("assigning %s [%s]", name, v->chain->driver->name));
	return v;
}

int blkid_probe_reset_last_value(blkid_probe pr)
{
	struct blkid_prval *v;

	if (pr->nvals == 0)
		return -1;

	v = &pr->vals[pr->nvals - 1];

	DBG(LOWPROBE, ul_debug("un-assigning %s [%s]", v->name, v->chain->driver->name));

	memset(v, 0, sizeof(struct blkid_prval));
	pr->nvals--;

	return 0;

}

int blkid_probe_set_value(blkid_probe pr, const char *name,
		unsigned char *data, size_t len)
{
	struct blkid_prval *v;

	if (len > BLKID_PROBVAL_BUFSIZ)
		len = BLKID_PROBVAL_BUFSIZ;

	v = blkid_probe_assign_value(pr, name);
	if (!v)
		return -1;

	memcpy(v->data, data, len);
	v->len = len;
	return 0;
}

int blkid_probe_vsprintf_value(blkid_probe pr, const char *name,
		const char *fmt, va_list ap)
{
	struct blkid_prval *v;
	ssize_t len;

	v = blkid_probe_assign_value(pr, name);
	if (!v)
		return -1;

	len = vsnprintf((char *) v->data, sizeof(v->data), fmt, ap);

	if (len <= 0 || (size_t) len >= sizeof(v->data)) {
		blkid_probe_reset_last_value(pr);
		return -1;
	}
	v->len = len + 1;
	return 0;
}

int blkid_probe_sprintf_value(blkid_probe pr, const char *name,
		const char *fmt, ...)
{
	int rc;
	va_list ap;

	va_start(ap, fmt);
	rc = blkid_probe_vsprintf_value(pr, name, fmt, ap);
	va_end(ap);

	return rc;
}

int blkid_probe_set_magic(blkid_probe pr, blkid_loff_t offset,
			size_t len, unsigned char *magic)
{
	int rc = 0;
	struct blkid_chain *chn = blkid_probe_get_chain(pr);

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

	switch (chn->driver->id) {
	case BLKID_CHAIN_SUBLKS:
		if (!(chn->flags & BLKID_SUBLKS_MAGIC))
			return 0;
		rc = blkid_probe_set_value(pr, "SBMAGIC", magic, len);
		if (!rc)
			rc = blkid_probe_sprintf_value(pr,
					"SBMAGIC_OFFSET", "%llu", (unsigned long long)offset);
		break;
	case BLKID_CHAIN_PARTS:
		if (!(chn->flags & BLKID_PARTS_MAGIC))
			return 0;
		rc = blkid_probe_set_value(pr, "PTMAGIC", magic, len);
		if (!rc)
			rc = blkid_probe_sprintf_value(pr,
					"PTMAGIC_OFFSET", "%llu", (unsigned long long)offset);
		break;
	default:
		break;
	}

	return rc;
}

int blkid_probe_verify_csum(blkid_probe pr, uint64_t csum, uint64_t expected)
{
	if (csum != expected) {
		struct blkid_chain *chn = blkid_probe_get_chain(pr);

		DBG(LOWPROBE, ul_debug(
				"incorrect checksum for type %s,"
				" got %jX, expected %jX",
				blkid_probe_get_probername(pr),
				csum, expected));
		/*
		 * Accept bad checksum if BLKID_SUBLKS_BADCSUM flags is set
		 */
		if (chn->driver->id == BLKID_CHAIN_SUBLKS
		    && (chn->flags & BLKID_SUBLKS_BADCSUM)) {
			blkid_probe_set_value(pr, "SBBADCSUM", (unsigned char *) "1", 2);
			goto accept;
		}
		return 0;	/* bad checksum */
	}

accept:
	return 1;
}

/**
 * blkid_probe_get_devno:
 * @pr: probe
 *
 * Returns: block device number, or 0 for regular files.
 */
dev_t blkid_probe_get_devno(blkid_probe pr)
{
	return pr->devno;
}

/**
 * blkid_probe_get_wholedisk_devno:
 * @pr: probe
 *
 * Returns: device number of the wholedisk, or 0 for regular files.
 */
dev_t blkid_probe_get_wholedisk_devno(blkid_probe pr)
{
	if (!pr->disk_devno) {
		dev_t devno, disk_devno = 0;

		devno = blkid_probe_get_devno(pr);
		if (!devno)
			return 0;

		 if (blkid_devno_to_wholedisk(devno, NULL, 0, &disk_devno) == 0)
			pr->disk_devno = disk_devno;
	}
	return pr->disk_devno;
}

/**
 * blkid_probe_is_wholedisk:
 * @pr: probe
 *
 * Returns: 1 if the device is whole-disk or 0.
 */
int blkid_probe_is_wholedisk(blkid_probe pr)
{
	dev_t devno, disk_devno;

	devno = blkid_probe_get_devno(pr);
	if (!devno)
		return 0;

	disk_devno = blkid_probe_get_wholedisk_devno(pr);
	if (!disk_devno)
		return 0;

	return devno == disk_devno;
}

blkid_probe blkid_probe_get_wholedisk_probe(blkid_probe pr)
{
	dev_t disk;

	if (blkid_probe_is_wholedisk(pr))
		return NULL;			/* this is not partition */

	if (pr->parent)
		/* this is cloned blkid_probe, use parent's stuff */
		return blkid_probe_get_wholedisk_probe(pr->parent);

	disk = blkid_probe_get_wholedisk_devno(pr);

	if (pr->disk_probe && pr->disk_probe->devno != disk) {
		/* we have disk prober, but for another disk... close it */
		blkid_free_probe(pr->disk_probe);
		pr->disk_probe = NULL;
	}

	if (!pr->disk_probe) {
		/* Open a new disk prober */
		char *disk_path = blkid_devno_to_devname(disk);

		if (!disk_path)
			return NULL;

		DBG(LOWPROBE, ul_debug("allocate a wholedisk probe"));

		pr->disk_probe = blkid_new_probe_from_filename(disk_path);

		free(disk_path);

		if (!pr->disk_probe)
			return NULL;	/* ENOMEM? */
	}

	return pr->disk_probe;
}

/**
 * blkid_probe_get_size:
 * @pr: probe
 *
 * This function returns size of probing area as defined by blkid_probe_set_device().
 * If the size of the probing area is unrestricted then this function returns
 * the real size of device. See also blkid_get_dev_size().
 *
 * Returns: size in bytes or -1 in case of error.
 */
blkid_loff_t blkid_probe_get_size(blkid_probe pr)
{
	return pr ? pr->size : -1;
}

/**
 * blkid_probe_get_offset:
 * @pr: probe
 *
 * This function returns offset of probing area as defined by blkid_probe_set_device().
 *
 * Returns: offset in bytes or -1 in case of error.
 */
blkid_loff_t blkid_probe_get_offset(blkid_probe pr)
{
	return pr ? pr->off : -1;
}

/**
 * blkid_probe_get_fd:
 * @pr: probe
 *
 * Returns: file descriptor for assigned device/file or -1 in case of error.
 */
int blkid_probe_get_fd(blkid_probe pr)
{
	return pr ? pr->fd : -1;
}

/**
 * blkid_probe_get_sectorsize:
 * @pr: probe or NULL (for NULL returns 512)
 *
 * Returns: block device logical sector size (BLKSSZGET ioctl, default 512).
 */
unsigned int blkid_probe_get_sectorsize(blkid_probe pr)
{
	if (!pr)
		return DEFAULT_SECTOR_SIZE;  /*... and good luck! */

	if (pr->blkssz)
		return pr->blkssz;

	if (S_ISBLK(pr->mode) &&
	    blkdev_get_sector_size(pr->fd, (int *) &pr->blkssz) == 0)
		return pr->blkssz;

	pr->blkssz = DEFAULT_SECTOR_SIZE;
	return pr->blkssz;
}

/**
 * blkid_probe_get_sectors:
 * @pr: probe
 *
 * Returns: 512-byte sector count or -1 in case of error.
 */
blkid_loff_t blkid_probe_get_sectors(blkid_probe pr)
{
	return pr ? pr->size >> 9 : -1;
}

/**
 * blkid_probe_numof_values:
 * @pr: probe
 *
 * Returns: number of values in probing result or -1 in case of error.
 */
int blkid_probe_numof_values(blkid_probe pr)
{
	if (!pr)
		return -1;
	return pr->nvals;
}

/**
 * blkid_probe_get_value:
 * @pr: probe
 * @num: wanted value in range 0..N, where N is blkid_probe_numof_values() - 1
 * @name: pointer to return value name or NULL
 * @data: pointer to return value data or NULL
 * @len: pointer to return value length or NULL
 *
 * Note, the @len returns length of the @data, including the terminating
 * '\0' character.
 *
 * Returns: 0 on success, or -1 in case of error.
 */
int blkid_probe_get_value(blkid_probe pr, int num, const char **name,
			const char **data, size_t *len)
{
	struct blkid_prval *v = __blkid_probe_get_value(pr, num);

	if (!v)
		return -1;
	if (name)
		*name = v->name;
	if (data)
		*data = (char *) v->data;
	if (len)
		*len = v->len;

	DBG(LOWPROBE, ul_debug("returning %s value", v->name));
	return 0;
}

/**
 * blkid_probe_lookup_value:
 * @pr: probe
 * @name: name of value
 * @data: pointer to return value data or NULL
 * @len: pointer to return value length or NULL
 *
 * Note, the @len returns length of the @data, including the terminating
 * '\0' character.
 *
 * Returns: 0 on success, or -1 in case of error.
 */
int blkid_probe_lookup_value(blkid_probe pr, const char *name,
			const char **data, size_t *len)
{
	struct blkid_prval *v = __blkid_probe_lookup_value(pr, name);

	if (!v)
		return -1;
	if (data)
		*data = (char *) v->data;
	if (len)
		*len = v->len;
	return 0;
}

/**
 * blkid_probe_has_value:
 * @pr: probe
 * @name: name of value
 *
 * Returns: 1 if value exist in probing result, otherwise 0.
 */
int blkid_probe_has_value(blkid_probe pr, const char *name)
{
	if (blkid_probe_lookup_value(pr, name, NULL, NULL) == 0)
		return 1;
	return 0;
}

struct blkid_prval *__blkid_probe_get_value(blkid_probe pr, int num)
{
	if (num < 0 || num >= pr->nvals)
		return NULL;

	return &pr->vals[num];
}

struct blkid_prval *__blkid_probe_lookup_value(blkid_probe pr, const char *name)
{
	int i;

	if (!pr->nvals)
		return NULL;

	for (i = 0; i < pr->nvals; i++) {
		struct blkid_prval *v = &pr->vals[i];

		if (v->name && strcmp(name, v->name) == 0) {
			DBG(LOWPROBE, ul_debug("returning %s value", v->name));
			return v;
		}
	}
	return NULL;
}


/* converts DCE UUID (uuid[16]) to human readable string
 * - the @len should be always 37 */
#ifdef HAVE_LIBUUID
void blkid_unparse_uuid(const unsigned char *uuid, char *str,
			size_t len __attribute__((__unused__)))
{
	uuid_unparse(uuid, str);
}
#else
void blkid_unparse_uuid(const unsigned char *uuid, char *str, size_t len)
{
	snprintf(str, len,
		"%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
		uuid[0], uuid[1], uuid[2], uuid[3],
		uuid[4], uuid[5],
		uuid[6], uuid[7],
		uuid[8], uuid[9],
		uuid[10], uuid[11], uuid[12], uuid[13], uuid[14],uuid[15]);
}
#endif

/* like uuid_is_null() from libuuid, but works with arbitrary size of UUID */
int blkid_uuid_is_empty(const unsigned char *buf, size_t len)
{
	size_t i;

	for (i = 0; i < len; i++)
		if (buf[i])
			return 0;
	return 1;
}

/* Removes whitespace from the right-hand side of a string (trailing
 * whitespace).
 *
 * Returns size of the new string (without \0).
 */
size_t blkid_rtrim_whitespace(unsigned char *str)
{
	return rtrim_whitespace(str);
}

/* Removes whitespace from the left-hand side of a string.
 *
 * Returns size of the new string (without \0).
 */
size_t blkid_ltrim_whitespace(unsigned char *str)
{
	return ltrim_whitespace(str);
}

/*
 * Some mkfs-like utils wipe some parts (usually begin) of the device.
 * For example LVM (pvcreate) or mkswap(8). This information could be used
 * for later resolution to conflicts between superblocks.
 *
 * For example we found valid LVM superblock, LVM wipes 8KiB at the begin of
 * the device. If we found another signature (for example MBR) within the
 * wiped area then the signature has been added later and LVM superblock
 * should be ignore.
 *
 * Note that this heuristic is not 100% reliable, for example "pvcreate --zero
 * n" allows to keep the begin of the device unmodified. It's probably better
 * to use this heuristic for conflicts between superblocks and partition tables
 * than for conflicts between filesystem superblocks -- existence of unwanted
 * partition table is very unusual, because PT is pretty visible (parsed and
 * interpreted by kernel).
 *
 * Note that we usually expect only one signature on the device, it means that
 * we have to remember only one wiped area from previously successfully
 * detected signature.
 *
 * blkid_probe_set_wiper() -- defines wiped area (e.g. LVM)
 * blkid_probe_use_wiper() -- try to use area (e.g. MBR)
 *
 * Note that there is not relation between _wiper and blkid_to_wipe().
 *
 */
void blkid_probe_set_wiper(blkid_probe pr, blkid_loff_t off, blkid_loff_t size)
{
	struct blkid_chain *chn;

	if (!size) {
		DBG(LOWPROBE, ul_debug("zeroize wiper"));
		pr->wipe_size = pr->wipe_off = 0;
		pr->wipe_chain = NULL;
		return;
	}

	chn = pr->cur_chain;

	if (!chn || !chn->driver ||
	    chn->idx < 0 || (size_t) chn->idx >= chn->driver->nidinfos)
		return;

	pr->wipe_size = size;
	pr->wipe_off = off;
	pr->wipe_chain = chn;

	DBG(LOWPROBE,
		ul_debug("wiper set to %s::%s off=%jd size=%jd",
			chn->driver->name,
			chn->driver->idinfos[chn->idx]->name,
			pr->wipe_off, pr->wipe_size));
	return;
}

/*
 * Returns 1 if the <@off,@size> area was wiped
 */
int blkid_probe_is_wiped(blkid_probe pr, struct blkid_chain **chn,
		     blkid_loff_t off, blkid_loff_t size)
{
	if (!size)
		return 0;

	if (pr->wipe_off <= off && off + size <= pr->wipe_off + pr->wipe_size) {
		*chn = pr->wipe_chain;
		return 1;
	}
	return 0;
}

/*
 *  Try to use any area -- if the area has been previously wiped then the
 *  previous probing result should be ignored (reseted).
 */
void blkid_probe_use_wiper(blkid_probe pr, blkid_loff_t off, blkid_loff_t size)
{
	struct blkid_chain *chn = NULL;

	if (blkid_probe_is_wiped(pr, &chn, off, size) && chn) {
		DBG(LOWPROBE, ul_debug("previously wiped area modified "
				       " -- ignore previous results"));
		blkid_probe_set_wiper(pr, 0, 0);
		blkid_probe_chain_reset_vals(pr, chn);
	}
}
