diff options
author | Karel Zak | 2014-01-29 14:15:30 +0100 |
---|---|---|
committer | Karel Zak | 2014-03-11 11:35:13 +0100 |
commit | 20f878fee3ff40d0678e3cddfda06788c5ea87c9 (patch) | |
tree | dc65fe2c5e30e2675e96c13e96e98057f4e67237 /libfdisk | |
parent | lib/mbalign: add mbs_safe_width() from tt.c (diff) | |
download | kernel-qcow2-util-linux-20f878fee3ff40d0678e3cddfda06788c5ea87c9.tar.gz kernel-qcow2-util-linux-20f878fee3ff40d0678e3cddfda06788c5ea87c9.tar.xz kernel-qcow2-util-linux-20f878fee3ff40d0678e3cddfda06788c5ea87c9.zip |
libfdisk: add ASKTYPE_MENU and context last_lba
Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'libfdisk')
-rw-r--r-- | libfdisk/src/ask.c | 130 | ||||
-rw-r--r-- | libfdisk/src/dos.c | 61 | ||||
-rw-r--r-- | libfdisk/src/fdiskP.h | 15 | ||||
-rw-r--r-- | libfdisk/src/libfdisk.h | 19 |
4 files changed, 197 insertions, 28 deletions
diff --git a/libfdisk/src/ask.c b/libfdisk/src/ask.c index 23e6263c6..8647817af 100644 --- a/libfdisk/src/ask.c +++ b/libfdisk/src/ask.c @@ -3,6 +3,9 @@ #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)); @@ -13,6 +16,9 @@ void fdisk_reset_ask(struct fdisk_ask *ask) assert(ask); free(ask->query); + if (fdisk_is_ask(ask, MENU)) + fdisk_ask_menu_reset_items(ask); + memset(ask, 0, sizeof(*ask)); } @@ -490,6 +496,130 @@ int fdisk_ask_yesno_set_result(struct fdisk_ask *ask, uint64_t result) 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) diff --git a/libfdisk/src/dos.c b/libfdisk/src/dos.c index 1beeb6573..01e203268 100644 --- a/libfdisk/src/dos.c +++ b/libfdisk/src/dos.c @@ -826,9 +826,13 @@ static int get_start_from_user( struct fdisk_context *cxt, *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(); @@ -875,7 +879,7 @@ static int add_partition(struct fdisk_context *cxt, size_t n, 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. " @@ -984,8 +988,6 @@ static int add_partition(struct fdisk_context *cxt, size_t n, stop = limit; else if (pa && pa->size) { stop = start + pa->size; - if (stop > limit) - return -ERANGE; isrel = 1; } else { /* ask user by dialog */ @@ -1296,6 +1298,8 @@ static int dos_add_partition(struct fdisk_context *cxt, 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); @@ -1327,31 +1331,34 @@ static int dos_add_partition(struct fdisk_context *cxt, 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); diff --git a/libfdisk/src/fdiskP.h b/libfdisk/src/fdiskP.h index 1db19b648..eb8b90bc9 100644 --- a/libfdisk/src/fdiskP.h +++ b/libfdisk/src/fdiskP.h @@ -322,6 +322,14 @@ extern struct fdisk_label *fdisk_new_sgi_label(struct fdisk_context *cxt); 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. */ @@ -356,6 +364,12 @@ struct fdisk_ask { 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; }; @@ -380,6 +394,7 @@ struct fdisk_context { /* 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 */ diff --git a/libfdisk/src/libfdisk.h b/libfdisk/src/libfdisk.h index 8a9cc926e..fe1d290aa 100644 --- a/libfdisk/src/libfdisk.h +++ b/libfdisk/src/libfdisk.h @@ -55,7 +55,8 @@ enum { 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() */ @@ -209,6 +210,10 @@ extern int fdisk_partition_next_partno(struct fdisk_partition *pa, 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); @@ -374,6 +379,18 @@ extern int fdisk_ask_print_set_errno(struct fdisk_ask *ask, int errnum); 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 |