summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fdisks/fdisk.c46
-rw-r--r--fdisks/fdiskdoslabel.c30
-rw-r--r--fdisks/fdiskdoslabel.h5
-rw-r--r--libfdisk/src/context.c6
-rw-r--r--libfdisk/src/libfdisk.h5
5 files changed, 72 insertions, 20 deletions
diff --git a/fdisks/fdisk.c b/fdisks/fdisk.c
index c771f6e6d..b22f68589 100644
--- a/fdisks/fdisk.c
+++ b/fdisks/fdisk.c
@@ -128,7 +128,6 @@ char *line_ptr, /* interactive input */
line_buffer[LINE_LENGTH];
int nowarn = 0, /* no warnings for fdisk -l/-s */
- dos_compatible_flag = 0, /* disabled by default */
partitions = 4; /* maximum partition + 1 */
unsigned int user_cylinders, user_heads, user_sectors;
@@ -656,15 +655,25 @@ toggle_active(int i) {
pe->changed = 1;
}
-static void
-toggle_dos_compatibility_flag(struct fdisk_context *cxt) {
- dos_compatible_flag = ~dos_compatible_flag;
- if (dos_compatible_flag)
+static void toggle_dos_compatibility_flag(struct fdisk_context *cxt)
+{
+ struct fdisk_label *lb = fdisk_context_get_label(cxt, "dos");
+ int flag;
+
+ if (!lb)
+ return;
+
+ flag = !fdisk_dos_is_compatible(lb);
+
+ if (flag)
printf(_("DOS Compatibility flag is set (DEPRECATED!)\n"));
else
printf(_("DOS Compatibility flag is not set\n"));
- fdisk_reset_alignment(cxt);
+ fdisk_dos_enable_compatible(lb, flag);
+
+ if (fdisk_is_disklabel(cxt, DOS))
+ fdisk_reset_alignment(cxt);
}
static void delete_partition(struct fdisk_context *cxt, int partnum)
@@ -737,7 +746,7 @@ void check_consistency(struct fdisk_context *cxt, struct partition *p, int parti
unsigned int lbc, lbh, lbs; /* logical beginning c, h, s */
unsigned int lec, leh, les; /* logical ending c, h, s */
- if (!dos_compatible_flag)
+ if (!is_dos_compatible(cxt))
return;
if (!cxt->geom.heads || !cxt->geom.sectors || (partition >= 4))
@@ -796,7 +805,7 @@ list_disk_geometry(struct fdisk_context *cxt) {
cxt->dev_path, hectomega / 10, hectomega % 10, bytes);
}
printf(_(", %llu sectors\n"), cxt->total_sectors);
- if (dos_compatible_flag)
+ if (is_dos_compatible(cxt))
printf(_("%d heads, %llu sectors/track, %llu cylinders\n"),
cxt->geom.heads, cxt->geom.sectors, cxt->geom.cylinders);
printf(_("Units = %s of %d * %ld = %ld bytes\n"),
@@ -1352,7 +1361,7 @@ expert_command_prompt(struct fdisk_context *cxt)
case 's':
user_sectors = read_int(cxt, 1, cxt->geom.sectors, 63, 0,
_("Number of sectors"));
- if (dos_compatible_flag)
+ if (is_dos_compatible(cxt))
fprintf(stderr, _("Warning: setting "
"sector offset for DOS "
"compatibility\n"));
@@ -1590,6 +1599,7 @@ int main(int argc, char **argv)
int c, optl = 0, opts = 0;
unsigned long sector_size = 0;
struct fdisk_context *cxt;
+ struct fdisk_label *lb;
setlocale(LC_ALL, "");
bindtextdomain(PACKAGE, LOCALEDIR);
@@ -1617,12 +1627,18 @@ int main(int argc, char **argv)
user_cylinders = strtou32_or_err(optarg, _("invalid cylinders argument"));
break;
case 'c':
- dos_compatible_flag = 0; /* default */
-
- if (optarg && !strcmp(optarg, "=dos"))
- dos_compatible_flag = ~0;
- else if (optarg && strcmp(optarg, "=nondos"))
- usage(stderr);
+ if (optarg) {
+ lb = fdisk_context_get_label(cxt, "dos");
+ if (!lb)
+ err(EXIT_FAILURE, _("not found DOS label driver"));
+ if (strcmp(optarg, "=dos") == 0)
+ fdisk_dos_enable_compatible(lb, TRUE);
+ else if (strcmp(optarg, "=nondos") == 0)
+ fdisk_dos_enable_compatible(lb, FALSE);
+ else
+ usage(stderr);
+ }
+ /* use default if no optarg specified */
break;
case 'H':
user_heads = strtou32_or_err(optarg, _("invalid heads argument"));
diff --git a/fdisks/fdiskdoslabel.c b/fdisks/fdiskdoslabel.c
index 74d24cdea..04f529422 100644
--- a/fdisks/fdiskdoslabel.c
+++ b/fdisks/fdiskdoslabel.c
@@ -19,6 +19,8 @@
*/
struct fdisk_dos_label {
struct fdisk_label head; /* generic part */
+
+ unsigned int compatible : 1; /* is DOS compatible? */
};
/*
@@ -78,7 +80,7 @@ static void warn_alignment(struct fdisk_context *cxt)
"the physical sector size. Aligning to a physical sector (or optimal\n"
"I/O) size boundary is recommended, or performance may be impacted.\n"));
- if (dos_compatible_flag)
+ if (is_dos_compatible(cxt))
fprintf(stderr, _("\n"
"WARNING: DOS-compatible mode is deprecated. It's strongly recommended to\n"
" switch off the mode (with command 'c')."));
@@ -432,7 +434,7 @@ static void get_partition_table_geometry(struct fdisk_context *cxt,
static int dos_reset_alignment(struct fdisk_context *cxt)
{
/* overwrite necessary stuff by DOS deprecated stuff */
- if (dos_compatible_flag) {
+ if (is_dos_compatible(cxt)) {
if (cxt->geom.sectors)
cxt->first_lba = cxt->geom.sectors; /* usually 63 */
@@ -524,10 +526,10 @@ static void set_partition(struct fdisk_context *cxt,
if (!doext)
print_partition_size(cxt, i + 1, start, stop, sysid);
- if (dos_compatible_flag && (start/(cxt->geom.sectors*cxt->geom.heads) > 1023))
+ if (is_dos_compatible(cxt) && (start/(cxt->geom.sectors*cxt->geom.heads) > 1023))
start = cxt->geom.heads*cxt->geom.sectors*1024 - 1;
set_hsc(p->head, p->sector, p->cyl, start);
- if (dos_compatible_flag && (stop/(cxt->geom.sectors*cxt->geom.heads) > 1023))
+ if (is_dos_compatible(cxt) && (stop/(cxt->geom.sectors*cxt->geom.heads) > 1023))
stop = cxt->geom.heads*cxt->geom.sectors*1024 - 1;
set_hsc(p->end_head, p->end_sector, p->end_cyl, stop);
ptes[i].changed = 1;
@@ -981,3 +983,23 @@ struct fdisk_label *fdisk_new_dos_label(struct fdisk_context *cxt)
return lb;
}
+
+/*
+ * Public label specific functions
+ */
+
+int fdisk_dos_enable_compatible(struct fdisk_label *lb, int enable)
+{
+ struct fdisk_dos_label *dos = (struct fdisk_dos_label *) lb;
+
+ if (!lb)
+ return -EINVAL;
+
+ dos->compatible = enable;
+ return 0;
+}
+
+int fdisk_dos_is_compatible(struct fdisk_label *lb)
+{
+ return ((struct fdisk_dos_label *) lb)->compatible;
+}
diff --git a/fdisks/fdiskdoslabel.h b/fdisks/fdiskdoslabel.h
index 0e377d3ae..41a253bb3 100644
--- a/fdisks/fdiskdoslabel.h
+++ b/fdisks/fdiskdoslabel.h
@@ -18,7 +18,6 @@ struct pte {
};
extern struct pte ptes[MAXIMUM_PARTS];
-extern int dos_compatible_flag;
#define pt_offset(b, n) ((struct partition *)((b) + 0x1be + \
(n) * sizeof(struct partition)))
@@ -46,4 +45,8 @@ extern int mbr_is_valid_magic(unsigned char *b);
extern void change_units(struct fdisk_context *cxt);
extern void update_units(struct fdisk_context *cxt); /* called from sunlabel too */
+#define is_dos_compatible(_x) \
+ (fdisk_is_disklabel(_x, DOS) && \
+ fdisk_dos_is_compatible(fdisk_context_get_label(_x, NULL)))
+
#endif
diff --git a/libfdisk/src/context.c b/libfdisk/src/context.c
index b2929f351..9801b51f2 100644
--- a/libfdisk/src/context.c
+++ b/libfdisk/src/context.c
@@ -36,12 +36,18 @@ struct fdisk_context *fdisk_new_context(void)
return cxt;
}
+/*
+ * Returns the current label if no name specified.
+ */
struct fdisk_label *fdisk_context_get_label(struct fdisk_context *cxt, const char *name)
{
size_t i;
assert(cxt);
+ if (!name)
+ return cxt->label;
+
for (i = 0; i < cxt->nlabels; i++)
if (strcmp(cxt->labels[i]->name, name) == 0)
return cxt->labels[i];
diff --git a/libfdisk/src/libfdisk.h b/libfdisk/src/libfdisk.h
index d803fc2dc..927587622 100644
--- a/libfdisk/src/libfdisk.h
+++ b/libfdisk/src/libfdisk.h
@@ -87,6 +87,11 @@ extern int fdisk_set_partition_type(struct fdisk_context *cxt, int partnum,
/* alignment.c */
extern int fdisk_reset_alignment(struct fdisk_context *cxt);
+
+/* dos.c */
+extern int fdisk_dos_enable_compatible(struct fdisk_label *lb, int enable);
+extern int fdisk_dos_is_compatible(struct fdisk_label *lb);
+
#ifdef __cplusplus
}
#endif