/*
 *
 * Copyright (C) 2007-2013 Karel Zak <kzak@redhat.com>
 *                    2012 Davidlohr Bueso <dave@gnu.org>
 *
 * This is re-written version for libfdisk, the original was fdiskdoslabel.c
 * from util-linux fdisk.
 */
#include "c.h"
#include "nls.h"
#include "randutils.h"
#include "pt-mbr.h"
#include "strutils.h"

#include "fdiskP.h"

#include <ctype.h>

#define MAXIMUM_PARTS	60
#define ACTIVE_FLAG     0x80

/**
 * SECTION: dos
 * @title: DOS (MBR)
 * @short_description: disk label specific functions
 *
 */


#define IS_EXTENDED(i) \
	((i) == MBR_DOS_EXTENDED_PARTITION \
	 || (i) == MBR_W95_EXTENDED_PARTITION \
	 || (i) == MBR_LINUX_EXTENDED_PARTITION)

/*
 * per partition table entry data
 *
 * The four primary partitions have the same sectorbuffer
 * and have NULL ex_entry.
 *
 * Each logical partition table entry has two pointers, one for the
 * partition and one link to the next one.
 */
struct pte {
	struct dos_partition *pt_entry;	/* on-disk MBR entry */
	struct dos_partition *ex_entry;	/* on-disk EBR entry */
	fdisk_sector_t offset;	        /* disk sector number */
	unsigned char *sectorbuffer;	/* disk sector contents */

	unsigned int changed : 1,
		     private_sectorbuffer : 1;
};

/*
 * in-memory fdisk GPT stuff
 */
struct fdisk_dos_label {
	struct fdisk_label	head;		/* generic part */

	struct pte	ptes[MAXIMUM_PARTS];	/* partition */
	fdisk_sector_t	ext_offset;		/* start of the ext.partition */
	size_t		ext_index;		/* ext.partition index (if ext_offset is set) */
	unsigned int	compatible : 1,		/* is DOS compatible? */
			non_pt_changed : 1;	/* MBR, but no PT changed */
};

/*
 * Partition types
 */
static struct fdisk_parttype dos_parttypes[] = {
	#include "pt-mbr-partnames.h"
};

#define set_hsc(h,s,c,sector) { \
		s = sector % cxt->geom.sectors + 1;			\
		sector /= cxt->geom.sectors;				\
		h = sector % cxt->geom.heads;				\
		sector /= cxt->geom.heads;				\
		c = sector & 0xff;					\
		s |= (sector >> 2) & 0xc0;				\
	}


#define sector(s)	((s) & 0x3f)
#define cylinder(s, c)	((c) | (((s) & 0xc0) << 2))

#define alignment_required(_x)	((_x)->grain != (_x)->sector_size)

#define is_dos_compatible(_x) \
		   (fdisk_is_label(_x, DOS) && \
                    fdisk_dos_is_compatible(fdisk_get_label(_x, NULL)))

#define cround(c, n)	fdisk_cround(c, n)


static inline struct fdisk_dos_label *self_label(struct fdisk_context *cxt)
{
	assert(cxt);
	assert(cxt->label);
	assert(fdisk_is_label(cxt, DOS));

	return (struct fdisk_dos_label *) cxt->label;
}

static inline struct pte *self_pte(struct fdisk_context *cxt, size_t i)
{
	struct fdisk_dos_label *l = self_label(cxt);

	if (i >= ARRAY_SIZE(l->ptes))
		return NULL;

	return &l->ptes[i];
}

static inline struct dos_partition *self_partition(
				struct fdisk_context *cxt,
				size_t i)
{
	struct pte *pe = self_pte(cxt, i);
	return pe ? pe->pt_entry : NULL;
}

struct dos_partition *fdisk_dos_get_partition(
				struct fdisk_context *cxt,
				size_t i)
{
	assert(cxt);
	assert(cxt->label);
	assert(fdisk_is_label(cxt, DOS));

	return self_partition(cxt, i);
}

static struct fdisk_parttype *dos_partition_parttype(
		struct fdisk_context *cxt,
		struct dos_partition *p)
{
	struct fdisk_parttype *t
		= fdisk_label_get_parttype_from_code(cxt->label, p->sys_ind);
	return t ? : fdisk_new_unknown_parttype(p->sys_ind, NULL);
}

/*
 * Linux kernel cares about partition size only. Things like
 * partition type or so are completely irrelevant -- kzak Nov-2013
 */
static int is_used_partition(struct dos_partition *p)
{
	return p && dos_partition_get_size(p) != 0;
}

static void partition_set_changed(
				struct fdisk_context *cxt,
				size_t i,
				int changed)
{
	struct pte *pe = self_pte(cxt, i);

	if (!pe)
		return;

	DBG(LABEL, ul_debug("DOS: setting %zu partition to %s", i,
				changed ? "changed" : "unchanged"));

	pe->changed = changed ? 1 : 0;
	if (changed)
		fdisk_label_set_changed(cxt->label, 1);
}

static fdisk_sector_t get_abs_partition_start(struct pte *pe)
{
	assert(pe);
	assert(pe->pt_entry);

	return pe->offset + dos_partition_get_start(pe->pt_entry);
}

static fdisk_sector_t get_abs_partition_end(struct pte *pe)
{
	fdisk_sector_t size;

	assert(pe);
	assert(pe->pt_entry);

	size = dos_partition_get_size(pe->pt_entry);
	return get_abs_partition_start(pe) + size - (size ? 1 : 0);
}

static int is_cleared_partition(struct dos_partition *p)
{
	return !(!p || p->boot_ind || p->bh || p->bs || p->bc ||
		 p->sys_ind || p->eh || p->es || p->ec ||
		 dos_partition_get_start(p) || dos_partition_get_size(p));
}

static int get_partition_unused_primary(struct fdisk_context *cxt,
					struct fdisk_partition *pa,
					size_t *partno)
{
	size_t org, n;
	int rc;

	assert(cxt);
	assert(cxt->label);
	assert(partno);

	org = cxt->label->nparts_max;

	cxt->label->nparts_max = 4;
	rc = fdisk_partition_next_partno(pa, cxt, &n);
	cxt->label->nparts_max = org;

	if (rc == 1) {
		fdisk_info(cxt, _("All primary partitions have been defined already."));
		rc = -1;
	} else if (rc == 0)
		*partno = n;
	return rc;
}

static int seek_sector(struct fdisk_context *cxt, fdisk_sector_t secno)
{
	off_t offset = (off_t) secno * cxt->sector_size;

	return lseek(cxt->dev_fd, offset, SEEK_SET) == (off_t) -1 ? -errno : 0;
}

static int read_sector(struct fdisk_context *cxt, fdisk_sector_t secno,
			unsigned char *buf)
{
	int rc = seek_sector(cxt, secno);
	ssize_t r;

	if (rc < 0)
		return rc;

	r = read(cxt->dev_fd, buf, cxt->sector_size);
	if (r == (ssize_t) cxt->sector_size)
		return 0;
	if (r < 0)
		return -errno;
	return -1;
}

/* Allocate a buffer and read a partition table sector */
static int read_pte(struct fdisk_context *cxt, size_t pno, fdisk_sector_t offset)
{
	int rc;
	unsigned char *buf;
	struct pte *pe = self_pte(cxt, pno);

	buf = calloc(1, cxt->sector_size);
	if (!buf)
		return -ENOMEM;

	DBG(LABEL, ul_debug("DOS: reading EBR %zu: offset=%ju, buffer=%p",
				pno, (uintmax_t) offset, buf));

	pe->offset = offset;
	pe->sectorbuffer = buf;
	pe->private_sectorbuffer = 1;

	rc = read_sector(cxt, offset, pe->sectorbuffer);
	if (rc) {
		fdisk_warn(cxt, _("Failed to read extended partition table "
				"(offset=%ju)"), (uintmax_t) offset);
		return rc;
	}

	pe->changed = 0;
	pe->pt_entry = pe->ex_entry = NULL;
	return 0;
}


static void clear_partition(struct dos_partition *p)
{
	if (!p)
		return;
	p->boot_ind = 0;
	p->bh = 0;
	p->bs = 0;
	p->bc = 0;
	p->sys_ind = 0;
	p->eh = 0;
	p->es = 0;
	p->ec = 0;
	dos_partition_set_start(p,0);
	dos_partition_set_size(p,0);
}

static void dos_init(struct fdisk_context *cxt)
{
	struct fdisk_dos_label *l = self_label(cxt);
	size_t i;

	assert(cxt);
	assert(cxt->label);
	assert(fdisk_is_label(cxt, DOS));

	DBG(LABEL, ul_debug("DOS: initialize, first sector buffer %p", cxt->firstsector));

	cxt->label->nparts_max = 4;	/* default, unlimited number of logical */

	l->ext_index = 0;
	l->ext_offset = 0;
	l->non_pt_changed = 0;

	memset(l->ptes, 0, sizeof(l->ptes));

	for (i = 0; i < 4; i++) {
		struct pte *pe = self_pte(cxt, i);

		pe->pt_entry = mbr_get_partition(cxt->firstsector, i);
		pe->ex_entry = NULL;
		pe->offset = 0;
		pe->sectorbuffer = cxt->firstsector;
		pe->private_sectorbuffer = 0;
		pe->changed = 0;
	}

	if (fdisk_is_listonly(cxt))
		return;
	/*
	 * Various warnings...
	 */
	if (fdisk_missing_geometry(cxt))
		fdisk_warnx(cxt, _("You can set geometry from the extra functions menu."));

	if (is_dos_compatible(cxt)) {
		fdisk_warnx(cxt, _("DOS-compatible mode is deprecated."));

		if (cxt->sector_size != cxt->phy_sector_size)
			fdisk_info(cxt, _(
		"The device presents a logical sector size that is smaller than "
		"the physical sector size. Aligning to a physical sector (or optimal "
		"I/O) size boundary is recommended, or performance may be impacted."));
	}

	if (fdisk_use_cylinders(cxt))
		fdisk_warnx(cxt, _("Cylinders as display units are deprecated."));

	if (cxt->total_sectors > UINT_MAX) {
		uint64_t bytes = cxt->total_sectors * cxt->sector_size;
		char *szstr = size_to_human_string(SIZE_SUFFIX_SPACE
					   | SIZE_SUFFIX_3LETTER, bytes);
		fdisk_warnx(cxt,
		_("The size of this disk is %s (%ju bytes). DOS "
		  "partition table format can not be used on drives for "
		  "volumes larger than %lu bytes for %lu-byte "
		  "sectors. Use GUID partition table format (GPT)."),
			szstr, bytes,
			UINT_MAX * cxt->sector_size,
			cxt->sector_size);
		free(szstr);
	}
}

/* callback called by libfdisk */
static void dos_deinit(struct fdisk_label *lb)
{
	size_t i;
	struct fdisk_dos_label *l = (struct fdisk_dos_label *) lb;

	for (i = 0; i < ARRAY_SIZE(l->ptes); i++) {
		struct pte *pe = &l->ptes[i];

		if (pe->private_sectorbuffer && pe->sectorbuffer) {
			DBG(LABEL, ul_debug("DOS: freeing pte %zu sector buffer %p",
						i, pe->sectorbuffer));
			free(pe->sectorbuffer);
		}
		pe->sectorbuffer = NULL;
		pe->private_sectorbuffer = 0;
	}

	memset(l->ptes, 0, sizeof(l->ptes));
}

static void reset_pte(struct pte *pe)
{
	assert(pe);

	if (pe->private_sectorbuffer) {
		DBG(LABEL, ul_debug("  --> freeing pte sector buffer %p",
					pe->sectorbuffer));
		free(pe->sectorbuffer);
	}
	memset(pe, 0, sizeof(struct pte));
}

static int dos_delete_partition(struct fdisk_context *cxt, size_t partnum)
{
	struct fdisk_dos_label *l;
	struct pte *pe;
	struct dos_partition *p;
	struct dos_partition *q;

	assert(cxt);
	assert(cxt->label);
	assert(fdisk_is_label(cxt, DOS));

	pe = self_pte(cxt, partnum);
	if (!pe)
		return -EINVAL;

	DBG(LABEL, ul_debug("DOS: delete partiton %zu (max=%zu)", partnum,
				cxt->label->nparts_max));

	l = self_label(cxt);
	p = pe->pt_entry;
	q = pe->ex_entry;

	/* Note that for the fifth partition (partnum == 4) we don't actually
	   decrement partitions. */
	if (partnum < 4) {
		DBG(LABEL, ul_debug("--> delete primary"));
		if (IS_EXTENDED(p->sys_ind) && partnum == l->ext_index) {
			cxt->label->nparts_max = 4;
			l->ptes[l->ext_index].ex_entry = NULL;
			l->ext_offset = 0;
			l->ext_index = 0;
		}
		partition_set_changed(cxt, partnum, 1);
		clear_partition(p);
	} else if (!q->sys_ind && partnum > 4) {
		DBG(LABEL, ul_debug("--> delete logical [last in the chain]"));
		reset_pte(&l->ptes[partnum]);
		--cxt->label->nparts_max;
		--partnum;
		/* clear link to deleted partition */
		clear_partition(l->ptes[partnum].ex_entry);
		partition_set_changed(cxt, partnum, 1);
	} else {
		DBG(LABEL, ul_debug("--> delete logical [move down]"));
		if (partnum > 4) {
			DBG(LABEL, ul_debug(" --> delete %zu logical link", partnum));
			p = l->ptes[partnum - 1].ex_entry;
			*p = *q;
			dos_partition_set_start(p, dos_partition_get_start(q));
			dos_partition_set_size(p, dos_partition_get_size(q));
			partition_set_changed(cxt, partnum - 1, 1);

		} else if (cxt->label->nparts_max > 5) {
			DBG(LABEL, ul_debug(" --> delete first logical link"));
			pe = &l->ptes[5];	/* second logical */

			if (pe->pt_entry)	/* prevent SEGFAULT */
				dos_partition_set_start(pe->pt_entry,
					       get_abs_partition_start(pe) -
					       l->ext_offset);
			pe->offset = l->ext_offset;
			partition_set_changed(cxt, 5, 1);
		}

		if (cxt->label->nparts_max > 5) {
			DBG(LABEL, ul_debug(" --> move ptes"));
			cxt->label->nparts_max--;
			reset_pte(&l->ptes[partnum]);
			while (partnum < cxt->label->nparts_max) {
				DBG(LABEL, ul_debug("  --> moving pte %zu <-- %zu", partnum, partnum + 1));
				l->ptes[partnum] = l->ptes[partnum + 1];
				partnum++;
			}
			memset(&l->ptes[partnum], 0, sizeof(struct pte));
		} else {
			DBG(LABEL, ul_debug(" --> the only logical: clear only"));
			clear_partition(l->ptes[partnum].pt_entry);
			cxt->label->nparts_max--;

			if (partnum == 4) {
				DBG(LABEL, ul_debug("  --> clear last logical"));
				reset_pte(&l->ptes[partnum]);
				partition_set_changed(cxt, l->ext_index, 1);
			}
		}
	}

	fdisk_label_set_changed(cxt->label, 1);
	return 0;
}

static void read_extended(struct fdisk_context *cxt, size_t ext)
{
	size_t i;
	struct pte *pex, *pe;
	struct dos_partition *p, *q;
	struct fdisk_dos_label *l = self_label(cxt);

	l->ext_index = ext;
	pex = self_pte(cxt, ext);
	pex->ex_entry = pex->pt_entry;

	p = pex->pt_entry;
	if (!dos_partition_get_start(p)) {
		fdisk_warnx(cxt, _("Bad offset in primary extended partition."));
		return;
	}

	DBG(LABEL, ul_debug("DOS: Reading extended %zu", ext));

	while (IS_EXTENDED (p->sys_ind)) {
		pe = self_pte(cxt, cxt->label->nparts_max);

		if (cxt->label->nparts_max >= MAXIMUM_PARTS) {
			/* This is not a Linux restriction, but
			   this program uses arrays of size MAXIMUM_PARTS.
			   Do not try to `improve' this test. */
			struct pte *pre = self_pte(cxt,
						cxt->label->nparts_max - 1);
			fdisk_warnx(cxt,
			_("Omitting partitions after #%zu. They will be deleted "
			  "if you save this partition table."),
				cxt->label->nparts_max);

			clear_partition(pre->ex_entry);
			partition_set_changed(cxt,
					cxt->label->nparts_max - 1, 1);
			return;
		}

		if (read_pte(cxt, cxt->label->nparts_max, l->ext_offset +
						dos_partition_get_start(p)))
			return;

		if (!l->ext_offset)
			l->ext_offset = dos_partition_get_start(p);

		assert(pe->sectorbuffer);
		q = p = mbr_get_partition(pe->sectorbuffer, 0);

		for (i = 0; i < 4; i++, p++) {
			if (!dos_partition_get_size(p))
				continue;

			if (IS_EXTENDED (p->sys_ind)) {
				if (pe->ex_entry)
					fdisk_warnx(cxt, _(
					"Extra link pointer in partition "
					"table %zu."),
						cxt->label->nparts_max + 1);
				else
					pe->ex_entry = p;
			} else if (p->sys_ind) {
				if (pe->pt_entry)
					fdisk_warnx(cxt, _(
					"Ignoring extra data in partition "
					"table %zu."),
						cxt->label->nparts_max + 1);
				else
					pe->pt_entry = p;
			}
		}

		/* very strange code here... */
		if (!pe->pt_entry) {
			if (q != pe->ex_entry)
				pe->pt_entry = q;
			else
				pe->pt_entry = q + 1;
		}
		if (!pe->ex_entry) {
			if (q != pe->pt_entry)
				pe->ex_entry = q;
			else
				pe->ex_entry = q + 1;
		}

		p = pe->ex_entry;
		cxt->label->nparts_cur = ++cxt->label->nparts_max;

		DBG(LABEL, ul_debug("DOS: EBR[offset=%ju]: link: type=%x,  start=%u, size=%u; "
				                         " data: type=%x, start=%u, size=%u",
				    (uintmax_t) pe->offset,
				    pe->ex_entry->sys_ind,
				    dos_partition_get_start(pe->ex_entry),
				    dos_partition_get_size(pe->ex_entry),
				    pe->pt_entry->sys_ind,
				    dos_partition_get_start(pe->pt_entry),
				    dos_partition_get_size(pe->pt_entry)));

	}

	/* remove last empty EBR */
	pe = self_pte(cxt, cxt->label->nparts_max - 1);
	if (is_cleared_partition(pe->ex_entry) &&
	    is_cleared_partition(pe->pt_entry)) {
		DBG(LABEL, ul_debug("DOS: EBR[offset=%ju]: empty, remove", (uintmax_t) pe->offset));
		reset_pte(pe);
		cxt->label->nparts_max--;
		cxt->label->nparts_cur--;
	}

	/* remove empty links */
 remove:
	q = self_partition(cxt, 4);
	for (i = 4; i < cxt->label->nparts_max; i++) {
		p = self_partition(cxt, i);

		if (!dos_partition_get_size(p) &&
		    (cxt->label->nparts_max > 5 || q->sys_ind)) {
			fdisk_info(cxt, _("omitting empty partition (%zu)"), i+1);
			dos_delete_partition(cxt, i);
			goto remove; 	/* numbering changed */
		}
	}

	DBG(LABEL, ul_debug("DOS: nparts_max: %zu", cxt->label->nparts_max));
}

static int dos_get_disklabel_id(struct fdisk_context *cxt, char **id)
{
	unsigned int num;

	assert(cxt);
	assert(id);
	assert(cxt->label);
	assert(fdisk_is_label(cxt, DOS));

	num = mbr_get_id(cxt->firstsector);
	if (asprintf(id, "0x%08x", num) > 0)
		return 0;

	return -ENOMEM;
}

static int dos_create_disklabel(struct fdisk_context *cxt)
{
	unsigned int id = 0;
	int rc, has_id = 0;

	assert(cxt);
	assert(cxt->label);
	assert(fdisk_is_label(cxt, DOS));

	DBG(LABEL, ul_debug("DOS: creating new disklabel"));

	if (cxt->script) {
		char *end = NULL;
		const char *s = fdisk_script_get_header(cxt->script, "label-id");

		if (s) {
			errno = 0;
			id = strtol(s, &end, 16);
			if (!errno && end && s < end)
				has_id = 1;
		}
	}

	/* random disk signature */
	if (!has_id)
		random_get_bytes(&id, sizeof(id));

	dos_init(cxt);
	rc = fdisk_init_firstsector_buffer(cxt);
	if (rc)
		return rc;
	fdisk_label_set_changed(cxt->label, 1);

	/* Generate an MBR ID for this disk */
	mbr_set_id(cxt->firstsector, id);

	/* Put MBR signature */
	mbr_set_magic(cxt->firstsector);

	fdisk_info(cxt, _("Created a new DOS disklabel with disk "
			 "identifier 0x%08x."), id);
	return 0;
}

static int dos_set_disklabel_id(struct fdisk_context *cxt)
{
	char *end = NULL, *str = NULL;
	unsigned int id, old;
	struct fdisk_dos_label *l;
	int rc;

	assert(cxt);
	assert(cxt->label);
	assert(fdisk_is_label(cxt, DOS));

	DBG(LABEL, ul_debug("DOS: setting Id"));

	l = self_label(cxt);
	old = mbr_get_id(cxt->firstsector);
	rc = fdisk_ask_string(cxt,
			_("Enter the new disk identifier"), &str);
	if (rc)
		return rc;

	errno = 0;
	id = strtoul(str, &end, 0);
	if (errno || str == end || (end && *end)) {
		fdisk_warnx(cxt, _("Incorrect value."));
		return -EINVAL;
	}


	mbr_set_id(cxt->firstsector, id);
	l->non_pt_changed = 1;
	fdisk_label_set_changed(cxt->label, 1);

	fdisk_info(cxt, _("Disk identifier changed from 0x%08x to 0x%08x."),
			old, id);
	return 0;
}

static void get_partition_table_geometry(struct fdisk_context *cxt,
			unsigned int *ph, unsigned int *ps)
{
	unsigned char *bufp = cxt->firstsector;
	struct dos_partition *p;
	int i, h, s, hh, ss;
	int first = 1;
	int bad = 0;

	hh = ss = 0;
	for (i = 0; i < 4; i++) {
		p = mbr_get_partition(bufp, i);
		if (p->sys_ind != 0) {
			h = p->eh + 1;
			s = (p->es & 077);
			if (first) {
				hh = h;
				ss = s;
				first = 0;
			} else if (hh != h || ss != s)
				bad = 1;
		}
	}

	if (!first && !bad) {
		*ph = hh;
		*ps = ss;
	}

	DBG(LABEL, ul_debug("DOS PT geometry: heads=%u, sectors=%u", *ph, *ps));
}

static int dos_reset_alignment(struct fdisk_context *cxt)
{
	assert(cxt);
	assert(cxt->label);
	assert(fdisk_is_label(cxt, DOS));

	/* overwrite necessary stuff by DOS deprecated stuff */
	if (is_dos_compatible(cxt)) {
		DBG(LABEL, ul_debug("DOS: reseting alignemnt for DOS-comaptiblem PT"));
		if (cxt->geom.sectors)
			cxt->first_lba = cxt->geom.sectors;	/* usually 63 */

		cxt->grain = cxt->sector_size;			/* usually 512 */
	}

	return 0;
}

/* TODO: move to include/pt-dos.h and share with libblkid */
#define AIX_MAGIC_STRING	"\xC9\xC2\xD4\xC1"
#define AIX_MAGIC_STRLEN	(sizeof(AIX_MAGIC_STRING) - 1)

static int dos_probe_label(struct fdisk_context *cxt)
{
	size_t i;
	unsigned int h = 0, s = 0;

	assert(cxt);
	assert(cxt->label);
	assert(fdisk_is_label(cxt, DOS));

	/* ignore disks with AIX magic number */
	if (memcmp(cxt->firstsector, AIX_MAGIC_STRING, AIX_MAGIC_STRLEN) == 0)
		return 0;

	if (!mbr_is_valid_magic(cxt->firstsector))
		return 0;

	dos_init(cxt);

	get_partition_table_geometry(cxt, &h, &s);
	if (h && s) {
		cxt->geom.heads = h;
	        cxt->geom.sectors = s;
	}

	for (i = 0; i < 4; i++) {
		struct pte *pe = self_pte(cxt, i);

		if (is_used_partition(pe->pt_entry))
			cxt->label->nparts_cur++;

		if (IS_EXTENDED (pe->pt_entry->sys_ind)) {
			if (cxt->label->nparts_max != 4)
				fdisk_warnx(cxt, _(
				"Ignoring extra extended partition %zu"),
					i + 1);
			else
				read_extended(cxt, i);
		}
	}

	for (i = 3; i < cxt->label->nparts_max; i++) {
		struct pte *pe = self_pte(cxt, i);
		struct fdisk_dos_label *l = self_label(cxt);

		if (!mbr_is_valid_magic(pe->sectorbuffer)) {
			fdisk_info(cxt, _(
			"Invalid flag 0x%02x%02x of EBR (for partition %zu) will "
			"be corrected by w(rite)."),
				pe->sectorbuffer[510],
				pe->sectorbuffer[511],
				i + 1);
			partition_set_changed(cxt, i, 1);

			/* mark also extended as changed to update the first EBR
			 * in situation that there is no logical partitions at all */
			partition_set_changed(cxt, l->ext_index, 1);
		}
	}

	return 1;
}

static void set_partition(struct fdisk_context *cxt,
			  int i, int doext, fdisk_sector_t start,
			  fdisk_sector_t stop, int sysid, int boot)
{
	struct pte *pe = self_pte(cxt, i);
	struct dos_partition *p;
	fdisk_sector_t offset;

	assert(!FDISK_IS_UNDEF(start));
	assert(!FDISK_IS_UNDEF(stop));

	if (doext) {
		struct fdisk_dos_label *l = self_label(cxt);
		p = pe->ex_entry;
		offset = l->ext_offset;
	} else {
		p = pe->pt_entry;
		offset = pe->offset;
	}

	DBG(LABEL, ul_debug("DOS: setting partition %d%s, offset=%zu, start=%zu, stop=%zu, sysid=%02x",
				i, doext ? " [extended]" : "",
				(size_t) offset,
				(size_t) (start -  offset),
				(size_t) (stop - start + 1),
				sysid));

	p->boot_ind = boot ? ACTIVE_FLAG : 0;
	p->sys_ind = sysid;
	dos_partition_set_start(p, start - offset);
	dos_partition_set_size(p, stop - start + 1);

	if (is_dos_compatible(cxt) && (start/(cxt->geom.sectors*cxt->geom.heads) > 1023))
		start = cxt->geom.heads*cxt->geom.sectors*1024 - 1;
	set_hsc(p->bh, p->bs, p->bc, start);
	if (is_dos_compatible(cxt) && (stop/(cxt->geom.sectors*cxt->geom.heads) > 1023))
		stop = cxt->geom.heads*cxt->geom.sectors*1024 - 1;
	set_hsc(p->eh, p->es, p->ec, stop);
	partition_set_changed(cxt, i, 1);
}

static fdisk_sector_t get_unused_start(struct fdisk_context *cxt,
				 int part_n, fdisk_sector_t start,
				 fdisk_sector_t first[], fdisk_sector_t last[])
{
	size_t i;

	for (i = 0; i < cxt->label->nparts_max; i++) {
		fdisk_sector_t lastplusoff;
		struct pte *pe = self_pte(cxt, i);

		if (start == pe->offset)
			start += cxt->first_lba;
		lastplusoff = last[i] + ((part_n < 4) ? 0 : cxt->first_lba);
		if (start >= first[i] && start <= lastplusoff)
			start = lastplusoff + 1;
	}

	return start;
}

static void fill_bounds(struct fdisk_context *cxt,
			fdisk_sector_t *first, fdisk_sector_t *last)
{
	size_t i;
	struct pte *pe = self_pte(cxt, 0);
	struct dos_partition *p;

	for (i = 0; i < cxt->label->nparts_max; pe++,i++) {
		p = pe->pt_entry;
		if (is_cleared_partition(p) || IS_EXTENDED (p->sys_ind)) {
			first[i] = 0xffffffff;
			last[i] = 0;
		} else {
			first[i] = get_abs_partition_start(pe);
			last[i]  = get_abs_partition_end(pe);
		}
	}
}

static int get_start_from_user(	struct fdisk_context *cxt,
				fdisk_sector_t *start,
				fdisk_sector_t low,
				fdisk_sector_t dflt,
				fdisk_sector_t limit,
				struct fdisk_partition *pa)
{
	assert(start);

	/* try to use tepmlate from 'pa' */
	if (pa && pa->start_follow_default)
		*start = dflt;

	else if (pa && fdisk_partition_has_start(pa)) {
		DBG(LABEL, ul_debug("DOS: start: wanted=%ju, low=%ju, limit=%ju",
				(uintmax_t) pa->start, (uintmax_t) low, (uintmax_t) limit));
		*start = pa->start;
		if (*start < low || *start > limit) {
			fdisk_warnx(cxt, _("Start sector %ju out of range."),
					(uintmax_t) *start);
			return -ERANGE;
		}
	} else {
		/* ask user by dialog */
		struct fdisk_ask *ask = fdisk_new_ask();
		int rc;

		if (!ask)
			return -ENOMEM;
		fdisk_ask_set_query(ask,
			fdisk_use_cylinders(cxt) ?
				_("First cylinder") : _("First sector"));
		fdisk_ask_set_type(ask, FDISK_ASKTYPE_NUMBER);
		fdisk_ask_number_set_low(ask, fdisk_cround(cxt, low));
		fdisk_ask_number_set_default(ask, fdisk_cround(cxt, dflt));
		fdisk_ask_number_set_high(ask, fdisk_cround(cxt, limit));

		rc = fdisk_do_ask(cxt, ask);
		*start = fdisk_ask_number_get_result(ask);
		fdisk_unref_ask(ask);
		if (rc)
			return rc;
		if (fdisk_use_cylinders(cxt)) {
		        *start = (*start - 1)
				* fdisk_get_units_per_sector(cxt);
			if (*start < low)
				*start = low;
		}
	}

	DBG(LABEL, ul_debug("DOS: start is %ju", (uintmax_t) *start));
	return 0;
}

static fdisk_sector_t get_possible_last(struct fdisk_context *cxt, size_t n)
{
	fdisk_sector_t limit;

	if (n >= 4) {
		/* logical partitions */
		struct fdisk_dos_label *l = self_label(cxt);
		struct pte *ext_pe = l->ext_offset ? self_pte(cxt, l->ext_index) : NULL;

		if (!ext_pe)
			return 0;
		limit = get_abs_partition_end(ext_pe);
	} else {
		/* primary partitions */
		if (fdisk_use_cylinders(cxt) || !cxt->total_sectors)
			limit = cxt->geom.heads * cxt->geom.sectors * cxt->geom.cylinders - 1;
		else
			limit = cxt->total_sectors - 1;

		if (limit > UINT_MAX)
			limit = UINT_MAX;
	}

	DBG(LABEL, ul_debug("DOS: last possible sector for #%zu is %ju",
				n, (uintmax_t) limit));
	return limit;
}

/* returns last free sector for area addressed by @start, the first[] and
 * last[] are fill_bounds() results */
static fdisk_sector_t get_unused_last(struct fdisk_context *cxt, size_t n,
				fdisk_sector_t start,
				fdisk_sector_t first[], fdisk_sector_t last[])
{
	size_t i;
	fdisk_sector_t limit = get_possible_last(cxt, n);

	for (i = 0; i < cxt->label->nparts_max; i++) {
		struct pte *pe = self_pte(cxt, i);

		if (start < pe->offset && limit >= pe->offset)
			limit = pe->offset - 1;
		if (start < first[i] && limit >= first[i])
			limit = first[i] - 1;
	}

	DBG(LABEL, ul_debug("DOS: unused sector for #%zu is %ju",
				n, (uintmax_t) limit));
	return limit;
}

static int add_partition(struct fdisk_context *cxt, size_t n,
			 struct fdisk_partition *pa)
{
	int sys, read = 0, rc, isrel = 0;
	size_t i;
	struct fdisk_dos_label *l = self_label(cxt);
	struct dos_partition *p = self_partition(cxt, n);
	struct pte *ext_pe = l->ext_offset ? self_pte(cxt, l->ext_index) : NULL;

	fdisk_sector_t start, stop = 0, limit, temp,
		first[cxt->label->nparts_max],
		last[cxt->label->nparts_max];

	DBG(LABEL, ul_debug("DOS: adding partition %zu", n));

	sys = pa && pa->type ? pa->type->code : MBR_LINUX_DATA_PARTITION;

	if (is_used_partition(p)) {
		fdisk_warnx(cxt, _("Partition %zu is already defined.  "
			           "Delete it before re-adding it."),
				n + 1);
		return -EINVAL;
	}
	fill_bounds(cxt, first, last);
	limit = get_possible_last(cxt, n);

	if (n < 4) {
		if (cxt->parent && fdisk_is_label(cxt->parent, GPT))
			start = 1;		/* Bad boy modifies hybrid MBR */
		else {
			if (cxt->script && pa && fdisk_partition_has_start(pa)
			    && pa->start < cxt->first_lba
			    && pa->start >= 1)
				fdisk_set_first_lba(cxt, 1);

			start = cxt->first_lba;
		}

		if (l->ext_offset) {
			assert(ext_pe);
			first[l->ext_index] = l->ext_offset;
			last[l->ext_index] = get_abs_partition_end(ext_pe);
		}
	} else {
		assert(ext_pe);

		if (cxt->script && pa && fdisk_partition_has_start(pa)
		    && pa->start >= l->ext_offset
		    && pa->start < l->ext_offset + cxt->first_lba)
			fdisk_set_first_lba(cxt, 1);

		start = l->ext_offset + cxt->first_lba;
	}

	if (fdisk_use_cylinders(cxt))
		for (i = 0; i < cxt->label->nparts_max; i++) {
			first[i] = (fdisk_cround(cxt, first[i]) - 1)
				* fdisk_get_units_per_sector(cxt);
		}

	/*
	 * Ask for first sector
	 */
	do {
		fdisk_sector_t dflt, aligned;

		temp = start;
		dflt = start = get_unused_start(cxt, n, start, first, last);

		if (n >= 4 && pa && fdisk_partition_has_start(pa) && cxt->script
		    && cxt->first_lba > 1
		    && temp == start - cxt->first_lba) {
			fdisk_set_first_lba(cxt, 1);
			start = pa->start;
		}

		/* the default sector should be aligned and unused */
		do {
			aligned = fdisk_align_lba_in_range(cxt, dflt, dflt, limit);
			dflt = get_unused_start(cxt, n, aligned, first, last);
		} while (dflt != aligned && dflt > aligned && dflt < limit);

		if (dflt >= limit)
			dflt = start;
		if (start > limit)
			break;
		if (start >= temp + fdisk_get_units_per_sector(cxt)
		    && read) {
			fdisk_info(cxt, _("Sector %llu is already allocated."),
					temp);
			temp = start;
			read = 0;
			if (pa && (fdisk_partition_has_start(pa) ||
				   pa->start_follow_default))
				break;
		}

		if (!read && start == temp) {
			rc = get_start_from_user(cxt, &start, temp, dflt, limit, pa);
			if (rc)
				return rc;
			read = 1;
		}
	} while (start != temp || !read);

	if (n == 4) {
		/* The first EBR is stored at begin of the extended partition */
		struct pte *pe = self_pte(cxt, n);
		pe->offset = l->ext_offset;

	} else if (n > 4) {
		/* The second (and another) EBR */
		struct pte *pe = self_pte(cxt, n);

		pe->offset = start - cxt->first_lba;
		if (pe->offset == l->ext_offset) { /* must be corrected */
			pe->offset++;
			if (cxt->first_lba == 1)
				start++;
		}
	}

	limit = get_unused_last(cxt, n, start, first, last);

	if (start > limit) {
		fdisk_info(cxt, _("No free sectors available."));
		if (n > 4)
			cxt->label->nparts_max--;
		return -ENOSPC;
	}

	/*
	 * Ask for last sector
	 */
	if (fdisk_cround(cxt, start) == fdisk_cround(cxt, limit))
		stop = limit;
	else if (pa && pa->end_follow_default)
		stop = limit;
	else if (pa && fdisk_partition_has_size(pa)) {
		stop = start + pa->size - 1;
		isrel = pa->size_explicit ? 0 : 1;
	} else {
		/* ask user by dialog */
		struct fdisk_ask *ask = fdisk_new_ask();

		if (!ask)
			return -ENOMEM;
		fdisk_ask_set_type(ask, FDISK_ASKTYPE_OFFSET);

		if (fdisk_use_cylinders(cxt)) {
			fdisk_ask_set_query(ask, _("Last cylinder, +cylinders or +size{K,M,G,T,P}"));
			fdisk_ask_number_set_unit(ask,
				     cxt->sector_size *
				     fdisk_get_units_per_sector(cxt));
		} else {
			fdisk_ask_set_query(ask, _("Last sector, +sectors or +size{K,M,G,T,P}"));
			fdisk_ask_number_set_unit(ask,cxt->sector_size);
		}

		fdisk_ask_number_set_low(ask, fdisk_cround(cxt, start));
		fdisk_ask_number_set_default(ask, fdisk_cround(cxt, limit));
		fdisk_ask_number_set_high(ask, fdisk_cround(cxt, limit));
		fdisk_ask_number_set_base(ask, fdisk_cround(cxt, start));	/* base for relative input */

		rc = fdisk_do_ask(cxt, ask);
		stop = fdisk_ask_number_get_result(ask);
		isrel = fdisk_ask_number_is_relative(ask);
		fdisk_unref_ask(ask);
		if (rc)
			return rc;
		if (fdisk_use_cylinders(cxt)) {
			stop = stop * fdisk_get_units_per_sector(cxt) - 1;
			if (stop >limit)
				stop = limit;
		}
	}

	DBG(LABEL, ul_debug("DOS: raw stop: %ju", (uintmax_t) stop));

	if (stop > limit)
		stop = limit;

	if (stop < limit) {
		if (isrel && alignment_required(cxt)) {
			/* the last sector has not been exactly requested (but
			 * defined by +size{K,M,G} convention), so be smart and
			 * align the end of the partition. The next partition
			 * will start at phy.block boundary.
			 */
			stop = fdisk_align_lba_in_range(cxt, stop, start, limit) - 1;
			if (stop > limit)
				stop = limit;
		}
	}

	set_partition(cxt, n, 0, start, stop, sys, pa && pa->boot == 1 ? 1 : 0);
	if (n > 4) {
		struct pte *pe = self_pte(cxt, n);
		set_partition(cxt, n - 1, 1, pe->offset, stop,
					MBR_DOS_EXTENDED_PARTITION, 0);
	}

	/* report */
	{
		struct fdisk_parttype *t =
			fdisk_label_get_parttype_from_code(cxt->label, sys);
		fdisk_info_new_partition(cxt, n + 1, start, stop, t);
		fdisk_unref_parttype(t);
	}


	if (IS_EXTENDED(sys)) {
		struct pte *pen = self_pte(cxt, n);

		l->ext_index = n;
		l->ext_offset = start;
		pen->ex_entry = p;
	}

	fdisk_label_set_changed(cxt->label, 1);
	return 0;
}

static int add_logical(struct fdisk_context *cxt,
		       struct fdisk_partition *pa,
		       size_t *partno)
{
	struct pte *pe;
	int rc;

	assert(cxt);
	assert(partno);
	assert(cxt->label);
	assert(self_label(cxt)->ext_offset);

	DBG(LABEL, ul_debug("DOS: nparts max: %zu", cxt->label->nparts_max));
	pe = self_pte(cxt, cxt->label->nparts_max);

	if (!pe->sectorbuffer) {
		pe->sectorbuffer = calloc(1, cxt->sector_size);
		if (!pe->sectorbuffer)
			return -ENOMEM;
		DBG(LABEL, ul_debug("DOS: logical: %zu: new EBR sector buffer %p",
					cxt->label->nparts_max, pe->sectorbuffer));
		pe->private_sectorbuffer = 1;
	}
	pe->pt_entry = mbr_get_partition(pe->sectorbuffer, 0);
	pe->ex_entry = pe->pt_entry + 1;
	pe->offset = 0;
	partition_set_changed(cxt, cxt->label->nparts_max, 1);

	cxt->label->nparts_max++;

	/* this message makes sense only when we use extended/primary/logical
	 * dialog. The dialog is disable for scripts, see dos_add_partition() */
	if (!cxt->script)
		fdisk_info(cxt, _("Adding logical partition %zu"),
				cxt->label->nparts_max);
	*partno = cxt->label->nparts_max - 1;
	rc = add_partition(cxt, *partno, pa);

	if (rc) {
		/* reset on error */
		cxt->label->nparts_max--;
		pe->pt_entry = NULL;
		pe->ex_entry = NULL;
		pe->offset = 0;
		pe->changed = 0;
	}

	return rc;
}

static void check(struct fdisk_context *cxt, size_t n,
	   unsigned int h, unsigned int s, unsigned int c,
	   unsigned int start)
{
	unsigned int total, real_s, real_c;

	if (!is_dos_compatible(cxt))
		return;

	real_s = sector(s) - 1;
	real_c = cylinder(s, c);
	total = (real_c * cxt->geom.heads + h) * cxt->geom.sectors + real_s;

	if (!total)
		fdisk_warnx(cxt, _("Partition %zu: contains sector 0"), n);
	if (h >= cxt->geom.heads)
		fdisk_warnx(cxt, _("Partition %zu: head %d greater than "
				   "maximum %d"), n, h + 1, cxt->geom.heads);
	if (real_s >= cxt->geom.sectors)
		fdisk_warnx(cxt, _("Partition %zu: sector %d greater than "
				   "maximum %llu"), n, s, cxt->geom.sectors);
	if (real_c >= cxt->geom.cylinders)
		fdisk_warnx(cxt, _("Partition %zu: cylinder %d greater than "
				   "maximum %llu"),
				n, real_c + 1,
				cxt->geom.cylinders);

	if (cxt->geom.cylinders <= 1024 && start != total)
		fdisk_warnx(cxt, _("Partition %zu: previous sectors %u "
				   "disagrees with total %u"), n, start, total);
}

/* check_consistency() and long2chs() added Sat Mar 6 12:28:16 1993,
 * faith@cs.unc.edu, based on code fragments from pfdisk by Gordon W. Ross,
 * Jan.  1990 (version 1.2.1 by Gordon W. Ross Aug. 1990; Modified by S.
 * Lubkin Oct.  1991). */

static void
long2chs(struct fdisk_context *cxt, unsigned long ls,
	 unsigned int *c, unsigned int *h, unsigned int *s) {
	int spc = cxt->geom.heads * cxt->geom.sectors;

	*c = ls / spc;
	ls = ls % spc;
	*h = ls / cxt->geom.sectors;
	*s = ls % cxt->geom.sectors + 1;	/* sectors count from 1 */
}

static void check_consistency(struct fdisk_context *cxt, struct dos_partition *p,
			      size_t partition)
{
	unsigned int pbc, pbh, pbs;	/* physical beginning c, h, s */
	unsigned int pec, peh, pes;	/* physical ending c, h, s */
	unsigned int lbc, lbh, lbs;	/* logical beginning c, h, s */
	unsigned int lec, leh, les;	/* logical ending c, h, s */

	if (!is_dos_compatible(cxt))
		return;

	if (!cxt->geom.heads || !cxt->geom.sectors || (partition >= 4))
		return;		/* do not check extended partitions */

	/* physical beginning c, h, s */
	pbc = (p->bc & 0xff) | ((p->bs << 2) & 0x300);
	pbh = p->bh;
	pbs = p->bs & 0x3f;

	/* physical ending c, h, s */
	pec = (p->ec & 0xff) | ((p->es << 2) & 0x300);
	peh = p->eh;
	pes = p->es & 0x3f;

	/* compute logical beginning (c, h, s) */
	long2chs(cxt, dos_partition_get_start(p), &lbc, &lbh, &lbs);

	/* compute logical ending (c, h, s) */
	long2chs(cxt, dos_partition_get_start(p) + dos_partition_get_size(p) - 1, &lec, &leh, &les);

	/* Same physical / logical beginning? */
	if (cxt->geom.cylinders <= 1024
	    && (pbc != lbc || pbh != lbh || pbs != lbs)) {
		fdisk_warnx(cxt, _("Partition %zu: different physical/logical "
			"beginnings (non-Linux?): "
			"phys=(%d, %d, %d), logical=(%d, %d, %d)"),
			partition + 1,
			pbc, pbh, pbs,
			lbc, lbh, lbs);
	}

	/* Same physical / logical ending? */
	if (cxt->geom.cylinders <= 1024
	    && (pec != lec || peh != leh || pes != les)) {
		fdisk_warnx(cxt, _("Partition %zu: different physical/logical "
			"endings: phys=(%d, %d, %d), logical=(%d, %d, %d)"),
			partition + 1,
			pec, peh, pes,
			lec, leh, les);
	}

	/* Ending on cylinder boundary? */
	if (peh != (cxt->geom.heads - 1) || pes != cxt->geom.sectors) {
		fdisk_warnx(cxt, _("Partition %zu: does not end on "
				   "cylinder boundary."),
			partition + 1);
	}
}

static int dos_verify_disklabel(struct fdisk_context *cxt)
{
	size_t i, j;
	fdisk_sector_t total = 1, n_sectors = cxt->total_sectors;
	fdisk_sector_t first[cxt->label->nparts_max],
		       last[cxt->label->nparts_max];
	struct dos_partition *p;
	struct fdisk_dos_label *l = self_label(cxt);

	assert(fdisk_is_label(cxt, DOS));

	fill_bounds(cxt, first, last);
	for (i = 0; i < cxt->label->nparts_max; i++) {
		struct pte *pe = self_pte(cxt, i);

		p = self_partition(cxt, i);
		if (is_used_partition(p) && !IS_EXTENDED(p->sys_ind)) {
			check_consistency(cxt, p, i);
			if (get_abs_partition_start(pe) < first[i])
				fdisk_warnx(cxt, _(
					"Partition %zu: bad start-of-data."),
					 i + 1);

			check(cxt, i + 1, p->eh, p->es, p->ec, last[i]);
			total += last[i] + 1 - first[i];

			if (i == 0)
				total += get_abs_partition_start(pe) - 1;

			for (j = 0; j < i; j++) {
				if ((first[i] >= first[j] && first[i] <= last[j])
				    || ((last[i] <= last[j] && last[i] >= first[j]))) {

					fdisk_warnx(cxt, _("Partition %zu: "
						"overlaps partition %zu."),
						j + 1, i + 1);

					total += first[i] >= first[j] ?
						first[i] : first[j];
					total -= last[i] <= last[j] ?
						last[i] : last[j];
				}
			}
		}
	}

	if (l->ext_offset) {
		fdisk_sector_t e_last;
		struct pte *ext_pe = self_pte(cxt, l->ext_index);

		e_last = get_abs_partition_end(ext_pe);

		for (i = 4; i < cxt->label->nparts_max; i++) {
			total++;
			p = self_partition(cxt, i);

			if (!p->sys_ind) {
				if (i != 4 || i + 1 < cxt->label->nparts_max)
					fdisk_warnx(cxt,
						_("Partition %zu: empty."),
						i + 1);
			} else if (first[i] < l->ext_offset
				   || last[i] > e_last) {

				fdisk_warnx(cxt, _("Logical partition %zu: "
					"not entirely in partition %zu."),
					i + 1, l->ext_index + 1);
			}
		}
	}

	if (total > n_sectors)
		fdisk_warnx(cxt, _("Total allocated sectors %llu greater "
			"than the maximum %llu."), total, n_sectors);
	else if (total < n_sectors)
		fdisk_warnx(cxt, _("Remaining %lld unallocated %ld-byte "
			"sectors."), n_sectors - total, cxt->sector_size);

	return 0;
}

/*
 * Ask the user for new partition type information (logical, extended).
 * This function calls the actual partition adding logic - add_partition.
 *
 * API callback.
 */
static int dos_add_partition(struct fdisk_context *cxt,
			     struct fdisk_partition *pa,
			     size_t *partno)
{
	size_t i, free_primary = 0, free_sectors = 0;
	fdisk_sector_t last = 0, grain;
	int rc = 0;
	struct fdisk_dos_label *l;
	struct pte *ext_pe;
	size_t res;		/* partno */

	assert(cxt);
	assert(cxt->label);
	assert(fdisk_is_label(cxt, DOS));

	DBG(LABEL, ul_debug("DOS: new partition wanted"));

	l = self_label(cxt);
	ext_pe = l->ext_offset ? self_pte(cxt, l->ext_index) : NULL;

	/*
	 * partition template (@pa) based partitioning
	 */

	/* pa specifies start within extended partition, add logical */
	if (pa && fdisk_partition_has_start(pa) && ext_pe
	    && pa->start >= l->ext_offset
	    && pa->start <= get_abs_partition_end(ext_pe)) {
		DBG(LABEL, ul_debug("DOS: pa template %p: add logical", pa));
		rc = add_logical(cxt, pa, &res);
		goto done;

	/* pa specifies that extended partition is wanted */
	} else if (pa && pa->type && pa->type->code == MBR_DOS_EXTENDED_PARTITION) {
		DBG(LABEL, ul_debug("DOS: pa template %p: add extened", pa));
		if (l->ext_offset) {
			fdisk_warnx(cxt, _("Extended partition already exists."));
			return -EINVAL;
		}
		rc = get_partition_unused_primary(cxt, pa, &res);
		if (rc == 0) {
			rc = add_partition(cxt, res, pa);
			goto done;
		}

	/* pa specifies start, but outside extended partition */
	} else if (pa && fdisk_partition_has_start(pa) && l->ext_offset) {
		DBG(LABEL, ul_debug("DOS: pa template %p: add primary", pa));
		rc = get_partition_unused_primary(cxt, pa, &res);
		if (rc == 0) {
			rc = add_partition(cxt, res, pa);
			goto done;
		}
	}

	/*
	 * dialog driven partitioning (it does not mean that @pa template is
	 * completely ignored!)
	 */

	/* check if there is space for primary partition */
	grain = cxt->grain > cxt->sector_size ? cxt->grain / cxt->sector_size : 1;
	last = cxt->first_lba;

	for (i = 0; i < 4; i++) {
		struct dos_partition *p = self_partition(cxt, i);

		if (is_used_partition(p)) {
			fdisk_sector_t start = dos_partition_get_start(p);
			if (last + grain <= start)
				free_sectors = 1;
			last = start + dos_partition_get_size(p);
		} else
			free_primary++;
	}
	if (last + grain < cxt->total_sectors - 1)
		free_sectors = 1;

	if (!free_primary && cxt->label->nparts_max >= MAXIMUM_PARTS) {
		fdisk_info(cxt, _("The maximum number of partitions has "
				  "been created."));
		return -EINVAL;
	}
	rc = 1;

	if (!free_primary || !free_sectors) {
		DBG(LABEL, ul_debug("DOS: primary impossible, add logical"));
		if (l->ext_offset) {
			if (!pa || fdisk_partition_has_start(pa)) {
				if (!free_primary)
					fdisk_info(cxt, _("All primary partitions are in use."));
				else if (!free_sectors)
					fdisk_info(cxt, _("All space for primary partitions is in use."));
			}
			rc = add_logical(cxt, pa, &res);
		} else {
			fdisk_info(cxt,
			     _(	"Impossible to create another primary partition. "
				"If you want to create more partitions, you must "
				"replace a primary partition with an extended "
				"partition first."));
			return -EINVAL;
		}
	} else if (cxt->label->nparts_max >= MAXIMUM_PARTS) {
		fdisk_info(cxt, _("All logical partitions are in use. "
				  "Adding a primary partition."));
		rc = get_partition_unused_primary(cxt, pa, &res);
		if (rc == 0)
			rc = add_partition(cxt, res, pa);
	} else {
		char hint[BUFSIZ];
		struct fdisk_ask *ask;
		int c;

		/* the default layout for scripts is to create primary partitions */
		if (cxt->script) {
			rc = get_partition_unused_primary(cxt, pa, &res);
			if (rc == 0)
				rc = add_partition(cxt, res, pa);
			goto done;
		}

		ask = fdisk_new_ask();
		if (!ask)
			return -ENOMEM;
		fdisk_ask_set_type(ask, FDISK_ASKTYPE_MENU);
		fdisk_ask_set_query(ask, _("Partition type"));
		fdisk_ask_menu_set_default(ask, free_primary == 1
						&& !l->ext_offset ? 'e' : 'p');
		snprintf(hint, sizeof(hint),
				_("%zu primary, %d extended, %zu free"),
				4 - (l->ext_offset ? 1 : 0) - free_primary,
				l->ext_offset ? 1 : 0,
				free_primary);

		fdisk_ask_menu_add_item(ask, 'p', _("primary"), hint);
		if (!l->ext_offset)
			fdisk_ask_menu_add_item(ask, 'e', _("extended"), _("container for logical partitions"));
		else
			fdisk_ask_menu_add_item(ask, 'l', _("logical"), _("numbered from 5"));

		rc = fdisk_do_ask(cxt, ask);
		if (rc)
			return rc;
		fdisk_ask_menu_get_result(ask, &c);
		fdisk_unref_ask(ask);

		if (c == 'p') {
			rc = get_partition_unused_primary(cxt, pa, &res);
			if (rc == 0)
				rc = add_partition(cxt, res, pa);
			goto done;
		} else if (c == 'l' && l->ext_offset) {
			rc = add_logical(cxt, pa, &res);
			goto done;
		} else if (c == 'e' && !l->ext_offset) {
			rc = get_partition_unused_primary(cxt, pa, &res);
			if (rc == 0) {
				struct fdisk_partition *xpa = NULL;
				struct fdisk_parttype *t;

				t = fdisk_label_get_parttype_from_code(cxt->label,
						MBR_DOS_EXTENDED_PARTITION);
				if (!pa) {
					pa = xpa = fdisk_new_partition();
					if (!xpa)
						return -ENOMEM;
				}
				fdisk_partition_set_type(pa, t);
				rc = add_partition(cxt, res, pa);
				if (xpa) {
					fdisk_unref_partition(xpa);
					pa = NULL;
				}
			}
			goto done;
		} else
			fdisk_warnx(cxt, _("Invalid partition type `%c'."), c);
	}
done:
	if (rc == 0) {
		cxt->label->nparts_cur++;
		if (partno)
			*partno = res;
	}
	return rc;
}

static int write_sector(struct fdisk_context *cxt, fdisk_sector_t secno,
			       unsigned char *buf)
{
	int rc;

	rc = seek_sector(cxt, secno);
	if (rc != 0) {
		fdisk_warn(cxt, _("Cannot write sector %jd: seek failed"),
				(uintmax_t) secno);
		return rc;
	}

	DBG(LABEL, ul_debug("DOS: writting to sector %ju", (uintmax_t) secno));

	if (write(cxt->dev_fd, buf, cxt->sector_size) != (ssize_t) cxt->sector_size)
		return -errno;
	return 0;
}

static int dos_write_disklabel(struct fdisk_context *cxt)
{
	struct fdisk_dos_label *l = self_label(cxt);
	size_t i;
	int rc = 0, mbr_changed = 0;

	assert(cxt);
	assert(cxt->label);
	assert(fdisk_is_label(cxt, DOS));

	mbr_changed = l->non_pt_changed;

	/* MBR (primary partitions) */
	if (!mbr_changed) {
		for (i = 0; i < 4; i++) {
			struct pte *pe = self_pte(cxt, i);
			if (pe->changed)
				mbr_changed = 1;
		}
	}
	if (mbr_changed) {
		mbr_set_magic(cxt->firstsector);
		rc = write_sector(cxt, 0, cxt->firstsector);
		if (rc)
			goto done;
	}

	if (cxt->label->nparts_max <= 4 && l->ext_offset) {
		/* we have empty extended partition, check if the partition has
		 * been modified and then cleanup possible remaining EBR  */
		struct pte *pe = self_pte(cxt, l->ext_index);
		unsigned char empty[512] = { 0 };
		fdisk_sector_t off = pe ? get_abs_partition_start(pe) : 0;

		if (off && pe->changed) {
			mbr_set_magic(empty);
			write_sector(cxt, off, empty);
		}
	}

	/* EBR (logical partitions) */
	for (i = 4; i < cxt->label->nparts_max; i++) {
		struct pte *pe = self_pte(cxt, i);

		if (!pe->changed || !pe->offset || !pe->sectorbuffer)
			continue;

		mbr_set_magic(pe->sectorbuffer);
		rc = write_sector(cxt, pe->offset, pe->sectorbuffer);
		if (rc)
			goto done;
	}

done:
	return rc;
}

static int dos_locate_disklabel(struct fdisk_context *cxt, int n,
		const char **name, off_t *offset, size_t *size)
{
	assert(cxt);

	*name = NULL;
	*offset = 0;
	*size = 0;

	switch (n) {
	case 0:
		*name = "MBR";
		*offset = 0;
		*size = 512;
		break;
	default:
		/* extended partitions */
		if (n - 1 + 4 < cxt->label->nparts_max) {
			struct pte *pe = self_pte(cxt, n - 1 + 4);

			assert(pe->private_sectorbuffer);

			*name = "EBR";
			*offset = pe->offset * cxt->sector_size;
			*size = 512;
		} else
			return 1;
		break;
	}

	return 0;
}

/*
 * Check whether partition entries are ordered by their starting positions.
 * Return 0 if OK. Return i if partition i should have been earlier.
 * Two separate checks: primary and logical partitions.
 */
static int wrong_p_order(struct fdisk_context *cxt, size_t *prev)
{
	size_t last_p_start_pos = 0, p_start_pos;
	size_t i, last_i = 0;

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

		struct pte *pe = self_pte(cxt, i);
		struct dos_partition *p = pe->pt_entry;

		if (i == 4) {
			last_i = 4;
			last_p_start_pos = 0;
		}
		if (is_used_partition(p)) {
			p_start_pos = get_abs_partition_start(pe);

			if (last_p_start_pos > p_start_pos) {
				if (prev)
					*prev = last_i;
				return i;
			}

			last_p_start_pos = p_start_pos;
			last_i = i;
		}
	}
	return 0;
}

static int dos_list_disklabel(struct fdisk_context *cxt)
{
	assert(cxt);
	assert(cxt->label);
	assert(fdisk_is_label(cxt, DOS));

	return 0;
}

static int dos_get_partition(struct fdisk_context *cxt, size_t n,
			     struct fdisk_partition *pa)
{
	struct dos_partition *p;
	struct pte *pe;
	struct fdisk_dos_label *lb;

	assert(cxt);
	assert(pa);
	assert(cxt->label);
	assert(fdisk_is_label(cxt, DOS));

	lb = self_label(cxt);
	pe = self_pte(cxt, n);
	p = pe->pt_entry;
	pa->used = !is_cleared_partition(p);
	if (!pa->used)
		return 0;

	pa->type = dos_partition_parttype(cxt, p);
	pa->boot = p->boot_ind == ACTIVE_FLAG ? 1 : 0;
	pa->start = get_abs_partition_start(pe);
	pa->size = dos_partition_get_size(p);
	pa->container = lb->ext_offset && n == lb->ext_index;

	if (n >= 4)
		pa->parent_partno = lb->ext_index;

	if (p->boot_ind && asprintf(&pa->attrs, "%02x", p->boot_ind) < 0)
		return -ENOMEM;

	/* start C/H/S */
	if (asprintf(&pa->start_chs, "%d/%d/%d",
				cylinder(p->bs, p->bc),
				sector(p->bs),
				p->bh) < 0)
		return -ENOMEM;

	/* end C/H/S */
	if (asprintf(&pa->end_chs, "%d/%d/%d",
				cylinder(p->es, p->ec),
				sector(p->es),
				p->eh) < 0)
		return -ENOMEM;

	return 0;
}

static int dos_set_partition(struct fdisk_context *cxt, size_t n,
			     struct fdisk_partition *pa)
{
	struct fdisk_dos_label *l;
	struct dos_partition *p;
	struct pte *pe;
	fdisk_sector_t start, size;

	assert(cxt);
	assert(pa);
	assert(cxt->label);
	assert(fdisk_is_label(cxt, DOS));

	if (n >= cxt->label->nparts_max)
		return -EINVAL;

	if (pa->type && IS_EXTENDED(pa->type->code)) {
		fdisk_warnx(cxt, _("You cannot change a partition into an "
			"extended one or vice versa. Delete it first."));
		return -EINVAL;
	}

	if (pa->type && !pa->type->code)
		fdisk_warnx(cxt, _("Type 0 means free space to many systems. "
				   "Having partitions of type 0 is probably unwise."));
	l = self_label(cxt);
	p = self_partition(cxt, n);
	pe = self_pte(cxt, n);

	FDISK_INIT_UNDEF(start);
	FDISK_INIT_UNDEF(size);

	if (fdisk_partition_has_start(pa))
		start = pa->start;
	if (fdisk_partition_has_size(pa))
		size = pa->size;

	if (pa->end_follow_default) {
		fdisk_sector_t first[cxt->label->nparts_max],
			 last[cxt->label->nparts_max],
			 xlast;
		struct pte *ext = l->ext_offset ? self_pte(cxt, l->ext_index) : NULL; 

		fill_bounds(cxt, first, last);

		if (ext && l->ext_offset) {
			first[l->ext_index] = l->ext_offset;
			last[l->ext_index] = get_abs_partition_end(ext);
		}
		if (FDISK_IS_UNDEF(start))
			start = get_abs_partition_start(pe);

		DBG(LABEL, ul_debug("DOS: #%zu    now %ju +%ju sectors",
			n, (uintmax_t) start, (uintmax_t) dos_partition_get_size(p)));

		xlast = get_unused_last(cxt, n, start, first, last);
		size = xlast ? xlast - start + 1: dos_partition_get_size(p);

		DBG(LABEL, ul_debug("DOS: #%zu wanted %ju +%ju sectors",
			n, (uintmax_t) start, (uintmax_t) size));
	}

	if (!FDISK_IS_UNDEF(start) || !FDISK_IS_UNDEF(size)) {
		DBG(LABEL, ul_debug("DOS: resize partition"));

		if (FDISK_IS_UNDEF(start))
			start = get_abs_partition_start(pe);
		if (FDISK_IS_UNDEF(size))
			size = dos_partition_get_size(p);

		set_partition(cxt, n, 0, start, start + size - 1,
				pa->type  ? pa->type->code : p->sys_ind,
				pa->boot == 1);
	} else {
		DBG(LABEL, ul_debug("DOS: keep size, modify properties"));
		if (pa->type)
			p->sys_ind = pa->type->code;
		if (!FDISK_IS_UNDEF(pa->boot))
			p->boot_ind = pa->boot == 1 ? ACTIVE_FLAG : 0;
	}

	partition_set_changed(cxt, n, 1);
	return 0;
}

static void print_chain_of_logicals(struct fdisk_context *cxt)
{
	size_t i;
	struct fdisk_dos_label *l = self_label(cxt);

	fputc('\n', stdout);

	for (i = 4; i < cxt->label->nparts_max; i++) {
		struct pte *pe = self_pte(cxt, i);

		fprintf(stderr, "#%02zu EBR [%10ju], "
			"data[start=%10ju (%10ju), size=%10ju], "
			"link[start=%10ju (%10ju), size=%10ju]\n",
			i, (uintmax_t) pe->offset,
			/* data */
			(uintmax_t) dos_partition_get_start(pe->pt_entry),
			(uintmax_t) get_abs_partition_start(pe),
			(uintmax_t) dos_partition_get_size(pe->pt_entry),
			/* link */
			(uintmax_t) dos_partition_get_start(pe->ex_entry),
			(uintmax_t) l->ext_offset + dos_partition_get_start(pe->ex_entry),
			(uintmax_t) dos_partition_get_size(pe->ex_entry));
	}
}

static int cmp_ebr_offsets(const void *a, const void *b)
{
	struct pte *ae = (struct pte *) a,
		   *be = (struct pte *) b;

	if (ae->offset == 0 && be->offset == 0)
		return 0;
	if (ae->offset == 0)
		return 1;
	if (be->offset == 0)
		return -1;

	return cmp_numbers(ae->offset, be->offset);
}

/*
 * Fix the chain of logicals.
 *
 * The function does not modify data partitions within EBR tables
 * (pte->pt_entry). It sorts the chain by EBR offsets and then update links
 * (pte->ex_entry) between EBR tables.
 *
 */
static void fix_chain_of_logicals(struct fdisk_context *cxt)
{
	struct fdisk_dos_label *l = self_label(cxt);
	struct pte *last;
	size_t i;

	DBG(LABEL, print_chain_of_logicals(cxt));

	/* Sort chain by EBR offsets */
	qsort(&l->ptes[4], cxt->label->nparts_max - 4, sizeof(struct pte),
			cmp_ebr_offsets);

again:
	/* Sort data partitions by start */
	for (i = 4; i < cxt->label->nparts_max - 1; i++) {
		struct pte *cur = self_pte(cxt, i),
			   *nxt = self_pte(cxt, i + 1);

		if (get_abs_partition_start(cur) >
		    get_abs_partition_start(nxt)) {

			struct dos_partition tmp = *cur->pt_entry;
			fdisk_sector_t cur_start = get_abs_partition_start(cur),
				 nxt_start = get_abs_partition_start(nxt);

			/* swap data partitions */
			*cur->pt_entry = *nxt->pt_entry;
			*nxt->pt_entry = tmp;

			/* Recount starts according to EBR offsets, the absolute
			 * address tas to be still the same! */
			dos_partition_set_start(cur->pt_entry, nxt_start - cur->offset);
			dos_partition_set_start(nxt->pt_entry, cur_start - nxt->offset);

			partition_set_changed(cxt, i, 1);
			partition_set_changed(cxt, i + 1, 1);
			goto again;
		}
	}

	/* Update EBR links */
	for (i = 4; i < cxt->label->nparts_max - 1; i++) {
		struct pte *cur = self_pte(cxt, i),
			   *nxt = self_pte(cxt, i + 1);

		fdisk_sector_t noff = nxt->offset - l->ext_offset,
			 ooff = dos_partition_get_start(cur->ex_entry);

		if (noff == ooff)
			continue;

		DBG(LABEL, ul_debug("DOS: fix EBR [%10ju] link %ju -> %ju",
			(uintmax_t) cur->offset,
			(uintmax_t) ooff, (uintmax_t) noff));

		set_partition(cxt, i, 1, nxt->offset,
				get_abs_partition_end(nxt),
				MBR_DOS_EXTENDED_PARTITION, 0);
	}

	/* always terminate the chain ! */
	last = self_pte(cxt, cxt->label->nparts_max - 1);
	if (last) {
		clear_partition(last->ex_entry);
		partition_set_changed(cxt, cxt->label->nparts_max - 1, 1);
	}

	DBG(LABEL, print_chain_of_logicals(cxt));
}

static int dos_reorder(struct fdisk_context *cxt)
{
	struct pte *pei, *pek;
	size_t i,k;

	if (!wrong_p_order(cxt, NULL)) {
		fdisk_info(cxt, _("Nothing to do. Ordering is correct already."));
		return 0;
	}

	while ((i = wrong_p_order(cxt, &k)) != 0 && i < 4) {
		/* partition i should have come earlier, move it */
		/* We have to move data in the MBR */
		struct dos_partition *pi, *pk, *pe, pbuf;
		pei = self_pte(cxt, i);
		pek = self_pte(cxt, k);

		pe = pei->ex_entry;
		pei->ex_entry = pek->ex_entry;
		pek->ex_entry = pe;

		pi = pei->pt_entry;
		pk = pek->pt_entry;

		memmove(&pbuf, pi, sizeof(struct dos_partition));
		memmove(pi, pk, sizeof(struct dos_partition));
		memmove(pk, &pbuf, sizeof(struct dos_partition));

		partition_set_changed(cxt, i, 1);
		partition_set_changed(cxt, k, 1);
	}

	if (i)
		fix_chain_of_logicals(cxt);

	fdisk_info(cxt, _("Done."));
	return 0;
}

/* TODO: use fdisk_set_partition() API */
int fdisk_dos_move_begin(struct fdisk_context *cxt, size_t i)
{
	struct pte *pe;
	struct dos_partition *p;
	unsigned int new, free_start, curr_start, last;
	uintmax_t res = 0;
	size_t x;
	int rc;

	assert(cxt);
	assert(fdisk_is_label(cxt, DOS));

	pe = self_pte(cxt, i);
	p = pe->pt_entry;

	if (!is_used_partition(p) || IS_EXTENDED (p->sys_ind)) {
		fdisk_warnx(cxt, _("Partition %zu: no data area."), i + 1);
		return 0;
	}

	/* the default start is at the second sector of the disk or at the
	 * second sector of the extended partition
	 */
	free_start = pe->offset ? pe->offset + 1 : 1;

	curr_start = get_abs_partition_start(pe);

	/* look for a free space before the current start of the partition */
	for (x = 0; x < cxt->label->nparts_max; x++) {
		unsigned int end;
		struct pte *prev_pe = self_pte(cxt, x);
		struct dos_partition *prev_p = prev_pe->pt_entry;

		if (!prev_p)
			continue;
		end = get_abs_partition_start(prev_pe)
		      + dos_partition_get_size(prev_p);

		if (is_used_partition(prev_p) &&
		    end > free_start && end <= curr_start)
			free_start = end;
	}

	last = get_abs_partition_end(pe);

	rc = fdisk_ask_number(cxt, free_start, curr_start, last,
			_("New beginning of data"), &res);
	if (rc)
		return rc;

	new = res - pe->offset;

	if (new != dos_partition_get_size(p)) {
		unsigned int sects = dos_partition_get_size(p)
				+ dos_partition_get_start(p) - new;

		dos_partition_set_size(p, sects);
		dos_partition_set_start(p, new);

		partition_set_changed(cxt, i, 1);
	}

	return rc;
}

static int dos_partition_is_used(
		struct fdisk_context *cxt,
		size_t i)
{
	struct dos_partition *p;

	assert(cxt);
	assert(cxt->label);
	assert(fdisk_is_label(cxt, DOS));

	if (i >= cxt->label->nparts_max)
		return 0;

	p = self_partition(cxt, i);

	return p && !is_cleared_partition(p);
}

static int dos_toggle_partition_flag(
		struct fdisk_context *cxt,
		size_t i,
		unsigned long flag)
{
	struct dos_partition *p;

	assert(cxt);
	assert(cxt->label);
	assert(fdisk_is_label(cxt, DOS));

	if (i >= cxt->label->nparts_max)
		return -EINVAL;

	p = self_partition(cxt, i);

	switch (flag) {
	case DOS_FLAG_ACTIVE:
		if (IS_EXTENDED(p->sys_ind) && !p->boot_ind)
			fdisk_warnx(cxt, _("Partition %zu: is an extended "
					"partition."), i + 1);

		p->boot_ind = (p->boot_ind ? 0 : ACTIVE_FLAG);
		partition_set_changed(cxt, i, 1);
		fdisk_info(cxt,	p->boot_ind ?
			_("The bootable flag on partition %zu is enabled now.") :
			_("The bootable flag on partition %zu is disabled now."),
			i + 1);
		break;
	default:
		return 1;
	}

	return 0;
}

static const struct fdisk_field dos_fields[] =
{
	/* basic */
	{ FDISK_FIELD_DEVICE,	N_("Device"),	 10,	0 },
	{ FDISK_FIELD_BOOT,	N_("Boot"),	  1,	0 },
	{ FDISK_FIELD_START,	N_("Start"),	  5,	FDISK_FIELDFL_NUMBER },
	{ FDISK_FIELD_END,	N_("End"),	  5,	FDISK_FIELDFL_NUMBER },
	{ FDISK_FIELD_SECTORS,	N_("Sectors"),	  5,	FDISK_FIELDFL_NUMBER },
	{ FDISK_FIELD_CYLINDERS,N_("Cylinders"),  5,	FDISK_FIELDFL_NUMBER },
	{ FDISK_FIELD_SIZE,	N_("Size"),	  5,	FDISK_FIELDFL_NUMBER | FDISK_FIELDFL_EYECANDY },
	{ FDISK_FIELD_TYPEID,	N_("Id"),	  2,	FDISK_FIELDFL_NUMBER },
	{ FDISK_FIELD_TYPE,	N_("Type"),	0.1,	0 },

	/* expert mode */
	{ FDISK_FIELD_SADDR,	N_("Start-C/H/S"), 1,   FDISK_FIELDFL_NUMBER | FDISK_FIELDFL_DETAIL },
	{ FDISK_FIELD_EADDR,	N_("End-C/H/S"),   1,   FDISK_FIELDFL_NUMBER | FDISK_FIELDFL_DETAIL },
	{ FDISK_FIELD_ATTR,	N_("Attrs"),	   2,   FDISK_FIELDFL_NUMBER | FDISK_FIELDFL_DETAIL }

};

static const struct fdisk_label_operations dos_operations =
{
	.probe		= dos_probe_label,
	.write		= dos_write_disklabel,
	.verify		= dos_verify_disklabel,
	.create		= dos_create_disklabel,
	.locate		= dos_locate_disklabel,
	.list		= dos_list_disklabel,
	.reorder	= dos_reorder,
	.get_id		= dos_get_disklabel_id,
	.set_id		= dos_set_disklabel_id,

	.get_part	= dos_get_partition,
	.set_part	= dos_set_partition,
	.add_part	= dos_add_partition,
	.del_part	= dos_delete_partition,

	.part_toggle_flag = dos_toggle_partition_flag,
	.part_is_used	= dos_partition_is_used,

	.reset_alignment = dos_reset_alignment,

	.deinit		= dos_deinit,
};

/*
 * allocates DOS in-memory stuff
 */
struct fdisk_label *fdisk_new_dos_label(struct fdisk_context *cxt)
{
	struct fdisk_label *lb;
	struct fdisk_dos_label *dos;

	assert(cxt);

	dos = calloc(1, sizeof(*dos));
	if (!dos)
		return NULL;

	/* initialize generic part of the driver */
	lb = (struct fdisk_label *) dos;
	lb->name = "dos";
	lb->id = FDISK_DISKLABEL_DOS;
	lb->op = &dos_operations;
	lb->parttypes = dos_parttypes;
	lb->nparttypes = ARRAY_SIZE(dos_parttypes) - 1;
	lb->fields = dos_fields;
	lb->nfields = ARRAY_SIZE(dos_fields);

	return lb;
}

/**
 * fdisk_dos_enable_compatible:
 * @lb: DOS label (see fdisk_get_label())
 * @enable: 0 or 1
 *
 * Enables deprecated DOS compatible mode, in this mode library checks for
 * cylinders boundary, cases about CHS addressing and another obscure things.
 *
 * Returns: 0 on success, <0 on error.
 */
int fdisk_dos_enable_compatible(struct fdisk_label *lb, int enable)
{
	struct fdisk_dos_label *dos = (struct fdisk_dos_label *) lb;

	if (!lb)
		return -EINVAL;

	dos->compatible = enable;
	if (enable)
		lb->flags |= FDISK_LABEL_FL_REQUIRE_GEOMETRY;
	return 0;
}

/**
 * fdisk_dos_is_compatible:
 * @lb: DOS label
 *
 * Returns: 0 if DOS compatibility disabled, 1 if enabled
 */
int fdisk_dos_is_compatible(struct fdisk_label *lb)
{
	return ((struct fdisk_dos_label *) lb)->compatible;
}
