]>
git.ipfire.org Git - thirdparty/util-linux.git/blob - disk-utils/fdisk-menu.c
2 * SPDX-License-Identifier: GPL-2.0-or-later
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * Copyright (C) 2014 Karel Zak <kzak@redhat.com>
24 const char key
; /* command key */
25 const char *title
; /* help string */
26 unsigned int normal
: 1, /* normal mode */
27 expert
: 1, /* expert mode */
28 hidden
: 1; /* be sensitive for this key,
29 but don't print it in help */
31 enum fdisk_labeltype label
; /* only for this label */
32 int exclude
; /* all labels except these */
33 enum fdisk_labeltype parent
; /* for nested PT */
36 #define IS_MENU_SEP(e) ((e)->key == '-')
37 #define IS_MENU_HID(e) ((e)->hidden)
40 enum fdisk_labeltype label
; /* only for this label */
41 int exclude
; /* all labels except these */
43 unsigned int nonested
: 1; /* don't make this menu active in nested PT */
45 int (*callback
)(struct fdisk_context
**,
47 const struct menu_entry
*);
49 struct menu_entry entries
[]; /* NULL terminated array */
53 size_t menu_idx
; /* the current menu */
54 size_t entry_idx
; /* index with in the current menu */
57 #define MENU_CXT_EMPTY { 0, 0 }
58 #define DECLARE_MENU_CB(x) \
59 static int x(struct fdisk_context **, \
60 const struct menu *, \
61 const struct menu_entry *)
63 DECLARE_MENU_CB(gpt_menu_cb
);
64 DECLARE_MENU_CB(sun_menu_cb
);
65 DECLARE_MENU_CB(sgi_menu_cb
);
66 DECLARE_MENU_CB(geo_menu_cb
);
67 DECLARE_MENU_CB(dos_menu_cb
);
68 DECLARE_MENU_CB(bsd_menu_cb
);
69 DECLARE_MENU_CB(createlabel_menu_cb
);
70 DECLARE_MENU_CB(generic_menu_cb
);
74 * MENU_X* expert mode only
75 * MENU_B* both -- expert + normal mode
77 * *_E exclude this label
79 * *_L only for this label
83 #define MENU_SEP(t) { .title = t, .key = '-', .normal = 1 }
84 #define MENU_XSEP(t) { .title = t, .key = '-', .expert = 1 }
85 #define MENU_BSEP(t) { .title = t, .key = '-', .expert = 1, .normal = 1 }
88 #define MENU_ENT(k, t) { .title = t, .key = k, .normal = 1 }
89 #define MENU_ENT_E(k, t, l) { .title = t, .key = k, .normal = 1, .exclude = l }
90 #define MENU_ENT_L(k, t, l) { .title = t, .key = k, .normal = 1, .label = l }
92 #define MENU_XENT(k, t) { .title = t, .key = k, .expert = 1 }
93 #define MENU_XENT_H(k, t) { .title = t, .key = k, .expert = 1, .hidden = 1 }
95 #define MENU_BENT(k, t) { .title = t, .key = k, .expert = 1, .normal = 1 }
96 #define MENU_BENT_E(k, t, l) { .title = t, .key = k, .expert = 1, .normal = 1, .exclude = l }
98 #define MENU_ENT_NEST(k, t, l, p) { .title = t, .key = k, .normal = 1, .label = l, .parent = p }
99 #define MENU_BENT_NEST_H(k, t, l, p) { .title = t, .key = k, .expert = 1, .normal = 1, .label = l, .parent = p, .hidden = 1 }
102 static const struct menu menu_generic
= {
103 .callback
= generic_menu_cb
,
105 MENU_BSEP(N_("Generic")),
106 MENU_ENT ('d', N_("delete a partition")),
107 MENU_ENT ('F', N_("list free unpartitioned space")),
108 MENU_ENT ('l', N_("list known partition types")),
109 MENU_ENT ('n', N_("add a new partition")),
110 MENU_BENT ('p', N_("print the partition table")),
111 MENU_ENT ('t', N_("change a partition type")),
112 MENU_BENT_E('v', N_("verify the partition table"), FDISK_DISKLABEL_BSD
),
113 MENU_ENT ('i', N_("print information about a partition")),
114 MENU_ENT ('e', N_("resize a partition")),
115 MENU_ENT ('T', N_("discard (trim) sectors")),
117 MENU_XENT('d', N_("print the raw data of the first sector from the device")),
118 MENU_XENT('D', N_("print the raw data of the disklabel from the device")),
119 MENU_XENT('f', N_("fix partitions order")),
121 MENU_SEP(N_("Misc")),
122 MENU_BENT ('m', N_("print this menu")),
123 MENU_ENT_E('u', N_("change display/entry units"), FDISK_DISKLABEL_GPT
),
124 MENU_ENT_E('x', N_("extra functionality (experts only)"), FDISK_DISKLABEL_BSD
),
126 MENU_SEP(N_("Script")),
127 MENU_ENT ('I', N_("load disk layout from sfdisk script file")),
128 MENU_ENT ('O', N_("dump disk layout to sfdisk script file")),
130 MENU_BSEP(N_("Save & Exit")),
131 MENU_ENT_E('w', N_("write table to disk and exit"), FDISK_DISKLABEL_BSD
),
132 MENU_ENT_L('w', N_("write table to disk"), FDISK_DISKLABEL_BSD
),
133 MENU_BENT ('q', N_("quit without saving changes")),
134 MENU_XENT ('r', N_("return to main menu")),
136 MENU_ENT_NEST('r', N_("return from BSD to DOS (MBR)"), FDISK_DISKLABEL_BSD
, FDISK_DISKLABEL_DOS
),
138 MENU_ENT_NEST('r', N_("return from protective/hybrid MBR to GPT"), FDISK_DISKLABEL_DOS
, FDISK_DISKLABEL_GPT
),
144 static const struct menu menu_createlabel
= {
145 .callback
= createlabel_menu_cb
,
146 .exclude
= FDISK_DISKLABEL_BSD
,
149 MENU_SEP(N_("Create a new label")),
150 MENU_ENT('g', N_("create a new empty GPT partition table")),
151 MENU_ENT('G', N_("create a new empty SGI (IRIX) partition table")),
152 MENU_ENT('o', N_("create a new empty MBR (DOS) partition table")),
153 MENU_ENT('s', N_("create a new empty Sun partition table")),
155 /* backward compatibility -- be sensitive to 'g', but don't
156 * print it in the expert menu */
157 MENU_XENT_H('g', N_("create an IRIX (SGI) partition table")),
162 static const struct menu menu_geo
= {
163 .callback
= geo_menu_cb
,
164 .exclude
= FDISK_DISKLABEL_GPT
| FDISK_DISKLABEL_BSD
,
166 MENU_XSEP(N_("Geometry (for the current label)")),
167 MENU_XENT('c', N_("change number of cylinders")),
168 MENU_XENT('h', N_("change number of heads")),
169 MENU_XENT('s', N_("change number of sectors/track")),
174 static const struct menu menu_gpt
= {
175 .callback
= gpt_menu_cb
,
176 .label
= FDISK_DISKLABEL_GPT
,
178 MENU_BSEP(N_("GPT")),
179 MENU_XENT('i', N_("change disk GUID")),
180 MENU_XENT('n', N_("change partition name")),
181 MENU_XENT('u', N_("change partition UUID")),
182 MENU_XENT('l', N_("change table length")),
183 MENU_BENT('M', N_("enter protective/hybrid MBR")),
186 MENU_XENT('A', N_("toggle the legacy BIOS bootable flag")),
187 MENU_XENT('B', N_("toggle the no block IO protocol flag")),
188 MENU_XENT('R', N_("toggle the required partition flag")),
189 MENU_XENT('S', N_("toggle the GUID specific bits")),
195 static const struct menu menu_sun
= {
196 .callback
= sun_menu_cb
,
197 .label
= FDISK_DISKLABEL_SUN
,
199 MENU_BSEP(N_("Sun")),
200 MENU_ENT('a', N_("toggle the read-only flag")),
201 MENU_ENT('c', N_("toggle the mountable flag")),
203 MENU_XENT('a', N_("change number of alternate cylinders")),
204 MENU_XENT('e', N_("change number of extra sectors per cylinder")),
205 MENU_XENT('i', N_("change interleave factor")),
206 MENU_XENT('o', N_("change rotation speed (rpm)")),
207 MENU_XENT('y', N_("change number of physical cylinders")),
212 static const struct menu menu_sgi
= {
213 .callback
= sgi_menu_cb
,
214 .label
= FDISK_DISKLABEL_SGI
,
217 MENU_ENT('a', N_("select bootable partition")),
218 MENU_ENT('b', N_("edit bootfile entry")),
219 MENU_ENT('c', N_("select sgi swap partition")),
220 MENU_ENT('i', N_("create SGI info")),
225 static const struct menu menu_dos
= {
226 .callback
= dos_menu_cb
,
227 .label
= FDISK_DISKLABEL_DOS
,
229 MENU_BSEP(N_("DOS (MBR)")),
230 MENU_ENT('a', N_("toggle a bootable flag")),
231 MENU_ENT('b', N_("edit nested BSD disklabel")),
232 MENU_ENT('c', N_("toggle the dos compatibility flag")),
234 MENU_XENT('b', N_("move beginning of data in a partition")),
235 MENU_XENT('F', N_("fix partitions C/H/S values")),
236 MENU_XENT('i', N_("change the disk identifier")),
238 MENU_BENT_NEST_H('M', N_("return from protective/hybrid MBR to GPT"), FDISK_DISKLABEL_DOS
, FDISK_DISKLABEL_GPT
),
244 static const struct menu menu_bsd
= {
245 .callback
= bsd_menu_cb
,
246 .label
= FDISK_DISKLABEL_BSD
,
249 MENU_ENT('e', N_("edit drive data")),
250 MENU_ENT('i', N_("install bootstrap")),
251 MENU_ENT('s', N_("show complete disklabel")),
252 MENU_ENT('x', N_("link BSD partition to non-BSD partition")),
257 static const struct menu
*menus
[] = {
268 static const struct menu_entry
*next_menu_entry(
269 struct fdisk_context
*cxt
,
270 struct menu_context
*mc
)
272 struct fdisk_label
*lb
= fdisk_get_label(cxt
, NULL
);
273 struct fdisk_context
*parent
= fdisk_get_parent(cxt
);
274 unsigned int type
= 0, pr_type
= 0;
279 type
= fdisk_label_get_type(lb
);
281 pr_type
= fdisk_label_get_type(fdisk_get_label(parent
, NULL
));
283 while (mc
->menu_idx
< ARRAY_SIZE(menus
)) {
284 const struct menu
*m
= menus
[mc
->menu_idx
];
285 const struct menu_entry
*e
= &(m
->entries
[mc
->entry_idx
]);
291 /* no more entries */
292 if (e
->title
== NULL
||
293 /* menu wanted for specified labels only */
294 (m
->label
&& (!lb
|| !(m
->label
& type
))) ||
295 /* unwanted for nested PT */
296 (m
->nonested
&& parent
) ||
297 /* menu excluded for specified labels */
298 (m
->exclude
&& lb
&& (m
->exclude
& type
))) {
308 /* excluded for the current label */
309 if ((e
->exclude
&& lb
&& e
->exclude
& type
) ||
310 /* entry wanted for specified labels only */
311 (e
->label
&& (!lb
|| !(e
->label
& type
))) ||
312 /* exclude non-expert entries in expect mode */
313 (e
->expert
== 0 && fdisk_is_details(cxt
)) ||
315 (e
->parent
&& (!parent
|| pr_type
!= e
->parent
)) ||
316 /* exclude non-normal entries in normal mode */
317 (e
->normal
== 0 && !fdisk_is_details(cxt
))) {
328 /* returns @menu and menu entry for then @key */
329 static const struct menu_entry
*get_fdisk_menu_entry(
330 struct fdisk_context
*cxt
,
332 const struct menu
**menu
)
334 struct menu_context mc
= MENU_CXT_EMPTY
;
335 const struct menu_entry
*e
;
337 while ((e
= next_menu_entry(cxt
, &mc
))) {
338 if (IS_MENU_SEP(e
) || e
->key
!= key
)
342 *menu
= menus
[mc
.menu_idx
];
349 static int menu_detect_collisions(struct fdisk_context
*cxt
)
351 struct menu_context mc
= MENU_CXT_EMPTY
;
352 const struct menu_entry
*e
, *r
;
354 while ((e
= next_menu_entry(cxt
, &mc
))) {
358 r
= get_fdisk_menu_entry(cxt
, e
->key
, NULL
);
360 DBG(MENU
, ul_debug("warning: not found "
361 "entry for %c", e
->key
));
365 DBG(MENU
, ul_debug("warning: duplicate key '%c'",
367 DBG(MENU
, ul_debug(" : %s", e
->title
));
368 DBG(MENU
, ul_debug(" : %s", r
->title
));
376 static int print_fdisk_menu(struct fdisk_context
*cxt
)
378 struct menu_context mc
= MENU_CXT_EMPTY
;
379 const struct menu_entry
*e
;
381 ON_DBG(MENU
, menu_detect_collisions(cxt
));
383 if (fdisk_is_details(cxt
))
384 printf(_("\nHelp (expert commands):\n"));
386 printf(_("\nHelp:\n"));
388 while ((e
= next_menu_entry(cxt
, &mc
))) {
390 continue; /* hidden entry */
391 if (IS_MENU_SEP(e
) && (!e
->title
|| !*e
->title
))
393 else if (IS_MENU_SEP(e
)) {
394 color_scheme_enable("help-title", UL_COLOR_BOLD
);
395 printf("\n %s\n", _(e
->title
));
398 printf(" %c %s\n", e
->key
, _(e
->title
));
402 if (fdisk_get_parent(cxt
)) {
403 struct fdisk_label
*l
= fdisk_get_label(cxt
, NULL
),
404 *p
= fdisk_get_label(fdisk_get_parent(cxt
), NULL
);
406 fdisk_info(cxt
, _("You're editing nested '%s' partition table, "
407 "primary partition table is '%s'."),
408 fdisk_label_get_name(l
),
409 fdisk_label_get_name(p
));
415 /* Asks for command, verify the key and perform the command or
416 * returns the command key if no callback for the command is
419 * Note that this function might exchange the context pointer to
420 * switch to another (nested) context.
422 * Returns: <0 on error
423 * 0 on success (the command performed)
424 * >0 if no callback (then returns the key)
426 int process_fdisk_menu(struct fdisk_context
**cxt0
)
428 struct fdisk_context
*cxt
= *cxt0
;
429 const struct menu_entry
*ent
;
430 const struct menu
*menu
;
433 char buf
[BUFSIZ
] = { '\0' };
435 if (fdisk_is_details(cxt
))
436 prompt
= _("Expert command (m for help): ");
438 prompt
= _("Command (m for help): ");
441 rc
= get_user_reply(prompt
, buf
, sizeof(buf
));
443 if (rc
== -ECANCELED
) {
444 /* Map ^C and ^D in main menu to 'q' */
446 && fdisk_label_is_changed(fdisk_get_label(cxt
, NULL
))) {
447 /* TRANSLATORS: these yes no questions use rpmatch(),
448 * and should be translated. */
450 _("\nAll unwritten changes will be lost, do you really want to quit? (y/n)"),
452 if (rc
|| !rpmatch(buf
))
461 ent
= get_fdisk_menu_entry(cxt
, key
, &menu
);
463 fdisk_warnx(cxt
, _("%c: unknown command"), key
);
467 DBG(MENU
, ul_debug("selected: key=%c, entry='%s'",
470 /* menu has implemented callback, use it */
472 rc
= menu
->callback(cxt0
, menu
, ent
);
474 DBG(MENU
, ul_debug("no callback for key '%c'", key
));
478 DBG(MENU
, ul_debug("process menu done [rc=%d]", rc
));
482 static int script_read(struct fdisk_context
*cxt
)
484 struct fdisk_script
*sc
= NULL
;
485 char *filename
= NULL
;
488 rc
= fdisk_ask_string(cxt
, _("Enter script file name"), &filename
);
493 sc
= fdisk_new_script_from_file(cxt
, filename
);
495 fdisk_warn(cxt
, _("Cannot open %s"), filename
);
497 fdisk_warnx(cxt
, _("Failed to parse script file %s"), filename
);
498 else if (fdisk_apply_script(cxt
, sc
) != 0) {
499 fdisk_warnx(cxt
, _("Failed to apply script %s"), filename
);
500 fdisk_warnx(cxt
, _("Resetting fdisk!"));
501 rc
= fdisk_reassign_device(cxt
);
502 if (rc
== 0 && !fdisk_has_label(cxt
)) {
503 fdisk_info(cxt
, _("Device does not contain a recognized partition table."));
504 rc
= fdisk_create_disklabel(cxt
, NULL
);
507 fdisk_info(cxt
, _("Script successfully applied."));
509 fdisk_unref_script(sc
);
514 static int script_write(struct fdisk_context
*cxt
)
516 struct fdisk_script
*sc
= NULL
;
517 char *filename
= NULL
;
521 rc
= fdisk_ask_string(cxt
, _("Enter script file name"), &filename
);
525 sc
= fdisk_new_script(cxt
);
527 fdisk_warn(cxt
, _("Failed to allocate script handler"));
531 rc
= fdisk_script_read_context(sc
, NULL
);
533 fdisk_warnx(cxt
, _("Failed to transform disk layout into script"));
537 f
= fopen(filename
, "w");
539 fdisk_warn(cxt
, _("Cannot open %s"), filename
);
543 rc
= fdisk_script_write_file(sc
, f
);
545 fdisk_warn(cxt
, _("Failed to write script %s"), filename
);
547 fdisk_info(cxt
, _("Script successfully saved."));
551 fdisk_unref_script(sc
);
556 static int ask_for_wipe(struct fdisk_context
*cxt
, size_t partno
)
558 struct fdisk_partition
*tmp
= NULL
;
562 rc
= fdisk_get_partition(cxt
, partno
, &tmp
);
566 rc
= fdisk_partition_to_string(tmp
, cxt
, FDISK_FIELD_FSTYPE
, &fstype
);
567 if (rc
|| fstype
== NULL
)
570 fdisk_warnx(cxt
, _("Partition #%zu contains a %s signature."), partno
+ 1, fstype
);
572 if (pwipemode
== WIPEMODE_AUTO
&& isatty(STDIN_FILENO
))
573 fdisk_ask_yesno(cxt
, _("Do you want to remove the signature?"), &yes
);
574 else if (pwipemode
== WIPEMODE_ALWAYS
)
578 fdisk_info(cxt
, _("The signature will be removed by a write command."));
579 rc
= fdisk_wipe_partition(cxt
, partno
, TRUE
);
582 fdisk_unref_partition(tmp
);
588 * Basic fdisk actions
590 static int generic_menu_cb(struct fdisk_context
**cxt0
,
591 const struct menu
*menu
__attribute__((__unused__
)),
592 const struct menu_entry
*ent
)
594 struct fdisk_context
*cxt
= *cxt0
;
598 /* actions shared between expert and normal mode */
601 list_disk_geometry(cxt
);
605 if (fdisk_is_readonly(cxt
)) {
606 fdisk_warnx(cxt
, _("Device is open in read-only mode."));
609 rc
= fdisk_write_disklabel(cxt
);
611 err(EXIT_FAILURE
, _("failed to write disklabel"));
613 fdisk_info(cxt
, _("The partition table has been altered."));
614 if (fdisk_get_parent(cxt
))
615 break; /* nested PT, don't leave */
618 rc
= fdisk_reread_changes(cxt
, original_layout
);
620 rc
= fdisk_reread_partition_table(cxt
);
622 rc
= fdisk_deassign_device(cxt
, 0);
625 fdisk_unref_context(cxt
);
627 exit(rc
== 0 ? EXIT_SUCCESS
: EXIT_FAILURE
);
629 rc
= print_fdisk_menu(cxt
);
632 rc
= fdisk_verify_disklabel(cxt
);
635 rc
= print_partition_info(cxt
);
646 dump_firstsector(cxt
);
652 rc
= fdisk_reorder_partitions(cxt
);
655 rc
= fdisk_enable_details(cxt
, 0);
664 rc
= fdisk_ask_partnum(cxt
, &n
, FALSE
);
666 break; /* no partitions yet (or ENOMEM, ...) */
668 rc
= fdisk_delete_partition(cxt
, n
);
670 fdisk_warnx(cxt
, _("Could not delete partition %zu"), n
+ 1);
672 fdisk_info(cxt
, _("Partition %zu has been deleted."), n
+ 1);
681 list_partition_types(cxt
);
686 rc
= fdisk_add_partition(cxt
, NULL
, &partno
);
688 rc
= ask_for_wipe(cxt
, partno
);
692 resize_partition(cxt
);
695 change_partition_type(cxt
);
699 fdisk_use_cylinders(cxt
) ? "sectors" :
701 if (fdisk_use_cylinders(cxt
))
702 fdisk_info(cxt
, _("Changing display/entry units to cylinders (DEPRECATED!)."));
704 fdisk_info(cxt
, _("Changing display/entry units to sectors."));
707 fdisk_enable_details(cxt
, 1);
710 /* return from nested BSD to DOS or MBR to GPT */
711 if (fdisk_get_parent(cxt
)) {
712 *cxt0
= fdisk_get_parent(cxt
);
714 fdisk_info(cxt
, _("Leaving nested disklabel."));
715 fdisk_unref_context(cxt
);
720 discard_sectors(cxt
);
729 * This is fdisk frontend for GPT specific libfdisk functions that
730 * are not exported by generic libfdisk API.
732 static int gpt_menu_cb(struct fdisk_context
**cxt0
,
733 const struct menu
*menu
__attribute__((__unused__
)),
734 const struct menu_entry
*ent
)
736 struct fdisk_context
*cxt
= *cxt0
;
737 struct fdisk_context
*mbr
;
738 struct fdisk_partition
*pa
= NULL
;
741 uintmax_t length
= 0;
745 assert(fdisk_is_label(cxt
, GPT
));
747 DBG(MENU
, ul_debug("enter GPT menu"));
752 return fdisk_set_disklabel_id(cxt
);
754 rc
= fdisk_ask_number(cxt
, 1, fdisk_get_npartitions(cxt
),
755 ~(uint32_t)0, _("New maximum entries"), &length
);
758 return fdisk_gpt_set_npartitions(cxt
, (uint32_t) length
);
760 mbr
= fdisk_new_nested_context(cxt
, "dos");
764 if (fdisk_is_details(cxt
))
765 fdisk_enable_details(cxt
, 1); /* keep us in expert mode */
766 fdisk_info(cxt
, _("Entering protective/hybrid MBR disklabel."));
770 /* actions where is necessary partnum */
771 rc
= fdisk_ask_partnum(cxt
, &n
, FALSE
);
777 pa
= fdisk_new_partition(); /* new template */
782 rc
= fdisk_ask_string(cxt
, _("New UUID (in 8-4-4-4-12 format)"), &str
);
784 rc
= fdisk_partition_set_uuid(pa
, str
);
786 rc
= fdisk_set_partition(cxt
, n
, pa
);
788 fdisk_unref_partition(pa
);
792 pa
= fdisk_new_partition(); /* new template */
797 rc
= fdisk_ask_string(cxt
, _("New name"), &str
);
799 rc
= fdisk_partition_set_name(pa
, str
);
801 rc
= fdisk_set_partition(cxt
, n
, pa
);
803 fdisk_unref_partition(pa
);
807 rc
= fdisk_toggle_partition_flag(cxt
, n
, GPT_FLAG_LEGACYBOOT
);
810 rc
= fdisk_toggle_partition_flag(cxt
, n
, GPT_FLAG_NOBLOCK
);
813 rc
= fdisk_toggle_partition_flag(cxt
, n
, GPT_FLAG_REQUIRED
);
816 rc
= fdisk_toggle_partition_flag(cxt
, n
, GPT_FLAG_GUIDSPECIFIC
);
826 * This is fdisk frontend for MBR specific libfdisk functions that
827 * are not exported by generic libfdisk API.
829 static int dos_menu_cb(struct fdisk_context
**cxt0
,
830 const struct menu
*menu
__attribute__((__unused__
)),
831 const struct menu_entry
*ent
)
833 struct fdisk_context
*cxt
= *cxt0
;
836 DBG(MENU
, ul_debug("enter DOS menu"));
843 rc
= fdisk_ask_partnum(cxt
, &n
, FALSE
);
845 rc
= fdisk_toggle_partition_flag(cxt
, n
, DOS_FLAG_ACTIVE
);
850 struct fdisk_context
*bsd
851 = fdisk_new_nested_context(cxt
, "bsd");
854 if (!fdisk_has_label(bsd
))
855 rc
= fdisk_create_disklabel(bsd
, "bsd");
857 fdisk_unref_context(bsd
);
860 fdisk_info(cxt
, _("Entering nested BSD disklabel."));
865 toggle_dos_compatibility_flag(cxt
);
876 rc
= fdisk_ask_partnum(cxt
, &n
, FALSE
);
878 rc
= fdisk_dos_move_begin(cxt
, n
);
882 rc
= fdisk_set_disklabel_id(cxt
);
885 /* return from nested MBR to GPT (backward compatibility only) */
886 if (fdisk_get_parent(cxt
)) {
887 *cxt0
= fdisk_get_parent(cxt
);
889 fdisk_info(cxt
, _("Leaving nested disklabel."));
890 fdisk_unref_context(cxt
);
894 rc
= fdisk_dos_fix_chs(cxt
);
896 fdisk_info(cxt
, _("C/H/S values fixed."));
898 fdisk_info(cxt
, _("Nothing to do. C/H/S values are correct already."));
904 static int sun_menu_cb(struct fdisk_context
**cxt0
,
905 const struct menu
*menu
__attribute__((__unused__
)),
906 const struct menu_entry
*ent
)
908 struct fdisk_context
*cxt
= *cxt0
;
911 DBG(MENU
, ul_debug("enter SUN menu"));
915 assert(fdisk_is_label(cxt
, SUN
));
917 DBG(MENU
, ul_debug("enter SUN menu"));
923 rc
= fdisk_ask_partnum(cxt
, &n
, FALSE
);
928 rc
= fdisk_toggle_partition_flag(cxt
, n
, SUN_FLAG_RONLY
);
931 rc
= fdisk_toggle_partition_flag(cxt
, n
, SUN_FLAG_UNMNT
);
940 rc
= fdisk_sun_set_alt_cyl(cxt
);
943 rc
= fdisk_sun_set_xcyl(cxt
);
946 rc
= fdisk_sun_set_ilfact(cxt
);
949 rc
= fdisk_sun_set_rspeed(cxt
);
952 rc
= fdisk_sun_set_pcylcount(cxt
);
958 static int sgi_menu_cb(struct fdisk_context
**cxt0
,
959 const struct menu
*menu
__attribute__((__unused__
)),
960 const struct menu_entry
*ent
)
962 struct fdisk_context
*cxt
= *cxt0
;
966 DBG(MENU
, ul_debug("enter SGI menu"));
970 assert(fdisk_is_label(cxt
, SGI
));
977 rc
= fdisk_ask_partnum(cxt
, &n
, FALSE
);
979 rc
= fdisk_toggle_partition_flag(cxt
, n
, SGI_FLAG_BOOT
);
982 fdisk_sgi_set_bootfile(cxt
);
985 rc
= fdisk_ask_partnum(cxt
, &n
, FALSE
);
987 rc
= fdisk_toggle_partition_flag(cxt
, n
, SGI_FLAG_SWAP
);
990 rc
= fdisk_sgi_create_info(cxt
);
998 * This is fdisk frontend for BSD specific libfdisk functions that
999 * are not exported by generic libfdisk API.
1001 static int bsd_menu_cb(struct fdisk_context
**cxt0
,
1002 const struct menu
*menu
__attribute__((__unused__
)),
1003 const struct menu_entry
*ent
)
1005 struct fdisk_context
*cxt
= *cxt0
;
1010 assert(fdisk_is_label(cxt
, BSD
));
1012 DBG(MENU
, ul_debug("enter BSD menu"));
1016 rc
= fdisk_bsd_edit_disklabel(cxt
);
1019 rc
= fdisk_bsd_write_bootstrap(cxt
);
1022 org
= fdisk_is_details(cxt
);
1024 fdisk_enable_details(cxt
, 1);
1025 list_disklabel(cxt
);
1026 fdisk_enable_details(cxt
, org
);
1029 rc
= fdisk_bsd_link_partition(cxt
);
1037 * The geometry setting from this dialog is not persistent and maybe reset by
1038 * fdisk_reset_device_properties() (for example when you create a new disk
1039 * label). Note that on command line specified -C/-H/-S setting is persistent
1040 * as it's based on fdisk_save_user_geometry().
1042 static int geo_menu_cb(struct fdisk_context
**cxt0
,
1043 const struct menu
*menu
__attribute__((__unused__
)),
1044 const struct menu_entry
*ent
)
1046 struct fdisk_context
*cxt
= *cxt0
;
1047 struct fdisk_label
*lb
= fdisk_get_label(cxt
, NULL
);
1049 uintmax_t c
= 0, h
= 0, s
= 0;
1050 fdisk_sector_t mi
, ma
;
1052 DBG(MENU
, ul_debug("enter GEO menu"));
1059 lb
= fdisk_get_label(cxt
, "dos");
1063 fdisk_label_get_geomrange_cylinders(lb
, &mi
, &ma
);
1064 rc
= fdisk_ask_number(cxt
, mi
, fdisk_get_geom_cylinders(cxt
),
1065 ma
, _("Number of cylinders"), &c
);
1070 fdisk_label_get_geomrange_heads(lb
, &i
, &a
);
1071 rc
= fdisk_ask_number(cxt
, i
, fdisk_get_geom_heads(cxt
),
1072 a
, _("Number of heads"), &h
);
1076 fdisk_label_get_geomrange_sectors(lb
, &mi
, &ma
);
1077 rc
= fdisk_ask_number(cxt
, mi
, fdisk_get_geom_sectors(cxt
),
1078 ma
, _("Number of sectors"), &s
);
1083 fdisk_override_geometry(cxt
, c
, h
, s
);
1087 static int createlabel_menu_cb(struct fdisk_context
**cxt0
,
1088 const struct menu
*menu
__attribute__((__unused__
)),
1089 const struct menu_entry
*ent
)
1091 struct fdisk_context
*cxt
= *cxt0
;
1092 const char *wanted
= NULL
;
1095 DBG(MENU
, ul_debug("enter Create label menu"));
1103 /* Deprecated, use 'G' in main menu, just for backward
1104 * compatibility only. */
1126 rc
= fdisk_create_disklabel(cxt
, wanted
);
1129 fdisk_warn(cxt
, _("Failed to create '%s' disk label"), wanted
);
1132 if (rc
== 0 && fdisk_get_collision(cxt
))
1133 follow_wipe_mode(cxt
);