diff options
-rw-r--r-- | fdisks/fdisk.c | 46 | ||||
-rw-r--r-- | fdisks/fdiskdoslabel.c | 30 | ||||
-rw-r--r-- | fdisks/fdiskdoslabel.h | 5 | ||||
-rw-r--r-- | libfdisk/src/context.c | 6 | ||||
-rw-r--r-- | libfdisk/src/libfdisk.h | 5 |
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 |