fdisk: add callback for ask-numbers API

Signed-off-by: Karel Zak <kzak@redhat.com>
This commit is contained in:
Karel Zak 2013-01-28 16:16:11 +01:00
parent 7845ca8dc2
commit 416c43a9a5
6 changed files with 131 additions and 7 deletions

View File

@ -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 \

111
fdisks/fdisk-ask.c Normal file
View File

@ -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;
}

View File

@ -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':

View File

@ -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;

View File

@ -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

View File

@ -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)
{