diff options
author | Michael Brown <mcb30@etherboot.org> | 2008-03-18 03:23:36 +0000 |
---|---|---|
committer | Michael Brown <mcb30@etherboot.org> | 2008-03-18 03:23:36 +0000 |
commit | e2613e8896cf491721d7c9ad79bceb578744a545 (patch) | |
tree | af66980325754b20615c6e6d34eccddc6dcc04ac /src/core/settings.c | |
parent | 6fe585642a79c071ed3657547acc9d4133c7abf8 (diff) | |
download | ipxe-e2613e8896cf491721d7c9ad79bceb578744a545.tar.gz |
[Settings] Add int16, int32 and hex-string configuration setting types
Add parse and display routines for 16-bit and 32-bit integer configuration
settings.
Add parse and display routines for hex-string configuration settings.
Assume hex-string as a configuration setting type if no type is explicitly
specified.
Diffstat (limited to 'src/core/settings.c')
-rw-r--r-- | src/core/settings.c | 136 |
1 files changed, 131 insertions, 5 deletions
diff --git a/src/core/settings.c b/src/core/settings.c index 258fc1c7..11afd824 100644 --- a/src/core/settings.c +++ b/src/core/settings.c @@ -25,6 +25,7 @@ #include <errno.h> #include <assert.h> #include <gpxe/in.h> +#include <gpxe/vsprintf.h> #include <gpxe/settings.h> /** @file @@ -45,6 +46,8 @@ static struct config_setting config_settings[0] static struct config_setting config_settings_end[0] __table_end ( struct config_setting, config_settings ); +struct config_setting_type config_setting_type_hex __config_setting_type; + /** * Find configuration setting type * @@ -108,9 +111,16 @@ find_or_build_config_setting ( const char *name, memset ( setting, 0, sizeof ( *setting ) ); setting->name = name; setting->tag = strtoul ( name, &separator, 10 ); - if ( *separator != '.' ) - return NULL; - setting->type = find_config_setting_type ( separator + 1 ); + switch ( *separator ) { + case '.' : + setting->type = find_config_setting_type ( separator + 1 ); + break; + case '\0' : + setting->type = &config_setting_type_hex; + break; + default : + break; + } if ( ! setting->type ) return NULL; return setting; @@ -340,11 +350,41 @@ static int set_int ( struct config_context *context, * @ret rc Return status code */ static int set_int8 ( struct config_context *context, - struct config_setting *setting, - const char *value ) { + 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, + const char *value ) { + return set_int ( context, setting, value, 2 ); +} + +/** + * Set value of 32-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_int32 ( struct config_context *context, + struct config_setting *setting, + const char *value ) { + return set_int ( context, setting, value, 4 ); +} + /** An 8-bit integer configuration setting */ struct config_setting_type config_setting_type_int8 __config_setting_type = { .name = "int8", @@ -353,6 +393,92 @@ struct config_setting_type config_setting_type_int8 __config_setting_type = { .set = set_int8, }; +/** A 16-bit integer configuration setting */ +struct config_setting_type config_setting_type_int16 __config_setting_type = { + .name = "int16", + .description = "16-bit integer", + .show = show_int, + .set = set_int16, +}; + +/** A 32-bit integer configuration setting */ +struct config_setting_type config_setting_type_int32 __config_setting_type = { + .name = "int32", + .description = "32-bit integer", + .show = show_int, + .set = set_int32, +}; + +/** + * Set value of hex-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_hex ( struct config_context *context, + struct config_setting *setting, + const char *value ) { + struct dhcp_option *option; + char *ptr = ( char * ) value; + uint8_t bytes[ strlen ( value ) ]; /* cannot exceed strlen(value) */ + unsigned int len = 0; + + while ( 1 ) { + 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; + case ':' : + ptr++; + break; + default : + return -EINVAL; + } + } +} + +/** + * Show value of hex-string 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_hex ( struct config_context *context, + struct config_setting *setting, + char *buf, size_t len ) { + struct dhcp_option *option; + int used = 0; + int i; + + option = find_dhcp_option ( context->options, setting->tag ); + if ( ! option ) + return -ENODATA; + + for ( i = 0 ; i < option->len ; i++ ) { + used += ssnprintf ( ( buf + used ), ( len - used ), + "%s%02x", ( used ? ":" : "" ), + option->data.bytes[i] ); + } + return used; +} + +/** A hex-string configuration setting */ +struct config_setting_type config_setting_type_hex __config_setting_type = { + .name = "hex", + .description = "Hex string", + .show = show_hex, + .set = set_hex, +}; + /** Some basic setting definitions */ struct config_setting basic_config_settings[] __config_setting = { { |