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.
28 #include <gpxe/vsprintf.h>
29 #include <gpxe/dhcp.h>
30 #include <gpxe/uuid.h>
31 #include <gpxe/settings.h>
35 * Configuration settings
39 /** Registered settings */
40 static struct setting settings
[0]
41 __table_start ( struct setting
, settings
);
42 static struct setting settings_end
[0]
43 __table_end ( struct setting
, settings
);
45 /** Registered setting types */
46 static struct setting_type setting_types
[0]
47 __table_start ( struct setting_type
, setting_types
);
48 static struct setting_type setting_types_end
[0]
49 __table_end ( struct setting_type
, setting_types
);
51 /** Registered settings applicators */
52 static struct settings_applicator settings_applicators
[0]
53 __table_start ( struct settings_applicator
, settings_applicators
);
54 static struct settings_applicator settings_applicators_end
[0]
55 __table_end ( struct settings_applicator
, settings_applicators
);
57 /******************************************************************************
59 * Registered settings blocks
61 ******************************************************************************
65 * Store value of simple setting
67 * @v options DHCP option block
68 * @v setting Setting to store
69 * @v data Setting data, or NULL to clear setting
70 * @v len Length of setting data
71 * @ret rc Return status code
73 int simple_settings_store ( struct settings
*settings
, struct setting
*setting
,
74 const void *data
, size_t len
) {
75 struct simple_settings
*simple
=
76 container_of ( settings
, struct simple_settings
, settings
);
77 return dhcpopt_extensible_store ( &simple
->dhcpopts
, setting
->tag
,
82 * Fetch value of simple setting
84 * @v options DHCP option block
85 * @v setting Setting to fetch
86 * @v data Buffer to fill with setting data
87 * @v len Length of buffer
88 * @ret len Length of setting data, or negative error
90 int simple_settings_fetch ( struct settings
*settings
, struct setting
*setting
,
91 void *data
, size_t len
) {
92 struct simple_settings
*simple
=
93 container_of ( settings
, struct simple_settings
, settings
);
94 return dhcpopt_fetch ( &simple
->dhcpopts
, setting
->tag
, data
, len
);
97 /** Simple settings operations */
98 struct settings_operations simple_settings_operations
= {
99 .store
= simple_settings_store
,
100 .fetch
= simple_settings_fetch
,
103 /** Root simple settings block */
104 struct simple_settings simple_settings_root
= {
109 LIST_HEAD_INIT ( simple_settings_root
.settings
.siblings
),
111 LIST_HEAD_INIT ( simple_settings_root
.settings
.children
),
112 .op
= &simple_settings_operations
,
116 /** Root settings block */
117 #define settings_root simple_settings_root.settings
122 * @ret rc Return status code
124 static int apply_settings ( void ) {
125 struct settings_applicator
*applicator
;
128 /* Call all settings applicators */
129 for ( applicator
= settings_applicators
;
130 applicator
< settings_applicators_end
; applicator
++ ) {
131 if ( ( rc
= applicator
->apply() ) != 0 ) {
132 DBG ( "Could not apply settings using applicator "
133 "%p: %s\n", applicator
, strerror ( rc
) );
142 * Reprioritise settings
144 * @v settings Settings block
146 * Reorders the settings block amongst its siblings according to its
149 static void reprioritise_settings ( struct settings
*settings
) {
150 struct settings
*parent
= settings
->parent
;
152 struct settings
*tmp
;
155 /* Stop when we reach the top of the tree */
159 /* Read priority, if present */
160 priority
= fetch_intz_setting ( settings
, &priority_setting
);
162 /* Remove from siblings list */
163 list_del ( &settings
->siblings
);
165 /* Reinsert after any existing blocks which have a higher priority */
166 list_for_each_entry ( tmp
, &parent
->children
, siblings
) {
167 tmp_priority
= fetch_intz_setting ( tmp
, &priority_setting
);
168 if ( priority
> tmp_priority
)
171 list_add_tail ( &settings
->siblings
, &tmp
->siblings
);
173 /* Recurse up the tree */
174 reprioritise_settings ( parent
);
178 * Register settings block
180 * @v settings Settings block
181 * @v parent Parent settings block, or NULL
182 * @ret rc Return status code
184 int register_settings ( struct settings
*settings
, struct settings
*parent
) {
186 /* NULL parent => add to settings root */
187 assert ( settings
!= NULL
);
188 if ( parent
== NULL
)
189 parent
= &settings_root
;
191 /* Add to list of settings */
192 ref_get ( settings
->refcnt
);
193 ref_get ( parent
->refcnt
);
194 settings
->parent
= parent
;
195 list_add_tail ( &settings
->siblings
, &parent
->children
);
196 DBGC ( settings
, "Settings %p registered\n", settings
);
198 /* Fix up settings priority */
199 reprioritise_settings ( settings
);
201 /* Apply potentially-updated settings */
208 * Unregister settings block
210 * @v settings Settings block
212 void unregister_settings ( struct settings
*settings
) {
214 /* Remove from list of settings */
215 ref_put ( settings
->refcnt
);
216 ref_put ( settings
->parent
->refcnt
);
217 settings
->parent
= NULL
;
218 list_del ( &settings
->siblings
);
219 DBGC ( settings
, "Settings %p unregistered\n", settings
);
221 /* Apply potentially-updated settings */
226 * Find child named settings block
228 * @v parent Parent settings block
229 * @v name Name within this parent
230 * @ret settings Settings block, or NULL
232 struct settings
* find_child_settings ( struct settings
*parent
,
234 struct settings
*settings
;
237 /* NULL parent => add to settings root */
238 if ( parent
== NULL
)
239 parent
= &settings_root
;
241 /* Look for a child whose name matches the initial component */
242 list_for_each_entry ( settings
, &parent
->children
, siblings
) {
243 len
= strlen ( settings
->name
);
244 if ( strncmp ( name
, settings
->name
, len
) != 0 )
246 if ( name
[len
] == 0 )
248 if ( name
[len
] == '.' )
249 return find_child_settings ( settings
,
250 ( name
+ len
+ 1 ) );
257 * Find named settings block
260 * @ret settings Settings block, or NULL
262 struct settings
* find_settings ( const char *name
) {
264 /* If name is empty, use the root */
266 return &settings_root
;
268 return find_child_settings ( &settings_root
, name
);
271 /******************************************************************************
273 * Core settings routines
275 ******************************************************************************
279 * Store value of setting
281 * @v settings Settings block
282 * @v setting Setting to store
283 * @v data Setting data, or NULL to clear setting
284 * @v len Length of setting data
285 * @ret rc Return status code
287 int store_setting ( struct settings
*settings
, struct setting
*setting
,
288 const void *data
, size_t len
) {
296 if ( ( rc
= settings
->op
->store ( settings
, setting
,
300 /* Reprioritise settings if necessary */
301 if ( setting_cmp ( setting
, &priority_setting
) == 0 )
302 reprioritise_settings ( settings
);
304 /* If these settings are registered, apply potentially-updated
307 for ( ; settings
; settings
= settings
->parent
) {
308 if ( settings
== &settings_root
) {
309 if ( ( rc
= apply_settings() ) != 0 )
319 * Fetch value of setting
321 * @v settings Settings block, or NULL to search all blocks
322 * @v setting Setting to fetch
323 * @v data Buffer to fill with setting data
324 * @v len Length of buffer
325 * @ret len Length of setting data, or negative error
327 * The actual length of the setting will be returned even if
328 * the buffer was too small.
330 int fetch_setting ( struct settings
*settings
, struct setting
*setting
,
331 void *data
, size_t len
) {
332 struct settings
*child
;
335 /* NULL settings implies starting at the global settings root */
337 settings
= &settings_root
;
339 /* Try this block first */
340 if ( ( ret
= settings
->op
->fetch ( settings
, setting
,
344 /* Recurse into each child block in turn */
345 list_for_each_entry ( child
, &settings
->children
, siblings
) {
346 if ( ( ret
= fetch_setting ( child
, setting
,
355 * Fetch length of setting
357 * @v settings Settings block, or NULL to search all blocks
358 * @v setting Setting to fetch
359 * @ret len Length of setting data, or negative error
361 * This function can also be used as an existence check for the
364 int fetch_setting_len ( struct settings
*settings
, struct setting
*setting
) {
365 return fetch_setting ( settings
, setting
, NULL
, 0 );
369 * Fetch value of string setting
371 * @v settings Settings block, or NULL to search all blocks
372 * @v setting Setting to fetch
373 * @v data Buffer to fill with setting string data
374 * @v len Length of buffer
375 * @ret len Length of string setting, or negative error
377 * The resulting string is guaranteed to be correctly NUL-terminated.
378 * The returned length will be the length of the underlying setting
381 int fetch_string_setting ( struct settings
*settings
, struct setting
*setting
,
382 char *data
, size_t len
) {
383 memset ( data
, 0, len
);
384 return fetch_setting ( settings
, setting
, data
, ( len
- 1 ) );
388 * Fetch value of IPv4 address setting
390 * @v settings Settings block, or NULL to search all blocks
391 * @v setting Setting to fetch
392 * @v inp IPv4 address to fill in
393 * @ret len Length of setting, or negative error
395 int fetch_ipv4_setting ( struct settings
*settings
, struct setting
*setting
,
396 struct in_addr
*inp
) {
399 len
= fetch_setting ( settings
, setting
, inp
, sizeof ( *inp
) );
402 if ( len
< ( int ) sizeof ( *inp
) )
408 * Fetch value of signed integer setting
410 * @v settings Settings block, or NULL to search all blocks
411 * @v setting Setting to fetch
412 * @v value Integer value to fill in
413 * @ret len Length of setting, or negative error
415 int fetch_int_setting ( struct settings
*settings
, struct setting
*setting
,
419 uint8_t u8
[ sizeof ( long ) ];
420 int8_t s8
[ sizeof ( long ) ];
426 len
= fetch_setting ( settings
, setting
, &buf
, sizeof ( buf
) );
429 if ( len
> ( int ) sizeof ( buf
) )
432 *value
= ( ( buf
.s8
[0] >= 0 ) ? 0 : -1L );
433 for ( i
= 0 ; i
< len
; i
++ ) {
434 *value
= ( ( *value
<< 8 ) | buf
.u8
[i
] );
441 * Fetch value of unsigned integer setting
443 * @v settings Settings block, or NULL to search all blocks
444 * @v setting Setting to fetch
445 * @v value Integer value to fill in
446 * @ret len Length of setting, or negative error
448 int fetch_uint_setting ( struct settings
*settings
, struct setting
*setting
,
449 unsigned long *value
) {
453 len
= fetch_int_setting ( settings
, setting
, &svalue
);
457 *value
= ( svalue
& ( -1UL >> ( sizeof ( long ) - len
) ) );
463 * Fetch value of signed integer setting, or zero
465 * @v settings Settings block, or NULL to search all blocks
466 * @v setting Setting to fetch
467 * @ret value Setting value, or zero
469 long fetch_intz_setting ( struct settings
*settings
, struct setting
*setting
){
472 fetch_int_setting ( settings
, setting
, &value
);
477 * Fetch value of unsigned integer setting, or zero
479 * @v settings Settings block, or NULL to search all blocks
480 * @v setting Setting to fetch
481 * @ret value Setting value, or zero
483 unsigned long fetch_uintz_setting ( struct settings
*settings
,
484 struct setting
*setting
) {
485 unsigned long value
= 0;
487 fetch_uint_setting ( settings
, setting
, &value
);
492 * Fetch value of UUID setting
494 * @v settings Settings block, or NULL to search all blocks
495 * @v setting Setting to fetch
496 * @v uuid UUID to fill in
497 * @ret len Length of setting, or negative error
499 int fetch_uuid_setting ( struct settings
*settings
, struct setting
*setting
,
503 len
= fetch_setting ( settings
, setting
, uuid
, sizeof ( *uuid
) );
506 if ( len
!= sizeof ( *uuid
) )
512 * Compare two settings
514 * @v a Setting to compare
515 * @v b Setting to compare
516 * @ret 0 Settings are the same
517 * @ret non-zero Settings are not the same
519 int setting_cmp ( struct setting
*a
, struct setting
*b
) {
521 /* If the settings have tags, compare them */
522 if ( a
->tag
&& ( a
->tag
== b
->tag
) )
525 /* Otherwise, compare the names */
526 return strcmp ( a
->name
, b
->name
);
529 /******************************************************************************
531 * Formatted setting routines
533 ******************************************************************************
537 * Store value of typed setting
539 * @v settings Settings block
540 * @v setting Setting to store
541 * @v type Settings type
542 * @v value Formatted setting data, or NULL
543 * @ret rc Return status code
545 int storef_setting ( struct settings
*settings
, struct setting
*setting
,
546 const char *value
) {
548 /* NULL value implies deletion. Avoid imposing the burden of
549 * checking for NULL values on each typed setting's storef()
553 return delete_setting ( settings
, setting
);
555 return setting
->type
->storef ( settings
, setting
, value
);
562 * @ret setting Named setting, or NULL
564 static struct setting
* find_setting ( const char *name
) {
565 struct setting
*setting
;
567 for ( setting
= settings
; setting
< settings_end
; setting
++ ) {
568 if ( strcmp ( name
, setting
->name
) == 0 )
578 * @ret type Setting type, or NULL
580 static struct setting_type
* find_setting_type ( const char *name
) {
581 struct setting_type
*type
;
583 for ( type
= setting_types
; type
< setting_types_end
; type
++ ) {
584 if ( strcmp ( name
, type
->name
) == 0 )
593 * @v name Name of setting
594 * @v settings Settings block to fill in
595 * @v setting Setting to fill in
596 * @ret rc Return status code
598 * Interprets a name of the form
599 * "[settings_name/]tag_name[:type_name]" and fills in the appropriate
602 static int parse_setting_name ( const char *name
, struct settings
**settings
,
603 struct setting
*setting
) {
604 char tmp_name
[ strlen ( name
) + 1 ];
608 struct setting
*named_setting
;
612 *settings
= &settings_root
;
613 memset ( setting
, 0, sizeof ( *setting
) );
614 setting
->type
= &setting_type_hex
;
616 /* Split name into "[settings_name/]setting_name[:type_name]" */
617 memcpy ( tmp_name
, name
, sizeof ( tmp_name
) );
618 if ( ( setting_name
= strchr ( tmp_name
, '/' ) ) != NULL
) {
619 *(setting_name
++) = 0;
620 settings_name
= tmp_name
;
622 setting_name
= tmp_name
;
623 settings_name
= NULL
;
625 if ( ( type_name
= strchr ( setting_name
, ':' ) ) != NULL
)
628 /* Identify settings block, if specified */
629 if ( settings_name
) {
630 *settings
= find_settings ( settings_name
);
631 if ( *settings
== NULL
) {
632 DBG ( "Unrecognised settings block \"%s\" in \"%s\"\n",
633 settings_name
, name
);
638 /* Identify tag number */
639 if ( ( named_setting
= find_setting ( setting_name
) ) != NULL
) {
640 memcpy ( setting
, named_setting
, sizeof ( *setting
) );
642 /* Unrecognised name: try to interpret as a tag number */
645 setting
->tag
= ( ( setting
->tag
<< 8 ) |
646 strtoul ( tmp
, &tmp
, 0 ) );
650 DBG ( "Invalid setting \"%s\" in \"%s\"\n",
651 setting_name
, name
);
658 /* Identify setting type, if specified */
660 setting
->type
= find_setting_type ( type_name
);
661 if ( setting
->type
== NULL
) {
662 DBG ( "Invalid setting type \"%s\" in \"%s\"\n",
672 * Parse and store value of named setting
674 * @v name Name of setting
675 * @v value Formatted setting data, or NULL
676 * @ret rc Return status code
678 int storef_named_setting ( const char *name
, const char *value
) {
679 struct settings
*settings
;
680 struct setting setting
;
683 if ( ( rc
= parse_setting_name ( name
, &settings
, &setting
) ) != 0 )
685 return storef_setting ( settings
, &setting
, value
);
689 * Fetch and format value of named setting
691 * @v name Name of setting
692 * @v buf Buffer to contain formatted value
693 * @v len Length of buffer
694 * @ret len Length of formatted value, or negative error
696 int fetchf_named_setting ( const char *name
, char *buf
, size_t len
) {
697 struct settings
*settings
;
698 struct setting setting
;
701 if ( ( rc
= parse_setting_name ( name
, &settings
, &setting
) ) != 0 )
703 return fetchf_setting ( settings
, &setting
, buf
, len
);
706 /******************************************************************************
710 ******************************************************************************
714 * Parse and store value of string setting
716 * @v settings Settings block
717 * @v setting Setting to store
718 * @v value Formatted setting data
719 * @ret rc Return status code
721 static int storef_string ( struct settings
*settings
, struct setting
*setting
,
722 const char *value
) {
723 return store_setting ( settings
, setting
, value
, strlen ( value
) );
727 * Fetch and format value of string setting
729 * @v settings Settings block, or NULL to search all blocks
730 * @v setting Setting to fetch
731 * @v buf Buffer to contain formatted value
732 * @v len Length of buffer
733 * @ret len Length of formatted value, or negative error
735 static int fetchf_string ( struct settings
*settings
, struct setting
*setting
,
736 char *buf
, size_t len
) {
737 return fetch_string_setting ( settings
, setting
, buf
, len
);
740 /** A string setting type */
741 struct setting_type setting_type_string __setting_type
= {
743 .storef
= storef_string
,
744 .fetchf
= fetchf_string
,
748 * Parse and store value of IPv4 address setting
750 * @v settings Settings block
751 * @v setting Setting to store
752 * @v value Formatted setting data
753 * @ret rc Return status code
755 static int storef_ipv4 ( struct settings
*settings
, struct setting
*setting
,
756 const char *value
) {
759 if ( inet_aton ( value
, &ipv4
) == 0 )
761 return store_setting ( settings
, setting
, &ipv4
, sizeof ( ipv4
) );
765 * Fetch and format value of IPv4 address setting
767 * @v settings Settings block, or NULL to search all blocks
768 * @v setting Setting to fetch
769 * @v buf Buffer to contain formatted value
770 * @v len Length of buffer
771 * @ret len Length of formatted value, or negative error
773 static int fetchf_ipv4 ( struct settings
*settings
, struct setting
*setting
,
774 char *buf
, size_t len
) {
778 if ( ( raw_len
= fetch_ipv4_setting ( settings
, setting
, &ipv4
) ) < 0)
780 return snprintf ( buf
, len
, "%s", inet_ntoa ( ipv4
) );
783 /** An IPv4 address setting type */
784 struct setting_type setting_type_ipv4 __setting_type
= {
786 .storef
= storef_ipv4
,
787 .fetchf
= fetchf_ipv4
,
791 * Parse and store value of integer setting
793 * @v settings Settings block
794 * @v setting Setting to store
795 * @v value Formatted setting data
796 * @v size Integer size, in bytes
797 * @ret rc Return status code
799 static int storef_int ( struct settings
*settings
, struct setting
*setting
,
800 const char *value
, unsigned int size
) {
807 u
.num
= htonl ( strtoul ( value
, &endp
, 0 ) );
810 return store_setting ( settings
, setting
,
811 &u
.bytes
[ sizeof ( u
) - size
], size
);
815 * Parse and store value of 8-bit integer setting
817 * @v settings Settings block
818 * @v setting Setting to store
819 * @v value Formatted setting data
820 * @v size Integer size, in bytes
821 * @ret rc Return status code
823 static int storef_int8 ( struct settings
*settings
, struct setting
*setting
,
824 const char *value
) {
825 return storef_int ( settings
, setting
, value
, 1 );
829 * Parse and store value of 16-bit integer setting
831 * @v settings Settings block
832 * @v setting Setting to store
833 * @v value Formatted setting data
834 * @v size Integer size, in bytes
835 * @ret rc Return status code
837 static int storef_int16 ( struct settings
*settings
, struct setting
*setting
,
838 const char *value
) {
839 return storef_int ( settings
, setting
, value
, 2 );
843 * Parse and store value of 32-bit integer setting
845 * @v settings Settings block
846 * @v setting Setting to store
847 * @v value Formatted setting data
848 * @v size Integer size, in bytes
849 * @ret rc Return status code
851 static int storef_int32 ( struct settings
*settings
, struct setting
*setting
,
852 const char *value
) {
853 return storef_int ( settings
, setting
, value
, 4 );
857 * Fetch and format value of signed integer setting
859 * @v settings Settings block, or NULL to search all blocks
860 * @v setting Setting to fetch
861 * @v buf Buffer to contain formatted value
862 * @v len Length of buffer
863 * @ret len Length of formatted value, or negative error
865 static int fetchf_int ( struct settings
*settings
, struct setting
*setting
,
866 char *buf
, size_t len
) {
870 if ( ( rc
= fetch_int_setting ( settings
, setting
, &value
) ) < 0 )
872 return snprintf ( buf
, len
, "%ld", value
);
876 * Fetch and format value of unsigned integer setting
878 * @v settings Settings block, or NULL to search all blocks
879 * @v setting Setting to fetch
880 * @v buf Buffer to contain formatted value
881 * @v len Length of buffer
882 * @ret len Length of formatted value, or negative error
884 static int fetchf_uint ( struct settings
*settings
, struct setting
*setting
,
885 char *buf
, size_t len
) {
889 if ( ( rc
= fetch_uint_setting ( settings
, setting
, &value
) ) < 0 )
891 return snprintf ( buf
, len
, "%#lx", value
);
894 /** A signed 8-bit integer setting type */
895 struct setting_type setting_type_int8 __setting_type
= {
897 .storef
= storef_int8
,
898 .fetchf
= fetchf_int
,
901 /** A signed 16-bit integer setting type */
902 struct setting_type setting_type_int16 __setting_type
= {
904 .storef
= storef_int16
,
905 .fetchf
= fetchf_int
,
908 /** A signed 32-bit integer setting type */
909 struct setting_type setting_type_int32 __setting_type
= {
911 .storef
= storef_int32
,
912 .fetchf
= fetchf_int
,
915 /** An unsigned 8-bit integer setting type */
916 struct setting_type setting_type_uint8 __setting_type
= {
918 .storef
= storef_int8
,
919 .fetchf
= fetchf_uint
,
922 /** An unsigned 16-bit integer setting type */
923 struct setting_type setting_type_uint16 __setting_type
= {
925 .storef
= storef_int16
,
926 .fetchf
= fetchf_uint
,
929 /** An unsigned 32-bit integer setting type */
930 struct setting_type setting_type_uint32 __setting_type
= {
932 .storef
= storef_int32
,
933 .fetchf
= fetchf_uint
,
937 * Parse and store value of hex string setting
939 * @v settings Settings block
940 * @v setting Setting to store
941 * @v value Formatted setting data
942 * @ret rc Return status code
944 static int storef_hex ( struct settings
*settings
, struct setting
*setting
,
945 const char *value
) {
946 char *ptr
= ( char * ) value
;
947 uint8_t bytes
[ strlen ( value
) ]; /* cannot exceed strlen(value) */
948 unsigned int len
= 0;
951 bytes
[len
++] = strtoul ( ptr
, &ptr
, 16 );
954 return store_setting ( settings
, setting
, bytes
, len
);
965 * Fetch and format value of hex string setting
967 * @v settings Settings block, or NULL to search all blocks
968 * @v setting Setting to fetch
969 * @v buf Buffer to contain formatted value
970 * @v len Length of buffer
971 * @ret len Length of formatted value, or negative error
973 static int fetchf_hex ( struct settings
*settings
, struct setting
*setting
,
974 char *buf
, size_t len
) {
980 raw_len
= fetch_setting_len ( settings
, setting
);
985 uint8_t raw
[raw_len
];
987 check_len
= fetch_setting ( settings
, setting
, raw
,
989 assert ( check_len
== raw_len
);
992 buf
[0] = 0; /* Ensure that a terminating NUL exists */
993 for ( i
= 0 ; i
< raw_len
; i
++ ) {
994 used
+= ssnprintf ( ( buf
+ used
), ( len
- used
),
995 "%s%02x", ( used
? ":" : "" ),
1002 /** A hex-string setting */
1003 struct setting_type setting_type_hex __setting_type
= {
1005 .storef
= storef_hex
,
1006 .fetchf
= fetchf_hex
,
1010 * Parse and store value of UUID setting
1012 * @v settings Settings block
1013 * @v setting Setting to store
1014 * @v value Formatted setting data
1015 * @ret rc Return status code
1017 static int storef_uuid ( struct settings
*settings __unused
,
1018 struct setting
*setting __unused
,
1019 const char *value __unused
) {
1024 * Fetch and format value of UUID setting
1026 * @v settings Settings block, or NULL to search all blocks
1027 * @v setting Setting to fetch
1028 * @v buf Buffer to contain formatted value
1029 * @v len Length of buffer
1030 * @ret len Length of formatted value, or negative error
1032 static int fetchf_uuid ( struct settings
*settings
, struct setting
*setting
,
1033 char *buf
, size_t len
) {
1037 if ( ( raw_len
= fetch_uuid_setting ( settings
, setting
, &uuid
) ) < 0)
1039 return snprintf ( buf
, len
, "%s", uuid_ntoa ( &uuid
) );
1042 /** UUID setting type */
1043 struct setting_type setting_type_uuid __setting_type
= {
1045 .storef
= storef_uuid
,
1046 .fetchf
= fetchf_uuid
,
1049 /******************************************************************************
1053 ******************************************************************************
1056 /** Hostname setting */
1057 struct setting hostname_setting __setting
= {
1059 .description
= "Host name",
1060 .tag
= DHCP_HOST_NAME
,
1061 .type
= &setting_type_string
,
1064 /** Filename setting */
1065 struct setting filename_setting __setting
= {
1067 .description
= "Boot filename",
1068 .tag
= DHCP_BOOTFILE_NAME
,
1069 .type
= &setting_type_string
,
1072 /** Root path setting */
1073 struct setting root_path_setting __setting
= {
1074 .name
= "root-path",
1075 .description
= "NFS/iSCSI root path",
1076 .tag
= DHCP_ROOT_PATH
,
1077 .type
= &setting_type_string
,
1080 /** Username setting */
1081 struct setting username_setting __setting
= {
1083 .description
= "User name",
1084 .tag
= DHCP_EB_USERNAME
,
1085 .type
= &setting_type_string
,
1088 /** Password setting */
1089 struct setting password_setting __setting
= {
1091 .description
= "Password",
1092 .tag
= DHCP_EB_PASSWORD
,
1093 .type
= &setting_type_string
,
1096 /** Priority setting */
1097 struct setting priority_setting __setting
= {
1099 .description
= "Priority of these settings",
1100 .tag
= DHCP_EB_PRIORITY
,
1101 .type
= &setting_type_int8
,