From: Jeremy Kerr Date: Wed, 18 Dec 2013 05:05:01 +0000 (+0800) Subject: ui/ncurses/nc-widgets: Add initial textbox validation functions X-Git-Tag: v1.0.0~281 X-Git-Url: http://git.ozlabs.org/?p=petitboot;a=commitdiff_plain;h=90cc2a11507462e9c40f2494165741561729bdfb ui/ncurses/nc-widgets: Add initial textbox validation functions We'd like to do some validation of the system configuration parameters, so add a few validation types to the widget code. We currently need integer, ipv4 address and multiple ipv4 address types. These are implemented as small wrappers around the ncurses form validator code. Signed-off-by: Jeremy Kerr --- diff --git a/ui/ncurses/nc-widgets.c b/ui/ncurses/nc-widgets.c index 60f9100..2829040 100644 --- a/ui/ncurses/nc-widgets.c +++ b/ui/ncurses/nc-widgets.c @@ -77,6 +77,9 @@ struct nc_widgetset { void (*widget_focus)(struct nc_widget *, void *); void *widget_focus_arg; FIELD *cur_field; + + /* custom validators */ + FIELDTYPE *ipv4_multi_type; }; struct nc_widget { @@ -105,6 +108,7 @@ struct nc_widget_checkbox { }; struct nc_widget_textbox { + struct nc_widgetset *set; struct nc_widget widget; }; @@ -328,6 +332,7 @@ struct nc_widget_textbox *widget_new_textbox(struct nc_widgetset *set, FIELD *f; textbox = talloc_zero(set, struct nc_widget_textbox); + textbox->set = set; textbox->widget.height = 1; textbox->widget.width = len; textbox->widget.x = x; @@ -348,6 +353,62 @@ struct nc_widget_textbox *widget_new_textbox(struct nc_widgetset *set, return textbox; } +void widget_textbox_set_validator_integer(struct nc_widget_textbox *textbox, + long min, long max) +{ + set_field_type(textbox->widget.field, TYPE_INTEGER, 1, min, max); +} + +void widget_textbox_set_validator_ipv4(struct nc_widget_textbox *textbox) +{ + set_field_type(textbox->widget.field, TYPE_IPV4); +} + +static bool check_ipv4_multi_char(int c, + const void *arg __attribute__((unused))) +{ + return isdigit(c) || c == '.' || c == ' '; +} + +static bool check_ipv4_multi_field(FIELD *field, + const void *arg __attribute__((unused))) +{ + char *buf = field_buffer(field, 0); + unsigned int ip[4]; + int n, len; + + while (*buf != '\0') { + n = sscanf(buf, "%u.%u.%u.%u%n", + &ip[0], &ip[1], &ip[2], &ip[3], &len); + if (n != 4) + return false; + + if (ip[0] > 255 || ip[1] > 255 || ip[2] > 255 || ip[3] > 255) + return false; + + for (buf += len; *buf != '\0'; buf++) { + if (isspace(*buf)) + continue; + else if (isdigit(*buf)) + break; + else + return false; + } + } + + return true; +} + +void widget_textbox_set_validator_ipv4_multi(struct nc_widget_textbox *textbox) +{ + if (!textbox->set->ipv4_multi_type) { + textbox->set->ipv4_multi_type = new_fieldtype( + check_ipv4_multi_field, + check_ipv4_multi_char); + } + set_field_type(textbox->widget.field, textbox->set->ipv4_multi_type); +} + static void select_option_change(struct select_option *opt, bool selected) { const char *str; @@ -672,6 +733,8 @@ static int widgetset_destructor(void *ptr) { struct nc_widgetset *set = ptr; free_form(set->form); + if (set->ipv4_multi_type) + free_fieldtype(set->ipv4_multi_type); return 0; } diff --git a/ui/ncurses/nc-widgets.h b/ui/ncurses/nc-widgets.h index 47a57d9..32b6bae 100644 --- a/ui/ncurses/nc-widgets.h +++ b/ui/ncurses/nc-widgets.h @@ -35,6 +35,11 @@ struct nc_widget_button *widget_new_button(struct nc_widgetset *set, int y, int x, int size, const char *str, void (*click)(void *), void *arg); +void widget_textbox_set_validator_integer(struct nc_widget_textbox *textbox, + long min, long max); +void widget_textbox_set_validator_ipv4(struct nc_widget_textbox *textbox); +void widget_textbox_set_validator_ipv4_multi(struct nc_widget_textbox *textbox); + void widget_select_add_option(struct nc_widget_select *select, int value, const char *text, bool selected);