summaryrefslogtreecommitdiffstats
path: root/src/core/settings.c
diff options
context:
space:
mode:
authorMichael Brown2008-03-18 04:23:36 +0100
committerMichael Brown2008-03-18 04:23:36 +0100
commite2613e8896cf491721d7c9ad79bceb578744a545 (patch)
treeaf66980325754b20615c6e6d34eccddc6dcc04ac /src/core/settings.c
parent[libc] Fix a validation bug in strtoul() (diff)
downloadipxe-e2613e8896cf491721d7c9ad79bceb578744a545.tar.gz
ipxe-e2613e8896cf491721d7c9ad79bceb578744a545.tar.xz
ipxe-e2613e8896cf491721d7c9ad79bceb578744a545.zip
[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.c136
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 = {
{