123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253 |
- /*
- * Copyright (C) 2006 Michael Brown <mbrown@fensystems.co.uk>.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
- #include <stdint.h>
- #include <stdlib.h>
- #include <string.h>
- #include <errno.h>
- #include <assert.h>
- #include <vsprintf.h>
- #include <gpxe/in.h>
- #include <gpxe/settings.h>
-
- /** @file
- *
- * Configuration settings
- *
- */
-
- /** Registered configuration setting types */
- static struct config_setting_type
- config_setting_types[0] __table_start ( config_setting_types );
- static struct config_setting_type
- config_setting_types_end[0] __table_end ( config_setting_types );
-
- /** Registered configuration settings */
- static struct config_setting
- config_settings[0] __table_start ( config_settings );
- static struct config_setting
- config_settings_end[0] __table_end ( config_settings );
-
- /**
- * Find configuration setting type
- *
- * @v name Name
- * @ret type Configuration setting type, or NULL
- */
- static struct config_setting_type *
- find_config_setting_type ( const char *name ) {
- struct config_setting_type *type;
-
- for ( type = config_setting_types ; type < config_setting_types_end ;
- type++ ) {
- if ( strcmp ( name, type->name ) == 0 )
- return type;
- }
- return NULL;
- }
-
- /**
- * Find configuration setting
- *
- * @v name Name
- * @ret setting Configuration setting, or NULL
- */
- static struct config_setting * find_config_setting ( const char *name ) {
- struct config_setting *setting;
-
- for ( setting = config_settings ; setting < config_settings_end ;
- setting++ ) {
- if ( strcmp ( name, setting->name ) == 0 )
- return setting;
- }
- return NULL;
- }
-
- /**
- * Find or build configuration setting
- *
- * @v name Name
- * @v tmp_setting Temporary buffer for constructing a setting
- * @ret setting Configuration setting, or NULL
- *
- * Find setting if it exists. If it doesn't exist, but the name is of
- * the form "<num>.<type>" (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 temporary buffer.
- */
- static struct config_setting *
- find_or_build_config_setting ( const char *name,
- struct config_setting *tmp_setting ) {
- struct config_setting *setting;
- char *separator;
-
- /* Look in the list of registered settings first */
- setting = find_config_setting ( name );
- if ( setting )
- return setting;
-
- /* If name is of the form "<num>.<type>", try to construct a setting */
- setting = tmp_setting;
- 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 );
- if ( ! setting->type )
- return NULL;
- return setting;
- }
-
- /** Show value of setting
- *
- * @v context Configuration context
- * @v name Configuration setting name
- * @v buf Buffer to contain value
- * @v len Length of buffer
- * @ret rc Return status code
- */
- int ( show_setting ) ( struct config_context *context, const char *name,
- char *buf, size_t len ) {
- struct config_setting *setting;
- struct config_setting tmp_setting;
-
- setting = find_or_build_config_setting ( name, &tmp_setting );
- if ( ! setting )
- return -ENOENT;
- return setting->type->show ( context, setting, buf, len );
- }
-
- /** Set value of setting
- *
- * @v context Configuration context
- * @v name Configuration setting name
- * @v value Setting value (as a string)
- * @ret rc Return status code
- */
- int ( set_setting ) ( struct config_context *context, const char *name,
- const char *value ) {
- struct config_setting *setting;
- struct config_setting tmp_setting;
-
- setting = find_or_build_config_setting ( name, &tmp_setting );
- if ( ! setting )
- return -ENOENT;
- 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 len Length of buffer
- * @ret rc Return status code
- */
- static int show_string ( struct config_context *context,
- struct config_setting *setting,
- char *buf, size_t len ) {
- struct dhcp_option *option;
-
- option = find_dhcp_option ( context->options, setting->tag );
- if ( ! option )
- return -ENOENT;
- dhcp_snprintf ( buf, len, option );
- return 0;
- }
-
- /** 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 -ENOMEM;
- return 0;
- }
-
- /** A string configuration setting */
- struct config_setting_type config_setting_type_string __config_setting_type = {
- .name = "string",
- .show = show_string,
- .set = set_string,
- };
-
- /**
- * Show value of IPv4 setting
- *
- * @v context Configuration context
- * @v setting Configuration setting
- * @v buf Buffer to contain value
- * @v len Length of buffer
- * @ret rc Return status code
- */
- static int show_ipv4 ( struct config_context *context,
- struct config_setting *setting,
- char *buf, size_t len ) {
- struct dhcp_option *option;
- struct in_addr ipv4;
-
- option = find_dhcp_option ( context->options, setting->tag );
- if ( ! option )
- return -ENOENT;
- dhcp_ipv4_option ( option, &ipv4 );
- snprintf ( buf, len, inet_ntoa ( ipv4 ) );
- return 0;
- }
-
- /** 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;
- int rc;
-
- if ( ( rc = inet_aton ( value, &ipv4 ) ) != 0 )
- return rc;
- option = set_dhcp_option ( context->options, setting->tag,
- &ipv4, sizeof ( ipv4 ) );
- if ( ! option )
- return -ENOMEM;
- return 0;
- }
-
- /** An IPv4 configuration setting */
- struct config_setting_type config_setting_type_ipv4 __config_setting_type = {
- .name = "ipv4",
- .show = show_ipv4,
- .set = set_ipv4,
- };
|