2 * Copyright (C) 2006 Michael Brown <mbrown@fensystems.co.uk>.
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * License, or any later version.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 #include <gpxe/settings.h>
30 * Configuration settings
34 /** Registered configuration setting types */
35 static struct config_setting_type
36 config_setting_types[0] __table_start ( config_setting_types );
37 static struct config_setting_type
38 config_setting_types_end[0] __table_end ( config_setting_types );
40 /** Registered configuration settings */
41 static struct config_setting
42 config_settings[0] __table_start ( config_settings );
43 static struct config_setting
44 config_settings_end[0] __table_end ( config_settings );
47 * Find configuration setting type
50 * @ret type Configuration setting type, or NULL
52 static struct config_setting_type *
53 find_config_setting_type ( const char *name ) {
54 struct config_setting_type *type;
56 for ( type = config_setting_types ; type < config_setting_types_end ;
58 if ( strcmp ( name, type->name ) == 0 )
65 * Find configuration setting
68 * @ret setting Configuration setting, or NULL
70 static struct config_setting * find_config_setting ( const char *name ) {
71 struct config_setting *setting;
73 for ( setting = config_settings ; setting < config_settings_end ;
75 if ( strcmp ( name, setting->name ) == 0 )
82 * Find or build configuration setting
85 * @v tmp_setting Temporary buffer for constructing a setting
86 * @ret setting Configuration setting, or NULL
88 * Find setting if it exists. If it doesn't exist, but the name is of
89 * the form "<num>.<type>" (e.g. "12.string"), then construct a
90 * setting for that tag and data type, and return it. The constructed
91 * setting will be placed in the temporary buffer.
93 static struct config_setting *
94 find_or_build_config_setting ( const char *name,
95 struct config_setting *tmp_setting ) {
96 struct config_setting *setting;
99 /* Look in the list of registered settings first */
100 setting = find_config_setting ( name );
104 /* If name is of the form "<num>.<type>", try to construct a setting */
105 setting = tmp_setting;
106 memset ( setting, 0, sizeof ( *setting ) );
107 setting->name = name;
108 setting->tag = strtoul ( name, &separator, 10 );
109 if ( *separator != '.' )
111 setting->type = find_config_setting_type ( separator + 1 );
112 if ( ! setting->type )
117 /** Show value of setting
119 * @v context Configuration context
120 * @v name Configuration setting name
121 * @v buf Buffer to contain value
122 * @v len Length of buffer
123 * @ret rc Return status code
125 int show_setting ( struct config_context *context, const char *name,
126 char *buf, size_t len ) {
127 struct config_setting *setting;
128 struct config_setting tmp_setting;
130 setting = find_or_build_config_setting ( name, &tmp_setting );
133 return setting->type->show ( context, setting, buf, len );
136 /** Set value of setting
138 * @v context Configuration context
139 * @v name Configuration setting name
140 * @v value Setting value (as a string)
141 * @ret rc Return status code
143 int set_setting ( struct config_context *context, const char *name,
144 const char *value ) {
145 struct config_setting *setting;
146 struct config_setting tmp_setting;
148 setting = find_or_build_config_setting ( name, &tmp_setting );
151 return setting->type->set ( context, setting, value );
155 * Show value of string setting
157 * @v context Configuration context
158 * @v setting Configuration setting
159 * @v buf Buffer to contain value
160 * @v len Length of buffer
161 * @ret rc Return status code
163 static int show_string ( struct config_context *context,
164 struct config_setting *setting,
165 char *buf, size_t len ) {
166 struct dhcp_option *option;
168 option = find_dhcp_option ( context->options, setting->tag );
171 dhcp_snprintf ( buf, len, option );
175 /** Set value of string setting
177 * @v context Configuration context
178 * @v setting Configuration setting
179 * @v value Setting value (as a string)
180 * @ret rc Return status code
182 static int set_string ( struct config_context *context,
183 struct config_setting *setting,
184 const char *value ) {
185 struct dhcp_option *option;
187 option = set_dhcp_option ( context->options, setting->tag,
188 value, strlen ( value ) );
194 /** A string configuration setting */
195 struct config_setting_type config_setting_type_string __config_setting_type = {
202 * Show value of IPv4 setting
204 * @v context Configuration context
205 * @v setting Configuration setting
206 * @v buf Buffer to contain value
207 * @v len Length of buffer
208 * @ret rc Return status code
210 static int show_ipv4 ( struct config_context *context,
211 struct config_setting *setting,
212 char *buf, size_t len ) {
213 struct dhcp_option *option;
216 option = find_dhcp_option ( context->options, setting->tag );
219 dhcp_ipv4_option ( option, &ipv4 );
220 snprintf ( buf, len, inet_ntoa ( ipv4 ) );
224 /** Set value of IPV4 setting
226 * @v context Configuration context
227 * @v setting Configuration setting
228 * @v value Setting value (as a string)
229 * @ret rc Return status code
231 static int set_ipv4 ( struct config_context *context,
232 struct config_setting *setting,
233 const char *value ) {
234 struct dhcp_option *option;
238 if ( ( rc = inet_aton ( value, &ipv4 ) ) != 0 )
240 option = set_dhcp_option ( context->options, setting->tag,
241 &ipv4, sizeof ( ipv4 ) );
247 /** An IPv4 configuration setting */
248 struct config_setting_type config_setting_type_ipv4 __config_setting_type = {
254 /** Some basic setting definitions */
255 struct config_setting ip_config_setting __config_setting = {
257 .tag = DHCP_EB_YIADDR,
258 .type = &config_setting_type_ipv4,
260 struct config_setting hostname_config_setting __config_setting = {
262 .tag = DHCP_HOST_NAME,
263 .type = &config_setting_type_string,
265 struct config_setting username_config_setting __config_setting = {
267 .tag = DHCP_EB_USERNAME,
268 .type = &config_setting_type_string,
270 struct config_setting password_config_setting __config_setting = {
272 .tag = DHCP_EB_PASSWORD,
273 .type = &config_setting_type_string,