# define USE_FEATURE_FDISK_BLKSIZE(a)
#endif
-#define DEFAULT_SECTOR_SIZE 512
-#define MAX_SECTOR_SIZE 2048
-#define SECTOR_SIZE 512 /* still used in osf/sgi/sun code */
-#define MAXIMUM_PARTS 60
-
-#define ACTIVE_FLAG 0x80
-
-#define EXTENDED 0x05
-#define WIN98_EXTENDED 0x0f
-#define LINUX_PARTITION 0x81
-#define LINUX_SWAP 0x82
-#define LINUX_NATIVE 0x83
-#define LINUX_EXTENDED 0x85
-#define LINUX_LVM 0x8e
-#define LINUX_RAID 0xfd
+#define DEFAULT_SECTOR_SIZE 512
+#define DEFAULT_SECTOR_SIZE_STR "512"
+#define MAX_SECTOR_SIZE 2048
+#define SECTOR_SIZE 512 /* still used in osf/sgi/sun code */
+#define MAXIMUM_PARTS 60
+
+#define ACTIVE_FLAG 0x80
+
+#define EXTENDED 0x05
+#define WIN98_EXTENDED 0x0f
+#define LINUX_PARTITION 0x81
+#define LINUX_SWAP 0x82
+#define LINUX_NATIVE 0x83
+#define LINUX_EXTENDED 0x85
+#define LINUX_LVM 0x8e
+#define LINUX_RAID 0xfd
+
+
+enum {
+ OPT_b = 1 << 0,
+ OPT_C = 1 << 1,
+ OPT_H = 1 << 2,
+ OPT_l = 1 << 3,
+ OPT_S = 1 << 4,
+ OPT_u = 1 << 5,
+ OPT_s = (1 << 6) * ENABLE_FEATURE_FDISK_BLKSIZE,
+};
+
/* Used for sector numbers. Today's disk sizes make it necessary */
typedef unsigned long long ullong;
#define HDIO_GETGEO 0x0301 /* get device geometry */
-static const char msg_building_new_label[] =
+static const char msg_building_new_label[] ALIGN1 =
"Building a new %s. Changes will remain in memory only,\n"
"until you decide to write them. After that the previous content\n"
"won't be recoverable.\n\n";
-static const char msg_part_already_defined[] =
+static const char msg_part_already_defined[] ALIGN1 =
"Partition %d is already defined, delete it before re-adding\n";
-static unsigned sector_size = DEFAULT_SECTOR_SIZE;
-static unsigned user_set_sector_size;
-static unsigned sector_offset = 1;
-
-#if ENABLE_FEATURE_OSF_LABEL
-static int possibly_osf_label;
-#endif
-
-static unsigned heads, sectors, cylinders;
-static void update_units(void);
-
-
struct partition {
unsigned char boot_ind; /* 0x80 - active */
unsigned char head; /* starting head */
unsigned char sector; /* starting sector */
unsigned char cyl; /* starting cylinder */
- unsigned char sys_ind; /* What partition type */
+ unsigned char sys_ind; /* what partition type */
unsigned char end_head; /* end head */
unsigned char end_sector; /* end sector */
unsigned char end_cyl; /* end cylinder */
unsigned char start4[4]; /* starting sector counting from 0 */
unsigned char size4[4]; /* nr of sectors in partition */
-} ATTRIBUTE_PACKED;
+} PACKED;
-static const char unable_to_open[] = "cannot open %s";
-static const char unable_to_read[] = "cannot read from %s";
-static const char unable_to_seek[] = "cannot seek on %s";
-static const char unable_to_write[] = "cannot write to %s";
-static const char ioctl_error[] = "BLKGETSIZE ioctl failed on %s";
-static void fdisk_fatal(const char *why) ATTRIBUTE_NORETURN;
+static const char unable_to_open[] ALIGN1 = "can't open %s";
+static const char unable_to_read[] ALIGN1 = "can't read from %s";
+static const char unable_to_seek[] ALIGN1 = "can't seek on %s";
enum label_type {
- label_dos, label_sun, label_sgi, label_aix, label_osf
+ LABEL_DOS, LABEL_SUN, LABEL_SGI, LABEL_AIX, LABEL_OSF
};
-#define LABEL_IS_DOS (label_dos == current_label_type)
+#define LABEL_IS_DOS (LABEL_DOS == current_label_type)
#if ENABLE_FEATURE_SUN_LABEL
-#define LABEL_IS_SUN (label_sun == current_label_type)
+#define LABEL_IS_SUN (LABEL_SUN == current_label_type)
#define STATIC_SUN static
#else
#define LABEL_IS_SUN 0
#endif
#if ENABLE_FEATURE_SGI_LABEL
-#define LABEL_IS_SGI (label_sgi == current_label_type)
+#define LABEL_IS_SGI (LABEL_SGI == current_label_type)
#define STATIC_SGI static
#else
#define LABEL_IS_SGI 0
#endif
#if ENABLE_FEATURE_AIX_LABEL
-#define LABEL_IS_AIX (label_aix == current_label_type)
+#define LABEL_IS_AIX (LABEL_AIX == current_label_type)
#define STATIC_AIX static
#else
#define LABEL_IS_AIX 0
#endif
#if ENABLE_FEATURE_OSF_LABEL
-#define LABEL_IS_OSF (label_osf == current_label_type)
+#define LABEL_IS_OSF (LABEL_OSF == current_label_type)
#define STATIC_OSF static
#else
#define LABEL_IS_OSF 0
#define STATIC_OSF extern
#endif
-enum action { fdisk, require, try_only, create_empty_dos, create_empty_sun };
+enum action { OPEN_MAIN, TRY_ONLY, CREATE_EMPTY_DOS, CREATE_EMPTY_SUN };
-static enum label_type current_label_type;
-
-static const char *disk_device;
-static int fd; /* the disk */
-static int partitions = 4; /* maximum partition + 1 */
-static int display_in_cyl_units = 1;
-static unsigned units_per_sector = 1;
+static void update_units(void);
#if ENABLE_FEATURE_FDISK_WRITABLE
static void change_units(void);
static void reread_partition_table(int leave);
#endif
static const char *partition_type(unsigned char type);
static void get_geometry(void);
+#if ENABLE_FEATURE_SUN_LABEL || ENABLE_FEATURE_FDISK_WRITABLE
static int get_boot(enum action what);
+#else
+static int get_boot(void);
+#endif
#define PLURAL 0
#define SINGULAR 1
NULL
};
+enum {
+ dev_fd = 3 /* the disk */
+};
/* Globals */
-
struct globals {
char *line_ptr;
+
+ const char *disk_device;
+ int g_partitions; // = 4; /* maximum partition + 1 */
+ unsigned units_per_sector; // = 1;
+ unsigned sector_size; // = DEFAULT_SECTOR_SIZE;
+ unsigned user_set_sector_size;
+ unsigned sector_offset; // = 1;
+ unsigned g_heads, g_sectors, g_cylinders;
+ smallint /* enum label_type */ current_label_type;
+ smallint display_in_cyl_units; // = 1;
+#if ENABLE_FEATURE_OSF_LABEL
+ smallint possibly_osf_label;
+#endif
+
+ smallint listing; /* no aborts for fdisk -l */
+ smallint dos_compatible_flag; // = 1;
+#if ENABLE_FEATURE_FDISK_WRITABLE
+ //int dos_changed;
+ smallint nowarn; /* no warnings for fdisk -l/-s */
+#endif
+ int ext_index; /* the prime extended partition */
+ unsigned user_cylinders, user_heads, user_sectors;
+ unsigned pt_heads, pt_sectors;
+ unsigned kern_heads, kern_sectors;
+ ullong extended_offset; /* offset of link pointers */
+ ullong total_number_of_sectors;
+
+ jmp_buf listingbuf;
char line_buffer[80];
char partname_buffer[80];
- jmp_buf listingbuf;
/* Raw disk label. For DOS-type partition tables the MBR,
* with descriptions of the primary partitions. */
char MBRbuffer[MAX_SECTOR_SIZE];
/* Partition tables */
struct pte ptes[MAXIMUM_PARTS];
};
-/* bb_common_bufsiz1 is too small for this on 64 bit CPUs */
#define G (*ptr_to_globals)
-
-#define line_ptr (G.line_ptr)
-#define listingbuf (G.listingbuf)
-#define line_buffer (G.line_buffer)
+#define line_ptr (G.line_ptr )
+#define disk_device (G.disk_device )
+#define g_partitions (G.g_partitions )
+#define units_per_sector (G.units_per_sector )
+#define sector_size (G.sector_size )
+#define user_set_sector_size (G.user_set_sector_size)
+#define sector_offset (G.sector_offset )
+#define g_heads (G.g_heads )
+#define g_sectors (G.g_sectors )
+#define g_cylinders (G.g_cylinders )
+#define current_label_type (G.current_label_type )
+#define display_in_cyl_units (G.display_in_cyl_units)
+#define possibly_osf_label (G.possibly_osf_label )
+#define listing (G.listing )
+#define dos_compatible_flag (G.dos_compatible_flag )
+#define nowarn (G.nowarn )
+#define ext_index (G.ext_index )
+#define user_cylinders (G.user_cylinders )
+#define user_heads (G.user_heads )
+#define user_sectors (G.user_sectors )
+#define pt_heads (G.pt_heads )
+#define pt_sectors (G.pt_sectors )
+#define kern_heads (G.kern_heads )
+#define kern_sectors (G.kern_sectors )
+#define extended_offset (G.extended_offset )
+#define total_number_of_sectors (G.total_number_of_sectors)
+#define listingbuf (G.listingbuf )
+#define line_buffer (G.line_buffer )
#define partname_buffer (G.partname_buffer)
-#define MBRbuffer (G.MBRbuffer)
-#define ptes (G.ptes)
+#define MBRbuffer (G.MBRbuffer )
+#define ptes (G.ptes )
+#define INIT_G() do { \
+ SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \
+ sector_size = DEFAULT_SECTOR_SIZE; \
+ sector_offset = 1; \
+ g_partitions = 4; \
+ display_in_cyl_units = 1; \
+ units_per_sector = 1; \
+ dos_compatible_flag = 1; \
+} while (0)
+
+
+/* TODO: move to libbb? */
+static ullong bb_BLKGETSIZE_sectors(int fd)
+{
+ uint64_t v64;
+ unsigned long longsectors;
+ if (ioctl(fd, BLKGETSIZE64, &v64) == 0) {
+ /* Got bytes, convert to 512 byte sectors */
+ return (v64 >> 9);
+ }
+ /* Needs temp of type long */
+ if (ioctl(fd, BLKGETSIZE, &longsectors))
+ longsectors = 0;
+ return longsectors;
+}
-/* Code */
#define IS_EXTENDED(i) \
((i) == EXTENDED || (i) == WIN98_EXTENDED || (i) == LINUX_EXTENDED)
#define set_hsc(h,s,c,sector) \
do { \
- s = sector % sectors + 1; \
- sector /= sectors; \
- h = sector % heads; \
- sector /= heads; \
- c = sector & 0xff; \
- s |= (sector >> 2) & 0xc0; \
+ s = sector % g_sectors + 1; \
+ sector /= g_sectors; \
+ h = sector % g_heads; \
+ sector /= g_heads; \
+ c = sector & 0xff; \
+ s |= (sector >> 2) & 0xc0; \
} while (0)
+static void
+close_dev_fd(void)
+{
+ /* Not really closing, but making sure it is open, and to harmless place */
+ xmove_fd(xopen(bb_dev_null, O_RDONLY), dev_fd);
+}
+
#if ENABLE_FEATURE_FDISK_WRITABLE
-/* read line; return 0 or first printable char */
+/* Read line; return 0 or first printable char */
static int
read_line(const char *prompt)
{
sz = read_line_input(prompt, line_buffer, sizeof(line_buffer), NULL);
if (sz <= 0)
- exit(0); /* Ctrl-D or Ctrl-C */
+ exit(EXIT_SUCCESS); /* Ctrl-D or Ctrl-C */
if (line_buffer[sz-1] == '\n')
line_buffer[--sz] = '\0';
#endif
/*
- * return partition name - uses static storage
+ * Return partition name - uses static storage
*/
static const char *
partname(const char *dev, int pno, int lth)
static char
read_nonempty(const char *mesg)
{
- while (!read_line(mesg)) /* repeat */;
+ while (!read_line(mesg))
+ continue;
return *line_ptr;
}
}
#endif /* FEATURE_FDISK_WRITABLE */
+static void fdisk_fatal(const char *why)
+{
+ if (listing) {
+ close_dev_fd();
+ longjmp(listingbuf, 1);
+ }
+ bb_error_msg_and_die(why, disk_device);
+}
+
+static void
+seek_sector(ullong secno)
+{
+ secno *= sector_size;
+#if ENABLE_FDISK_SUPPORT_LARGE_DISKS
+ if (lseek64(dev_fd, (off64_t)secno, SEEK_SET) == (off64_t) -1)
+ fdisk_fatal(unable_to_seek);
+#else
+ if (secno > MAXINT(off_t)
+ || lseek(dev_fd, (off_t)secno, SEEK_SET) == (off_t) -1
+ ) {
+ fdisk_fatal(unable_to_seek);
+ }
+#endif
+}
+
+#if ENABLE_FEATURE_FDISK_WRITABLE
+static void
+write_sector(ullong secno, const void *buf)
+{
+ seek_sector(secno);
+ xwrite(dev_fd, buf, sector_size);
+}
+#endif
+
+
#include "fdisk_aix.c"
typedef struct {
STATIC_SUN void sun_write_table(void);
#include "fdisk_sun.c"
+
#if ENABLE_FEATURE_FDISK_WRITABLE
/* start_sect and nr_sects are stored little endian on all machines */
/* moreover, they are not aligned correctly */
return read4_little_endian(p->size4);
}
-/* normally O_RDWR, -l option gives O_RDONLY */
-static int type_open = O_RDWR;
-
-static int ext_index; /* the prime extended partition */
-static int listing; /* no aborts for fdisk -l */
-static int dos_compatible_flag = ~0;
-#if ENABLE_FEATURE_FDISK_WRITABLE
-static int dos_changed;
-static int nowarn; /* no warnings for fdisk -l/-s */
-#endif
-
-static unsigned user_cylinders, user_heads, user_sectors;
-static unsigned pt_heads, pt_sectors;
-static unsigned kern_heads, kern_sectors;
-
-static ullong extended_offset; /* offset of link pointers */
-static ullong total_number_of_sectors;
-
-static void fdisk_fatal(const char *why)
-{
- if (listing) {
- close(fd);
- longjmp(listingbuf, 1);
- }
- bb_error_msg_and_die(why, disk_device);
-}
-
-static void
-seek_sector(ullong secno)
-{
- secno *= sector_size;
- if (lseek64(fd, (off64_t)secno, SEEK_SET) == (off64_t) -1)
- fdisk_fatal(unable_to_seek);
-}
-
-#if ENABLE_FEATURE_FDISK_WRITABLE
-static void
-write_sector(ullong secno, char *buf)
-{
- seek_sector(secno);
- if (write(fd, buf, sector_size) != sector_size)
- fdisk_fatal(unable_to_write);
-}
-#endif
-
/* Allocate a buffer and read a partition table sector */
static void
read_pte(struct pte *pe, ullong offset)
{
pe->offset = offset;
- pe->sectorbuffer = xmalloc(sector_size);
+ pe->sectorbuffer = xzalloc(sector_size);
seek_sector(offset);
- if (read(fd, pe->sectorbuffer, sector_size) != sector_size)
+ /* xread would make us abort - bad for fdisk -l */
+ if (full_read(dev_fd, pe->sectorbuffer, sector_size) != sector_size)
fdisk_fatal(unable_to_read);
#if ENABLE_FEATURE_FDISK_WRITABLE
pe->changed = 0;
* We might also do the opposite and warn in all cases except
* for "is probably nondos partition".
*/
+#ifdef UNUSED
static int
is_dos_partition(int t)
{
t == 0x1b || t == 0x1c || t == 0x1e || t == 0x24 ||
t == 0xc1 || t == 0xc4 || t == 0xc6);
}
+#endif
static void
menu(void)
unsigned done, next, size;
int i;
- for (size = 0; sys[size]; size++) /* */;
+ for (size = 0; sys[size]; size++)
+ continue;
done = 0;
for (i = COLS-1; i >= 0; i--) {
next = ++done;
}
} while (done < last[0]);
- putchar('\n');
+ bb_putchar('\n');
}
#endif /* FEATURE_FDISK_WRITABLE */
p->sys_ind = sysid;
set_start_sect(p, start - offset);
set_nr_sects(p, stop - start + 1);
- if (dos_compatible_flag && (start/(sectors*heads) > 1023))
- start = heads*sectors*1024 - 1;
+ if (dos_compatible_flag && (start / (g_sectors * g_heads) > 1023))
+ start = g_heads * g_sectors * 1024 - 1;
set_hsc(p->head, p->sector, p->cyl, start);
- if (dos_compatible_flag && (stop/(sectors*heads) > 1023))
- stop = heads*sectors*1024 - 1;
+ if (dos_compatible_flag && (stop / (g_sectors * g_heads) > 1023))
+ stop = g_heads * g_sectors * 1024 - 1;
set_hsc(p->end_head, p->end_sector, p->end_cyl, stop);
ptes[i].changed = 1;
}
static int
warn_geometry(void)
{
- if (heads && sectors && cylinders)
+ if (g_heads && g_sectors && g_cylinders)
return 0;
printf("Unknown value(s) for:");
- if (!heads)
+ if (!g_heads)
printf(" heads");
- if (!sectors)
+ if (!g_sectors)
printf(" sectors");
- if (!cylinders)
+ if (!g_cylinders)
printf(" cylinders");
printf(
#if ENABLE_FEATURE_FDISK_WRITABLE
static void
update_units(void)
{
- int cyl_units = heads * sectors;
+ int cyl_units = g_heads * g_sectors;
if (display_in_cyl_units && cyl_units)
units_per_sector = cyl_units;
static void
warn_cylinders(void)
{
- if (LABEL_IS_DOS && cylinders > 1024 && !nowarn)
+ if (LABEL_IS_DOS && g_cylinders > 1024 && !nowarn)
printf("\n"
"The number of cylinders for this disk is set to %d.\n"
"There is nothing wrong with that, but this is larger than 1024,\n"
"1) software that runs at boot time (e.g., old versions of LILO)\n"
"2) booting and partitioning software from other OSs\n"
" (e.g., DOS FDISK, OS/2 FDISK)\n",
- cylinders);
+ g_cylinders);
}
#endif
}
while (IS_EXTENDED(p->sys_ind)) {
- struct pte *pe = &ptes[partitions];
+ struct pte *pe = &ptes[g_partitions];
- if (partitions >= MAXIMUM_PARTS) {
+ if (g_partitions >= MAXIMUM_PARTS) {
/* This is not a Linux restriction, but
this program uses arrays of size MAXIMUM_PARTS.
Do not try to 'improve' this test. */
- struct pte *pre = &ptes[partitions-1];
+ struct pte *pre = &ptes[g_partitions - 1];
#if ENABLE_FEATURE_FDISK_WRITABLE
printf("Warning: deleting partitions after %d\n",
- partitions);
+ g_partitions);
pre->changed = 1;
#endif
clear_partition(pre->ext_pointer);
if (pe->ext_pointer)
printf("Warning: extra link "
"pointer in partition table"
- " %d\n", partitions + 1);
+ " %d\n", g_partitions + 1);
else
pe->ext_pointer = p;
} else if (p->sys_ind) {
if (pe->part_table)
printf("Warning: ignoring extra "
"data in partition table"
- " %d\n", partitions + 1);
+ " %d\n", g_partitions + 1);
else
pe->part_table = p;
}
}
p = pe->ext_pointer;
- partitions++;
+ g_partitions++;
}
#if ENABLE_FEATURE_FDISK_WRITABLE
/* remove empty links */
remove:
- for (i = 4; i < partitions; i++) {
+ for (i = 4; i < g_partitions; i++) {
struct pte *pe = &ptes[i];
if (!get_nr_sects(pe->part_table)
- && (partitions > 5 || ptes[4].part_table->sys_ind)
+ && (g_partitions > 5 || ptes[4].part_table->sys_ind)
) {
printf("Omitting empty partition (%d)\n", i+1);
delete_partition(i);
printf(msg_building_new_label, "DOS disklabel");
- current_label_type = label_dos;
+ current_label_type = LABEL_DOS;
#if ENABLE_FEATURE_OSF_LABEL
possibly_osf_label = 0;
#endif
- partitions = 4;
+ g_partitions = 4;
for (i = 510-64; i < 510; i++)
MBRbuffer[i] = 0;
extended_offset = 0;
set_all_unchanged();
set_changed(0);
- get_boot(create_empty_dos);
+ get_boot(CREATE_EMPTY_DOS);
}
#endif /* FEATURE_FDISK_WRITABLE */
{
if (!user_set_sector_size) {
int arg;
- if (ioctl(fd, BLKSSZGET, &arg) == 0)
+ if (ioctl(dev_fd, BLKSSZGET, &arg) == 0)
sector_size = arg;
if (sector_size != DEFAULT_SECTOR_SIZE)
- printf("Note: sector size is %d (not %d)\n",
- sector_size, DEFAULT_SECTOR_SIZE);
+ printf("Note: sector size is %d "
+ "(not " DEFAULT_SECTOR_SIZE_STR ")\n",
+ sector_size);
}
}
{
struct hd_geometry geometry;
- if (!ioctl(fd, HDIO_GETGEO, &geometry)) {
+ if (!ioctl(dev_fd, HDIO_GETGEO, &geometry)) {
kern_heads = geometry.heads;
kern_sectors = geometry.sectors;
/* never use geometry.cylinders - it is truncated */
get_geometry(void)
{
int sec_fac;
- uint64_t v64;
get_sectorsize();
sec_fac = sector_size / 512;
#if ENABLE_FEATURE_SUN_LABEL
guess_device_type();
#endif
- heads = cylinders = sectors = 0;
+ g_heads = g_cylinders = g_sectors = 0;
kern_heads = kern_sectors = 0;
pt_heads = pt_sectors = 0;
get_kernel_geometry();
get_partition_table_geometry();
- heads = user_heads ? user_heads :
+ g_heads = user_heads ? user_heads :
pt_heads ? pt_heads :
kern_heads ? kern_heads : 255;
- sectors = user_sectors ? user_sectors :
+ g_sectors = user_sectors ? user_sectors :
pt_sectors ? pt_sectors :
kern_sectors ? kern_sectors : 63;
- if (ioctl(fd, BLKGETSIZE64, &v64) == 0) {
- /* got bytes, convert to 512 byte sectors */
- total_number_of_sectors = (v64 >> 9);
- } else {
- unsigned long longsectors; /* need temp of type long */
- if (ioctl(fd, BLKGETSIZE, &longsectors))
- longsectors = 0;
- total_number_of_sectors = longsectors;
- }
+ total_number_of_sectors = bb_BLKGETSIZE_sectors(dev_fd);
sector_offset = 1;
if (dos_compatible_flag)
- sector_offset = sectors;
+ sector_offset = g_sectors;
- cylinders = total_number_of_sectors / (heads * sectors * sec_fac);
- if (!cylinders)
- cylinders = user_cylinders;
+ g_cylinders = total_number_of_sectors / (g_heads * g_sectors * sec_fac);
+ if (!g_cylinders)
+ g_cylinders = user_cylinders;
}
/*
- * Read MBR. Returns:
+ * Opens disk_device and optionally reads MBR.
+ * FIXME: document what each 'what' value will do!
+ * Returns:
* -1: no 0xaa55 flag present (possibly entire disk BSD)
* 0: found or created label
* 1: I/O error
*/
-static int
-get_boot(enum action what)
+#if ENABLE_FEATURE_SUN_LABEL || ENABLE_FEATURE_FDISK_WRITABLE
+static int get_boot(enum action what)
+#else
+static int get_boot(void)
+#define get_boot(what) get_boot()
+#endif
{
- int i;
-
- partitions = 4;
+ int i, fd;
+ g_partitions = 4;
for (i = 0; i < 4; i++) {
struct pte *pe = &ptes[i];
-
pe->part_table = pt_offset(MBRbuffer, i);
pe->ext_pointer = NULL;
pe->offset = 0;
pe->sectorbuffer = MBRbuffer;
#if ENABLE_FEATURE_FDISK_WRITABLE
- pe->changed = (what == create_empty_dos);
+ pe->changed = (what == CREATE_EMPTY_DOS);
#endif
}
-#if ENABLE_FEATURE_SUN_LABEL
- if (what == create_empty_sun && check_sun_label())
- return 0;
-#endif
-
- memset(MBRbuffer, 0, 512);
-
#if ENABLE_FEATURE_FDISK_WRITABLE
- if (what == create_empty_dos)
- goto got_dos_table; /* skip reading disk */
+// ALERT! highly idiotic design!
+// We end up here when we call get_boot() recursively
+// via get_boot() [table is bad] -> create_doslabel() -> get_boot(CREATE_EMPTY_DOS).
+// or get_boot() [table is bad] -> create_sunlabel() -> get_boot(CREATE_EMPTY_SUN).
+// (just factor out re-init of ptes[0,1,2,3] in a separate fn instead?)
+// So skip opening device _again_...
+ if (what == CREATE_EMPTY_DOS USE_FEATURE_SUN_LABEL(|| what == CREATE_EMPTY_SUN))
+ goto created_table;
+
+ fd = open(disk_device, (option_mask32 & OPT_l) ? O_RDONLY : O_RDWR);
- fd = open(disk_device, type_open);
if (fd < 0) {
fd = open(disk_device, O_RDONLY);
if (fd < 0) {
- if (what == try_only)
+ if (what == TRY_ONLY)
return 1;
fdisk_fatal(unable_to_open);
- } else
- printf("You will not be able to write "
- "the partition table\n");
+ }
+ printf("'%s' is opened for read only\n", disk_device);
}
-
- if (512 != read(fd, MBRbuffer, 512)) {
- if (what == try_only)
+ xmove_fd(fd, dev_fd);
+ if (512 != full_read(dev_fd, MBRbuffer, 512)) {
+ if (what == TRY_ONLY) {
+ close_dev_fd();
return 1;
+ }
fdisk_fatal(unable_to_read);
}
#else
fd = open(disk_device, O_RDONLY);
if (fd < 0)
return 1;
- if (512 != read(fd, MBRbuffer, 512))
+ if (512 != full_read(fd, MBRbuffer, 512)) {
+ close(fd);
return 1;
+ }
+ xmove_fd(fd, dev_fd);
#endif
get_geometry();
-
update_units();
#if ENABLE_FEATURE_SUN_LABEL
if (check_sun_label())
return 0;
#endif
-
#if ENABLE_FEATURE_SGI_LABEL
if (check_sgi_label())
return 0;
#endif
-
#if ENABLE_FEATURE_AIX_LABEL
if (check_aix_label())
return 0;
#endif
-
#if ENABLE_FEATURE_OSF_LABEL
if (check_osf_label()) {
possibly_osf_label = 1;
if (!valid_part_table_flag(MBRbuffer)) {
- current_label_type = label_osf;
+ current_label_type = LABEL_OSF;
return 0;
}
printf("This disk has both DOS and BSD magic.\n"
}
#endif
-#if ENABLE_FEATURE_FDISK_WRITABLE
- got_dos_table:
-#endif
-
- if (!valid_part_table_flag(MBRbuffer)) {
#if !ENABLE_FEATURE_FDISK_WRITABLE
+ if (!valid_part_table_flag(MBRbuffer))
return -1;
#else
- switch (what) {
- case fdisk:
+ if (!valid_part_table_flag(MBRbuffer)) {
+ if (what == OPEN_MAIN) {
printf("Device contains neither a valid DOS "
"partition table, nor Sun, SGI or OSF "
"disklabel\n");
#ifdef __sparc__
-#if ENABLE_FEATURE_SUN_LABEL
- create_sunlabel();
-#endif
+ USE_FEATURE_SUN_LABEL(create_sunlabel();)
#else
create_doslabel();
#endif
return 0;
- case try_only:
- return -1;
- case create_empty_dos:
-#if ENABLE_FEATURE_SUN_LABEL
- case create_empty_sun:
-#endif
- break;
- default:
- bb_error_msg_and_die("internal error");
}
-#endif /* FEATURE_FDISK_WRITABLE */
+ /* TRY_ONLY: */
+ return -1;
}
+ created_table:
+#endif /* FEATURE_FDISK_WRITABLE */
-#if ENABLE_FEATURE_FDISK_WRITABLE
- warn_cylinders();
-#endif
+
+ USE_FEATURE_FDISK_WRITABLE(warn_cylinders();)
warn_geometry();
for (i = 0; i < 4; i++) {
- struct pte *pe = &ptes[i];
-
- if (IS_EXTENDED(pe->part_table->sys_ind)) {
- if (partitions != 4)
+ if (IS_EXTENDED(ptes[i].part_table->sys_ind)) {
+ if (g_partitions != 4)
printf("Ignoring extra extended "
"partition %d\n", i + 1);
else
}
}
- for (i = 3; i < partitions; i++) {
+ for (i = 3; i < g_partitions; i++) {
struct pte *pe = &ptes[i];
-
if (!valid_part_table_flag(pe->sectorbuffer)) {
printf("Warning: invalid flag 0x%02x,0x%02x of partition "
"table %d will be corrected by w(rite)\n",
pe->sectorbuffer[510],
pe->sectorbuffer[511],
i + 1);
-#if ENABLE_FEATURE_FDISK_WRITABLE
- pe->changed = 1;
-#endif
+ USE_FEATURE_FDISK_WRITABLE(pe->changed = 1;)
}
}
case 'c':
case 'C':
if (!display_in_cyl_units)
- i *= heads * sectors;
+ i *= g_heads * g_sectors;
break;
case 'K':
absolute = 1024;
static void
toggle_dos_compatibility_flag(void)
{
- dos_compatible_flag = ~dos_compatible_flag;
+ dos_compatible_flag = 1 - dos_compatible_flag;
if (dos_compatible_flag) {
- sector_offset = sectors;
+ sector_offset = g_sectors;
printf("DOS Compatibility flag is set\n");
} else {
sector_offset = 1;
if (i < 4) {
if (IS_EXTENDED(p->sys_ind) && i == ext_index) {
- partitions = 4;
+ g_partitions = 4;
ptes[ext_index].ext_pointer = NULL;
extended_offset = 0;
}
if (!q->sys_ind && i > 4) {
/* the last one in the chain - just delete */
- --partitions;
+ --g_partitions;
--i;
clear_partition(ptes[i].ext_pointer);
ptes[i].changed = 1;
set_start_sect(p, get_start_sect(q));
set_nr_sects(p, get_nr_sects(q));
ptes[i-1].changed = 1;
- } else if (partitions > 5) { /* 5 will be moved to 4 */
+ } else if (g_partitions > 5) { /* 5 will be moved to 4 */
/* the first logical in a longer chain */
pe = &ptes[5];
pe->changed = 1;
}
- if (partitions > 5) {
- partitions--;
- while (i < partitions) {
+ if (g_partitions > 5) {
+ g_partitions--;
+ while (i < g_partitions) {
ptes[i] = ptes[i+1];
i++;
}
let the user select a partition, since get_existing_partition()
only works for Linux like partition tables. */
if (!LABEL_IS_SGI) {
- i = get_existing_partition(0, partitions);
+ i = get_existing_partition(0, g_partitions);
} else {
- i = get_partition(0, partitions);
+ i = get_partition(0, g_partitions);
}
if (i == -1)
return;
"to %x (%s)\n", i + 1, sys,
partition_type(sys));
ptes[i].changed = 1;
- if (is_dos_partition(origsys) ||
- is_dos_partition(sys))
- dos_changed = 1;
+ //if (is_dos_partition(origsys) || is_dos_partition(sys))
+ // dos_changed = 1;
break;
}
}
static void
linear2chs(unsigned ls, unsigned *c, unsigned *h, unsigned *s)
{
- int spc = heads * sectors;
+ int spc = g_heads * g_sectors;
*c = ls / spc;
ls = ls % spc;
- *h = ls / sectors;
- *s = ls % sectors + 1; /* sectors count from 1 */
+ *h = ls / g_sectors;
+ *s = ls % g_sectors + 1; /* sectors count from 1 */
}
static void
unsigned lbc, lbh, lbs; /* logical beginning c, h, s */
unsigned lec, leh, les; /* logical ending c, h, s */
- if (!heads || !sectors || (partition >= 4))
+ if (!g_heads || !g_sectors || (partition >= 4))
return; /* do not check extended partitions */
/* physical beginning c, h, s */
linear2chs(get_start_sect(p) + get_nr_sects(p) - 1, &lec, &leh, &les);
/* Same physical / logical beginning? */
- if (cylinders <= 1024 && (pbc != lbc || pbh != lbh || pbs != lbs)) {
+ if (g_cylinders <= 1024 && (pbc != lbc || pbh != lbh || pbs != lbs)) {
printf("Partition %d has different physical/logical "
"beginnings (non-Linux?):\n", partition + 1);
printf(" phys=(%d, %d, %d) ", pbc, pbh, pbs);
- printf("logical=(%d, %d, %d)\n",lbc, lbh, lbs);
+ printf("logical=(%d, %d, %d)\n", lbc, lbh, lbs);
}
/* Same physical / logical ending? */
- if (cylinders <= 1024 && (pec != lec || peh != leh || pes != les)) {
+ if (g_cylinders <= 1024 && (pec != lec || peh != leh || pes != les)) {
printf("Partition %d has different physical/logical "
"endings:\n", partition + 1);
printf(" phys=(%d, %d, %d) ", pec, peh, pes);
}
/* Ending on cylinder boundary? */
- if (peh != (heads - 1) || pes != sectors) {
+ if (peh != (g_heads - 1) || pes != g_sectors) {
printf("Partition %i does not end on cylinder boundary\n",
partition + 1);
}
printf("\nDisk %s: %ld.%ld GB, %lld bytes\n",
disk_device, megabytes/1000, (megabytes/100)%10, bytes);
printf("%d heads, %d sectors/track, %d cylinders",
- heads, sectors, cylinders);
+ g_heads, g_sectors, g_cylinders);
if (units_per_sector == 1)
printf(", total %llu sectors",
total_number_of_sectors / (sector_size/512));
ullong last_p_start_pos = 0, p_start_pos;
int i, last_i = 0;
- for (i = 0 ; i < partitions; i++) {
+ for (i = 0; i < g_partitions; i++) {
if (i == 4) {
last_i = 4;
last_p_start_pos = 0;
}
pe = &ptes[i];
- if ((p = pe->part_table)->sys_ind) {
+ p = pe->part_table;
+ if (p->sys_ind) {
p_start_pos = get_partition_start(pe);
if (last_p_start_pos > p_start_pos) {
/* Stage 1: sort sectors but leave sector of part 4 */
/* (Its sector is the global extended_offset.) */
stage1:
- for (j = 5; j < partitions-1; j++) {
+ for (j = 5; j < g_partitions - 1; j++) {
oj = ptes[j].offset;
ojj = ptes[j+1].offset;
if (oj > ojj) {
/* Stage 2: sort starting sectors */
stage2:
- for (j = 4; j < partitions-1; j++) {
+ for (j = 4; j < g_partitions - 1; j++) {
pj = ptes[j].part_table;
pjj = ptes[j+1].part_table;
sj = get_start_sect(pj);
}
/* Probably something was changed */
- for (j = 4; j < partitions; j++)
+ for (j = 4; j < g_partitions; j++)
ptes[j].changed = 1;
}
printf("%*s Boot Start End Blocks Id System\n",
w+1, "Device");
- for (i = 0; i < partitions; i++) {
+ for (i = 0; i < g_partitions; i++) {
const struct pte *pe = &ptes[i];
ullong psects;
ullong pblocks;
int i;
printf("\nDisk %s: %d heads, %d sectors, %d cylinders\n\n",
- disk_device, heads, sectors, cylinders);
+ disk_device, g_heads, g_sectors, g_cylinders);
printf("Nr AF Hd Sec Cyl Hd Sec Cyl Start Size ID\n");
- for (i = 0 ; i < partitions; i++) {
+ for (i = 0; i < g_partitions; i++) {
pe = &ptes[i];
p = (extend ? pe->ext_pointer : pe->part_table);
if (p != NULL) {
const struct pte *pe = &ptes[0];
const struct partition *p;
- for (i = 0; i < partitions; pe++,i++) {
+ for (i = 0; i < g_partitions; pe++,i++) {
p = pe->part_table;
if (!p->sys_ind || IS_EXTENDED(p->sys_ind)) {
first[i] = 0xffffffff;
real_s = sector(s) - 1;
real_c = cylinder(s, c);
- total = (real_c * sectors + real_s) * heads + h;
+ total = (real_c * g_sectors + real_s) * g_heads + h;
if (!total)
printf("Partition %d contains sector 0\n", n);
- if (h >= heads)
+ if (h >= g_heads)
printf("Partition %d: head %d greater than maximum %d\n",
- n, h + 1, heads);
- if (real_s >= sectors)
+ n, h + 1, g_heads);
+ if (real_s >= g_sectors)
printf("Partition %d: sector %d greater than "
- "maximum %d\n", n, s, sectors);
- if (real_c >= cylinders)
+ "maximum %d\n", n, s, g_sectors);
+ if (real_c >= g_cylinders)
printf("Partition %d: cylinder %llu greater than "
- "maximum %d\n", n, real_c + 1, cylinders);
- if (cylinders <= 1024 && start != total)
+ "maximum %d\n", n, real_c + 1, g_cylinders);
+ if (g_cylinders <= 1024 && start != total)
printf("Partition %d: previous sectors %llu disagrees with "
"total %llu\n", n, start, total);
}
{
int i, j;
unsigned total = 1;
- ullong first[partitions], last[partitions];
+ ullong first[g_partitions], last[g_partitions];
struct partition *p;
if (warn_geometry())
}
fill_bounds(first, last);
- for (i = 0; i < partitions; i++) {
+ for (i = 0; i < g_partitions; i++) {
struct pte *pe = &ptes[i];
p = pe->part_table;
ullong e_last = get_start_sect(pex->part_table) +
get_nr_sects(pex->part_table) - 1;
- for (i = 4; i < partitions; i++) {
+ for (i = 4; i < g_partitions; i++) {
total++;
p = ptes[i].part_table;
if (!p->sys_ind) {
- if (i != 4 || i + 1 < partitions)
+ if (i != 4 || i + 1 < g_partitions)
printf("Warning: partition %d "
"is empty\n", i + 1);
} else if (first[i] < extended_offset || last[i] > e_last) {
}
}
- if (total > heads * sectors * cylinders)
+ if (total > g_heads * g_sectors * g_cylinders)
printf("Total allocated sectors %d greater than the maximum "
- "%d\n", total, heads * sectors * cylinders);
+ "%d\n", total, g_heads * g_sectors * g_cylinders);
else {
- total = heads * sectors * cylinders - total;
+ total = g_heads * g_sectors * g_cylinders - total;
if (total != 0)
printf("%d unallocated sectors\n", total);
}
struct partition *q = ptes[ext_index].part_table;
ullong limit, temp;
ullong start, stop = 0;
- ullong first[partitions], last[partitions];
+ ullong first[g_partitions], last[g_partitions];
if (p && p->sys_ind) {
printf(msg_part_already_defined, n + 1);
if (n < 4) {
start = sector_offset;
if (display_in_cyl_units || !total_number_of_sectors)
- limit = (ullong) heads * sectors * cylinders - 1;
+ limit = (ullong) g_heads * g_sectors * g_cylinders - 1;
else
limit = total_number_of_sectors - 1;
if (extended_offset) {
limit = get_start_sect(q) + get_nr_sects(q) - 1;
}
if (display_in_cyl_units)
- for (i = 0; i < partitions; i++)
+ for (i = 0; i < g_partitions; i++)
first[i] = (cround(first[i]) - 1) * units_per_sector;
snprintf(mesg, sizeof(mesg), "First %s", str_units(SINGULAR));
do {
temp = start;
- for (i = 0; i < partitions; i++) {
+ for (i = 0; i < g_partitions; i++) {
int lastplusoff;
if (start == ptes[i].offset)
}
}
- for (i = 0; i < partitions; i++) {
+ for (i = 0; i < g_partitions; i++) {
struct pte *pe = &ptes[i];
if (start < pe->offset && limit >= pe->offset)
if (start > limit) {
printf("No free sectors available\n");
if (n > 4)
- partitions--;
+ g_partitions--;
return;
}
if (cround(start) == cround(limit)) {
pe4->part_table = pt_offset(pe4->sectorbuffer, 0);
pe4->ext_pointer = pe4->part_table + 1;
pe4->changed = 1;
- partitions = 5;
+ g_partitions = 5;
}
}
static void
add_logical(void)
{
- if (partitions > 5 || ptes[4].part_table->sys_ind) {
- struct pte *pe = &ptes[partitions];
+ if (g_partitions > 5 || ptes[4].part_table->sys_ind) {
+ struct pte *pe = &ptes[g_partitions];
pe->sectorbuffer = xzalloc(sector_size);
pe->part_table = pt_offset(pe->sectorbuffer, 0);
pe->ext_pointer = pe->part_table + 1;
pe->offset = 0;
pe->changed = 1;
- partitions++;
+ g_partitions++;
}
- add_partition(partitions - 1, LINUX_NATIVE);
+ add_partition(g_partitions - 1, LINUX_NATIVE);
}
static void
return;
if (LABEL_IS_SUN) {
- add_sun_partition(get_partition(0, partitions), LINUX_NATIVE);
+ add_sun_partition(get_partition(0, g_partitions), LINUX_NATIVE);
return;
}
if (LABEL_IS_SGI) {
- sgi_add_partition(get_partition(0, partitions), LINUX_NATIVE);
+ sgi_add_partition(get_partition(0, g_partitions), LINUX_NATIVE);
return;
}
if (LABEL_IS_AIX) {
for (i = 0; i < 4; i++)
free_primary += !ptes[i].part_table->sys_ind;
- if (!free_primary && partitions >= MAXIMUM_PARTS) {
+ if (!free_primary && g_partitions >= MAXIMUM_PARTS) {
printf("The maximum number of partitions has been created\n");
return;
}
for (i = 0; i < 3; i++)
if (ptes[i].changed)
ptes[3].changed = 1;
- for (i = 3; i < partitions; i++) {
+ for (i = 3; i < g_partitions; i++) {
struct pte *pe = &ptes[i];
if (pe->changed) {
printf("Calling ioctl() to re-read partition table\n");
sync();
/* sleep(2); Huh? */
- i = ioctl(fd, BLKRRPART);
-#if 0
- else {
- /* some kernel versions (1.2.x) seem to have trouble
- rereading the partition table, but if asked to do it
- twice, the second time works. - biro@yggdrasil.com */
- sync();
- sleep(2);
- i = ioctl(fd, BLKRRPART);
- }
-#endif
-
- if (i) {
- bb_perror_msg("WARNING: rereading partition table "
+ i = ioctl_or_perror(dev_fd, BLKRRPART, NULL,
+ "WARNING: rereading partition table "
"failed, kernel still uses old table");
- }
-
#if 0
if (dos_changed)
printf(
if (leave) {
if (ENABLE_FEATURE_CLEAN_UP)
- close(fd);
+ close_dev_fd();
exit(i != 0);
}
}
printf("0x%03X:", i);
printf(" %02X", (unsigned char) pbuffer[i]);
if (l == MAX_PER_LINE - 1) {
- puts("");
+ bb_putchar('\n');
l = -1;
}
}
if (l > 0)
- puts("");
- puts("");
+ bb_putchar('\n');
+ bb_putchar('\n');
}
static void
if (LABEL_IS_SGI || LABEL_IS_SUN)
print_buffer(MBRbuffer);
else {
- for (i = 3; i < partitions; i++)
+ for (i = 3; i < g_partitions; i++)
print_buffer(ptes[i].sectorbuffer);
}
}
char c;
while (1) {
- putchar('\n');
+ bb_putchar('\n');
c = tolower(read_nonempty("Expert command (m for help): "));
switch (c) {
case 'a':
break;
case 'b':
if (LABEL_IS_DOS)
- move_begin(get_partition(0, partitions));
+ move_begin(get_partition(0, g_partitions));
break;
case 'c':
- user_cylinders = cylinders =
- read_int(1, cylinders, 1048576, 0,
+ user_cylinders = g_cylinders =
+ read_int(1, g_cylinders, 1048576, 0,
"Number of cylinders");
if (LABEL_IS_SUN)
- sun_set_ncyl(cylinders);
+ sun_set_ncyl(g_cylinders);
if (LABEL_IS_DOS)
warn_cylinders();
break;
#endif
break;
case 'h':
- user_heads = heads = read_int(1, heads, 256, 0,
+ user_heads = g_heads = read_int(1, g_heads, 256, 0,
"Number of heads");
update_units();
break;
x_list_table(0);
break;
case 'q':
- close(fd);
- puts("");
- exit(0);
+ if (ENABLE_FEATURE_CLEAN_UP)
+ close_dev_fd();
+ bb_putchar('\n');
+ exit(EXIT_SUCCESS);
case 'r':
return;
case 's':
- user_sectors = sectors = read_int(1, sectors, 63, 0,
+ user_sectors = g_sectors = read_int(1, g_sectors, 63, 0,
"Number of sectors");
if (dos_compatible_flag) {
- sector_offset = sectors;
+ sector_offset = g_sectors;
printf("Warning: setting sector offset for DOS "
"compatiblity\n");
}
return 0;
snprintf(buf, sizeof(buf), "/proc/ide/%s/media", device+5);
- procf = fopen(buf, "r");
+ procf = fopen_for_read(buf);
if (procf != NULL && fgets(buf, sizeof(buf), procf))
is_ide = (!strncmp(buf, "cdrom", 5) ||
!strncmp(buf, "tape", 4));
static void
-trydev(const char *device, int user_specified)
+open_list_and_close(const char *device, int user_specified)
{
int gb;
if (!user_specified)
if (is_ide_cdrom_or_tape(device))
return;
- fd = open(disk_device, type_open);
- if (fd >= 0) {
- gb = get_boot(try_only);
- if (gb > 0) { /* I/O error */
- close(fd);
- } else if (gb < 0) { /* no DOS signature */
- list_disk_geometry();
- if (LABEL_IS_AIX) {
- return;
- }
-#if ENABLE_FEATURE_OSF_LABEL
- if (bsd_trydev(device) < 0)
-#endif
- printf("Disk %s doesn't contain a valid "
- "partition table\n", device);
- close(fd);
- } else {
- close(fd);
- list_table(0);
-#if ENABLE_FEATURE_FDISK_WRITABLE
- if (!LABEL_IS_SUN && partitions > 4){
- delete_partition(ext_index);
- }
-#endif
- }
- } else {
+
+ /* Open disk_device, save file descriptor to dev_fd */
+ errno = 0;
+ gb = get_boot(TRY_ONLY);
+ if (gb > 0) { /* I/O error */
/* Ignore other errors, since we try IDE
and SCSI hard disks which may not be
installed on the system. */
- if (errno == EACCES) {
- printf("Cannot open %s\n", device);
- return;
+ if (user_specified || errno == EACCES)
+ bb_perror_msg("can't open '%s'", device);
+ return;
+ }
+
+ if (gb < 0) { /* no DOS signature */
+ list_disk_geometry();
+ if (LABEL_IS_AIX)
+ goto ret;
+#if ENABLE_FEATURE_OSF_LABEL
+ if (bsd_trydev(device) < 0)
+#endif
+ printf("Disk %s doesn't contain a valid "
+ "partition table\n", device);
+ } else {
+ list_table(0);
+#if ENABLE_FEATURE_FDISK_WRITABLE
+ if (!LABEL_IS_SUN && g_partitions > 4) {
+ delete_partition(ext_index);
}
+#endif
}
+ ret:
+ close_dev_fd();
}
/* for fdisk -l: try all things in /proc/partitions
that look like a partition name (do not end in a digit) */
static void
-tryprocpt(void)
+list_devs_in_proc_partititons(void)
{
FILE *procpt;
char line[100], ptname[100], devname[120], *s;
if (sscanf(line, " %d %d %d %[^\n ]",
&ma, &mi, &sz, ptname) != 4)
continue;
- for (s = ptname; *s; s++);
+ for (s = ptname; *s; s++)
+ continue;
if (isdigit(s[-1]))
continue;
sprintf(devname, "/dev/%s", ptname);
- trydev(devname, 0);
+ open_list_and_close(devname, 0);
}
#if ENABLE_FEATURE_CLEAN_UP
fclose(procpt);
}
#endif
-int fdisk_main(int argc, char **argv);
+int fdisk_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
int fdisk_main(int argc, char **argv)
{
- char *str_b, *str_C, *str_H, *str_S;
unsigned opt;
/*
* fdisk -v
*
* Options -C, -H, -S set the geometry.
*/
- enum {
- OPT_b = 1 << 0,
- OPT_C = 1 << 1,
- OPT_H = 1 << 2,
- OPT_l = 1 << 3,
- OPT_S = 1 << 4,
- OPT_u = 1 << 5,
- OPT_s = (1 << 6) * ENABLE_FEATURE_FDISK_BLKSIZE,
- };
-
- PTR_TO_GLOBALS = xzalloc(sizeof(G));
-
- opt = getopt32(argc, argv, "b:C:H:lS:u" USE_FEATURE_FDISK_BLKSIZE("s"),
- &str_b, &str_C, &str_H, &str_S);
+ INIT_G();
+
+ close_dev_fd(); /* needed: fd 3 must not stay closed */
+
+ opt_complementary = "b+:C+:H+:S+"; /* numeric params */
+ opt = getopt32(argv, "b:C:H:lS:u" USE_FEATURE_FDISK_BLKSIZE("s"),
+ §or_size, &user_cylinders, &user_heads, &user_sectors);
argc -= optind;
argv += optind;
if (opt & OPT_b) { // -b
so cannot be combined with multiple disks,
and the same goes for the C/H/S options.
*/
- sector_size = xatoi_u(str_b);
- if (sector_size != 512 && sector_size != 1024 &&
- sector_size != 2048)
+ if (sector_size != 512 && sector_size != 1024
+ && sector_size != 2048)
bb_show_usage();
sector_offset = 2;
user_set_sector_size = 1;
}
- if (opt & OPT_C) user_cylinders = xatoi_u(str_C); // -C
- if (opt & OPT_H) { // -H
- user_heads = xatoi_u(str_H);
- if (user_heads <= 0 || user_heads >= 256)
- user_heads = 0;
- }
- //if (opt & OPT_l) // -l
- if (opt & OPT_S) { // -S
- user_sectors = xatoi_u(str_S);
- if (user_sectors <= 0 || user_sectors >= 64)
- user_sectors = 0;
- }
- if (opt & OPT_u) display_in_cyl_units = 0; // -u
- //if (opt & OPT_s) // -s
-
- if (user_set_sector_size && argc != 1)
- printf("Warning: the -b (set sector size) option should"
- " be used with one specified device\n");
+ if (user_heads <= 0 || user_heads >= 256)
+ user_heads = 0;
+ if (user_sectors <= 0 || user_sectors >= 64)
+ user_sectors = 0;
+ if (opt & OPT_u)
+ display_in_cyl_units = 0; // -u
#if ENABLE_FEATURE_FDISK_WRITABLE
if (opt & OPT_l) {
nowarn = 1;
#endif
- type_open = O_RDONLY;
- if (argc > 0) {
- int k;
-#if defined(__GNUC__)
- /* avoid gcc warning:
- variable `k' might be clobbered by `longjmp' */
- (void)&k;
-#endif
+ if (*argv) {
listing = 1;
- for (k = 0; k < argc; k++)
- trydev(argv[k], 1);
+ do {
+ open_list_and_close(*argv, 1);
+ } while (*++argv);
} else {
- /* we no longer have default device names */
- /* but, we can use /proc/partitions instead */
- tryprocpt();
+ /* we don't have device names, */
+ /* use /proc/partitions instead */
+ list_devs_in_proc_partititons();
}
return 0;
#if ENABLE_FEATURE_FDISK_WRITABLE
#if ENABLE_FEATURE_FDISK_BLKSIZE
if (opt & OPT_s) {
- long size;
int j;
nowarn = 1;
- type_open = O_RDONLY;
-
if (argc <= 0)
bb_show_usage();
-
for (j = 0; j < argc; j++) {
- disk_device = argv[j];
- fd = open(disk_device, type_open);
- if (fd < 0)
- fdisk_fatal(unable_to_open);
- if (ioctl(fd, BLKGETSIZE, &size))
- fdisk_fatal(ioctl_error);
+ unsigned long long size;
+ fd = xopen(argv[j], O_RDONLY);
+ size = bb_BLKGETSIZE_sectors(fd) / 2;
close(fd);
if (argc == 1)
- printf("%ld\n", size/2);
+ printf("%lld\n", size);
else
- printf("%s: %ld\n", argv[j], size/2);
+ printf("%s: %lld\n", argv[j], size);
}
return 0;
}
bb_show_usage();
disk_device = argv[0];
- get_boot(fdisk);
+ get_boot(OPEN_MAIN);
if (LABEL_IS_OSF) {
/* OSF label, and no DOS label */
"disklabel mode\n", disk_device);
bsd_select();
/*Why do we do this? It seems to be counter-intuitive*/
- current_label_type = label_dos;
+ current_label_type = LABEL_DOS;
/* If we return we may want to make an empty DOS label? */
}
while (1) {
int c;
- putchar('\n');
+ bb_putchar('\n');
c = tolower(read_nonempty("Command (m for help): "));
switch (c) {
case 'a':
if (LABEL_IS_DOS)
- toggle_active(get_partition(1, partitions));
+ toggle_active(get_partition(1, g_partitions));
else if (LABEL_IS_SUN)
- toggle_sunflags(get_partition(1, partitions),
+ toggle_sunflags(get_partition(1, g_partitions),
0x01);
else if (LABEL_IS_SGI)
sgi_set_bootpartition(
- get_partition(1, partitions));
+ get_partition(1, g_partitions));
else
unknown_command(c);
break;
if (LABEL_IS_DOS)
toggle_dos_compatibility_flag();
else if (LABEL_IS_SUN)
- toggle_sunflags(get_partition(1, partitions),
+ toggle_sunflags(get_partition(1, g_partitions),
0x10);
else if (LABEL_IS_SGI)
sgi_set_swappartition(
- get_partition(1, partitions));
+ get_partition(1, g_partitions));
else
unknown_command(c);
break;
get_existing_partition() only works for Linux-like
partition tables */
if (!LABEL_IS_SGI) {
- j = get_existing_partition(1, partitions);
+ j = get_existing_partition(1, g_partitions);
} else {
- j = get_partition(1, partitions);
+ j = get_partition(1, g_partitions);
}
if (j >= 0)
delete_partition(j);
list_table(0);
break;
case 'q':
- close(fd);
- puts("");
+ if (ENABLE_FEATURE_CLEAN_UP)
+ close_dev_fd();
+ bb_putchar('\n');
return 0;
case 's':
#if ENABLE_FEATURE_SUN_LABEL