]>
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_gpt
= {
116 .callback
= gpt_menu_cb
,
117 .label
= FDISK_DISKLABEL_GPT
,
119 MENU_XSEP(N_("GPT")),
120 MENU_XENT('u', N_("change partition UUID")),
121 MENU_XENT('n', N_("change partition name")),
126 struct menu menu_sun
= {
127 /* .callback = sun_menu_cb, */
128 .label
= FDISK_DISKLABEL_SUN
,
130 MENU_BSEP(N_("Sun")),
131 MENU_ENT('a', N_("toggle a read only flag")),
132 MENU_ENT('c', N_("toggle the mountable flag")),
134 MENU_XENT('a', N_("change number of alternate cylinders")),
135 MENU_XENT('c', N_("change number of cylinders")),
136 MENU_XENT('e', N_("change number of extra sectors per cylinder")),
137 MENU_XENT('h', N_("change number of heads")),
138 MENU_XENT('i', N_("change interleave factor")),
139 MENU_XENT('o', N_("change rotation speed (rpm)")),
140 MENU_XENT('s', N_("change number of sectors/track")),
141 MENU_XENT('y', N_("change number of physical cylinders")),
146 struct menu menu_sgi
= {
147 /* .callback = sgi_menu_cb, */
148 .label
= FDISK_DISKLABEL_SGI
,
151 MENU_ENT('a', N_("select bootable partition")),
152 MENU_ENT('b', N_("edit bootfile entry")),
153 MENU_ENT('c', N_("select sgi swap partition")),
158 struct menu menu_dos
= {
159 /* .callback = dos_menu_cb, */
160 .label
= FDISK_DISKLABEL_DOS
,
162 MENU_BSEP(N_("DOS (MBR)")),
163 MENU_ENT('a', N_("toggle a bootable flag")),
164 MENU_ENT('b', N_("edit nested BSD disklabel")),
165 MENU_ENT('c', N_("toggle the dos compatibility flag")),
167 MENU_XENT('b', N_("move beginning of data in a partition")),
168 MENU_XENT('c', N_("change number of cylinders")), MENU_XENT('e', N_("list extended partitions")),
169 MENU_XENT('f', N_("fix partition order")),
170 MENU_XENT('h', N_("change number of heads")),
171 MENU_XENT('i', N_("change the disk identifier")),
172 MENU_XENT('s', N_("change number of sectors/track")),
177 struct menu menu_bsd
= {
178 /* .callback = bsd_menu_cb, */
179 .label
= FDISK_DISKLABEL_OSF
,
182 MENU_ENT('e', N_("edit drive data")),
183 MENU_ENT('i', N_("install bootstrap")),
184 MENU_ENT('s', N_("show complete disklabel")),
185 MENU_ENT('w', N_("write disklabel to disk")),
186 #if !defined (__alpha__)
187 MENU_ENT('x', N_("link BSD partition to non-BSD partition")),
193 static const struct menu
*menus
[] = {
203 static const struct menu_entry
*next_menu_entry(
204 struct fdisk_context
*cxt
,
205 struct menu_context
*mc
)
207 while (mc
->menu_idx
< ARRAY_SIZE(menus
)) {
208 const struct menu
*m
= menus
[mc
->menu_idx
];
209 const struct menu_entry
*e
= &(m
->entries
[mc
->entry_idx
]);
211 /* move to the next submenu if there is no more entries */
212 if (e
->title
== NULL
||
213 (m
->label
&& cxt
->label
&& !(m
->label
& cxt
->label
->id
))) {
219 /* is the entry excluded for the current label? */
220 if ((e
->exclude
&& cxt
->label
&&
221 e
->exclude
& cxt
->label
->id
) ||
222 /* exclude non-expert entries in expect mode */
223 (e
->expert
== 0 && fdisk_context_display_details(cxt
)) ||
224 /* exclude non-normal entries in normal mode */
225 (e
->normal
== 0 && !fdisk_context_display_details(cxt
))) {
237 /* returns @menu and menu entry for then @key */
238 static const struct menu_entry
*get_fdisk_menu_entry(
239 struct fdisk_context
*cxt
,
241 const struct menu
**menu
)
243 struct menu_context mc
= MENU_CXT_EMPTY
;
244 const struct menu_entry
*e
;
246 while ((e
= next_menu_entry(cxt
, &mc
))) {
247 if (IS_MENU_SEP(e
) || e
->key
!= key
)
251 *menu
= menus
[mc
.menu_idx
];
258 static int menu_detect_collisions(struct fdisk_context
*cxt
)
260 struct menu_context mc
= MENU_CXT_EMPTY
;
261 const struct menu_entry
*e
, *r
;
263 while ((e
= next_menu_entry(cxt
, &mc
))) {
267 r
= get_fdisk_menu_entry(cxt
, e
->key
, NULL
);
269 DBG(FRONTEND
, dbgprint("warning: not found "
270 "entry for %c", e
->key
));
274 DBG(FRONTEND
, dbgprint("warning: duplicate key '%c'",
276 DBG(FRONTEND
, dbgprint(" %s", e
->title
));
277 DBG(FRONTEND
, dbgprint(" %s", r
->title
));
285 int print_fdisk_menu(struct fdisk_context
*cxt
)
287 struct menu_context mc
= MENU_CXT_EMPTY
;
288 const struct menu_entry
*e
;
290 ON_DBG(FRONTEND
, menu_detect_collisions(cxt
));
292 if (fdisk_context_display_details(cxt
))
293 printf(_("\nHelp (expert commands):\n"));
295 printf(_("\nHelp:\n"));
297 while ((e
= next_menu_entry(cxt
, &mc
))) {
299 continue; /* hidden entry */
301 printf("\n %s\n", _(e
->title
));
303 printf(" %c %s\n", e
->key
, _(e
->title
));
310 /* Asks for command, verify the key and perform the command or
311 * returns the command key if no callback for the command is
314 * Returns: <0 on error
315 * 0 on success (the command performed)
316 * >0 if no callback (then returns the key)
318 int process_fdisk_menu(struct fdisk_context
*cxt
)
320 const struct menu_entry
*ent
;
321 const struct menu
*menu
;
326 if (fdisk_context_display_details(cxt
))
327 prompt
= _("Expert command (m for help): ");
329 prompt
= _("Command (m for help): ");
332 rc
= get_user_reply(cxt
, prompt
, buf
, sizeof(buf
));
337 ent
= get_fdisk_menu_entry(cxt
, key
, &menu
);
339 fdisk_warnx(cxt
, _("%c: unknown command"), key
);
343 DBG(FRONTEND
, dbgprint("selected: key=%c, entry='%s'",
347 print_fdisk_menu(cxt
);
350 /* menu has implemented callback, use it */
351 } else if (menu
->callback
)
352 return menu
->callback(cxt
, menu
, ent
);
354 /* no callback, return the key */
359 * This is fdisk frontend for GPT specific libfdisk functions that
360 * are not expported by generic libfdisk API.
362 static int gpt_menu_cb(struct fdisk_context
*cxt
,
363 const struct menu
*menu
__attribute__((__unused__
)),
364 const struct menu_entry
*ent
)
371 assert(fdisk_is_disklabel(cxt
, GPT
));
373 DBG(FRONTEND
, dbgprint("enter GPT menu"));
375 rc
= fdisk_ask_partnum(cxt
, &n
, FALSE
);
381 rc
= fdisk_gpt_partition_set_uuid(cxt
, n
);
384 rc
= fdisk_gpt_partition_set_name(cxt
, n
);
392 struct fdisk_label
*fdisk_new_dos_label(struct fdisk_context
*cxt
) { return NULL
; }
393 struct fdisk_label
*fdisk_new_bsd_label(struct fdisk_context
*cxt
) { return NULL
; }
394 struct fdisk_label
*fdisk_new_mac_label(struct fdisk_context
*cxt
) { return NULL
; }
395 struct fdisk_label
*fdisk_new_sgi_label(struct fdisk_context
*cxt
) { return NULL
; }
397 int main(int argc
, char *argv
[])
399 struct fdisk_context
*cxt
;
403 cxt
= fdisk_new_context();
405 if (argc
> idx
&& strcmp(argv
[idx
], "--expert") == 0) {
406 fdisk_context_enable_details(cxt
, 1);
409 fdisk_context_switch_label(cxt
, argc
> idx
? argv
[idx
] : "gpt");
411 print_fdisk_menu(cxt
);