last_patch100 from vidz updating fdisk to 2.12pre
diff --git a/util-linux/fdisk.c b/util-linux/fdisk.c
index 291be4b..4fecbbb 100644
--- a/util-linux/fdisk.c
+++ b/util-linux/fdisk.c
@@ -7,19 +7,10 @@
  * published by the Free Software Foundation: either version 1 or
  * (at your option) any later version.
  *
- * For detailed old history, see older versions.
- * Contributions before 2001 by faith@cs.unc.edu, Michael Bischoff,
- * LeBlanc@mcc.ac.uk, martin@cs.unc.edu, leisner@sdsp.mc.xerox.com,
- * esr@snark.thyrsus.com, aeb@cwi.nl, quinlan@yggdrasil.com,
- * fasten@cs.bonn.edu, orschaer@cip.informatik.uni-erlangen.de,
- * jj@sunsite.mff.cuni.cz, fasten@shw.com, ANeuper@GUUG.de,
- * kgw@suse.de, kalium@gmx.de, dhuggins@linuxcare.com,
- * michal@ellpspace.math.ualberta.ca and probably others.
- *
  * Vladimir Oleynik <dzo@simtreas.ru> 2001,2002 Busybox port
  */
 
-#define UTIL_LINUX_VERSION "2.11z"
+#define UTIL_LINUX_VERSION "2.12pre"
 
 #define PROC_PARTITIONS "/proc/partitions"
 
@@ -43,6 +34,7 @@
 
 #include <sys/ioctl.h>
 #include <sys/param.h>
+#include <sys/sysmacros.h>     /* major */
 
 #include <stdint.h>        /* for uint32_t, uint16_t, uint8_t, int16_t, etc */
 
@@ -63,7 +55,7 @@
 #define BLKGETSIZE _IO(0x12,96)    /* return device size */
 #define BLKFLSBUF  _IO(0x12,97)    /* flush buffer cache */
 #define BLKSSZGET  _IO(0x12,104)   /* get block device sector size */
-
+#define BLKGETSIZE64 _IOR(0x12,114,8)  /* 8 = sizeof(u64) */
 
 /*
    fdisk.h
@@ -117,6 +109,9 @@
 	const unsigned char *name;
 };
 
+static uint    sector_size = DEFAULT_SECTOR_SIZE,
+	user_set_sector_size,
+	sector_offset = 1;
 
 /*
  * Raw disk label. For DOS-type partition tables the MBR,
@@ -405,8 +400,11 @@
 
 /*
   Changes:
-  Sat Mar 20 09:51:38 EST 1999 Arnaldo Carvalho de Melo <acme@conectiva.com.br>
-	Internationalization
+  * 1999-03-20 Arnaldo Carvalho de Melo <acme@conectiva.com.br>
+  *     Internationalization
+  *
+  * 2003-03-20 Phillip Kesling <pkesling@sgi.com>
+  *      Some fixes
 */
 
 static  int     aix_other_endian;
@@ -515,6 +513,9 @@
 #elif defined (__alpha__) || defined (__powerpc__) || defined (__ia64__) || defined (__hppa__)
 #define BSD_LABELSECTOR   0
 #define BSD_LABELOFFSET   64
+#elif defined (__s390__) || defined (__s390x__)
+#define BSD_LABELSECTOR   1
+#define BSD_LABELOFFSET   0
 #else
 #error unknown architecture
 #endif
@@ -830,6 +831,7 @@
 	unsigned short csum;       /* Label xor'd checksum */
 } sun_partition;
 
+
 #define SUN_LABEL_MAGIC          0xDABE
 #define SUN_LABEL_MAGIC_SWAPPED  0xBEDA
 #define sunlabel ((sun_partition *)MBRbuffer)
@@ -1216,7 +1218,8 @@
 		c = read_char (_("Do you want to create a disklabel? (y/n) "));
 		if (c == 'y' || c == 'Y') {
 			if (xbsd_initlabel (
-#if defined (__alpha__) || defined (__powerpc__) || defined (__hppa__)
+#if defined (__alpha__) || defined (__powerpc__) || defined (__hppa__) || \
+    defined (__s390__) || defined (__s390x__)
 				NULL, &xbsd_dlabel, 0
 #else
 				xbsd_part, &xbsd_dlabel, xbsd_part_index
@@ -1557,7 +1560,7 @@
 static int
 xbsd_writelabel (struct partition *p, struct xbsd_disklabel *d)
 {
-  int sector;
+  unsigned int sector;
 
 #if !defined (__alpha__) && !defined (__powerpc__) && !defined (__hppa__)
   sector = get_start_sect(p) + BSD_LABELSECTOR;
@@ -1663,7 +1666,10 @@
 
 static inline uint32_t
 __swap32(uint32_t x) {
-	return (((uint32_t)(x) & 0xFF) << 24) | (((uint32_t)(x) & 0xFF00) << 8) | (((uint32_t)(x) & 0xFF0000) >> 8) | (((uint32_t)(x) & 0xFF000000) >> 24);
+	 return (((x & 0xFF) << 24) |
+		((x & 0xFF00) << 8) |
+		((x & 0xFF0000) >> 8) |
+		((x & 0xFF000000) >> 24));
 }
 #endif
 
@@ -1689,40 +1695,39 @@
  * only dealing with free blocks here
  */
 
-typedef struct { int first; int last; } freeblocks;
+typedef struct { unsigned int first; unsigned int last; } freeblocks;
 static freeblocks freelist[17]; /* 16 partitions can produce 17 vacant slots */
 
 static void
-setfreelist( int i, int f, int l ) {
+setfreelist(int i, unsigned int f, unsigned int l) {
 	freelist[i].first = f;
 	freelist[i].last = l;
 }
 
 static void
-add2freelist( int f, int l ) {
+add2freelist(unsigned int f, unsigned int l) {
 	int i = 0;
-	for( ; i<17 ; i++ ) {
-		if(freelist[i].last==0) break;
-	}
-	setfreelist( i, f, l );
+	for ( ; i < 17 ; i++)
+		if (freelist[i].last == 0)
+			break;
+	setfreelist(i, f, l);
 }
 
 static void
 clearfreelist(void) {
-	int i = 0;
-	for( ; i<17 ; i++ ) {
-		setfreelist( i, 0, 0 );
-	}
+	int i;
+
+	for (i = 0; i < 17 ; i++)
+		setfreelist(i, 0, 0);
 }
 
-static int
-isinfreelist( int b ) {
-	int i = 0;
-	for( ; i<17 ; i++ ) {
-		if (freelist[i].first <= b && freelist[i].last >= b) {
+static unsigned int
+isinfreelist(unsigned int b) {
+	int i;
+
+	for (i = 0; i < 17 ; i++)
+		if (freelist[i].first <= b && freelist[i].last >= b)
 			return freelist[i].last;
-		}
-	}
 	return 0;
 }
 	/* return last vacant block of this stride (never 0). */
@@ -1764,11 +1769,6 @@
     return SGI_SSWAP16(sgilabel->devparam.ntrks);
 }
 
-static int
-sgi_get_pcylcount(void) {
-    return SGI_SSWAP16(sgilabel->devparam.pcylcount);
-}
-
 static void
 sgi_nolabel(void) {
     sgilabel->magic = 0;
@@ -1777,13 +1777,13 @@
 }
 
 static unsigned int
-two_s_complement_32bit_sum(unsigned int* base, int size /* in bytes */ ) {
+two_s_complement_32bit_sum(unsigned int* base, int size /* in bytes */) {
     int i=0;
     unsigned int sum=0;
 
-    size = size / sizeof( unsigned int );
-    for( i=0; i<size; i++ )
-	sum = sum - SGI_SSWAP32(base[i]);
+    size /= sizeof(unsigned int);
+    for (i = 0; i < size; i++)
+	    sum -= SGI_SSWAP32(base[i]);
     return sum;
 }
 
@@ -1807,15 +1807,10 @@
     /*
      * test for correct checksum
      */
-    if( two_s_complement_32bit_sum( (unsigned int*)sgilabel,
-			sizeof(*sgilabel) ) )
-    {
-	fprintf( stderr, _("Detected sgi disklabel with wrong checksum.\n"));
-    } else
-    {
-	heads = sgi_get_ntrks();
-	cylinders = sgi_get_pcylcount();
-	sectors = sgi_get_nsect();
+    if (two_s_complement_32bit_sum((unsigned int*)sgilabel,
+				       sizeof(*sgilabel))) {
+		fprintf(stderr,
+			_("Detected sgi disklabel with wrong checksum.\n"));
     }
     update_units();
     sgi_label = 1;
@@ -1824,18 +1819,18 @@
     return 1;
 }
 
-static int
-sgi_get_start_sector( int i ) {
+static unsigned int
+sgi_get_start_sector(int i) {
     return SGI_SSWAP32(sgilabel->partitions[i].start_sector);
 }
 
-static int
-sgi_get_num_sectors( int i ) {
+static unsigned int
+sgi_get_num_sectors(int i) {
     return SGI_SSWAP32(sgilabel->partitions[i].num_sectors);
 }
 
 static int
-sgi_get_sysid( int i )
+sgi_get_sysid(int i)
 {
     return SGI_SSWAP32(sgilabel->partitions[i].id);
 }
@@ -1853,13 +1848,13 @@
 }
 
 static void
-sgi_list_table( int xtra ) {
+sgi_list_table(int xtra) {
     int i, w;
     int kpi = 0;                /* kernel partition ID */
 
-    w = strlen( disk_device );
+    w = strlen(disk_device);
 
-    if( xtra ) {
+    if(xtra) {
 	printf(_("\nDisk %s (SGI disk label): %d heads, %d sectors\n"
 	       "%d cylinders, %d physical cylinders\n"
 	       "%d extra sects/cyl, interleave %d:1\n"
@@ -1901,14 +1896,13 @@
     }
     printf(_("----- Bootinfo -----\nBootfile: %s\n"
 	     "----- Directory Entries -----\n"),
-	   sgilabel->boot_file );
-    for (i = 0 ; i < sgi_volumes; i++)
-    {
-	if (sgilabel->directory[i].vol_file_size)
-	{
+	       sgilabel->boot_file);
+	for (i = 0 ; i < sgi_volumes; i++) {
+	    if (sgilabel->directory[i].vol_file_size) {
 	    uint32_t start = SGI_SSWAP32(sgilabel->directory[i].vol_file_start);
 	    uint32_t len = SGI_SSWAP32(sgilabel->directory[i].vol_file_size);
 	    char*name = sgilabel->directory[i].vol_file_name;
+
 	    printf(_("%2d: %-10s sector%5u size%8u\n"),
 		    i, name, (unsigned int) start, (unsigned int) len);
 	}
@@ -1921,7 +1915,7 @@
     sgilabel->boot_part = SGI_SSWAP16(((short)i));
 }
 
-static int
+static unsigned int
 sgi_get_lastblock(void) {
     return heads * sectors * cylinders;
 }
@@ -1932,28 +1926,29 @@
 }
 
 static int
-sgi_check_bootfile( const char* aFile ) {
-    if( strlen( aFile ) < 3 ) /* "/a\n" is minimum */
-    {
-	printf( _("\nInvalid Bootfile!\n"
+sgi_check_bootfile(const char* aFile) {
+
+	if (strlen(aFile) < 3) /* "/a\n" is minimum */ {
+		printf(_("\nInvalid Bootfile!\n"
 		"\tThe bootfile must be an absolute non-zero pathname,\n"
-		"\te.g. \"/unix\" or \"/unix.save\".\n") );
+			 "\te.g. \"/unix\" or \"/unix.save\".\n"));
 	return 0;
-    } else
-    if( strlen( aFile ) > 16 )
-    {
-	printf( _("\n\tName of Bootfile too long:  16 bytes maximum.\n") );
+	} else {
+		if (strlen(aFile) > 16) {
+			printf(_("\n\tName of Bootfile too long:  "
+				 "16 bytes maximum.\n"));
 	return 0;
-    } else
-    if( aFile[0] != '/' )
-    {
-	printf( _("\n\tBootfile must have a fully qualified pathname.\n") );
+		} else {
+			if (aFile[0] != '/') {
+				printf(_("\n\tBootfile must have a "
+					 "fully qualified pathname.\n"));
 	return 0;
     }
-    if( strncmp( aFile, sgilabel->boot_file, 16 ) )
-    {
-	printf( _("\n\tBe aware, that the bootfile is not checked for existence.\n\t"
-		"SGI's default is \"/unix\" and for backup \"/unix.save\".\n") );
+		}
+	}
+	if (strncmp(aFile, sgilabel->boot_file, 16)) {
+		printf(_("\n\tBe aware, that the bootfile is not checked for existence.\n\t"
+			 "SGI's default is \"/unix\" and for backup \"/unix.save\".\n"));
 	/* filename is correct and did change */
 	return 1;
     }
@@ -1966,21 +1961,19 @@
 }
 
 static void
-sgi_set_bootfile( const char* aFile )
-{
+sgi_set_bootfile(const char* aFile) {
     int i = 0;
-    if( sgi_check_bootfile( aFile ) )
-    {
-	while( i<16 )
-	{
-	    if( (aFile[i] != '\n')      /* in principle caught again by next line */
-	    &&  (strlen( aFile ) > i ) )
+
+    if (sgi_check_bootfile(aFile)) {
+	while (i < 16) {
+	    if ((aFile[i] != '\n')  /* in principle caught again by next line */
+			    &&  (strlen(aFile) > i))
 		sgilabel->boot_file[i] = aFile[i];
 	    else
 		sgilabel->boot_file[i] = 0;
 	    i++;
 	}
-	printf( _("\n\tBootfile is changed to \"%s\".\n"), sgilabel->boot_file );
+	printf(_("\n\tBootfile is changed to \"%s\".\n"), sgilabel->boot_file);
     }
 }
 
@@ -1988,200 +1981,179 @@
 create_sgiinfo(void)
 {
     /* I keep SGI's habit to write the sgilabel to the second block */
-    sgilabel->directory[0].vol_file_start = SGI_SSWAP32( 2 );
-    sgilabel->directory[0].vol_file_size = SGI_SSWAP32( sizeof( sgiinfo ) );
-    strncpy( sgilabel->directory[0].vol_file_name, "sgilabel", 8 );
+    sgilabel->directory[0].vol_file_start = SGI_SSWAP32(2);
+    sgilabel->directory[0].vol_file_size = SGI_SSWAP32(sizeof(sgiinfo));
+    strncpy(sgilabel->directory[0].vol_file_name, "sgilabel", 8);
 }
 
-static sgiinfo * fill_sgiinfo(void);
+static sgiinfo *fill_sgiinfo(void);
 
 static void
-sgi_write_table(void)
-{
+sgi_write_table(void) {
     sgilabel->csum = 0;
-    sgilabel->csum = SGI_SSWAP32( two_s_complement_32bit_sum(
+     sgilabel->csum = SGI_SSWAP32(two_s_complement_32bit_sum(
 				 (unsigned int*)sgilabel,
-				 sizeof(*sgilabel) ) );
-    assert( two_s_complement_32bit_sum(
-	    (unsigned int*)sgilabel, sizeof(*sgilabel) ) == 0 );
-    if( lseek(fd, 0, SEEK_SET) < 0 )
+					sizeof(*sgilabel)));
+     assert(two_s_complement_32bit_sum(
+		(unsigned int*)sgilabel, sizeof(*sgilabel)) == 0);
+     if (lseek(fd, 0, SEEK_SET) < 0)
 	fdisk_fatal(unable_to_seek);
-    if( write(fd, sgilabel, SECTOR_SIZE) != SECTOR_SIZE )
+     if (write(fd, sgilabel, SECTOR_SIZE) != SECTOR_SIZE)
 	fdisk_fatal(unable_to_write);
-    if( ! strncmp( sgilabel->directory[0].vol_file_name, "sgilabel",8 ) )
-    {
+     if (! strncmp(sgilabel->directory[0].vol_file_name, "sgilabel", 8)) {
 	/*
-	 * keep this habbit of first writing the "sgilabel".
+	 * keep this habit of first writing the "sgilabel".
 	 * I never tested whether it works without (AN 981002).
 	 */
-	sgiinfo*info = fill_sgiinfo();  /* fills the block appropriately */
-	int infostartblock = SGI_SSWAP32( sgilabel->directory[0].vol_file_start );
-	if( lseek(fd, (ext2_loff_t)infostartblock*
-	    SECTOR_SIZE, SEEK_SET) < 0 )
+	 sgiinfo *info = fill_sgiinfo();
+	 int infostartblock = SGI_SSWAP32(sgilabel->directory[0].vol_file_start);
+	 if (lseek(fd, (long long)infostartblock*
+				SECTOR_SIZE, SEEK_SET) < 0)
 	    fdisk_fatal(unable_to_seek);
-	if( write(fd, info, SECTOR_SIZE) != SECTOR_SIZE )
+	 if (write(fd, info, SECTOR_SIZE) != SECTOR_SIZE)
 	    fdisk_fatal(unable_to_write);
-	free( info );
+	 free(info);
     }
 }
 
 static int
-compare_start( int *x, int *y ) {
+compare_start(int *x, int *y) {
     /*
      * sort according to start sectors
      * and prefers largest partition:
      * entry zero is entire disk entry
      */
-    int i = *x;
-    int j = *y;
-    int a = sgi_get_start_sector(i);
-    int b = sgi_get_start_sector(j);
-    int c = sgi_get_num_sectors(i);
-    int d = sgi_get_num_sectors(j);
-    if( a == b )
-    {
-	return( d - c );
-    }
-    return( a - b );
+    unsigned int i = *x;
+    unsigned int j = *y;
+    unsigned int a = sgi_get_start_sector(i);
+    unsigned int b = sgi_get_start_sector(j);
+    unsigned int c = sgi_get_num_sectors(i);
+    unsigned int d = sgi_get_num_sectors(j);
+
+    if (a == b)
+	return (d > c) ? 1 : (d == c) ? 0 : -1;
+    return (a > b) ? 1 : -1;
 }
 
 
 static int
-verify_sgi( int verbose )
+verify_sgi(int verbose)
 {
     int Index[16];      /* list of valid partitions */
     int sortcount = 0;  /* number of used partitions, i.e. non-zero lengths */
-    int entire = 0, i = 0;      /* local counters */
-    int start = 0;
-    int gap = 0;        /* count unused blocks */
-    int lastblock = sgi_get_lastblock();
-    /*
-     */
+    int entire = 0, i = 0;
+    unsigned int start = 0;
+    long long gap = 0;      /* count unused blocks */
+    unsigned int lastblock = sgi_get_lastblock();
+
     clearfreelist();
-    for( i=0; i<16; i++ )
-    {
-	if( sgi_get_num_sectors(i)!=0 )
-	{
+    for (i=0; i<16; i++) {
+	if (sgi_get_num_sectors(i) != 0) {
 	    Index[sortcount++]=i;
-	    if( sgi_get_sysid(i) == ENTIRE_DISK )
-	    {
-		if( entire++ == 1 )
-		{
-		    if(verbose)
+	    if (sgi_get_sysid(i) == ENTIRE_DISK) {
+		if (entire++ == 1) {
+		    if (verbose)
 			printf(_("More than one entire disk entry present.\n"));
 		}
 	    }
 	}
     }
-    if( sortcount == 0 )
-    {
-	if(verbose)
+    if (sortcount == 0) {
+	if (verbose)
 	    printf(_("No partitions defined\n"));
-	return lastblock;
+	       return (lastblock > 0) ? 1 : (lastblock == 0) ? 0 : -1;
     }
-    qsort( Index, sortcount, sizeof(Index[0]), (void*)compare_start );
-    if( sgi_get_sysid( Index[0] ) == ENTIRE_DISK )
-    {
-	if( ( Index[0] != 10 ) && verbose )
-	    printf( _("IRIX likes when Partition 11 covers the entire disk.\n") );
-	if( ( sgi_get_start_sector( Index[0] ) != 0 ) && verbose )
-	    printf( _("The entire disk partition should start at block 0,\nnot "
-		    "at diskblock %d.\n"), sgi_get_start_sector(Index[0] ) );
-    if(debug)   /* I do not understand how some disks fulfil it */
-	if( ( sgi_get_num_sectors( Index[0] ) != lastblock ) && verbose )
-	    printf( _("The entire disk partition is only %d diskblock large,\n"
+    qsort(Index, sortcount, sizeof(Index[0]), (void*)compare_start);
+    if (sgi_get_sysid(Index[0]) == ENTIRE_DISK) {
+	if ((Index[0] != 10) && verbose)
+	    printf(_("IRIX likes when Partition 11 covers the entire disk.\n"));
+	    if ((sgi_get_start_sector(Index[0]) != 0) && verbose)
+		printf(_("The entire disk partition should start "
+				"at block 0,\n"
+				"not at diskblock %d.\n"),
+			      sgi_get_start_sector(Index[0]));
+		if (debug)      /* I do not understand how some disks fulfil it */
+		       if ((sgi_get_num_sectors(Index[0]) != lastblock) && verbose)
+			       printf(_("The entire disk partition is only %d diskblock large,\n"
 		    "but the disk is %d diskblocks long.\n"),
-		    sgi_get_num_sectors( Index[0] ), lastblock );
-	lastblock = sgi_get_num_sectors( Index[0] );
-    } else
-    {
-	if( verbose )
-	    printf( _("One Partition (#11) should cover the entire disk.\n") );
-	if(debug>2)
-	    printf( "sysid=%d\tpartition=%d\n",
-			sgi_get_sysid( Index[0] ), Index[0]+1 );
+				      sgi_get_num_sectors(Index[0]), lastblock);
+		lastblock = sgi_get_num_sectors(Index[0]);
+    } else {
+	    if (verbose)
+		printf(_("One Partition (#11) should cover the entire disk.\n"));
+	    if (debug>2)
+		printf("sysid=%d\tpartition=%d\n",
+			      sgi_get_sysid(Index[0]), Index[0]+1);
     }
-    for( i=1, start=0; i<sortcount; i++ )
-    {
+    for (i=1, start=0; i<sortcount; i++) {
 	int cylsize = sgi_get_nsect() * sgi_get_ntrks();
-	if( (sgi_get_start_sector( Index[i] ) % cylsize) != 0 )
-	{
-	if(debug)       /* I do not understand how some disks fulfil it */
-	    if( verbose )
-		printf( _("Partition %d does not start on cylinder boundary.\n"),
-			Index[i]+1 );
-	}
-	if( sgi_get_num_sectors( Index[i] ) % cylsize != 0 )
-	{
-	if(debug)       /* I do not understand how some disks fulfil it */
-	    if( verbose )
-		printf( _("Partition %d does not end on cylinder boundary.\n"),
-			Index[i]+1 );
+
+	    if ((sgi_get_start_sector(Index[i]) % cylsize) != 0) {
+		if (debug)      /* I do not understand how some disks fulfil it */
+		    if (verbose)
+			printf(_("Partition %d does not start on cylinder boundary.\n"),
+					      Index[i]+1);
+	    }
+	    if (sgi_get_num_sectors(Index[i]) % cylsize != 0) {
+		if (debug)      /* I do not understand how some disks fulfil it */
+		    if (verbose)
+			printf(_("Partition %d does not end on cylinder boundary.\n"),
+					      Index[i]+1);
 	}
 	/* We cannot handle several "entire disk" entries. */
-	if( sgi_get_sysid( Index[i] ) == ENTIRE_DISK ) continue;
-	if( start > sgi_get_start_sector( Index[i] ) )
-	{
-	    if( verbose )
-		printf( _("The Partition %d and %d overlap by %d sectors.\n"),
+	    if (sgi_get_sysid(Index[i]) == ENTIRE_DISK) continue;
+	    if (start > sgi_get_start_sector(Index[i])) {
+		if (verbose)
+		    printf(_("The Partition %d and %d overlap by %d sectors.\n"),
 			Index[i-1]+1, Index[i]+1,
-			start - sgi_get_start_sector( Index[i] ) );
-	    if( gap >  0 ) gap = -gap;
-	    if( gap == 0 ) gap = -1;
-	}
-	if( start < sgi_get_start_sector( Index[i] ) )
-	{
-	    if( verbose )
-		printf( _("Unused gap of %8d sectors - sectors %8d-%d\n"),
-			sgi_get_start_sector( Index[i] ) - start,
-			start, sgi_get_start_sector( Index[i] )-1 );
-	    gap += sgi_get_start_sector( Index[i] ) - start;
-	    add2freelist( start, sgi_get_start_sector( Index[i] ) );
-	}
-	start = sgi_get_start_sector( Index[i] )
-	      + sgi_get_num_sectors(  Index[i] );
-	if(debug>1)
-	{
-	    if( verbose )
-		printf( "%2d:%12d\t%12d\t%12d\n", Index[i],
+				start - sgi_get_start_sector(Index[i]));
+		if (gap >  0) gap = -gap;
+		if (gap == 0) gap = -1;
+	    }
+	    if (start < sgi_get_start_sector(Index[i])) {
+		if (verbose)
+		    printf(_("Unused gap of %8u sectors - sectors %8u-%u\n"),
+				sgi_get_start_sector(Index[i]) - start,
+				start, sgi_get_start_sector(Index[i])-1);
+		gap += sgi_get_start_sector(Index[i]) - start;
+		add2freelist(start, sgi_get_start_sector(Index[i]));
+	    }
+	    start = sgi_get_start_sector(Index[i])
+		       + sgi_get_num_sectors(Index[i]);
+	    if (debug > 1) {
+		if (verbose)
+		    printf("%2d:%12d\t%12d\t%12d\n", Index[i],
 			sgi_get_start_sector(Index[i]),
 			sgi_get_num_sectors(Index[i]),
-			sgi_get_sysid(Index[i]) );
+				sgi_get_sysid(Index[i]));
 	}
     }
-    if( ( start < lastblock ) )
-    {
-	if( verbose )
-	    printf( _("Unused gap of %8d sectors - sectors %8d-%d\n"),
-		    lastblock - start, start, lastblock-1 );
+    if (start < lastblock) {
+	if (verbose)
+		printf(_("Unused gap of %8u sectors - sectors %8u-%u\n"),
+			    lastblock - start, start, lastblock-1);
 	gap += lastblock - start;
-	add2freelist( start, lastblock );
+	add2freelist(start, lastblock);
     }
     /*
      * Done with arithmetics
      * Go for details now
      */
-    if( verbose )
-    {
-	if( !sgi_get_num_sectors( sgi_get_bootpartition() ) )
-	{
-	    printf( _("\nThe boot partition does not exist.\n") );
+    if (verbose) {
+	if (!sgi_get_num_sectors(sgi_get_bootpartition())) {
+	    printf(_("\nThe boot partition does not exist.\n"));
 	}
-	if( !sgi_get_num_sectors( sgi_get_swappartition() ) )
-	{
-	    printf( _("\nThe swap partition does not exist.\n") );
-	} else
-	if( ( sgi_get_sysid( sgi_get_swappartition() ) != SGI_SWAP )
-	&&  ( sgi_get_sysid( sgi_get_swappartition() ) != LINUX_SWAP ) )
-	{
-	    printf( _("\nThe swap partition has no swap type.\n") );
+	if (!sgi_get_num_sectors(sgi_get_swappartition())) {
+	    printf(_("\nThe swap partition does not exist.\n"));
+	} else {
+	    if ((sgi_get_sysid(sgi_get_swappartition()) != SGI_SWAP)
+			&&  (sgi_get_sysid(sgi_get_swappartition()) != LINUX_SWAP))
+		printf(_("\nThe swap partition has no swap type.\n"));
 	}
-	if( sgi_check_bootfile( "/unix" ) )
-	{
-	    printf( _("\tYou have chosen an unusual boot file name.\n") );
-	}
+	if (sgi_check_bootfile("/unix"))
+	    printf(_("\tYou have chosen an unusual boot file name.\n"));
     }
-    return gap;
+    return (gap > 0) ? 1 : (gap == 0) ? 0 : -1;
 }
 
 static int
@@ -2221,32 +2193,32 @@
 /* returns partition index of first entry marked as entire disk */
 static int
 sgi_entire(void) {
-    int i=0;
-    for( i=0; i<16; i++ )
-	if( sgi_get_sysid(i) == SGI_VOLUME )
+    int i;
+
+    for(i=0; i<16; i++)
+	if(sgi_get_sysid(i) == SGI_VOLUME)
 	    return i;
     return -1;
 }
 
 static void
-sgi_set_partition( int i, uint start, uint length, int sys ) {
-    sgilabel->partitions[i].id =
-	    SGI_SSWAP32( sys );
-    sgilabel->partitions[i].num_sectors =
-	    SGI_SSWAP32( length );
-    sgilabel->partitions[i].start_sector =
-	    SGI_SSWAP32( start );
+sgi_set_partition(int i, unsigned int start, unsigned int length, int sys) {
+
+    sgilabel->partitions[i].id = SGI_SSWAP32(sys);
+    sgilabel->partitions[i].num_sectors = SGI_SSWAP32(length);
+    sgilabel->partitions[i].start_sector = SGI_SSWAP32(start);
     set_changed(i);
-    if( sgi_gaps() < 0 )        /* rebuild freelist */
+    if (sgi_gaps() < 0)     /* rebuild freelist */
 	printf(_("Do You know, You got a partition overlap on the disk?\n"));
 }
 
 static void
 sgi_set_entire(void) {
     int n;
-    for( n=10; n<partitions; n++ ) {
-	if(!sgi_get_num_sectors( n ) ) {
-	    sgi_set_partition( n, 0, sgi_get_lastblock(), SGI_VOLUME );
+
+    for(n=10; n < partitions; n++) {
+	if(!sgi_get_num_sectors(n) ) {
+	    sgi_set_partition(n, 0, sgi_get_lastblock(), SGI_VOLUME);
 	    break;
 	}
     }
@@ -2283,34 +2255,28 @@
 sgi_add_partition( int n, int sys )
 {
     char mesg[256];
-    int first=0, last=0;
+    unsigned int first=0, last=0;
 
     if( n == 10 ) {
 	sys = SGI_VOLUME;
     } else if ( n == 8 ) {
 	sys = 0;
     }
-    if( sgi_get_num_sectors(n) )
-    {
+    if(sgi_get_num_sectors(n)) {
 	printf(_("Partition %d is already defined.  Delete "
 		"it before re-adding it.\n"), n + 1);
 	return;
     }
-    if( (sgi_entire() == -1)
-    &&  (sys != SGI_VOLUME) )
-    {
+    if( (sgi_entire() == -1) &&  (sys != SGI_VOLUME) ) {
 	printf(_("Attempting to generate entire disk entry automatically.\n"));
 	sgi_set_entire();
 	sgi_set_volhdr();
     }
-    if( (sgi_gaps() == 0)
-    &&  (sys != SGI_VOLUME) )
-    {
+    if( (sgi_gaps() == 0) &&  (sys != SGI_VOLUME) ) {
 	printf(_("The entire disk is already covered with partitions.\n"));
 	return;
     }
-    if( sgi_gaps() < 0 )
-    {
+    if(sgi_gaps() < 0) {
 	printf(_("You got a partition overlap on the disk. Fix it first!\n"));
 	return;
     }
@@ -2354,48 +2320,62 @@
     sgi_set_partition( n, first, last-first, sys );
 }
 
+#ifdef CONFIG_FEATURE_FDISK_ADVANCED
 static void
 create_sgilabel(void)
 {
     struct hd_geometry geometry;
-    struct { int start;
-	     int nsect;
-	     int sysid; } old[4];
+    struct {
+	unsigned int start;
+	unsigned int nsect;
+	int sysid;
+    } old[4];
     int i=0;
+    long longsectors;               /* the number of sectors on the device */
+    int res;                        /* the result from the ioctl */
+    int sec_fac;                    /* the sector factor */
+
+    sec_fac = sector_size / 512;    /* determine the sector factor */
+
     fprintf( stderr,
 	_("Building a new SGI disklabel. Changes will remain in memory only,\n"
 	"until you decide to write them. After that, of course, the previous\n"
 	"content will be unrecoverably lost.\n\n"));
 
     sgi_other_endian = (BYTE_ORDER == LITTLE_ENDIAN);
-
-#ifdef HDIO_REQ
-    if (!ioctl(fd, HDIO_REQ, &geometry))
-#else
-    if (!ioctl(fd, HDIO_GETGEO, &geometry))
-#endif
-    {
+    res = ioctl(fd, BLKGETSIZE, &longsectors);
+    if (!ioctl(fd, HDIO_GETGEO, &geometry)) {
 	heads = geometry.heads;
 	sectors = geometry.sectors;
+	if (res == 0) {
+	    /* the get device size ioctl was successful */
+	    cylinders = longsectors / (heads * sectors);
+	    cylinders /= sec_fac;
+	} else {
+	    /* otherwise print error and use truncated version */
 	cylinders = geometry.cylinders;
+	    fprintf(stderr,
+		   _("Warning:  BLKGETSIZE ioctl failed on %s.  "
+		     "Using geometry cylinder value of %d.\n"
+		     "This value may be truncated for devices"
+		     " > 33.8 GB.\n"), disk_device, cylinders);
     }
-    for (i = 0; i < 4; i++)
-    {
+    }
+    for (i = 0; i < 4; i++) {
 	old[i].sysid = 0;
-	if( valid_part_table_flag(MBRbuffer) )
-	{
-	    if( get_part_table(i)->sys_ind )
-	    {
+	if(valid_part_table_flag(MBRbuffer)) {
+	    if(get_part_table(i)->sys_ind) {
 		old[i].sysid = get_part_table(i)->sys_ind;
-		old[i].start = get_start_sect( get_part_table(i) );
-		old[i].nsect = get_nr_sects( get_part_table(i) );
-		printf( _("Trying to keep parameters of partition %d.\n"), i );
-		if( debug )
-		    printf( _("ID=%02x\tSTART=%d\tLENGTH=%d\n"),
-			    old[i].sysid, old[i].start, old[i].nsect );
+		old[i].start = get_start_sect(get_part_table(i));
+		old[i].nsect = get_nr_sects(get_part_table(i));
+		printf(_("Trying to keep parameters of partition %d.\n"), i);
+		if (debug)
+		    printf(_("ID=%02x\tSTART=%d\tLENGTH=%d\n"),
+			old[i].sysid, old[i].start, old[i].nsect);
 	    }
 	}
     }
+
     memset(MBRbuffer, 0, sizeof(MBRbuffer));
     sgilabel->magic = SGI_SSWAP32(SGI_LABEL_MAGIC);
     sgilabel->boot_part = SGI_SSWAP16(0);
@@ -2438,11 +2418,9 @@
     sgi_volumes    = 15;
     sgi_set_entire();
     sgi_set_volhdr();
-    for (i = 0; i < 4; i++)
-    {
-	if( old[i].sysid )
-	{
-	    sgi_set_partition( i, old[i].start, old[i].nsect, old[i].sysid );
+    for (i = 0; i < 4; i++) {
+	if(old[i].sysid) {
+	    sgi_set_partition(i, old[i].start, old[i].nsect, old[i].sysid);
 	}
     }
 }
@@ -2452,14 +2430,16 @@
 {
     /* do nothing in the beginning */
 }
+#endif /* CONFIG_FEATURE_FDISK_ADVANCED */
 
 /* _____________________________________________________________
  */
 
-static sgiinfo*
+static sgiinfo *
 fill_sgiinfo(void)
 {
-    sgiinfo*info=calloc( 1, sizeof(sgiinfo) );
+    sgiinfo *info = calloc(1, sizeof(sgiinfo));
+
     info->magic=SGI_SSWAP32(SGI_INFO_MAGIC);
     info->b1=SGI_SSWAP32(-1);
     info->b2=SGI_SSWAP16(-1);
@@ -2498,6 +2478,7 @@
 #ifndef IDE1_MAJOR
 #define IDE1_MAJOR 22
 #endif
+
 static void guess_device_type(void) {
 	struct stat bootstat;
 
@@ -2505,12 +2486,12 @@
 		scsi_disk = 0;
 		floppy = 0;
 	} else if (S_ISBLK(bootstat.st_mode)
-		   && ((bootstat.st_rdev >> 8) == IDE0_MAJOR ||
-		       (bootstat.st_rdev >> 8) == IDE1_MAJOR)) {
+		   && (major(bootstat.st_rdev) == IDE0_MAJOR ||
+		       major(bootstat.st_rdev) == IDE1_MAJOR)) {
 		scsi_disk = 0;
 		floppy = 0;
 	} else if (S_ISBLK(bootstat.st_mode)
-		   && (bootstat.st_rdev >> 8) == FLOPPY_MAJOR) {
+		   && major(bootstat.st_rdev) == FLOPPY_MAJOR) {
 		scsi_disk = 0;
 		floppy = 1;
 	} else {
@@ -2736,11 +2717,7 @@
 	    }
 	}
 	if (!p || floppy) {
-#ifdef HDIO_REQ
-	    if (!ioctl(fd, HDIO_REQ, &geometry)) {
-#else
 	    if (!ioctl(fd, HDIO_GETGEO, &geometry)) {
-#endif
 		heads = geometry.heads;
 		sectors = geometry.sectors;
 		cylinders = geometry.cylinders;
@@ -3046,15 +3023,16 @@
 
 static void
 sun_delete_partition(int i) {
+	unsigned int nsec;
+
 	if (i == 2 && sunlabel->infos[i].id == WHOLE_DISK &&
 	    !sunlabel->partitions[i].start_cylinder &&
-	    SUN_SSWAP32(sunlabel->partitions[i].num_sectors)
+	    (nsec = SUN_SSWAP32(sunlabel->partitions[i].num_sectors))
 	      == heads * sectors * 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"),
-		       (uint) SUN_SSWAP32(sunlabel->partitions[i].num_sectors));
+		       "sectors\n"), nsec);
 	sunlabel->infos[i].id = 0;
 	sunlabel->partitions[i].num_sectors = 0;
 }
@@ -3132,6 +3110,8 @@
 	}
 }
 
+#ifdef CONFIG_FEATURE_FDISK_ADVANCED
+
 static void
 sun_set_alt_cyl(void) {
 	sunlabel->nacyl =
@@ -3171,6 +3151,7 @@
 		SUN_SSWAP16(read_int(0, SUN_SSWAP16(sunlabel->pcylcount), 65535, 0,
 				 _("Number of physical cylinders")));
 }
+#endif /* CONFIG_FEATURE_FDISK_ADVANCED */
 
 static void
 sun_write_table(void) {
@@ -3368,11 +3349,8 @@
 static uint    kern_heads, kern_sectors;
 
 static uint extended_offset;            /* offset of link pointers */
-static uint    sector_size = DEFAULT_SECTOR_SIZE,
-	user_set_sector_size,
-	sector_offset = 1;
 
-static unsigned long total_number_of_sectors;
+static unsigned long long total_number_of_sectors;
 
 
 static jmp_buf listingbuf;
@@ -3979,7 +3957,7 @@
 void
 get_geometry(void) {
 	int sec_fac;
-	unsigned long longsectors;
+	unsigned long long bytes;       /* really u64 */
 
 	get_sectorsize();
 	sec_fac = sector_size / 512;
@@ -3999,20 +3977,25 @@
 	sectors = user_sectors ? user_sectors :
 		pt_sectors ? pt_sectors :
 		kern_sectors ? kern_sectors : 63;
+	if (ioctl(fd, BLKGETSIZE64, &bytes) == 0) {
+		/* got bytes */
+	} else {
+		unsigned long longsectors;
 
 	if (ioctl(fd, BLKGETSIZE, &longsectors))
 		longsectors = 0;
+			bytes = ((unsigned long long) longsectors) << 9;
+	}
+
+	total_number_of_sectors = (bytes >> 9);
 
 	sector_offset = 1;
 	if (dos_compatible_flag)
 		sector_offset = sectors;
 
-	cylinders = longsectors / (heads * sectors);
-	cylinders /= sec_fac;
+	cylinders = total_number_of_sectors / (heads * sectors * sec_fac);
 	if (!cylinders)
 		cylinders = user_cylinders;
-
-	total_number_of_sectors = longsectors;
 }
 
 /*
@@ -4198,10 +4181,10 @@
 		default_ok = 0;
 
 	if (default_ok)
-		snprintf(ms, mslen, _("%s (%d-%d, default %d): "),
+		snprintf(ms, mslen, _("%s (%u-%u, default %u): "),
 			 mesg, low, high, dflt);
 	else
-		snprintf(ms, mslen, "%s (%d-%d): ",
+		snprintf(ms, mslen, "%s (%u-%u): ",
 			 mesg, low, high);
 
 	while (1) {
@@ -4227,8 +4210,10 @@
 					if (!display_in_cyl_units)
 						i *= heads * sectors;
 					break;
-			       case 'k':
 			       case 'K':
+					absolute = 1024;
+					break;
+				case 'k':
 				       absolute = 1000;
 				       break;
 			       case 'm':
@@ -4263,7 +4248,7 @@
 			}
 		}
 		if (use_default)
-			printf(_("Using default value %d\n"), i = dflt);
+			printf(_("Using default value %u\n"), i = dflt);
 		if (i >= low && i <= high)
 			break;
 		else
@@ -4466,7 +4451,18 @@
 	int i, sys, origsys;
 	struct partition *p;
 
+#ifdef CONFIG_FEATURE_SGI_LABEL
+	/* If sgi_label then don't use get_existing_partition,
+	   let the user select a partition, since get_existing_partition()
+	   only works for Linux like partition tables. */
+	if (!sgi_label) {
 	i = get_existing_partition(0, partitions);
+	} else {
+		i = get_partition(0, partitions);
+	}
+#else
+	i = get_existing_partition(0, partitions);
+#endif
 	if (i == -1)
 		return;
 	p = ptes[i].part_table;
@@ -4618,7 +4614,7 @@
 
 static void
 list_disk_geometry(void) {
-	long long bytes = (long long) total_number_of_sectors * 512;
+	long long bytes = (total_number_of_sectors << 9);
 	long megabytes = bytes/1000000;
 
 	if (megabytes < 10000)
@@ -4630,7 +4626,7 @@
 	printf(_("%d heads, %d sectors/track, %d cylinders"),
 	       heads, sectors, cylinders);
 	if (units_per_sector == 1)
-		printf(_(", total %lu sectors"),
+		printf(_(", total %llu sectors"),
 		       total_number_of_sectors / (sector_size/512));
 	printf(_("\nUnits = %s of %d * %d = %d bytes\n\n"),
 	       str_units(PLURAL),
@@ -4831,14 +4827,14 @@
 			if (sector_size > 1024)
 				pblocks *= (sector_size / 1024);
 			printf(
-			    "%s  %c %9ld %9ld %9ld%c  %2x  %s\n",
+			    "%s  %c %11lu %11lu %11lu%c  %2x  %s\n",
 			partname(disk_device, i+1, w+2),
 /* boot flag */         !p->boot_ind ? ' ' : p->boot_ind == ACTIVE_FLAG
 			? '*' : '?',
-/* start */             (long) cround(get_partition_start(pe)),
-/* end */               (long) cround(get_partition_start(pe) + psects
+/* start */             (unsigned long) cround(get_partition_start(pe)),
+/* end */               (unsigned long) cround(get_partition_start(pe) + psects
 				- (psects ? 1 : 0)),
-/* odd flag on end */   (long) pblocks, podd ? '+' : ' ',
+/* odd flag on end */   (unsigned long) pblocks, podd ? '+' : ' ',
 /* type id */           p->sys_ind,
 /* type name */         partition_type(p->sys_ind));
 			check_consistency(p, i);
@@ -4867,7 +4863,7 @@
 		pe = &ptes[i];
 		p = (extend ? pe->ext_pointer : pe->part_table);
 		if (p != NULL) {
-			printf("%2d %02x%4d%4d%5d%4d%4d%5d%9d%9d %02x\n",
+			printf("%2d %02x%4d%4d%5d%4d%4d%5d%11u%11u %02x\n",
 				i + 1, p->boot_ind, p->head,
 				sector(p->sector),
 				cylinder(p->sector, p->cyl), p->end_head,
@@ -5007,6 +5003,7 @@
 	int i, readed = 0;
 	struct partition *p = ptes[n].part_table;
 	struct partition *q = ptes[ext_index].part_table;
+	long long llimit;
 	uint start, stop = 0, limit, temp,
 		first[partitions], last[partitions];
 
@@ -5018,10 +5015,13 @@
 	fill_bounds(first, last);
 	if (n < 4) {
 		start = sector_offset;
-		if (display_in_cyl_units)
-			limit = heads * sectors * cylinders - 1;
+		if (display_in_cyl_units || !total_number_of_sectors)
+			llimit = heads * sectors * cylinders - 1;
 		else
-			limit = total_number_of_sectors - 1;
+			llimit = total_number_of_sectors - 1;
+		limit = llimit;
+		if (limit != llimit)
+			limit = 0x7fffffff;
 		if (extended_offset) {
 			first[ext_index] = extended_offset;
 			last[ext_index] = get_start_sect(q) +
@@ -5792,7 +5792,20 @@
 			break;
 		case 'd':
 			{
-				int j = get_existing_partition(1, partitions);
+				int j;
+#ifdef CONFIG_FEATURE_SGI_LABEL
+			/* If sgi_label then don't use get_existing_partition,
+			   let the user select a partition, since
+			   get_existing_partition() only works for Linux-like
+			   partition tables */
+				if (!sgi_label) {
+					j = get_existing_partition(1, partitions);
+				} else {
+					j = get_partition(1, partitions);
+				}
+#else
+				j = get_existing_partition(1, partitions);
+#endif
 				if (j >= 0)
 					delete_partition(j);
 			}