]> git.ipfire.org Git - thirdparty/util-linux.git/blame - fdisks/fdisk-menu.c
fdisk: (bsd) implement regular bsd menu callback
[thirdparty/util-linux.git] / fdisks / fdisk-menu.c
CommitLineData
161b0d1a
KZ
1
2#include <stdio.h>
3#include <stdlib.h>
4#include <string.h>
5#include <ctype.h>
6#include <stdint.h>
7
8#include "c.h"
9#include "fdisk.h"
9f280903 10#include "pt-sun.h"
f02fecd1
KZ
11#include "pt-mbr.h"
12
f02fecd1 13#include "fdiskbsdlabel.h"
161b0d1a
KZ
14
15struct menu_entry {
7e937b77
KZ
16 const char key; /* command key */
17 const char *title; /* help string */
18 unsigned int normal : 1, /* normal mode */
19 expert : 1, /* expert mode */
20 hidden : 1; /* be sensitive for this key,
21 but don't print it in help */
161b0d1a 22
7e937b77
KZ
23 enum fdisk_labeltype label; /* only for this label */
24 enum fdisk_labeltype exclude; /* all labels except this */
161b0d1a
KZ
25};
26
27#define IS_MENU_SEP(e) ((e)->key == '-')
28#define IS_MENU_HID(e) ((e)->hidden)
29
30struct menu {
31 enum fdisk_labeltype label; /* only for this label */
32 enum fdisk_labeltype exclude; /* all labels except this */
33
a47fec81 34 int (*callback)(struct fdisk_context **,
a410f8df
KZ
35 const struct menu *,
36 const struct menu_entry *);
161b0d1a
KZ
37
38 struct menu_entry entries[]; /* NULL terminated array */
39};
40
41struct menu_context {
42 size_t menu_idx; /* the current menu */
43 size_t entry_idx; /* index with in the current menu */
44};
45
46#define MENU_CXT_EMPTY { 0, 0 }
8e40a677 47#define DECLARE_MENU_CB(x) \
a47fec81 48 static int x(struct fdisk_context **, \
8e40a677
KZ
49 const struct menu *, \
50 const struct menu_entry *)
161b0d1a 51
8e40a677 52DECLARE_MENU_CB(gpt_menu_cb);
9f280903 53DECLARE_MENU_CB(sun_menu_cb);
8e40a677 54DECLARE_MENU_CB(geo_menu_cb);
f02fecd1 55DECLARE_MENU_CB(dos_menu_cb);
b529ea2a 56DECLARE_MENU_CB(bsd_menu_cb);
b9e94cd7 57
161b0d1a
KZ
58/*
59 * Menu entry macros:
60 * MENU_X* expert mode only
61 * MENU_B* both -- expert + normal mode
62 *
7e937b77
KZ
63 * *_E exclude this label
64 * *_H hidden
65 * *_L only for this label
161b0d1a
KZ
66 */
67
68/* separator */
69#define MENU_SEP(t) { .title = t, .key = '-', .normal = 1 }
70#define MENU_XSEP(t) { .title = t, .key = '-', .expert = 1 }
71#define MENU_BSEP(t) { .title = t, .key = '-', .expert = 1, .normal = 1 }
72
73/* entry */
74#define MENU_ENT(k, t) { .title = t, .key = k, .normal = 1 }
75#define MENU_ENT_E(k, t, l) { .title = t, .key = k, .normal = 1, .exclude = l }
7e937b77 76#define MENU_ENT_L(k, t, l) { .title = t, .key = k, .normal = 1, .label = l }
161b0d1a
KZ
77
78#define MENU_XENT(k, t) { .title = t, .key = k, .expert = 1 }
79#define MENU_XENT_H(k, t) { .title = t, .key = k, .expert = 1, .hidden = 1 }
80
81#define MENU_BENT(k, t) { .title = t, .key = k, .expert = 1, .normal = 1 }
82
83
84/* Generic menu */
85struct menu menu_generic = {
86/* .callback = generic_menu_cb,*/
87 .entries = {
6ae5e1e0 88 MENU_BSEP(N_("Generic")),
161b0d1a
KZ
89 MENU_ENT ('d', N_("delete a partition")),
90 MENU_ENT ('l', N_("list known partition types")),
91 MENU_ENT ('n', N_("add a new partition")),
92 MENU_BENT ('p', N_("print the partition table")),
6ae5e1e0 93 MENU_ENT ('t', N_("change a partition type")),
7e937b77 94 MENU_ENT_E('v', N_("verify the partition table"), FDISK_DISKLABEL_OSF),
161b0d1a 95
6ae5e1e0
KZ
96 MENU_XENT('d', N_("print the raw data of the first sector")),
97
161b0d1a
KZ
98 MENU_SEP(N_("Misc")),
99 MENU_BENT ('m', N_("print this menu")),
100 MENU_ENT_E('u', N_("change display/entry units"), FDISK_DISKLABEL_GPT),
7e937b77 101 MENU_ENT_E('x', N_("extra functionality (experts only)"), FDISK_DISKLABEL_OSF),
161b0d1a 102
2a1a67df 103 MENU_BSEP(N_("Save & Exit")),
161b0d1a 104 MENU_ENT_E('w', N_("write table to disk and exit"), FDISK_DISKLABEL_OSF),
7e937b77 105 MENU_ENT_L('w', N_("write table to disk"), FDISK_DISKLABEL_OSF),
161b0d1a
KZ
106 MENU_BENT ('q', N_("quit without saving changes")),
107 MENU_XENT ('r', N_("return to main menu")),
7e937b77 108 MENU_ENT_L('r', N_("return to main menu"), FDISK_DISKLABEL_OSF),
161b0d1a
KZ
109
110 { 0, NULL }
111 }
112};
113
114struct menu menu_createlabel = {
115/* .callback = createlabel_menu_cb, */
116 .exclude = FDISK_DISKLABEL_OSF,
117 .entries = {
118 MENU_SEP(N_("Create a new label")),
119 MENU_ENT('g', N_("create a new empty GPT partition table")),
120 MENU_ENT('G', N_("create a new empty SGI (IRIX) partition table")),
121 MENU_ENT('o', N_("create a new empty DOS partition table")),
122 MENU_ENT('s', N_("create a new empty Sun partition table")),
123
124 /* backward compatibility -- be sensitive to 'g', but don't
125 * print it in the expert menu */
126 MENU_XENT_H('g', N_("create an IRIX (SGI) partition table")),
127 { 0, NULL }
128 }
129};
130
be9ba6f3 131struct menu menu_geo = {
8e40a677 132 .callback = geo_menu_cb,
7e937b77 133 .exclude = FDISK_DISKLABEL_GPT | FDISK_DISKLABEL_OSF,
be9ba6f3
KZ
134 .entries = {
135 MENU_XSEP(N_("Geometry")),
136 MENU_XENT('c', N_("change number of cylinders")),
137 MENU_XENT('h', N_("change number of heads")),
138 MENU_XENT('s', N_("change number of sectors/track")),
139 { 0, NULL }
140 }
141};
142
161b0d1a 143struct menu menu_gpt = {
b9e94cd7 144 .callback = gpt_menu_cb,
161b0d1a
KZ
145 .label = FDISK_DISKLABEL_GPT,
146 .entries = {
147 MENU_XSEP(N_("GPT")),
35b1f0a4 148 MENU_XENT('i', N_("change disk GUID")),
161b0d1a 149 MENU_XENT('n', N_("change partition name")),
35b1f0a4
KZ
150 MENU_XENT('u', N_("change partition UUID")),
151
161b0d1a
KZ
152 { 0, NULL }
153 }
154};
155
2a1a67df 156struct menu menu_sun = {
9f280903 157 .callback = sun_menu_cb,
2a1a67df
KZ
158 .label = FDISK_DISKLABEL_SUN,
159 .entries = {
160 MENU_BSEP(N_("Sun")),
161 MENU_ENT('a', N_("toggle a read only flag")),
162 MENU_ENT('c', N_("toggle the mountable flag")),
163
164 MENU_XENT('a', N_("change number of alternate cylinders")),
2a1a67df 165 MENU_XENT('e', N_("change number of extra sectors per cylinder")),
2a1a67df
KZ
166 MENU_XENT('i', N_("change interleave factor")),
167 MENU_XENT('o', N_("change rotation speed (rpm)")),
2a1a67df
KZ
168 MENU_XENT('y', N_("change number of physical cylinders")),
169 { 0, NULL }
170 }
171};
172
6ae5e1e0
KZ
173struct menu menu_sgi = {
174/* .callback = sgi_menu_cb, */
175 .label = FDISK_DISKLABEL_SGI,
176 .entries = {
177 MENU_SEP(N_("SGI")),
178 MENU_ENT('a', N_("select bootable partition")),
179 MENU_ENT('b', N_("edit bootfile entry")),
180 MENU_ENT('c', N_("select sgi swap partition")),
181 { 0, NULL }
182 }
183};
184
185struct menu menu_dos = {
f02fecd1 186 .callback = dos_menu_cb,
6ae5e1e0
KZ
187 .label = FDISK_DISKLABEL_DOS,
188 .entries = {
189 MENU_BSEP(N_("DOS (MBR)")),
190 MENU_ENT('a', N_("toggle a bootable flag")),
191 MENU_ENT('b', N_("edit nested BSD disklabel")),
192 MENU_ENT('c', N_("toggle the dos compatibility flag")),
193
194 MENU_XENT('b', N_("move beginning of data in a partition")),
be9ba6f3 195 MENU_XENT('e', N_("list extended partitions")),
6ae5e1e0 196 MENU_XENT('f', N_("fix partition order")),
6ae5e1e0 197 MENU_XENT('i', N_("change the disk identifier")),
6ae5e1e0
KZ
198 { 0, NULL }
199 }
200};
201
202struct menu menu_bsd = {
b529ea2a 203 .callback = bsd_menu_cb,
6ae5e1e0
KZ
204 .label = FDISK_DISKLABEL_OSF,
205 .entries = {
206 MENU_SEP(N_("BSD")),
207 MENU_ENT('e', N_("edit drive data")),
208 MENU_ENT('i', N_("install bootstrap")),
209 MENU_ENT('s', N_("show complete disklabel")),
6ae5e1e0 210 MENU_ENT('x', N_("link BSD partition to non-BSD partition")),
6ae5e1e0
KZ
211 { 0, NULL }
212 }
213};
214
161b0d1a 215static const struct menu *menus[] = {
6ae5e1e0
KZ
216 &menu_gpt,
217 &menu_sun,
218 &menu_sgi,
219 &menu_dos,
220 &menu_bsd,
be9ba6f3 221 &menu_geo,
161b0d1a
KZ
222 &menu_generic,
223 &menu_createlabel,
161b0d1a
KZ
224};
225
226static const struct menu_entry *next_menu_entry(
227 struct fdisk_context *cxt,
228 struct menu_context *mc)
229{
230 while (mc->menu_idx < ARRAY_SIZE(menus)) {
231 const struct menu *m = menus[mc->menu_idx];
232 const struct menu_entry *e = &(m->entries[mc->entry_idx]);
233
be9ba6f3 234 /* no more entries */
161b0d1a 235 if (e->title == NULL ||
be9ba6f3
KZ
236 /* menu wanted for specified labels only */
237 (m->label && cxt->label && !(m->label & cxt->label->id)) ||
238 /* menu excluded for specified labels */
239 (m->exclude && cxt->label && (m->exclude & cxt->label->id))) {
161b0d1a
KZ
240 mc->menu_idx++;
241 mc->entry_idx = 0;
242 continue;
243 }
244
7e937b77
KZ
245 /* excluded for the current label */
246 if ((e->exclude && cxt->label && e->exclude & cxt->label->id) ||
247 /* entry wanted for specified labels only */
248 (e->label && cxt->label && !(e->label & cxt->label->id)) ||
161b0d1a
KZ
249 /* exclude non-expert entries in expect mode */
250 (e->expert == 0 && fdisk_context_display_details(cxt)) ||
251 /* exclude non-normal entries in normal mode */
252 (e->normal == 0 && !fdisk_context_display_details(cxt))) {
253
254 mc->entry_idx++;
255 continue;
256 }
257 mc->entry_idx++;
258 return e;
259
260 }
261 return NULL;
262}
263
3b4f9f16
KZ
264/* returns @menu and menu entry for then @key */
265static const struct menu_entry *get_fdisk_menu_entry(
266 struct fdisk_context *cxt,
267 int key,
268 const struct menu **menu)
269{
270 struct menu_context mc = MENU_CXT_EMPTY;
271 const struct menu_entry *e;
272
273 while ((e = next_menu_entry(cxt, &mc))) {
274 if (IS_MENU_SEP(e) || e->key != key)
275 continue;
276
277 if (menu)
278 *menu = menus[mc.menu_idx];
279 return e;
280 }
281
282 return NULL;
283}
284
285static int menu_detect_collisions(struct fdisk_context *cxt)
286{
287 struct menu_context mc = MENU_CXT_EMPTY;
288 const struct menu_entry *e, *r;
289
290 while ((e = next_menu_entry(cxt, &mc))) {
291 if (IS_MENU_SEP(e))
292 continue;
293
294 r = get_fdisk_menu_entry(cxt, e->key, NULL);
295 if (!r) {
36050e70 296 DBG(FRONTEND, dbgprint("warning: not found "
3b4f9f16
KZ
297 "entry for %c", e->key));
298 return -1;
299 }
300 if (r != e) {
36050e70 301 DBG(FRONTEND, dbgprint("warning: duplicate key '%c'",
3b4f9f16 302 e->key));
818d7924
KZ
303 DBG(FRONTEND, dbgprint(" : %s", e->title));
304 DBG(FRONTEND, dbgprint(" : %s", r->title));
3b4f9f16
KZ
305 abort();
306 }
307 }
308
309 return 0;
310}
311
39f01b7b 312int print_fdisk_menu(struct fdisk_context *cxt)
161b0d1a
KZ
313{
314 struct menu_context mc = MENU_CXT_EMPTY;
315 const struct menu_entry *e;
316
36050e70 317 ON_DBG(FRONTEND, menu_detect_collisions(cxt));
3b4f9f16 318
161b0d1a 319 if (fdisk_context_display_details(cxt))
39f01b7b 320 printf(_("\nHelp (expert commands):\n"));
161b0d1a 321 else
39f01b7b 322 printf(_("\nHelp:\n"));
161b0d1a
KZ
323
324 while ((e = next_menu_entry(cxt, &mc))) {
325 if (IS_MENU_HID(e))
326 continue; /* hidden entry */
327 if (IS_MENU_SEP(e))
328 printf("\n %s\n", _(e->title));
329 else
330 printf(" %c %s\n", e->key, _(e->title));
331 }
332 fputc('\n', stdout);
333
334 return 0;
335}
336
a410f8df
KZ
337/* Asks for command, verify the key and perform the command or
338 * returns the command key if no callback for the command is
339 * implemented.
340 *
a47fec81
KZ
341 * Note that this function might exchange the context pointer to
342 * switch to another (nested) context.
343 *
a410f8df
KZ
344 * Returns: <0 on error
345 * 0 on success (the command performed)
346 * >0 if no callback (then returns the key)
347 */
a47fec81 348int process_fdisk_menu(struct fdisk_context **cxt0)
a410f8df 349{
a47fec81 350 struct fdisk_context *cxt = *cxt0;
a410f8df
KZ
351 const struct menu_entry *ent;
352 const struct menu *menu;
353 int key, rc;
354 const char *prompt;
355 char buf[BUFSIZ];
356
357 if (fdisk_context_display_details(cxt))
358 prompt = _("Expert command (m for help): ");
359 else
360 prompt = _("Command (m for help): ");
361
362 fputc('\n',stdout);
363 rc = get_user_reply(cxt, prompt, buf, sizeof(buf));
364 if (rc)
365 return rc;
366
367 key = buf[0];
368 ent = get_fdisk_menu_entry(cxt, key, &menu);
369 if (!ent) {
370 fdisk_warnx(cxt, _("%c: unknown command"), key);
371 return -EINVAL;
372 }
373
a47fec81 374 rc = 0;
36050e70 375 DBG(FRONTEND, dbgprint("selected: key=%c, entry='%s'",
a410f8df
KZ
376 key, ent->title));
377 /* hardcoded help */
a47fec81 378 if (key == 'm')
a410f8df 379 print_fdisk_menu(cxt);
a410f8df
KZ
380
381 /* menu has implemented callback, use it */
a47fec81
KZ
382 else if (menu->callback)
383 rc = menu->callback(cxt0, menu, ent);
384 else {
385 DBG(FRONTEND, dbgprint("no callback, return key '%c'", key));
386 return key;
387 }
a410f8df 388
a47fec81
KZ
389 DBG(FRONTEND, dbgprint("process menu done [rc=%d]", rc));
390 return rc;
a410f8df
KZ
391}
392
8e40a677 393
b9e94cd7
KZ
394/*
395 * This is fdisk frontend for GPT specific libfdisk functions that
396 * are not expported by generic libfdisk API.
397 */
a47fec81 398static int gpt_menu_cb(struct fdisk_context **cxt0,
b9e94cd7
KZ
399 const struct menu *menu __attribute__((__unused__)),
400 const struct menu_entry *ent)
401{
a47fec81 402 struct fdisk_context *cxt = *cxt0;
b9e94cd7
KZ
403 size_t n;
404 int rc;
405
406 assert(cxt);
407 assert(ent);
408 assert(fdisk_is_disklabel(cxt, GPT));
409
36050e70 410 DBG(FRONTEND, dbgprint("enter GPT menu"));
b9e94cd7 411
35b1f0a4
KZ
412 if (ent->key == 'i')
413 return fdisk_set_disklabel_id(cxt);
414
b9e94cd7
KZ
415 rc = fdisk_ask_partnum(cxt, &n, FALSE);
416 if (rc)
417 return rc;
418
419 switch(ent->key) {
420 case 'u':
421 rc = fdisk_gpt_partition_set_uuid(cxt, n);
422 break;
423 case 'n':
1054699c 424 rc = fdisk_gpt_partition_set_name(cxt, n);
b9e94cd7
KZ
425 break;
426 }
427 return rc;
428}
429
f02fecd1
KZ
430
431/*
432 * This is fdisk frontend for MBR specific libfdisk functions that
433 * are not expported by generic libfdisk API.
434 */
a47fec81 435static int dos_menu_cb(struct fdisk_context **cxt0,
f02fecd1
KZ
436 const struct menu *menu __attribute__((__unused__)),
437 const struct menu_entry *ent)
438{
a47fec81 439 struct fdisk_context *cxt = *cxt0;
f02fecd1
KZ
440 int rc = 0;
441
a47fec81
KZ
442 DBG(FRONTEND, dbgprint("enter DOS menu"));
443
f02fecd1
KZ
444 if (!ent->expert) {
445 switch (ent->key) {
446 case 'a':
447 {
448 size_t n;
449 rc = fdisk_ask_partnum(cxt, &n, FALSE);
450 if (!rc)
451 rc = fdisk_partition_toggle_flag(cxt, n, DOS_FLAG_ACTIVE);
452 break;
453 }
454 case 'b':
455 {
456 struct fdisk_context *bsd
457 = fdisk_new_nested_context(cxt, "bsd");
818d7924
KZ
458 if (!bsd)
459 return -ENOMEM;
460 if (!fdisk_dev_has_disklabel(bsd))
461 rc = fdisk_create_disklabel(bsd, "bsd");
a47fec81
KZ
462 if (rc)
463 fdisk_free_context(bsd);
464 else
465 *cxt0 = cxt = bsd;
f02fecd1
KZ
466 break;
467 }
468 case 'c':
469 toggle_dos_compatibility_flag(cxt);
470 break;
471 }
472 return rc;
473 }
474
475 /* expert mode */
476 switch (ent->key) {
477 case 'b':
478 {
479 size_t n;
480 rc = fdisk_ask_partnum(cxt, &n, FALSE);
481 if (!rc)
f8ad3899 482 rc = fdisk_dos_move_begin(cxt, n);
f02fecd1
KZ
483 break;
484 }
485 case 'e':
486 rc = fdisk_dos_list_extended(cxt);
487 break;
488 case 'f':
f8ad3899 489 rc = fdisk_dos_fix_order(cxt);
f02fecd1
KZ
490 break;
491 case 'i':
492 rc = fdisk_set_disklabel_id(cxt);
493 break;
494 }
495 return rc;
496}
497
a47fec81 498static int sun_menu_cb(struct fdisk_context **cxt0,
9f280903
KZ
499 const struct menu *menu __attribute__((__unused__)),
500 const struct menu_entry *ent)
501{
a47fec81 502 struct fdisk_context *cxt = *cxt0;
9f280903
KZ
503 int rc = 0;
504
a47fec81
KZ
505 DBG(FRONTEND, dbgprint("enter SUN menu"));
506
9f280903
KZ
507 assert(cxt);
508 assert(ent);
509 assert(fdisk_is_disklabel(cxt, SUN));
510
511 DBG(FRONTEND, dbgprint("enter SUN menu"));
512
513 /* normal mode */
514 if (!ent->expert) {
515 size_t n;
516
517 rc = fdisk_ask_partnum(cxt, &n, FALSE);
518 if (rc)
519 return rc;
520 switch (ent->key) {
521 case 'a':
522 rc = fdisk_partition_toggle_flag(cxt, n, SUN_FLAG_RONLY);
523 break;
524 case 'c':
525 rc = fdisk_partition_toggle_flag(cxt, n, SUN_FLAG_UNMNT);
526 break;
527 }
528 return rc;
529 }
530
531 /* expert mode */
532 switch (ent->key) {
533 case 'a':
534 rc = fdisk_sun_set_alt_cyl(cxt);
535 break;
536 case 'e':
537 rc = fdisk_sun_set_xcyl(cxt);
538 break;
539 case 'i':
540 rc = fdisk_sun_set_ilfact(cxt);
541 break;
542 case 'o':
543 rc = fdisk_sun_set_rspeed(cxt);
544 break;
545 case 'y':
546 rc = fdisk_sun_set_pcylcount(cxt);
547 break;
548 }
549 return rc;
550}
551
b529ea2a
KZ
552/*
553 * This is fdisk frontend for BSD specific libfdisk functions that
554 * are not expported by generic libfdisk API.
555 */
556static int bsd_menu_cb(struct fdisk_context **cxt0,
557 const struct menu *menu __attribute__((__unused__)),
558 const struct menu_entry *ent)
559{
560 struct fdisk_context *cxt = *cxt0;
561 int rc = 0;
562
563 assert(cxt);
564 assert(ent);
565 assert(fdisk_is_disklabel(cxt, OSF));
566
567 DBG(FRONTEND, dbgprint("enter BSD menu"));
568
569 switch(ent->key) {
570 case 'e':
571 rc = fdisk_bsd_edit_disklabel(cxt);
572 break;
573 case 'i':
574 rc = fdisk_bsd_write_bootstrap(cxt);
575 break;
576 case 's':
577 xbsd_print_disklabel(cxt, 1);
578 break;
579 case 'x':
580 rc = fdisk_bsd_link_partition(cxt);
581 break;
582 }
583 return rc;
584}
585
8e40a677 586/* C/H/S commands */
a47fec81 587static int geo_menu_cb(struct fdisk_context **cxt0,
8e40a677
KZ
588 const struct menu *menu __attribute__((__unused__)),
589 const struct menu_entry *ent)
590{
a47fec81 591 struct fdisk_context *cxt = *cxt0;
8e40a677
KZ
592 int rc = -EINVAL;
593 uintmax_t c = 0, h = 0, s = 0;
594
a47fec81
KZ
595 DBG(FRONTEND, dbgprint("enter GEO menu"));
596
8e40a677
KZ
597 assert(cxt);
598 assert(ent);
599
600 switch (ent->key) {
601 case 'c':
602 rc = fdisk_ask_number(cxt, 1, cxt->geom.cylinders,
603 1048576, _("Number of cylinders"), &c);
604 break;
605 case 'h':
606 rc = fdisk_ask_number(cxt, 1, cxt->geom.heads,
607 256, _("Number of heads"), &h);
608 break;
609 case 's':
610 rc = fdisk_ask_number(cxt, 1, cxt->geom.sectors,
611 63, _("Number of sectors"), &s);
612 break;
613 }
614
615 if (!rc)
616 fdisk_override_geometry(cxt, c, h, s);
617 return rc;
618}
619
161b0d1a
KZ
620#ifdef TEST_PROGRAM
621struct fdisk_label *fdisk_new_dos_label(struct fdisk_context *cxt) { return NULL; }
622struct fdisk_label *fdisk_new_bsd_label(struct fdisk_context *cxt) { return NULL; }
623struct fdisk_label *fdisk_new_mac_label(struct fdisk_context *cxt) { return NULL; }
624struct fdisk_label *fdisk_new_sgi_label(struct fdisk_context *cxt) { return NULL; }
625
626int main(int argc, char *argv[])
627{
628 struct fdisk_context *cxt;
629 int idx = 1;
630
631 fdisk_init_debug(0);
632 cxt = fdisk_new_context();
633
634 if (argc > idx && strcmp(argv[idx], "--expert") == 0) {
635 fdisk_context_enable_details(cxt, 1);
636 idx++;
637 }
638 fdisk_context_switch_label(cxt, argc > idx ? argv[idx] : "gpt");
639
640 print_fdisk_menu(cxt);
641 return 0;
642}
643#endif