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.
28 #include <gpxe/settings.h>
32 * Configuration settings
36 /** Registered configuration setting types */
37 static struct config_setting_type config_setting_types
[0]
38 __table_start ( struct config_setting_type
, config_setting_types
);
39 static struct config_setting_type config_setting_types_end
[0]
40 __table_end ( struct config_setting_type
, config_setting_types
);
42 /** Registered configuration settings */
43 static struct config_setting config_settings
[0]
44 __table_start ( struct config_setting
, config_settings
);
45 static struct config_setting config_settings_end
[0]
46 __table_end ( struct config_setting
, config_settings
);
49 * Find configuration setting type
52 * @ret type Configuration setting type, or NULL
54 static struct config_setting_type
*
55 find_config_setting_type ( const char *name
) {
56 struct config_setting_type
*type
;
58 for ( type
= config_setting_types
; type
< config_setting_types_end
;
60 if ( strcasecmp ( name
, type
->name
) == 0 )
67 * Find configuration setting
70 * @ret setting Configuration setting, or NULL
72 static struct config_setting
* find_config_setting ( const char *name
) {
73 struct config_setting
*setting
;
75 for ( setting
= config_settings
; setting
< config_settings_end
;
77 if ( strcasecmp ( name
, setting
->name
) == 0 )
84 * Find or build configuration setting
87 * @v tmp_setting Temporary buffer for constructing a setting
88 * @ret setting Configuration setting, or NULL
90 * Find setting if it exists. If it doesn't exist, but the name is of
91 * the form "<num>.<type>" (e.g. "12.string"), then construct a
92 * setting for that tag and data type, and return it. The constructed
93 * setting will be placed in the temporary buffer.
95 static struct config_setting
*
96 find_or_build_config_setting ( const char *name
,
97 struct config_setting
*tmp_setting
) {
98 struct config_setting
*setting
;
101 /* Look in the list of registered settings first */
102 setting
= find_config_setting ( name
);
106 /* If name is of the form "<num>.<type>", try to construct a setting */
107 setting
= tmp_setting
;
108 memset ( setting
, 0, sizeof ( *setting
) );
109 setting
->name
= name
;
110 setting
->tag
= strtoul ( name
, &separator
, 10 );
111 if ( *separator
!= '.' )
113 setting
->type
= find_config_setting_type ( separator
+ 1 );
114 if ( ! setting
->type
)
120 * Show value of named setting
122 * @v context Configuration context
123 * @v name Configuration setting name
124 * @v buf Buffer to contain value
125 * @v len Length of buffer
126 * @ret rc Return status code
128 int show_named_setting ( struct config_context
*context
, const char *name
,
129 char *buf
, size_t len
) {
130 struct config_setting
*setting
;
131 struct config_setting tmp_setting
;
133 setting
= find_or_build_config_setting ( name
, &tmp_setting
);
136 return show_setting ( context
, setting
, buf
, len
);
140 * Set value of named setting
142 * @v context Configuration context
143 * @v name Configuration setting name
144 * @v value Setting value (as a string)
145 * @ret rc Return status code
147 int set_named_setting ( struct config_context
*context
, const char *name
,
148 const char *value
) {
149 struct config_setting
*setting
;
150 struct config_setting tmp_setting
;
152 setting
= find_or_build_config_setting ( name
, &tmp_setting
);
155 return setting
->type
->set ( context
, setting
, value
);
159 * Set value of setting
161 * @v context Configuration context
162 * @v setting Configuration setting
163 * @v value Setting value (as a string), or NULL
164 * @ret rc Return status code
166 int set_setting ( struct config_context
*context
,
167 struct config_setting
*setting
,
168 const char *value
) {
169 if ( ( ! value
) || ( ! *value
) ) {
170 /* Save putting deletion logic in each individual handler */
171 return clear_setting ( context
, setting
);
173 return setting
->type
->set ( context
, setting
, value
);
177 * Show value of string setting
179 * @v context Configuration context
180 * @v setting Configuration setting
181 * @v buf Buffer to contain value
182 * @v len Length of buffer
183 * @ret rc Return status code
185 static int show_string ( struct config_context
*context
,
186 struct config_setting
*setting
,
187 char *buf
, size_t len
) {
188 struct dhcp_option
*option
;
190 option
= find_dhcp_option ( context
->options
, setting
->tag
);
193 dhcp_snprintf ( buf
, len
, option
);
198 * Set value of string setting
200 * @v context Configuration context
201 * @v setting Configuration setting
202 * @v value Setting value (as a string)
203 * @ret rc Return status code
205 static int set_string ( struct config_context
*context
,
206 struct config_setting
*setting
,
207 const char *value
) {
208 struct dhcp_option
*option
;
210 option
= set_dhcp_option ( context
->options
, setting
->tag
,
211 value
, strlen ( value
) );
217 /** A string configuration setting */
218 struct config_setting_type config_setting_type_string __config_setting_type
= {
220 .description
= "Text string",
226 * Show value of IPv4 setting
228 * @v context Configuration context
229 * @v setting Configuration setting
230 * @v buf Buffer to contain value
231 * @v len Length of buffer
232 * @ret rc Return status code
234 static int show_ipv4 ( struct config_context
*context
,
235 struct config_setting
*setting
,
236 char *buf
, size_t len
) {
237 struct dhcp_option
*option
;
240 option
= find_dhcp_option ( context
->options
, setting
->tag
);
243 dhcp_ipv4_option ( option
, &ipv4
);
244 snprintf ( buf
, len
, inet_ntoa ( ipv4
) );
249 * Set value of IPV4 setting
251 * @v context Configuration context
252 * @v setting Configuration setting
253 * @v value Setting value (as a string)
254 * @ret rc Return status code
256 static int set_ipv4 ( struct config_context
*context
,
257 struct config_setting
*setting
,
258 const char *value
) {
259 struct dhcp_option
*option
;
262 if ( inet_aton ( value
, &ipv4
) == 0 )
264 option
= set_dhcp_option ( context
->options
, setting
->tag
,
265 &ipv4
, sizeof ( ipv4
) );
271 /** An IPv4 configuration setting */
272 struct config_setting_type config_setting_type_ipv4 __config_setting_type
= {
274 .description
= "IPv4 address",
280 * Show value of integer setting
282 * @v context Configuration context
283 * @v setting Configuration setting
284 * @v buf Buffer to contain value
285 * @v len Length of buffer
286 * @ret rc Return status code
288 static int show_int ( struct config_context
*context
,
289 struct config_setting
*setting
,
290 char *buf
, size_t len
) {
291 struct dhcp_option
*option
;
294 option
= find_dhcp_option ( context
->options
, setting
->tag
);
297 num
= dhcp_num_option ( option
);
298 snprintf ( buf
, len
, "%ld", num
);
303 * Set value of integer setting
305 * @v context Configuration context
306 * @v setting Configuration setting
307 * @v value Setting value (as a string)
308 * @v size Size of integer (in bytes)
309 * @ret rc Return status code
311 static int set_int ( struct config_context
*context
,
312 struct config_setting
*setting
,
313 const char *value
, unsigned int size
) {
314 struct dhcp_option
*option
;
324 u
.num
= htonl ( strtoul ( value
, &endp
, 0 ) );
329 option
= set_dhcp_option ( context
->options
, setting
->tag
,
330 &u
.bytes
[ sizeof ( u
) - size
], size
);
337 * Set value of 8-bit integer setting
339 * @v context Configuration context
340 * @v setting Configuration setting
341 * @v value Setting value (as a string)
342 * @v size Size of integer (in bytes)
343 * @ret rc Return status code
345 static int set_int8 ( struct config_context
*context
,
346 struct config_setting
*setting
,
347 const char *value
) {
348 return set_int ( context
, setting
, value
, 1 );
351 /** An 8-bit integer configuration setting */
352 struct config_setting_type config_setting_type_int8 __config_setting_type
= {
354 .description
= "8-bit integer",
359 /** Some basic setting definitions */
360 struct config_setting basic_config_settings
[] __config_setting
= {
363 .description
= "IP address of this machine (e.g. 192.168.0.1)",
364 .tag
= DHCP_EB_YIADDR
,
365 .type
= &config_setting_type_ipv4
,
369 .description
= "Host name of this machine",
370 .tag
= DHCP_HOST_NAME
,
371 .type
= &config_setting_type_string
,
375 .description
= "User name for authentication to servers",
376 .tag
= DHCP_EB_USERNAME
,
377 .type
= &config_setting_type_string
,
381 .description
= "Password for authentication to servers",
382 .tag
= DHCP_EB_PASSWORD
,
383 .type
= &config_setting_type_string
,
387 .description
= "NFS/iSCSI root path",
388 .tag
= DHCP_ROOT_PATH
,
389 .type
= &config_setting_type_string
,
393 .description
= "Priority of these options",
394 .tag
= DHCP_EB_PRIORITY
,
395 .type
= &config_setting_type_int8
,
398 .name
= "initiator-iqn",
399 .description
= "iSCSI qualified name of this machine",
400 .tag
= DHCP_ISCSI_INITIATOR_IQN
,
401 .type
= &config_setting_type_string
,