printf("\n");
}
-/*
- * Check whether partition entries are ordered by their starting positions.
- * Return 0 if OK. Return i if partition i should have been earlier.
- * Two separate checks: primary and logical partitions.
- */
-int
-wrong_p_order(int *prev) {
- struct pte *pe;
- struct partition *p;
- unsigned int last_p_start_pos = 0, p_start_pos;
- int i, last_i = 0;
-
- for (i = 0 ; i < partitions; i++) {
- if (i == 4) {
- last_i = 4;
- last_p_start_pos = 0;
- }
- pe = &ptes[i];
- if ((p = pe->part_table)->sys_ind) {
- p_start_pos = get_partition_start(pe);
-
- if (last_p_start_pos > p_start_pos) {
- if (prev)
- *prev = last_i;
- return i;
- }
-
- last_p_start_pos = p_start_pos;
- last_i = i;
- }
- }
- return 0;
-}
-
-/*
- * Fix the chain of logicals.
- * extended_offset is unchanged, the set of sectors used is unchanged
- * The chain is sorted so that sectors increase, and so that
- * starting sectors increase.
- *
- * After this it may still be that cfdisk doesn't like the table.
- * (This is because cfdisk considers expanded parts, from link to
- * end of partition, and these may still overlap.)
- * Now
- * sfdisk /dev/hda > ohda; sfdisk /dev/hda < ohda
- * may help.
- */
-static void
-fix_chain_of_logicals(void) {
- int j, oj, ojj, sj, sjj;
- struct partition *pj,*pjj,tmp;
-
- /* 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++) {
- oj = ptes[j].offset;
- ojj = ptes[j+1].offset;
- if (oj > ojj) {
- ptes[j].offset = ojj;
- ptes[j+1].offset = oj;
- pj = ptes[j].part_table;
- set_start_sect(pj, get_start_sect(pj)+oj-ojj);
- pjj = ptes[j+1].part_table;
- set_start_sect(pjj, get_start_sect(pjj)+ojj-oj);
- set_start_sect(ptes[j-1].ext_pointer,
- ojj-extended_offset);
- set_start_sect(ptes[j].ext_pointer,
- oj-extended_offset);
- goto stage1;
- }
- }
-
- /* Stage 2: sort starting sectors */
- stage2:
- for (j = 4; j < partitions-1; j++) {
- pj = ptes[j].part_table;
- pjj = ptes[j+1].part_table;
- sj = get_start_sect(pj);
- sjj = get_start_sect(pjj);
- oj = ptes[j].offset;
- ojj = ptes[j+1].offset;
- if (oj+sj > ojj+sjj) {
- tmp = *pj;
- *pj = *pjj;
- *pjj = tmp;
- set_start_sect(pj, ojj+sjj-oj);
- set_start_sect(pjj, oj+sj-ojj);
- goto stage2;
- }
- }
-
- /* Probably something was changed */
- for (j = 4; j < partitions; j++)
- ptes[j].changed = 1;
-}
-
-static void
-fix_partition_table_order(void) {
- struct pte *pei, *pek;
- int i,k;
-
- if (!wrong_p_order(NULL)) {
- printf(_("Nothing to do. Ordering is correct already.\n\n"));
- return;
- }
-
- while ((i = wrong_p_order(&k)) != 0 && i < 4) {
- /* partition i should have come earlier, move it */
- /* We have to move data in the MBR */
- struct partition *pi, *pk, *pe, pbuf;
- pei = &ptes[i];
- pek = &ptes[k];
-
- pe = pei->ext_pointer;
- pei->ext_pointer = pek->ext_pointer;
- pek->ext_pointer = pe;
-
- pi = pei->part_table;
- pk = pek->part_table;
-
- memmove(&pbuf, pi, sizeof(struct partition));
- memmove(pi, pk, sizeof(struct partition));
- memmove(pk, &pbuf, sizeof(struct partition));
-
- pei->changed = pek->changed = 1;
- }
-
- if (i)
- fix_chain_of_logicals();
-
- printf(_("Done.\n"));
-
-}
-
static void list_table(struct fdisk_context *cxt, int xtra)
{
if (fdisk_is_disklabel(cxt, SUN)) {
break;
case 'f':
if (fdisk_is_disklabel(cxt, DOS))
- fix_partition_table_order();
+ dos_fix_partition_table_order();
break;
case 'g':
fdisk_create_disklabel(cxt, "sgi");
unsigned int base, char *mesg, int *is_suffix_used);
extern int get_partition_dflt(struct fdisk_context *cxt, int warn, int max, int dflt);
-extern int wrong_p_order(int *prev);
-
#define PLURAL 0
#define SINGULAR 1
extern const char * str_units(int);
return 0;
}
+/*
+ * Check whether partition entries are ordered by their starting positions.
+ * Return 0 if OK. Return i if partition i should have been earlier.
+ * Two separate checks: primary and logical partitions.
+ */
+static int wrong_p_order(int *prev)
+{
+ struct pte *pe;
+ struct partition *p;
+ unsigned int last_p_start_pos = 0, p_start_pos;
+ int i, last_i = 0;
+
+ for (i = 0 ; i < partitions; i++) {
+ if (i == 4) {
+ last_i = 4;
+ last_p_start_pos = 0;
+ }
+ pe = &ptes[i];
+ if ((p = pe->part_table)->sys_ind) {
+ p_start_pos = get_partition_start(pe);
+
+ if (last_p_start_pos > p_start_pos) {
+ if (prev)
+ *prev = last_i;
+ return i;
+ }
+
+ last_p_start_pos = p_start_pos;
+ last_i = i;
+ }
+ }
+ return 0;
+}
static int is_garbage_table(void)
{
return 0;
}
+/*
+ * Fix the chain of logicals.
+ * extended_offset is unchanged, the set of sectors used is unchanged
+ * The chain is sorted so that sectors increase, and so that
+ * starting sectors increase.
+ *
+ * After this it may still be that cfdisk doesn't like the table.
+ * (This is because cfdisk considers expanded parts, from link to
+ * end of partition, and these may still overlap.)
+ * Now
+ * sfdisk /dev/hda > ohda; sfdisk /dev/hda < ohda
+ * may help.
+ */
+static void fix_chain_of_logicals(void)
+{
+ int j, oj, ojj, sj, sjj;
+ struct partition *pj,*pjj,tmp;
+
+ /* 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++) {
+ oj = ptes[j].offset;
+ ojj = ptes[j+1].offset;
+ if (oj > ojj) {
+ ptes[j].offset = ojj;
+ ptes[j+1].offset = oj;
+ pj = ptes[j].part_table;
+ set_start_sect(pj, get_start_sect(pj)+oj-ojj);
+ pjj = ptes[j+1].part_table;
+ set_start_sect(pjj, get_start_sect(pjj)+ojj-oj);
+ set_start_sect(ptes[j-1].ext_pointer,
+ ojj-extended_offset);
+ set_start_sect(ptes[j].ext_pointer,
+ oj-extended_offset);
+ goto stage1;
+ }
+ }
+
+ /* Stage 2: sort starting sectors */
+ stage2:
+ for (j = 4; j < partitions-1; j++) {
+ pj = ptes[j].part_table;
+ pjj = ptes[j+1].part_table;
+ sj = get_start_sect(pj);
+ sjj = get_start_sect(pjj);
+ oj = ptes[j].offset;
+ ojj = ptes[j+1].offset;
+ if (oj+sj > ojj+sjj) {
+ tmp = *pj;
+ *pj = *pjj;
+ *pjj = tmp;
+ set_start_sect(pj, ojj+sjj-oj);
+ set_start_sect(pjj, oj+sj-ojj);
+ goto stage2;
+ }
+ }
+
+ /* Probably something was changed */
+ for (j = 4; j < partitions; j++)
+ ptes[j].changed = 1;
+}
+
+void dos_fix_partition_table_order(void)
+{
+ struct pte *pei, *pek;
+ int i,k;
+
+ if (!wrong_p_order(NULL)) {
+ printf(_("Nothing to do. Ordering is correct already.\n\n"));
+ return;
+ }
+
+ while ((i = wrong_p_order(&k)) != 0 && i < 4) {
+ /* partition i should have come earlier, move it */
+ /* We have to move data in the MBR */
+ struct partition *pi, *pk, *pe, pbuf;
+ pei = &ptes[i];
+ pek = &ptes[k];
+
+ pe = pei->ext_pointer;
+ pei->ext_pointer = pek->ext_pointer;
+ pek->ext_pointer = pe;
+
+ pi = pei->part_table;
+ pk = pek->part_table;
+
+ memmove(&pbuf, pi, sizeof(struct partition));
+ memmove(pi, pk, sizeof(struct partition));
+ memmove(pk, &pbuf, sizeof(struct partition));
+
+ pei->changed = pek->changed = 1;
+ }
+
+ if (i)
+ fix_chain_of_logicals();
+
+ printf(_("Done.\n"));
+
+}
static const struct fdisk_label_operations dos_operations =
extern int dos_list_table(struct fdisk_context *cxt, int xtra);
+extern void dos_fix_partition_table_order(void);
+
extern int mbr_is_valid_magic(unsigned char *b);
extern void change_units(struct fdisk_context *cxt);