/*
 * fdisk_sun.c
 *
 * I think this is mostly, or entirely, due to
 *      Jakub Jelinek (jj@sunsite.mff.cuni.cz), July 1996
 *
 * Merged with fdisk for other architectures, aeb, June 1998.
 *
 * Sat Mar 20 EST 1999 Arnaldo Carvalho de Melo <acme@conectiva.com.br>
 *      Internationalization
 *
 * Licensed under GPLv2, see file LICENSE in this source tree.
 */

#if ENABLE_FEATURE_SUN_LABEL

#define SUNOS_SWAP 3
#define SUN_WHOLE_DISK 5

#define SUN_LABEL_MAGIC          0xDABE
#define SUN_LABEL_MAGIC_SWAPPED  0xBEDA
#define SUN_SSWAP16(x) (sun_other_endian ? fdisk_swap16(x) : (uint16_t)(x))
#define SUN_SSWAP32(x) (sun_other_endian ? fdisk_swap32(x) : (uint32_t)(x))

/* Copied from linux/major.h */
#define FLOPPY_MAJOR    2

#define SCSI_IOCTL_GET_IDLUN 0x5382

static smallint sun_other_endian;
static smallint scsi_disk;
static smallint floppy;

#ifndef IDE0_MAJOR
#define IDE0_MAJOR 3
#endif
#ifndef IDE1_MAJOR
#define IDE1_MAJOR 22
#endif

static void
guess_device_type(void)
{
	struct stat bootstat;

	if (fstat(dev_fd, &bootstat) < 0) {
		scsi_disk = 0;
		floppy = 0;
	} else if (S_ISBLK(bootstat.st_mode)
		&& (major(bootstat.st_rdev) == IDE0_MAJOR ||
		    major(bootstat.st_rdev) == IDE1_MAJOR)) {
		scsi_disk = 0;
		floppy = 0;
	} else if (S_ISBLK(bootstat.st_mode)
		&& major(bootstat.st_rdev) == FLOPPY_MAJOR) {
		scsi_disk = 0;
		floppy = 1;
	} else {
		scsi_disk = 1;
		floppy = 0;
	}
}

static const char *const sun_sys_types[] = {
	"\x00" "Empty"       , /* 0            */
	"\x01" "Boot"        , /* 1            */
	"\x02" "SunOS root"  , /* 2            */
	"\x03" "SunOS swap"  , /* SUNOS_SWAP   */
	"\x04" "SunOS usr"   , /* 4            */
	"\x05" "Whole disk"  , /* SUN_WHOLE_DISK   */
	"\x06" "SunOS stand" , /* 6            */
	"\x07" "SunOS var"   , /* 7            */
	"\x08" "SunOS home"  , /* 8            */
	"\x82" "Linux swap"  , /* LINUX_SWAP   */
	"\x83" "Linux native", /* LINUX_NATIVE */
	"\x8e" "Linux LVM"   , /* 0x8e         */
/* New (2.2.x) raid partition with autodetect using persistent superblock */
	"\xfd" "Linux raid autodetect", /* 0xfd         */
	NULL
};


static void
set_sun_partition(int i, unsigned start, unsigned stop, int sysid)
{
	sunlabel->infos[i].id = sysid;
	sunlabel->partitions[i].start_cylinder =
		SUN_SSWAP32(start / (g_heads * g_sectors));
	sunlabel->partitions[i].num_sectors =
		SUN_SSWAP32(stop - start);
	set_changed(i);
}

static int
check_sun_label(void)
{
	unsigned short *ush;
	int csum;

	if (sunlabel->magic != SUN_LABEL_MAGIC
	 && sunlabel->magic != SUN_LABEL_MAGIC_SWAPPED
	) {
		current_label_type = LABEL_DOS;
		sun_other_endian = 0;
		return 0;
	}
	sun_other_endian = (sunlabel->magic == SUN_LABEL_MAGIC_SWAPPED);
	ush = ((unsigned short *) (sunlabel + 1)) - 1;
	for (csum = 0; ush >= (unsigned short *)sunlabel;) csum ^= *ush--;
	if (csum) {
		printf("Detected sun disklabel with wrong checksum.\n"
"Probably you'll have to set all the values,\n"
"e.g. heads, sectors, cylinders and partitions\n"
"or force a fresh label (s command in main menu)\n");
	} else {
		g_heads = SUN_SSWAP16(sunlabel->ntrks);
		g_cylinders = SUN_SSWAP16(sunlabel->ncyl);
		g_sectors = SUN_SSWAP16(sunlabel->nsect);
	}
	update_units();
	current_label_type = LABEL_SUN;
	g_partitions = 8;
	return 1;
}

static const struct sun_predefined_drives {
	const char *vendor;
	const char *model;
	unsigned short sparecyl;
	unsigned short ncyl;
	unsigned short nacyl;
	unsigned short pcylcount;
	unsigned short ntrks;
	unsigned short nsect;
	unsigned short rspeed;
} sun_drives[] = {
	{ "Quantum","ProDrive 80S",1,832,2,834,6,34,3662},
	{ "Quantum","ProDrive 105S",1,974,2,1019,6,35,3662},
	{ "CDC","Wren IV 94171-344",3,1545,2,1549,9,46,3600},
	{ "IBM","DPES-31080",0,4901,2,4903,4,108,5400},
	{ "IBM","DORS-32160",0,1015,2,1017,67,62,5400},
	{ "IBM","DNES-318350",0,11199,2,11474,10,320,7200},
	{ "SEAGATE","ST34371",0,3880,2,3882,16,135,7228},
	{ "","SUN0104",1,974,2,1019,6,35,3662},
	{ "","SUN0207",4,1254,2,1272,9,36,3600},
	{ "","SUN0327",3,1545,2,1549,9,46,3600},
	{ "","SUN0340",0,1538,2,1544,6,72,4200},
	{ "","SUN0424",2,1151,2,2500,9,80,4400},
	{ "","SUN0535",0,1866,2,2500,7,80,5400},
	{ "","SUN0669",5,1614,2,1632,15,54,3600},
	{ "","SUN1.0G",5,1703,2,1931,15,80,3597},
	{ "","SUN1.05",0,2036,2,2038,14,72,5400},
	{ "","SUN1.3G",6,1965,2,3500,17,80,5400},
	{ "","SUN2.1G",0,2733,2,3500,19,80,5400},
	{ "IOMEGA","Jaz",0,1019,2,1021,64,32,5394},
};

static const struct sun_predefined_drives *
sun_autoconfigure_scsi(void)
{
	const struct sun_predefined_drives *p = NULL;

#ifdef SCSI_IOCTL_GET_IDLUN
	unsigned int id[2];
	char buffer[2048];
	char buffer2[2048];
	FILE *pfd;
	char *vendor;
	char *model;
	char *q;
	int i;

	if (ioctl(dev_fd, SCSI_IOCTL_GET_IDLUN, &id))
		return NULL;

	sprintf(buffer,
		"Host: scsi%u Channel: %02u Id: %02u Lun: %02u\n",
		/* This is very wrong (works only if you have one HBA),
		   but I haven't found a way how to get hostno
		   from the current kernel */
		0,
		(id[0]>>16) & 0xff,
		id[0] & 0xff,
		(id[0]>>8) & 0xff
	);
	pfd = fopen_for_read("/proc/scsi/scsi");
	if (!pfd) {
		return NULL;
	}
	while (fgets(buffer2, 2048, pfd)) {
		if (strcmp(buffer, buffer2))
			continue;
		if (!fgets(buffer2, 2048, pfd))
			break;
		q = strstr(buffer2, "Vendor: ");
		if (!q)
			break;
		q += 8;
		vendor = q;
		q = strstr(q, " ");
		*q++ = '\0';   /* truncate vendor name */
		q = strstr(q, "Model: ");
		if (!q)
			break;
		*q = '\0';
		q += 7;
		model = q;
		q = strstr(q, " Rev: ");
		if (!q)
			break;
		*q = '\0';
		for (i = 0; i < ARRAY_SIZE(sun_drives); i++) {
			if (*sun_drives[i].vendor && strcasecmp(sun_drives[i].vendor, vendor))
				continue;
			if (!strstr(model, sun_drives[i].model))
				continue;
			printf("Autoconfigure found a %s%s%s\n",
					sun_drives[i].vendor,
					(*sun_drives[i].vendor) ? " " : "",
					sun_drives[i].model);
			p = sun_drives + i;
			break;
		}
		break;
	}
	fclose(pfd);
#endif
	return p;
}

static void
create_sunlabel(void)
{
	struct hd_geometry geometry;
	unsigned ndiv;
	unsigned char c;
	const struct sun_predefined_drives *p = NULL;

	printf(msg_building_new_label, "sun disklabel");

	sun_other_endian = BB_LITTLE_ENDIAN;
	memset(MBRbuffer, 0, sizeof(MBRbuffer));
	sunlabel->magic = SUN_SSWAP16(SUN_LABEL_MAGIC);
	if (!floppy) {
		unsigned i;
		puts("Drive type\n"
		 "   ?   auto configure\n"
		 "   0   custom (with hardware detected defaults)");
		for (i = 0; i < ARRAY_SIZE(sun_drives); i++) {
			printf("   %c   %s%s%s\n",
				i + 'a', sun_drives[i].vendor,
				(*sun_drives[i].vendor) ? " " : "",
				sun_drives[i].model);
		}
		while (1) {
			c = read_nonempty("Select type (? for auto, 0 for custom): ");
			if (c == '0') {
				break;
			}
			if (c >= 'a' && c < 'a' + ARRAY_SIZE(sun_drives)) {
				p = sun_drives + c - 'a';
				break;
			}
			if (c >= 'A' && c < 'A' + ARRAY_SIZE(sun_drives)) {
				p = sun_drives + c - 'A';
				break;
			}
			if (c == '?' && scsi_disk) {
				p = sun_autoconfigure_scsi();
				if (p)
					break;
				printf("Autoconfigure failed\n");
			}
		}
	}
	if (!p || floppy) {
		if (!ioctl(dev_fd, HDIO_GETGEO, &geometry)) {
			g_heads = geometry.heads;
			g_sectors = geometry.sectors;
			g_cylinders = geometry.cylinders;
		} else {
			g_heads = 0;
			g_sectors = 0;
			g_cylinders = 0;
		}
		if (floppy) {
			sunlabel->nacyl = 0;
			sunlabel->pcylcount = SUN_SSWAP16(g_cylinders);
			sunlabel->rspeed = SUN_SSWAP16(300);
			sunlabel->ilfact = SUN_SSWAP16(1);
			sunlabel->sparecyl = 0;
		} else {
			g_heads = read_int(1, g_heads, 1024, 0, "Heads");
			g_sectors = read_int(1, g_sectors, 1024, 0, "Sectors/track");
		if (g_cylinders)
			g_cylinders = read_int(1, g_cylinders - 2, 65535, 0, "Cylinders");
		else
			g_cylinders = read_int(1, 0, 65535, 0, "Cylinders");
			sunlabel->nacyl = SUN_SSWAP16(read_int(0, 2, 65535, 0, "Alternate cylinders"));
			sunlabel->pcylcount = SUN_SSWAP16(read_int(0, g_cylinders + SUN_SSWAP16(sunlabel->nacyl), 65535, 0, "Physical cylinders"));
			sunlabel->rspeed = SUN_SSWAP16(read_int(1, 5400, 100000, 0, "Rotation speed (rpm)"));
			sunlabel->ilfact = SUN_SSWAP16(read_int(1, 1, 32, 0, "Interleave factor"));
			sunlabel->sparecyl = SUN_SSWAP16(read_int(0, 0, g_sectors, 0, "Extra sectors per cylinder"));
		}
	} else {
		sunlabel->sparecyl = SUN_SSWAP16(p->sparecyl);
		sunlabel->ncyl = SUN_SSWAP16(p->ncyl);
		sunlabel->nacyl = SUN_SSWAP16(p->nacyl);
		sunlabel->pcylcount = SUN_SSWAP16(p->pcylcount);
		sunlabel->ntrks = SUN_SSWAP16(p->ntrks);
		sunlabel->nsect = SUN_SSWAP16(p->nsect);
		sunlabel->rspeed = SUN_SSWAP16(p->rspeed);
		sunlabel->ilfact = SUN_SSWAP16(1);
		g_cylinders = p->ncyl;
		g_heads = p->ntrks;
		g_sectors = p->nsect;
		puts("You may change all the disk params from the x menu");
	}

	snprintf((char *)(sunlabel->info), sizeof(sunlabel->info),
		"%s%s%s cyl %u alt %u hd %u sec %u",
		p ? p->vendor : "", (p && *p->vendor) ? " " : "",
		p ? p->model : (floppy ? "3,5\" floppy" : "Linux custom"),
		g_cylinders, SUN_SSWAP16(sunlabel->nacyl), g_heads, g_sectors);

	sunlabel->ntrks = SUN_SSWAP16(g_heads);
	sunlabel->nsect = SUN_SSWAP16(g_sectors);
	sunlabel->ncyl = SUN_SSWAP16(g_cylinders);
	if (floppy)
		set_sun_partition(0, 0, g_cylinders * g_heads * g_sectors, LINUX_NATIVE);
	else {
		if (g_cylinders * g_heads * g_sectors >= 150 * 2048) {
			ndiv = g_cylinders - (50 * 2048 / (g_heads * g_sectors)); /* 50M swap */
		} else
			ndiv = g_cylinders * 2 / 3;
		set_sun_partition(0, 0, ndiv * g_heads * g_sectors, LINUX_NATIVE);
		set_sun_partition(1, ndiv * g_heads * g_sectors, g_cylinders * g_heads * g_sectors, LINUX_SWAP);
		sunlabel->infos[1].flags |= 0x01; /* Not mountable */
	}
	set_sun_partition(2, 0, g_cylinders * g_heads * g_sectors, SUN_WHOLE_DISK);
	{
		unsigned short *ush = (unsigned short *)sunlabel;
		unsigned short csum = 0;
		while (ush < (unsigned short *)(&sunlabel->csum))
			csum ^= *ush++;
		sunlabel->csum = csum;
	}

	set_all_unchanged();
	set_changed(0);
	check_sun_label();
	get_boot(CREATE_EMPTY_SUN);
}

static void
toggle_sunflags(int i, unsigned char mask)
{
	if (sunlabel->infos[i].flags & mask)
		sunlabel->infos[i].flags &= ~mask;
	else
		sunlabel->infos[i].flags |= mask;
	set_changed(i);
}

static void
fetch_sun(unsigned *starts, unsigned *lens, unsigned *start, unsigned *stop)
{
	int i, continuous = 1;

	*start = 0;
	*stop = g_cylinders * g_heads * g_sectors;
	for (i = 0; i < g_partitions; i++) {
		if (sunlabel->partitions[i].num_sectors
		 && sunlabel->infos[i].id
		 && sunlabel->infos[i].id != SUN_WHOLE_DISK) {
			starts[i] = SUN_SSWAP32(sunlabel->partitions[i].start_cylinder) * g_heads * g_sectors;
			lens[i] = SUN_SSWAP32(sunlabel->partitions[i].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;
		}
	}
}

static unsigned *verify_sun_starts;

static int
verify_sun_cmp(int *a, int *b)
{
	if (*a == -1) return 1;
	if (*b == -1) return -1;
	if (verify_sun_starts[*a] > verify_sun_starts[*b]) return 1;
	return -1;
}

static void
verify_sun(void)
{
	unsigned starts[8], lens[8], start, stop;
	int i,j,k,starto,endo;
	int array[8];

	verify_sun_starts = starts;
	fetch_sun(starts, lens, &start, &stop);
	for (k = 0; k < 7; k++) {
		for (i = 0; i < 8; i++) {
			if (k && (lens[i] % (g_heads * g_sectors))) {
				printf("Partition %u doesn't end on cylinder boundary\n", 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];
								printf("Partition %u overlaps with others in "
									"sectors %u-%u\n", i+1, starto, endo);
							}
						}
					}
			}
		}
	}
	for (i = 0; i < 8; i++) {
		if (lens[i])
			array[i] = i;
		else
			array[i] = -1;
	}
	qsort(array, ARRAY_SIZE(array), sizeof(array[0]),
		(int (*)(const void *,const void *)) verify_sun_cmp);
	if (array[0] == -1) {
		printf("No partitions defined\n");
		return;
	}
	stop = g_cylinders * g_heads * g_sectors;
	if (starts[array[0]])
		printf("Unused gap - sectors %u-%u\n", 0, starts[array[0]]);
	for (i = 0; i < 7 && array[i+1] != -1; i++) {
		printf("Unused gap - sectors %u-%u\n", starts[array[i]]+lens[array[i]], starts[array[i+1]]);
	}
	start = starts[array[i]] + lens[array[i]];
	if (start < stop)
		printf("Unused gap - sectors %u-%u\n", start, stop);
}

static void
add_sun_partition(int n, int sys)
{
	unsigned start, stop, stop2;
	unsigned starts[8], lens[8];
	int whole_disk = 0;

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

	if (sunlabel->partitions[n].num_sectors && sunlabel->infos[n].id) {
		printf(msg_part_already_defined, n + 1);
		return;
	}

	fetch_sun(starts, lens, &start, &stop);
	if (stop <= start) {
		if (n == 2)
			whole_disk = 1;
		else {
			printf("Other partitions already cover the whole disk.\n"
				"Delete/shrink them before retry.\n");
			return;
		}
	}
	snprintf(mesg, sizeof(mesg), "First %s", str_units());
	while (1) {
		if (whole_disk)
			first = read_int(0, 0, 0, 0, mesg);
		else
			first = read_int(scround(start), scround(stop)+1,
					 scround(stop), 0, mesg);
		if (display_in_cyl_units) {
			first *= units_per_sector;
		} else {
			/* Starting sector has to be properly aligned */
			first = (first + g_heads * g_sectors - 1) /
				(g_heads * g_sectors);
			first *= g_heads * g_sectors;
		}
		if (n == 2 && first != 0)
			printf("\
It is highly recommended that the third partition covers the whole disk\n\
and is of type 'Whole disk'\n");
		/* 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. */
		for (i = 0; i < g_partitions; i++)
			if (lens[i] && starts[i] <= first && starts[i] + lens[i] > first)
				break;
		if (i < g_partitions && !whole_disk) {
			if (n == 2 && !first) {
				whole_disk = 1;
				break;
			}
			printf("Sector %u is already allocated\n", first);
		} else
			break;
	}
	stop = g_cylinders * g_heads * g_sectors;
	stop2 = stop;
	for (i = 0; i < g_partitions; i++) {
		if (starts[i] > first && starts[i] < stop)
			stop = starts[i];
	}
	snprintf(mesg, sizeof(mesg),
		"Last %s or +size or +sizeM or +sizeK",
		str_units());
	if (whole_disk)
		last = read_int(scround(stop2), scround(stop2), scround(stop2),
				0, mesg);
	else if (n == 2 && !first)
		last = read_int(scround(first), scround(stop2), scround(stop2),
				scround(first), mesg);
	else
		last = read_int(scround(first), scround(stop), scround(stop),
				scround(first), mesg);
	if (display_in_cyl_units)
		last *= units_per_sector;
	if (n == 2 && !first) {
		if (last >= stop2) {
			whole_disk = 1;
			last = stop2;
		} else if (last > stop) {
			printf(
"You haven't covered the whole disk with the 3rd partition,\n"
"but your value %u %s covers some other partition.\n"
"Your entry has been changed to %u %s\n",
				scround(last), str_units(),
				scround(stop), str_units());
			last = stop;
		}
	} else if (!whole_disk && last > stop)
		last = stop;

	if (whole_disk)
		sys = SUN_WHOLE_DISK;
	set_sun_partition(n, first, last, sys);
}

static void
sun_delete_partition(int i)
{
	unsigned int nsec;

	if (i == 2
	 && sunlabel->infos[i].id == SUN_WHOLE_DISK
	 && !sunlabel->partitions[i].start_cylinder
	 && (nsec = SUN_SSWAP32(sunlabel->partitions[i].num_sectors)) == g_heads * g_sectors * g_cylinders)
		printf("If you want to maintain SunOS/Solaris compatibility, "
			"consider leaving this\n"
			"partition as Whole disk (5), starting at 0, with %u "
			"sectors\n", nsec);
	sunlabel->infos[i].id = 0;
	sunlabel->partitions[i].num_sectors = 0;
}

static void
sun_change_sysid(int i, int sys)
{
	if (sys == LINUX_SWAP && !sunlabel->partitions[i].start_cylinder) {
		read_maybe_empty(
			"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"
			"Type YES if you're very sure you would like that partition\n"
			"tagged with 82 (Linux swap): ");
		if (strcmp(line_ptr, "YES") != 0)
			return;
	}
	switch (sys) {
	case SUNOS_SWAP:
	case LINUX_SWAP:
		/* swaps are not mountable by default */
		sunlabel->infos[i].flags |= 0x01;
		break;
	default:
		/* assume other types are mountable;
		   user can change it anyway */
		sunlabel->infos[i].flags &= ~0x01;
		break;
	}
	sunlabel->infos[i].id = sys;
}

static void
sun_list_table(int xtra)
{
	int i, w;

	w = strlen(disk_device);
	if (xtra)
		printf(
		"\nDisk %s (Sun disk label): %u heads, %u sectors, %u rpm\n"
		"%u cylinders, %u alternate cylinders, %u physical cylinders\n"
		"%u extra sects/cyl, interleave %u:1\n"
		"%s\n"
		"Units = %ss of %u * 512 bytes\n\n",
			disk_device, g_heads, g_sectors, SUN_SSWAP16(sunlabel->rspeed),
			g_cylinders, SUN_SSWAP16(sunlabel->nacyl),
			SUN_SSWAP16(sunlabel->pcylcount),
			SUN_SSWAP16(sunlabel->sparecyl),
			SUN_SSWAP16(sunlabel->ilfact),
			(char *)sunlabel,
			str_units(), units_per_sector);
	else
		printf(
	"\nDisk %s (Sun disk label): %u heads, %u sectors, %u cylinders\n"
	"Units = %ss of %u * 512 bytes\n\n",
			disk_device, g_heads, g_sectors, g_cylinders,
			str_units(), units_per_sector);

	printf("%*s Flag    Start       End    Blocks   Id  System\n",
		w + 1, "Device");
	for (i = 0; i < g_partitions; i++) {
		if (sunlabel->partitions[i].num_sectors) {
			uint32_t start = SUN_SSWAP32(sunlabel->partitions[i].start_cylinder) * g_heads * g_sectors;
			uint32_t len = SUN_SSWAP32(sunlabel->partitions[i].num_sectors);
			printf("%s %c%c %9lu %9lu %9lu%c  %2x  %s\n",
				partname(disk_device, i+1, w),                  /* device */
				(sunlabel->infos[i].flags & 0x01) ? 'u' : ' ',  /* flags */
				(sunlabel->infos[i].flags & 0x10) ? 'r' : ' ',
				(long) scround(start),                          /* start */
				(long) scround(start+len),                      /* end */
				(long) len / 2, len & 1 ? '+' : ' ',            /* odd flag on end */
				sunlabel->infos[i].id,                          /* type id */
				partition_type(sunlabel->infos[i].id));         /* type name */
		}
	}
}

#if ENABLE_FEATURE_FDISK_ADVANCED

static void
sun_set_alt_cyl(void)
{
	sunlabel->nacyl =
		SUN_SSWAP16(read_int(0, SUN_SSWAP16(sunlabel->nacyl), 65535, 0,
				"Number of alternate cylinders"));
}

static void
sun_set_ncyl(int cyl)
{
	sunlabel->ncyl = SUN_SSWAP16(cyl);
}

static void
sun_set_xcyl(void)
{
	sunlabel->sparecyl =
		SUN_SSWAP16(read_int(0, SUN_SSWAP16(sunlabel->sparecyl), g_sectors, 0,
				"Extra sectors per cylinder"));
}

static void
sun_set_ilfact(void)
{
	sunlabel->ilfact =
		SUN_SSWAP16(read_int(1, SUN_SSWAP16(sunlabel->ilfact), 32, 0,
				"Interleave factor"));
}

static void
sun_set_rspeed(void)
{
	sunlabel->rspeed =
		SUN_SSWAP16(read_int(1, SUN_SSWAP16(sunlabel->rspeed), 100000, 0,
				"Rotation speed (rpm)"));
}

static void
sun_set_pcylcount(void)
{
	sunlabel->pcylcount =
		SUN_SSWAP16(read_int(0, SUN_SSWAP16(sunlabel->pcylcount), 65535, 0,
				"Number of physical cylinders"));
}
#endif /* FEATURE_FDISK_ADVANCED */

static void
sun_write_table(void)
{
	unsigned short *ush = (unsigned short *)sunlabel;
	unsigned short csum = 0;

	while (ush < (unsigned short *)(&sunlabel->csum))
		csum ^= *ush++;
	sunlabel->csum = csum;
	write_sector(0, sunlabel);
}
#endif /* SUN_LABEL */
