diff --git a/libblkid/libfdisk/src/dos.c b/libblkid/libfdisk/src/dos.c
new file mode 100644
index 0000000..2a06707
--- /dev/null
+++ b/libblkid/libfdisk/src/dos.c
@@ -0,0 +1,2331 @@
+/*
+ *
+ * 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;
+}
