diff options
author | Karel Zak | 2013-01-29 15:28:30 +0100 |
---|---|---|
committer | Karel Zak | 2013-03-11 13:00:55 +0100 |
commit | 4114da08d090dcf02d77c8e6ed343b40d9c8ff96 (patch) | |
tree | 30b43ccf140df7bd6584c7d17529a634441ae7e8 /libfdisk/src/ask.c | |
parent | lib/strutils: simplify strtosize(), return info about suffix (diff) | |
download | kernel-qcow2-util-linux-4114da08d090dcf02d77c8e6ed343b40d9c8ff96.tar.gz kernel-qcow2-util-linux-4114da08d090dcf02d77c8e6ed343b40d9c8ff96.tar.xz kernel-qcow2-util-linux-4114da08d090dcf02d77c8e6ed343b40d9c8ff96.zip |
libfdisk: extend "ask" API, add support for offsets
Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'libfdisk/src/ask.c')
-rw-r--r-- | libfdisk/src/ask.c | 206 |
1 files changed, 166 insertions, 40 deletions
diff --git a/libfdisk/src/ask.c b/libfdisk/src/ask.c index a5ee2f559..fc0214d26 100644 --- a/libfdisk/src/ask.c +++ b/libfdisk/src/ask.c @@ -1,42 +1,132 @@ +#include "strutils.h" + #include "fdiskP.h" +struct fdisk_ask *fdisk_new_ask(void) +{ + return calloc(1, sizeof(struct fdisk_ask)); +} + +void fdisk_reset_ask(struct fdisk_ask *ask) +{ + assert(ask); + free(ask->data.num.range); + free(ask->query); + memset(ask, 0, sizeof(*ask)); +} + +void fdisk_free_ask(struct fdisk_ask *ask) +{ + if (!ask) + return; + fdisk_reset_ask(ask); + free(ask); +} -const char *fdisk_ask_get_question(struct fdisk_ask *ask) +const char *fdisk_ask_get_query(struct fdisk_ask *ask) { assert(ask); return ask->query; } +int fdisk_ask_set_query(struct fdisk_ask *ask, const char *str) +{ + assert(ask); + return !strdup_to_struct_member(ask, query, str) ? -ENOMEM : 0; +} + int fdisk_ask_get_type(struct fdisk_ask *ask) { assert(ask); return ask->type; } +int fdisk_ask_set_type(struct fdisk_ask *ask, int type) +{ + assert(ask); + ask->type = type; + return 0; +} + +int fdisk_do_ask(struct fdisk_context *cxt, struct fdisk_ask *ask) +{ + int rc; + + assert(ask); + assert(cxt); + + DBG(ASK, dbgprint("asking for '%s'", ask->query)); + + if (!cxt->ask_cb) { + DBG(ASK, dbgprint("no ask callback specified!")); + return -EINVAL; + } + + rc = cxt->ask_cb(cxt, ask, cxt->ask_data); + + DBG(ASK, dbgprint("do_ask done [rc=%d]", rc)); + return rc; +} + + const char *fdisk_ask_number_get_range(struct fdisk_ask *ask) { assert(ask); return ask->data.num.range; } + +int fdisk_ask_number_set_range(struct fdisk_ask *ask, const char *range) +{ + assert(ask); + return !strdup_to_struct_member(ask, data.num.range, range) ? -ENOMEM : 0; +} + uint64_t fdisk_ask_number_get_default(struct fdisk_ask *ask) { assert(ask); return ask->data.num.dfl; } +int fdisk_ask_number_set_default(struct fdisk_ask *ask, uint64_t dflt) +{ + assert(ask); + ask->data.num.dfl = dflt; + return 0; +} + uint64_t fdisk_ask_number_get_low(struct fdisk_ask *ask) { assert(ask); return ask->data.num.low; } +int fdisk_ask_number_set_low(struct fdisk_ask *ask, uint64_t low) +{ + assert(ask); + ask->data.num.low = low; + return 0; +} + uint64_t fdisk_ask_number_get_high(struct fdisk_ask *ask) { assert(ask); return ask->data.num.hig; } +int fdisk_ask_number_set_high(struct fdisk_ask *ask, uint64_t high) +{ + assert(ask); + ask->data.num.hig = high; + return 0; +} + +uint64_t fdisk_ask_number_get_result(struct fdisk_ask *ask) +{ + assert(ask); + return ask->data.num.result; +} + int fdisk_ask_number_set_result(struct fdisk_ask *ask, uint64_t result) { assert(ask); @@ -44,6 +134,46 @@ int fdisk_ask_number_set_result(struct fdisk_ask *ask, uint64_t result) return 0; } +uint64_t fdisk_ask_number_get_base(struct fdisk_ask *ask) +{ + assert(ask); + return ask->data.num.base; +} + +int fdisk_ask_number_set_base(struct fdisk_ask *ask, uint64_t base) +{ + assert(ask); + ask->data.num.base = base; + return 0; +} + +/* if numbers are not in bytes, then specify number of bytes per the unit */ +uint64_t fdisk_ask_number_get_unit(struct fdisk_ask *ask) +{ + assert(ask); + return ask->data.num.unit; +} + +int fdisk_ask_number_set_unit(struct fdisk_ask *ask, uint64_t unit) +{ + assert(ask); + ask->data.num.unit = unit; + return 0; +} + +int fdisk_ask_number_is_relative(struct fdisk_ask *ask) +{ + assert(ask); + return ask->data.num.relative; +} + +int fdisk_ask_number_set_relative(struct fdisk_ask *ask, int relative) +{ + assert(ask); + ask->data.num.relative = relative ? 1 : 0; + return 0; +} + /* * Generates string with list ranges (e.g. 1,2,5-8) for the 'cur' */ @@ -97,39 +227,41 @@ static char *mk_string_list(char *ptr, size_t *len, size_t *begin, return ptr; } +/* returns: 1=0 on success, < 0 on error, 1 if no free partition */ int fdisk_ask_partnum(struct fdisk_context *cxt, size_t *partnum, int wantnew) { - int rc; + int rc = 0; char range[BUFSIZ], *ptr = range; size_t i, len = sizeof(range), begin = 0, run = 0; - struct fdisk_ask ask = { .name = "partnum" }; - __typeof__(ask.data.num) *num = &ask.data.num; + struct fdisk_ask *ask = NULL; + __typeof__(ask->data.num) *num; assert(cxt); assert(cxt->label); assert(partnum); - if (!cxt->ask_cb) { - DBG(ASK, dbgprint("no ask callback specified!")); - return -EINVAL; /* ask callback undefined */ - } - DBG(ASK, dbgprint("%s: asking for %s partition number (max: %zd)", - cxt->label->name, - wantnew ? "new" : "used", + cxt->label->name, wantnew ? "new" : "used", cxt->label->nparts_max)); + ask = fdisk_new_ask(); + if (!ask) + return -ENOMEM; + + num = &ask->data.num; + for (i = 0; i < cxt->label->nparts_max; i++) { int status = 0; rc = fdisk_partition_get_status(cxt, i, &status); if (rc) - return rc; - + break; if (wantnew && !(status & FDISK_PARTSTAT_USED)) { ptr = mk_string_list(ptr, &len, &begin, &run, i); - if (!ptr) - return -EINVAL; + if (!ptr) { + rc = -EINVAL; + break; + } if (!num->low) num->dfl = num->low = i + 1; num->hig = i + 1; @@ -141,20 +273,28 @@ int fdisk_ask_partnum(struct fdisk_context *cxt, size_t *partnum, int wantnew) } } - if (wantnew && num->low == 0 && num->hig == 0) { + if (!rc) { + mk_string_list(ptr, &len, &begin, &run, -1); /* terminate the list */ + rc = fdisk_ask_number_set_range(ask, range); + } + if (!rc && wantnew && num->low == 0 && num->hig == 0) { DBG(ASK, dbgprint("no free partition")); - return 1; + rc = 1; + } + if (!rc) + rc = fdisk_ask_set_query(ask, _("Partition number")); + if (!rc) + rc = fdisk_ask_set_type(ask, FDISK_ASKTYPE_NUMBER); + if (!rc) + rc = fdisk_do_ask(cxt, ask); + if (!rc) { + *partnum = fdisk_ask_number_get_result(ask); + if (*partnum) + *partnum -= 1; } - mk_string_list(ptr, &len, &begin, &run, -1); /* terminate the list */ - num->range = range; - - ask.query = _("Partition number"); - ask.type = FDISK_ASKTYPE_NUMBER; - - rc = cxt->ask_cb(cxt, &ask, cxt->ask_data); - *partnum = num->result ? num->result - 1 : 0; - DBG(ASK, dbgprint("result: %zd [rc=%d]\n", num->result, rc)); + fdisk_free_ask(ask); + DBG(ASK, dbgprint("result: %zd [rc=%d]\n", *partnum, rc)); return rc; } @@ -167,20 +307,6 @@ struct fdisk_label *fdisk_new_mac_label(struct fdisk_context *cxt) { return NULL struct fdisk_label *fdisk_new_sgi_label(struct fdisk_context *cxt) { return NULL; } struct fdisk_label *fdisk_new_sun_label(struct fdisk_context *cxt) { return NULL; } -unsigned int read_int_with_suffix(struct fdisk_context *cxt, - unsigned int low, unsigned int dflt, unsigned int high, - unsigned int base, char *mesg, int *is_suffix_used) -{ - return 0; -} - -unsigned int read_int(struct fdisk_context *cxt, - unsigned int low, unsigned int dflt, - unsigned int high, unsigned int base, char *mesg) -{ - return 0; -} - int test_ranges(struct fdisk_test *ts, int argc, char *argv[]) { /* 1 - 3, 6, 8, 9, 11 13 */ |