#include "fdiskP.h"
+static void fdisk_ask_menu_reset_items(struct fdisk_ask *ask);
+
+
struct fdisk_ask *fdisk_new_ask(void)
{
return calloc(1, sizeof(struct fdisk_ask));
assert(ask);
free(ask->query);
+ if (fdisk_is_ask(ask, MENU))
+ fdisk_ask_menu_reset_items(ask);
+
memset(ask, 0, sizeof(*ask));
}
return 0;
}
+/*
+ * menu
+ */
+int fdisk_ask_menu_set_default(struct fdisk_ask *ask, int dfl)
+{
+ assert(ask);
+ assert(fdisk_is_ask(ask, MENU));
+ ask->data.menu.dfl = dfl;
+ return 0;
+}
+
+int fdisk_ask_menu_get_default(struct fdisk_ask *ask)
+{
+ assert(ask);
+ assert(fdisk_is_ask(ask, MENU));
+ return ask->data.menu.dfl;
+}
+
+int fdisk_ask_menu_set_result(struct fdisk_ask *ask, int key)
+{
+ assert(ask);
+ assert(fdisk_is_ask(ask, MENU));
+ ask->data.menu.result = key;
+ DBG(ASK, dbgprint("menu result: %c\n", key));
+ return 0;
+
+}
+
+int fdisk_ask_menu_get_result(struct fdisk_ask *ask, int *key)
+{
+ assert(ask);
+ assert(fdisk_is_ask(ask, MENU));
+ if (key)
+ *key = ask->data.menu.result;
+ return 0;
+}
+
+/* returns: 0 = success, <0 = error, >0 = idx out-of-range */
+int fdisk_ask_menu_get_item(struct fdisk_ask *ask, size_t idx, int *key,
+ const char **name, const char **desc)
+{
+ size_t i;
+ struct ask_menuitem *mi;
+
+ assert(ask);
+ assert(fdisk_is_ask(ask, MENU));
+
+ for (i = 0, mi = ask->data.menu.first; mi; mi = mi->next, i++) {
+ if (i == idx)
+ break;
+ }
+
+ if (!mi)
+ return 1; /* no more items */
+ if (key)
+ *key = mi->key;
+ if (name)
+ *name = mi->name;
+ if (desc)
+ *desc = mi->desc;
+ return 0;
+}
+
+static void fdisk_ask_menu_reset_items(struct fdisk_ask *ask)
+{
+ struct ask_menuitem *mi;
+
+ assert(ask);
+ assert(fdisk_is_ask(ask, MENU));
+
+ for (mi = ask->data.menu.first; mi; ) {
+ struct ask_menuitem *next = mi->next;
+ free(mi);
+ mi = next;
+ }
+}
+
+size_t fdisk_ask_menu_get_nitems(struct fdisk_ask *ask)
+{
+ struct ask_menuitem *mi;
+ size_t n;
+
+ assert(ask);
+ assert(fdisk_is_ask(ask, MENU));
+
+ for (n = 0, mi = ask->data.menu.first; mi; mi = mi->next, n++);
+
+ return n;
+}
+
+int fdisk_ask_menu_add_item(struct fdisk_ask *ask, int key,
+ const char *name, const char *desc)
+{
+ struct ask_menuitem *mi;
+
+ assert(ask);
+ assert(fdisk_is_ask(ask, MENU));
+
+ mi = calloc(1, sizeof(*mi));
+ if (!mi)
+ return -ENOMEM;
+ mi->key = key;
+ mi->name = name;
+ mi->desc = desc;
+
+ if (!ask->data.menu.first)
+ ask->data.menu.first = mi;
+ else {
+ struct ask_menuitem *last = ask->data.menu.first;
+
+ while (last->next)
+ last = last->next;
+ last->next = mi;
+ }
+
+ DBG(ASK, dbgprint("new menu item: %c, \"%s\" (%s)\n", mi->key, mi->name, mi->desc));
+ return 0;
+}
+
+
+/*
+ * print-like
+ */
+
#define is_print_ask(a) (fdisk_is_ask(a, WARN) || fdisk_is_ask(a, WARNX) || fdisk_is_ask(a, INFO))
int fdisk_ask_print_get_errno(struct fdisk_ask *ask)
*start = dflt;
else if (pa && pa->start) {
+ DBG(LABEL, dbgprint("DOS: start: wanted=%ju, low=%ju, limit=%ju",
+ (uintmax_t) pa->start, (uintmax_t) low, (uintmax_t) limit));
*start = pa->start;
- if (*start < low || *start > limit)
+ if (*start < low || *start > limit) {
+ fdisk_warnx(cxt, _("Start sector out of range."));
return -ERANGE;
+ }
} else {
/* ask user by dialog */
struct fdisk_ask *ask = fdisk_new_ask();
DBG(LABEL, dbgprint("DOS: adding partition %zu", n));
- sys = pa ? pa->type->type : MBR_LINUX_DATA_PARTITION;
+ sys = pa && pa->type ? pa->type->type : MBR_LINUX_DATA_PARTITION;
if (is_used_partition(p)) {
fdisk_warnx(cxt, _("Partition %zu is already defined. "
stop = limit;
else if (pa && pa->size) {
stop = start + pa->size;
- if (stop > limit)
- return -ERANGE;
isrel = 1;
} else {
/* ask user by dialog */
assert(cxt->label);
assert(fdisk_is_disklabel(cxt, DOS));
+ /* TODO: use pa->type */
+
for (i = 0; i < 4; i++) {
struct dos_partition *p = self_partition(cxt, i);
free_primary += !is_used_partition(p);
if (j >= 0)
rc = add_partition(cxt, j, pa);
} else {
- char *buf;
- char c, prompt[BUFSIZ];
- int dflt;
-
- dflt = (free_primary == 1 && !l->ext_offset) ? 'e' : 'p';
-
- snprintf(prompt, sizeof(prompt),
- _("Partition type:\n"
- " p primary (%zu primary, %d extended, %zu free)\n"
- "%s\n"
- "Select (default %c)"),
- 4 - (l->ext_offset ? 1 : 0) - free_primary,
- l->ext_offset ? 1 : 0, free_primary,
- l->ext_offset ? _(" l logical (numbered from 5)") : _(" e extended"),
- dflt);
-
- rc = fdisk_ask_string(cxt, prompt, &buf);
+ char hint[BUFSIZ];
+ struct fdisk_ask *ask;
+ int c;
+
+ ask = fdisk_new_ask();
+ if (!ask)
+ return -ENOMEM;
+ fdisk_ask_set_type(ask, FDISK_ASKTYPE_MENU);
+ fdisk_ask_set_query(ask, _("Partition type"));
+ fdisk_ask_menu_set_default(ask, free_primary == 1
+ && !l->ext_offset ? 'e' : 'p');
+ snprintf(hint, sizeof(hint),
+ _("%zu primary, %d extended, %zu free"),
+ 4 - (l->ext_offset ? 1 : 0) - free_primary,
+ l->ext_offset ? 1 : 0,
+ free_primary);
+
+ fdisk_ask_menu_add_item(ask, 'p', _("primary"), hint);
+ if (!l->ext_offset)
+ fdisk_ask_menu_add_item(ask, 'e', _("extended"), _("container for logical partitions"));
+ else
+ fdisk_ask_menu_add_item(ask, 'l', _("logical"), _("numbered from 5"));
+
+ rc = fdisk_do_ask(cxt, ask);
if (rc)
return rc;
- if (!buf[0]) {
- c = dflt;
- fdisk_info(cxt, _("Using default response %c."), c);
- } else
- c = tolower(buf[0]);
- free(buf);
+ fdisk_ask_menu_get_result(ask, &c);
+ fdisk_free_ask(ask);
if (c == 'p') {
int j = get_partition_unused_primary(cxt, pa);
extern struct fdisk_label *fdisk_new_sun_label(struct fdisk_context *cxt);
+struct ask_menuitem {
+ char key;
+ const char *name;
+ const char *desc;
+
+ struct ask_menuitem *next;
+};
+
/* fdisk dialog -- note that nothing from this stuff will be directly exported,
* we will have get/set() function for everything.
*/
struct ask_string {
char *result; /* allocated */
} str;
+ /* FDISK_ASKTYPE_MENU */
+ struct ask_menu {
+ int dfl; /* default meni item */
+ int result;
+ struct ask_menuitem *first;
+ } menu;
} data;
};
/* alignment */
unsigned long grain; /* alignment unit */
sector_t first_lba; /* recommended begin of the first partition */
+ sector_t last_lba; /* recomennded end of last partition */
/* geometry */
sector_t total_sectors; /* in logical sectors */
FDISK_ASKTYPE_WARNX,
FDISK_ASKTYPE_INFO,
FDISK_ASKTYPE_YESNO,
- FDISK_ASKTYPE_STRING
+ FDISK_ASKTYPE_STRING,
+ FDISK_ASKTYPE_MENU
};
/* extra flags for info massages (see fdisk_sinfo() */
struct fdisk_context *cxt,
size_t *n);
+extern int fdisk_partition_partno_follow_default(struct fdisk_partition *pa, int enable);
+extern int fdisk_partition_start_follow_default(struct fdisk_partition *pa, int enable);
+extern int fdisk_partition_end_follow_default(struct fdisk_partition *pa, int enable);
+
/* table.c */
extern struct fdisk_table *fdisk_new_table(void);
extern int fdisk_reset_table(struct fdisk_table *tb);
extern const char *fdisk_ask_print_get_mesg(struct fdisk_ask *ask);
extern int fdisk_ask_print_set_mesg(struct fdisk_ask *ask, const char *mesg);
+
+extern size_t fdisk_ask_menu_get_nitems(struct fdisk_ask *ask);
+extern int fdisk_ask_menu_set_default(struct fdisk_ask *ask, int dfl);
+extern int fdisk_ask_menu_get_default(struct fdisk_ask *ask);
+extern int fdisk_ask_menu_set_result(struct fdisk_ask *ask, int key);
+extern int fdisk_ask_menu_get_result(struct fdisk_ask *ask, int *key);
+extern int fdisk_ask_menu_get_item(struct fdisk_ask *ask, size_t idx, int *key,
+ const char **name, const char **desc);
+extern int fdisk_ask_menu_add_item(struct fdisk_ask *ask, int key,
+ const char *name, const char *desc);
+
+
#ifdef __cplusplus
}
#endif