Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Comparing changes

Choose two branches to see what's changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
base fork: karelzak/util-linux
...
head fork: karelzak/util-linux
Checking mergeability… Don't worry, you can still create the pull request.
  • 7 commits
  • 7 files changed
  • 0 commit comments
  • 3 contributors
Commits on Apr 23, 2012
@kerolasa kerolasa build-sys: determine availability of __fpending()
Needed to for making Cygwin more possible.

Reference: http://comments.gmane.org/gmane.linux.utilities.util-linux-ng/5656
Reported-by: Bernhard Voelker <bernhard.voelker@siemens-enterprise.com>
Signed-off-by: Sami Kerola <kerolasa@iki.fi>
7828876
Commits on May 02, 2012
Davidlohr Bueso fdisk: remove stack jumping
This patch eliminates the long/setjmp code. The current logic does not do
anything with stack jumps as it only exits from
print_partition_table_from_option() when a fatal error occurs.

Signed-off-by: Davidlohr Bueso <dave@gnu.org>
9f6c866
Davidlohr Bueso fdisk: remove listing variable
useless global variable.

Signed-off-by: Davidlohr Bueso <dave@gnu.org>
337643a
Davidlohr Bueso fdisk: rework fatal errors
When the device cannot be opened, there's no point calling fatal() when we can
just use err(3). When any other kind of fatal error occurs it's Ok, in addition
we can also go ahead and close the descriptor before exiting the program as
it's currently leaking.

Signed-off-by: Davidlohr Bueso <dave@gnu.org>
3457420
Davidlohr Bueso fdisk: remove dummy function
Signed-off-by: Davidlohr Bueso <dave@gnu.org>
64115ee
@karelzak Merge branch '2012wk17' of https://github.com/kerolasa/lelux-utiliteetit


* '2012wk17' of https://github.com/kerolasa/lelux-utiliteetit:
  build-sys: determine availability of __fpending()
1f13d6f
Davidlohr Bueso fdisk: isolate dos label logic
DOS specific logic is currently embedded in the heart of fdisk code. This patch
separates DOS label specific code into its own file, just like the rest of the
labels, leaving a more generic fdisk.c file. Most changes are just moving code
from fdisk.c to fdisk.h and fdiskdoslabel.[c/h].

The only logical modification is calling dos_delete_partition() from
read_extended(), instead of the generic delete_partition.  This is ok since
read extended is only called from a DOS context.

Signed-off-by: Davidlohr Bueso <dave@gnu.org>
e2ee917
View
2  configure.ac
@@ -152,6 +152,7 @@ AC_CHECK_HEADERS([ \
pty.h \
security/pam_misc.h \
stdint.h \
+ stdio_ext.h \
stdlib.h \
sys/disk.h \
sys/disklabel.h \
@@ -245,6 +246,7 @@ AC_CHECK_DECL([lseek64],
#include <unistd.h>])
AC_CHECK_FUNCS([ \
+ __fpending \
__secure_getenv \
err \
errx \
View
2  fdisk/Makefile.am
@@ -32,6 +32,8 @@ fdisk_SOURCES = \
fdisksgilabel.h \
fdisksunlabel.c \
fdisksunlabel.h \
+ fdiskdoslabel.c \
+ fdiskdoslabel.h \
partname.c \
$(fdisk_common) \
$(top_srcdir)/lib/canonicalize.c
View
459 fdisk/fdisk.c
@@ -14,7 +14,6 @@
#include <string.h>
#include <fcntl.h>
#include <ctype.h>
-#include <setjmp.h>
#include <errno.h>
#include <getopt.h>
#include <sys/stat.h>
@@ -33,13 +32,13 @@
#include "pathnames.h"
#include "canonicalize.h"
#include "strutils.h"
-#include "randutils.h"
#include "closestream.h"
#include "fdisksunlabel.h"
#include "fdisksgilabel.h"
#include "fdiskaixlabel.h"
#include "fdiskmaclabel.h"
+#include "fdiskdoslabel.h"
#ifdef HAVE_LINUX_COMPILER_H
#include <linux/compiler.h>
@@ -63,8 +62,6 @@ static void delete_partition(int i);
#define LINE_LENGTH 800
-#define pt_offset(b, n) ((struct partition *)((b) + 0x1be + \
- (n) * sizeof(struct partition)))
#define sector(s) ((s) & 0x3f)
#define cylinder(s, c) ((c) | (((s) & 0xc0) << 2))
@@ -133,91 +130,22 @@ static const struct menulist_descr menulist[] = {
{'y', N_("change number of physical cylinders"), {0, SUN_LABEL}},
};
-/* A valid partition table sector ends in 0x55 0xaa */
-static unsigned int
-part_table_flag(unsigned char *b) {
- return ((unsigned int) b[510]) + (((unsigned int) b[511]) << 8);
-}
-
int
valid_part_table_flag(unsigned char *b) {
return (b[510] == 0x55 && b[511] == 0xaa);
}
-static void
-write_part_table_flag(unsigned char *b) {
- b[510] = 0x55;
- b[511] = 0xaa;
-}
-
-/* start_sect and nr_sects are stored little endian on all machines */
-/* moreover, they are not aligned correctly */
-static void
-store4_little_endian(unsigned char *cp, unsigned int val) {
- cp[0] = (val & 0xff);
- cp[1] = ((val >> 8) & 0xff);
- cp[2] = ((val >> 16) & 0xff);
- cp[3] = ((val >> 24) & 0xff);
-}
-
-static unsigned int
-read4_little_endian(const unsigned char *cp) {
- return (unsigned int)(cp[0]) + ((unsigned int)(cp[1]) << 8)
- + ((unsigned int)(cp[2]) << 16)
- + ((unsigned int)(cp[3]) << 24);
-}
-
-static void
-set_start_sect(struct partition *p, unsigned int start_sect) {
- store4_little_endian(p->start4, start_sect);
-}
-
-unsigned long long
-get_start_sect(struct partition *p) {
- return read4_little_endian(p->start4);
-}
-
-static void
-set_nr_sects(struct partition *p, unsigned long long nr_sects) {
- store4_little_endian(p->size4, nr_sects);
-}
-
unsigned long long
get_nr_sects(struct partition *p) {
return read4_little_endian(p->size4);
}
-/*
- * Raw disk label. For DOS-type partition tables the MBR,
- * with descriptions of the primary partitions.
- */
-unsigned char *MBRbuffer;
-
-int MBRbuffer_changed;
-
-/*
- * per partition table entry data
- *
- * The four primary partitions have the same sectorbuffer (MBRbuffer)
- * and have NULL ext_pointer.
- * Each logical partition table entry has two pointers, one for the
- * partition and one link to the next one.
- */
-struct pte {
- struct partition *part_table; /* points into sectorbuffer */
- struct partition *ext_pointer; /* points into sectorbuffer */
- char changed; /* boolean */
- unsigned long long offset; /* disk sector number */
- unsigned char *sectorbuffer; /* disk sector contents */
-} ptes[MAXIMUM_PARTS];
-
char *disk_device, /* must be specified */
*line_ptr, /* interactive input */
line_buffer[LINE_LENGTH];
int fd, /* the disk */
ext_index, /* the prime extended partition */
- listing = 0, /* no aborts for fdisk -l */
nowarn = 0, /* no warnings for fdisk -l/-s */
dos_compatible_flag = 0, /* disabled by default */
dos_changed = 0,
@@ -226,7 +154,7 @@ int fd, /* the disk */
unsigned int user_cylinders, user_heads, user_sectors;
unsigned int pt_heads, pt_sectors;
-unsigned long long sector_offset = 1, extended_offset = 0, sectors;
+unsigned long long sector_offset = 1, /* extended_offset = 0, */ sectors;
unsigned int heads,
cylinders,
@@ -245,8 +173,6 @@ int has_topology;
enum labeltype disklabel; /* Current disklabel */
-jmp_buf listingbuf;
-
static void __attribute__ ((__noreturn__)) usage(FILE *out)
{
fprintf(out, _("Usage:\n"
@@ -266,17 +192,10 @@ static void __attribute__ ((__noreturn__)) usage(FILE *out)
exit(out == stderr ? EXIT_FAILURE : EXIT_SUCCESS);
}
-void fatal(enum failure why) {
-
- if (listing) {
- close(fd);
- longjmp(listingbuf, 1);
- }
-
+void fatal(enum failure why)
+{
+ close(fd);
switch (why) {
- case unable_to_open:
- err(EXIT_FAILURE, _("unable to open %s"), disk_device);
-
case unable_to_read:
err(EXIT_FAILURE, _("unable to read %s"), disk_device);
@@ -294,44 +213,6 @@ void fatal(enum failure why) {
}
}
-static void
-seek_sector(int fd, unsigned long long secno) {
- off_t offset = (off_t) secno * sector_size;
- if (lseek(fd, offset, SEEK_SET) == (off_t) -1)
- fatal(unable_to_seek);
-}
-
-static void
-read_sector(int fd, unsigned long long secno, unsigned char *buf) {
- seek_sector(fd, secno);
- if (read(fd, buf, sector_size) != sector_size)
- fatal(unable_to_read);
-}
-
-static void
-write_sector(int fd, unsigned long long secno, unsigned char *buf) {
- seek_sector(fd, secno);
- if (write(fd, buf, sector_size) != sector_size)
- fatal(unable_to_write);
-}
-
-/* Allocate a buffer and read a partition table sector */
-static void
-read_pte(int fd, int pno, unsigned long long offset) {
- struct pte *pe = &ptes[pno];
-
- pe->offset = offset;
- pe->sectorbuffer = xmalloc(sector_size);
- read_sector(fd, offset, pe->sectorbuffer);
- pe->changed = 0;
- pe->part_table = pe->ext_pointer = NULL;
-}
-
-static unsigned long long
-get_partition_start(struct pte *pe) {
- return pe->offset + get_start_sect(pe->part_table);
-}
-
struct partition *
get_part_table(int i) {
return ptes[i].part_table;
@@ -364,21 +245,6 @@ is_garbage_table(void) {
return 0;
}
-/*
- * Avoid warning about DOS partitions when no DOS partition was changed.
- * Here a heuristic "is probably dos partition".
- * We might also do the opposite and warn in all cases except
- * for "is probably nondos partition".
- */
-static int
-is_dos_partition(int t) {
- return (t == 1 || t == 4 || t == 6 ||
- t == 0x0b || t == 0x0c || t == 0x0e ||
- t == 0x11 || t == 0x12 || t == 0x14 || t == 0x16 ||
- t == 0x1b || t == 0x1c || t == 0x1e || t == 0x24 ||
- t == 0xc1 || t == 0xc4 || t == 0xc6);
-}
-
void print_menu(enum menutype menu)
{
size_t i;
@@ -460,22 +326,6 @@ is_cleared_partition(struct partition *p) {
}
static void
-clear_partition(struct partition *p) {
- if (!p)
- return;
- p->boot_ind = 0;
- p->head = 0;
- p->sector = 0;
- p->cyl = 0;
- p->sys_ind = 0;
- p->end_head = 0;
- p->end_sector = 0;
- p->end_cyl = 0;
- set_start_sect(p,0);
- set_nr_sects(p,0);
-}
-
-static void
set_partition(int i, int doext, unsigned long long start,
unsigned long long stop, int sysid) {
struct partition *p;
@@ -602,8 +452,8 @@ align_lba_in_range( unsigned long long lba,
return lba;
}
-static int
-warn_geometry(void) {
+int warn_geometry(void)
+{
char *m = NULL;
int prev = 0;
@@ -633,8 +483,8 @@ void update_units(void)
units_per_sector = 1; /* in sectors */
}
-static void
-warn_limits(void) {
+void warn_limits(void)
+{
if (total_number_of_sectors > UINT_MAX && !nowarn) {
unsigned long long bytes = total_number_of_sectors * sector_size;
int giga = bytes / 1000000000;
@@ -652,8 +502,8 @@ warn_limits(void) {
}
}
-static void
-warn_alignment(void) {
+void warn_alignment(void)
+{
if (nowarn)
return;
@@ -676,182 +526,6 @@ warn_alignment(void) {
}
static void
-read_extended(int ext) {
- int i;
- struct pte *pex;
- struct partition *p, *q;
-
- ext_index = ext;
- pex = &ptes[ext];
- pex->ext_pointer = pex->part_table;
-
- p = pex->part_table;
- if (!get_start_sect(p)) {
- fprintf(stderr,
- _("Bad offset in primary extended partition\n"));
- return;
- }
-
- while (IS_EXTENDED (p->sys_ind)) {
- struct pte *pe = &ptes[partitions];
-
- if (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];
-
- fprintf(stderr,
- _("Warning: omitting partitions after #%d.\n"
- "They will be deleted "
- "if you save this partition table.\n"),
- partitions);
- clear_partition(pre->ext_pointer);
- pre->changed = 1;
- return;
- }
-
- read_pte(fd, partitions, extended_offset + get_start_sect(p));
-
- if (!extended_offset)
- extended_offset = get_start_sect(p);
-
- q = p = pt_offset(pe->sectorbuffer, 0);
- for (i = 0; i < 4; i++, p++) if (get_nr_sects(p)) {
- if (IS_EXTENDED (p->sys_ind)) {
- if (pe->ext_pointer)
- fprintf(stderr,
- _("Warning: extra link "
- "pointer in partition table"
- " %d\n"), partitions + 1);
- else
- pe->ext_pointer = p;
- } else if (p->sys_ind) {
- if (pe->part_table)
- fprintf(stderr,
- _("Warning: ignoring extra "
- "data in partition table"
- " %d\n"), partitions + 1);
- else
- pe->part_table = p;
- }
- }
-
- /* very strange code here... */
- if (!pe->part_table) {
- if (q != pe->ext_pointer)
- pe->part_table = q;
- else
- pe->part_table = q + 1;
- }
- if (!pe->ext_pointer) {
- if (q != pe->part_table)
- pe->ext_pointer = q;
- else
- pe->ext_pointer = q + 1;
- }
-
- p = pe->ext_pointer;
- partitions++;
- }
-
- /* remove empty links */
- remove:
- for (i = 4; i < partitions; i++) {
- struct pte *pe = &ptes[i];
-
- if (!get_nr_sects(pe->part_table) &&
- (partitions > 5 || ptes[4].part_table->sys_ind)) {
- printf(_("omitting empty partition (%d)\n"), i+1);
- delete_partition(i);
- goto remove; /* numbering changed */
- }
- }
-}
-
-static void
-dos_write_mbr_id(unsigned char *b, unsigned int id) {
- store4_little_endian(&b[440], id);
-}
-
-static unsigned int
-dos_read_mbr_id(const unsigned char *b) {
- return read4_little_endian(&b[440]);
-}
-
-static void
-dos_print_mbr_id(void) {
- printf(_("Disk identifier: 0x%08x\n"), dos_read_mbr_id(MBRbuffer));
-}
-
-static void
-dos_set_mbr_id(void) {
- unsigned long new_id;
- char *ep;
- char ps[64];
-
- snprintf(ps, sizeof ps, _("New disk identifier (current 0x%08x): "),
- dos_read_mbr_id(MBRbuffer));
-
- if (read_chars(ps) == '\n')
- return;
-
- new_id = strtoul(line_ptr, &ep, 0);
- if (*ep != '\n')
- return;
-
- dos_write_mbr_id(MBRbuffer, new_id);
- MBRbuffer_changed = 1;
- dos_print_mbr_id();
-}
-
-static void dos_init(void)
-{
- int i;
-
- disklabel = DOS_LABEL;
- partitions = 4;
- ext_index = 0;
- extended_offset = 0;
-
- 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;
- pe->changed = 0;
- }
-
- warn_geometry();
- warn_limits();
- warn_alignment();
-}
-
-static void
-create_doslabel(void) {
- unsigned int id;
-
- /* random disk signature */
- random_get_bytes(&id, sizeof(id));
-
- fprintf(stderr, _("Building a new DOS disklabel with disk identifier 0x%08x.\n"), id);
-
- dos_init();
- zeroize_mbr_buffer();
-
- set_all_unchanged();
- set_changed(0);
-
- /* Generate an MBR ID for this disk */
- dos_write_mbr_id(MBRbuffer, id);
-
- /* Put MBR signature */
- write_part_table_flag(MBRbuffer);
-}
-
-static void
get_topology(int fd) {
int arg;
#ifdef HAVE_LIBBLKID
@@ -1049,41 +723,7 @@ void zeroize_mbr_buffer(void)
memset(MBRbuffer, 0, MAX_SECTOR_SIZE);
}
-static int check_dos_label(void)
-{
- int i;
-
- if (!valid_part_table_flag(MBRbuffer))
- return 0;
-
- dos_init();
-
- for (i = 0; i < 4; i++) {
- struct pte *pe = &ptes[i];
-
- if (IS_EXTENDED (pe->part_table->sys_ind)) {
- if (partitions != 4)
- fprintf(stderr, _("Ignoring extra extended "
- "partition %d\n"), i + 1);
- else
- read_extended(i);
- }
- }
-
- for (i = 3; i < partitions; i++) {
- struct pte *pe = &ptes[i];
-
- if (!valid_part_table_flag(pe->sectorbuffer)) {
- fprintf(stderr,
- _("Warning: invalid flag 0x%04x of partition "
- "table %d will be corrected by w(rite)\n"),
- part_table_flag(pe->sectorbuffer), i + 1);
- pe->changed = 1;
- }
- }
- return 1;
-}
/*
* Read MBR. Returns:
@@ -1096,18 +736,14 @@ static int get_boot(int try_only) {
disklabel = ANY_LABEL;
memset(MBRbuffer, 0, 512);
- if (try_only && (fd = open(disk_device, O_RDONLY)) < 0) {
- fprintf(stderr, _("Cannot open %s\n"), disk_device);
- fatal(unable_to_open);
- }
+ if (try_only && (fd = open(disk_device, O_RDONLY)) < 0)
+ err(EXIT_FAILURE, _("unable to open %s"), disk_device);
else {
if ((fd = open(disk_device, O_RDWR)) < 0) {
/* ok, can we read-only the device? */
if ((fd = open(disk_device, O_RDONLY)) < 0)
- fatal(unable_to_open);
- else
- printf(_("You will not be able to write "
- "the partition table.\n"));
+ err(EXIT_FAILURE, _("unable to open %s"), disk_device);
+ printf(_("You will not be able to write the partition table.\n"));
}
}
@@ -1519,61 +1155,6 @@ toggle_dos_compatibility_flag(void) {
update_sector_offset();
}
-static void dos_delete_partition(int i)
-{
- struct pte *pe = &ptes[i];
- struct partition *p = pe->part_table;
- struct partition *q = pe->ext_pointer;
-
- /* Note that for the fifth partition (i == 4) we don't actually
- decrement partitions. */
-
- if (i < 4) {
- if (IS_EXTENDED (p->sys_ind) && i == ext_index) {
- partitions = 4;
- ptes[ext_index].ext_pointer = NULL;
- extended_offset = 0;
- }
- clear_partition(p);
- } else if (!q->sys_ind && i > 4) {
- /* the last one in the chain - just delete */
- --partitions;
- --i;
- clear_partition(ptes[i].ext_pointer);
- ptes[i].changed = 1;
- } else {
- /* not the last one - further ones will be moved down */
- if (i > 4) {
- /* delete this link in the chain */
- p = ptes[i-1].ext_pointer;
- *p = *q;
- 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 */
- /* the first logical in a longer chain */
- struct pte *pe = &ptes[5];
-
- if (pe->part_table) /* prevent SEGFAULT */
- set_start_sect(pe->part_table,
- get_partition_start(pe) -
- extended_offset);
- pe->offset = extended_offset;
- pe->changed = 1;
- }
-
- if (partitions > 5) {
- partitions--;
- while (i < partitions) {
- ptes[i] = ptes[i+1];
- i++;
- }
- } else
- /* the only logical: clear only */
- clear_partition(ptes[i].part_table);
- }
-}
-
static void
delete_partition(int i)
{
@@ -2708,8 +2289,6 @@ print_partition_table_from_option(char *device)
int gb;
disk_device = device;
- if (setjmp(listingbuf))
- return;
gpt_warning(device);
gb = get_boot(1);
if (gb < 0) { /* no DOS signature */
@@ -2757,8 +2336,6 @@ print_all_partition_table_from_option(void)
fclose(procpt);
}
-static void dummy(int *kk __attribute__ ((__unused__))) {}
-
static void
unknown_command(int c) {
printf(_("%c: unknown command\n"), c);
@@ -2950,10 +2527,6 @@ main(int argc, char **argv) {
nowarn = 1;
if (argc > optind) {
int k;
- /* avoid gcc warning:
- variable `k' might be clobbered by `longjmp' */
- dummy(&k);
- listing = 1;
for (k = optind; k < argc; k++)
print_partition_table_from_option(argv[k]);
} else
@@ -2973,7 +2546,7 @@ main(int argc, char **argv) {
for (j = optind; j < argc; j++) {
disk_device = argv[j];
if ((fd = open(disk_device, O_RDONLY)) < 0)
- fatal(unable_to_open);
+ err(EXIT_FAILURE, _("unable to open %s"), disk_device);
if (blkdev_get_sectors(fd, &size) == -1)
fatal(ioctl_error);
close(fd);
View
73 fdisk/fdisk.h
@@ -44,9 +44,12 @@ enum menutype {
EXPERT_MENU,
};
-enum failure {ioctl_error,
- unable_to_open, unable_to_read, unable_to_seek,
- unable_to_write};
+enum failure {
+ ioctl_error,
+ unable_to_read,
+ unable_to_seek,
+ unable_to_write
+};
struct geom {
unsigned int heads;
@@ -84,12 +87,14 @@ extern void update_units(void);
extern char read_chars(char *mesg);
extern void set_changed(int);
extern void set_all_unchanged(void);
+extern int warn_geometry(void);
+extern void warn_limits(void);
+extern void warn_alignment(void);
#define PLURAL 0
#define SINGULAR 1
extern const char * str_units(int);
-extern unsigned long long get_start_sect(struct partition *p);
extern unsigned long long get_nr_sects(struct partition *p);
enum labeltype {
@@ -104,6 +109,66 @@ enum labeltype {
extern enum labeltype disklabel;
+/*
+ * Raw disk label. For DOS-type partition tables the MBR,
+ * with descriptions of the primary partitions.
+ */
+int MBRbuffer_changed;
+unsigned char *MBRbuffer;
+
+/* start_sect and nr_sects are stored little endian on all machines */
+/* moreover, they are not aligned correctly */
+static void
+store4_little_endian(unsigned char *cp, unsigned int val) {
+ cp[0] = (val & 0xff);
+ cp[1] = ((val >> 8) & 0xff);
+ cp[2] = ((val >> 16) & 0xff);
+ cp[3] = ((val >> 24) & 0xff);
+}
+
+static unsigned int read4_little_endian(const unsigned char *cp)
+{
+ return (unsigned int)(cp[0]) + ((unsigned int)(cp[1]) << 8)
+ + ((unsigned int)(cp[2]) << 16)
+ + ((unsigned int)(cp[3]) << 24);
+}
+
+static void set_nr_sects(struct partition *p, unsigned long long nr_sects)
+{
+ store4_little_endian(p->size4, nr_sects);
+}
+
+static void set_start_sect(struct partition *p, unsigned int start_sect)
+{
+ store4_little_endian(p->start4, start_sect);
+}
+
+static void seek_sector(int fd, unsigned long long secno)
+{
+ off_t offset = (off_t) secno * sector_size;
+ if (lseek(fd, offset, SEEK_SET) == (off_t) -1)
+ fatal(unable_to_seek);
+}
+
+static void read_sector(int fd, unsigned long long secno, unsigned char *buf)
+{
+ seek_sector(fd, secno);
+ if (read(fd, buf, sector_size) != sector_size)
+ fatal(unable_to_read);
+}
+
+static void write_sector(int fd, unsigned long long secno, unsigned char *buf)
+{
+ seek_sector(fd, secno);
+ if (write(fd, buf, sector_size) != sector_size)
+ fatal(unable_to_write);
+}
+
+static unsigned long long get_start_sect(struct partition *p)
+{
+ return read4_little_endian(p->start4);
+}
+
/* prototypes for fdiskbsdlabel.c */
extern void bsd_command_prompt(void);
extern int check_osf_label(void);
View
323 fdisk/fdiskdoslabel.c
@@ -0,0 +1,323 @@
+/*
+ * Many, many hands.
+ * Specific DOS label file - Davidlohr Bueso <dave@gnu.org>
+ */
+
+#include <unistd.h>
+
+#include "nls.h"
+#include "xalloc.h"
+#include "randutils.h"
+#include "common.h"
+#include "fdisk.h"
+#include "fdiskdoslabel.h"
+
+/* Allocate a buffer and read a partition table sector */
+static void read_pte(int fd, int pno, unsigned long long offset)
+{
+ struct pte *pe = &ptes[pno];
+
+ pe->offset = offset;
+ pe->sectorbuffer = xmalloc(sector_size);
+ read_sector(fd, offset, pe->sectorbuffer);
+ pe->changed = 0;
+ pe->part_table = pe->ext_pointer = NULL;
+}
+
+static void dos_write_mbr_id(unsigned char *b, unsigned int id)
+{
+ store4_little_endian(&b[440], id);
+}
+
+static unsigned int dos_read_mbr_id(const unsigned char *b)
+{
+ return read4_little_endian(&b[440]);
+}
+
+static void clear_partition(struct partition *p)
+{
+ if (!p)
+ return;
+ p->boot_ind = 0;
+ p->head = 0;
+ p->sector = 0;
+ p->cyl = 0;
+ p->sys_ind = 0;
+ p->end_head = 0;
+ p->end_sector = 0;
+ p->end_cyl = 0;
+ set_start_sect(p,0);
+ set_nr_sects(p,0);
+}
+
+static void dos_init(void)
+{
+ int i;
+
+ disklabel = DOS_LABEL;
+ partitions = 4;
+ ext_index = 0;
+ extended_offset = 0;
+
+ 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;
+ pe->changed = 0;
+ }
+
+ warn_geometry();
+ warn_limits();
+ warn_alignment();
+}
+
+static void read_extended(int ext)
+{
+ int i;
+ struct pte *pex;
+ struct partition *p, *q;
+
+ ext_index = ext;
+ pex = &ptes[ext];
+ pex->ext_pointer = pex->part_table;
+
+ p = pex->part_table;
+ if (!get_start_sect(p)) {
+ fprintf(stderr,
+ _("Bad offset in primary extended partition\n"));
+ return;
+ }
+
+ while (IS_EXTENDED (p->sys_ind)) {
+ struct pte *pe = &ptes[partitions];
+
+ if (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];
+
+ fprintf(stderr,
+ _("Warning: omitting partitions after #%d.\n"
+ "They will be deleted "
+ "if you save this partition table.\n"),
+ partitions);
+ clear_partition(pre->ext_pointer);
+ pre->changed = 1;
+ return;
+ }
+
+ read_pte(fd, partitions, extended_offset + get_start_sect(p));
+
+ if (!extended_offset)
+ extended_offset = get_start_sect(p);
+
+ q = p = pt_offset(pe->sectorbuffer, 0);
+ for (i = 0; i < 4; i++, p++) if (get_nr_sects(p)) {
+ if (IS_EXTENDED (p->sys_ind)) {
+ if (pe->ext_pointer)
+ fprintf(stderr,
+ _("Warning: extra link "
+ "pointer in partition table"
+ " %d\n"), partitions + 1);
+ else
+ pe->ext_pointer = p;
+ } else if (p->sys_ind) {
+ if (pe->part_table)
+ fprintf(stderr,
+ _("Warning: ignoring extra "
+ "data in partition table"
+ " %d\n"), partitions + 1);
+ else
+ pe->part_table = p;
+ }
+ }
+
+ /* very strange code here... */
+ if (!pe->part_table) {
+ if (q != pe->ext_pointer)
+ pe->part_table = q;
+ else
+ pe->part_table = q + 1;
+ }
+ if (!pe->ext_pointer) {
+ if (q != pe->part_table)
+ pe->ext_pointer = q;
+ else
+ pe->ext_pointer = q + 1;
+ }
+
+ p = pe->ext_pointer;
+ partitions++;
+ }
+
+ /* remove empty links */
+ remove:
+ for (i = 4; i < partitions; i++) {
+ struct pte *pe = &ptes[i];
+
+ if (!get_nr_sects(pe->part_table) &&
+ (partitions > 5 || ptes[4].part_table->sys_ind)) {
+ printf(_("omitting empty partition (%d)\n"), i+1);
+ dos_delete_partition(i);
+ goto remove; /* numbering changed */
+ }
+ }
+}
+
+void dos_print_mbr_id(void)
+{
+ printf(_("Disk identifier: 0x%08x\n"), dos_read_mbr_id(MBRbuffer));
+}
+
+void create_doslabel(void)
+{
+ unsigned int id;
+
+ /* random disk signature */
+ random_get_bytes(&id, sizeof(id));
+
+ fprintf(stderr, _("Building a new DOS disklabel with disk identifier 0x%08x.\n"), id);
+
+ dos_init();
+ zeroize_mbr_buffer();
+
+ set_all_unchanged();
+ set_changed(0);
+
+ /* Generate an MBR ID for this disk */
+ dos_write_mbr_id(MBRbuffer, id);
+
+ /* Put MBR signature */
+ write_part_table_flag(MBRbuffer);
+}
+
+void dos_set_mbr_id(void)
+{
+ unsigned long new_id;
+ char *ep;
+ char ps[64];
+
+ snprintf(ps, sizeof ps, _("New disk identifier (current 0x%08x): "),
+ dos_read_mbr_id(MBRbuffer));
+
+ if (read_chars(ps) == '\n')
+ return;
+
+ new_id = strtoul(line_ptr, &ep, 0);
+ if (*ep != '\n')
+ return;
+
+ dos_write_mbr_id(MBRbuffer, new_id);
+ MBRbuffer_changed = 1;
+ dos_print_mbr_id();
+}
+
+void dos_delete_partition(int i)
+{
+ struct pte *pe = &ptes[i];
+ struct partition *p = pe->part_table;
+ struct partition *q = pe->ext_pointer;
+
+ /* Note that for the fifth partition (i == 4) we don't actually
+ decrement partitions. */
+
+ if (i < 4) {
+ if (IS_EXTENDED (p->sys_ind) && i == ext_index) {
+ partitions = 4;
+ ptes[ext_index].ext_pointer = NULL;
+ extended_offset = 0;
+ }
+ clear_partition(p);
+ } else if (!q->sys_ind && i > 4) {
+ /* the last one in the chain - just delete */
+ --partitions;
+ --i;
+ clear_partition(ptes[i].ext_pointer);
+ ptes[i].changed = 1;
+ } else {
+ /* not the last one - further ones will be moved down */
+ if (i > 4) {
+ /* delete this link in the chain */
+ p = ptes[i-1].ext_pointer;
+ *p = *q;
+ 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 */
+ /* the first logical in a longer chain */
+ struct pte *pe = &ptes[5];
+
+ if (pe->part_table) /* prevent SEGFAULT */
+ set_start_sect(pe->part_table,
+ get_partition_start(pe) -
+ extended_offset);
+ pe->offset = extended_offset;
+ pe->changed = 1;
+ }
+
+ if (partitions > 5) {
+ partitions--;
+ while (i < partitions) {
+ ptes[i] = ptes[i+1];
+ i++;
+ }
+ } else
+ /* the only logical: clear only */
+ clear_partition(ptes[i].part_table);
+ }
+}
+
+int check_dos_label(void)
+{
+ int i;
+
+ if (!valid_part_table_flag(MBRbuffer))
+ return 0;
+
+ dos_init();
+
+ for (i = 0; i < 4; i++) {
+ struct pte *pe = &ptes[i];
+
+ if (IS_EXTENDED (pe->part_table->sys_ind)) {
+ if (partitions != 4)
+ fprintf(stderr, _("Ignoring extra extended "
+ "partition %d\n"), i + 1);
+ else
+ read_extended(i);
+ }
+ }
+
+ for (i = 3; i < partitions; i++) {
+ struct pte *pe = &ptes[i];
+
+ if (!valid_part_table_flag(pe->sectorbuffer)) {
+ fprintf(stderr,
+ _("Warning: invalid flag 0x%04x of partition "
+ "table %d will be corrected by w(rite)\n"),
+ part_table_flag(pe->sectorbuffer), i + 1);
+ pe->changed = 1;
+ }
+ }
+
+ return 1;
+}
+
+/*
+ * Avoid warning about DOS partitions when no DOS partition was changed.
+ * Here a heuristic "is probably dos partition".
+ * We might also do the opposite and warn in all cases except
+ * for "is probably nondos partition".
+ */
+int is_dos_partition(int t)
+{
+ return (t == 1 || t == 4 || t == 6 ||
+ t == 0x0b || t == 0x0c || t == 0x0e ||
+ t == 0x11 || t == 0x12 || t == 0x14 || t == 0x16 ||
+ t == 0x1b || t == 0x1c || t == 0x1e || t == 0x24 ||
+ t == 0xc1 || t == 0xc4 || t == 0xc6);
+}
View
50 fdisk/fdiskdoslabel.h
@@ -0,0 +1,50 @@
+#ifndef FDISK_DOS_LABEL_H
+#define FDISK_DOS_LABEL_H
+
+/*
+ * per partition table entry data
+ *
+ * The four primary partitions have the same sectorbuffer (MBRbuffer)
+ * and have NULL ext_pointer.
+ * Each logical partition table entry has two pointers, one for the
+ * partition and one link to the next one.
+ */
+struct pte {
+ struct partition *part_table; /* points into sectorbuffer */
+ struct partition *ext_pointer; /* points into sectorbuffer */
+ char changed; /* boolean */
+ unsigned long long offset; /* disk sector number */
+ unsigned char *sectorbuffer; /* disk sector contents */
+} ptes[MAXIMUM_PARTS];
+
+#define pt_offset(b, n) ((struct partition *)((b) + 0x1be + \
+ (n) * sizeof(struct partition)))
+
+int ext_index; /* the prime extended partition */
+unsigned long long extended_offset;
+
+static void write_part_table_flag(unsigned char *b)
+{
+ b[510] = 0x55;
+ b[511] = 0xaa;
+}
+
+/* A valid partition table sector ends in 0x55 0xaa */
+static unsigned int part_table_flag(unsigned char *b)
+{
+ return ((unsigned int) b[510]) + (((unsigned int) b[511]) << 8);
+}
+
+static unsigned long long get_partition_start(struct pte *pe)
+{
+ return pe->offset + get_start_sect(pe->part_table);
+}
+
+extern void create_doslabel(void);
+extern void dos_print_mbr_id(void);
+extern void dos_set_mbr_id(void);
+extern void dos_delete_partition(int i);
+extern int check_dos_label(void);
+extern int is_dos_partition(int t);
+
+#endif
View
10 include/closestream.h
@@ -2,12 +2,22 @@
#define UTIL_LINUX_CLOSESTREAM_H
#include <stdio.h>
+#ifdef HAVE_STDIO_EXT_H
#include <stdio_ext.h>
+#endif
#include <unistd.h>
#include "c.h"
#include "nls.h"
+#ifndef HAVE___FPENDING
+static inline int
+__fpending(FILE *stream __attribute__((__unused__)))
+{
+ return 0;
+}
+#endif
+
static inline int
close_stream(FILE * stream)
{

No commit comments for this range

Something went wrong with that request. Please try again.