2 * Copyright (C) 2008 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.
19 FILE_LICENCE ( GPL2_OR_LATER
);
30 #include <gpxe/vsprintf.h>
31 #include <gpxe/dhcp.h>
32 #include <gpxe/uuid.h>
34 #include <gpxe/settings.h>
38 * Configuration settings
42 /******************************************************************************
44 * Generic settings blocks
46 ******************************************************************************
53 struct generic_setting
{
54 /** List of generic settings */
55 struct list_head list
;
57 struct setting setting
;
58 /** Size of setting name */
60 /** Size of setting data */
65 * Get generic setting name
67 * @v generic Generic setting
68 * @ret name Generic setting name
70 static inline void * generic_setting_name ( struct generic_setting
*generic
) {
71 return ( ( ( void * ) generic
) + sizeof ( *generic
) );
75 * Get generic setting data
77 * @v generic Generic setting
78 * @ret data Generic setting data
80 static inline void * generic_setting_data ( struct generic_setting
*generic
) {
81 return ( ( ( void * ) generic
) + sizeof ( *generic
) +
86 * Find generic setting
88 * @v generics Generic settings block
89 * @v setting Setting to find
90 * @ret generic Generic setting, or NULL
92 static struct generic_setting
*
93 find_generic_setting ( struct generic_settings
*generics
,
94 struct setting
*setting
) {
95 struct generic_setting
*generic
;
97 list_for_each_entry ( generic
, &generics
->list
, list
) {
98 if ( setting_cmp ( &generic
->setting
, setting
) == 0 )
105 * Store value of generic setting
107 * @v settings Settings block
108 * @v setting Setting to store
109 * @v data Setting data, or NULL to clear setting
110 * @v len Length of setting data
111 * @ret rc Return status code
113 int generic_settings_store ( struct settings
*settings
,
114 struct setting
*setting
,
115 const void *data
, size_t len
) {
116 struct generic_settings
*generics
=
117 container_of ( settings
, struct generic_settings
, settings
);
118 struct generic_setting
*old
;
119 struct generic_setting
*new = NULL
;
122 /* Identify existing generic setting, if any */
123 old
= find_generic_setting ( generics
, setting
);
125 /* Create new generic setting, if required */
127 /* Allocate new generic setting */
128 name_len
= ( strlen ( setting
->name
) + 1 );
129 new = zalloc ( sizeof ( *new ) + name_len
+ len
);
133 /* Populate new generic setting */
134 new->name_len
= name_len
;
136 memcpy ( &new->setting
, setting
, sizeof ( new->setting
) );
137 new->setting
.name
= generic_setting_name ( new );
138 memcpy ( generic_setting_name ( new ),
139 setting
->name
, name_len
);
140 memcpy ( generic_setting_data ( new ), data
, len
);
143 /* Delete existing generic setting, if any */
145 list_del ( &old
->list
);
149 /* Add new setting to list, if any */
151 list_add ( &new->list
, &generics
->list
);
157 * Fetch value of generic setting
159 * @v settings Settings block
160 * @v setting Setting to fetch
161 * @v data Buffer to fill with setting data
162 * @v len Length of buffer
163 * @ret len Length of setting data, or negative error
165 int generic_settings_fetch ( struct settings
*settings
,
166 struct setting
*setting
,
167 void *data
, size_t len
) {
168 struct generic_settings
*generics
=
169 container_of ( settings
, struct generic_settings
, settings
);
170 struct generic_setting
*generic
;
172 /* Find generic setting */
173 generic
= find_generic_setting ( generics
, setting
);
177 /* Copy out generic setting data */
178 if ( len
> generic
->data_len
)
179 len
= generic
->data_len
;
180 memcpy ( data
, generic_setting_data ( generic
), len
);
181 return generic
->data_len
;
185 * Clear generic settings block
187 * @v settings Settings block
189 void generic_settings_clear ( struct settings
*settings
) {
190 struct generic_settings
*generics
=
191 container_of ( settings
, struct generic_settings
, settings
);
192 struct generic_setting
*generic
;
193 struct generic_setting
*tmp
;
195 list_for_each_entry_safe ( generic
, tmp
, &generics
->list
, list
) {
196 list_del ( &generic
->list
);
199 assert ( list_empty ( &generics
->list
) );
202 /** Generic settings operations */
203 struct settings_operations generic_settings_operations
= {
204 .store
= generic_settings_store
,
205 .fetch
= generic_settings_fetch
,
206 .clear
= generic_settings_clear
,
209 /******************************************************************************
211 * Registered settings blocks
213 ******************************************************************************
216 /** Root generic settings block */
217 struct generic_settings generic_settings_root
= {
222 LIST_HEAD_INIT ( generic_settings_root
.settings
.siblings
),
224 LIST_HEAD_INIT ( generic_settings_root
.settings
.children
),
225 .op
= &generic_settings_operations
,
227 .list
= LIST_HEAD_INIT ( generic_settings_root
.list
),
230 /** Root settings block */
231 #define settings_root generic_settings_root.settings
234 * Find child named settings block
236 * @v parent Parent settings block
237 * @v name Name within this parent
238 * @ret settings Settings block, or NULL
240 static struct settings
* find_child_settings ( struct settings
*parent
,
242 struct settings
*settings
;
244 /* Treat empty name as meaning "this block" */
248 /* Look for child with matching name */
249 list_for_each_entry ( settings
, &parent
->children
, siblings
) {
250 if ( strcmp ( settings
->name
, name
) == 0 )
258 * Find or create child named settings block
260 * @v parent Parent settings block
261 * @v name Name within this parent
262 * @ret settings Settings block, or NULL
264 static struct settings
* autovivify_child_settings ( struct settings
*parent
,
267 struct generic_settings generic
;
268 char name
[ strlen ( name
) + 1 /* NUL */ ];
270 struct settings
*settings
;
272 /* Return existing settings, if existent */
273 if ( ( settings
= find_child_settings ( parent
, name
) ) != NULL
)
276 /* Create new generic settings block */
277 new_child
= zalloc ( sizeof ( *new_child
) );
279 DBGC ( parent
, "Settings %p could not create child %s\n",
283 memcpy ( new_child
->name
, name
, sizeof ( new_child
->name
) );
284 generic_settings_init ( &new_child
->generic
, NULL
, new_child
->name
);
285 settings
= &new_child
->generic
.settings
;
286 register_settings ( settings
, parent
);
291 * Return settings block name (for debug only)
293 * @v settings Settings block
294 * @ret name Settings block name
296 static const char * settings_name ( struct settings
*settings
) {
298 char tmp
[ sizeof ( buf
) ];
301 for ( count
= 0 ; settings
; settings
= settings
->parent
) {
302 memcpy ( tmp
, buf
, sizeof ( tmp
) );
303 snprintf ( buf
, sizeof ( buf
), "%s%c%s", settings
->name
,
304 ( count
++ ? '.' : '\0' ), tmp
);
310 * Parse settings block name
313 * @v get_child Function to find or create child settings block
314 * @ret settings Settings block, or NULL
316 static struct settings
*
317 parse_settings_name ( const char *name
,
318 struct settings
* ( * get_child
) ( struct settings
*,
320 struct settings
*settings
= &settings_root
;
321 char name_copy
[ strlen ( name
) + 1 ];
325 /* Create modifiable copy of name */
326 memcpy ( name_copy
, name
, sizeof ( name_copy
) );
327 remainder
= name_copy
;
329 /* Parse each name component in turn */
330 while ( remainder
) {
331 struct net_device
*netdev
;
334 remainder
= strchr ( subname
, '.' );
336 *(remainder
++) = '\0';
338 /* Special case "netX" root settings block */
339 if ( ( subname
== name_copy
) && ! strcmp ( subname
, "netX" ) &&
340 ( ( netdev
= last_opened_netdev() ) != NULL
) )
341 settings
= get_child ( settings
, netdev
->name
);
343 settings
= get_child ( settings
, subname
);
353 * Find named settings block
356 * @ret settings Settings block, or NULL
358 struct settings
* find_settings ( const char *name
) {
360 return parse_settings_name ( name
, find_child_settings
);
366 * @ret rc Return status code
368 static int apply_settings ( void ) {
369 struct settings_applicator
*applicator
;
372 /* Call all settings applicators */
373 for_each_table_entry ( applicator
, SETTINGS_APPLICATORS
) {
374 if ( ( rc
= applicator
->apply() ) != 0 ) {
375 DBG ( "Could not apply settings using applicator "
376 "%p: %s\n", applicator
, strerror ( rc
) );
385 * Reprioritise settings
387 * @v settings Settings block
389 * Reorders the settings block amongst its siblings according to its
392 static void reprioritise_settings ( struct settings
*settings
) {
393 struct settings
*parent
= settings
->parent
;
395 struct settings
*tmp
;
398 /* Stop when we reach the top of the tree */
402 /* Read priority, if present */
403 priority
= fetch_intz_setting ( settings
, &priority_setting
);
405 /* Remove from siblings list */
406 list_del ( &settings
->siblings
);
408 /* Reinsert after any existing blocks which have a higher priority */
409 list_for_each_entry ( tmp
, &parent
->children
, siblings
) {
410 tmp_priority
= fetch_intz_setting ( tmp
, &priority_setting
);
411 if ( priority
> tmp_priority
)
414 list_add_tail ( &settings
->siblings
, &tmp
->siblings
);
416 /* Recurse up the tree */
417 reprioritise_settings ( parent
);
421 * Register settings block
423 * @v settings Settings block
424 * @v parent Parent settings block, or NULL
425 * @ret rc Return status code
427 int register_settings ( struct settings
*settings
, struct settings
*parent
) {
428 struct settings
*old_settings
;
430 /* NULL parent => add to settings root */
431 assert ( settings
!= NULL
);
432 if ( parent
== NULL
)
433 parent
= &settings_root
;
435 /* Remove any existing settings with the same name */
436 if ( ( old_settings
= find_child_settings ( parent
, settings
->name
) ))
437 unregister_settings ( old_settings
);
439 /* Add to list of settings */
440 ref_get ( settings
->refcnt
);
441 ref_get ( parent
->refcnt
);
442 settings
->parent
= parent
;
443 list_add_tail ( &settings
->siblings
, &parent
->children
);
444 DBGC ( settings
, "Settings %p (\"%s\") registered\n",
445 settings
, settings_name ( settings
) );
447 /* Fix up settings priority */
448 reprioritise_settings ( settings
);
450 /* Apply potentially-updated settings */
457 * Unregister settings block
459 * @v settings Settings block
461 void unregister_settings ( struct settings
*settings
) {
462 struct settings
*child
;
463 struct settings
*tmp
;
465 /* Unregister child settings */
466 list_for_each_entry_safe ( child
, tmp
, &settings
->children
, siblings
) {
467 unregister_settings ( child
);
470 DBGC ( settings
, "Settings %p (\"%s\") unregistered\n",
471 settings
, settings_name ( settings
) );
473 /* Remove from list of settings */
474 ref_put ( settings
->parent
->refcnt
);
475 settings
->parent
= NULL
;
476 list_del ( &settings
->siblings
);
477 ref_put ( settings
->refcnt
);
479 /* Apply potentially-updated settings */
483 /******************************************************************************
485 * Core settings routines
487 ******************************************************************************
491 * Store value of setting
493 * @v settings Settings block, or NULL
494 * @v setting Setting to store
495 * @v data Setting data, or NULL to clear setting
496 * @v len Length of setting data
497 * @ret rc Return status code
499 int store_setting ( struct settings
*settings
, struct setting
*setting
,
500 const void *data
, size_t len
) {
503 /* NULL settings implies storing into the global settings root */
505 settings
= &settings_root
;
508 if ( ! settings
->op
->store
)
512 if ( ( rc
= settings
->op
->store ( settings
, setting
,
516 /* Reprioritise settings if necessary */
517 if ( setting_cmp ( setting
, &priority_setting
) == 0 )
518 reprioritise_settings ( settings
);
520 /* If these settings are registered, apply potentially-updated
523 for ( ; settings
; settings
= settings
->parent
) {
524 if ( settings
== &settings_root
) {
525 if ( ( rc
= apply_settings() ) != 0 )
535 * Fetch value of setting
537 * @v settings Settings block, or NULL to search all blocks
538 * @v setting Setting to fetch
539 * @v data Buffer to fill with setting data
540 * @v len Length of buffer
541 * @ret len Length of setting data, or negative error
543 * The actual length of the setting will be returned even if
544 * the buffer was too small.
546 int fetch_setting ( struct settings
*settings
, struct setting
*setting
,
547 void *data
, size_t len
) {
548 struct settings
*child
;
551 /* Avoid returning uninitialised data on error */
552 memset ( data
, 0, len
);
554 /* NULL settings implies starting at the global settings root */
556 settings
= &settings_root
;
559 if ( ! settings
->op
->fetch
)
562 /* Try this block first */
563 if ( ( ret
= settings
->op
->fetch ( settings
, setting
,
567 /* Recurse into each child block in turn */
568 list_for_each_entry ( child
, &settings
->children
, siblings
) {
569 if ( ( ret
= fetch_setting ( child
, setting
,
578 * Fetch length of setting
580 * @v settings Settings block, or NULL to search all blocks
581 * @v setting Setting to fetch
582 * @ret len Length of setting data, or negative error
584 * This function can also be used as an existence check for the
587 int fetch_setting_len ( struct settings
*settings
, struct setting
*setting
) {
588 return fetch_setting ( settings
, setting
, NULL
, 0 );
592 * Fetch value of string setting
594 * @v settings Settings block, or NULL to search all blocks
595 * @v setting Setting to fetch
596 * @v data Buffer to fill with setting string data
597 * @v len Length of buffer
598 * @ret len Length of string setting, or negative error
600 * The resulting string is guaranteed to be correctly NUL-terminated.
601 * The returned length will be the length of the underlying setting
604 int fetch_string_setting ( struct settings
*settings
, struct setting
*setting
,
605 char *data
, size_t len
) {
606 memset ( data
, 0, len
);
607 return fetch_setting ( settings
, setting
, data
,
608 ( ( len
> 0 ) ? ( len
- 1 ) : 0 ) );
612 * Fetch value of string setting
614 * @v settings Settings block, or NULL to search all blocks
615 * @v setting Setting to fetch
616 * @v data Buffer to allocate and fill with setting string data
617 * @ret len Length of string setting, or negative error
619 * The resulting string is guaranteed to be correctly NUL-terminated.
620 * The returned length will be the length of the underlying setting
621 * data. The caller is responsible for eventually freeing the
624 int fetch_string_setting_copy ( struct settings
*settings
,
625 struct setting
*setting
,
630 len
= fetch_setting_len ( settings
, setting
);
634 *data
= malloc ( len
+ 1 );
638 check_len
= fetch_string_setting ( settings
, setting
, *data
,
640 assert ( check_len
== len
);
645 * Fetch value of IPv4 address setting
647 * @v settings Settings block, or NULL to search all blocks
648 * @v setting Setting to fetch
649 * @v inp IPv4 address to fill in
650 * @ret len Length of setting, or negative error
652 int fetch_ipv4_setting ( struct settings
*settings
, struct setting
*setting
,
653 struct in_addr
*inp
) {
656 len
= fetch_setting ( settings
, setting
, inp
, sizeof ( *inp
) );
659 if ( len
< ( int ) sizeof ( *inp
) )
665 * Fetch value of signed integer setting
667 * @v settings Settings block, or NULL to search all blocks
668 * @v setting Setting to fetch
669 * @v value Integer value to fill in
670 * @ret len Length of setting, or negative error
672 int fetch_int_setting ( struct settings
*settings
, struct setting
*setting
,
675 uint8_t u8
[ sizeof ( long ) ];
676 int8_t s8
[ sizeof ( long ) ];
681 /* Avoid returning uninitialised data on error */
684 /* Fetch raw (network-ordered, variable-length) setting */
685 len
= fetch_setting ( settings
, setting
, &buf
, sizeof ( buf
) );
688 if ( len
> ( int ) sizeof ( buf
) )
691 /* Convert to host-ordered signed long */
692 *value
= ( ( buf
.s8
[0] >= 0 ) ? 0 : -1L );
693 for ( i
= 0 ; i
< len
; i
++ ) {
694 *value
= ( ( *value
<< 8 ) | buf
.u8
[i
] );
701 * Fetch value of unsigned integer setting
703 * @v settings Settings block, or NULL to search all blocks
704 * @v setting Setting to fetch
705 * @v value Integer value to fill in
706 * @ret len Length of setting, or negative error
708 int fetch_uint_setting ( struct settings
*settings
, struct setting
*setting
,
709 unsigned long *value
) {
713 /* Avoid returning uninitialised data on error */
716 /* Fetch as a signed long */
717 len
= fetch_int_setting ( settings
, setting
, &svalue
);
721 /* Mask off sign-extended bits */
722 assert ( len
<= ( int ) sizeof ( long ) );
723 *value
= ( svalue
& ( -1UL >> ( 8 * ( sizeof ( long ) - len
) ) ) );
729 * Fetch value of signed integer setting, or zero
731 * @v settings Settings block, or NULL to search all blocks
732 * @v setting Setting to fetch
733 * @ret value Setting value, or zero
735 long fetch_intz_setting ( struct settings
*settings
, struct setting
*setting
){
738 fetch_int_setting ( settings
, setting
, &value
);
743 * Fetch value of unsigned integer setting, or zero
745 * @v settings Settings block, or NULL to search all blocks
746 * @v setting Setting to fetch
747 * @ret value Setting value, or zero
749 unsigned long fetch_uintz_setting ( struct settings
*settings
,
750 struct setting
*setting
) {
753 fetch_uint_setting ( settings
, setting
, &value
);
758 * Fetch value of UUID setting
760 * @v settings Settings block, or NULL to search all blocks
761 * @v setting Setting to fetch
762 * @v uuid UUID to fill in
763 * @ret len Length of setting, or negative error
765 int fetch_uuid_setting ( struct settings
*settings
, struct setting
*setting
,
769 len
= fetch_setting ( settings
, setting
, uuid
, sizeof ( *uuid
) );
772 if ( len
!= sizeof ( *uuid
) )
778 * Clear settings block
780 * @v settings Settings block
782 void clear_settings ( struct settings
*settings
) {
783 if ( settings
->op
->clear
)
784 settings
->op
->clear ( settings
);
788 * Compare two settings
790 * @v a Setting to compare
791 * @v b Setting to compare
792 * @ret 0 Settings are the same
793 * @ret non-zero Settings are not the same
795 int setting_cmp ( struct setting
*a
, struct setting
*b
) {
797 /* If the settings have tags, compare them */
798 if ( a
->tag
&& ( a
->tag
== b
->tag
) )
801 /* Otherwise, if the settings have names, compare them */
802 if ( a
->name
&& b
->name
&& a
->name
[0] )
803 return strcmp ( a
->name
, b
->name
);
805 /* Otherwise, return a non-match */
809 /******************************************************************************
811 * Formatted setting routines
813 ******************************************************************************
817 * Store value of typed setting
819 * @v settings Settings block
820 * @v setting Setting to store
821 * @v type Settings type
822 * @v value Formatted setting data, or NULL
823 * @ret rc Return status code
825 int storef_setting ( struct settings
*settings
, struct setting
*setting
,
826 const char *value
) {
828 /* NULL value implies deletion. Avoid imposing the burden of
829 * checking for NULL values on each typed setting's storef()
833 return delete_setting ( settings
, setting
);
835 return setting
->type
->storef ( settings
, setting
, value
);
842 * @ret setting Named setting, or NULL
844 static struct setting
* find_setting ( const char *name
) {
845 struct setting
*setting
;
847 for_each_table_entry ( setting
, SETTINGS
) {
848 if ( strcmp ( name
, setting
->name
) == 0 )
855 * Parse setting name as tag number
858 * @ret tag Tag number, or 0 if not a valid number
860 static unsigned int parse_setting_tag ( const char *name
) {
861 char *tmp
= ( ( char * ) name
);
862 unsigned int tag
= 0;
865 tag
= ( ( tag
<< 8 ) | strtoul ( tmp
, &tmp
, 0 ) );
878 * @ret type Setting type, or NULL
880 static struct setting_type
* find_setting_type ( const char *name
) {
881 struct setting_type
*type
;
883 for_each_table_entry ( type
, SETTING_TYPES
) {
884 if ( strcmp ( name
, type
->name
) == 0 )
893 * @v name Name of setting
894 * @v get_child Function to find or create child settings block
895 * @v settings Settings block to fill in
896 * @v setting Setting to fill in
897 * @v tmp_name Buffer for copy of setting name
898 * @ret rc Return status code
900 * Interprets a name of the form
901 * "[settings_name/]tag_name[:type_name]" and fills in the appropriate
904 * The @c tmp_name buffer must be large enough to hold a copy of the
908 parse_setting_name ( const char *name
,
909 struct settings
* ( * get_child
) ( struct settings
*,
911 struct settings
**settings
, struct setting
*setting
,
916 struct setting
*named_setting
;
919 *settings
= &settings_root
;
920 memset ( setting
, 0, sizeof ( *setting
) );
922 setting
->type
= &setting_type_string
;
924 /* Split name into "[settings_name/]setting_name[:type_name]" */
925 strcpy ( tmp_name
, name
);
926 if ( ( setting_name
= strchr ( tmp_name
, '/' ) ) != NULL
) {
927 *(setting_name
++) = 0;
928 settings_name
= tmp_name
;
930 setting_name
= tmp_name
;
931 settings_name
= NULL
;
933 if ( ( type_name
= strchr ( setting_name
, ':' ) ) != NULL
)
936 /* Identify settings block, if specified */
937 if ( settings_name
) {
938 *settings
= parse_settings_name ( settings_name
, get_child
);
939 if ( *settings
== NULL
) {
940 DBG ( "Unrecognised settings block \"%s\" in \"%s\"\n",
941 settings_name
, name
);
946 /* Identify setting */
947 if ( ( named_setting
= find_setting ( setting_name
) ) != NULL
) {
948 /* Matches a defined named setting; use that setting */
949 memcpy ( setting
, named_setting
, sizeof ( *setting
) );
950 } else if ( ( setting
->tag
= parse_setting_tag ( setting_name
) ) !=0){
951 /* Is a valid numeric tag; use the tag */
952 setting
->tag
|= (*settings
)->tag_magic
;
954 /* Use the arbitrary name */
955 setting
->name
= setting_name
;
958 /* Identify setting type, if specified */
960 setting
->type
= find_setting_type ( type_name
);
961 if ( setting
->type
== NULL
) {
962 DBG ( "Invalid setting type \"%s\" in \"%s\"\n",
972 * Parse and store value of named setting
974 * @v name Name of setting
975 * @v value Formatted setting data, or NULL
976 * @ret rc Return status code
978 int storef_named_setting ( const char *name
, const char *value
) {
979 struct settings
*settings
;
980 struct setting setting
;
981 char tmp_name
[ strlen ( name
) + 1 ];
984 if ( ( rc
= parse_setting_name ( name
, autovivify_child_settings
,
985 &settings
, &setting
, tmp_name
)) != 0)
987 return storef_setting ( settings
, &setting
, value
);
991 * Fetch and format value of named setting
993 * @v name Name of setting
994 * @v buf Buffer to contain formatted value
995 * @v len Length of buffer
996 * @ret len Length of formatted value, or negative error
998 int fetchf_named_setting ( const char *name
, char *buf
, size_t len
) {
999 struct settings
*settings
;
1000 struct setting setting
;
1001 char tmp_name
[ strlen ( name
) + 1 ];
1004 if ( ( rc
= parse_setting_name ( name
, find_child_settings
,
1005 &settings
, &setting
, tmp_name
)) != 0)
1007 return fetchf_setting ( settings
, &setting
, buf
, len
);
1010 /******************************************************************************
1014 ******************************************************************************
1018 * Parse and store value of string setting
1020 * @v settings Settings block
1021 * @v setting Setting to store
1022 * @v value Formatted setting data
1023 * @ret rc Return status code
1025 static int storef_string ( struct settings
*settings
, struct setting
*setting
,
1026 const char *value
) {
1027 return store_setting ( settings
, setting
, value
, strlen ( value
) );
1031 * Fetch and format value of string setting
1033 * @v settings Settings block, or NULL to search all blocks
1034 * @v setting Setting to fetch
1035 * @v buf Buffer to contain formatted value
1036 * @v len Length of buffer
1037 * @ret len Length of formatted value, or negative error
1039 static int fetchf_string ( struct settings
*settings
, struct setting
*setting
,
1040 char *buf
, size_t len
) {
1041 return fetch_string_setting ( settings
, setting
, buf
, len
);
1044 /** A string setting type */
1045 struct setting_type setting_type_string __setting_type
= {
1047 .storef
= storef_string
,
1048 .fetchf
= fetchf_string
,
1052 * Parse and store value of URI-encoded string setting
1054 * @v settings Settings block
1055 * @v setting Setting to store
1056 * @v value Formatted setting data
1057 * @ret rc Return status code
1059 static int storef_uristring ( struct settings
*settings
,
1060 struct setting
*setting
,
1061 const char *value
) {
1062 char buf
[ strlen ( value
) + 1 ]; /* Decoding never expands string */
1065 len
= uri_decode ( value
, buf
, sizeof ( buf
) );
1066 return store_setting ( settings
, setting
, buf
, len
);
1070 * Fetch and format value of URI-encoded string setting
1072 * @v settings Settings block, or NULL to search all blocks
1073 * @v setting Setting to fetch
1074 * @v buf Buffer to contain formatted value
1075 * @v len Length of buffer
1076 * @ret len Length of formatted value, or negative error
1078 static int fetchf_uristring ( struct settings
*settings
,
1079 struct setting
*setting
,
1080 char *buf
, size_t len
) {
1083 /* We need to always retrieve the full raw string to know the
1084 * length of the encoded string.
1086 raw_len
= fetch_setting ( settings
, setting
, NULL
, 0 );
1091 char raw_buf
[ raw_len
+ 1 ];
1093 fetch_string_setting ( settings
, setting
, raw_buf
,
1094 sizeof ( raw_buf
) );
1095 return uri_encode ( raw_buf
, buf
, len
, URI_FRAGMENT
);
1099 /** A URI-encoded string setting type */
1100 struct setting_type setting_type_uristring __setting_type
= {
1101 .name
= "uristring",
1102 .storef
= storef_uristring
,
1103 .fetchf
= fetchf_uristring
,
1107 * Parse and store value of IPv4 address setting
1109 * @v settings Settings block
1110 * @v setting Setting to store
1111 * @v value Formatted setting data
1112 * @ret rc Return status code
1114 static int storef_ipv4 ( struct settings
*settings
, struct setting
*setting
,
1115 const char *value
) {
1116 struct in_addr ipv4
;
1118 if ( inet_aton ( value
, &ipv4
) == 0 )
1120 return store_setting ( settings
, setting
, &ipv4
, sizeof ( ipv4
) );
1124 * Fetch and format value of IPv4 address setting
1126 * @v settings Settings block, or NULL to search all blocks
1127 * @v setting Setting to fetch
1128 * @v buf Buffer to contain formatted value
1129 * @v len Length of buffer
1130 * @ret len Length of formatted value, or negative error
1132 static int fetchf_ipv4 ( struct settings
*settings
, struct setting
*setting
,
1133 char *buf
, size_t len
) {
1134 struct in_addr ipv4
;
1137 if ( ( raw_len
= fetch_ipv4_setting ( settings
, setting
, &ipv4
) ) < 0)
1139 return snprintf ( buf
, len
, "%s", inet_ntoa ( ipv4
) );
1142 /** An IPv4 address setting type */
1143 struct setting_type setting_type_ipv4 __setting_type
= {
1145 .storef
= storef_ipv4
,
1146 .fetchf
= fetchf_ipv4
,
1150 * Parse and store value of integer setting
1152 * @v settings Settings block
1153 * @v setting Setting to store
1154 * @v value Formatted setting data
1155 * @v size Integer size, in bytes
1156 * @ret rc Return status code
1158 static int storef_int ( struct settings
*settings
, struct setting
*setting
,
1159 const char *value
, unsigned int size
) {
1166 u
.num
= htonl ( strtoul ( value
, &endp
, 0 ) );
1169 return store_setting ( settings
, setting
,
1170 &u
.bytes
[ sizeof ( u
) - size
], size
);
1174 * Parse and store value of 8-bit integer setting
1176 * @v settings Settings block
1177 * @v setting Setting to store
1178 * @v value Formatted setting data
1179 * @v size Integer size, in bytes
1180 * @ret rc Return status code
1182 static int storef_int8 ( struct settings
*settings
, struct setting
*setting
,
1183 const char *value
) {
1184 return storef_int ( settings
, setting
, value
, 1 );
1188 * Parse and store value of 16-bit integer setting
1190 * @v settings Settings block
1191 * @v setting Setting to store
1192 * @v value Formatted setting data
1193 * @v size Integer size, in bytes
1194 * @ret rc Return status code
1196 static int storef_int16 ( struct settings
*settings
, struct setting
*setting
,
1197 const char *value
) {
1198 return storef_int ( settings
, setting
, value
, 2 );
1202 * Parse and store value of 32-bit integer setting
1204 * @v settings Settings block
1205 * @v setting Setting to store
1206 * @v value Formatted setting data
1207 * @v size Integer size, in bytes
1208 * @ret rc Return status code
1210 static int storef_int32 ( struct settings
*settings
, struct setting
*setting
,
1211 const char *value
) {
1212 return storef_int ( settings
, setting
, value
, 4 );
1216 * Fetch and format value of signed integer setting
1218 * @v settings Settings block, or NULL to search all blocks
1219 * @v setting Setting to fetch
1220 * @v buf Buffer to contain formatted value
1221 * @v len Length of buffer
1222 * @ret len Length of formatted value, or negative error
1224 static int fetchf_int ( struct settings
*settings
, struct setting
*setting
,
1225 char *buf
, size_t len
) {
1229 if ( ( rc
= fetch_int_setting ( settings
, setting
, &value
) ) < 0 )
1231 return snprintf ( buf
, len
, "%ld", value
);
1235 * Fetch and format value of unsigned integer setting
1237 * @v settings Settings block, or NULL to search all blocks
1238 * @v setting Setting to fetch
1239 * @v buf Buffer to contain formatted value
1240 * @v len Length of buffer
1241 * @ret len Length of formatted value, or negative error
1243 static int fetchf_uint ( struct settings
*settings
, struct setting
*setting
,
1244 char *buf
, size_t len
) {
1245 unsigned long value
;
1248 if ( ( rc
= fetch_uint_setting ( settings
, setting
, &value
) ) < 0 )
1250 return snprintf ( buf
, len
, "%#lx", value
);
1253 /** A signed 8-bit integer setting type */
1254 struct setting_type setting_type_int8 __setting_type
= {
1256 .storef
= storef_int8
,
1257 .fetchf
= fetchf_int
,
1260 /** A signed 16-bit integer setting type */
1261 struct setting_type setting_type_int16 __setting_type
= {
1263 .storef
= storef_int16
,
1264 .fetchf
= fetchf_int
,
1267 /** A signed 32-bit integer setting type */
1268 struct setting_type setting_type_int32 __setting_type
= {
1270 .storef
= storef_int32
,
1271 .fetchf
= fetchf_int
,
1274 /** An unsigned 8-bit integer setting type */
1275 struct setting_type setting_type_uint8 __setting_type
= {
1277 .storef
= storef_int8
,
1278 .fetchf
= fetchf_uint
,
1281 /** An unsigned 16-bit integer setting type */
1282 struct setting_type setting_type_uint16 __setting_type
= {
1284 .storef
= storef_int16
,
1285 .fetchf
= fetchf_uint
,
1288 /** An unsigned 32-bit integer setting type */
1289 struct setting_type setting_type_uint32 __setting_type
= {
1291 .storef
= storef_int32
,
1292 .fetchf
= fetchf_uint
,
1296 * Parse and store value of hex string setting
1298 * @v settings Settings block
1299 * @v setting Setting to store
1300 * @v value Formatted setting data
1301 * @ret rc Return status code
1303 static int storef_hex ( struct settings
*settings
, struct setting
*setting
,
1304 const char *value
) {
1305 char *ptr
= ( char * ) value
;
1306 uint8_t bytes
[ strlen ( value
) ]; /* cannot exceed strlen(value) */
1307 unsigned int len
= 0;
1310 bytes
[len
++] = strtoul ( ptr
, &ptr
, 16 );
1313 return store_setting ( settings
, setting
, bytes
, len
);
1324 * Fetch and format value of hex string setting
1326 * @v settings Settings block, or NULL to search all blocks
1327 * @v setting Setting to fetch
1328 * @v buf Buffer to contain formatted value
1329 * @v len Length of buffer
1330 * @ret len Length of formatted value, or negative error
1332 static int fetchf_hex ( struct settings
*settings
, struct setting
*setting
,
1333 char *buf
, size_t len
) {
1339 raw_len
= fetch_setting_len ( settings
, setting
);
1344 uint8_t raw
[raw_len
];
1346 check_len
= fetch_setting ( settings
, setting
, raw
,
1348 if ( check_len
< 0 )
1350 assert ( check_len
== raw_len
);
1353 buf
[0] = 0; /* Ensure that a terminating NUL exists */
1354 for ( i
= 0 ; i
< raw_len
; i
++ ) {
1355 used
+= ssnprintf ( ( buf
+ used
), ( len
- used
),
1356 "%s%02x", ( used
? ":" : "" ),
1363 /** A hex-string setting */
1364 struct setting_type setting_type_hex __setting_type
= {
1366 .storef
= storef_hex
,
1367 .fetchf
= fetchf_hex
,
1371 * Parse and store value of UUID setting
1373 * @v settings Settings block
1374 * @v setting Setting to store
1375 * @v value Formatted setting data
1376 * @ret rc Return status code
1378 static int storef_uuid ( struct settings
*settings __unused
,
1379 struct setting
*setting __unused
,
1380 const char *value __unused
) {
1385 * Fetch and format value of UUID setting
1387 * @v settings Settings block, or NULL to search all blocks
1388 * @v setting Setting to fetch
1389 * @v buf Buffer to contain formatted value
1390 * @v len Length of buffer
1391 * @ret len Length of formatted value, or negative error
1393 static int fetchf_uuid ( struct settings
*settings
, struct setting
*setting
,
1394 char *buf
, size_t len
) {
1398 if ( ( raw_len
= fetch_uuid_setting ( settings
, setting
, &uuid
) ) < 0)
1400 return snprintf ( buf
, len
, "%s", uuid_ntoa ( &uuid
) );
1403 /** UUID setting type */
1404 struct setting_type setting_type_uuid __setting_type
= {
1406 .storef
= storef_uuid
,
1407 .fetchf
= fetchf_uuid
,
1410 /******************************************************************************
1414 ******************************************************************************
1417 /** Hostname setting */
1418 struct setting hostname_setting __setting
= {
1420 .description
= "Host name",
1421 .tag
= DHCP_HOST_NAME
,
1422 .type
= &setting_type_string
,
1425 /** Filename setting */
1426 struct setting filename_setting __setting
= {
1428 .description
= "Boot filename",
1429 .tag
= DHCP_BOOTFILE_NAME
,
1430 .type
= &setting_type_string
,
1433 /** Root path setting */
1434 struct setting root_path_setting __setting
= {
1435 .name
= "root-path",
1436 .description
= "iSCSI root path",
1437 .tag
= DHCP_ROOT_PATH
,
1438 .type
= &setting_type_string
,
1441 /** Username setting */
1442 struct setting username_setting __setting
= {
1444 .description
= "User name",
1445 .tag
= DHCP_EB_USERNAME
,
1446 .type
= &setting_type_string
,
1449 /** Password setting */
1450 struct setting password_setting __setting
= {
1452 .description
= "Password",
1453 .tag
= DHCP_EB_PASSWORD
,
1454 .type
= &setting_type_string
,
1457 /** Priority setting */
1458 struct setting priority_setting __setting
= {
1460 .description
= "Priority of these settings",
1461 .tag
= DHCP_EB_PRIORITY
,
1462 .type
= &setting_type_int8
,