# 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;
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[] ALIGN1 = "cannot open %s";
-static const char unable_to_read[] ALIGN1 = "cannot read from %s";
-static const char unable_to_seek[] ALIGN1 = "cannot seek on %s";
-static const char unable_to_write[] ALIGN1 = "cannot write to %s";
-static const char ioctl_error[] ALIGN1 = "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 void update_units(void);
#if ENABLE_FEATURE_FDISK_WRITABLE
#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 fd; /* the disk */
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;
- enum label_type current_label_type;
+ 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];
struct pte ptes[MAXIMUM_PARTS];
};
#define G (*ptr_to_globals)
-#define line_ptr (G.line_ptr)
+#define line_ptr (G.line_ptr )
#define disk_device (G.disk_device )
-#define fd (G.fd )
#define g_partitions (G.g_partitions )
#define units_per_sector (G.units_per_sector )
#define sector_size (G.sector_size )
#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 listingbuf (G.listingbuf)
-#define line_buffer (G.line_buffer)
+#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 { \
- PTR_TO_GLOBALS = xzalloc(sizeof(G)); \
+ 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;
+}
+
+
#define IS_EXTENDED(i) \
((i) == EXTENDED || (i) == WIN98_EXTENDED || (i) == LINUX_EXTENDED)
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 smallint listing; /* no aborts for fdisk -l */
-static int dos_compatible_flag = ~0;
-#if ENABLE_FEATURE_FDISK_WRITABLE
-//static int dos_changed;
-static smallint 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 ENABLE_FDISK_SUPPORT_LARGE_DISKS
- if (lseek64(fd, (off64_t)secno, SEEK_SET) == (off64_t) -1)
- fdisk_fatal(unable_to_seek);
-#else
- if (secno > MAXINT(off_t)
- || lseek(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, 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;
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--) {
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;
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;
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)
}
/*
- * 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;
+ 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 (IS_EXTENDED(ptes[i].part_table->sys_ind)) {
if (g_partitions != 4)
printf("Ignoring extra extended "
"partition %d\n", i + 1);
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;)
}
}
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 = g_sectors;
printf("DOS Compatibility flag is set\n");
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? */
printf("Calling ioctl() to re-read partition table\n");
sync();
/* sleep(2); Huh? */
- i = ioctl_or_perror(fd, BLKRRPART, NULL,
+ i = ioctl_or_perror(dev_fd, BLKRRPART, NULL,
"WARNING: rereading partition table "
"failed, kernel still uses old table");
#if 0
if (leave) {
if (ENABLE_FEATURE_CLEAN_UP)
- close(fd);
+ close_dev_fd();
exit(i != 0);
}
}
x_list_table(0);
break;
case 'q':
- close(fd);
+ if (ENABLE_FEATURE_CLEAN_UP)
+ close_dev_fd();
bb_putchar('\n');
- exit(0);
+ exit(EXIT_SUCCESS);
case 'r':
return;
case 's':
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 && g_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);
*
* 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,
- };
-
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);
if (opt & OPT_u)
display_in_cyl_units = 0; // -u
- if (user_set_sector_size && argc != 1)
- printf("Warning: the -b (set sector size) option should"
- " be used with one specified device\n");
-
#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? */
}
list_table(0);
break;
case 'q':
- close(fd);
+ if (ENABLE_FEATURE_CLEAN_UP)
+ close_dev_fd();
bb_putchar('\n');
return 0;
case 's':