/*
 * Copyright (C) 2013 Karel Zak <kzak@redhat.com>
 *
 * Based on original code from fdisk:
 *   Jakub Jelinek (jj@sunsite.mff.cuni.cz), July 1996
 *   Merged with fdisk for other architectures, aeb, June 1998.
 *   Arnaldo Carvalho de Melo <acme@conectiva.com.br> Mar 1999, Internationalization
 */
#include <stdio.h>		/* stderr */
#include <stdlib.h>		/* qsort */
#include <string.h>		/* strstr */
#include <unistd.h>		/* write */
#include <sys/ioctl.h>		/* ioctl */

#include "nls.h"
#include "blkdev.h"
#include "bitops.h"

#include "fdiskP.h"
#include "pt-sun.h"
#include "all-io.h"


/**
 * SECTION: sun
 * @title: SUN
 * @short_description: disk label specific functions
 *
 */

/*
 * in-memory fdisk SUN stuff
 */
struct fdisk_sun_label {
	struct fdisk_label	head;		/* generic part */
	struct sun_disklabel   *header;		/* on-disk data (pointer to cxt->firstsector) */
};

static struct fdisk_parttype sun_parttypes[] = {
	{SUN_TAG_UNASSIGNED, N_("Unassigned")},
	{SUN_TAG_BOOT, N_("Boot")},
	{SUN_TAG_ROOT, N_("SunOS root")},
	{SUN_TAG_SWAP, N_("SunOS swap")},
	{SUN_TAG_USR, N_("SunOS usr")},
	{SUN_TAG_WHOLEDISK, N_("Whole disk")},
	{SUN_TAG_STAND, N_("SunOS stand")},
	{SUN_TAG_VAR, N_("SunOS var")},
	{SUN_TAG_HOME, N_("SunOS home")},
	{SUN_TAG_ALTSCTR, N_("SunOS alt sectors")},
	{SUN_TAG_CACHE, N_("SunOS cachefs")},
	{SUN_TAG_RESERVED, N_("SunOS reserved")},
	{SUN_TAG_LINUX_SWAP, N_("Linux swap")},
	{SUN_TAG_LINUX_NATIVE, N_("Linux native")},
	{SUN_TAG_LINUX_LVM, N_("Linux LVM")},
	{SUN_TAG_LINUX_RAID, N_("Linux raid autodetect")},
	{ 0, NULL }
};

/* return poiter buffer with on-disk data */
static inline struct sun_disklabel *self_disklabel(struct fdisk_context *cxt)
{
	assert(cxt);
	assert(cxt->label);
	assert(fdisk_is_label(cxt, SUN));

	return ((struct fdisk_sun_label *) cxt->label)->header;
}

/* return in-memory sun fdisk data */
static inline struct fdisk_sun_label *self_label(struct fdisk_context *cxt)
{
	assert(cxt);
	assert(cxt->label);
	assert(fdisk_is_label(cxt, SUN));

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

static void set_partition(struct fdisk_context *cxt, size_t i,
		uint32_t start,uint32_t stop, uint16_t sysid)
{
	struct sun_disklabel *sunlabel = self_disklabel(cxt);
	struct fdisk_parttype *t =
			fdisk_label_get_parttype_from_code(cxt->label, sysid);

	sunlabel->vtoc.infos[i].id = cpu_to_be16(sysid);
	sunlabel->vtoc.infos[i].flags = cpu_to_be16(0);
	sunlabel->partitions[i].start_cylinder =
		cpu_to_be32(start / (cxt->geom.heads * cxt->geom.sectors));
	sunlabel->partitions[i].num_sectors = cpu_to_be32(stop - start);
	fdisk_label_set_changed(cxt->label, 1);

	fdisk_info_new_partition(cxt, i + 1, start, stop, t);
}

static size_t count_used_partitions(struct fdisk_context *cxt)
{
	struct sun_disklabel *sunlabel = self_disklabel(cxt);
	size_t ct = 0, i;

	assert(sunlabel);

	for (i = 0; i < cxt->label->nparts_max; i++) {
		if (sunlabel->partitions[i].num_sectors)
			ct++;
	}
	return ct;
}

static int sun_probe_label(struct fdisk_context *cxt)
{
	struct fdisk_sun_label *sun;
	struct sun_disklabel *sunlabel;
	unsigned short *ush;
	int csum;
	int need_fixing = 0;

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

	/* map first sector to header */
	sun = (struct fdisk_sun_label *) cxt->label;
	sun->header = (struct sun_disklabel *) cxt->firstsector;
	sunlabel = sun->header;

	if (be16_to_cpu(sunlabel->magic) != SUN_LABEL_MAGIC) {
		sun->header = NULL;
		return 0;		/* failed */
	}

	ush = ((unsigned short *) (sunlabel + 1)) - 1;
	for (csum = 0; ush >= (unsigned short *)sunlabel;)
		csum ^= *ush--;

	if (csum) {
		fdisk_warnx(cxt, _("Detected sun disklabel with wrong checksum. "
			      "Probably you'll have to set all the values, "
			      "e.g. heads, sectors, cylinders and partitions "
			      "or force a fresh label (s command in main menu)"));
		return 1;
	}

	cxt->label->nparts_max = SUN_MAXPARTITIONS;
	cxt->geom.heads = be16_to_cpu(sunlabel->nhead);
	cxt->geom.cylinders = be16_to_cpu(sunlabel->ncyl);
	cxt->geom.sectors = be16_to_cpu(sunlabel->nsect);

	if (be32_to_cpu(sunlabel->vtoc.version) != SUN_VTOC_VERSION) {
		fdisk_warnx(cxt, _("Detected sun disklabel with wrong version [%d]."),
			be32_to_cpu(sunlabel->vtoc.version));
		need_fixing = 1;
	}
	if (be32_to_cpu(sunlabel->vtoc.sanity) != SUN_VTOC_SANITY) {
		fdisk_warnx(cxt, _("Detected sun disklabel with wrong vtoc.sanity [0x%08x]."),
			be32_to_cpu(sunlabel->vtoc.sanity));
		need_fixing = 1;
	}
	if (be16_to_cpu(sunlabel->vtoc.nparts) != SUN_MAXPARTITIONS) {
		fdisk_warnx(cxt, _("Detected sun disklabel with wrong vtoc.nparts [%u]."),
			be16_to_cpu(sunlabel->vtoc.nparts));
		need_fixing = 1;
	}
	if (need_fixing) {
		fdisk_warnx(cxt, _("Warning: Wrong values need to be fixed up and "
			           "will be corrected by w(rite)"));

		sunlabel->vtoc.version = cpu_to_be32(SUN_VTOC_VERSION);
		sunlabel->vtoc.sanity = cpu_to_be32(SUN_VTOC_SANITY);
		sunlabel->vtoc.nparts = cpu_to_be16(SUN_MAXPARTITIONS);

		ush = (unsigned short *)sunlabel;
		csum = 0;
		while(ush < (unsigned short *)(&sunlabel->csum))
			csum ^= *ush++;
		sunlabel->csum = csum;

		fdisk_label_set_changed(cxt->label, 1);
	}

	cxt->label->nparts_cur = count_used_partitions(cxt);

	return 1;
}

static void ask_geom(struct fdisk_context *cxt)
{
	uintmax_t res;

	assert(cxt);

	if (fdisk_ask_number(cxt, 1, 1, 1024, _("Heads"), &res) == 0)
		cxt->geom.heads = res;
	if (fdisk_ask_number(cxt, 1, 1, 1024, _("Sectors/track"), &res) == 0)
		cxt->geom.sectors = res;
	if (fdisk_ask_number(cxt, 1, 1, USHRT_MAX, _("Cylinders"), &res) == 0)
		cxt->geom.cylinders = res;
}

static int sun_create_disklabel(struct fdisk_context *cxt)
{
	unsigned int ndiv;
	struct fdisk_sun_label *sun;		/* libfdisk sun handler */
	struct sun_disklabel *sunlabel;	/* on disk data */
	int rc = 0;

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

	/* map first sector to header */
	rc = fdisk_init_firstsector_buffer(cxt);
	if (rc)
		return rc;

	sun = (struct fdisk_sun_label *) cxt->label;
	sun->header = (struct sun_disklabel *) cxt->firstsector;

	sunlabel = sun->header;

	cxt->label->nparts_max = SUN_MAXPARTITIONS;

	sunlabel->magic = cpu_to_be16(SUN_LABEL_MAGIC);
	sunlabel->vtoc.version = cpu_to_be32(SUN_VTOC_VERSION);
	sunlabel->vtoc.sanity = cpu_to_be32(SUN_VTOC_SANITY);
	sunlabel->vtoc.nparts = cpu_to_be16(SUN_MAXPARTITIONS);

#ifdef HDIO_GETGEO
	if (cxt->geom.heads && cxt->geom.sectors) {
		fdisk_sector_t llsectors;

		if (blkdev_get_sectors(cxt->dev_fd, (unsigned long long *) &llsectors) == 0) {
			int sec_fac = cxt->sector_size / 512;
			fdisk_sector_t llcyls;

			llcyls = llsectors / (cxt->geom.heads * cxt->geom.sectors * sec_fac);
			cxt->geom.cylinders = llcyls;
			if (cxt->geom.cylinders != llcyls)
				cxt->geom.cylinders = ~0;
		} else {
			fdisk_warnx(cxt,
				_("BLKGETSIZE ioctl failed on %s. "
				  "Using geometry cylinder value of %llu. "
				  "This value may be truncated for devices "
				  "> 33.8 GB."),
				cxt->dev_path, cxt->geom.cylinders);
		}
	} else
#endif
		ask_geom(cxt);

	sunlabel->acyl   = cpu_to_be16(0);
	sunlabel->pcyl   = cpu_to_be16(cxt->geom.cylinders);
	sunlabel->rpm    = cpu_to_be16(5400);
	sunlabel->intrlv = cpu_to_be16(1);
	sunlabel->apc    = cpu_to_be16(0);

	sunlabel->nhead  = cpu_to_be16(cxt->geom.heads);
	sunlabel->nsect  = cpu_to_be16(cxt->geom.sectors);
	sunlabel->ncyl   = cpu_to_be16(cxt->geom.cylinders);

	snprintf((char *) sunlabel->label_id, sizeof(sunlabel->label_id),
		 "Linux cyl %ju alt %u hd %u sec %ju",
		 (uintmax_t) cxt->geom.cylinders,
		 be16_to_cpu(sunlabel->acyl),
		 cxt->geom.heads,
		 (uintmax_t) cxt->geom.sectors);

	if (cxt->geom.cylinders * cxt->geom.heads * cxt->geom.sectors >= 150 * 2048) {
	        ndiv = cxt->geom.cylinders - (50 * 2048 / (cxt->geom.heads * cxt->geom.sectors)); /* 50M swap */
	} else
	        ndiv = cxt->geom.cylinders * 2 / 3;

	/* create the default layout only if no-script defined */
	if (!cxt->script) {
		set_partition(cxt, 0, 0, ndiv * cxt->geom.heads * cxt->geom.sectors,
			  SUN_TAG_LINUX_NATIVE);
		set_partition(cxt, 1, ndiv * cxt->geom.heads * cxt->geom.sectors,
			  cxt->geom.cylinders * cxt->geom.heads * cxt->geom.sectors,
			  SUN_TAG_LINUX_SWAP);
		sunlabel->vtoc.infos[1].flags |= cpu_to_be16(SUN_FLAG_UNMNT);

		set_partition(cxt, 2, 0,
			  cxt->geom.cylinders * cxt->geom.heads * cxt->geom.sectors,
			  SUN_TAG_WHOLEDISK);
	}

	{
		unsigned short *ush = (unsigned short *)sunlabel;
		unsigned short csum = 0;
		while(ush < (unsigned short *)(&sunlabel->csum))
			csum ^= *ush++;
		sunlabel->csum = csum;
	}

	fdisk_label_set_changed(cxt->label, 1);
	cxt->label->nparts_cur = count_used_partitions(cxt);

	fdisk_info(cxt, _("Created a new Sun disklabel."));
	return 0;
}

static int sun_toggle_partition_flag(struct fdisk_context *cxt, size_t i, unsigned long flag)
{
	struct sun_disklabel *sunlabel;
	struct sun_info *p;

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

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

	sunlabel = self_disklabel(cxt);
	p = &sunlabel->vtoc.infos[i];

	switch (flag) {
	case SUN_FLAG_UNMNT:
		p->flags ^= cpu_to_be16(SUN_FLAG_UNMNT);
		fdisk_label_set_changed(cxt->label, 1);
		break;
	case SUN_FLAG_RONLY:
		p->flags ^= cpu_to_be16(SUN_FLAG_RONLY);
		fdisk_label_set_changed(cxt->label, 1);
		break;
	default:
		return 1;
	}

	return 0;
}

static void fetch_sun(struct fdisk_context *cxt,
		      uint32_t *starts,
		      uint32_t *lens,
		      uint32_t *start,
		      uint32_t *stop)
{
	struct sun_disklabel *sunlabel;
	int continuous = 1;
	size_t i;

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

	sunlabel = self_disklabel(cxt);

	*start = 0;
	*stop = cxt->geom.cylinders * cxt->geom.heads * cxt->geom.sectors;

	for (i = 0; i < cxt->label->nparts_max; i++) {
		struct sun_partition *part = &sunlabel->partitions[i];
		struct sun_info *info = &sunlabel->vtoc.infos[i];

		if (part->num_sectors &&
		    be16_to_cpu(info->id) != SUN_TAG_UNASSIGNED &&
		    be16_to_cpu(info->id) != SUN_TAG_WHOLEDISK) {
			starts[i] = be32_to_cpu(part->start_cylinder) *
				     cxt->geom.heads * cxt->geom.sectors;
			lens[i] = be32_to_cpu(part->num_sectors);
			if (continuous) {
				if (starts[i] == *start)
					*start += lens[i];
				else if (starts[i] + lens[i] >= *stop)
					*stop = starts[i];
				else
					continuous = 0;
				        /* There will be probably more gaps
					  than one, so lets check afterwards */
			}
		} else {
			starts[i] = 0;
			lens[i] = 0;
		}
	}
}

#ifdef HAVE_QSORT_R
static int verify_sun_cmp(int *a, int *b, void *data)
{
    unsigned int *verify_sun_starts = (unsigned int *) data;

    if (*a == -1)
	    return 1;
    if (*b == -1)
	    return -1;
    if (verify_sun_starts[*a] > verify_sun_starts[*b])
	    return 1;
    return -1;
}
#endif

static int sun_verify_disklabel(struct fdisk_context *cxt)
{
    uint32_t starts[SUN_MAXPARTITIONS], lens[SUN_MAXPARTITIONS], start, stop;
    uint32_t i,j,k,starto,endo;
#ifdef HAVE_QSORT_R
    int array[SUN_MAXPARTITIONS];
    unsigned int *verify_sun_starts;
#endif
    assert(cxt);
    assert(cxt->label);
    assert(fdisk_is_label(cxt, SUN));

    fetch_sun(cxt, starts, lens, &start, &stop);

    for (k = 0; k < 7; k++) {
	for (i = 0; i < SUN_MAXPARTITIONS; i++) {
	    if (k && (lens[i] % (cxt->geom.heads * cxt->geom.sectors)))
	        fdisk_warnx(cxt, _("Partition %u doesn't end on cylinder boundary."), i+1);
	    if (lens[i]) {
	        for (j = 0; j < i; j++)
	            if (lens[j]) {
	                if (starts[j] == starts[i]+lens[i]) {
	                    starts[j] = starts[i]; lens[j] += lens[i];
	                    lens[i] = 0;
	                } else if (starts[i] == starts[j]+lens[j]){
	                    lens[j] += lens[i];
	                    lens[i] = 0;
	                } else if (!k) {
	                    if (starts[i] < starts[j]+lens[j] &&
				starts[j] < starts[i]+lens[i]) {
	                        starto = starts[i];
	                        if (starts[j] > starto)
					starto = starts[j];
	                        endo = starts[i]+lens[i];
	                        if (starts[j]+lens[j] < endo)
					endo = starts[j]+lens[j];
	                        fdisk_warnx(cxt, _("Partition %u overlaps with others in "
				       "sectors %u-%u."), i+1, starto, endo);
	                    }
	                }
	            }
	    }
	}
    }

#ifdef HAVE_QSORT_R
    for (i = 0; i < SUN_MAXPARTITIONS; i++) {
        if (lens[i])
            array[i] = i;
        else
            array[i] = -1;
    }
    verify_sun_starts = starts;

    qsort_r(array,ARRAY_SIZE(array),sizeof(array[0]),
	  (int (*)(const void *,const void *,void *)) verify_sun_cmp,
	  verify_sun_starts);

    if (array[0] == -1) {
	fdisk_info(cxt, _("No partitions defined."));
	return 0;
    }
    stop = cxt->geom.cylinders * cxt->geom.heads * cxt->geom.sectors;
    if (starts[array[0]])
        fdisk_warnx(cxt, _("Unused gap - sectors 0-%u."), starts[array[0]]);
    for (i = 0; i < 7 && array[i+1] != -1; i++) {
        fdisk_warnx(cxt, _("Unused gap - sectors %u-%u."),
	       (starts[array[i]] + lens[array[i]]),
	       starts[array[i+1]]);
    }
    start = (starts[array[i]] + lens[array[i]]);
    if (start < stop)
        fdisk_warnx(cxt, _("Unused gap - sectors %u-%u."), start, stop);
#endif
    return 0;
}


static int is_free_sector(struct fdisk_context *cxt,
		fdisk_sector_t s, uint32_t starts[], uint32_t lens[])
{
	size_t i;

	for (i = 0; i < cxt->label->nparts_max; i++) {
		if (lens[i] && starts[i] <= s
		    && starts[i] + lens[i] > s)
			return 0;
	}
	return 1;
}

static int sun_add_partition(
		struct fdisk_context *cxt,
		struct fdisk_partition *pa,
		size_t *partno)
{
	struct sun_disklabel *sunlabel = self_disklabel(cxt);
	uint32_t starts[SUN_MAXPARTITIONS], lens[SUN_MAXPARTITIONS];
	struct sun_partition *part;
	struct sun_info *info;
	uint32_t start, stop, stop2;
	int whole_disk = 0;
	int sys = pa && pa->type ? pa->type->code : SUN_TAG_LINUX_NATIVE;
	int rc;
	size_t n;

	char mesg[256];
	size_t i;
	unsigned int first, last;

	rc = fdisk_partition_next_partno(pa, cxt, &n);
	if (rc)
		return rc;

	part = &sunlabel->partitions[n];
	info = &sunlabel->vtoc.infos[n];

	if (part->num_sectors && be16_to_cpu(info->id) != SUN_TAG_UNASSIGNED) {
		fdisk_info(cxt, _("Partition %zu is already defined.  Delete "
			"it before re-adding it."), n + 1);
		return -EINVAL;
	}

	fetch_sun(cxt, starts, lens, &start, &stop);

	if (stop <= start) {
		if (n == 2)
			whole_disk = 1;
		else {
			fdisk_info(cxt, _("Other partitions already cover the "
				"whole disk. Delete some/shrink them before retry."));
			return -EINVAL;
		}
	}

	if (pa && pa->start_follow_default)
		first = start;
	else if (pa && fdisk_partition_has_start(pa)) {
		first = pa->start;

		if (!whole_disk && !is_free_sector(cxt, first, starts, lens))
			return -ERANGE;
	} else {
		struct fdisk_ask *ask;

		snprintf(mesg, sizeof(mesg), _("First %s"),
				fdisk_get_unit(cxt, FDISK_SINGULAR));
		for (;;) {
			ask = fdisk_new_ask();
			if (!ask)
				return -ENOMEM;

			fdisk_ask_set_query(ask, mesg);
			fdisk_ask_set_type(ask, FDISK_ASKTYPE_NUMBER);

			if (whole_disk) {
				fdisk_ask_number_set_low(ask,     0);	/* minimal */
				fdisk_ask_number_set_default(ask, 0);	/* default */
				fdisk_ask_number_set_high(ask,    0);	/* maximal */
			} else {
				fdisk_ask_number_set_low(ask,     fdisk_scround(cxt, start));	/* minimal */
				fdisk_ask_number_set_default(ask, fdisk_scround(cxt, start));	/* default */
				fdisk_ask_number_set_high(ask,    fdisk_scround(cxt, stop));	/* maximal */
			}
			rc = fdisk_do_ask(cxt, ask);
			first = fdisk_ask_number_get_result(ask);
			fdisk_unref_ask(ask);
			if (rc)
				return rc;

			if (fdisk_use_cylinders(cxt))
				first *= fdisk_get_units_per_sector(cxt);

			/* ewt asks to add: "don't start a partition at cyl 0"
			   However, edmundo@rano.demon.co.uk writes:
			   "In addition to having a Sun partition table, to be able to
			   boot from the disc, the first partition, /dev/sdX1, must
			   start at cylinder 0. This means that /dev/sdX1 contains
			   the partition table and the boot block, as these are the
			   first two sectors of the disc. Therefore you must be
			   careful what you use /dev/sdX1 for. In particular, you must
			   not use a partition starting at cylinder 0 for Linux swap,
			   as that would overwrite the partition table and the boot
			   block. You may, however, use such a partition for a UFS
			   or EXT2 file system, as these file systems leave the first
			   1024 bytes undisturbed. */
			/* On the other hand, one should not use partitions
			   starting at block 0 in an md, or the label will
			   be trashed. */
			if (!is_free_sector(cxt, first, starts,  lens) && !whole_disk) {
				if (n == 2 && !first) {
				    whole_disk = 1;
				    break;
				}
				fdisk_warnx(cxt, _("Sector %d is already allocated"), first);
			} else
				break;
		}
	}

	if (n == 2 && first != 0)
		fdisk_warnx(cxt, _("It is highly recommended that the "
				   "third partition covers the whole disk "
				   "and is of type `Whole disk'"));

	if (!fdisk_use_cylinders(cxt)) {
		/* Starting sector has to be properly aligned */
		int cs = cxt->geom.heads * cxt->geom.sectors;
		int x = first % cs;

		if (x) {
			fdisk_info(cxt, _("Aligning the first sector from %u to %u "
					  "to be on cylinder boundary."),
					first, first + cs - x);
			first += cs - x;
		}
	}

	stop = cxt->geom.cylinders * cxt->geom.heads * cxt->geom.sectors;	/* ancient */
	stop2 = stop;
	for (i = 0; i < cxt->label->nparts_max; i++) {
		if (starts[i] > first && starts[i] < stop)
			stop = starts[i];
	}

	/* last */
	if (pa && pa->end_follow_default)
		last = whole_disk || (n == 2 && !first) ? stop2 : stop;
	else if (pa && fdisk_partition_has_size(pa)) {
		last = first + pa->size - 1ULL;

		if (!whole_disk && last > stop)
			return -ERANGE;
	} else {
		struct fdisk_ask *ask = fdisk_new_ask();

		if (!ask)
			return -ENOMEM;

		snprintf(mesg, sizeof(mesg),
			 _("Last %s or +%s or +size{K,M,G,T,P}"),
			 fdisk_get_unit(cxt, FDISK_SINGULAR),
			 fdisk_get_unit(cxt, FDISK_PLURAL));
		fdisk_ask_set_query(ask, mesg);
		fdisk_ask_set_type(ask, FDISK_ASKTYPE_OFFSET);

		if (whole_disk) {
			fdisk_ask_number_set_low(ask,     fdisk_scround(cxt, stop2));	/* minimal */
			fdisk_ask_number_set_default(ask, fdisk_scround(cxt, stop2));	/* default */
			fdisk_ask_number_set_high(ask,    fdisk_scround(cxt, stop2));	/* maximal */
			fdisk_ask_number_set_base(ask,    0);
		} else if (n == 2 && !first) {
			fdisk_ask_number_set_low(ask,     fdisk_scround(cxt, first));	/* minimal */
			fdisk_ask_number_set_default(ask, fdisk_scround(cxt, stop2));	/* default */
			fdisk_ask_number_set_high(ask,    fdisk_scround(cxt, stop2));	/* maximal */
			fdisk_ask_number_set_base(ask,	  fdisk_scround(cxt, first));
		} else {
			fdisk_ask_number_set_low(ask,     fdisk_scround(cxt, first));	/* minimal */
			fdisk_ask_number_set_default(ask, fdisk_scround(cxt, stop));	/* default */
			fdisk_ask_number_set_high(ask,    fdisk_scround(cxt, stop));	/* maximal */
			fdisk_ask_number_set_base(ask,    fdisk_scround(cxt, first));
		}

		if (fdisk_use_cylinders(cxt))
			fdisk_ask_number_set_unit(ask,
				     cxt->sector_size *
				     fdisk_get_units_per_sector(cxt));
		else
			fdisk_ask_number_set_unit(ask,	cxt->sector_size);

		rc = fdisk_do_ask(cxt, ask);
		last = fdisk_ask_number_get_result(ask);

		fdisk_unref_ask(ask);
		if (rc)
			return rc;
		if (fdisk_use_cylinders(cxt))
			last *= fdisk_get_units_per_sector(cxt);
	}

	if (n == 2 && !first) {
		if (last >= stop2) {
		    whole_disk = 1;
		    last = stop2;
		} else if (last > stop) {
		    fdisk_warnx(cxt,
   _("You haven't covered the whole disk with the 3rd partition, but your value\n"
     "%lu %s covers some other partition. Your entry has been changed\n"
     "to %lu %s"),
			(unsigned long) fdisk_scround(cxt, last), fdisk_get_unit(cxt, FDISK_SINGULAR),
			(unsigned long) fdisk_scround(cxt, stop), fdisk_get_unit(cxt, FDISK_SINGULAR));
		    last = stop;
		}
	} else if (!whole_disk && last > stop)
		last = stop;

	if (whole_disk)
		sys = SUN_TAG_WHOLEDISK;

	set_partition(cxt, n, first, last, sys);
	cxt->label->nparts_cur = count_used_partitions(cxt);
	if (partno)
		*partno = n;
	return 0;
}

static int sun_delete_partition(struct fdisk_context *cxt,
		size_t partnum)
{
	struct sun_disklabel *sunlabel;
	struct sun_partition *part;
	struct sun_info *info;
	unsigned int nsec;

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

	sunlabel = self_disklabel(cxt);
	part = &sunlabel->partitions[partnum];
	info = &sunlabel->vtoc.infos[partnum];

	if (partnum == 2 &&
	    be16_to_cpu(info->id) == SUN_TAG_WHOLEDISK &&
	    !part->start_cylinder &&
	    (nsec = be32_to_cpu(part->num_sectors))
	    == cxt->geom.heads * cxt->geom.sectors * cxt->geom.cylinders)
		fdisk_info(cxt, _("If you want to maintain SunOS/Solaris compatibility, "
			 "consider leaving this "
			 "partition as Whole disk (5), starting at 0, with %u "
			 "sectors"), nsec);
	info->id = cpu_to_be16(SUN_TAG_UNASSIGNED);
	part->num_sectors = 0;
	cxt->label->nparts_cur = count_used_partitions(cxt);
	fdisk_label_set_changed(cxt->label, 1);
	return 0;
}


static int sun_list_disklabel(struct fdisk_context *cxt)
{
	struct sun_disklabel *sunlabel;

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

	sunlabel = self_disklabel(cxt);

	if (fdisk_is_details(cxt)) {
		fdisk_info(cxt,
		_("Label geometry: %d rpm, %d alternate and %d physical cylinders,\n"
		  "                %d extra sects/cyl, interleave %d:1"),
		       be16_to_cpu(sunlabel->rpm),
		       be16_to_cpu(sunlabel->acyl),
		       be16_to_cpu(sunlabel->pcyl),
		       be16_to_cpu(sunlabel->apc),
		       be16_to_cpu(sunlabel->intrlv));
		fdisk_info(cxt, _("Label ID: %s"), sunlabel->label_id);
		fdisk_info(cxt, _("Volume ID: %s"),
		       *sunlabel->vtoc.volume_id ? sunlabel->vtoc.volume_id : _("<none>"));
	}

	return 0;
}

static struct fdisk_parttype *sun_get_parttype(
		struct fdisk_context *cxt,
		size_t n)
{
	struct sun_disklabel *sunlabel = self_disklabel(cxt);
	struct fdisk_parttype *t;

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

	t = fdisk_label_get_parttype_from_code(cxt->label,
			be16_to_cpu(sunlabel->vtoc.infos[n].id));
	return t ? : fdisk_new_unknown_parttype(be16_to_cpu(sunlabel->vtoc.infos[n].id), NULL);
}


static int sun_get_partition(struct fdisk_context *cxt, size_t n,
			      struct fdisk_partition *pa)
{
	struct sun_disklabel *sunlabel;
	struct sun_partition *part;
	uint16_t flags;
	uint32_t start, len;

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

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

	sunlabel = self_disklabel(cxt);
	part = &sunlabel->partitions[n];

	pa->used = part->num_sectors ? 1 : 0;
	if (!pa->used)
		return 0;

	flags = be16_to_cpu(sunlabel->vtoc.infos[n].flags);
	start = be32_to_cpu(part->start_cylinder)
			* cxt->geom.heads * cxt->geom.sectors;
	len = be32_to_cpu(part->num_sectors);

	pa->type = sun_get_parttype(cxt, n);
	if (pa->type && pa->type->code == SUN_TAG_WHOLEDISK)
		pa->wholedisk = 1;

	if (flags & SUN_FLAG_UNMNT || flags & SUN_FLAG_RONLY) {
		if (asprintf(&pa->attrs, "%c%c",
				flags & SUN_FLAG_UNMNT ? 'u' : ' ',
				flags & SUN_FLAG_RONLY ? 'r' : ' ') < 0)
			return -ENOMEM;
	}

	pa->start = start;
	pa->size = len;

	return 0;
}

/**
 * fdisk_sun_set_alt_cyl:
 * @cxt: context
 *
 * Sets number of alternative cylinders. This function uses libfdisk Ask API
 * for dialog with user.
 *
 * Returns: 0 on success, <0 on error.
 */
int fdisk_sun_set_alt_cyl(struct fdisk_context *cxt)
{
	struct sun_disklabel *sunlabel = self_disklabel(cxt);
	uintmax_t res;
	int rc = fdisk_ask_number(cxt, 0,			/* low */
			be16_to_cpu(sunlabel->acyl),		/* default */
			65535,					/* high */
			_("Number of alternate cylinders"),	/* query */
			&res);					/* result */
	if (rc)
		return rc;

	sunlabel->acyl = cpu_to_be16(res);
	return 0;
}

/**
 * fdisk_sun_set_xcyl:
 * @cxt: context
 *
 * Sets number of extra sectors per cylinder. This function uses libfdisk Ask API
 * for dialog with user.
 *
 * Returns: 0 on success, <0 on error.
 */
int fdisk_sun_set_xcyl(struct fdisk_context *cxt)
{
	struct sun_disklabel *sunlabel = self_disklabel(cxt);
	uintmax_t res;
	int rc = fdisk_ask_number(cxt, 0,			/* low */
			be16_to_cpu(sunlabel->apc),		/* default */
			cxt->geom.sectors,			/* high */
			_("Extra sectors per cylinder"),	/* query */
			&res);					/* result */
	if (rc)
		return rc;
	sunlabel->apc = cpu_to_be16(res);
	return 0;
}

/**
 * fdisk_sun_set_ilfact:
 * @cxt: context
 *
 * Sets interleave factor. This function uses libfdisk Ask API for dialog with
 * user.
 *
 * Returns: 0 on success, <0 on error.
 */
int fdisk_sun_set_ilfact(struct fdisk_context *cxt)
{
	struct sun_disklabel *sunlabel = self_disklabel(cxt);
	uintmax_t res;
	int rc = fdisk_ask_number(cxt, 1,			/* low */
			be16_to_cpu(sunlabel->intrlv),		/* default */
			32,					/* high */
			_("Interleave factor"),	/* query */
			&res);					/* result */
	if (rc)
		return rc;
	sunlabel->intrlv = cpu_to_be16(res);
	return 0;
}

/**
 * fdisk_sun_set_rspeed
 * @cxt: context
 *
 * Sets rotation speed. This function uses libfdisk Ask API for dialog with
 * user.
 *
 * Returns: 0 on success, <0 on error.
 */
int fdisk_sun_set_rspeed(struct fdisk_context *cxt)
{
	struct sun_disklabel *sunlabel = self_disklabel(cxt);
	uintmax_t res;
	int rc = fdisk_ask_number(cxt, 1,			/* low */
			be16_to_cpu(sunlabel->rpm),		/* default */
			USHRT_MAX,				/* high */
			_("Rotation speed (rpm)"),		/* query */
			&res);					/* result */
	if (rc)
		return rc;
	sunlabel->rpm = cpu_to_be16(res);
	return 0;
}

/**
 * fdisk_sun_set_pcylcount
 * @cxt: context
 *
 * Sets number of physical cylinders. This function uses libfdisk Ask API for
 * dialog with user.
 *
 * Returns: 0 on success, <0 on error.
 */
int fdisk_sun_set_pcylcount(struct fdisk_context *cxt)
{
	struct sun_disklabel *sunlabel = self_disklabel(cxt);
	uintmax_t res;
	int rc = fdisk_ask_number(cxt, 0,			/* low */
			be16_to_cpu(sunlabel->pcyl),		/* default */
			USHRT_MAX,				/* high */
			_("Number of physical cylinders"),	/* query */
			&res);					/* result */
	if (!rc)
		return rc;
	sunlabel->pcyl = cpu_to_be16(res);
	return 0;
}

static int sun_write_disklabel(struct fdisk_context *cxt)
{
	struct sun_disklabel *sunlabel;
	unsigned short *ush;
	unsigned short csum = 0;
	const size_t sz = sizeof(struct sun_disklabel);

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

	sunlabel = self_disklabel(cxt);

	/* Maybe geometry has been modified */
	sunlabel->nhead = cpu_to_be16(cxt->geom.heads);
	sunlabel->nsect = cpu_to_be16(cxt->geom.sectors);

	if (cxt->geom.cylinders != be16_to_cpu(sunlabel->ncyl))
		sunlabel->ncyl = cpu_to_be16( cxt->geom.cylinders
				      - be16_to_cpu(sunlabel->acyl) );

	ush = (unsigned short *) sunlabel;

	while(ush < (unsigned short *)(&sunlabel->csum))
		csum ^= *ush++;
	sunlabel->csum = csum;
	if (lseek(cxt->dev_fd, 0, SEEK_SET) < 0)
		return -errno;
	if (write_all(cxt->dev_fd, sunlabel, sz) != 0)
		return -errno;

	return 0;
}

static int sun_set_partition(
		struct fdisk_context *cxt,
		size_t i,
		struct fdisk_partition *pa)
{
	struct sun_disklabel *sunlabel;
	struct sun_partition *part;
	struct sun_info *info;

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

	sunlabel = self_disklabel(cxt);

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

	if (pa->type) {
		struct fdisk_parttype *t = pa->type;

		if (t->code > UINT16_MAX)
			return -EINVAL;

		if (i == 2 && t->code != SUN_TAG_WHOLEDISK)
			fdisk_info(cxt, _("Consider leaving partition 3 as Whole disk (5),\n"
			         "as SunOS/Solaris expects it and even Linux likes it.\n"));

		part = &sunlabel->partitions[i];
		info = &sunlabel->vtoc.infos[i];

		if (cxt->script == NULL &&
		    t->code == SUN_TAG_LINUX_SWAP && !part->start_cylinder) {
			int yes, rc;

			rc = fdisk_ask_yesno(cxt,
			      _("It is highly recommended that the partition at offset 0\n"
			      "is UFS, EXT2FS filesystem or SunOS swap. Putting Linux swap\n"
			      "there may destroy your partition table and bootblock.\n"
			      "Are you sure you want to tag the partition as Linux swap?"), &yes);
			if (rc)
				return rc;
			if (!yes)
				return 1;
		}

		switch (t->code) {
		case SUN_TAG_SWAP:
		case SUN_TAG_LINUX_SWAP:
			/* swaps are not mountable by default */
			info->flags |= cpu_to_be16(SUN_FLAG_UNMNT);
			break;
		default:
			/* assume other types are mountable;
			   user can change it anyway */
			info->flags &= ~cpu_to_be16(SUN_FLAG_UNMNT);
			break;
		}
		info->id = cpu_to_be16(t->code);
	}

	if (fdisk_partition_has_start(pa))
		sunlabel->partitions[i].start_cylinder =
			cpu_to_be32(pa->start / (cxt->geom.heads * cxt->geom.sectors));
	if (fdisk_partition_has_size(pa))
		sunlabel->partitions[i].num_sectors = cpu_to_be32(pa->size);

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


static int sun_reset_alignment(struct fdisk_context *cxt __attribute__((__unused__)))
{
	return 0;
}


static int sun_partition_is_used(
		struct fdisk_context *cxt,
		size_t i)
{
	struct sun_disklabel *sunlabel;

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

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

	sunlabel = self_disklabel(cxt);
	return sunlabel->partitions[i].num_sectors ? 1 : 0;
}

static const struct fdisk_field sun_fields[] =
{
	{ FDISK_FIELD_DEVICE,	N_("Device"),	 10,	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_FIELD_TYPEID,	N_("Id"),	  2,	FDISK_FIELDFL_NUMBER },
	{ FDISK_FIELD_TYPE,	N_("Type"),	0.1,	0 },
	{ FDISK_FIELD_ATTR,	N_("Flags"),	  0,	FDISK_FIELDFL_NUMBER }
};

const struct fdisk_label_operations sun_operations =
{
	.probe		= sun_probe_label,
	.write		= sun_write_disklabel,
	.verify		= sun_verify_disklabel,
	.create		= sun_create_disklabel,
	.list		= sun_list_disklabel,

	.get_part	= sun_get_partition,
	.set_part	= sun_set_partition,
	.add_part	= sun_add_partition,
	.del_part	= sun_delete_partition,

	.part_is_used	= sun_partition_is_used,
	.part_toggle_flag = sun_toggle_partition_flag,

	.reset_alignment = sun_reset_alignment,
};

/*
 * allocates SUN label driver
 */
struct fdisk_label *fdisk_new_sun_label(struct fdisk_context *cxt)
{
	struct fdisk_label *lb;
	struct fdisk_sun_label *sun;

	assert(cxt);

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

	/* initialize generic part of the driver */
	lb = (struct fdisk_label *) sun;
	lb->name = "sun";
	lb->id = FDISK_DISKLABEL_SUN;
	lb->op = &sun_operations;
	lb->parttypes = sun_parttypes;
	lb->nparttypes = ARRAY_SIZE(sun_parttypes) - 1;
	lb->fields = sun_fields;
	lb->nfields = ARRAY_SIZE(sun_fields);
	lb->flags |= FDISK_LABEL_FL_REQUIRE_GEOMETRY;

	return lb;
}
