summaryrefslogtreecommitdiffstats
path: root/libfdisk/src/ask.c
diff options
context:
space:
mode:
authorKarel Zak2013-01-29 15:28:30 +0100
committerKarel Zak2013-03-11 13:00:55 +0100
commit4114da08d090dcf02d77c8e6ed343b40d9c8ff96 (patch)
tree30b43ccf140df7bd6584c7d17529a634441ae7e8 /libfdisk/src/ask.c
parentlib/strutils: simplify strtosize(), return info about suffix (diff)
downloadkernel-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.c206
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 */