fdisk: add callback for ask-numbers API
Signed-off-by: Karel Zak <kzak@redhat.com>
This commit is contained in:
parent
7845ca8dc2
commit
416c43a9a5
|
@ -7,6 +7,7 @@ fdisk_SOURCES = \
|
|||
fdisks/dos_part_types.h \
|
||||
fdisks/fdisk.c \
|
||||
fdisks/fdisk.h \
|
||||
fdisks/fdisk-ask.c \
|
||||
fdisks/fdiskaixlabel.c \
|
||||
fdisks/fdiskaixlabel.h \
|
||||
fdisks/fdiskbsdlabel.c \
|
||||
|
|
|
@ -0,0 +1,111 @@
|
|||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "c.h"
|
||||
#include "strutils.h"
|
||||
#include "rpmatch.h"
|
||||
|
||||
#include "fdisk.h"
|
||||
|
||||
static int get_user_reply(struct fdisk_context *cxt, char *prompt,
|
||||
char *buf, size_t bufsz)
|
||||
{
|
||||
char *p;
|
||||
size_t sz;
|
||||
|
||||
do {
|
||||
fputs(prompt, stdout);
|
||||
fflush(stdout);
|
||||
|
||||
if (!fgets(buf, bufsz, stdin)) {
|
||||
if (fdisk_label_is_changed(cxt->label)) {
|
||||
fprintf(stderr, _("Do you really want to quit? "));
|
||||
|
||||
if (fgets(buf, bufsz, stdin) && !rpmatch(buf))
|
||||
continue;
|
||||
}
|
||||
fdisk_free_context(cxt);
|
||||
exit(EXIT_FAILURE);
|
||||
} else
|
||||
break;
|
||||
} while (1);
|
||||
|
||||
for (p = buf; *p && !isgraph(*p); p++); /* get first non-blank */
|
||||
|
||||
if (p > buf)
|
||||
memmove(buf, p, p - buf); /* remove blank space */
|
||||
sz = strlen(buf);
|
||||
if (sz && *(buf + sz - 1) == '\n')
|
||||
*(buf + sz - 1) = '\0';
|
||||
|
||||
DBG(ASK, dbgprint("user's reply: >>>%s<<<", buf));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ask_number(struct fdisk_context *cxt,
|
||||
struct fdisk_ask *ask,
|
||||
char *buf, size_t bufsz)
|
||||
{
|
||||
char prompt[128] = { '\0' };
|
||||
const char *q = fdisk_ask_get_question(ask);
|
||||
const char *range = fdisk_ask_number_get_range(ask);
|
||||
|
||||
uint64_t dfl = fdisk_ask_number_get_default(ask),
|
||||
low = fdisk_ask_number_get_low(ask),
|
||||
hig = fdisk_ask_number_get_high(ask);
|
||||
|
||||
assert(q);
|
||||
|
||||
DBG(ASK, dbgprint("asking for number ['%s', <%jd,%jd>, default: %jd, range: %s]",
|
||||
q, low, hig, dfl, range));
|
||||
|
||||
if (range && dfl)
|
||||
snprintf(prompt, sizeof(prompt), _("%s (%s, default %jd): "), q, range, dfl);
|
||||
else if (dfl)
|
||||
snprintf(prompt, sizeof(prompt), _("%s (%jd-%jd, default %jd): "), q, low, hig, dfl);
|
||||
else
|
||||
snprintf(prompt, sizeof(prompt), _("%s (%jd-%jd): "), q, low, hig);
|
||||
|
||||
do {
|
||||
uint64_t num;
|
||||
int rc = get_user_reply(cxt, prompt, buf, bufsz);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
if (!*buf && dfl)
|
||||
return fdisk_ask_number_set_result(ask, dfl);
|
||||
else if (isdigit_string(buf)) {
|
||||
char *end;
|
||||
errno = 0;
|
||||
num = strtoumax(buf, &end, 10);
|
||||
if (errno || buf == end || (end && *end))
|
||||
continue;
|
||||
if (num >= low && num <= hig)
|
||||
return fdisk_ask_number_set_result(ask, num);
|
||||
printf(_("Value out of range.\n"));
|
||||
}
|
||||
} while (1);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int ask_callback(struct fdisk_context *cxt, struct fdisk_ask *ask,
|
||||
void *data __attribute__((__unused__)))
|
||||
{
|
||||
char buf[BUFSIZ];
|
||||
|
||||
assert(cxt);
|
||||
assert(ask);
|
||||
|
||||
switch(fdisk_ask_get_type(ask)) {
|
||||
case FDISK_ASKTYPE_NUMBER:
|
||||
return ask_number(cxt, ask, buf, sizeof(buf));
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
|
@ -752,19 +752,13 @@ void print_partition_size(struct fdisk_context *cxt,
|
|||
|
||||
static void new_partition(struct fdisk_context *cxt)
|
||||
{
|
||||
int partnum = 0;
|
||||
|
||||
assert(cxt);
|
||||
assert(cxt->label);
|
||||
|
||||
if (warn_geometry(cxt))
|
||||
return;
|
||||
|
||||
if (!(cxt->label->flags & FDISK_LABEL_FL_ADDPART_NOPARTNO))
|
||||
partnum = get_partition_dflt(cxt, 0, cxt->label->nparts_max,
|
||||
cxt->label->nparts_cur + 1);
|
||||
|
||||
fdisk_add_partition(cxt, partnum, NULL);
|
||||
fdisk_add_partition(cxt, NULL);
|
||||
}
|
||||
|
||||
static void write_table(struct fdisk_context *cxt)
|
||||
|
@ -1197,6 +1191,8 @@ int main(int argc, char **argv)
|
|||
if (!cxt)
|
||||
err(EXIT_FAILURE, _("failed to allocate libfdisk context"));
|
||||
|
||||
fdisk_context_set_ask(cxt, ask_callback, NULL);
|
||||
|
||||
while ((c = getopt(argc, argv, "b:c::C:hH:lsS:u::vV")) != -1) {
|
||||
switch (c) {
|
||||
case 'b':
|
||||
|
|
|
@ -60,6 +60,10 @@ enum failure {
|
|||
unable_to_write
|
||||
};
|
||||
|
||||
|
||||
extern int ask_callback(struct fdisk_context *cxt, struct fdisk_ask *ask,
|
||||
void *data __attribute__((__unused__)));
|
||||
|
||||
/* prototypes for fdisk.c */
|
||||
extern char *line_ptr;
|
||||
extern unsigned int display_in_cyl_units, units_per_sector;
|
||||
|
|
|
@ -28,6 +28,8 @@ extern double strtod_or_err(const char *str, const char *errmesg);
|
|||
extern long strtol_or_err(const char *str, const char *errmesg);
|
||||
extern unsigned long strtoul_or_err(const char *str, const char *errmesg);
|
||||
|
||||
extern int isdigit_string(const char *str);
|
||||
|
||||
#ifndef HAVE_MEMPCPY
|
||||
extern void *mempcpy(void *restrict dest, const void *restrict src, size_t n);
|
||||
#endif
|
||||
|
|
|
@ -132,6 +132,16 @@ err:
|
|||
return -1;
|
||||
}
|
||||
|
||||
int isdigit_string(const char *str)
|
||||
{
|
||||
const char *p;
|
||||
|
||||
for (p = str; p && *p && isdigit((unsigned char) *p); p++);
|
||||
|
||||
return p && p > str && !*p;
|
||||
}
|
||||
|
||||
|
||||
#ifndef HAVE_MEMPCPY
|
||||
void *mempcpy(void *restrict dest, const void *restrict src, size_t n)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue