Ignore:
Timestamp:
Feb 25, 2011, 9:26:54 PM (13 years ago)
Author:
Bruno Cornec
Message:
  • Update mindi-busybox to 1.18.3 to avoid problems with the tar command which is now failing on recent versions with busybox 1.7.3
File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/2.2.9/mindi-busybox/util-linux/fdisk.c

    r1765 r2725  
    55 * Copyright (C) 2001,2002 Vladimir Oleynik <dzo@simtreas.ru> (initial bb port)
    66 *
    7  * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
     7 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
    88 */
    99
    1010#ifndef _LARGEFILE64_SOURCE
    1111/* For lseek64 */
    12 #define _LARGEFILE64_SOURCE
     12# define _LARGEFILE64_SOURCE
    1313#endif
    1414#include <assert.h>             /* assert */
     15#include <sys/mount.h>
     16#if !defined(BLKSSZGET)
     17# define BLKSSZGET _IO(0x12, 104)
     18#endif
     19#if !defined(BLKGETSIZE64)
     20# define BLKGETSIZE64 _IOR(0x12,114,size_t)
     21#endif
    1522#include "libbb.h"
     23
     24#if BB_LITTLE_ENDIAN
     25# define inline_if_little_endian ALWAYS_INLINE
     26#else
     27# define inline_if_little_endian /* nothing */
     28#endif
     29
    1630
    1731/* Looks like someone forgot to add this to config system */
    1832#ifndef ENABLE_FEATURE_FDISK_BLKSIZE
    1933# define ENABLE_FEATURE_FDISK_BLKSIZE 0
    20 # define USE_FEATURE_FDISK_BLKSIZE(a)
    21 #endif
    22 
    23 #define DEFAULT_SECTOR_SIZE     512
    24 #define MAX_SECTOR_SIZE 2048
    25 #define SECTOR_SIZE     512     /* still used in osf/sgi/sun code */
    26 #define MAXIMUM_PARTS   60
    27 
    28 #define ACTIVE_FLAG     0x80
    29 
    30 #define EXTENDED        0x05
    31 #define WIN98_EXTENDED  0x0f
    32 #define LINUX_PARTITION 0x81
    33 #define LINUX_SWAP      0x82
    34 #define LINUX_NATIVE    0x83
    35 #define LINUX_EXTENDED  0x85
    36 #define LINUX_LVM       0x8e
    37 #define LINUX_RAID      0xfd
    38 
    39 /* Used for sector numbers. Today's disk sizes make it necessary */
     34# define IF_FEATURE_FDISK_BLKSIZE(a)
     35#endif
     36
     37#define DEFAULT_SECTOR_SIZE      512
     38#define DEFAULT_SECTOR_SIZE_STR "512"
     39#define MAX_SECTOR_SIZE         2048
     40#define SECTOR_SIZE              512 /* still used in osf/sgi/sun code */
     41#define MAXIMUM_PARTS             60
     42
     43#define ACTIVE_FLAG             0x80
     44
     45#define EXTENDED                0x05
     46#define WIN98_EXTENDED          0x0f
     47#define LINUX_PARTITION         0x81
     48#define LINUX_SWAP              0x82
     49#define LINUX_NATIVE            0x83
     50#define LINUX_EXTENDED          0x85
     51#define LINUX_LVM               0x8e
     52#define LINUX_RAID              0xfd
     53
     54
     55enum {
     56    OPT_b = 1 << 0,
     57    OPT_C = 1 << 1,
     58    OPT_H = 1 << 2,
     59    OPT_l = 1 << 3,
     60    OPT_S = 1 << 4,
     61    OPT_u = 1 << 5,
     62    OPT_s = (1 << 6) * ENABLE_FEATURE_FDISK_BLKSIZE,
     63};
     64
     65
    4066typedef unsigned long long ullong;
     67/* Used for sector numbers. Partition formats we know
     68 * do not support more than 2^32 sectors
     69 */
     70typedef uint32_t sector_t;
     71#if UINT_MAX == 4294967295
     72# define SECT_FMT ""
     73#elif ULONG_MAX == 4294967295
     74# define SECT_FMT "l"
     75#else
     76# error Cant detect sizeof(uint32_t)
     77#endif
    4178
    4279struct hd_geometry {
     
    5592
    5693static const char msg_part_already_defined[] ALIGN1 =
    57 "Partition %d is already defined, delete it before re-adding\n";
    58 
    59 
    60 static unsigned sector_size = DEFAULT_SECTOR_SIZE;
    61 static unsigned user_set_sector_size;
    62 static unsigned sector_offset = 1;
    63 
    64 #if ENABLE_FEATURE_OSF_LABEL
    65 static int possibly_osf_label;
    66 #endif
    67 
    68 static unsigned heads, sectors, cylinders;
    69 static void update_units(void);
     94"Partition %u is already defined, delete it before re-adding\n";
    7095
    7196
     
    75100    unsigned char sector;           /* starting sector */
    76101    unsigned char cyl;              /* starting cylinder */
    77     unsigned char sys_ind;          /* What partition type */
     102    unsigned char sys_ind;          /* what partition type */
    78103    unsigned char end_head;         /* end head */
    79104    unsigned char end_sector;       /* end sector */
     
    81106    unsigned char start4[4];        /* starting sector counting from 0 */
    82107    unsigned char size4[4];         /* nr of sectors in partition */
    83 } ATTRIBUTE_PACKED;
    84 
    85 static const char unable_to_open[] ALIGN1 = "cannot open %s";
    86 static const char unable_to_read[] ALIGN1 = "cannot read from %s";
    87 static const char unable_to_seek[] ALIGN1 = "cannot seek on %s";
    88 static const char unable_to_write[] ALIGN1 = "cannot write to %s";
    89 static const char ioctl_error[] ALIGN1 = "BLKGETSIZE ioctl failed on %s";
    90 static void fdisk_fatal(const char *why) ATTRIBUTE_NORETURN;
    91 
    92 enum label_type {
    93     label_dos, label_sun, label_sgi, label_aix, label_osf
    94 };
    95 
    96 #define LABEL_IS_DOS    (label_dos == current_label_type)
    97 
    98 #if ENABLE_FEATURE_SUN_LABEL
    99 #define LABEL_IS_SUN    (label_sun == current_label_type)
    100 #define STATIC_SUN static
    101 #else
    102 #define LABEL_IS_SUN    0
    103 #define STATIC_SUN extern
    104 #endif
    105 
    106 #if ENABLE_FEATURE_SGI_LABEL
    107 #define LABEL_IS_SGI    (label_sgi == current_label_type)
    108 #define STATIC_SGI static
    109 #else
    110 #define LABEL_IS_SGI    0
    111 #define STATIC_SGI extern
    112 #endif
    113 
    114 #if ENABLE_FEATURE_AIX_LABEL
    115 #define LABEL_IS_AIX    (label_aix == current_label_type)
    116 #define STATIC_AIX static
    117 #else
    118 #define LABEL_IS_AIX    0
    119 #define STATIC_AIX extern
    120 #endif
    121 
    122 #if ENABLE_FEATURE_OSF_LABEL
    123 #define LABEL_IS_OSF    (label_osf == current_label_type)
    124 #define STATIC_OSF static
    125 #else
    126 #define LABEL_IS_OSF    0
    127 #define STATIC_OSF extern
    128 #endif
    129 
    130 enum action { fdisk, require, try_only, create_empty_dos, create_empty_sun };
    131 
    132 static enum label_type current_label_type;
    133 
    134 static const char *disk_device;
    135 static int fd;                  /* the disk */
    136 static int partitions = 4;      /* maximum partition + 1 */
    137 static int display_in_cyl_units = 1;
    138 static unsigned units_per_sector = 1;
    139 #if ENABLE_FEATURE_FDISK_WRITABLE
    140 static void change_units(void);
    141 static void reread_partition_table(int leave);
    142 static void delete_partition(int i);
    143 static int get_partition(int warn, int max);
    144 static void list_types(const char *const *sys);
    145 static unsigned read_int(unsigned low, unsigned dflt, unsigned high, unsigned base, const char *mesg);
    146 #endif
    147 static const char *partition_type(unsigned char type);
    148 static void get_geometry(void);
    149 static int get_boot(enum action what);
    150 
    151 #define PLURAL   0
    152 #define SINGULAR 1
    153 
    154 static unsigned get_start_sect(const struct partition *p);
    155 static unsigned get_nr_sects(const struct partition *p);
     108} PACKED;
    156109
    157110/*
     
    166119    struct partition *part_table;   /* points into sectorbuffer */
    167120    struct partition *ext_pointer;  /* points into sectorbuffer */
    168     ullong offset;          /* disk sector number */
    169     char *sectorbuffer;     /* disk sector contents */
     121    sector_t offset_from_dev_start; /* disk sector number */
     122    char *sectorbuffer;             /* disk sector contents */
    170123#if ENABLE_FEATURE_FDISK_WRITABLE
    171     char changed;           /* boolean */
     124    char changed;                   /* boolean */
    172125#endif
    173126};
     127
     128#define unable_to_open "can't open '%s'"
     129#define unable_to_read "can't read from %s"
     130#define unable_to_seek "can't seek on %s"
     131
     132enum label_type {
     133    LABEL_DOS, LABEL_SUN, LABEL_SGI, LABEL_AIX, LABEL_OSF, LABEL_GPT
     134};
     135
     136#define LABEL_IS_DOS    (LABEL_DOS == current_label_type)
     137
     138#if ENABLE_FEATURE_SUN_LABEL
     139#define LABEL_IS_SUN    (LABEL_SUN == current_label_type)
     140#define STATIC_SUN static
     141#else
     142#define LABEL_IS_SUN    0
     143#define STATIC_SUN extern
     144#endif
     145
     146#if ENABLE_FEATURE_SGI_LABEL
     147#define LABEL_IS_SGI    (LABEL_SGI == current_label_type)
     148#define STATIC_SGI static
     149#else
     150#define LABEL_IS_SGI    0
     151#define STATIC_SGI extern
     152#endif
     153
     154#if ENABLE_FEATURE_AIX_LABEL
     155#define LABEL_IS_AIX    (LABEL_AIX == current_label_type)
     156#define STATIC_AIX static
     157#else
     158#define LABEL_IS_AIX    0
     159#define STATIC_AIX extern
     160#endif
     161
     162#if ENABLE_FEATURE_OSF_LABEL
     163#define LABEL_IS_OSF    (LABEL_OSF == current_label_type)
     164#define STATIC_OSF static
     165#else
     166#define LABEL_IS_OSF    0
     167#define STATIC_OSF extern
     168#endif
     169
     170#if ENABLE_FEATURE_GPT_LABEL
     171#define LABEL_IS_GPT    (LABEL_GPT == current_label_type)
     172#define STATIC_GPT static
     173#else
     174#define LABEL_IS_GPT    0
     175#define STATIC_GPT extern
     176#endif
     177
     178enum action { OPEN_MAIN, TRY_ONLY, CREATE_EMPTY_DOS, CREATE_EMPTY_SUN };
     179
     180static void update_units(void);
     181#if ENABLE_FEATURE_FDISK_WRITABLE
     182static void change_units(void);
     183static void reread_partition_table(int leave);
     184static void delete_partition(int i);
     185static unsigned get_partition(int warn, unsigned max);
     186static void list_types(const char *const *sys);
     187static sector_t read_int(sector_t low, sector_t dflt, sector_t high, sector_t base, const char *mesg);
     188#endif
     189static const char *partition_type(unsigned char type);
     190static void get_geometry(void);
     191static void read_pte(struct pte *pe, sector_t offset);
     192#if ENABLE_FEATURE_SUN_LABEL || ENABLE_FEATURE_FDISK_WRITABLE
     193static int get_boot(enum action what);
     194#else
     195static int get_boot(void);
     196#endif
     197
     198#define PLURAL   0
     199#define SINGULAR 1
     200
     201static sector_t get_start_sect(const struct partition *p);
     202static sector_t get_nr_sects(const struct partition *p);
    174203
    175204/* DOS partition types */
     
    278307};
    279308
     309enum {
     310    dev_fd = 3                  /* the disk */
     311};
    280312
    281313/* Globals */
    282 
    283314struct globals {
    284315    char *line_ptr;
     316
     317    const char *disk_device;
     318    int g_partitions; // = 4;       /* maximum partition + 1 */
     319    unsigned units_per_sector; // = 1;
     320    unsigned sector_size; // = DEFAULT_SECTOR_SIZE;
     321    unsigned user_set_sector_size;
     322    unsigned sector_offset; // = 1;
     323    unsigned g_heads, g_sectors, g_cylinders;
     324    smallint /* enum label_type */ current_label_type;
     325    smallint display_in_cyl_units; // = 1;
     326#if ENABLE_FEATURE_OSF_LABEL
     327    smallint possibly_osf_label;
     328#endif
     329
     330    smallint listing;               /* no aborts for fdisk -l */
     331    smallint dos_compatible_flag; // = 1;
     332#if ENABLE_FEATURE_FDISK_WRITABLE
     333    //int dos_changed;
     334    smallint nowarn;                /* no warnings for fdisk -l/-s */
     335#endif
     336    int ext_index;                  /* the prime extended partition */
     337    unsigned user_cylinders, user_heads, user_sectors;
     338    unsigned pt_heads, pt_sectors;
     339    unsigned kern_heads, kern_sectors;
     340    sector_t extended_offset;       /* offset of link pointers */
     341    sector_t total_number_of_sectors;
     342
     343    jmp_buf listingbuf;
    285344    char line_buffer[80];
    286345    char partname_buffer[80];
    287     jmp_buf listingbuf;
    288346    /* Raw disk label. For DOS-type partition tables the MBR,
    289347     * with descriptions of the primary partitions. */
     
    292350    struct pte ptes[MAXIMUM_PARTS];
    293351};
    294 /* bb_common_bufsiz1 is too small for this on 64 bit CPUs */
    295352#define G (*ptr_to_globals)
    296 
    297 #define line_ptr        (G.line_ptr)
    298 #define listingbuf      (G.listingbuf)
    299 #define line_buffer     (G.line_buffer)
     353#define line_ptr             (G.line_ptr            )
     354#define disk_device          (G.disk_device         )
     355#define g_partitions         (G.g_partitions        )
     356#define units_per_sector     (G.units_per_sector    )
     357#define sector_size          (G.sector_size         )
     358#define user_set_sector_size (G.user_set_sector_size)
     359#define sector_offset        (G.sector_offset       )
     360#define g_heads              (G.g_heads             )
     361#define g_sectors            (G.g_sectors           )
     362#define g_cylinders          (G.g_cylinders         )
     363#define current_label_type   (G.current_label_type  )
     364#define display_in_cyl_units (G.display_in_cyl_units)
     365#define possibly_osf_label   (G.possibly_osf_label  )
     366#define listing                 (G.listing                )
     367#define dos_compatible_flag     (G.dos_compatible_flag    )
     368#define nowarn                  (G.nowarn                 )
     369#define ext_index               (G.ext_index              )
     370#define user_cylinders          (G.user_cylinders         )
     371#define user_heads              (G.user_heads             )
     372#define user_sectors            (G.user_sectors           )
     373#define pt_heads                (G.pt_heads               )
     374#define pt_sectors              (G.pt_sectors             )
     375#define kern_heads              (G.kern_heads             )
     376#define kern_sectors            (G.kern_sectors           )
     377#define extended_offset         (G.extended_offset        )
     378#define total_number_of_sectors (G.total_number_of_sectors)
     379#define listingbuf      (G.listingbuf     )
     380#define line_buffer     (G.line_buffer    )
    300381#define partname_buffer (G.partname_buffer)
    301 #define MBRbuffer       (G.MBRbuffer)
    302 #define ptes            (G.ptes)
    303 
    304 
    305 /* Code */
     382#define MBRbuffer       (G.MBRbuffer      )
     383#define ptes            (G.ptes           )
     384#define INIT_G() do { \
     385    SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \
     386    sector_size = DEFAULT_SECTOR_SIZE; \
     387    sector_offset = 1; \
     388    g_partitions = 4; \
     389    display_in_cyl_units = 1; \
     390    units_per_sector = 1; \
     391    dos_compatible_flag = 1; \
     392} while (0)
     393
     394
     395/* TODO: move to libbb? */
     396/* TODO: return unsigned long long, FEATURE_FDISK_BLKSIZE _can_ handle
     397 * disks > 2^32 sectors
     398 */
     399static sector_t bb_BLKGETSIZE_sectors(int fd)
     400{
     401    uint64_t v64;
     402    unsigned long longsectors;
     403
     404    if (ioctl(fd, BLKGETSIZE64, &v64) == 0) {
     405        /* Got bytes, convert to 512 byte sectors */
     406        v64 >>= 9;
     407        if (v64 != (sector_t)v64) {
     408 ret_trunc:
     409            /* Not only DOS, but all other partition tables
     410             * we support can't record more than 32 bit
     411             * sector counts or offsets
     412             */
     413            bb_error_msg("device has more than 2^32 sectors, can't use all of them");
     414            v64 = (uint32_t)-1L;
     415        }
     416        return v64;
     417    }
     418    /* Needs temp of type long */
     419    if (ioctl(fd, BLKGETSIZE, &longsectors)) {
     420        /* Perhaps this is a disk image */
     421        off_t sz = lseek(fd, 0, SEEK_END);
     422        longsectors = 0;
     423        if (sz > 0)
     424            longsectors = (uoff_t)sz / sector_size;
     425        lseek(fd, 0, SEEK_SET);
     426    }
     427    if (sizeof(long) > sizeof(sector_t)
     428     && longsectors != (sector_t)longsectors
     429    ) {
     430        goto ret_trunc;
     431    }
     432    return longsectors;
     433}
     434
    306435
    307436#define IS_EXTENDED(i) \
     
    322451    (sector(s) - 1 + sectors * ((h) + heads * cylinder(s,c)))
    323452
    324 #define set_hsc(h,s,c,sector) \
    325     do { \
    326         s = sector % sectors + 1;  \
    327         sector /= sectors;         \
    328         h = sector % heads;        \
    329         sector /= heads;           \
    330         c = sector & 0xff;         \
    331         s |= (sector >> 2) & 0xc0; \
    332     } while (0)
    333 
    334 #if ENABLE_FEATURE_FDISK_WRITABLE
    335 /* read line; return 0 or first printable char */
    336 static int
    337 read_line(const char *prompt)
    338 {
    339     int sz;
    340 
    341     sz = read_line_input(prompt, line_buffer, sizeof(line_buffer), NULL);
    342     if (sz <= 0)
    343         exit(0); /* Ctrl-D or Ctrl-C */
    344 
    345     if (line_buffer[sz-1] == '\n')
    346         line_buffer[--sz] = '\0';
    347 
    348     line_ptr = line_buffer;
    349     while (*line_ptr && !isgraph(*line_ptr))
    350         line_ptr++;
    351     return *line_ptr;
    352 }
    353 #endif
     453static void
     454close_dev_fd(void)
     455{
     456    /* Not really closing, but making sure it is open, and to harmless place */
     457    xmove_fd(xopen(bb_dev_null, O_RDONLY), dev_fd);
     458}
    354459
    355460/*
    356  * return partition name - uses static storage
     461 * Return partition name - uses static storage
    357462 */
    358463static const char *
     
    384489    if (lth) {
    385490        snprintf(bufp, bufsiz, "%*.*s%s%-2u",
    386              lth-wp-2, w, dev, p, pno);
     491            lth-wp-2, w, dev, p, pno);
    387492    } else {
    388493        snprintf(bufp, bufsiz, "%.*s%s%-2u", w, dev, p, pno);
     
    390495    return bufp;
    391496}
    392 
    393 #if ENABLE_FEATURE_FDISK_WRITABLE
    394 static void
    395 set_all_unchanged(void)
    396 {
    397     int i;
    398 
    399     for (i = 0; i < MAXIMUM_PARTS; i++)
    400         ptes[i].changed = 0;
    401 }
    402 
    403 static ALWAYS_INLINE void
    404 set_changed(int i)
    405 {
    406     ptes[i].changed = 1;
    407 }
    408 #endif /* FEATURE_FDISK_WRITABLE */
    409497
    410498static ALWAYS_INLINE struct partition *
     
    428516}
    429517
     518static void fdisk_fatal(const char *why)
     519{
     520    if (listing) {
     521        close_dev_fd();
     522        longjmp(listingbuf, 1);
     523    }
     524    bb_error_msg_and_die(why, disk_device);
     525}
     526
     527static void
     528seek_sector(sector_t secno)
     529{
     530#if ENABLE_FDISK_SUPPORT_LARGE_DISKS
     531    off64_t off = (off64_t)secno * sector_size;
     532    if (lseek64(dev_fd, off, SEEK_SET) == (off64_t) -1)
     533        fdisk_fatal(unable_to_seek);
     534#else
     535    uint64_t off = (uint64_t)secno * sector_size;
     536    if (off > MAXINT(off_t)
     537     || lseek(dev_fd, (off_t)off, SEEK_SET) == (off_t) -1
     538    ) {
     539        fdisk_fatal(unable_to_seek);
     540    }
     541#endif
     542}
     543
    430544#if ENABLE_FEATURE_FDISK_WRITABLE
     545/* Read line; return 0 or first printable char */
     546static int
     547read_line(const char *prompt)
     548{
     549    int sz;
     550
     551    sz = read_line_input(prompt, line_buffer, sizeof(line_buffer), NULL);
     552    if (sz <= 0)
     553        exit(EXIT_SUCCESS); /* Ctrl-D or Ctrl-C */
     554
     555    if (line_buffer[sz-1] == '\n')
     556        line_buffer[--sz] = '\0';
     557
     558    line_ptr = line_buffer;
     559    while (*line_ptr != '\0' && (unsigned char)*line_ptr <= ' ')
     560        line_ptr++;
     561    return *line_ptr;
     562}
     563
     564static void
     565set_all_unchanged(void)
     566{
     567    int i;
     568
     569    for (i = 0; i < MAXIMUM_PARTS; i++)
     570        ptes[i].changed = 0;
     571}
     572
     573static ALWAYS_INLINE void
     574set_changed(int i)
     575{
     576    ptes[i].changed = 1;
     577}
     578
    431579static ALWAYS_INLINE void
    432580write_part_table_flag(char *b)
     
    439587read_nonempty(const char *mesg)
    440588{
    441     while (!read_line(mesg)) /* repeat */;
     589    while (!read_line(mesg))
     590        continue;
    442591    return *line_ptr;
    443592}
     
    460609    while (1) {
    461610        read_nonempty("Hex code (type L to list codes): ");
    462         if (*line_ptr == 'l' || *line_ptr == 'L') {
     611        if ((line_ptr[0] | 0x20) == 'l') {
    463612            list_types(sys);
    464613            continue;
    465614        }
    466615        v = bb_strtoul(line_ptr, NULL, 16);
    467         if (v > 0xff)
    468             /* Bad input also triggers this */
    469             continue;
    470         return v;
    471     }
     616        if (v <= 0xff)
     617            return v;
     618    }
     619}
     620
     621static void
     622write_sector(sector_t secno, const void *buf)
     623{
     624    seek_sector(secno);
     625    xwrite(dev_fd, buf, sector_size);
    472626}
    473627#endif /* FEATURE_FDISK_WRITABLE */
    474628
     629
    475630#include "fdisk_aix.c"
    476631
    477 typedef struct {
     632struct sun_partition {
    478633    unsigned char info[128];   /* Informative text string */
    479634    unsigned char spare0[14];
     
    501656    unsigned short magic;      /* Magic number */
    502657    unsigned short csum;       /* Label xor'd checksum */
    503 } sun_partition;
     658} FIX_ALIASING;
     659typedef struct sun_partition sun_partition;
    504660#define sunlabel ((sun_partition *)MBRbuffer)
    505661STATIC_OSF void bsd_select(void);
    506662STATIC_OSF void xbsd_print_disklabel(int);
    507663#include "fdisk_osf.c"
     664
     665STATIC_GPT void gpt_list_table(int xtra);
     666#include "fdisk_gpt.c"
    508667
    509668#if ENABLE_FEATURE_SGI_LABEL || ENABLE_FEATURE_SUN_LABEL
     
    561720#include "fdisk_sun.c"
    562721
     722
     723static inline_if_little_endian unsigned
     724read4_little_endian(const unsigned char *cp)
     725{
     726    uint32_t v;
     727    move_from_unaligned32(v, cp);
     728    return SWAP_LE32(v);
     729}
     730
     731static sector_t
     732get_start_sect(const struct partition *p)
     733{
     734    return read4_little_endian(p->start4);
     735}
     736
     737static sector_t
     738get_nr_sects(const struct partition *p)
     739{
     740    return read4_little_endian(p->size4);
     741}
     742
    563743#if ENABLE_FEATURE_FDISK_WRITABLE
    564744/* start_sect and nr_sects are stored little endian on all machines */
    565745/* moreover, they are not aligned correctly */
    566 static void
     746static inline_if_little_endian void
    567747store4_little_endian(unsigned char *cp, unsigned val)
    568748{
    569     cp[0] = val;
    570     cp[1] = val >> 8;
    571     cp[2] = val >> 16;
    572     cp[3] = val >> 24;
    573 }
    574 #endif /* FEATURE_FDISK_WRITABLE */
    575 
    576 static unsigned
    577 read4_little_endian(const unsigned char *cp)
    578 {
    579     return cp[0] + (cp[1] << 8) + (cp[2] << 16) + (cp[3] << 24);
    580 }
    581 
    582 #if ENABLE_FEATURE_FDISK_WRITABLE
     749    uint32_t v = SWAP_LE32(val);
     750    move_to_unaligned32(cp, v);
     751}
     752
    583753static void
    584754set_start_sect(struct partition *p, unsigned start_sect)
     
    586756    store4_little_endian(p->start4, start_sect);
    587757}
    588 #endif
    589 
    590 static unsigned
    591 get_start_sect(const struct partition *p)
    592 {
    593     return read4_little_endian(p->start4);
    594 }
    595 
    596 #if ENABLE_FEATURE_FDISK_WRITABLE
     758
    597759static void
    598760set_nr_sects(struct partition *p, unsigned nr_sects)
     
    602764#endif
    603765
    604 static unsigned
    605 get_nr_sects(const struct partition *p)
    606 {
    607     return read4_little_endian(p->size4);
    608 }
    609 
    610 /* normally O_RDWR, -l option gives O_RDONLY */
    611 static int type_open = O_RDWR;
    612 
    613 static int ext_index;               /* the prime extended partition */
    614 static int listing;                 /* no aborts for fdisk -l */
    615 static int dos_compatible_flag = ~0;
    616 #if ENABLE_FEATURE_FDISK_WRITABLE
    617 static int dos_changed;
    618 static int nowarn;            /* no warnings for fdisk -l/-s */
    619 #endif
    620 
    621 static unsigned user_cylinders, user_heads, user_sectors;
    622 static unsigned pt_heads, pt_sectors;
    623 static unsigned kern_heads, kern_sectors;
    624 
    625 static ullong extended_offset;            /* offset of link pointers */
    626 static ullong total_number_of_sectors;
    627 
    628 static void fdisk_fatal(const char *why)
    629 {
    630     if (listing) {
    631         close(fd);
    632         longjmp(listingbuf, 1);
    633     }
    634     bb_error_msg_and_die(why, disk_device);
    635 }
    636 
    637 static void
    638 seek_sector(ullong secno)
    639 {
    640     secno *= sector_size;
    641 #if ENABLE_FDISK_SUPPORT_LARGE_DISKS
    642     if (lseek64(fd, (off64_t)secno, SEEK_SET) == (off64_t) -1)
    643         fdisk_fatal(unable_to_seek);
    644 #else
    645     if (secno > MAXINT(off_t)
    646      || lseek(fd, (off_t)secno, SEEK_SET) == (off_t) -1
    647     ) {
    648         fdisk_fatal(unable_to_seek);
    649     }
    650 #endif
    651 }
    652 
    653 #if ENABLE_FEATURE_FDISK_WRITABLE
    654 static void
    655 write_sector(ullong secno, char *buf)
    656 {
    657     seek_sector(secno);
    658     if (write(fd, buf, sector_size) != sector_size)
    659         fdisk_fatal(unable_to_write);
    660 }
    661 #endif
    662 
    663766/* Allocate a buffer and read a partition table sector */
    664767static void
    665 read_pte(struct pte *pe, ullong offset)
    666 {
    667     pe->offset = offset;
    668     pe->sectorbuffer = xmalloc(sector_size);
     768read_pte(struct pte *pe, sector_t offset)
     769{
     770    pe->offset_from_dev_start = offset;
     771    pe->sectorbuffer = xzalloc(sector_size);
    669772    seek_sector(offset);
    670     if (read(fd, pe->sectorbuffer, sector_size) != sector_size)
     773    /* xread would make us abort - bad for fdisk -l */
     774    if (full_read(dev_fd, pe->sectorbuffer, sector_size) != sector_size)
    671775        fdisk_fatal(unable_to_read);
    672776#if ENABLE_FEATURE_FDISK_WRITABLE
     
    676780}
    677781
    678 static unsigned
    679 get_partition_start(const struct pte *pe)
    680 {
    681     return pe->offset + get_start_sect(pe->part_table);
     782static sector_t
     783get_partition_start_from_dev_start(const struct pte *pe)
     784{
     785    return pe->offset_from_dev_start + get_start_sect(pe->part_table);
    682786}
    683787
     
    689793 * for "is probably nondos partition".
    690794 */
     795#ifdef UNUSED
    691796static int
    692797is_dos_partition(int t)
     
    698803        t == 0xc1 || t == 0xc4 || t == 0xc6);
    699804}
     805#endif
    700806
    701807static void
     
    738844    } else if (LABEL_IS_AIX) {
    739845        puts("o\tcreate a new empty DOS partition table");
     846        puts("q\tquit without saving changes");
     847        puts("s\tcreate a new empty Sun disklabel");  /* sun */
     848    } else if (LABEL_IS_GPT) {
     849        puts("o\tcreate a new empty DOS partition table");
     850        puts("p\tprint the partition table");
    740851        puts("q\tquit without saving changes");
    741852        puts("s\tcreate a new empty Sun disklabel");  /* sun */
     
    840951#else
    841952#define get_sys_types() i386_sys_types
    842 #endif /* FEATURE_FDISK_WRITABLE */
     953#endif
    843954
    844955static const char *
     
    855966}
    856967
     968static int
     969is_cleared_partition(const struct partition *p)
     970{
     971    /* We consider partition "cleared" only if it has only zeros */
     972    const char *cp = (const char *)p;
     973    int cnt = sizeof(*p);
     974    char bits = 0;
     975    while (--cnt >= 0)
     976        bits |= *cp++;
     977    return (bits == 0);
     978}
     979
     980static void
     981clear_partition(struct partition *p)
     982{
     983    if (p)
     984        memset(p, 0, sizeof(*p));
     985}
    857986
    858987#if ENABLE_FEATURE_FDISK_WRITABLE
     
    8741003    int i;
    8751004
    876     for (size = 0; sys[size]; size++) /* */;
     1005    for (size = 0; sys[size]; size++)
     1006        continue;
    8771007
    8781008    done = 0;
     
    8931023        }
    8941024    } while (done < last[0]);
    895     putchar('\n');
    896 }
    897 #endif /* FEATURE_FDISK_WRITABLE */
    898 
    899 static int
    900 is_cleared_partition(const struct partition *p)
    901 {
    902     return !(!p || p->boot_ind || p->head || p->sector || p->cyl ||
    903          p->sys_ind || p->end_head || p->end_sector || p->end_cyl ||
    904          get_start_sect(p) || get_nr_sects(p));
    905 }
    906 
    907 static void
    908 clear_partition(struct partition *p)
    909 {
    910     if (!p)
    911         return;
    912     memset(p, 0, sizeof(struct partition));
    913 }
    914 
    915 #if ENABLE_FEATURE_FDISK_WRITABLE
    916 static void
    917 set_partition(int i, int doext, ullong start, ullong stop, int sysid)
     1025    bb_putchar('\n');
     1026}
     1027
     1028#define set_hsc(h, s, c, sector) do \
     1029{ \
     1030    s = sector % g_sectors + 1;  \
     1031    sector /= g_sectors;         \
     1032    h = sector % g_heads;        \
     1033    sector /= g_heads;           \
     1034    c = sector & 0xff;           \
     1035    s |= (sector >> 2) & 0xc0;   \
     1036} while (0)
     1037
     1038static void set_hsc_start_end(struct partition *p, sector_t start, sector_t stop)
     1039{
     1040    if (dos_compatible_flag && (start / (g_sectors * g_heads) > 1023))
     1041        start = g_heads * g_sectors * 1024 - 1;
     1042    set_hsc(p->head, p->sector, p->cyl, start);
     1043
     1044    if (dos_compatible_flag && (stop / (g_sectors * g_heads) > 1023))
     1045        stop = g_heads * g_sectors * 1024 - 1;
     1046    set_hsc(p->end_head, p->end_sector, p->end_cyl, stop);
     1047}
     1048
     1049static void
     1050set_partition(int i, int doext, sector_t start, sector_t stop, int sysid)
    9181051{
    9191052    struct partition *p;
    920     ullong offset;
     1053    sector_t offset;
    9211054
    9221055    if (doext) {
     
    9251058    } else {
    9261059        p = ptes[i].part_table;
    927         offset = ptes[i].offset;
     1060        offset = ptes[i].offset_from_dev_start;
    9281061    }
    9291062    p->boot_ind = 0;
     
    9311064    set_start_sect(p, start - offset);
    9321065    set_nr_sects(p, stop - start + 1);
    933     if (dos_compatible_flag && (start/(sectors*heads) > 1023))
    934         start = heads*sectors*1024 - 1;
    935     set_hsc(p->head, p->sector, p->cyl, start);
    936     if (dos_compatible_flag && (stop/(sectors*heads) > 1023))
    937         stop = heads*sectors*1024 - 1;
    938     set_hsc(p->end_head, p->end_sector, p->end_cyl, stop);
     1066    set_hsc_start_end(p, start, stop);
    9391067    ptes[i].changed = 1;
    9401068}
     
    9441072warn_geometry(void)
    9451073{
    946     if (heads && sectors && cylinders)
     1074    if (g_heads && g_sectors && g_cylinders)
    9471075        return 0;
    9481076
    9491077    printf("Unknown value(s) for:");
    950     if (!heads)
     1078    if (!g_heads)
    9511079        printf(" heads");
    952     if (!sectors)
     1080    if (!g_sectors)
    9531081        printf(" sectors");
    954     if (!cylinders)
     1082    if (!g_cylinders)
    9551083        printf(" cylinders");
    9561084    printf(
     
    9651093update_units(void)
    9661094{
    967     int cyl_units = heads * sectors;
     1095    int cyl_units = g_heads * g_sectors;
    9681096
    9691097    if (display_in_cyl_units && cyl_units)
     
    9771105warn_cylinders(void)
    9781106{
    979     if (LABEL_IS_DOS && cylinders > 1024 && !nowarn)
     1107    if (LABEL_IS_DOS && g_cylinders > 1024 && !nowarn)
    9801108        printf("\n"
    981 "The number of cylinders for this disk is set to %d.\n"
     1109"The number of cylinders for this disk is set to %u.\n"
    9821110"There is nothing wrong with that, but this is larger than 1024,\n"
    9831111"and could in certain setups cause problems with:\n"
     
    9851113"2) booting and partitioning software from other OSs\n"
    9861114"   (e.g., DOS FDISK, OS/2 FDISK)\n",
    987             cylinders);
     1115            g_cylinders);
    9881116}
    9891117#endif
     
    10071135
    10081136    while (IS_EXTENDED(p->sys_ind)) {
    1009         struct pte *pe = &ptes[partitions];
    1010 
    1011         if (partitions >= MAXIMUM_PARTS) {
     1137        struct pte *pe = &ptes[g_partitions];
     1138
     1139        if (g_partitions >= MAXIMUM_PARTS) {
    10121140            /* This is not a Linux restriction, but
    10131141               this program uses arrays of size MAXIMUM_PARTS.
    10141142               Do not try to 'improve' this test. */
    1015             struct pte *pre = &ptes[partitions-1];
     1143            struct pte *pre = &ptes[g_partitions - 1];
    10161144#if ENABLE_FEATURE_FDISK_WRITABLE
    1017             printf("Warning: deleting partitions after %d\n",
    1018                 partitions);
     1145            printf("Warning: deleting partitions after %u\n",
     1146                g_partitions);
    10191147            pre->changed = 1;
    10201148#endif
     
    10341162                    printf("Warning: extra link "
    10351163                        "pointer in partition table"
    1036                         " %d\n", partitions + 1);
     1164                        " %u\n", g_partitions + 1);
    10371165                else
    10381166                    pe->ext_pointer = p;
     
    10411169                    printf("Warning: ignoring extra "
    10421170                          "data in partition table"
    1043                           " %d\n", partitions + 1);
     1171                          " %u\n", g_partitions + 1);
    10441172                else
    10451173                    pe->part_table = p;
     
    10621190
    10631191        p = pe->ext_pointer;
    1064         partitions++;
     1192        g_partitions++;
    10651193    }
    10661194
     
    10681196    /* remove empty links */
    10691197 remove:
    1070     for (i = 4; i < partitions; i++) {
     1198    for (i = 4; i < g_partitions; i++) {
    10711199        struct pte *pe = &ptes[i];
    10721200
    10731201        if (!get_nr_sects(pe->part_table)
    1074          && (partitions > 5 || ptes[4].part_table->sys_ind)
     1202         && (g_partitions > 5 || ptes[4].part_table->sys_ind)
    10751203        ) {
    1076             printf("Omitting empty partition (%d)\n", i+1);
     1204            printf("Omitting empty partition (%u)\n", i+1);
    10771205            delete_partition(i);
    10781206            goto remove;    /* numbering changed */
     
    10861214create_doslabel(void)
    10871215{
    1088     int i;
    1089 
    10901216    printf(msg_building_new_label, "DOS disklabel");
    10911217
    1092     current_label_type = label_dos;
    1093 
     1218    current_label_type = LABEL_DOS;
    10941219#if ENABLE_FEATURE_OSF_LABEL
    10951220    possibly_osf_label = 0;
    10961221#endif
    1097     partitions = 4;
    1098 
    1099     for (i = 510-64; i < 510; i++)
    1100         MBRbuffer[i] = 0;
     1222    g_partitions = 4;
     1223
     1224    memset(&MBRbuffer[510 - 4*16], 0, 4*16);
    11011225    write_part_table_flag(MBRbuffer);
    11021226    extended_offset = 0;
    11031227    set_all_unchanged();
    11041228    set_changed(0);
    1105     get_boot(create_empty_dos);
    1106 }
    1107 #endif /* FEATURE_FDISK_WRITABLE */
     1229    get_boot(CREATE_EMPTY_DOS);
     1230}
     1231#endif
    11081232
    11091233static void
     
    11121236    if (!user_set_sector_size) {
    11131237        int arg;
    1114         if (ioctl(fd, BLKSSZGET, &arg) == 0)
     1238        if (ioctl(dev_fd, BLKSSZGET, &arg) == 0)
    11151239            sector_size = arg;
    11161240        if (sector_size != DEFAULT_SECTOR_SIZE)
    1117             printf("Note: sector size is %d (not %d)\n",
    1118                    sector_size, DEFAULT_SECTOR_SIZE);
     1241            printf("Note: sector size is %u "
     1242                "(not " DEFAULT_SECTOR_SIZE_STR ")\n",
     1243                sector_size);
    11191244    }
    11201245}
     
    11251250    struct hd_geometry geometry;
    11261251
    1127     if (!ioctl(fd, HDIO_GETGEO, &geometry)) {
     1252    if (!ioctl(dev_fd, HDIO_GETGEO, &geometry)) {
    11281253        kern_heads = geometry.heads;
    11291254        kern_sectors = geometry.sectors;
     
    11691294{
    11701295    int sec_fac;
    1171     uint64_t v64;
    11721296
    11731297    get_sectorsize();
     
    11761300    guess_device_type();
    11771301#endif
    1178     heads = cylinders = sectors = 0;
     1302    g_heads = g_cylinders = g_sectors = 0;
    11791303    kern_heads = kern_sectors = 0;
    11801304    pt_heads = pt_sectors = 0;
     
    11831307    get_partition_table_geometry();
    11841308
    1185     heads = user_heads ? user_heads :
     1309    g_heads = user_heads ? user_heads :
    11861310        pt_heads ? pt_heads :
    11871311        kern_heads ? kern_heads : 255;
    1188     sectors = user_sectors ? user_sectors :
     1312    g_sectors = user_sectors ? user_sectors :
    11891313        pt_sectors ? pt_sectors :
    11901314        kern_sectors ? kern_sectors : 63;
    1191     if (ioctl(fd, BLKGETSIZE64, &v64) == 0) {
    1192         /* got bytes, convert to 512 byte sectors */
    1193         total_number_of_sectors = (v64 >> 9);
    1194     } else {
    1195         unsigned long longsectors; /* need temp of type long */
    1196         if (ioctl(fd, BLKGETSIZE, &longsectors))
    1197             longsectors = 0;
    1198         total_number_of_sectors = longsectors;
    1199     }
     1315    total_number_of_sectors = bb_BLKGETSIZE_sectors(dev_fd);
    12001316
    12011317    sector_offset = 1;
    12021318    if (dos_compatible_flag)
    1203         sector_offset = sectors;
    1204 
    1205     cylinders = total_number_of_sectors / (heads * sectors * sec_fac);
    1206     if (!cylinders)
    1207         cylinders = user_cylinders;
     1319        sector_offset = g_sectors;
     1320
     1321    g_cylinders = total_number_of_sectors / (g_heads * g_sectors * sec_fac);
     1322    if (!g_cylinders)
     1323        g_cylinders = user_cylinders;
    12081324}
    12091325
    12101326/*
    1211  * Read MBR.  Returns:
     1327 * Opens disk_device and optionally reads MBR.
     1328 *    If what == OPEN_MAIN:
     1329 *      Open device, read MBR.  Abort program on short read.  Create empty
     1330 *      disklabel if the on-disk structure is invalid (WRITABLE mode).
     1331 *    If what == TRY_ONLY:
     1332 *      Open device, read MBR.  Return an error if anything is out of place.
     1333 *      Do not create an empty disklabel.  This is used for the "list"
     1334 *      operations: "fdisk -l /dev/sda" and "fdisk -l" (all devices).
     1335 *    If what == CREATE_EMPTY_*:
     1336 *      This means that get_boot() was called recursively from create_*label().
     1337 *      Do not re-open the device; just set up the ptes array and print
     1338 *      geometry warnings.
     1339 *
     1340 * Returns:
    12121341 *   -1: no 0xaa55 flag present (possibly entire disk BSD)
    12131342 *    0: found or created label
    12141343 *    1: I/O error
    12151344 */
    1216 static int
    1217 get_boot(enum action what)
    1218 {
    1219     int i;
    1220 
    1221     partitions = 4;
    1222 
     1345#if ENABLE_FEATURE_SUN_LABEL || ENABLE_FEATURE_FDISK_WRITABLE
     1346static int get_boot(enum action what)
     1347#else
     1348static int get_boot(void)
     1349#define get_boot(what) get_boot()
     1350#endif
     1351{
     1352    int i, fd;
     1353
     1354    g_partitions = 4;
    12231355    for (i = 0; i < 4; i++) {
    12241356        struct pte *pe = &ptes[i];
    1225 
    12261357        pe->part_table = pt_offset(MBRbuffer, i);
    12271358        pe->ext_pointer = NULL;
    1228         pe->offset = 0;
     1359        pe->offset_from_dev_start = 0;
    12291360        pe->sectorbuffer = MBRbuffer;
    12301361#if ENABLE_FEATURE_FDISK_WRITABLE
    1231         pe->changed = (what == create_empty_dos);
    1232 #endif
    1233     }
    1234 
    1235 #if ENABLE_FEATURE_SUN_LABEL
    1236     if (what == create_empty_sun && check_sun_label())
    1237         return 0;
    1238 #endif
    1239 
    1240     memset(MBRbuffer, 0, 512);
     1362        pe->changed = (what == CREATE_EMPTY_DOS);
     1363#endif
     1364    }
    12411365
    12421366#if ENABLE_FEATURE_FDISK_WRITABLE
    1243     if (what == create_empty_dos)
    1244         goto got_dos_table;             /* skip reading disk */
    1245 
    1246     fd = open(disk_device, type_open);
     1367// ALERT! highly idiotic design!
     1368// We end up here when we call get_boot() recursively
     1369// via get_boot() [table is bad] -> create_doslabel() -> get_boot(CREATE_EMPTY_DOS).
     1370// or get_boot() [table is bad] -> create_sunlabel() -> get_boot(CREATE_EMPTY_SUN).
     1371// (just factor out re-init of ptes[0,1,2,3] in a separate fn instead?)
     1372// So skip opening device _again_...
     1373    if (what == CREATE_EMPTY_DOS  IF_FEATURE_SUN_LABEL(|| what == CREATE_EMPTY_SUN))
     1374        goto created_table;
     1375
     1376    fd = open(disk_device, (option_mask32 & OPT_l) ? O_RDONLY : O_RDWR);
     1377
    12471378    if (fd < 0) {
    12481379        fd = open(disk_device, O_RDONLY);
    12491380        if (fd < 0) {
    1250             if (what == try_only)
     1381            if (what == TRY_ONLY)
    12511382                return 1;
    12521383            fdisk_fatal(unable_to_open);
    1253         } else
    1254             printf("You will not be able to write "
    1255                 "the partition table\n");
    1256     }
    1257 
    1258     if (512 != read(fd, MBRbuffer, 512)) {
    1259         if (what == try_only)
     1384        }
     1385        printf("'%s' is opened for read only\n", disk_device);
     1386    }
     1387    xmove_fd(fd, dev_fd);
     1388    if (512 != full_read(dev_fd, MBRbuffer, 512)) {
     1389        if (what == TRY_ONLY) {
     1390            close_dev_fd();
    12601391            return 1;
     1392        }
    12611393        fdisk_fatal(unable_to_read);
    12621394    }
     
    12651397    if (fd < 0)
    12661398        return 1;
    1267     if (512 != read(fd, MBRbuffer, 512))
     1399    if (512 != full_read(fd, MBRbuffer, 512)) {
     1400        close(fd);
    12681401        return 1;
     1402    }
     1403    xmove_fd(fd, dev_fd);
    12691404#endif
    12701405
    12711406    get_geometry();
    1272 
    12731407    update_units();
    12741408
     
    12771411        return 0;
    12781412#endif
    1279 
    12801413#if ENABLE_FEATURE_SGI_LABEL
    12811414    if (check_sgi_label())
    12821415        return 0;
    12831416#endif
    1284 
    12851417#if ENABLE_FEATURE_AIX_LABEL
    12861418    if (check_aix_label())
    12871419        return 0;
    12881420#endif
    1289 
     1421#if ENABLE_FEATURE_GPT_LABEL
     1422    if (check_gpt_label())
     1423        return 0;
     1424#endif
    12901425#if ENABLE_FEATURE_OSF_LABEL
    12911426    if (check_osf_label()) {
    12921427        possibly_osf_label = 1;
    12931428        if (!valid_part_table_flag(MBRbuffer)) {
    1294             current_label_type = label_osf;
     1429            current_label_type = LABEL_OSF;
    12951430            return 0;
    12961431        }
     
    13001435#endif
    13011436
    1302 #if ENABLE_FEATURE_FDISK_WRITABLE
    1303  got_dos_table:
    1304 #endif
    1305 
    1306     if (!valid_part_table_flag(MBRbuffer)) {
    13071437#if !ENABLE_FEATURE_FDISK_WRITABLE
     1438    if (!valid_part_table_flag(MBRbuffer))
    13081439        return -1;
    13091440#else
    1310         switch (what) {
    1311         case fdisk:
     1441    if (!valid_part_table_flag(MBRbuffer)) {
     1442        if (what == OPEN_MAIN) {
    13121443            printf("Device contains neither a valid DOS "
    1313                   "partition table, nor Sun, SGI or OSF "
     1444                  "partition table, nor Sun, SGI, OSF or GPT "
    13141445                  "disklabel\n");
    13151446#ifdef __sparc__
    1316 #if ENABLE_FEATURE_SUN_LABEL
    1317             create_sunlabel();
    1318 #endif
     1447            IF_FEATURE_SUN_LABEL(create_sunlabel();)
    13191448#else
    13201449            create_doslabel();
    13211450#endif
    13221451            return 0;
    1323         case try_only:
    1324             return -1;
    1325         case create_empty_dos:
    1326 #if ENABLE_FEATURE_SUN_LABEL
    1327         case create_empty_sun:
    1328 #endif
    1329             break;
    1330         default:
    1331             bb_error_msg_and_die("internal error");
    1332         }
     1452        }
     1453        /* TRY_ONLY: */
     1454        return -1;
     1455    }
     1456 created_table:
    13331457#endif /* FEATURE_FDISK_WRITABLE */
    1334     }
    1335 
    1336 #if ENABLE_FEATURE_FDISK_WRITABLE
    1337     warn_cylinders();
    1338 #endif
     1458
     1459
     1460    IF_FEATURE_FDISK_WRITABLE(warn_cylinders();)
    13391461    warn_geometry();
    13401462
    13411463    for (i = 0; i < 4; i++) {
    1342         struct pte *pe = &ptes[i];
    1343 
    1344         if (IS_EXTENDED(pe->part_table->sys_ind)) {
    1345             if (partitions != 4)
     1464        if (IS_EXTENDED(ptes[i].part_table->sys_ind)) {
     1465            if (g_partitions != 4)
    13461466                printf("Ignoring extra extended "
    1347                     "partition %d\n", i + 1);
     1467                    "partition %u\n", i + 1);
    13481468            else
    13491469                read_extended(i);
     
    13511471    }
    13521472
    1353     for (i = 3; i < partitions; i++) {
     1473    for (i = 3; i < g_partitions; i++) {
    13541474        struct pte *pe = &ptes[i];
    1355 
    13561475        if (!valid_part_table_flag(pe->sectorbuffer)) {
    13571476            printf("Warning: invalid flag 0x%02x,0x%02x of partition "
    1358                 "table %d will be corrected by w(rite)\n",
     1477                "table %u will be corrected by w(rite)\n",
    13591478                pe->sectorbuffer[510],
    13601479                pe->sectorbuffer[511],
    13611480                i + 1);
    1362 #if ENABLE_FEATURE_FDISK_WRITABLE
    1363             pe->changed = 1;
    1364 #endif
     1481            IF_FEATURE_FDISK_WRITABLE(pe->changed = 1;)
    13651482        }
    13661483    }
     
    13771494 * There is no default if DFLT is not between LOW and HIGH.
    13781495 */
    1379 static unsigned
    1380 read_int(unsigned low, unsigned dflt, unsigned high, unsigned base, const char *mesg)
    1381 {
    1382     unsigned i;
     1496static sector_t
     1497read_int(sector_t low, sector_t dflt, sector_t high, sector_t base, const char *mesg)
     1498{
     1499    sector_t value;
    13831500    int default_ok = 1;
    13841501    const char *fmt = "%s (%u-%u, default %u): ";
     
    14031520            int absolute = 0;
    14041521
    1405             i = atoi(line_ptr + 1);
    1406 
     1522            value = atoi(line_ptr + 1);
     1523
     1524            /* (1) if 2nd char is digit, use_default = 0.
     1525             * (2) move line_ptr to first non-digit. */
    14071526            while (isdigit(*++line_ptr))
    14081527                use_default = 0;
     
    14121531            case 'C':
    14131532                if (!display_in_cyl_units)
    1414                     i *= heads * sectors;
     1533                    value *= g_heads * g_sectors;
    14151534                break;
    14161535            case 'K':
     
    14351554                unsigned long unit;
    14361555
    1437                 bytes = (ullong) i * absolute;
     1556                bytes = (ullong) value * absolute;
    14381557                unit = sector_size * units_per_sector;
    14391558                bytes += unit/2; /* round */
    14401559                bytes /= unit;
    1441                 i = bytes;
     1560                value = bytes;
    14421561            }
    14431562            if (minus)
    1444                 i = -i;
    1445             i += base;
     1563                value = -value;
     1564            value += base;
    14461565        } else {
    1447             i = atoi(line_ptr);
     1566            value = atoi(line_ptr);
    14481567            while (isdigit(*line_ptr)) {
    14491568                line_ptr++;
     
    14521571        }
    14531572        if (use_default) {
    1454             i = dflt;
    1455             printf("Using default value %u\n", i);
    1456         }
    1457         if (i >= low && i <= high)
     1573            value = dflt;
     1574            printf("Using default value %u\n", value);
     1575        }
     1576        if (value >= low && value <= high)
    14581577            break;
    14591578        printf("Value is out of range\n");
    14601579    }
    1461     return i;
    1462 }
    1463 
    1464 static int
    1465 get_partition(int warn, int max)
     1580    return value;
     1581}
     1582
     1583static unsigned
     1584get_partition(int warn, unsigned max)
    14661585{
    14671586    struct pte *pe;
    1468     int i;
     1587    unsigned i;
    14691588
    14701589    i = read_int(1, 0, max, 0, "Partition number") - 1;
     
    14761595         || (LABEL_IS_SGI && !sgi_get_num_sectors(i))
    14771596        ) {
    1478             printf("Warning: partition %d has empty type\n", i+1);
     1597            printf("Warning: partition %u has empty type\n", i+1);
    14791598        }
    14801599    }
     
    14831602
    14841603static int
    1485 get_existing_partition(int warn, int max)
     1604get_existing_partition(int warn, unsigned max)
    14861605{
    14871606    int pno = -1;
    1488     int i;
     1607    unsigned i;
    14891608
    14901609    for (i = 0; i < max; i++) {
     
    14991618    }
    15001619    if (pno >= 0) {
    1501         printf("Selected partition %d\n", pno+1);
     1620        printf("Selected partition %u\n", pno+1);
    15021621        return pno;
    15031622    }
     
    15101629
    15111630static int
    1512 get_nonexisting_partition(int warn, int max)
     1631get_nonexisting_partition(int warn, unsigned max)
    15131632{
    15141633    int pno = -1;
    1515     int i;
     1634    unsigned i;
    15161635
    15171636    for (i = 0; i < max; i++) {
     
    15261645    }
    15271646    if (pno >= 0) {
    1528         printf("Selected partition %d\n", pno+1);
     1647        printf("Selected partition %u\n", pno+1);
    15291648        return pno;
    15301649    }
     
    15531672
    15541673    if (IS_EXTENDED(p->sys_ind) && !p->boot_ind)
    1555         printf("WARNING: Partition %d is an extended partition\n", i + 1);
     1674        printf("WARNING: Partition %u is an extended partition\n", i + 1);
    15561675    p->boot_ind = (p->boot_ind ? 0 : ACTIVE_FLAG);
    15571676    pe->changed = 1;
     
    15611680toggle_dos_compatibility_flag(void)
    15621681{
    1563     dos_compatible_flag = ~dos_compatible_flag;
     1682    dos_compatible_flag = 1 - dos_compatible_flag;
    15641683    if (dos_compatible_flag) {
    1565         sector_offset = sectors;
     1684        sector_offset = g_sectors;
    15661685        printf("DOS Compatibility flag is set\n");
    15671686    } else {
     
    15971716    if (i < 4) {
    15981717        if (IS_EXTENDED(p->sys_ind) && i == ext_index) {
    1599             partitions = 4;
     1718            g_partitions = 4;
    16001719            ptes[ext_index].ext_pointer = NULL;
    16011720            extended_offset = 0;
     
    16071726    if (!q->sys_ind && i > 4) {
    16081727        /* the last one in the chain - just delete */
    1609         --partitions;
     1728        --g_partitions;
    16101729        --i;
    16111730        clear_partition(ptes[i].ext_pointer);
     
    16201739            set_nr_sects(p, get_nr_sects(q));
    16211740            ptes[i-1].changed = 1;
    1622         } else if (partitions > 5) {    /* 5 will be moved to 4 */
     1741        } else if (g_partitions > 5) {    /* 5 will be moved to 4 */
    16231742            /* the first logical in a longer chain */
    16241743            pe = &ptes[5];
     
    16261745            if (pe->part_table) /* prevent SEGFAULT */
    16271746                set_start_sect(pe->part_table,
    1628                            get_partition_start(pe) -
    1629                            extended_offset);
    1630             pe->offset = extended_offset;
     1747                        get_partition_start_from_dev_start(pe) -
     1748                        extended_offset);
     1749            pe->offset_from_dev_start = extended_offset;
    16311750            pe->changed = 1;
    16321751        }
    16331752
    1634         if (partitions > 5) {
    1635             partitions--;
    1636             while (i < partitions) {
     1753        if (g_partitions > 5) {
     1754            g_partitions--;
     1755            while (i < g_partitions) {
    16371756                ptes[i] = ptes[i+1];
    16381757                i++;
    16391758            }
    1640         } else
     1759        } else {
    16411760            /* the only logical: clear only */
    16421761            clear_partition(ptes[i].part_table);
     1762        }
    16431763    }
    16441764}
     
    16541774       only works for Linux like partition tables. */
    16551775    if (!LABEL_IS_SGI) {
    1656         i = get_existing_partition(0, partitions);
     1776        i = get_existing_partition(0, g_partitions);
    16571777    } else {
    1658         i = get_partition(0, partitions);
     1778        i = get_partition(0, g_partitions);
    16591779    }
    16601780    if (i == -1)
     
    16661786       the reverse change must be allowed, too */
    16671787    if (!sys && !LABEL_IS_SGI && !LABEL_IS_SUN && !get_nr_sects(p)) {
    1668         printf("Partition %d does not exist yet!\n", i + 1);
     1788        printf("Partition %u does not exist yet!\n", i + 1);
    16691789        return;
    16701790    }
     
    17171837                p->sys_ind = sys;
    17181838
    1719             printf("Changed system type of partition %d "
     1839            printf("Changed system type of partition %u "
    17201840                "to %x (%s)\n", i + 1, sys,
    17211841                partition_type(sys));
    17221842            ptes[i].changed = 1;
    1723             if (is_dos_partition(origsys) ||
    1724                 is_dos_partition(sys))
    1725                 dos_changed = 1;
     1843            //if (is_dos_partition(origsys) || is_dos_partition(sys))
     1844            //  dos_changed = 1;
    17261845            break;
    17271846        }
     
    17391858linear2chs(unsigned ls, unsigned *c, unsigned *h, unsigned *s)
    17401859{
    1741     int spc = heads * sectors;
     1860    int spc = g_heads * g_sectors;
    17421861
    17431862    *c = ls / spc;
    17441863    ls = ls % spc;
    1745     *h = ls / sectors;
    1746     *s = ls % sectors + 1;  /* sectors count from 1 */
     1864    *h = ls / g_sectors;
     1865    *s = ls % g_sectors + 1;  /* sectors count from 1 */
    17471866}
    17481867
     
    17551874    unsigned lec, leh, les;          /* logical ending c, h, s */
    17561875
    1757     if (!heads || !sectors || (partition >= 4))
     1876    if (!g_heads || !g_sectors || (partition >= 4))
    17581877        return;         /* do not check extended partitions */
    17591878
     
    17751894
    17761895/* Same physical / logical beginning? */
    1777     if (cylinders <= 1024 && (pbc != lbc || pbh != lbh || pbs != lbs)) {
    1778         printf("Partition %d has different physical/logical "
     1896    if (g_cylinders <= 1024 && (pbc != lbc || pbh != lbh || pbs != lbs)) {
     1897        printf("Partition %u has different physical/logical "
    17791898            "beginnings (non-Linux?):\n", partition + 1);
    1780         printf("     phys=(%d, %d, %d) ", pbc, pbh, pbs);
    1781         printf("logical=(%d, %d, %d)\n",lbc, lbh, lbs);
     1899        printf("     phys=(%u, %u, %u) ", pbc, pbh, pbs);
     1900        printf("logical=(%u, %u, %u)\n", lbc, lbh, lbs);
    17821901    }
    17831902
    17841903/* Same physical / logical ending? */
    1785     if (cylinders <= 1024 && (pec != lec || peh != leh || pes != les)) {
    1786         printf("Partition %d has different physical/logical "
     1904    if (g_cylinders <= 1024 && (pec != lec || peh != leh || pes != les)) {
     1905        printf("Partition %u has different physical/logical "
    17871906            "endings:\n", partition + 1);
    1788         printf("     phys=(%d, %d, %d) ", pec, peh, pes);
    1789         printf("logical=(%d, %d, %d)\n", lec, leh, les);
     1907        printf("     phys=(%u, %u, %u) ", pec, peh, pes);
     1908        printf("logical=(%u, %u, %u)\n", lec, leh, les);
    17901909    }
    17911910
    17921911/* Ending on cylinder boundary? */
    1793     if (peh != (heads - 1) || pes != sectors) {
    1794         printf("Partition %i does not end on cylinder boundary\n",
     1912    if (peh != (g_heads - 1) || pes != g_sectors) {
     1913        printf("Partition %u does not end on cylinder boundary\n",
    17951914            partition + 1);
    17961915    }
     
    18001919list_disk_geometry(void)
    18011920{
    1802     long long bytes = (total_number_of_sectors << 9);
    1803     long megabytes = bytes/1000000;
     1921    ullong bytes = ((ullong)total_number_of_sectors << 9);
     1922    long megabytes = bytes / 1000000;
    18041923
    18051924    if (megabytes < 10000)
    1806         printf("\nDisk %s: %ld MB, %lld bytes\n",
    1807                disk_device, megabytes, bytes);
     1925        printf("\nDisk %s: %lu MB, %llu bytes\n",
     1926            disk_device, megabytes, bytes);
    18081927    else
    1809         printf("\nDisk %s: %ld.%ld GB, %lld bytes\n",
    1810                disk_device, megabytes/1000, (megabytes/100)%10, bytes);
    1811     printf("%d heads, %d sectors/track, %d cylinders",
    1812            heads, sectors, cylinders);
     1928        printf("\nDisk %s: %lu.%lu GB, %llu bytes\n",
     1929            disk_device, megabytes/1000, (megabytes/100)%10, bytes);
     1930    printf("%u heads, %u sectors/track, %u cylinders",
     1931           g_heads, g_sectors, g_cylinders);
    18131932    if (units_per_sector == 1)
    1814         printf(", total %llu sectors",
    1815                total_number_of_sectors / (sector_size/512));
    1816     printf("\nUnits = %s of %d * %d = %d bytes\n\n",
    1817            str_units(PLURAL),
    1818            units_per_sector, sector_size, units_per_sector * sector_size);
     1933        printf(", total %"SECT_FMT"u sectors",
     1934            total_number_of_sectors / (sector_size/512));
     1935    printf("\nUnits = %s of %u * %u = %u bytes\n\n",
     1936        str_units(PLURAL),
     1937        units_per_sector, sector_size, units_per_sector * sector_size);
    18191938}
    18201939
     
    18291948    const struct pte *pe;
    18301949    const struct partition *p;
    1831     ullong last_p_start_pos = 0, p_start_pos;
    1832     int i, last_i = 0;
    1833 
    1834     for (i = 0; i < partitions; i++) {
     1950    sector_t last_p_start_pos = 0, p_start_pos;
     1951    unsigned i, last_i = 0;
     1952
     1953    for (i = 0; i < g_partitions; i++) {
    18351954        if (i == 4) {
    18361955            last_i = 4;
     
    18381957        }
    18391958        pe = &ptes[i];
    1840         if ((p = pe->part_table)->sys_ind) {
    1841             p_start_pos = get_partition_start(pe);
     1959        p = pe->part_table;
     1960        if (p->sys_ind) {
     1961            p_start_pos = get_partition_start_from_dev_start(pe);
    18421962
    18431963            if (last_p_start_pos > p_start_pos) {
     
    18771997    /* (Its sector is the global extended_offset.) */
    18781998 stage1:
    1879     for (j = 5; j < partitions-1; j++) {
    1880         oj = ptes[j].offset;
    1881         ojj = ptes[j+1].offset;
     1999    for (j = 5; j < g_partitions - 1; j++) {
     2000        oj = ptes[j].offset_from_dev_start;
     2001        ojj = ptes[j+1].offset_from_dev_start;
    18822002        if (oj > ojj) {
    1883             ptes[j].offset = ojj;
    1884             ptes[j+1].offset = oj;
     2003            ptes[j].offset_from_dev_start = ojj;
     2004            ptes[j+1].offset_from_dev_start = oj;
    18852005            pj = ptes[j].part_table;
    18862006            set_start_sect(pj, get_start_sect(pj)+oj-ojj);
     
    18972017    /* Stage 2: sort starting sectors */
    18982018 stage2:
    1899     for (j = 4; j < partitions-1; j++) {
     2019    for (j = 4; j < g_partitions - 1; j++) {
    19002020        pj = ptes[j].part_table;
    19012021        pjj = ptes[j+1].part_table;
    19022022        sj = get_start_sect(pj);
    19032023        sjj = get_start_sect(pjj);
    1904         oj = ptes[j].offset;
    1905         ojj = ptes[j+1].offset;
     2024        oj = ptes[j].offset_from_dev_start;
     2025        ojj = ptes[j+1].offset_from_dev_start;
    19062026        if (oj+sj > ojj+sjj) {
    19072027            tmp = *pj;
     
    19152035
    19162036    /* Probably something was changed */
    1917     for (j = 4; j < partitions; j++)
     2037    for (j = 4; j < g_partitions; j++)
    19182038        ptes[j].changed = 1;
    19192039}
     
    19562076
    19572077    printf("Done.\n");
    1958 
    19592078}
    19602079#endif
     
    19702089        return;
    19712090    }
    1972     if (LABEL_IS_SUN) {
     2091    if (LABEL_IS_SGI) {
    19732092        sgi_list_table(xtra);
     2093        return;
     2094    }
     2095    if (LABEL_IS_GPT) {
     2096        gpt_list_table(xtra);
    19742097        return;
    19752098    }
     
    19952118           w+1, "Device");
    19962119
    1997     for (i = 0; i < partitions; i++) {
     2120    for (i = 0; i < g_partitions; i++) {
    19982121        const struct pte *pe = &ptes[i];
    1999         ullong psects;
    2000         ullong pblocks;
     2122        sector_t psects;
     2123        sector_t pblocks;
    20012124        unsigned podd;
    20022125
     
    20162139            pblocks *= (sector_size / 1024);
    20172140
    2018         printf("%s  %c %11llu %11llu %11llu%c %2x %s\n",
     2141        printf("%s  %c %11"SECT_FMT"u %11"SECT_FMT"u %11"SECT_FMT"u%c %2x %s\n",
    20192142            partname(disk_device, i+1, w+2),
    20202143            !p->boot_ind ? ' ' : p->boot_ind == ACTIVE_FLAG /* boot flag */
    20212144                ? '*' : '?',
    2022             (ullong) cround(get_partition_start(pe)),           /* start */
    2023             (ullong) cround(get_partition_start(pe) + psects    /* end */
     2145            cround(get_partition_start_from_dev_start(pe)),           /* start */
     2146            cround(get_partition_start_from_dev_start(pe) + psects    /* end */
    20242147                - (psects ? 1 : 0)),
    2025             (ullong) pblocks, podd ? '+' : ' ', /* odd flag on end */
     2148            pblocks, podd ? '+' : ' ', /* odd flag on end */
    20262149            p->sys_ind,                                     /* type id */
    20272150            partition_type(p->sys_ind));                    /* type name */
     
    20312154
    20322155    /* Is partition table in disk order? It need not be, but... */
    2033     /* partition table entries are not checked for correct order if this
    2034        is a sgi, sun or aix labeled disk... */
     2156    /* partition table entries are not checked for correct order
     2157     * if this is a sgi, sun or aix labeled disk... */
    20352158    if (LABEL_IS_DOS && wrong_p_order(NULL)) {
    20362159        /* FIXME */
     
    20472170    int i;
    20482171
    2049     printf("\nDisk %s: %d heads, %d sectors, %d cylinders\n\n",
    2050         disk_device, heads, sectors, cylinders);
     2172    printf("\nDisk %s: %u heads, %u sectors, %u cylinders\n\n",
     2173        disk_device, g_heads, g_sectors, g_cylinders);
    20512174    printf("Nr AF  Hd Sec  Cyl  Hd Sec  Cyl      Start       Size ID\n");
    2052     for (i = 0; i < partitions; i++) {
     2175    for (i = 0; i < g_partitions; i++) {
    20532176        pe = &ptes[i];
    20542177        p = (extend ? pe->ext_pointer : pe->part_table);
    20552178        if (p != NULL) {
    2056             printf("%2d %02x%4d%4d%5d%4d%4d%5d%11u%11u %02x\n",
     2179            printf("%2u %02x%4u%4u%5u%4u%4u%5u%11"SECT_FMT"u%11"SECT_FMT"u %02x\n",
    20572180                i + 1, p->boot_ind, p->head,
    20582181                sector(p->sector),
     
    20602183                sector(p->end_sector),
    20612184                cylinder(p->end_sector, p->end_cyl),
    2062                 get_start_sect(p), get_nr_sects(p), p->sys_ind);
     2185                get_start_sect(p), get_nr_sects(p),
     2186                p->sys_ind);
    20632187            if (p->sys_ind)
    20642188                check_consistency(p, i);
     
    20702194#if ENABLE_FEATURE_FDISK_WRITABLE
    20712195static void
    2072 fill_bounds(ullong *first, ullong *last)
    2073 {
    2074     int i;
     2196fill_bounds(sector_t *first, sector_t *last)
     2197{
     2198    unsigned i;
    20752199    const struct pte *pe = &ptes[0];
    20762200    const struct partition *p;
    20772201
    2078     for (i = 0; i < partitions; pe++,i++) {
     2202    for (i = 0; i < g_partitions; pe++,i++) {
    20792203        p = pe->part_table;
    20802204        if (!p->sys_ind || IS_EXTENDED(p->sys_ind)) {
     
    20822206            last[i] = 0;
    20832207        } else {
    2084             first[i] = get_partition_start(pe);
     2208            first[i] = get_partition_start_from_dev_start(pe);
    20852209            last[i] = first[i] + get_nr_sects(p) - 1;
    20862210        }
     
    20892213
    20902214static void
    2091 check(int n, unsigned h, unsigned s, unsigned c, ullong start)
    2092 {
    2093     ullong total, real_s, real_c;
     2215check(int n, unsigned h, unsigned s, unsigned c, sector_t start)
     2216{
     2217    sector_t total, real_s, real_c;
    20942218
    20952219    real_s = sector(s) - 1;
    20962220    real_c = cylinder(s, c);
    2097     total = (real_c * sectors + real_s) * heads + h;
     2221    total = (real_c * g_sectors + real_s) * g_heads + h;
    20982222    if (!total)
    2099         printf("Partition %d contains sector 0\n", n);
    2100     if (h >= heads)
    2101         printf("Partition %d: head %d greater than maximum %d\n",
    2102             n, h + 1, heads);
    2103     if (real_s >= sectors)
    2104         printf("Partition %d: sector %d greater than "
    2105             "maximum %d\n", n, s, sectors);
    2106     if (real_c >= cylinders)
    2107         printf("Partition %d: cylinder %llu greater than "
    2108             "maximum %d\n", n, real_c + 1, cylinders);
    2109     if (cylinders <= 1024 && start != total)
    2110         printf("Partition %d: previous sectors %llu disagrees with "
    2111             "total %llu\n", n, start, total);
     2223        printf("Partition %u contains sector 0\n", n);
     2224    if (h >= g_heads)
     2225        printf("Partition %u: head %u greater than maximum %u\n",
     2226            n, h + 1, g_heads);
     2227    if (real_s >= g_sectors)
     2228        printf("Partition %u: sector %u greater than "
     2229            "maximum %u\n", n, s, g_sectors);
     2230    if (real_c >= g_cylinders)
     2231        printf("Partition %u: cylinder %"SECT_FMT"u greater than "
     2232            "maximum %u\n", n, real_c + 1, g_cylinders);
     2233    if (g_cylinders <= 1024 && start != total)
     2234        printf("Partition %u: previous sectors %"SECT_FMT"u disagrees with "
     2235            "total %"SECT_FMT"u\n", n, start, total);
    21122236}
    21132237
     
    21162240{
    21172241    int i, j;
    2118     unsigned total = 1;
    2119     ullong first[partitions], last[partitions];
     2242    sector_t total = 1;
     2243    sector_t first[g_partitions], last[g_partitions];
    21202244    struct partition *p;
    21212245
     
    21332257
    21342258    fill_bounds(first, last);
    2135     for (i = 0; i < partitions; i++) {
     2259    for (i = 0; i < g_partitions; i++) {
    21362260        struct pte *pe = &ptes[i];
    21372261
     
    21392263        if (p->sys_ind && !IS_EXTENDED(p->sys_ind)) {
    21402264            check_consistency(p, i);
    2141             if (get_partition_start(pe) < first[i])
     2265            if (get_partition_start_from_dev_start(pe) < first[i])
    21422266                printf("Warning: bad start-of-data in "
    2143                     "partition %d\n", i + 1);
     2267                    "partition %u\n", i + 1);
    21442268            check(i + 1, p->end_head, p->end_sector, p->end_cyl,
    21452269                last[i]);
     
    21482272                if ((first[i] >= first[j] && first[i] <= last[j])
    21492273                 || ((last[i] <= last[j] && last[i] >= first[j]))) {
    2150                     printf("Warning: partition %d overlaps "
    2151                         "partition %d\n", j + 1, i + 1);
     2274                    printf("Warning: partition %u overlaps "
     2275                        "partition %u\n", j + 1, i + 1);
    21522276                    total += first[i] >= first[j] ?
    21532277                        first[i] : first[j];
     
    21612285    if (extended_offset) {
    21622286        struct pte *pex = &ptes[ext_index];
    2163         ullong e_last = get_start_sect(pex->part_table) +
     2287        sector_t e_last = get_start_sect(pex->part_table) +
    21642288            get_nr_sects(pex->part_table) - 1;
    21652289
    2166         for (i = 4; i < partitions; i++) {
     2290        for (i = 4; i < g_partitions; i++) {
    21672291            total++;
    21682292            p = ptes[i].part_table;
    21692293            if (!p->sys_ind) {
    2170                 if (i != 4 || i + 1 < partitions)
    2171                     printf("Warning: partition %d "
     2294                if (i != 4 || i + 1 < g_partitions)
     2295                    printf("Warning: partition %u "
    21722296                        "is empty\n", i + 1);
    21732297            } else if (first[i] < extended_offset || last[i] > e_last) {
    2174                 printf("Logical partition %d not entirely in "
    2175                     "partition %d\n", i + 1, ext_index + 1);
     2298                printf("Logical partition %u not entirely in "
     2299                    "partition %u\n", i + 1, ext_index + 1);
    21762300            }
    21772301        }
    21782302    }
    21792303
    2180     if (total > heads * sectors * cylinders)
    2181         printf("Total allocated sectors %d greater than the maximum "
    2182             "%d\n", total, heads * sectors * cylinders);
     2304    if (total > g_heads * g_sectors * g_cylinders)
     2305        printf("Total allocated sectors %u greater than the maximum "
     2306            "%u\n", total, g_heads * g_sectors * g_cylinders);
    21832307    else {
    2184         total = heads * sectors * cylinders - total;
     2308        total = g_heads * g_sectors * g_cylinders - total;
    21852309        if (total != 0)
    2186             printf("%d unallocated sectors\n", total);
     2310            printf("%"SECT_FMT"u unallocated sectors\n", total);
    21872311    }
    21882312}
     
    21952319    struct partition *p = ptes[n].part_table;
    21962320    struct partition *q = ptes[ext_index].part_table;
    2197     ullong limit, temp;
    2198     ullong start, stop = 0;
    2199     ullong first[partitions], last[partitions];
     2321    sector_t limit, temp;
     2322    sector_t start, stop = 0;
     2323    sector_t first[g_partitions], last[g_partitions];
    22002324
    22012325    if (p && p->sys_ind) {
     
    22072331        start = sector_offset;
    22082332        if (display_in_cyl_units || !total_number_of_sectors)
    2209             limit = (ullong) heads * sectors * cylinders - 1;
     2333            limit = (sector_t) g_heads * g_sectors * g_cylinders - 1;
    22102334        else
    22112335            limit = total_number_of_sectors - 1;
     
    22202344    }
    22212345    if (display_in_cyl_units)
    2222         for (i = 0; i < partitions; i++)
     2346        for (i = 0; i < g_partitions; i++)
    22232347            first[i] = (cround(first[i]) - 1) * units_per_sector;
    22242348
     
    22262350    do {
    22272351        temp = start;
    2228         for (i = 0; i < partitions; i++) {
     2352        for (i = 0; i < g_partitions; i++) {
    22292353            int lastplusoff;
    22302354
    2231             if (start == ptes[i].offset)
     2355            if (start == ptes[i].offset_from_dev_start)
    22322356                start += sector_offset;
    22332357            lastplusoff = last[i] + ((n < 4) ? 0 : sector_offset);
     
    22382362            break;
    22392363        if (start >= temp+units_per_sector && num_read) {
    2240             printf("Sector %lld is already allocated\n", temp);
     2364            printf("Sector %"SECT_FMT"u is already allocated\n", temp);
    22412365            temp = start;
    22422366            num_read = 0;
    22432367        }
    22442368        if (!num_read && start == temp) {
    2245             ullong saved_start;
     2369            sector_t saved_start;
    22462370
    22472371            saved_start = start;
    2248             start = read_int(cround(saved_start), cround(saved_start), cround(limit),
    2249                      0, mesg);
     2372            start = read_int(cround(saved_start), cround(saved_start), cround(limit), 0, mesg);
    22502373            if (display_in_cyl_units) {
    22512374                start = (start - 1) * units_per_sector;
    2252                 if (start < saved_start) start = saved_start;
     2375                if (start < saved_start)
     2376                    start = saved_start;
    22532377            }
    22542378            num_read = 1;
     
    22582382        struct pte *pe = &ptes[n];
    22592383
    2260         pe->offset = start - sector_offset;
    2261         if (pe->offset == extended_offset) { /* must be corrected */
    2262             pe->offset++;
     2384        pe->offset_from_dev_start = start - sector_offset;
     2385        if (pe->offset_from_dev_start == extended_offset) { /* must be corrected */
     2386            pe->offset_from_dev_start++;
    22632387            if (sector_offset == 1)
    22642388                start++;
     
    22662390    }
    22672391
    2268     for (i = 0; i < partitions; i++) {
     2392    for (i = 0; i < g_partitions; i++) {
    22692393        struct pte *pe = &ptes[i];
    22702394
    2271         if (start < pe->offset && limit >= pe->offset)
    2272             limit = pe->offset - 1;
     2395        if (start < pe->offset_from_dev_start && limit >= pe->offset_from_dev_start)
     2396            limit = pe->offset_from_dev_start - 1;
    22732397        if (start < first[i] && limit >= first[i])
    22742398            limit = first[i] - 1;
     
    22772401        printf("No free sectors available\n");
    22782402        if (n > 4)
    2279             partitions--;
     2403            g_partitions--;
    22802404        return;
    22812405    }
     
    22862410             "Last %s or +size or +sizeM or +sizeK",
    22872411             str_units(SINGULAR));
    2288         stop = read_int(cround(start), cround(limit), cround(limit),
    2289                 cround(start), mesg);
     2412        stop = read_int(cround(start), cround(limit), cround(limit), cround(start), mesg);
    22902413        if (display_in_cyl_units) {
    22912414            stop = stop * units_per_sector - 1;
     
    22972420    set_partition(n, 0, start, stop, sys);
    22982421    if (n > 4)
    2299         set_partition(n - 1, 1, ptes[n].offset, stop, EXTENDED);
     2422        set_partition(n - 1, 1, ptes[n].offset_from_dev_start, stop, EXTENDED);
    23002423
    23012424    if (IS_EXTENDED(sys)) {
     
    23052428        ext_index = n;
    23062429        pen->ext_pointer = p;
    2307         pe4->offset = extended_offset = start;
     2430        pe4->offset_from_dev_start = extended_offset = start;
    23082431        pe4->sectorbuffer = xzalloc(sector_size);
    23092432        pe4->part_table = pt_offset(pe4->sectorbuffer, 0);
    23102433        pe4->ext_pointer = pe4->part_table + 1;
    23112434        pe4->changed = 1;
    2312         partitions = 5;
     2435        g_partitions = 5;
    23132436    }
    23142437}
     
    23172440add_logical(void)
    23182441{
    2319     if (partitions > 5 || ptes[4].part_table->sys_ind) {
    2320         struct pte *pe = &ptes[partitions];
     2442    if (g_partitions > 5 || ptes[4].part_table->sys_ind) {
     2443        struct pte *pe = &ptes[g_partitions];
    23212444
    23222445        pe->sectorbuffer = xzalloc(sector_size);
    23232446        pe->part_table = pt_offset(pe->sectorbuffer, 0);
    23242447        pe->ext_pointer = pe->part_table + 1;
    2325         pe->offset = 0;
     2448        pe->offset_from_dev_start = 0;
    23262449        pe->changed = 1;
    2327         partitions++;
    2328     }
    2329     add_partition(partitions - 1, LINUX_NATIVE);
     2450        g_partitions++;
     2451    }
     2452    add_partition(g_partitions - 1, LINUX_NATIVE);
    23302453}
    23312454
     
    23392462
    23402463    if (LABEL_IS_SUN) {
    2341         add_sun_partition(get_partition(0, partitions), LINUX_NATIVE);
     2464        add_sun_partition(get_partition(0, g_partitions), LINUX_NATIVE);
    23422465        return;
    23432466    }
    23442467    if (LABEL_IS_SGI) {
    2345         sgi_add_partition(get_partition(0, partitions), LINUX_NATIVE);
     2468        sgi_add_partition(get_partition(0, g_partitions), LINUX_NATIVE);
    23462469        return;
    23472470    }
     
    23562479        free_primary += !ptes[i].part_table->sys_ind;
    23572480
    2358     if (!free_primary && partitions >= MAXIMUM_PARTS) {
     2481    if (!free_primary && g_partitions >= MAXIMUM_PARTS) {
    23592482        printf("The maximum number of partitions has been created\n");
    23602483        return;
     
    23772500        while (1) {
    23782501            c = read_nonempty(line);
    2379             if (c == 'p' || c == 'P') {
     2502            if ((c | 0x20) == 'p') {
    23802503                i = get_nonexisting_partition(0, 4);
    23812504                if (i >= 0)
     
    24082531            if (ptes[i].changed)
    24092532                ptes[3].changed = 1;
    2410         for (i = 3; i < partitions; i++) {
     2533        for (i = 3; i < g_partitions; i++) {
    24112534            struct pte *pe = &ptes[i];
    24122535
    24132536            if (pe->changed) {
    24142537                write_part_table_flag(pe->sectorbuffer);
    2415                 write_sector(pe->offset, pe->sectorbuffer);
     2538                write_sector(pe->offset_from_dev_start, pe->sectorbuffer);
    24162539            }
    24172540        }
     
    24432566    sync();
    24442567    /* sleep(2); Huh? */
    2445     i = ioctl_or_perror(fd, BLKRRPART, NULL,
     2568    i = ioctl_or_perror(dev_fd, BLKRRPART, NULL,
    24462569            "WARNING: rereading partition table "
    24472570            "failed, kernel still uses old table");
     
    24562579    if (leave) {
    24572580        if (ENABLE_FEATURE_CLEAN_UP)
    2458             close(fd);
     2581            close_dev_fd();
    24592582        exit(i != 0);
    24602583    }
     
    24742597        printf(" %02X", (unsigned char) pbuffer[i]);
    24752598        if (l == MAX_PER_LINE - 1) {
    2476             puts("");
     2599            bb_putchar('\n');
    24772600            l = -1;
    24782601        }
    24792602    }
    24802603    if (l > 0)
    2481         puts("");
    2482     puts("");
     2604        bb_putchar('\n');
     2605    bb_putchar('\n');
    24832606}
    24842607
     
    24922615        print_buffer(MBRbuffer);
    24932616    else {
    2494         for (i = 3; i < partitions; i++)
     2617        for (i = 3; i < g_partitions; i++)
    24952618            print_buffer(ptes[i].sectorbuffer);
    24962619    }
     
    24982621
    24992622static void
    2500 move_begin(int i)
     2623move_begin(unsigned i)
    25012624{
    25022625    struct pte *pe = &ptes[i];
    25032626    struct partition *p = pe->part_table;
    2504     ullong new, first;
     2627    sector_t new, first, nr_sects;
    25052628
    25062629    if (warn_geometry())
    25072630        return;
    2508     if (!p->sys_ind || !get_nr_sects(p) || IS_EXTENDED(p->sys_ind)) {
    2509         printf("Partition %d has no data area\n", i + 1);
     2631    nr_sects = get_nr_sects(p);
     2632    if (!p->sys_ind || !nr_sects || IS_EXTENDED(p->sys_ind)) {
     2633        printf("Partition %u has no data area\n", i + 1);
    25102634        return;
    25112635    }
    2512     first = get_partition_start(pe);
    2513     new = read_int(first, first, first + get_nr_sects(p) - 1, first,
    2514                "New beginning of data") - pe->offset;
    2515 
    2516     if (new != get_nr_sects(p)) {
    2517         first = get_nr_sects(p) + get_start_sect(p) - new;
    2518         set_nr_sects(p, first);
    2519         set_start_sect(p, new);
     2636    first = get_partition_start_from_dev_start(pe); /* == pe->offset_from_dev_start + get_start_sect(p) */
     2637    new = read_int(0 /*was:first*/, first, first + nr_sects - 1, first, "New beginning of data");
     2638    if (new != first) {
     2639        sector_t new_relative = new - pe->offset_from_dev_start;
     2640        nr_sects += (get_start_sect(p) - new_relative);
     2641        set_start_sect(p, new_relative);
     2642        set_nr_sects(p, nr_sects);
     2643        read_nonempty("Recalculate C/H/S values? (Y/N): ");
     2644        if ((line_ptr[0] | 0x20) == 'y')
     2645            set_hsc_start_end(p, new, new + nr_sects - 1);
    25202646        pe->changed = 1;
    25212647    }
     
    25282654
    25292655    while (1) {
    2530         putchar('\n');
    2531         c = tolower(read_nonempty("Expert command (m for help): "));
     2656        bb_putchar('\n');
     2657        c = 0x20 | read_nonempty("Expert command (m for help): ");
    25322658        switch (c) {
    25332659        case 'a':
     
    25372663        case 'b':
    25382664            if (LABEL_IS_DOS)
    2539                 move_begin(get_partition(0, partitions));
     2665                move_begin(get_partition(0, g_partitions));
    25402666            break;
    25412667        case 'c':
    2542             user_cylinders = cylinders =
    2543                 read_int(1, cylinders, 1048576, 0,
     2668            user_cylinders = g_cylinders =
     2669                read_int(1, g_cylinders, 1048576, 0,
    25442670                    "Number of cylinders");
    25452671            if (LABEL_IS_SUN)
    2546                 sun_set_ncyl(cylinders);
     2672                sun_set_ncyl(g_cylinders);
    25472673            if (LABEL_IS_DOS)
    25482674                warn_cylinders();
     
    25692695            break;
    25702696        case 'h':
    2571             user_heads = heads = read_int(1, heads, 256, 0,
    2572                     "Number of heads");
     2697            user_heads = g_heads = read_int(1, g_heads, 256, 0, "Number of heads");
    25732698            update_units();
    25742699            break;
     
    25882713            break;
    25892714        case 'q':
    2590             close(fd);
    2591             puts("");
    2592             exit(0);
     2715            if (ENABLE_FEATURE_CLEAN_UP)
     2716                close_dev_fd();
     2717            bb_putchar('\n');
     2718            exit(EXIT_SUCCESS);
    25932719        case 'r':
    25942720            return;
    25952721        case 's':
    2596             user_sectors = sectors = read_int(1, sectors, 63, 0,
    2597                        "Number of sectors");
     2722            user_sectors = g_sectors = read_int(1, g_sectors, 63, 0, "Number of sectors");
    25982723            if (dos_compatible_flag) {
    2599                 sector_offset = sectors;
     2724                sector_offset = g_sectors;
    26002725                printf("Warning: setting sector offset for DOS "
    26012726                    "compatiblity\n");
     
    26392764
    26402765    snprintf(buf, sizeof(buf), "/proc/ide/%s/media", device+5);
    2641     procf = fopen(buf, "r");
     2766    procf = fopen_for_read(buf);
    26422767    if (procf != NULL && fgets(buf, sizeof(buf), procf))
    26432768        is_ide = (!strncmp(buf, "cdrom", 5) ||
     
    26562781
    26572782static void
    2658 trydev(const char *device, int user_specified)
     2783open_list_and_close(const char *device, int user_specified)
    26592784{
    26602785    int gb;
     
    26662791        if (is_ide_cdrom_or_tape(device))
    26672792            return;
    2668     fd = open(disk_device, type_open);
    2669     if (fd >= 0) {
    2670         gb = get_boot(try_only);
    2671         if (gb > 0) {   /* I/O error */
    2672             close(fd);
    2673         } else if (gb < 0) { /* no DOS signature */
    2674             list_disk_geometry();
    2675             if (LABEL_IS_AIX) {
    2676                 return;
    2677             }
    2678 #if ENABLE_FEATURE_OSF_LABEL
    2679             if (bsd_trydev(device) < 0)
    2680 #endif
    2681                 printf("Disk %s doesn't contain a valid "
    2682                     "partition table\n", device);
    2683             close(fd);
    2684         } else {
    2685             close(fd);
    2686             list_table(0);
    2687 #if ENABLE_FEATURE_FDISK_WRITABLE
    2688             if (!LABEL_IS_SUN && partitions > 4){
    2689                 delete_partition(ext_index);
    2690             }
    2691 #endif
    2692         }
    2693     } else {
     2793
     2794    /* Open disk_device, save file descriptor to dev_fd */
     2795    errno = 0;
     2796    gb = get_boot(TRY_ONLY);
     2797    if (gb > 0) {   /* I/O error */
    26942798        /* Ignore other errors, since we try IDE
    26952799           and SCSI hard disks which may not be
    26962800           installed on the system. */
    2697         if (errno == EACCES) {
    2698             printf("Cannot open %s\n", device);
    2699             return;
    2700         }
    2701     }
     2801        if (user_specified || errno == EACCES)
     2802            bb_perror_msg("can't open '%s'", device);
     2803        return;
     2804    }
     2805
     2806    if (gb < 0) { /* no DOS signature */
     2807        list_disk_geometry();
     2808        if (LABEL_IS_AIX)
     2809            goto ret;
     2810#if ENABLE_FEATURE_OSF_LABEL
     2811        if (bsd_trydev(device) < 0)
     2812#endif
     2813            printf("Disk %s doesn't contain a valid "
     2814                "partition table\n", device);
     2815    } else {
     2816        list_table(0);
     2817#if ENABLE_FEATURE_FDISK_WRITABLE
     2818        if (!LABEL_IS_SUN && g_partitions > 4) {
     2819            delete_partition(ext_index);
     2820        }
     2821#endif
     2822    }
     2823 ret:
     2824    close_dev_fd();
    27022825}
    27032826
     
    27052828   that look like a partition name (do not end in a digit) */
    27062829static void
    2707 tryprocpt(void)
     2830list_devs_in_proc_partititons(void)
    27082831{
    27092832    FILE *procpt;
     
    27142837
    27152838    while (fgets(line, sizeof(line), procpt)) {
    2716         if (sscanf(line, " %d %d %d %[^\n ]",
     2839        if (sscanf(line, " %u %u %u %[^\n ]",
    27172840                &ma, &mi, &sz, ptname) != 4)
    27182841            continue;
    2719         for (s = ptname; *s; s++);
    2720         if (isdigit(s[-1]))
     2842        for (s = ptname; *s; s++)
     2843            continue;
     2844        /* note: excluding '0': e.g. mmcblk0 is not a partition name! */
     2845        if (s[-1] >= '1' && s[-1] <= '9')
    27212846            continue;
    27222847        sprintf(devname, "/dev/%s", ptname);
    2723         trydev(devname, 0);
     2848        open_list_and_close(devname, 0);
    27242849    }
    27252850#if ENABLE_FEATURE_CLEAN_UP
     
    27362861#endif
    27372862
    2738 int fdisk_main(int argc, char **argv);
    2739 int fdisk_main(int argc, char **argv)
    2740 {
    2741     char *str_b, *str_C, *str_H, *str_S;
     2863int fdisk_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
     2864int fdisk_main(int argc UNUSED_PARAM, char **argv)
     2865{
    27422866    unsigned opt;
    27432867    /*
     
    27492873     * Options -C, -H, -S set the geometry.
    27502874     */
    2751     enum {
    2752         OPT_b = 1 << 0,
    2753         OPT_C = 1 << 1,
    2754         OPT_H = 1 << 2,
    2755         OPT_l = 1 << 3,
    2756         OPT_S = 1 << 4,
    2757         OPT_u = 1 << 5,
    2758         OPT_s = (1 << 6) * ENABLE_FEATURE_FDISK_BLKSIZE,
    2759     };
    2760 
    2761     PTR_TO_GLOBALS = xzalloc(sizeof(G));
    2762 
    2763     opt = getopt32(argv, "b:C:H:lS:u" USE_FEATURE_FDISK_BLKSIZE("s"),
    2764                 &str_b, &str_C, &str_H, &str_S);
    2765     argc -= optind;
     2875    INIT_G();
     2876
     2877    close_dev_fd(); /* needed: fd 3 must not stay closed */
     2878
     2879    opt_complementary = "b+:C+:H+:S+"; /* numeric params */
     2880    opt = getopt32(argv, "b:C:H:lS:u" IF_FEATURE_FDISK_BLKSIZE("s"),
     2881                &sector_size, &user_cylinders, &user_heads, &user_sectors);
    27662882    argv += optind;
    2767     if (opt & OPT_b) { // -b
     2883    if (opt & OPT_b) {
    27682884        /* Ugly: this sector size is really per device,
    2769            so cannot be combined with multiple disks,
    2770            and the same goes for the C/H/S options.
    2771         */
    2772         sector_size = xatoi_u(str_b);
    2773         if (sector_size != 512 && sector_size != 1024 &&
    2774             sector_size != 2048)
     2885         * so cannot be combined with multiple disks,
     2886         * and the same goes for the C/H/S options.
     2887         */
     2888        if (sector_size < 512
     2889         || sector_size > 0x10000
     2890         || (sector_size & (sector_size-1)) /* not power of 2 */
     2891        ) {
    27752892            bb_show_usage();
     2893        }
    27762894        sector_offset = 2;
    27772895        user_set_sector_size = 1;
    27782896    }
    2779     if (opt & OPT_C) user_cylinders = xatoi_u(str_C); // -C
    2780     if (opt & OPT_H) { // -H
    2781         user_heads = xatoi_u(str_H);
    2782         if (user_heads <= 0 || user_heads >= 256)
    2783             user_heads = 0;
    2784     }
    2785     //if (opt & OPT_l) // -l
    2786     if (opt & OPT_S) { // -S
    2787         user_sectors = xatoi_u(str_S);
    2788         if (user_sectors <= 0 || user_sectors >= 64)
    2789             user_sectors = 0;
    2790     }
    2791     if (opt & OPT_u) display_in_cyl_units = 0; // -u
    2792     //if (opt & OPT_s) // -s
    2793 
    2794     if (user_set_sector_size && argc != 1)
    2795         printf("Warning: the -b (set sector size) option should"
    2796              " be used with one specified device\n");
     2897    if (user_heads <= 0 || user_heads >= 256)
     2898        user_heads = 0;
     2899    if (user_sectors <= 0 || user_sectors >= 64)
     2900        user_sectors = 0;
     2901    if (opt & OPT_u)
     2902        display_in_cyl_units = 0; // -u
    27972903
    27982904#if ENABLE_FEATURE_FDISK_WRITABLE
     
    28002906        nowarn = 1;
    28012907#endif
    2802         type_open = O_RDONLY;
    2803         if (argc > 0) {
    2804             int k;
    2805 #if defined(__GNUC__)
    2806             /* avoid gcc warning:
    2807                variable `k' might be clobbered by `longjmp' */
    2808             (void)&k;
    2809 #endif
     2908        if (*argv) {
    28102909            listing = 1;
    2811             for (k = 0; k < argc; k++)
    2812                 trydev(argv[k], 1);
     2910            do {
     2911                open_list_and_close(*argv, 1);
     2912            } while (*++argv);
    28132913        } else {
    2814             /* we no longer have default device names */
    2815             /* but, we can use /proc/partitions instead */
    2816             tryprocpt();
     2914            /* we don't have device names, */
     2915            /* use /proc/partitions instead */
     2916            list_devs_in_proc_partititons();
    28172917        }
    28182918        return 0;
     
    28232923#if ENABLE_FEATURE_FDISK_BLKSIZE
    28242924    if (opt & OPT_s) {
    2825         long size;
    28262925        int j;
    28272926
    28282927        nowarn = 1;
    2829         type_open = O_RDONLY;
    2830 
    2831         if (argc <= 0)
     2928        if (!argv[0])
    28322929            bb_show_usage();
    2833 
    2834         for (j = 0; j < argc; j++) {
    2835             disk_device = argv[j];
    2836             fd = open(disk_device, type_open);
    2837             if (fd < 0)
    2838                 fdisk_fatal(unable_to_open);
    2839             if (ioctl(fd, BLKGETSIZE, &size))
    2840                 fdisk_fatal(ioctl_error);
     2930        for (j = 0; argv[j]; j++) {
     2931            unsigned long long size;
     2932            fd = xopen(argv[j], O_RDONLY);
     2933            size = bb_BLKGETSIZE_sectors(fd) / 2;
    28412934            close(fd);
    2842             if (argc == 1)
    2843                 printf("%ld\n", size/2);
     2935            if (argv[1])
     2936                printf("%llu\n", size);
    28442937            else
    2845                 printf("%s: %ld\n", argv[j], size/2);
     2938                printf("%s: %llu\n", argv[j], size);
    28462939        }
    28472940        return 0;
     
    28502943
    28512944#if ENABLE_FEATURE_FDISK_WRITABLE
    2852     if (argc != 1)
     2945    if (!argv[0] || argv[1])
    28532946        bb_show_usage();
    28542947
    28552948    disk_device = argv[0];
    2856     get_boot(fdisk);
     2949    get_boot(OPEN_MAIN);
    28572950
    28582951    if (LABEL_IS_OSF) {
     
    28622955        bsd_select();
    28632956        /*Why do we do this?  It seems to be counter-intuitive*/
    2864         current_label_type = label_dos;
     2957        current_label_type = LABEL_DOS;
    28652958        /* If we return we may want to make an empty DOS label? */
    28662959    }
     
    28682961    while (1) {
    28692962        int c;
    2870         putchar('\n');
    2871         c = tolower(read_nonempty("Command (m for help): "));
     2963        bb_putchar('\n');
     2964        c = 0x20 | read_nonempty("Command (m for help): ");
    28722965        switch (c) {
    28732966        case 'a':
    28742967            if (LABEL_IS_DOS)
    2875                 toggle_active(get_partition(1, partitions));
     2968                toggle_active(get_partition(1, g_partitions));
    28762969            else if (LABEL_IS_SUN)
    2877                 toggle_sunflags(get_partition(1, partitions),
     2970                toggle_sunflags(get_partition(1, g_partitions),
    28782971                        0x01);
    28792972            else if (LABEL_IS_SGI)
    28802973                sgi_set_bootpartition(
    2881                     get_partition(1, partitions));
     2974                    get_partition(1, g_partitions));
    28822975            else
    28832976                unknown_command(c);
     
    29022995                toggle_dos_compatibility_flag();
    29032996            else if (LABEL_IS_SUN)
    2904                 toggle_sunflags(get_partition(1, partitions),
     2997                toggle_sunflags(get_partition(1, g_partitions),
    29052998                        0x10);
    29062999            else if (LABEL_IS_SGI)
    29073000                sgi_set_swappartition(
    2908                         get_partition(1, partitions));
     3001                        get_partition(1, g_partitions));
    29093002            else
    29103003                unknown_command(c);
     
    29183011               partition tables */
    29193012                if (!LABEL_IS_SGI) {
    2920                     j = get_existing_partition(1, partitions);
     3013                    j = get_existing_partition(1, g_partitions);
    29213014                } else {
    2922                     j = get_partition(1, partitions);
     3015                    j = get_partition(1, g_partitions);
    29233016                }
    29243017                if (j >= 0)
     
    29473040            break;
    29483041        case 'q':
    2949             close(fd);
    2950             puts("");
     3042            if (ENABLE_FEATURE_CLEAN_UP)
     3043                close_dev_fd();
     3044            bb_putchar('\n');
    29513045            return 0;
    29523046        case 's':
Note: See TracChangeset for help on using the changeset viewer.