]>
git.ipfire.org Git - thirdparty/util-linux.git/blob - fdisks/fdisk-menu.c
14 unsigned int normal
: 1,
18 enum fdisk_labeltype exclude
;
21 #define IS_MENU_SEP(e) ((e)->key == '-')
22 #define IS_MENU_HID(e) ((e)->hidden)
25 enum fdisk_labeltype label
; /* only for this label */
26 enum fdisk_labeltype exclude
; /* all labels except this */
28 int (*callback
)(struct fdisk_context
*,
30 const struct menu_entry
*);
32 struct menu_entry entries
[]; /* NULL terminated array */
36 size_t menu_idx
; /* the current menu */
37 size_t entry_idx
; /* index with in the current menu */
40 #define MENU_CXT_EMPTY { 0, 0 }
42 static int gpt_menu_cb(struct fdisk_context
*cxt
,
43 const struct menu
*menu
,
44 const struct menu_entry
*ent
);
48 * MENU_X* expert mode only
49 * MENU_B* both -- expert + normal mode
56 #define MENU_SEP(t) { .title = t, .key = '-', .normal = 1 }
57 #define MENU_XSEP(t) { .title = t, .key = '-', .expert = 1 }
58 #define MENU_BSEP(t) { .title = t, .key = '-', .expert = 1, .normal = 1 }
61 #define MENU_ENT(k, t) { .title = t, .key = k, .normal = 1 }
62 #define MENU_ENT_E(k, t, l) { .title = t, .key = k, .normal = 1, .exclude = l }
64 #define MENU_XENT(k, t) { .title = t, .key = k, .expert = 1 }
65 #define MENU_XENT_H(k, t) { .title = t, .key = k, .expert = 1, .hidden = 1 }
67 #define MENU_BENT(k, t) { .title = t, .key = k, .expert = 1, .normal = 1 }
71 struct menu menu_generic
= {
72 /* .callback = generic_menu_cb,*/
74 MENU_BSEP(N_("Generic")),
75 MENU_ENT ('d', N_("delete a partition")),
76 MENU_ENT ('l', N_("list known partition types")),
77 MENU_ENT ('n', N_("add a new partition")),
78 MENU_BENT ('p', N_("print the partition table")),
79 MENU_ENT ('t', N_("change a partition type")),
80 MENU_ENT ('v', N_("verify the partition table")),
82 MENU_XENT('d', N_("print the raw data of the first sector")),
85 MENU_BENT ('m', N_("print this menu")),
86 MENU_ENT_E('u', N_("change display/entry units"), FDISK_DISKLABEL_GPT
),
87 MENU_ENT ('x', N_("extra functionality (experts only)")),
89 MENU_BSEP(N_("Save & Exit")),
90 MENU_ENT_E('w', N_("write table to disk and exit"), FDISK_DISKLABEL_OSF
),
91 MENU_BENT ('q', N_("quit without saving changes")),
92 MENU_XENT ('r', N_("return to main menu")),
98 struct menu menu_createlabel
= {
99 /* .callback = createlabel_menu_cb, */
100 .exclude
= FDISK_DISKLABEL_OSF
,
102 MENU_SEP(N_("Create a new label")),
103 MENU_ENT('g', N_("create a new empty GPT partition table")),
104 MENU_ENT('G', N_("create a new empty SGI (IRIX) partition table")),
105 MENU_ENT('o', N_("create a new empty DOS partition table")),
106 MENU_ENT('s', N_("create a new empty Sun partition table")),
108 /* backward compatibility -- be sensitive to 'g', but don't
109 * print it in the expert menu */
110 MENU_XENT_H('g', N_("create an IRIX (SGI) partition table")),
115 struct menu menu_geo
= {
116 /* .callback = geo_menu_cb, */
117 .exclude
= FDISK_DISKLABEL_GPT
,
119 MENU_XSEP(N_("Geometry")),
120 MENU_XENT('c', N_("change number of cylinders")),
121 MENU_XENT('h', N_("change number of heads")),
122 MENU_XENT('s', N_("change number of sectors/track")),
127 struct menu menu_gpt
= {
128 .callback
= gpt_menu_cb
,
129 .label
= FDISK_DISKLABEL_GPT
,
131 MENU_XSEP(N_("GPT")),
132 MENU_XENT('u', N_("change partition UUID")),
133 MENU_XENT('n', N_("change partition name")),
138 struct menu menu_sun
= {
139 /* .callback = sun_menu_cb, */
140 .label
= FDISK_DISKLABEL_SUN
,
142 MENU_BSEP(N_("Sun")),
143 MENU_ENT('a', N_("toggle a read only flag")),
144 MENU_ENT('c', N_("toggle the mountable flag")),
146 MENU_XENT('a', N_("change number of alternate cylinders")),
147 MENU_XENT('e', N_("change number of extra sectors per cylinder")),
148 MENU_XENT('i', N_("change interleave factor")),
149 MENU_XENT('o', N_("change rotation speed (rpm)")),
150 MENU_XENT('y', N_("change number of physical cylinders")),
155 struct menu menu_sgi
= {
156 /* .callback = sgi_menu_cb, */
157 .label
= FDISK_DISKLABEL_SGI
,
160 MENU_ENT('a', N_("select bootable partition")),
161 MENU_ENT('b', N_("edit bootfile entry")),
162 MENU_ENT('c', N_("select sgi swap partition")),
167 struct menu menu_dos
= {
168 /* .callback = dos_menu_cb, */
169 .label
= FDISK_DISKLABEL_DOS
,
171 MENU_BSEP(N_("DOS (MBR)")),
172 MENU_ENT('a', N_("toggle a bootable flag")),
173 MENU_ENT('b', N_("edit nested BSD disklabel")),
174 MENU_ENT('c', N_("toggle the dos compatibility flag")),
176 MENU_XENT('b', N_("move beginning of data in a partition")),
177 MENU_XENT('e', N_("list extended partitions")),
178 MENU_XENT('f', N_("fix partition order")),
179 MENU_XENT('i', N_("change the disk identifier")),
184 struct menu menu_bsd
= {
185 /* .callback = bsd_menu_cb, */
186 .label
= FDISK_DISKLABEL_OSF
,
189 MENU_ENT('e', N_("edit drive data")),
190 MENU_ENT('i', N_("install bootstrap")),
191 MENU_ENT('s', N_("show complete disklabel")),
192 MENU_ENT('w', N_("write disklabel to disk")),
193 #if !defined (__alpha__)
194 MENU_ENT('x', N_("link BSD partition to non-BSD partition")),
200 static const struct menu
*menus
[] = {
211 static const struct menu_entry
*next_menu_entry(
212 struct fdisk_context
*cxt
,
213 struct menu_context
*mc
)
215 while (mc
->menu_idx
< ARRAY_SIZE(menus
)) {
216 const struct menu
*m
= menus
[mc
->menu_idx
];
217 const struct menu_entry
*e
= &(m
->entries
[mc
->entry_idx
]);
219 /* no more entries */
220 if (e
->title
== NULL
||
221 /* menu wanted for specified labels only */
222 (m
->label
&& cxt
->label
&& !(m
->label
& cxt
->label
->id
)) ||
223 /* menu excluded for specified labels */
224 (m
->exclude
&& cxt
->label
&& (m
->exclude
& cxt
->label
->id
))) {
230 /* is the entry excluded for the current label? */
231 if ((e
->exclude
&& cxt
->label
&&
232 e
->exclude
& cxt
->label
->id
) ||
233 /* exclude non-expert entries in expect mode */
234 (e
->expert
== 0 && fdisk_context_display_details(cxt
)) ||
235 /* exclude non-normal entries in normal mode */
236 (e
->normal
== 0 && !fdisk_context_display_details(cxt
))) {
248 /* returns @menu and menu entry for then @key */
249 static const struct menu_entry
*get_fdisk_menu_entry(
250 struct fdisk_context
*cxt
,
252 const struct menu
**menu
)
254 struct menu_context mc
= MENU_CXT_EMPTY
;
255 const struct menu_entry
*e
;
257 while ((e
= next_menu_entry(cxt
, &mc
))) {
258 if (IS_MENU_SEP(e
) || e
->key
!= key
)
262 *menu
= menus
[mc
.menu_idx
];
269 static int menu_detect_collisions(struct fdisk_context
*cxt
)
271 struct menu_context mc
= MENU_CXT_EMPTY
;
272 const struct menu_entry
*e
, *r
;
274 while ((e
= next_menu_entry(cxt
, &mc
))) {
278 r
= get_fdisk_menu_entry(cxt
, e
->key
, NULL
);
280 DBG(FRONTEND
, dbgprint("warning: not found "
281 "entry for %c", e
->key
));
285 DBG(FRONTEND
, dbgprint("warning: duplicate key '%c'",
287 DBG(FRONTEND
, dbgprint(" %s", e
->title
));
288 DBG(FRONTEND
, dbgprint(" %s", r
->title
));
296 int print_fdisk_menu(struct fdisk_context
*cxt
)
298 struct menu_context mc
= MENU_CXT_EMPTY
;
299 const struct menu_entry
*e
;
301 ON_DBG(FRONTEND
, menu_detect_collisions(cxt
));
303 if (fdisk_context_display_details(cxt
))
304 printf(_("\nHelp (expert commands):\n"));
306 printf(_("\nHelp:\n"));
308 while ((e
= next_menu_entry(cxt
, &mc
))) {
310 continue; /* hidden entry */
312 printf("\n %s\n", _(e
->title
));
314 printf(" %c %s\n", e
->key
, _(e
->title
));
321 /* Asks for command, verify the key and perform the command or
322 * returns the command key if no callback for the command is
325 * Returns: <0 on error
326 * 0 on success (the command performed)
327 * >0 if no callback (then returns the key)
329 int process_fdisk_menu(struct fdisk_context
*cxt
)
331 const struct menu_entry
*ent
;
332 const struct menu
*menu
;
337 if (fdisk_context_display_details(cxt
))
338 prompt
= _("Expert command (m for help): ");
340 prompt
= _("Command (m for help): ");
343 rc
= get_user_reply(cxt
, prompt
, buf
, sizeof(buf
));
348 ent
= get_fdisk_menu_entry(cxt
, key
, &menu
);
350 fdisk_warnx(cxt
, _("%c: unknown command"), key
);
354 DBG(FRONTEND
, dbgprint("selected: key=%c, entry='%s'",
358 print_fdisk_menu(cxt
);
361 /* menu has implemented callback, use it */
362 } else if (menu
->callback
)
363 return menu
->callback(cxt
, menu
, ent
);
365 /* no callback, return the key */
370 * This is fdisk frontend for GPT specific libfdisk functions that
371 * are not expported by generic libfdisk API.
373 static int gpt_menu_cb(struct fdisk_context
*cxt
,
374 const struct menu
*menu
__attribute__((__unused__
)),
375 const struct menu_entry
*ent
)
382 assert(fdisk_is_disklabel(cxt
, GPT
));
384 DBG(FRONTEND
, dbgprint("enter GPT menu"));
386 rc
= fdisk_ask_partnum(cxt
, &n
, FALSE
);
392 rc
= fdisk_gpt_partition_set_uuid(cxt
, n
);
395 rc
= fdisk_gpt_partition_set_name(cxt
, n
);
402 struct fdisk_label
*fdisk_new_dos_label(struct fdisk_context
*cxt
) { return NULL
; }
403 struct fdisk_label
*fdisk_new_bsd_label(struct fdisk_context
*cxt
) { return NULL
; }
404 struct fdisk_label
*fdisk_new_mac_label(struct fdisk_context
*cxt
) { return NULL
; }
405 struct fdisk_label
*fdisk_new_sgi_label(struct fdisk_context
*cxt
) { return NULL
; }
407 int main(int argc
, char *argv
[])
409 struct fdisk_context
*cxt
;
413 cxt
= fdisk_new_context();
415 if (argc
> idx
&& strcmp(argv
[idx
], "--expert") == 0) {
416 fdisk_context_enable_details(cxt
, 1);
419 fdisk_context_switch_label(cxt
, argc
> idx
? argv
[idx
] : "gpt");
421 print_fdisk_menu(cxt
);