From a48b4d9948b6ffb5ca05d59ee8b04391ed24cd3b Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Thu, 20 Mar 2008 04:06:07 +0000 Subject: [PATCH] [Settings] Start revamping the configuration settings API. Add the concept of an abstract configuration setting, comprising a (DHCP) tag value and an associated byte sequence. Add the concept of a settings namespace. Add functions for extracting string, IPv4 address, and signed and unsigned integer values from configuration settings (analogous to dhcp_snprintf(), dhcp_ipv4_option(), etc.). Update functions for parsing and formatting named/typed options to work with new settings API. Update NVO commands and config UI to use new settings API. --- src/core/settings.c | 947 ++++++++++++++++++++++----------- src/hci/commands/config_cmd.c | 25 +- src/hci/commands/nvo_cmd.c | 50 +- src/hci/tui/settings_ui.c | 80 ++- src/include/gpxe/settings.h | 212 +++++--- src/include/gpxe/settings_ui.h | 4 +- 6 files changed, 812 insertions(+), 506 deletions(-) diff --git a/src/core/settings.c b/src/core/settings.c index 1cf711d2..a5c7f816 100644 --- a/src/core/settings.c +++ b/src/core/settings.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006 Michael Brown . + * Copyright (C) 2008 Michael Brown . * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -26,6 +26,7 @@ #include #include #include +#include #include /** @file @@ -34,48 +35,284 @@ * */ -/** Registered configuration setting types */ -static struct config_setting_type config_setting_types[0] - __table_start ( struct config_setting_type, config_setting_types ); -static struct config_setting_type config_setting_types_end[0] - __table_end ( struct config_setting_type, config_setting_types ); +/** Registered setting types */ +static struct setting_type setting_types[0] + __table_start ( struct setting_type, setting_types ); +static struct setting_type setting_types_end[0] + __table_end ( struct setting_type, setting_types ); -/** Registered configuration settings */ -static struct config_setting config_settings[0] - __table_start ( struct config_setting, config_settings ); -static struct config_setting config_settings_end[0] - __table_end ( struct config_setting, config_settings ); +/** Registered named settings */ +static struct named_setting named_settings[0] + __table_start ( struct named_setting, named_settings ); +static struct named_setting named_settings_end[0] + __table_end ( struct named_setting, named_settings ); -struct config_setting_type config_setting_type_hex __config_setting_type; +struct setting_type setting_type_hex __setting_type; /** - * Find configuration setting type + * Obtain printable version of a settings tag number + * + * @v tag Settings tag number + * @ret name String representation of the tag + */ +static inline char * setting_tag_name ( unsigned int tag ) { + static char name[8]; + + if ( DHCP_IS_ENCAP_OPT ( tag ) ) { + snprintf ( name, sizeof ( name ), "%d.%d", + DHCP_ENCAPSULATOR ( tag ), + DHCP_ENCAPSULATED ( tag ) ); + } else { + snprintf ( name, sizeof ( name ), "%d", tag ); + } + return name; +} + +/****************************************************************************** + * + * Registered settings blocks + * + ****************************************************************************** + */ + +/** List of all registered settings */ +static struct list_head all_settings = { + &interactive_settings.list, &interactive_settings.list +}; + +// Dummy routine just for testing +static int dummy_set ( struct settings *settings, unsigned int tag, + const void *data, size_t len ) { + DBGC ( settings, "Settings %p: set %s to:\n", + settings, setting_tag_name ( tag ) ); + DBGC_HD ( settings, data, len ); + return 0; +} + +// Dummy routine just for testing +static int dummy_get ( struct settings *settings, unsigned int tag, + void *data, size_t len ) { + unsigned int i; + + DBGC ( settings, "Settings %p: get %s\n", + settings, setting_tag_name ( tag ) ); + for ( i = 0 ; i < len ; i++ ) + *( ( ( uint8_t * ) data ) + i ) = i; + return ( len ? len : 8 ); +} + +struct settings_operations dummy_settings_operations = { + .set = dummy_set, + .get = dummy_get, +}; + +/** Interactively-edited settings */ +struct settings interactive_settings = { + .refcnt = NULL, + .name = "", + .list = { &all_settings, &all_settings }, + .op = &dummy_settings_operations, +}; + +/** + * Find named settings block * * @v name Name - * @ret type Configuration setting type, or NULL + * @ret settings Settings block, or NULL */ -static struct config_setting_type * -find_config_setting_type ( const char *name ) { - struct config_setting_type *type; +struct settings * find_settings ( const char *name ) { + struct settings *settings; - for ( type = config_setting_types ; type < config_setting_types_end ; - type++ ) { - if ( strcasecmp ( name, type->name ) == 0 ) - return type; + list_for_each_entry ( settings, &all_settings, list ) { + if ( strcasecmp ( name, settings->name ) == 0 ) + return settings; } return NULL; } +/****************************************************************************** + * + * Core settings routines + * + ****************************************************************************** + */ + /** - * Find configuration setting + * Get value of setting + * + * @v settings Settings block, or NULL to search all blocks + * @v tag Setting tag number + * @v data Buffer to fill with setting data + * @v len Length of buffer + * @ret len Length of setting data, or negative error + * + * The actual length of the setting will be returned even if + * the buffer was too small. + */ +int get_setting ( struct settings *settings, unsigned int tag, + void *data, size_t len ) { + int ret; + + if ( settings ) { + return settings->op->get ( settings, tag, data, len ); + } else { + list_for_each_entry ( settings, &all_settings, list ) { + if ( ( ret = settings->op->get ( settings, tag, + data, len ) ) >= 0 ) + return ret; + } + return -ENOENT; + } +} + +/** + * Get length of setting + * + * @v settings Settings block, or NULL to search all blocks + * @v tag Setting tag number + * @ret len Length of setting data, or negative error + * + * This function can also be used as an existence check for the + * setting. + */ +int get_setting_len ( struct settings *settings, unsigned int tag ) { + return get_setting ( settings, tag, NULL, 0 ); +} + +/** + * Get value of string setting + * + * @v settings Settings block, or NULL to search all blocks + * @v tag Setting tag number + * @v data Buffer to fill with setting string data + * @v len Length of buffer + * @ret len Length of string setting, or negative error + * + * The resulting string is guaranteed to be correctly NUL-terminated. + * The returned length will be the length of the underlying setting + * data. + */ +int get_string_setting ( struct settings *settings, unsigned int tag, + char *data, size_t len ) { + memset ( data, 0, len ); + return get_setting ( settings, tag, data, ( len - 1 ) ); +} + +/** + * Get value of IPv4 address setting + * + * @v settings Settings block, or NULL to search all blocks + * @v tag Setting tag number + * @v inp IPv4 address to fill in + * @ret len Length of setting, or negative error + */ +int get_ipv4_setting ( struct settings *settings, unsigned int tag, + struct in_addr *inp ) { + int len; + + len = get_setting ( settings, tag, inp, sizeof ( *inp ) ); + if ( len < 0 ) + return len; + if ( len != sizeof ( *inp ) ) + return -ERANGE; + return len; +} + +/** + * Get value of signed integer setting + * + * @v settings Settings block, or NULL to search all blocks + * @v tag Setting tag number + * @v value Integer value to fill in + * @ret len Length of setting, or negative error + */ +int get_int_setting ( struct settings *settings, unsigned int tag, + long *value ) { + union { + long value; + uint8_t u8[ sizeof ( long ) ]; + int8_t s8[ sizeof ( long ) ]; + } buf; + int len; + int i; + + buf.value = 0; + len = get_setting ( settings, tag, &buf, sizeof ( buf ) ); + if ( len < 0 ) + return len; + if ( len > ( int ) sizeof ( buf ) ) + return -ERANGE; + + *value = ( ( buf.s8[0] >= 0 ) ? 0 : -1L ); + for ( i = 0 ; i < len ; i++ ) { + *value = ( ( *value << 8 ) | buf.u8[i] ); + } + + return len; +} + +/** + * Get value of unsigned integer setting + * + * @v settings Settings block, or NULL to search all blocks + * @v tag Setting tag number + * @v value Integer value to fill in + * @ret len Length of setting, or negative error + */ +int get_uint_setting ( struct settings *settings, unsigned int tag, + unsigned long *value ) { + long svalue; + int len; + + len = get_int_setting ( settings, tag, &svalue ); + if ( len < 0 ) + return len; + + *value = ( svalue & ( -1UL >> ( sizeof ( long ) - len ) ) ); + + return len; +} + +/****************************************************************************** + * + * Named and typed setting routines + * + ****************************************************************************** + */ + +/** + * Set value of typed setting + * + * @v settings Settings block + * @v tag Setting tag number + * @v type Settings type + * @v value Formatted setting data, or NULL + * @ret rc Return status code + */ +int set_typed_setting ( struct settings *settings, + unsigned int tag, struct setting_type *type, + const char *value ) { + + /* NULL value implies deletion. Avoid imposing the burden of + * checking for NULL values on each typed setting's setf() + * method. + */ + if ( ! value ) + return delete_setting ( settings, tag ); + + return type->setf ( settings, tag, value ); +} + +/** + * Find named setting * * @v name Name - * @ret setting Configuration setting, or NULL + * @ret setting Named setting, or NULL */ -static struct config_setting * find_config_setting ( const char *name ) { - struct config_setting *setting; +static struct named_setting * find_named_setting ( const char *name ) { + struct named_setting *setting; - for ( setting = config_settings ; setting < config_settings_end ; + for ( setting = named_settings ; setting < named_settings_end ; setting++ ) { if ( strcasecmp ( name, setting->name ) == 0 ) return setting; @@ -84,352 +321,385 @@ static struct config_setting * find_config_setting ( const char *name ) { } /** - * Find or build configuration setting + * Find setting type * * @v name Name - * @v setting Buffer to fill in with setting + * @ret type Setting type, or NULL + */ +static struct setting_type * find_setting_type ( const char *name ) { + struct setting_type *type; + + for ( type = setting_types ; type < setting_types_end ; type++ ) { + if ( strcasecmp ( name, type->name ) == 0 ) + return type; + } + return NULL; +} + +/** + * Parse setting name + * + * @v name Name of setting + * @ret settings Settings block, or NULL + * @ret tag Setting tag number + * @ret type Setting type * @ret rc Return status code * - * Find setting if it exists. If it doesn't exist, but the name is of - * the form ":" (e.g. "12:string"), then construct a - * setting for that tag and data type, and return it. The constructed - * setting will be placed in the buffer. + * Interprets a name of the form + * "[settings_name/]tag_name[:type_name]" and fills in the appropriate + * fields. */ -static int find_or_build_config_setting ( const char *name, - struct config_setting *setting ) { - struct config_setting *known_setting; +static int parse_setting_name ( const char *name, struct settings **settings, + unsigned int *tag, + struct setting_type **type ) { char tmp_name[ strlen ( name ) + 1 ]; - char *qualifier; + char *settings_name; + char *tag_name; + char *type_name; + struct named_setting *named_setting; char *tmp; /* Set defaults */ - memset ( setting, 0, sizeof ( *setting ) ); - setting->name = name; - setting->type = &config_setting_type_hex; + *settings = NULL; + *tag = 0; + *type = &setting_type_hex; - /* Strip qualifier, if present */ + /* Split name into "[settings_name/]tag_name[:type_name]" */ memcpy ( tmp_name, name, sizeof ( tmp_name ) ); - if ( ( qualifier = strchr ( tmp_name, ':' ) ) != NULL ) - *(qualifier++) = 0; - - /* If we recognise the name of the setting, use it */ - if ( ( known_setting = find_config_setting ( tmp_name ) ) != NULL ) { - memcpy ( setting, known_setting, sizeof ( *setting ) ); + if ( ( tag_name = strchr ( tmp_name, '/' ) ) != NULL ) { + *(tag_name++) = 0; + settings_name = tmp_name; } else { - /* Otherwise, try to interpret as a numerical setting */ - for ( tmp = tmp_name ; 1 ; tmp++ ) { - setting->tag = ( ( setting->tag << 8 ) | - strtoul ( tmp, &tmp, 0 ) ); - if ( *tmp != '.' ) - break; + tag_name = tmp_name; + settings_name = NULL; + } + if ( ( type_name = strchr ( tag_name, ':' ) ) != NULL ) + *(type_name++) = 0; + + /* Identify settings block, if specified */ + if ( settings_name ) { + *settings = find_settings ( settings_name ); + if ( *settings == NULL ) { + DBG ( "Unrecognised settings block \"%s\" in \"%s\"\n", + settings_name, name ); + return -ENODEV; } - if ( *tmp != 0 ) - return -EINVAL; } - /* Apply qualifier, if present */ - if ( qualifier ) { - setting->type = find_config_setting_type ( qualifier ); - if ( ! setting->type ) - return -EINVAL; + /* Identify tag number */ + if ( ( named_setting = find_named_setting ( tag_name ) ) != NULL ) { + *tag = named_setting->tag; + *type = named_setting->type; + } else { + /* Unrecognised name: try to interpret as a tag number */ + tmp = tag_name; + while ( 1 ) { + *tag = ( ( *tag << 8 ) | strtoul ( tmp, &tmp, 0 ) ); + if ( *tmp == 0 ) + break; + if ( *tmp != '.' ) { + DBG ( "Invalid tag number \"%s\" in \"%s\"\n", + tag_name, name ); + return -ENOENT; + } + tmp++; + } + } + + /* Identify setting type, if specified */ + if ( type_name ) { + *type = find_setting_type ( type_name ); + if ( *type == NULL ) { + DBG ( "Invalid setting type \"%s\" in \"%s\"\n", + type_name, name ); + return -ENOTSUP; + } } return 0; } /** - * Show value of named setting + * Parse and set value of named setting * - * @v context Configuration context - * @v name Configuration setting name - * @v buf Buffer to contain value + * @v name Name of setting + * @v value Formatted setting data, or NULL + * @ret rc Return status code + */ +int set_named_setting ( const char *name, const char *value ) { + struct settings *settings; + unsigned int tag; + struct setting_type *type; + int rc; + + if ( ( rc = parse_setting_name ( name, &settings, &tag, + &type ) ) != 0 ) + return rc; + if ( settings == NULL ) + return -ENODEV; + return set_typed_setting ( settings, tag, type, value ); +} + +/** + * Get and format value of named setting + * + * @v name Name of setting + * @v buf Buffer to contain formatted value * @v len Length of buffer * @ret len Length of formatted value, or negative error */ -int show_named_setting ( struct config_context *context, const char *name, - char *buf, size_t len ) { - struct config_setting setting; +int get_named_setting ( const char *name, char *buf, size_t len ) { + struct settings *settings; + unsigned int tag; + struct setting_type *type; int rc; - if ( ( rc = find_or_build_config_setting ( name, &setting ) ) != 0 ) + if ( ( rc = parse_setting_name ( name, &settings, &tag, + &type ) ) != 0 ) return rc; - return show_setting ( context, &setting, buf, len ); + return get_typed_setting ( settings, tag, type, buf, len ); } -/** - * Set value of named setting +/****************************************************************************** * - * @v context Configuration context - * @v name Configuration setting name - * @v value Setting value (as a string) + * Setting types + * + ****************************************************************************** + */ + +/** + * Parse and set value of string setting + * + * @v settings Settings block + * @v tag Setting tag number + * @v value Formatted setting data * @ret rc Return status code */ -int set_named_setting ( struct config_context *context, const char *name, - const char *value ) { - struct config_setting setting; - int rc; - - if ( ( rc = find_or_build_config_setting ( name, &setting ) ) != 0 ) - return rc; - return set_setting ( context, &setting, value ); +static int setf_string ( struct settings *settings, unsigned int tag, + const char *value ) { + return set_setting ( settings, tag, value, strlen ( value ) ); } /** - * Set value of setting + * Get and format value of string setting * - * @v context Configuration context - * @v setting Configuration setting - * @v value Setting value (as a string), or NULL - * @ret rc Return status code - */ -int set_setting ( struct config_context *context, - struct config_setting *setting, - const char *value ) { - if ( ( ! value ) || ( ! *value ) ) { - /* Save putting deletion logic in each individual handler */ - return clear_setting ( context, setting ); - } - return setting->type->set ( context, setting, value ); -} - -/** - * Show value of string setting - * - * @v context Configuration context - * @v setting Configuration setting - * @v buf Buffer to contain value + * @v settings Settings block, or NULL to search all blocks + * @v tag Setting tag number + * @v buf Buffer to contain formatted value * @v len Length of buffer * @ret len Length of formatted value, or negative error */ -static int show_string ( struct config_context *context, - struct config_setting *setting, +static int getf_string ( struct settings *settings, unsigned int tag, char *buf, size_t len ) { - struct dhcp_option *option; - - option = find_dhcp_option ( context->options, setting->tag ); - if ( ! option ) - return -ENODATA; - return dhcp_snprintf ( buf, len, option ); + return get_string_setting ( settings, tag, buf, len ); } -/** - * Set value of string setting - * - * @v context Configuration context - * @v setting Configuration setting - * @v value Setting value (as a string) - * @ret rc Return status code - */ -static int set_string ( struct config_context *context, - struct config_setting *setting, - const char *value ) { - struct dhcp_option *option; - - option = set_dhcp_option ( context->options, setting->tag, - value, strlen ( value ) ); - if ( ! option ) - return -ENOSPC; - return 0; -} - -/** A string configuration setting */ -struct config_setting_type config_setting_type_string __config_setting_type = { +/** A string setting type */ +struct setting_type setting_type_string __setting_type = { .name = "string", - .description = "Text string", - .show = show_string, - .set = set_string, + .setf = setf_string, + .getf = getf_string, }; /** - * Show value of IPv4 setting + * Parse and set value of IPv4 address setting * - * @v context Configuration context - * @v setting Configuration setting - * @v buf Buffer to contain value + * @v settings Settings block + * @v tag Setting tag number + * @v value Formatted setting data + * @ret rc Return status code + */ +static int setf_ipv4 ( struct settings *settings, unsigned int tag, + const char *value ) { + struct in_addr ipv4; + + if ( inet_aton ( value, &ipv4 ) == 0 ) + return -EINVAL; + return set_setting ( settings, tag, &ipv4, sizeof ( ipv4 ) ); +} + +/** + * Get and format value of IPv4 address setting + * + * @v settings Settings block, or NULL to search all blocks + * @v tag Setting tag number + * @v buf Buffer to contain formatted value * @v len Length of buffer * @ret len Length of formatted value, or negative error */ -static int show_ipv4 ( struct config_context *context, - struct config_setting *setting, +static int getf_ipv4 ( struct settings *settings, unsigned int tag, char *buf, size_t len ) { - struct dhcp_option *option; struct in_addr ipv4; + int rc; - option = find_dhcp_option ( context->options, setting->tag ); - if ( ! option ) - return -ENODATA; - dhcp_ipv4_option ( option, &ipv4 ); + if ( ( rc = get_ipv4_setting ( settings, tag, &ipv4 ) ) < 0 ) + return rc; return snprintf ( buf, len, inet_ntoa ( ipv4 ) ); } -/** - * Set value of IPV4 setting - * - * @v context Configuration context - * @v setting Configuration setting - * @v value Setting value (as a string) - * @ret rc Return status code - */ -static int set_ipv4 ( struct config_context *context, - struct config_setting *setting, - const char *value ) { - struct dhcp_option *option; - struct in_addr ipv4; - - if ( inet_aton ( value, &ipv4 ) == 0 ) - return -EINVAL; - option = set_dhcp_option ( context->options, setting->tag, - &ipv4, sizeof ( ipv4 ) ); - if ( ! option ) - return -ENOSPC; - return 0; -} - -/** An IPv4 configuration setting */ -struct config_setting_type config_setting_type_ipv4 __config_setting_type = { +/** An IPv4 address setting type */ +struct setting_type setting_type_ipv4 __setting_type = { .name = "ipv4", - .description = "IPv4 address", - .show = show_ipv4, - .set = set_ipv4, + .setf = setf_ipv4, + .getf = getf_ipv4, }; /** - * Show value of integer setting + * Parse and set value of integer setting * - * @v context Configuration context - * @v setting Configuration setting - * @v buf Buffer to contain value - * @v len Length of buffer - * @ret len Length of formatted value, or negative error - */ -static int show_int ( struct config_context *context, - struct config_setting *setting, - char *buf, size_t len ) { - struct dhcp_option *option; - long num; - - option = find_dhcp_option ( context->options, setting->tag ); - if ( ! option ) - return -ENODATA; - num = dhcp_num_option ( option ); - return snprintf ( buf, len, "%ld", num ); -} - -/** - * Set value of integer setting - * - * @v context Configuration context - * @v setting Configuration setting - * @v value Setting value (as a string) - * @v size Size of integer (in bytes) + * @v settings Settings block + * @v tag Setting tag number + * @v value Formatted setting data + * @v size Integer size, in bytes * @ret rc Return status code - */ -static int set_int ( struct config_context *context, - struct config_setting *setting, - const char *value, unsigned int size ) { - struct dhcp_option *option; + */ +static int setf_int ( struct settings *settings, unsigned int tag, + const char *value, unsigned int size ) { union { uint32_t num; uint8_t bytes[4]; } u; char *endp; - /* Parse number */ - if ( ! *value ) - return -EINVAL; u.num = htonl ( strtoul ( value, &endp, 0 ) ); if ( *endp ) return -EINVAL; - - /* Set option */ - option = set_dhcp_option ( context->options, setting->tag, - &u.bytes[ sizeof ( u ) - size ], size ); - if ( ! option ) - return -ENOSPC; - return 0; + return set_setting ( settings, tag, + &u.bytes[ sizeof ( u ) - size ], size ); } /** - * Set value of 8-bit integer setting + * Parse and set value of 8-bit integer setting * - * @v context Configuration context - * @v setting Configuration setting - * @v value Setting value (as a string) - * @v size Size of integer (in bytes) + * @v settings Settings block + * @v tag Setting tag number + * @v value Formatted setting data + * @v size Integer size, in bytes * @ret rc Return status code - */ -static int set_int8 ( struct config_context *context, - struct config_setting *setting, - const char *value ) { - return set_int ( context, setting, value, 1 ); -} - -/** - * Set value of 16-bit integer setting - * - * @v context Configuration context - * @v setting Configuration setting - * @v value Setting value (as a string) - * @v size Size of integer (in bytes) - * @ret rc Return status code - */ -static int set_int16 ( struct config_context *context, - struct config_setting *setting, + */ +static int setf_int8 ( struct settings *settings, unsigned int tag, const char *value ) { - return set_int ( context, setting, value, 2 ); + return setf_int ( settings, tag, value, 1 ); } /** - * Set value of 32-bit integer setting + * Parse and set value of 16-bit integer setting * - * @v context Configuration context - * @v setting Configuration setting - * @v value Setting value (as a string) - * @v size Size of integer (in bytes) + * @v settings Settings block + * @v tag Setting tag number + * @v value Formatted setting data + * @v size Integer size, in bytes * @ret rc Return status code - */ -static int set_int32 ( struct config_context *context, - struct config_setting *setting, + */ +static int setf_int16 ( struct settings *settings, unsigned int tag, const char *value ) { - return set_int ( context, setting, value, 4 ); + return setf_int ( settings, tag, value, 2 ); } -/** An 8-bit integer configuration setting */ -struct config_setting_type config_setting_type_int8 __config_setting_type = { +/** + * Parse and set value of 32-bit integer setting + * + * @v settings Settings block + * @v tag Setting tag number + * @v value Formatted setting data + * @v size Integer size, in bytes + * @ret rc Return status code + */ +static int setf_int32 ( struct settings *settings, unsigned int tag, + const char *value ) { + return setf_int ( settings, tag, value, 4 ); +} + +/** + * Get and format value of signed integer setting + * + * @v settings Settings block, or NULL to search all blocks + * @v tag Setting tag number + * @v buf Buffer to contain formatted value + * @v len Length of buffer + * @ret len Length of formatted value, or negative error + */ +static int getf_int ( struct settings *settings, unsigned int tag, + char *buf, size_t len ) { + long value; + int rc; + + if ( ( rc = get_int_setting ( settings, tag, &value ) ) < 0 ) + return rc; + return snprintf ( buf, len, "%ld", value ); +} + +/** + * Get and format value of unsigned integer setting + * + * @v settings Settings block, or NULL to search all blocks + * @v tag Setting tag number + * @v buf Buffer to contain formatted value + * @v len Length of buffer + * @ret len Length of formatted value, or negative error + */ +static int getf_uint ( struct settings *settings, unsigned int tag, + char *buf, size_t len ) { + unsigned long value; + int rc; + + if ( ( rc = get_uint_setting ( settings, tag, &value ) ) < 0 ) + return rc; + return snprintf ( buf, len, "%#lx", value ); +} + +/** A signed 8-bit integer setting type */ +struct setting_type setting_type_int8 __setting_type = { .name = "int8", - .description = "8-bit integer", - .show = show_int, - .set = set_int8, + .setf = setf_int8, + .getf = getf_int, }; -/** A 16-bit integer configuration setting */ -struct config_setting_type config_setting_type_int16 __config_setting_type = { +/** A signed 16-bit integer setting type */ +struct setting_type setting_type_int16 __setting_type = { .name = "int16", - .description = "16-bit integer", - .show = show_int, - .set = set_int16, + .setf = setf_int16, + .getf = getf_int, }; -/** A 32-bit integer configuration setting */ -struct config_setting_type config_setting_type_int32 __config_setting_type = { +/** A signed 32-bit integer setting type */ +struct setting_type setting_type_int32 __setting_type = { .name = "int32", - .description = "32-bit integer", - .show = show_int, - .set = set_int32, + .setf = setf_int32, + .getf = getf_int, +}; + +/** An unsigned 8-bit integer setting type */ +struct setting_type setting_type_uint8 __setting_type = { + .name = "uint8", + .setf = setf_int8, + .getf = getf_uint, +}; + +/** An unsigned 16-bit integer setting type */ +struct setting_type setting_type_uint16 __setting_type = { + .name = "uint16", + .setf = setf_int16, + .getf = getf_uint, +}; + +/** An unsigned 32-bit integer setting type */ +struct setting_type setting_type_uint32 __setting_type = { + .name = "uint32", + .setf = setf_int32, + .getf = getf_uint, }; /** - * Set value of hex-string setting + * Parse and set value of hex string setting * - * @v context Configuration context - * @v setting Configuration setting - * @v value Setting value (as a string) + * @v settings Settings block + * @v tag Setting tag number + * @v value Formatted setting data * @ret rc Return status code - */ -static int set_hex ( struct config_context *context, - struct config_setting *setting, - const char *value ) { - struct dhcp_option *option; + */ +static int setf_hex ( struct settings *settings, unsigned int tag, + const char *value ) { char *ptr = ( char * ) value; uint8_t bytes[ strlen ( value ) ]; /* cannot exceed strlen(value) */ unsigned int len = 0; @@ -438,11 +708,7 @@ static int set_hex ( struct config_context *context, bytes[len++] = strtoul ( ptr, &ptr, 16 ); switch ( *ptr ) { case '\0' : - option = set_dhcp_option ( context->options, - setting->tag, bytes, len ); - if ( ! option ) - return -ENOSPC; - return 0; + return set_setting ( settings, tag, bytes, len ); case ':' : ptr++; break; @@ -453,83 +719,122 @@ static int set_hex ( struct config_context *context, } /** - * Show value of hex-string setting + * Get and format value of hex string setting * - * @v context Configuration context - * @v setting Configuration setting - * @v buf Buffer to contain value + * @v settings Settings block, or NULL to search all blocks + * @v tag Setting tag number + * @v buf Buffer to contain formatted value * @v len Length of buffer * @ret len Length of formatted value, or negative error */ -static int show_hex ( struct config_context *context, - struct config_setting *setting, +static int getf_hex ( struct settings *settings, unsigned int tag, char *buf, size_t len ) { - struct dhcp_option *option; + int raw_len; + int check_len; int used = 0; int i; - option = find_dhcp_option ( context->options, setting->tag ); - if ( ! option ) - return -ENODATA; + raw_len = get_setting_len ( settings, tag ); + if ( raw_len < 0 ) + return raw_len; - for ( i = 0 ; i < option->len ; i++ ) { - used += ssnprintf ( ( buf + used ), ( len - used ), - "%s%02x", ( used ? ":" : "" ), - option->data.bytes[i] ); + { + uint8_t raw[raw_len]; + + check_len = get_setting ( settings, tag, raw, sizeof ( raw ) ); + assert ( check_len == raw_len ); + + if ( len ) + buf[0] = 0; /* Ensure that a terminating NUL exists */ + for ( i = 0 ; i < raw_len ; i++ ) { + used += ssnprintf ( ( buf + used ), ( len - used ), + "%s%02x", ( used ? ":" : "" ), + raw[i] ); + } + return used; } - return used; } -/** A hex-string configuration setting */ -struct config_setting_type config_setting_type_hex __config_setting_type = { +/** A hex-string setting */ +struct setting_type setting_type_hex __setting_type = { .name = "hex", - .description = "Hex string", - .show = show_hex, - .set = set_hex, + .setf = setf_hex, + .getf = getf_hex, }; +/****************************************************************************** + * + * Named settings + * + ****************************************************************************** + */ + /** Some basic setting definitions */ -struct config_setting basic_config_settings[] __config_setting = { +struct named_setting basic_named_settings[] __named_setting = { { .name = "ip", - .description = "IP address of this machine (e.g. 192.168.0.1)", + .description = "IPv4 address of this interface", .tag = DHCP_EB_YIADDR, - .type = &config_setting_type_ipv4, + .type = &setting_type_ipv4, + }, + { + .name = "subnet-mask", + .description = "IPv4 subnet mask", + .tag = DHCP_SUBNET_MASK, + .type = &setting_type_ipv4, + }, + { + .name = "routers", + .description = "Default gateway", + .tag = DHCP_ROUTERS, + .type = &setting_type_ipv4, + }, + { + .name = "domain-name-servers", + .description = "DNS server", + .tag = DHCP_DNS_SERVERS, + .type = &setting_type_ipv4, }, { .name = "hostname", .description = "Host name of this machine", .tag = DHCP_HOST_NAME, - .type = &config_setting_type_string, + .type = &setting_type_string, }, { - .name = "username", - .description = "User name for authentication to servers", - .tag = DHCP_EB_USERNAME, - .type = &config_setting_type_string, - }, - { - .name = "password", - .description = "Password for authentication to servers", - .tag = DHCP_EB_PASSWORD, - .type = &config_setting_type_string, + .name = "filename", + .description = "Boot filename", + .tag = DHCP_BOOTFILE_NAME, + .type = &setting_type_string, }, { .name = "root-path", .description = "NFS/iSCSI root path", .tag = DHCP_ROOT_PATH, - .type = &config_setting_type_string, + .type = &setting_type_string, + }, + { + .name = "username", + .description = "User name for authentication", + .tag = DHCP_EB_USERNAME, + .type = &setting_type_string, + }, + { + .name = "password", + .description = "Password for authentication", + .tag = DHCP_EB_PASSWORD, + .type = &setting_type_string, + }, + { + .name = "initiator-iqn", + .description = "iSCSI initiator name", + .tag = DHCP_ISCSI_INITIATOR_IQN, + .type = &setting_type_string, }, { .name = "priority", .description = "Priority of these options", .tag = DHCP_EB_PRIORITY, - .type = &config_setting_type_int8, + .type = &setting_type_int8, }, - { - .name = "initiator-iqn", - .description = "iSCSI qualified name of this machine", - .tag = DHCP_ISCSI_INITIATOR_IQN, - .type = &config_setting_type_string, - } }; diff --git a/src/hci/commands/config_cmd.c b/src/hci/commands/config_cmd.c index 368a6ca4..49cc41e7 100644 --- a/src/hci/commands/config_cmd.c +++ b/src/hci/commands/config_cmd.c @@ -4,28 +4,27 @@ #include #include - -#include -extern struct nvo_block *ugly_nvo_hack; - - static int config_exec ( int argc, char **argv ) { - struct config_context dummy_context; + struct settings *settings; int rc; - if ( argc != 1 ) { - printf ( "Usage: %s\n" + if ( argc > 2 ) { + printf ( "Usage: %s [scope]\n" "Opens the option configuration console\n", argv[0] ); return 1; } - if ( ! ugly_nvo_hack ) { - printf ( "No non-volatile option storage available\n" ); - return 1; + if ( argc == 2 ) { + settings = find_settings ( argv[1] ); + if ( ! settings ) { + printf ( "No such scope \"%s\"\n", argv[1] ); + return 1; + } + } else { + settings = &interactive_settings; } - dummy_context.options = ugly_nvo_hack->options; - if ( ( rc = settings_ui ( &dummy_context ) ) != 0 ) { + if ( ( rc = settings_ui ( settings ) ) != 0 ) { printf ( "Could not save settings: %s\n", strerror ( rc ) ); return 1; diff --git a/src/hci/commands/nvo_cmd.c b/src/hci/commands/nvo_cmd.c index 4c453c77..255e9795 100644 --- a/src/hci/commands/nvo_cmd.c +++ b/src/hci/commands/nvo_cmd.c @@ -4,33 +4,21 @@ #include #include #include -#include -#include #include #include -extern struct nvo_block *ugly_nvo_hack; - static int show_exec ( int argc, char **argv ) { - struct config_context dummy_context; char buf[256]; int rc; - if ( ! ugly_nvo_hack ) { - printf ( "No non-volatile option storage available\n" ); - return 1; - } - if ( argc != 2 ) { printf ( "Syntax: %s \n", argv[0] ); return 1; } - dummy_context.options = ugly_nvo_hack->options; - if ( ( rc = show_named_setting ( &dummy_context, argv[1], buf, - sizeof ( buf ) ) ) < 0 ) { + if ( ( rc = get_named_setting ( argv[1], buf, sizeof ( buf ) ) ) < 0 ){ printf ( "Could not find \"%s\": %s\n", - argv[1], strerror ( -rc ) ); + argv[1], strerror ( rc ) ); return 1; } @@ -39,30 +27,16 @@ static int show_exec ( int argc, char **argv ) { } static int set_exec ( int argc, char **argv ) { - struct config_context dummy_context; int rc; - if ( ! ugly_nvo_hack ) { - printf ( "No non-volatile option storage available\n" ); - return 1; - } - if ( argc != 3 ) { - printf ( "Syntax: %s \n", - argv[0] ); + printf ( "Syntax: %s \n", argv[0] ); return 1; } - dummy_context.options = ugly_nvo_hack->options; - if ( ( rc = set_named_setting ( &dummy_context, argv[1], - argv[2] ) ) != 0 ) { + if ( ( rc = set_named_setting ( argv[1], argv[2] ) ) != 0 ) { printf ( "Could not set \"%s\"=\"%s\": %s\n", - argv[1], argv[2], strerror ( -rc ) ); - return 1; - } - - if ( nvo_save ( ugly_nvo_hack ) != 0 ) { - printf ( "Could not save options to non-volatile storage\n" ); + argv[1], argv[2], strerror ( rc ) ); return 1; } @@ -70,24 +44,16 @@ static int set_exec ( int argc, char **argv ) { } static int clear_exec ( int argc, char **argv ) { - struct config_context dummy_context; int rc; - if ( ! ugly_nvo_hack ) { - printf ( "No non-volatile option storage available\n" ); - return 1; - } - if ( argc != 2 ) { - printf ( "Syntax: %s \n", - argv[0] ); + printf ( "Syntax: %s \n", argv[0] ); return 1; } - dummy_context.options = ugly_nvo_hack->options; - if ( ( rc = clear_named_setting ( &dummy_context, argv[1] ) ) != 0 ) { + if ( ( rc = delete_named_setting ( argv[1] ) ) != 0 ) { printf ( "Could not clear \"%s\": %s\n", - argv[1], strerror ( -rc ) ); + argv[1], strerror ( rc ) ); return 1; } diff --git a/src/hci/tui/settings_ui.c b/src/hci/tui/settings_ui.c index c6261c77..a20dd44d 100644 --- a/src/hci/tui/settings_ui.c +++ b/src/hci/tui/settings_ui.c @@ -33,9 +33,6 @@ * */ -#include -extern struct nvo_block *ugly_nvo_hack; - /* Colour pairs */ #define CPAIR_NORMAL 1 #define CPAIR_SELECT 2 @@ -64,10 +61,10 @@ struct setting_row { /** A setting widget */ struct setting_widget { - /** Configuration context */ - struct config_context *context; + /** Settings block */ + struct settings *settings; /** Configuration setting */ - struct config_setting *setting; + struct named_setting *setting; /** Screen row */ unsigned int row; /** Screen column */ @@ -81,32 +78,32 @@ struct setting_widget { }; /** Registered configuration settings */ -static struct config_setting config_settings[0] - __table_start ( struct config_setting, config_settings ); -static struct config_setting config_settings_end[0] - __table_end ( struct config_setting, config_settings ); -#define NUM_SETTINGS ( ( unsigned ) ( config_settings_end - config_settings ) ) +static struct named_setting named_settings[0] + __table_start ( struct named_setting, named_settings ); +static struct named_setting named_settings_end[0] + __table_end ( struct named_setting, named_settings ); +#define NUM_SETTINGS ( ( unsigned ) ( named_settings_end - named_settings ) ) static void load_setting ( struct setting_widget *widget ) __nonnull; static int save_setting ( struct setting_widget *widget ) __nonnull; static void init_setting ( struct setting_widget *widget, - struct config_context *context, - struct config_setting *setting, + struct settings *settings, + struct named_setting *setting, unsigned int row, unsigned int col ) __nonnull; static void draw_setting ( struct setting_widget *widget ) __nonnull; static int edit_setting ( struct setting_widget *widget, int key ) __nonnull; static void init_setting_index ( struct setting_widget *widget, - struct config_context *context, + struct settings *settings, unsigned int index ) __nonnull; static void vmsg ( unsigned int row, const char *fmt, va_list args ) __nonnull; static void msg ( unsigned int row, const char *fmt, ... ) __nonnull; static void valert ( const char *fmt, va_list args ) __nonnull; static void alert ( const char *fmt, ... ) __nonnull; -static void draw_info_row ( struct config_setting *setting ) __nonnull; -static int main_loop ( struct config_context *context ) __nonnull; +static void draw_info_row ( struct named_setting *setting ) __nonnull; +static int main_loop ( struct settings *settings ) __nonnull; /** - * Load setting widget value from configuration context + * Load setting widget value from configuration settings * * @v widget Setting widget * @@ -117,8 +114,9 @@ static void load_setting ( struct setting_widget *widget ) { widget->editing = 0; /* Read current setting value */ - if ( show_setting ( widget->context, widget->setting, - widget->value, sizeof ( widget->value ) ) < 0 ) { + if ( get_typed_setting ( widget->settings, widget->setting->tag, + widget->setting->type, widget->value, + sizeof ( widget->value ) ) < 0 ) { widget->value[0] = '\0'; } @@ -130,31 +128,32 @@ static void load_setting ( struct setting_widget *widget ) { } /** - * Save setting widget value back to configuration context + * Save setting widget value back to configuration settings * * @v widget Setting widget */ static int save_setting ( struct setting_widget *widget ) { - return set_setting ( widget->context, widget->setting, widget->value ); + return set_typed_setting ( widget->settings, widget->setting->tag, + widget->setting->type, widget->value ); } /** * Initialise setting widget * * @v widget Setting widget - * @v context Configuration context + * @v settings Settings block * @v setting Configuration setting * @v row Screen row * @v col Screen column */ static void init_setting ( struct setting_widget *widget, - struct config_context *context, - struct config_setting *setting, + struct settings *settings, + struct named_setting *setting, unsigned int row, unsigned int col ) { /* Initialise widget structure */ memset ( widget, 0, sizeof ( *widget ) ); - widget->context = context; + widget->settings = settings; widget->setting = setting; widget->row = row; widget->col = col; @@ -219,13 +218,13 @@ static int edit_setting ( struct setting_widget *widget, int key ) { * Initialise setting widget by index * * @v widget Setting widget - * @v context Configuration context + * @v settings Settings block * @v index Index of setting with settings list */ static void init_setting_index ( struct setting_widget *widget, - struct config_context *context, + struct settings *settings, unsigned int index ) { - init_setting ( widget, context, &config_settings[index], + init_setting ( widget, settings, &named_settings[index], ( SETTINGS_LIST_ROW + index ), SETTINGS_LIST_COL ); } @@ -312,11 +311,10 @@ static void draw_title_row ( void ) { * * @v setting Current configuration setting */ -static void draw_info_row ( struct config_setting *setting ) { +static void draw_info_row ( struct named_setting *setting ) { clearmsg ( INFO_ROW ); attron ( A_BOLD ); - msg ( INFO_ROW, "%s (%s) - %s", setting->name, - setting->type->description, setting->description ); + msg ( INFO_ROW, "%s - %s", setting->name, setting->description ); attroff ( A_BOLD ); } @@ -333,11 +331,11 @@ static void draw_instruction_row ( int editing ) { "Ctrl-C - discard changes" ); } else { msg ( INSTRUCTION_ROW, - "Ctrl-S - save configuration" ); + "Ctrl-X - exit configuration utility" ); } } -static int main_loop ( struct config_context *context ) { +static int main_loop ( struct settings *settings ) { struct setting_widget widget; unsigned int current = 0; unsigned int next; @@ -349,7 +347,7 @@ static int main_loop ( struct config_context *context ) { draw_title_row(); color_set ( CPAIR_NORMAL, NULL ); for ( i = ( NUM_SETTINGS - 1 ) ; i >= 0 ; i-- ) { - init_setting_index ( &widget, context, i ); + init_setting_index ( &widget, settings, i ); draw_setting ( &widget ); } @@ -394,19 +392,15 @@ static int main_loop ( struct config_context *context ) { if ( next > 0 ) next--; break; - case CTRL_S: - if ( ( rc = nvo_save ( ugly_nvo_hack ) ) != 0){ - alert ( " Could not save options: %s ", - strerror ( rc ) ); - } - return rc; + case CTRL_X: + return 0; default: edit_setting ( &widget, key ); break; } if ( next != current ) { draw_setting ( &widget ); - init_setting_index ( &widget, context, next ); + init_setting_index ( &widget, settings, next ); current = next; } } @@ -414,7 +408,7 @@ static int main_loop ( struct config_context *context ) { } -int settings_ui ( struct config_context *context ) { +int settings_ui ( struct settings *settings ) { int rc; initscr(); @@ -426,7 +420,7 @@ int settings_ui ( struct config_context *context ) { color_set ( CPAIR_NORMAL, NULL ); erase(); - rc = main_loop ( context ); + rc = main_loop ( settings ); endwin(); diff --git a/src/include/gpxe/settings.h b/src/include/gpxe/settings.h index 1b9c059b..7198399e 100644 --- a/src/include/gpxe/settings.h +++ b/src/include/gpxe/settings.h @@ -8,73 +8,96 @@ */ #include -#include #include +#include +#include -struct config_setting; +struct settings; +struct in_addr; -/** - * A configuration context - * - * This identifies the context within which settings are inspected and - * changed. For example, the context might be global, or might be - * restricted to the settings stored in NVS on a particular device. - */ -struct config_context { - /** DHCP options block, or NULL +/** Settings block operations */ +struct settings_operations { + /** Set value of setting * - * If NULL, all registered DHCP options blocks will be used. + * @v settings Settings block + * @v tag Setting tag number + * @v data Setting data, or NULL to clear setting + * @v len Length of setting data + * @ret rc Return status code */ - struct dhcp_option_block *options; + int ( * set ) ( struct settings *settings, unsigned int tag, + const void *data, size_t len ); + /** Get value of setting + * + * @v settings Settings block + * @v tag Setting tag number + * @v data Buffer to fill with setting data + * @v len Length of buffer + * @ret len Length of setting data, or negative error + * + * The actual length of the setting will be returned even if + * the buffer was too small. + */ + int ( * get ) ( struct settings *settings, unsigned int tag, + void *data, size_t len ); +}; + +/** A settings block */ +struct settings { + /** Reference counter */ + struct refcnt *refcnt; + /** Name */ + char name[16]; + /** List of all settings */ + struct list_head list; + /** Settings block operations */ + struct settings_operations *op; }; /** - * A configuration setting type + * A setting type * - * This represents a type of configuration setting (e.g. string, IPv4 - * address, etc.). + * This represents a type of setting (e.g. string, IPv4 address, + * etc.). */ -struct config_setting_type { +struct setting_type { /** Name * * This is the name exposed to the user (e.g. "string"). */ const char *name; - /** Description */ - const char *description; - /** Show value of setting + /** Parse and set value of setting * - * @v context Configuration context - * @v setting Configuration setting - * @v buf Buffer to contain value + * @v settings Settings block + * @v tag Setting tag number + * @v value Formatted setting data + * @ret rc Return status code + */ + int ( * setf ) ( struct settings *settings, unsigned int tag, + const char *value ); + /** Get and format value of setting + * + * @v settings Settings block, or NULL to search all blocks + * @v tag Setting tag number + * @v buf Buffer to contain formatted value * @v len Length of buffer * @ret len Length of formatted value, or negative error */ - int ( * show ) ( struct config_context *context, - struct config_setting *setting, + int ( * getf ) ( struct settings *settings, unsigned int tag, char *buf, size_t len ); - /** Set value of setting - * - * @v context Configuration context - * @v setting Configuration setting - * @v value Setting value (as a string) - * @ret rc Return status code - */ - int ( * set ) ( struct config_context *context, - struct config_setting *setting, - const char *value ); }; /** Declare a configuration setting type */ -#define __config_setting_type \ - __table ( struct config_setting_type, config_setting_types, 01 ) +#define __setting_type \ + __table ( struct setting_type, setting_types, 01 ) /** - * A configuration setting + * A named setting * - * This represents a single configuration setting (e.g. "hostname"). + * This represents a single setting (e.g. "hostname"), encapsulating + * the information about the setting's tag number and type. */ -struct config_setting { +struct named_setting { /** Name * * This is the human-readable name for the setting. Where @@ -84,71 +107,90 @@ struct config_setting { const char *name; /** Description */ const char *description; - /** DHCP option tag - * - * This is the DHCP tag used to identify the option in DHCP - * packets and stored option blocks. - */ + /** Setting tag number */ unsigned int tag; - /** Configuration setting type + /** Setting type * * This identifies the type of setting (e.g. string, IPv4 * address, etc.). */ - struct config_setting_type *type; + struct setting_type *type; }; /** Declare a configuration setting */ -#define __config_setting __table ( struct config_setting, config_settings, 01 ) +#define __named_setting __table ( struct named_setting, named_settings, 01 ) + +extern struct settings interactive_settings; + +extern int get_setting ( struct settings *settings, unsigned int tag, + void *data, size_t len ); +extern int get_setting_len ( struct settings *settings, unsigned int tag ); +extern int get_string_setting ( struct settings *settings, unsigned int tag, + char *data, size_t len ); +extern int get_ipv4_setting ( struct settings *settings, unsigned int tag, + struct in_addr *inp ); +extern int get_int_setting ( struct settings *settings, unsigned int tag, + long *value ); +extern int get_uint_setting ( struct settings *settings, unsigned int tag, + unsigned long *value ); +extern struct settings * find_settings ( const char *name ); +extern int set_typed_setting ( struct settings *settings, + unsigned int tag, struct setting_type *type, + const char *value ); +extern int set_named_setting ( const char *name, const char *value ); +extern int get_named_setting ( const char *name, char *buf, size_t len ); /** - * Show value of setting + * Set value of setting * - * @v context Configuration context - * @v setting Configuration setting - * @v buf Buffer to contain value + * @v settings Settings block + * @v tag Setting tag number + * @v data Setting data, or NULL to clear setting + * @v len Length of setting data + * @ret rc Return status code + */ +static inline int set_setting ( struct settings *settings, unsigned int tag, + const void *data, size_t len ) { + return settings->op->set ( settings, tag, data, len ); +} + +/** + * Delete setting + * + * @v settings Settings block + * @v tag Setting tag number + * @ret rc Return status code + */ +static inline int delete_setting ( struct settings *settings, + unsigned int tag ) { + return set_setting ( settings, tag, NULL, 0 ); +} + +/** + * Get and format value of setting + * + * @v settings Settings block, or NULL to search all blocks + * @v tag Setting tag number + * @v type Settings type + * @v buf Buffer to contain formatted value * @v len Length of buffer * @ret len Length of formatted value, or negative error */ -static inline int show_setting ( struct config_context *context, - struct config_setting *setting, - char *buf, size_t len ) { - return setting->type->show ( context, setting, buf, len ); +static inline int get_typed_setting ( struct settings *settings, + unsigned int tag, + struct setting_type *type, + char *buf, size_t len ) { + return type->getf ( settings, tag, buf, len ); } -extern int set_setting ( struct config_context *context, - struct config_setting *setting, - const char *value ); - /** - * Clear setting + * Delete named setting * - * @v context Configuration context - * @v setting Configuration setting + * @v name Name of setting * @ret rc Return status code */ -static inline int clear_setting ( struct config_context *context, - struct config_setting *setting ) { - delete_dhcp_option ( context->options, setting->tag ); - return 0; -} - -/* Function prototypes */ -extern int show_named_setting ( struct config_context *context, - const char *name, char *buf, size_t len ); -extern int set_named_setting ( struct config_context *context, - const char *name, const char *value ); - -/** - * Clear named setting - * - * @v context Configuration context - * @v name Configuration setting name - * @ret rc Return status code - */ -static inline int clear_named_setting ( struct config_context *context, - const char *name ) { - return set_named_setting ( context, name, NULL ); +static inline int delete_named_setting ( const char *name ) { + return set_named_setting ( name, NULL ); } #endif /* _GPXE_SETTINGS_H */ diff --git a/src/include/gpxe/settings_ui.h b/src/include/gpxe/settings_ui.h index 70ee8cb3..48548fd5 100644 --- a/src/include/gpxe/settings_ui.h +++ b/src/include/gpxe/settings_ui.h @@ -7,8 +7,8 @@ * */ -struct config_context; +struct settings; -extern int settings_ui ( struct config_context *context ) __nonnull; +extern int settings_ui ( struct settings *settings ) __nonnull; #endif /* _GPXE_SETTINGS_UI_H */