[process] Include process name in debug messages
[ipxe.git] / src / core / settings.c
1 /*
2 * Copyright (C) 2008 Michael Brown <mbrown@fensystems.co.uk>.
3 *
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.
8 *
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.
13 *
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., 51 Franklin Street, Fifth Floor, Boston, MA
17 * 02110-1301, USA.
18 *
19 * You can also choose to distribute this program under the terms of
20 * the Unmodified Binary Distribution Licence (as given in the file
21 * COPYING.UBDL), provided that you have satisfied its requirements.
22 */
23
24 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25
26 #include <stdint.h>
27 #include <stdlib.h>
28 #include <stdio.h>
29 #include <string.h>
30 #include <strings.h>
31 #include <byteswap.h>
32 #include <errno.h>
33 #include <assert.h>
34 #include <time.h>
35 #include <ipxe/in.h>
36 #include <ipxe/ip.h>
37 #include <ipxe/ipv6.h>
38 #include <ipxe/vsprintf.h>
39 #include <ipxe/dhcp.h>
40 #include <ipxe/uuid.h>
41 #include <ipxe/uri.h>
42 #include <ipxe/base16.h>
43 #include <ipxe/base64.h>
44 #include <ipxe/pci.h>
45 #include <ipxe/init.h>
46 #include <ipxe/version.h>
47 #include <ipxe/settings.h>
48
49 /** @file
50 *
51 * Configuration settings
52 *
53 */
54
55 /******************************************************************************
56 *
57 * Generic settings blocks
58 *
59 ******************************************************************************
60 */
61
62 /**
63 * A generic setting
64 *
65 */
66 struct generic_setting {
67 /** List of generic settings */
68 struct list_head list;
69 /** Setting */
70 struct setting setting;
71 /** Size of setting name */
72 size_t name_len;
73 /** Size of setting data */
74 size_t data_len;
75 };
76
77 /**
78 * Get generic setting name
79 *
80 * @v generic Generic setting
81 * @ret name Generic setting name
82 */
83 static inline void * generic_setting_name ( struct generic_setting *generic ) {
84 return ( ( ( void * ) generic ) + sizeof ( *generic ) );
85 }
86
87 /**
88 * Get generic setting data
89 *
90 * @v generic Generic setting
91 * @ret data Generic setting data
92 */
93 static inline void * generic_setting_data ( struct generic_setting *generic ) {
94 return ( ( ( void * ) generic ) + sizeof ( *generic ) +
95 generic->name_len );
96 }
97
98 /**
99 * Find generic setting
100 *
101 * @v generics Generic settings block
102 * @v setting Setting to find
103 * @ret generic Generic setting, or NULL
104 */
105 static struct generic_setting *
106 find_generic_setting ( struct generic_settings *generics,
107 const struct setting *setting ) {
108 struct generic_setting *generic;
109
110 list_for_each_entry ( generic, &generics->list, list ) {
111 if ( setting_cmp ( &generic->setting, setting ) == 0 )
112 return generic;
113 }
114 return NULL;
115 }
116
117 /**
118 * Store value of generic setting
119 *
120 * @v settings Settings block
121 * @v setting Setting to store
122 * @v data Setting data, or NULL to clear setting
123 * @v len Length of setting data
124 * @ret rc Return status code
125 */
126 int generic_settings_store ( struct settings *settings,
127 const struct setting *setting,
128 const void *data, size_t len ) {
129 struct generic_settings *generics =
130 container_of ( settings, struct generic_settings, settings );
131 struct generic_setting *old;
132 struct generic_setting *new = NULL;
133 size_t name_len;
134
135 /* Identify existing generic setting, if any */
136 old = find_generic_setting ( generics, setting );
137
138 /* Create new generic setting, if required */
139 if ( len ) {
140 /* Allocate new generic setting */
141 name_len = ( strlen ( setting->name ) + 1 );
142 new = zalloc ( sizeof ( *new ) + name_len + len );
143 if ( ! new )
144 return -ENOMEM;
145
146 /* Populate new generic setting */
147 new->name_len = name_len;
148 new->data_len = len;
149 memcpy ( &new->setting, setting, sizeof ( new->setting ) );
150 new->setting.name = generic_setting_name ( new );
151 memcpy ( generic_setting_name ( new ),
152 setting->name, name_len );
153 memcpy ( generic_setting_data ( new ), data, len );
154 }
155
156 /* Delete existing generic setting, if any */
157 if ( old ) {
158 list_del ( &old->list );
159 free ( old );
160 }
161
162 /* Add new setting to list, if any */
163 if ( new )
164 list_add ( &new->list, &generics->list );
165
166 return 0;
167 }
168
169 /**
170 * Fetch value of generic setting
171 *
172 * @v settings Settings block
173 * @v setting Setting to fetch
174 * @v data Buffer to fill with setting data
175 * @v len Length of buffer
176 * @ret len Length of setting data, or negative error
177 */
178 int generic_settings_fetch ( struct settings *settings,
179 struct setting *setting,
180 void *data, size_t len ) {
181 struct generic_settings *generics =
182 container_of ( settings, struct generic_settings, settings );
183 struct generic_setting *generic;
184
185 /* Find generic setting */
186 generic = find_generic_setting ( generics, setting );
187 if ( ! generic )
188 return -ENOENT;
189
190 /* Copy out generic setting data */
191 if ( len > generic->data_len )
192 len = generic->data_len;
193 memcpy ( data, generic_setting_data ( generic ), len );
194
195 /* Set setting type, if not yet specified */
196 if ( ! setting->type )
197 setting->type = generic->setting.type;
198
199 return generic->data_len;
200 }
201
202 /**
203 * Clear generic settings block
204 *
205 * @v settings Settings block
206 */
207 void generic_settings_clear ( struct settings *settings ) {
208 struct generic_settings *generics =
209 container_of ( settings, struct generic_settings, settings );
210 struct generic_setting *generic;
211 struct generic_setting *tmp;
212
213 list_for_each_entry_safe ( generic, tmp, &generics->list, list ) {
214 list_del ( &generic->list );
215 free ( generic );
216 }
217 assert ( list_empty ( &generics->list ) );
218 }
219
220 /** Generic settings operations */
221 struct settings_operations generic_settings_operations = {
222 .store = generic_settings_store,
223 .fetch = generic_settings_fetch,
224 .clear = generic_settings_clear,
225 };
226
227 /******************************************************************************
228 *
229 * Registered settings blocks
230 *
231 ******************************************************************************
232 */
233
234 /** Root generic settings block */
235 struct generic_settings generic_settings_root = {
236 .settings = {
237 .refcnt = NULL,
238 .name = "",
239 .siblings =
240 LIST_HEAD_INIT ( generic_settings_root.settings.siblings ),
241 .children =
242 LIST_HEAD_INIT ( generic_settings_root.settings.children ),
243 .op = &generic_settings_operations,
244 },
245 .list = LIST_HEAD_INIT ( generic_settings_root.list ),
246 };
247
248 /** Root settings block */
249 #define settings_root generic_settings_root.settings
250
251 /** Autovivified settings block */
252 struct autovivified_settings {
253 /** Reference count */
254 struct refcnt refcnt;
255 /** Generic settings block */
256 struct generic_settings generic;
257 };
258
259 /**
260 * Free autovivified settings block
261 *
262 * @v refcnt Reference count
263 */
264 static void autovivified_settings_free ( struct refcnt *refcnt ) {
265 struct autovivified_settings *autovivified =
266 container_of ( refcnt, struct autovivified_settings, refcnt );
267
268 generic_settings_clear ( &autovivified->generic.settings );
269 free ( autovivified );
270 }
271
272 /**
273 * Find child settings block
274 *
275 * @v parent Parent settings block
276 * @v name Name within this parent
277 * @ret settings Settings block, or NULL
278 */
279 struct settings * find_child_settings ( struct settings *parent,
280 const char *name ) {
281 struct settings *settings;
282
283 /* Find target parent settings block */
284 parent = settings_target ( parent );
285
286 /* Treat empty name as meaning "this block" */
287 if ( ! *name )
288 return parent;
289
290 /* Look for child with matching name */
291 list_for_each_entry ( settings, &parent->children, siblings ) {
292 if ( strcmp ( settings->name, name ) == 0 )
293 return settings_target ( settings );
294 }
295
296 return NULL;
297 }
298
299 /**
300 * Find or create child settings block
301 *
302 * @v parent Parent settings block
303 * @v name Name within this parent
304 * @ret settings Settings block, or NULL
305 */
306 struct settings * autovivify_child_settings ( struct settings *parent,
307 const char *name ) {
308 struct {
309 struct autovivified_settings autovivified;
310 char name[ strlen ( name ) + 1 /* NUL */ ];
311 } *new_child;
312 struct settings *settings;
313
314 /* Find target parent settings block */
315 parent = settings_target ( parent );
316
317 /* Return existing settings, if existent */
318 if ( ( settings = find_child_settings ( parent, name ) ) != NULL )
319 return settings;
320
321 /* Create new generic settings block */
322 new_child = zalloc ( sizeof ( *new_child ) );
323 if ( ! new_child ) {
324 DBGC ( parent, "Settings %p could not create child %s\n",
325 parent, name );
326 return NULL;
327 }
328 memcpy ( new_child->name, name, sizeof ( new_child->name ) );
329 ref_init ( &new_child->autovivified.refcnt,
330 autovivified_settings_free );
331 generic_settings_init ( &new_child->autovivified.generic,
332 &new_child->autovivified.refcnt );
333 settings = &new_child->autovivified.generic.settings;
334 register_settings ( settings, parent, new_child->name );
335 ref_put ( settings->refcnt );
336 return settings;
337 }
338
339 /**
340 * Return settings block name
341 *
342 * @v settings Settings block
343 * @ret name Settings block name
344 */
345 const char * settings_name ( struct settings *settings ) {
346 static char buf[16];
347 char tmp[ 1 /* '.' */ + sizeof ( buf ) ];
348
349 /* Find target settings block */
350 settings = settings_target ( settings );
351
352 /* Construct name */
353 buf[0] = '\0';
354 tmp[0] = '\0';
355 for ( ; settings->parent ; settings = settings->parent ) {
356 memcpy ( ( tmp + 1 ), buf, ( sizeof ( tmp ) - 1 ) );
357 snprintf ( buf, sizeof ( buf ), "%s%s", settings->name, tmp );
358 tmp[0] = '.';
359 }
360 return buf;
361 }
362
363 /**
364 * Parse settings block name
365 *
366 * @v name Name
367 * @v get_child Function to find or create child settings block
368 * @ret settings Settings block, or NULL
369 */
370 static struct settings *
371 parse_settings_name ( const char *name, get_child_settings_t get_child ) {
372 struct settings *settings = &settings_root;
373 char name_copy[ strlen ( name ) + 1 ];
374 char *subname;
375 char *remainder;
376
377 /* Create modifiable copy of name */
378 memcpy ( name_copy, name, sizeof ( name_copy ) );
379 remainder = name_copy;
380
381 /* Parse each name component in turn */
382 while ( remainder ) {
383 subname = remainder;
384 remainder = strchr ( subname, '.' );
385 if ( remainder )
386 *(remainder++) = '\0';
387 settings = get_child ( settings, subname );
388 if ( ! settings )
389 break;
390 }
391
392 return settings;
393 }
394
395 /**
396 * Find settings block
397 *
398 * @v name Name
399 * @ret settings Settings block, or NULL
400 */
401 struct settings * find_settings ( const char *name ) {
402
403 return parse_settings_name ( name, find_child_settings );
404 }
405
406 /**
407 * Apply all settings
408 *
409 * @ret rc Return status code
410 */
411 static int apply_settings ( void ) {
412 struct settings_applicator *applicator;
413 int rc;
414
415 /* Call all settings applicators */
416 for_each_table_entry ( applicator, SETTINGS_APPLICATORS ) {
417 if ( ( rc = applicator->apply() ) != 0 ) {
418 DBG ( "Could not apply settings using applicator "
419 "%p: %s\n", applicator, strerror ( rc ) );
420 return rc;
421 }
422 }
423
424 return 0;
425 }
426
427 /**
428 * Reprioritise settings
429 *
430 * @v settings Settings block
431 *
432 * Reorders the settings block amongst its siblings according to its
433 * priority.
434 */
435 static void reprioritise_settings ( struct settings *settings ) {
436 struct settings *parent = settings->parent;
437 long priority;
438 struct settings *tmp;
439 long tmp_priority;
440
441 /* Stop when we reach the top of the tree */
442 if ( ! parent )
443 return;
444
445 /* Read priority, if present */
446 priority = fetch_intz_setting ( settings, &priority_setting );
447
448 /* Remove from siblings list */
449 list_del ( &settings->siblings );
450
451 /* Reinsert after any existing blocks which have a higher priority */
452 list_for_each_entry ( tmp, &parent->children, siblings ) {
453 tmp_priority = fetch_intz_setting ( tmp, &priority_setting );
454 if ( priority > tmp_priority )
455 break;
456 if ( settings->order > tmp->order )
457 break;
458 }
459 list_add_tail ( &settings->siblings, &tmp->siblings );
460
461 /* Recurse up the tree */
462 reprioritise_settings ( parent );
463 }
464
465 /**
466 * Register settings block
467 *
468 * @v settings Settings block
469 * @v parent Parent settings block, or NULL
470 * @v name Settings block name
471 * @ret rc Return status code
472 */
473 int register_settings ( struct settings *settings, struct settings *parent,
474 const char *name ) {
475 struct settings *old_settings;
476
477 /* Sanity check */
478 assert ( settings != NULL );
479
480 /* Find target parent settings block */
481 parent = settings_target ( parent );
482
483 /* Apply settings block name */
484 settings->name = name;
485
486 /* Remove any existing settings with the same name */
487 if ( ( old_settings = find_child_settings ( parent, settings->name ) ))
488 unregister_settings ( old_settings );
489
490 /* Add to list of settings */
491 ref_get ( settings->refcnt );
492 ref_get ( parent->refcnt );
493 settings->parent = parent;
494 list_add_tail ( &settings->siblings, &parent->children );
495 DBGC ( settings, "Settings %p (\"%s\") registered\n",
496 settings, settings_name ( settings ) );
497
498 /* Fix up settings priority */
499 reprioritise_settings ( settings );
500
501 /* Apply potentially-updated settings */
502 apply_settings();
503
504 return 0;
505 }
506
507 /**
508 * Unregister settings block
509 *
510 * @v settings Settings block
511 */
512 void unregister_settings ( struct settings *settings ) {
513 struct settings *child;
514
515 /* Unregister child settings */
516 while ( ( child = list_first_entry ( &settings->children,
517 struct settings, siblings ) ) ) {
518 unregister_settings ( child );
519 }
520
521 DBGC ( settings, "Settings %p (\"%s\") unregistered\n",
522 settings, settings_name ( settings ) );
523
524 /* Remove from list of settings */
525 ref_put ( settings->parent->refcnt );
526 settings->parent = NULL;
527 list_del ( &settings->siblings );
528 ref_put ( settings->refcnt );
529
530 /* Apply potentially-updated settings */
531 apply_settings();
532 }
533
534 /******************************************************************************
535 *
536 * Core settings routines
537 *
538 ******************************************************************************
539 */
540
541 /**
542 * Redirect to target settings block
543 *
544 * @v settings Settings block, or NULL
545 * @ret settings Underlying settings block
546 */
547 struct settings * settings_target ( struct settings *settings ) {
548
549 /* NULL settings implies the global settings root */
550 if ( ! settings )
551 settings = &settings_root;
552
553 /* Redirect to underlying settings block, if applicable */
554 if ( settings->op->redirect )
555 return settings->op->redirect ( settings );
556
557 /* Otherwise, return this settings block */
558 return settings;
559 }
560
561 /**
562 * Check applicability of setting
563 *
564 * @v settings Settings block
565 * @v setting Setting
566 * @ret applies Setting applies within this settings block
567 */
568 int setting_applies ( struct settings *settings,
569 const struct setting *setting ) {
570
571 /* Find target settings block */
572 settings = settings_target ( settings );
573
574 /* Check applicability of setting */
575 return ( settings->op->applies ?
576 settings->op->applies ( settings, setting ) : 1 );
577 }
578
579 /**
580 * Find setting applicable to settings block, if any
581 *
582 * @v settings Settings block
583 * @v setting Setting
584 * @ret setting Applicable setting, if any
585 */
586 static const struct setting *
587 applicable_setting ( struct settings *settings, const struct setting *setting ){
588 const struct setting *applicable;
589
590 /* If setting is already applicable, use it */
591 if ( setting_applies ( settings, setting ) )
592 return setting;
593
594 /* Otherwise, look for a matching predefined setting which does apply */
595 for_each_table_entry ( applicable, SETTINGS ) {
596 if ( ( setting_cmp ( setting, applicable ) == 0 ) &&
597 ( setting_applies ( settings, applicable ) ) )
598 return applicable;
599 }
600
601 return NULL;
602 }
603
604 /**
605 * Store value of setting
606 *
607 * @v settings Settings block, or NULL
608 * @v setting Setting to store
609 * @v data Setting data, or NULL to clear setting
610 * @v len Length of setting data
611 * @ret rc Return status code
612 */
613 int store_setting ( struct settings *settings, const struct setting *setting,
614 const void *data, size_t len ) {
615 int rc;
616
617 /* Find target settings block */
618 settings = settings_target ( settings );
619
620 /* Fail if setting does not apply to this settings block */
621 if ( ! setting_applies ( settings, setting ) )
622 return -ENOTTY;
623
624 /* Sanity check */
625 if ( ! settings->op->store )
626 return -ENOTSUP;
627
628 /* Store setting */
629 if ( ( rc = settings->op->store ( settings, setting,
630 data, len ) ) != 0 )
631 return rc;
632
633 /* Reprioritise settings if necessary */
634 if ( setting_cmp ( setting, &priority_setting ) == 0 )
635 reprioritise_settings ( settings );
636
637 /* If these settings are registered, apply potentially-updated
638 * settings
639 */
640 for ( ; settings ; settings = settings->parent ) {
641 if ( settings == &settings_root ) {
642 if ( ( rc = apply_settings() ) != 0 )
643 return rc;
644 break;
645 }
646 }
647
648 return 0;
649 }
650
651 /**
652 * Fetch setting
653 *
654 * @v settings Settings block, or NULL to search all blocks
655 * @v setting Setting to fetch
656 * @v origin Origin of setting to fill in, or NULL
657 * @v fetched Fetched setting to fill in, or NULL
658 * @v data Buffer to fill with setting data
659 * @v len Length of buffer
660 * @ret len Length of setting data, or negative error
661 *
662 * The actual length of the setting will be returned even if
663 * the buffer was too small.
664 */
665 int fetch_setting ( struct settings *settings, const struct setting *setting,
666 struct settings **origin, struct setting *fetched,
667 void *data, size_t len ) {
668 const struct setting *applicable;
669 struct settings *child;
670 struct setting tmp;
671 int ret;
672
673 /* Avoid returning uninitialised data on error */
674 memset ( data, 0, len );
675 if ( origin )
676 *origin = NULL;
677 if ( fetched )
678 memcpy ( fetched, setting, sizeof ( *fetched ) );
679
680 /* Find target settings block */
681 settings = settings_target ( settings );
682
683 /* Sanity check */
684 if ( ! settings->op->fetch )
685 return -ENOTSUP;
686
687 /* Try this block first, if an applicable setting exists */
688 if ( ( applicable = applicable_setting ( settings, setting ) ) ) {
689
690 /* Create modifiable copy of setting */
691 memcpy ( &tmp, applicable, sizeof ( tmp ) );
692 if ( ( ret = settings->op->fetch ( settings, &tmp,
693 data, len ) ) >= 0 ) {
694
695 /* Default to string type, if not yet specified */
696 if ( ! tmp.type )
697 tmp.type = &setting_type_string;
698
699 /* Record origin, if applicable */
700 if ( origin )
701 *origin = settings;
702
703 /* Record fetched setting, if applicable */
704 if ( fetched )
705 memcpy ( fetched, &tmp, sizeof ( *fetched ) );
706
707 return ret;
708 }
709 }
710
711 /* Recurse into each child block in turn */
712 list_for_each_entry ( child, &settings->children, siblings ) {
713 if ( ( ret = fetch_setting ( child, setting, origin, fetched,
714 data, len ) ) >= 0 )
715 return ret;
716 }
717
718 return -ENOENT;
719 }
720
721 /**
722 * Fetch allocated copy of setting
723 *
724 * @v settings Settings block, or NULL to search all blocks
725 * @v setting Setting to fetch
726 * @v origin Origin of setting to fill in, or NULL
727 * @v fetched Fetched setting to fill in, or NULL
728 * @v data Buffer to allocate and fill with setting data
729 * @v alloc Allocation function
730 * @ret len Length of setting, or negative error
731 *
732 * The caller is responsible for eventually freeing the allocated
733 * buffer.
734 */
735 static int fetch_setting_alloc ( struct settings *settings,
736 const struct setting *setting,
737 struct settings **origin,
738 struct setting *fetched,
739 void **data,
740 void * ( * alloc ) ( size_t len ) ) {
741 struct settings *tmp_origin;
742 struct setting tmp_fetched;
743 int len;
744 int check_len;
745
746 /* Use local buffers if necessary */
747 if ( ! origin )
748 origin = &tmp_origin;
749 if ( ! fetched )
750 fetched = &tmp_fetched;
751
752 /* Avoid returning uninitialised data on error */
753 *data = NULL;
754
755 /* Check existence, and fetch setting length */
756 len = fetch_setting ( settings, setting, origin, fetched, NULL, 0 );
757 if ( len < 0 )
758 return len;
759
760 /* Allocate buffer */
761 *data = alloc ( len );
762 if ( ! *data )
763 return -ENOMEM;
764
765 /* Fetch setting value */
766 check_len = fetch_setting ( *origin, fetched, NULL, NULL, *data, len );
767 assert ( check_len == len );
768 return len;
769 }
770
771 /**
772 * Fetch copy of setting
773 *
774 * @v settings Settings block, or NULL to search all blocks
775 * @v setting Setting to fetch
776 * @v origin Origin of setting to fill in, or NULL
777 * @v fetched Fetched setting to fill in, or NULL
778 * @v data Buffer to allocate and fill with setting data
779 * @ret len Length of setting, or negative error
780 *
781 * The caller is responsible for eventually freeing the allocated
782 * buffer.
783 */
784 int fetch_setting_copy ( struct settings *settings,
785 const struct setting *setting,
786 struct settings **origin, struct setting *fetched,
787 void **data ) {
788
789 return fetch_setting_alloc ( settings, setting, origin, fetched,
790 data, malloc );
791 }
792
793 /**
794 * Fetch value of setting
795 *
796 * @v settings Settings block, or NULL to search all blocks
797 * @v setting Setting to fetch
798 * @v data Buffer to fill with setting string data
799 * @v len Length of buffer
800 * @ret len Length of setting, or negative error
801 */
802 int fetch_raw_setting ( struct settings *settings,
803 const struct setting *setting,
804 void *data, size_t len ) {
805
806 return fetch_setting ( settings, setting, NULL, NULL, data, len );
807 }
808
809 /**
810 * Fetch value of setting
811 *
812 * @v settings Settings block, or NULL to search all blocks
813 * @v setting Setting to fetch
814 * @v data Buffer to allocate and fill with setting data
815 * @ret len Length of setting, or negative error
816 *
817 * The caller is responsible for eventually freeing the allocated
818 * buffer.
819 */
820 int fetch_raw_setting_copy ( struct settings *settings,
821 const struct setting *setting,
822 void **data ) {
823
824 return fetch_setting_copy ( settings, setting, NULL, NULL, data );
825 }
826
827 /**
828 * Fetch value of string setting
829 *
830 * @v settings Settings block, or NULL to search all blocks
831 * @v setting Setting to fetch
832 * @v data Buffer to fill with setting string data
833 * @v len Length of buffer
834 * @ret len Length of string setting, or negative error
835 *
836 * The resulting string is guaranteed to be correctly NUL-terminated.
837 * The returned length will be the length of the underlying setting
838 * data.
839 */
840 int fetch_string_setting ( struct settings *settings,
841 const struct setting *setting,
842 char *data, size_t len ) {
843
844 memset ( data, 0, len );
845 return fetch_raw_setting ( settings, setting, data,
846 ( ( len > 0 ) ? ( len - 1 ) : 0 ) );
847 }
848
849 /**
850 * Allocate memory for copy of string setting
851 *
852 * @v len Length of setting
853 * @ret ptr Allocated memory
854 */
855 static void * fetch_string_setting_copy_alloc ( size_t len ) {
856 return zalloc ( len + 1 /* NUL */ );
857 }
858
859 /**
860 * Fetch value of string setting
861 *
862 * @v settings Settings block, or NULL to search all blocks
863 * @v setting Setting to fetch
864 * @v data Buffer to allocate and fill with setting string data
865 * @ret len Length of string setting, or negative error
866 *
867 * The resulting string is guaranteed to be correctly NUL-terminated.
868 * The returned length will be the length of the underlying setting
869 * data. The caller is responsible for eventually freeing the
870 * allocated buffer.
871 */
872 int fetch_string_setting_copy ( struct settings *settings,
873 const struct setting *setting, char **data ) {
874
875 return fetch_setting_alloc ( settings, setting, NULL, NULL,
876 ( ( void ** ) data ),
877 fetch_string_setting_copy_alloc );
878 }
879
880 /**
881 * Fetch value of IPv4 address setting
882 *
883 * @v settings Settings block, or NULL to search all blocks
884 * @v setting Setting to fetch
885 * @v inp IPv4 addresses to fill in
886 * @v count Maximum number of IPv4 addresses
887 * @ret len Length of setting, or negative error
888 */
889 int fetch_ipv4_array_setting ( struct settings *settings,
890 const struct setting *setting,
891 struct in_addr *inp, unsigned int count ) {
892 int len;
893
894 len = fetch_raw_setting ( settings, setting, inp,
895 ( sizeof ( *inp ) * count ) );
896 if ( len < 0 )
897 return len;
898 if ( ( len % sizeof ( *inp ) ) != 0 )
899 return -ERANGE;
900 return len;
901 }
902
903 /**
904 * Fetch value of IPv4 address setting
905 *
906 * @v settings Settings block, or NULL to search all blocks
907 * @v setting Setting to fetch
908 * @v inp IPv4 address to fill in
909 * @ret len Length of setting, or negative error
910 */
911 int fetch_ipv4_setting ( struct settings *settings,
912 const struct setting *setting,
913 struct in_addr *inp ) {
914
915 return fetch_ipv4_array_setting ( settings, setting, inp, 1 );
916 }
917
918 /**
919 * Fetch value of IPv6 address setting
920 *
921 * @v settings Settings block, or NULL to search all blocks
922 * @v setting Setting to fetch
923 * @v inp IPv6 addresses to fill in
924 * @v count Maximum number of IPv6 addresses
925 * @ret len Length of setting, or negative error
926 */
927 int fetch_ipv6_array_setting ( struct settings *settings,
928 const struct setting *setting,
929 struct in6_addr *inp, unsigned int count ) {
930 int len;
931
932 len = fetch_raw_setting ( settings, setting, inp,
933 ( sizeof ( *inp ) * count ) );
934 if ( len < 0 )
935 return len;
936 if ( ( len % sizeof ( *inp ) ) != 0 )
937 return -ERANGE;
938 return len;
939 }
940
941 /**
942 * Fetch value of IPv6 address setting
943 *
944 * @v settings Settings block, or NULL to search all blocks
945 * @v setting Setting to fetch
946 * @v inp IPv6 address to fill in
947 * @ret len Length of setting, or negative error
948 */
949 int fetch_ipv6_setting ( struct settings *settings,
950 const struct setting *setting,
951 struct in6_addr *inp ) {
952
953 return fetch_ipv6_array_setting ( settings, setting, inp, 1 );
954 }
955
956 /**
957 * Extract numeric value of setting
958 *
959 * @v is_signed Treat value as a signed integer
960 * @v raw Raw setting data
961 * @v len Length of raw setting data
962 * @ret value Numeric value
963 * @ret len Length of setting, or negative error
964 */
965 static int numeric_setting_value ( int is_signed, const void *raw, size_t len,
966 unsigned long *value ) {
967 const uint8_t *unsigned_bytes = raw;
968 const int8_t *signed_bytes = raw;
969 int is_negative;
970 unsigned int i;
971 uint8_t pad;
972 uint8_t byte;
973
974 /* Convert to host-ordered longs */
975 is_negative = ( len && ( signed_bytes[0] < 0 ) );
976 *value = ( ( is_signed && is_negative ) ? -1L : 0 );
977 pad = *value;
978 for ( i = 0 ; i < len ; i++ ) {
979 byte = unsigned_bytes[i];
980 *value = ( ( *value << 8 ) | byte );
981 if ( ( ( i + sizeof ( *value ) ) < len ) && ( byte != pad ) )
982 return -ERANGE;
983 }
984
985 return len;
986 }
987
988 /**
989 * Fetch value of numeric setting
990 *
991 * @v settings Settings block, or NULL to search all blocks
992 * @v setting Setting to fetch
993 * @v value Integer value to fill in
994 * @ret len Length of setting, or negative error
995 */
996 int fetch_numeric_setting ( struct settings *settings,
997 const struct setting *setting,
998 unsigned long *value, int is_signed ) {
999 unsigned long tmp;
1000 int len;
1001
1002 /* Avoid returning uninitialised data on error */
1003 *value = 0;
1004
1005 /* Fetch raw (network-ordered, variable-length) setting */
1006 len = fetch_raw_setting ( settings, setting, &tmp, sizeof ( tmp ) );
1007 if ( len < 0 )
1008 return len;
1009
1010 /* Extract numeric value */
1011 return numeric_setting_value ( is_signed, &tmp, len, value );
1012 }
1013
1014 /**
1015 * Fetch value of signed integer setting
1016 *
1017 * @v settings Settings block, or NULL to search all blocks
1018 * @v setting Setting to fetch
1019 * @v value Integer value to fill in
1020 * @ret len Length of setting, or negative error
1021 */
1022 int fetch_int_setting ( struct settings *settings,
1023 const struct setting *setting,
1024 long *value ) {
1025
1026 return fetch_numeric_setting ( settings, setting,
1027 ( ( unsigned long * ) value ), 1 );
1028 }
1029
1030 /**
1031 * Fetch value of unsigned integer setting
1032 *
1033 * @v settings Settings block, or NULL to search all blocks
1034 * @v setting Setting to fetch
1035 * @v value Integer value to fill in
1036 * @ret len Length of setting, or negative error
1037 */
1038 int fetch_uint_setting ( struct settings *settings,
1039 const struct setting *setting,
1040 unsigned long *value ) {
1041
1042 return fetch_numeric_setting ( settings, setting, value, 0 );
1043 }
1044
1045 /**
1046 * Fetch value of signed integer setting, or zero
1047 *
1048 * @v settings Settings block, or NULL to search all blocks
1049 * @v setting Setting to fetch
1050 * @ret value Setting value, or zero
1051 */
1052 long fetch_intz_setting ( struct settings *settings,
1053 const struct setting *setting ) {
1054 unsigned long value;
1055
1056 fetch_numeric_setting ( settings, setting, &value, 1 );
1057 return value;
1058 }
1059
1060 /**
1061 * Fetch value of unsigned integer setting, or zero
1062 *
1063 * @v settings Settings block, or NULL to search all blocks
1064 * @v setting Setting to fetch
1065 * @ret value Setting value, or zero
1066 */
1067 unsigned long fetch_uintz_setting ( struct settings *settings,
1068 const struct setting *setting ) {
1069 unsigned long value;
1070
1071 fetch_numeric_setting ( settings, setting, &value, 0 );
1072 return value;
1073 }
1074
1075 /**
1076 * Fetch value of UUID setting
1077 *
1078 * @v settings Settings block, or NULL to search all blocks
1079 * @v setting Setting to fetch
1080 * @v uuid UUID to fill in
1081 * @ret len Length of setting, or negative error
1082 */
1083 int fetch_uuid_setting ( struct settings *settings,
1084 const struct setting *setting,
1085 union uuid *uuid ) {
1086 int len;
1087
1088 len = fetch_raw_setting ( settings, setting, uuid, sizeof ( *uuid ) );
1089 if ( len < 0 )
1090 return len;
1091 if ( len != sizeof ( *uuid ) )
1092 return -ERANGE;
1093 return len;
1094 }
1095
1096 /**
1097 * Clear settings block
1098 *
1099 * @v settings Settings block
1100 */
1101 void clear_settings ( struct settings *settings ) {
1102
1103 /* Find target settings block */
1104 settings = settings_target ( settings );
1105
1106 /* Clear settings, if applicable */
1107 if ( settings->op->clear )
1108 settings->op->clear ( settings );
1109 }
1110
1111 /**
1112 * Compare two settings
1113 *
1114 * @v a Setting to compare
1115 * @v b Setting to compare
1116 * @ret 0 Settings are the same
1117 * @ret non-zero Settings are not the same
1118 */
1119 int setting_cmp ( const struct setting *a, const struct setting *b ) {
1120
1121 /* If the settings have tags, compare them */
1122 if ( a->tag && ( a->tag == b->tag ) && ( a->scope == b->scope ) )
1123 return 0;
1124
1125 /* Otherwise, if the settings have names, compare them */
1126 if ( a->name && b->name && a->name[0] )
1127 return strcmp ( a->name, b->name );
1128
1129 /* Otherwise, return a non-match */
1130 return ( ! 0 );
1131 }
1132
1133 /******************************************************************************
1134 *
1135 * Formatted setting routines
1136 *
1137 ******************************************************************************
1138 */
1139
1140 /**
1141 * Format setting value as a string
1142 *
1143 * @v type Setting type
1144 * @v raw Raw setting value
1145 * @v raw_len Length of raw setting value
1146 * @v buf Buffer to contain formatted value
1147 * @v len Length of buffer
1148 * @ret len Length of formatted value, or negative error
1149 */
1150 int setting_format ( const struct setting_type *type, const void *raw,
1151 size_t raw_len, char *buf, size_t len ) {
1152
1153 /* Sanity check */
1154 if ( ! type->format )
1155 return -ENOTSUP;
1156
1157 return type->format ( type, raw, raw_len, buf, len );
1158 }
1159
1160 /**
1161 * Parse formatted string to setting value
1162 *
1163 * @v type Setting type
1164 * @v value Formatted setting value
1165 * @v buf Buffer to contain raw value
1166 * @v len Length of buffer
1167 * @ret len Length of raw value, or negative error
1168 */
1169 int setting_parse ( const struct setting_type *type, const char *value,
1170 void *buf, size_t len ) {
1171
1172 /* Sanity check */
1173 if ( ! type->parse )
1174 return -ENOTSUP;
1175
1176 return type->parse ( type, value, buf, len );
1177 }
1178
1179 /**
1180 * Convert setting value to number
1181 *
1182 * @v type Setting type
1183 * @v raw Raw setting value
1184 * @v raw_len Length of raw setting value
1185 * @ret value Numeric value
1186 * @ret rc Return status code
1187 */
1188 int setting_numerate ( const struct setting_type *type, const void *raw,
1189 size_t raw_len, unsigned long *value ) {
1190
1191 /* Sanity check */
1192 if ( ! type->numerate )
1193 return -ENOTSUP;
1194
1195 return type->numerate ( type, raw, raw_len, value );
1196 }
1197
1198 /**
1199 * Convert number to setting value
1200 *
1201 * @v type Setting type
1202 * @v value Numeric value
1203 * @v buf Buffer to contain raw value
1204 * @v len Length of buffer
1205 * @ret len Length of raw value, or negative error
1206 */
1207 int setting_denumerate ( const struct setting_type *type, unsigned long value,
1208 void *buf, size_t len ) {
1209
1210 /* Sanity check */
1211 if ( ! type->denumerate )
1212 return -ENOTSUP;
1213
1214 return type->denumerate ( type, value, buf, len );
1215 }
1216
1217 /**
1218 * Fetch formatted value of setting
1219 *
1220 * @v settings Settings block, or NULL to search all blocks
1221 * @v setting Setting to fetch
1222 * @v origin Origin of setting to fill in, or NULL
1223 * @v fetched Fetched setting to fill in, or NULL
1224 * @v buf Buffer to contain formatted value
1225 * @v len Length of buffer
1226 * @ret len Length of formatted value, or negative error
1227 */
1228 int fetchf_setting ( struct settings *settings, const struct setting *setting,
1229 struct settings **origin, struct setting *fetched,
1230 char *buf, size_t len ) {
1231 struct setting tmp_fetched;
1232 void *raw;
1233 int raw_len;
1234 int ret;
1235
1236 /* Use local buffers if necessary */
1237 if ( ! fetched )
1238 fetched = &tmp_fetched;
1239
1240 /* Fetch raw value */
1241 raw_len = fetch_setting_copy ( settings, setting, origin, fetched,
1242 &raw );
1243 if ( raw_len < 0 ) {
1244 ret = raw_len;
1245 goto err_fetch_copy;
1246 }
1247
1248 /* Sanity check */
1249 assert ( fetched->type != NULL );
1250
1251 /* Format setting */
1252 if ( ( ret = setting_format ( fetched->type, raw, raw_len, buf,
1253 len ) ) < 0 )
1254 goto err_format;
1255
1256 err_format:
1257 free ( raw );
1258 err_fetch_copy:
1259 return ret;
1260 }
1261
1262 /**
1263 * Fetch copy of formatted value of setting
1264 *
1265 * @v settings Settings block, or NULL to search all blocks
1266 * @v setting Setting to fetch
1267 * @v origin Origin of setting to fill in, or NULL
1268 * @v fetched Fetched setting to fill in, or NULL
1269 * @v value Buffer to allocate and fill with formatted value
1270 * @ret len Length of formatted value, or negative error
1271 *
1272 * The caller is responsible for eventually freeing the allocated
1273 * buffer.
1274 */
1275 int fetchf_setting_copy ( struct settings *settings,
1276 const struct setting *setting,
1277 struct settings **origin, struct setting *fetched,
1278 char **value ) {
1279 struct settings *tmp_origin;
1280 struct setting tmp_fetched;
1281 int len;
1282 int check_len;
1283
1284 /* Use local buffers if necessary */
1285 if ( ! origin )
1286 origin = &tmp_origin;
1287 if ( ! fetched )
1288 fetched = &tmp_fetched;
1289
1290 /* Avoid returning uninitialised data on error */
1291 *value = NULL;
1292
1293 /* Check existence, and fetch formatted value length */
1294 len = fetchf_setting ( settings, setting, origin, fetched, NULL, 0 );
1295 if ( len < 0 )
1296 return len;
1297
1298 /* Allocate buffer */
1299 *value = zalloc ( len + 1 /* NUL */ );
1300 if ( ! *value )
1301 return -ENOMEM;
1302
1303 /* Fetch formatted value */
1304 check_len = fetchf_setting ( *origin, fetched, NULL, NULL, *value,
1305 ( len + 1 /* NUL */ ) );
1306 assert ( check_len == len );
1307 return len;
1308 }
1309
1310 /**
1311 * Store formatted value of setting
1312 *
1313 * @v settings Settings block
1314 * @v setting Setting to store
1315 * @v value Formatted setting data, or NULL
1316 * @ret rc Return status code
1317 */
1318 int storef_setting ( struct settings *settings, const struct setting *setting,
1319 const char *value ) {
1320 void *raw;
1321 int raw_len;
1322 int check_len;
1323 int rc;
1324
1325 /* NULL value or empty string implies deletion */
1326 if ( ( ! value ) || ( ! value[0] ) )
1327 return delete_setting ( settings, setting );
1328
1329 /* Sanity check */
1330 assert ( setting->type != NULL );
1331
1332 /* Get raw value length */
1333 raw_len = setting_parse ( setting->type, value, NULL, 0 );
1334 if ( raw_len < 0 ) {
1335 rc = raw_len;
1336 goto err_raw_len;
1337 }
1338
1339 /* Allocate buffer for raw value */
1340 raw = malloc ( raw_len );
1341 if ( ! raw ) {
1342 rc = -ENOMEM;
1343 goto err_alloc_raw;
1344 }
1345
1346 /* Parse formatted value */
1347 check_len = setting_parse ( setting->type, value, raw, raw_len );
1348 assert ( check_len == raw_len );
1349
1350 /* Store raw value */
1351 if ( ( rc = store_setting ( settings, setting, raw, raw_len ) ) != 0 )
1352 goto err_store;
1353
1354 err_store:
1355 free ( raw );
1356 err_alloc_raw:
1357 err_raw_len:
1358 return rc;
1359 }
1360
1361 /**
1362 * Fetch numeric value of setting
1363 *
1364 * @v settings Settings block, or NULL to search all blocks
1365 * @v setting Setting to fetch
1366 * @v origin Origin of setting to fill in, or NULL
1367 * @v fetched Fetched setting to fill in, or NULL
1368 * @v value Numeric value to fill in
1369 * @ret rc Return status code
1370 */
1371 int fetchn_setting ( struct settings *settings, const struct setting *setting,
1372 struct settings **origin, struct setting *fetched,
1373 unsigned long *value ) {
1374 struct setting tmp_fetched;
1375 void *raw;
1376 int raw_len;
1377 int rc;
1378
1379 /* Use local buffers if necessary */
1380 if ( ! fetched )
1381 fetched = &tmp_fetched;
1382
1383 /* Fetch raw value */
1384 raw_len = fetch_setting_copy ( settings, setting, origin, fetched,
1385 &raw );
1386 if ( raw_len < 0 ) {
1387 rc = raw_len;
1388 goto err_fetch_copy;
1389 }
1390
1391 /* Sanity check */
1392 assert ( fetched->type != NULL );
1393
1394 /* Numerate setting */
1395 if ( ( rc = setting_numerate ( fetched->type, raw, raw_len,
1396 value ) ) < 0 )
1397 goto err_numerate;
1398
1399 err_numerate:
1400 free ( raw );
1401 err_fetch_copy:
1402 return rc;
1403 }
1404
1405 /**
1406 * Store numeric value of setting
1407 *
1408 * @v settings Settings block
1409 * @v setting Setting
1410 * @v value Numeric value
1411 * @ret rc Return status code
1412 */
1413 int storen_setting ( struct settings *settings, const struct setting *setting,
1414 unsigned long value ) {
1415 void *raw;
1416 int raw_len;
1417 int check_len;
1418 int rc;
1419
1420 /* Sanity check */
1421 assert ( setting->type != NULL );
1422
1423 /* Get raw value length */
1424 raw_len = setting_denumerate ( setting->type, value, NULL, 0 );
1425 if ( raw_len < 0 ) {
1426 rc = raw_len;
1427 goto err_raw_len;
1428 }
1429
1430 /* Allocate buffer for raw value */
1431 raw = malloc ( raw_len );
1432 if ( ! raw ) {
1433 rc = -ENOMEM;
1434 goto err_alloc_raw;
1435 }
1436
1437 /* Denumerate value */
1438 check_len = setting_denumerate ( setting->type, value, raw, raw_len );
1439 assert ( check_len == raw_len );
1440
1441 /* Store raw value */
1442 if ( ( rc = store_setting ( settings, setting, raw, raw_len ) ) != 0 )
1443 goto err_store;
1444
1445 err_store:
1446 free ( raw );
1447 err_alloc_raw:
1448 err_raw_len:
1449 return rc;
1450 }
1451
1452 /******************************************************************************
1453 *
1454 * Named settings
1455 *
1456 ******************************************************************************
1457 */
1458
1459 /**
1460 * Find predefined setting
1461 *
1462 * @v name Name
1463 * @ret setting Setting, or NULL
1464 */
1465 struct setting * find_setting ( const char *name ) {
1466 struct setting *setting;
1467
1468 for_each_table_entry ( setting, SETTINGS ) {
1469 if ( strcmp ( name, setting->name ) == 0 )
1470 return setting;
1471 }
1472 return NULL;
1473 }
1474
1475 /**
1476 * Parse setting name as tag number
1477 *
1478 * @v name Name
1479 * @ret tag Tag number, or 0 if not a valid number
1480 */
1481 static uint64_t parse_setting_tag ( const char *name ) {
1482 char *tmp = ( ( char * ) name );
1483 uint64_t tag = 0;
1484
1485 while ( 1 ) {
1486 tag = ( ( tag << 8 ) | strtoul ( tmp, &tmp, 0 ) );
1487 if ( *tmp == 0 )
1488 return tag;
1489 if ( *tmp != '.' )
1490 return 0;
1491 tmp++;
1492 }
1493 }
1494
1495 /**
1496 * Find setting type
1497 *
1498 * @v name Name
1499 * @ret type Setting type, or NULL
1500 */
1501 static const struct setting_type * find_setting_type ( const char *name ) {
1502 const struct setting_type *type;
1503
1504 for_each_table_entry ( type, SETTING_TYPES ) {
1505 if ( strcmp ( name, type->name ) == 0 )
1506 return type;
1507 }
1508 return NULL;
1509 }
1510
1511 /**
1512 * Parse setting name
1513 *
1514 * @v name Name of setting
1515 * @v get_child Function to find or create child settings block
1516 * @v settings Settings block to fill in
1517 * @v setting Setting to fill in
1518 * @ret rc Return status code
1519 *
1520 * Interprets a name of the form
1521 * "[settings_name/]tag_name[:type_name]" and fills in the appropriate
1522 * fields.
1523 *
1524 * Note that on success, this function will have modified the original
1525 * setting @c name.
1526 */
1527 int parse_setting_name ( char *name, get_child_settings_t get_child,
1528 struct settings **settings, struct setting *setting ) {
1529 char *settings_name;
1530 char *setting_name;
1531 char *type_name;
1532 struct setting *predefined;
1533 int rc;
1534
1535 /* Set defaults */
1536 *settings = &settings_root;
1537 memset ( setting, 0, sizeof ( *setting ) );
1538 setting->name = "";
1539
1540 /* Split name into "[settings_name/]setting_name[:type_name]" */
1541 if ( ( setting_name = strchr ( name, '/' ) ) != NULL ) {
1542 *(setting_name++) = 0;
1543 settings_name = name;
1544 } else {
1545 setting_name = name;
1546 settings_name = NULL;
1547 }
1548 if ( ( type_name = strchr ( setting_name, ':' ) ) != NULL )
1549 *(type_name++) = 0;
1550
1551 /* Identify settings block, if specified */
1552 if ( settings_name ) {
1553 *settings = parse_settings_name ( settings_name, get_child );
1554 if ( *settings == NULL ) {
1555 DBG ( "Unrecognised settings block \"%s\" in \"%s\"\n",
1556 settings_name, name );
1557 rc = -ENODEV;
1558 goto err;
1559 }
1560 }
1561
1562 /* Identify setting */
1563 setting->tag = parse_setting_tag ( setting_name );
1564 setting->scope = (*settings)->default_scope;
1565 setting->name = setting_name;
1566 for_each_table_entry ( predefined, SETTINGS ) {
1567 /* Matches a predefined setting; use that setting */
1568 if ( setting_cmp ( predefined, setting ) == 0 ) {
1569 memcpy ( setting, predefined, sizeof ( *setting ) );
1570 break;
1571 }
1572 }
1573
1574 /* Identify setting type, if specified */
1575 if ( type_name ) {
1576 setting->type = find_setting_type ( type_name );
1577 if ( setting->type == NULL ) {
1578 DBG ( "Invalid setting type \"%s\" in \"%s\"\n",
1579 type_name, name );
1580 rc = -ENOTSUP;
1581 goto err;
1582 }
1583 }
1584
1585 return 0;
1586
1587 err:
1588 /* Restore original name */
1589 if ( settings_name )
1590 *( setting_name - 1 ) = '/';
1591 if ( type_name )
1592 *( type_name - 1 ) = ':';
1593 return rc;
1594 }
1595
1596 /**
1597 * Return full setting name
1598 *
1599 * @v settings Settings block, or NULL
1600 * @v setting Setting
1601 * @v buf Buffer
1602 * @v len Length of buffer
1603 * @ret len Length of setting name, or negative error
1604 */
1605 int setting_name ( struct settings *settings, const struct setting *setting,
1606 char *buf, size_t len ) {
1607 const char *name;
1608
1609 settings = settings_target ( settings );
1610 name = settings_name ( settings );
1611 return snprintf ( buf, len, "%s%s%s:%s", name, ( name[0] ? "/" : "" ),
1612 setting->name, setting->type->name );
1613 }
1614
1615 /******************************************************************************
1616 *
1617 * Setting types
1618 *
1619 ******************************************************************************
1620 */
1621
1622 /**
1623 * Parse string setting value
1624 *
1625 * @v type Setting type
1626 * @v value Formatted setting value
1627 * @v buf Buffer to contain raw value
1628 * @v len Length of buffer
1629 * @ret len Length of raw value, or negative error
1630 */
1631 static int parse_string_setting ( const struct setting_type *type __unused,
1632 const char *value, void *buf, size_t len ) {
1633 size_t raw_len = strlen ( value ); /* Exclude terminating NUL */
1634
1635 /* Copy string to buffer */
1636 if ( len > raw_len )
1637 len = raw_len;
1638 memcpy ( buf, value, len );
1639
1640 return raw_len;
1641 }
1642
1643 /**
1644 * Format string setting value
1645 *
1646 * @v type Setting type
1647 * @v raw Raw setting value
1648 * @v raw_len Length of raw setting value
1649 * @v buf Buffer to contain formatted value
1650 * @v len Length of buffer
1651 * @ret len Length of formatted value, or negative error
1652 */
1653 static int format_string_setting ( const struct setting_type *type __unused,
1654 const void *raw, size_t raw_len, char *buf,
1655 size_t len ) {
1656
1657 /* Copy string to buffer, and terminate */
1658 memset ( buf, 0, len );
1659 if ( len > raw_len )
1660 len = raw_len;
1661 memcpy ( buf, raw, len );
1662
1663 return raw_len;
1664 }
1665
1666 /** A string setting type */
1667 const struct setting_type setting_type_string __setting_type = {
1668 .name = "string",
1669 .parse = parse_string_setting,
1670 .format = format_string_setting,
1671 };
1672
1673 /**
1674 * Parse URI-encoded string setting value
1675 *
1676 * @v type Setting type
1677 * @v value Formatted setting value
1678 * @v buf Buffer to contain raw value
1679 * @v len Length of buffer
1680 * @ret len Length of raw value, or negative error
1681 */
1682 static int parse_uristring_setting ( const struct setting_type *type __unused,
1683 const char *value, void *buf, size_t len ){
1684
1685 return uri_decode ( value, buf, len );
1686 }
1687
1688 /**
1689 * Format URI-encoded string setting value
1690 *
1691 * @v type Setting type
1692 * @v raw Raw setting value
1693 * @v raw_len Length of raw setting value
1694 * @v buf Buffer to contain formatted value
1695 * @v len Length of buffer
1696 * @ret len Length of formatted value, or negative error
1697 */
1698 static int format_uristring_setting ( const struct setting_type *type __unused,
1699 const void *raw, size_t raw_len,
1700 char *buf, size_t len ) {
1701
1702 return uri_encode ( 0, raw, raw_len, buf, len );
1703 }
1704
1705 /** A URI-encoded string setting type */
1706 const struct setting_type setting_type_uristring __setting_type = {
1707 .name = "uristring",
1708 .parse = parse_uristring_setting,
1709 .format = format_uristring_setting,
1710 };
1711
1712 /**
1713 * Parse IPv4 address setting value (when IPv4 support is not present)
1714 *
1715 * @v type Setting type
1716 * @v value Formatted setting value
1717 * @v buf Buffer to contain raw value
1718 * @v len Length of buffer
1719 * @ret len Length of raw value, or negative error
1720 */
1721 __weak int parse_ipv4_setting ( const struct setting_type *type __unused,
1722 const char *value __unused, void *buf __unused,
1723 size_t len __unused ) {
1724 return -ENOTSUP;
1725 }
1726
1727 /**
1728 * Format IPv4 address setting value (when IPv4 support is not present)
1729 *
1730 * @v type Setting type
1731 * @v raw Raw setting value
1732 * @v raw_len Length of raw setting value
1733 * @v buf Buffer to contain formatted value
1734 * @v len Length of buffer
1735 * @ret len Length of formatted value, or negative error
1736 */
1737 __weak int format_ipv4_setting ( const struct setting_type *type __unused,
1738 const void *raw __unused,
1739 size_t raw_len __unused, char *buf __unused,
1740 size_t len __unused ) {
1741 return -ENOTSUP;
1742 }
1743
1744 /** An IPv4 address setting type */
1745 const struct setting_type setting_type_ipv4 __setting_type = {
1746 .name = "ipv4",
1747 .parse = parse_ipv4_setting,
1748 .format = format_ipv4_setting,
1749 };
1750
1751 /**
1752 * Parse IPv6 address setting value (when IPv6 support is not present)
1753 *
1754 * @v type Setting type
1755 * @v value Formatted setting value
1756 * @v buf Buffer to contain raw value
1757 * @v len Length of buffer
1758 * @ret len Length of raw value, or negative error
1759 */
1760 __weak int parse_ipv6_setting ( const struct setting_type *type __unused,
1761 const char *value __unused, void *buf __unused,
1762 size_t len __unused ) {
1763 return -ENOTSUP;
1764 }
1765
1766 /**
1767 * Format IPv6 address setting value (when IPv6 support is not present)
1768 *
1769 * @v type Setting type
1770 * @v raw Raw setting value
1771 * @v raw_len Length of raw setting value
1772 * @v buf Buffer to contain formatted value
1773 * @v len Length of buffer
1774 * @ret len Length of formatted value, or negative error
1775 */
1776 __weak int format_ipv6_setting ( const struct setting_type *type __unused,
1777 const void *raw __unused,
1778 size_t raw_len __unused, char *buf __unused,
1779 size_t len __unused ) {
1780 return -ENOTSUP;
1781 }
1782
1783 /** An IPv6 address setting type */
1784 const struct setting_type setting_type_ipv6 __setting_type = {
1785 .name = "ipv6",
1786 .parse = parse_ipv6_setting,
1787 .format = format_ipv6_setting,
1788 };
1789
1790 /** IPv6 settings scope */
1791 const struct settings_scope dhcpv6_scope;
1792
1793 /**
1794 * Integer setting type indices
1795 *
1796 * These indexes are defined such that (1<<index) gives the width of
1797 * the integer, in bytes.
1798 */
1799 enum setting_type_int_index {
1800 SETTING_TYPE_INT8 = 0,
1801 SETTING_TYPE_INT16 = 1,
1802 SETTING_TYPE_INT32 = 2,
1803 };
1804
1805 /**
1806 * Integer setting type names
1807 *
1808 * These names exist as a static array in order to allow the type's
1809 * integer size and signedness to be determined from the type's name.
1810 * Note that there are no separate entries for the signed integer
1811 * types: the name pointers simply point to the second character of
1812 * the relevant string.
1813 */
1814 static const char setting_type_int_name[][8] = {
1815 [SETTING_TYPE_INT8] = "uint8",
1816 [SETTING_TYPE_INT16] = "uint16",
1817 [SETTING_TYPE_INT32] = "uint32",
1818 };
1819
1820 /**
1821 * Get unsigned integer setting type name
1822 *
1823 * @v index Integer setting type index
1824 * @ret name Setting type name
1825 */
1826 #define SETTING_TYPE_UINT_NAME( index ) setting_type_int_name[index]
1827
1828 /**
1829 * Get signed integer setting type name
1830 *
1831 * @v index Integer setting type index
1832 * @ret name Setting type name
1833 */
1834 #define SETTING_TYPE_INT_NAME( index ) ( setting_type_int_name[index] + 1 )
1835
1836 /**
1837 * Get integer setting type index
1838 *
1839 * @v type Setting type
1840 * @ret index Integer setting type index
1841 */
1842 static unsigned int setting_type_int_index ( const struct setting_type *type ) {
1843
1844 return ( ( type->name - setting_type_int_name[0] ) /
1845 sizeof ( setting_type_int_name[0] ) );
1846 }
1847
1848 /**
1849 * Get integer setting type width
1850 *
1851 * @v type Setting type
1852 * @ret index Integer setting type width
1853 */
1854 static unsigned int setting_type_int_width ( const struct setting_type *type ) {
1855
1856 return ( 1 << setting_type_int_index ( type ) );
1857 }
1858
1859 /**
1860 * Get integer setting type signedness
1861 *
1862 * @v type Setting type
1863 * @ret is_signed Integer setting type is signed
1864 */
1865 static int setting_type_int_is_signed ( const struct setting_type *type ) {
1866 return ( ( type->name - setting_type_int_name[0] ) & 1 );
1867 }
1868
1869 /**
1870 * Convert number to setting value
1871 *
1872 * @v type Setting type
1873 * @v value Numeric value
1874 * @v buf Buffer to contain raw value
1875 * @v len Length of buffer
1876 * @ret len Length of raw value, or negative error
1877 */
1878 static int denumerate_int_setting ( const struct setting_type *type,
1879 unsigned long value, void *buf,
1880 size_t len ) {
1881 unsigned int size = setting_type_int_width ( type );
1882 union {
1883 uint32_t num;
1884 uint8_t bytes[4];
1885 } u;
1886
1887 u.num = htonl ( value );
1888 if ( len > size )
1889 len = size;
1890 memcpy ( buf, &u.bytes[ sizeof ( u ) - size ], len );
1891
1892 return size;
1893 }
1894
1895 /**
1896 * Convert setting value to number
1897 *
1898 * @v type Setting type
1899 * @v raw Raw setting value
1900 * @v raw_len Length of raw setting value
1901 * @v value Numeric value to fill in
1902 * @ret rc Return status code
1903 */
1904 static int numerate_int_setting ( const struct setting_type *type,
1905 const void *raw, size_t raw_len,
1906 unsigned long *value ) {
1907 int is_signed = setting_type_int_is_signed ( type );
1908 int check_len;
1909
1910 /* Extract numeric value */
1911 check_len = numeric_setting_value ( is_signed, raw, raw_len, value );
1912 if ( check_len < 0 )
1913 return check_len;
1914 assert ( check_len == ( int ) raw_len );
1915
1916 return 0;
1917 }
1918
1919 /**
1920 * Parse integer setting value
1921 *
1922 * @v type Setting type
1923 * @v value Formatted setting value
1924 * @v buf Buffer to contain raw value
1925 * @v len Length of buffer
1926 * @ret len Length of raw value, or negative error
1927 */
1928 static int parse_int_setting ( const struct setting_type *type,
1929 const char *value, void *buf, size_t len ) {
1930 char *endp;
1931 unsigned long num_value;
1932
1933 /* Parse value */
1934 num_value = strtoul ( value, &endp, 0 );
1935 if ( *endp )
1936 return -EINVAL;
1937
1938 return type->denumerate ( type, num_value, buf, len );
1939 }
1940
1941 /**
1942 * Format signed integer setting value
1943 *
1944 * @v type Setting type
1945 * @v raw Raw setting value
1946 * @v raw_len Length of raw setting value
1947 * @v buf Buffer to contain formatted value
1948 * @v len Length of buffer
1949 * @ret len Length of formatted value, or negative error
1950 */
1951 static int format_int_setting ( const struct setting_type *type,
1952 const void *raw, size_t raw_len,
1953 char *buf, size_t len ) {
1954 unsigned long value;
1955 int ret;
1956
1957 /* Extract numeric value */
1958 if ( ( ret = type->numerate ( type, raw, raw_len, &value ) ) < 0 )
1959 return ret;
1960
1961 /* Format value */
1962 return snprintf ( buf, len, "%ld", value );
1963 }
1964
1965 /**
1966 * Format unsigned integer setting value
1967 *
1968 * @v type Setting type
1969 * @v raw Raw setting value
1970 * @v raw_len Length of raw setting value
1971 * @v buf Buffer to contain formatted value
1972 * @v len Length of buffer
1973 * @ret len Length of formatted value, or negative error
1974 */
1975 static int format_uint_setting ( const struct setting_type *type,
1976 const void *raw, size_t raw_len,
1977 char *buf, size_t len ) {
1978 unsigned long value;
1979 int ret;
1980
1981 /* Extract numeric value */
1982 if ( ( ret = type->numerate ( type, raw, raw_len, &value ) ) < 0 )
1983 return ret;
1984
1985 /* Format value */
1986 return snprintf ( buf, len, "%#lx", value );
1987 }
1988
1989 /**
1990 * Define a signed integer setting type
1991 *
1992 * @v index Integer setting type index
1993 * @ret type Setting type
1994 */
1995 #define SETTING_TYPE_INT( index ) { \
1996 .name = SETTING_TYPE_INT_NAME ( index ), \
1997 .parse = parse_int_setting, \
1998 .format = format_int_setting, \
1999 .denumerate = denumerate_int_setting, \
2000 .numerate = numerate_int_setting, \
2001 }
2002
2003 /**
2004 * Define an unsigned integer setting type
2005 *
2006 * @v index Integer setting type index
2007 * @ret type Setting type
2008 */
2009 #define SETTING_TYPE_UINT( index ) { \
2010 .name = SETTING_TYPE_UINT_NAME ( index ), \
2011 .parse = parse_int_setting, \
2012 .format = format_uint_setting, \
2013 .denumerate = denumerate_int_setting, \
2014 .numerate = numerate_int_setting, \
2015 }
2016
2017 /** A signed 8-bit integer setting type */
2018 const struct setting_type setting_type_int8 __setting_type =
2019 SETTING_TYPE_INT ( SETTING_TYPE_INT8 );
2020
2021 /** A signed 16-bit integer setting type */
2022 const struct setting_type setting_type_int16 __setting_type =
2023 SETTING_TYPE_INT ( SETTING_TYPE_INT16 );
2024
2025 /** A signed 32-bit integer setting type */
2026 const struct setting_type setting_type_int32 __setting_type =
2027 SETTING_TYPE_INT ( SETTING_TYPE_INT32 );
2028
2029 /** An unsigned 8-bit integer setting type */
2030 const struct setting_type setting_type_uint8 __setting_type =
2031 SETTING_TYPE_UINT ( SETTING_TYPE_INT8 );
2032
2033 /** An unsigned 16-bit integer setting type */
2034 const struct setting_type setting_type_uint16 __setting_type =
2035 SETTING_TYPE_UINT ( SETTING_TYPE_INT16 );
2036
2037 /** An unsigned 32-bit integer setting type */
2038 const struct setting_type setting_type_uint32 __setting_type =
2039 SETTING_TYPE_UINT ( SETTING_TYPE_INT32 );
2040
2041 /**
2042 * Parse hex string setting value (using colon delimiter)
2043 *
2044 * @v type Setting type
2045 * @v value Formatted setting value
2046 * @v buf Buffer to contain raw value
2047 * @v len Length of buffer
2048 * @v size Integer size, in bytes
2049 * @ret len Length of raw value, or negative error
2050 */
2051 static int parse_hex_setting ( const struct setting_type *type __unused,
2052 const char *value, void *buf, size_t len ) {
2053 return hex_decode ( ':', value, buf, len );
2054 }
2055
2056 /**
2057 * Format hex string setting value (using colon delimiter)
2058 *
2059 * @v type Setting type
2060 * @v raw Raw setting value
2061 * @v raw_len Length of raw setting value
2062 * @v buf Buffer to contain formatted value
2063 * @v len Length of buffer
2064 * @ret len Length of formatted value, or negative error
2065 */
2066 static int format_hex_colon_setting ( const struct setting_type *type __unused,
2067 const void *raw, size_t raw_len,
2068 char *buf, size_t len ) {
2069 return hex_encode ( ':', raw, raw_len, buf, len );
2070 }
2071
2072 /**
2073 * Parse hex string setting value (using hyphen delimiter)
2074 *
2075 * @v type Setting type
2076 * @v value Formatted setting value
2077 * @v buf Buffer to contain raw value
2078 * @v len Length of buffer
2079 * @v size Integer size, in bytes
2080 * @ret len Length of raw value, or negative error
2081 */
2082 static int parse_hex_hyphen_setting ( const struct setting_type *type __unused,
2083 const char *value, void *buf,
2084 size_t len ) {
2085 return hex_decode ( '-', value, buf, len );
2086 }
2087
2088 /**
2089 * Format hex string setting value (using hyphen delimiter)
2090 *
2091 * @v type Setting type
2092 * @v raw Raw setting value
2093 * @v raw_len Length of raw setting value
2094 * @v buf Buffer to contain formatted value
2095 * @v len Length of buffer
2096 * @ret len Length of formatted value, or negative error
2097 */
2098 static int format_hex_hyphen_setting ( const struct setting_type *type __unused,
2099 const void *raw, size_t raw_len,
2100 char *buf, size_t len ) {
2101 return hex_encode ( '-', raw, raw_len, buf, len );
2102 }
2103
2104 /**
2105 * Parse hex string setting value (using no delimiter)
2106 *
2107 * @v type Setting type
2108 * @v value Formatted setting value
2109 * @v buf Buffer to contain raw value
2110 * @v len Length of buffer
2111 * @v size Integer size, in bytes
2112 * @ret len Length of raw value, or negative error
2113 */
2114 static int parse_hex_raw_setting ( const struct setting_type *type __unused,
2115 const char *value, void *buf, size_t len ) {
2116 return hex_decode ( 0, value, buf, len );
2117 }
2118
2119 /**
2120 * Format hex string setting value (using no delimiter)
2121 *
2122 * @v type Setting type
2123 * @v raw Raw setting value
2124 * @v raw_len Length of raw setting value
2125 * @v buf Buffer to contain formatted value
2126 * @v len Length of buffer
2127 * @ret len Length of formatted value, or negative error
2128 */
2129 static int format_hex_raw_setting ( const struct setting_type *type __unused,
2130 const void *raw, size_t raw_len,
2131 char *buf, size_t len ) {
2132 return hex_encode ( 0, raw, raw_len, buf, len );
2133 }
2134
2135 /** A hex-string setting (colon-delimited) */
2136 const struct setting_type setting_type_hex __setting_type = {
2137 .name = "hex",
2138 .parse = parse_hex_setting,
2139 .format = format_hex_colon_setting,
2140 };
2141
2142 /** A hex-string setting (hyphen-delimited) */
2143 const struct setting_type setting_type_hexhyp __setting_type = {
2144 .name = "hexhyp",
2145 .parse = parse_hex_hyphen_setting,
2146 .format = format_hex_hyphen_setting,
2147 };
2148
2149 /** A hex-string setting (non-delimited) */
2150 const struct setting_type setting_type_hexraw __setting_type = {
2151 .name = "hexraw",
2152 .parse = parse_hex_raw_setting,
2153 .format = format_hex_raw_setting,
2154 };
2155
2156 /**
2157 * Parse Base64-encoded setting value
2158 *
2159 * @v type Setting type
2160 * @v value Formatted setting value
2161 * @v buf Buffer to contain raw value
2162 * @v len Length of buffer
2163 * @v size Integer size, in bytes
2164 * @ret len Length of raw value, or negative error
2165 */
2166 static int parse_base64_setting ( const struct setting_type *type __unused,
2167 const char *value, void *buf, size_t len ) {
2168
2169 return base64_decode ( value, buf, len );
2170 }
2171
2172 /**
2173 * Format Base64-encoded setting value
2174 *
2175 * @v type Setting type
2176 * @v raw Raw setting value
2177 * @v raw_len Length of raw setting value
2178 * @v buf Buffer to contain formatted value
2179 * @v len Length of buffer
2180 * @ret len Length of formatted value, or negative error
2181 */
2182 static int format_base64_setting ( const struct setting_type *type __unused,
2183 const void *raw, size_t raw_len,
2184 char *buf, size_t len ) {
2185
2186 return base64_encode ( raw, raw_len, buf, len );
2187 }
2188
2189 /** A Base64-encoded setting */
2190 const struct setting_type setting_type_base64 __setting_type = {
2191 .name = "base64",
2192 .parse = parse_base64_setting,
2193 .format = format_base64_setting,
2194 };
2195
2196 /**
2197 * Format UUID setting value
2198 *
2199 * @v type Setting type
2200 * @v raw Raw setting value
2201 * @v raw_len Length of raw setting value
2202 * @v buf Buffer to contain formatted value
2203 * @v len Length of buffer
2204 * @ret len Length of formatted value, or negative error
2205 */
2206 static int format_uuid_setting ( const struct setting_type *type __unused,
2207 const void *raw, size_t raw_len, char *buf,
2208 size_t len ) {
2209 const union uuid *uuid = raw;
2210
2211 /* Range check */
2212 if ( raw_len != sizeof ( *uuid ) )
2213 return -ERANGE;
2214
2215 /* Format value */
2216 return snprintf ( buf, len, "%s", uuid_ntoa ( uuid ) );
2217 }
2218
2219 /** UUID setting type */
2220 const struct setting_type setting_type_uuid __setting_type = {
2221 .name = "uuid",
2222 .format = format_uuid_setting,
2223 };
2224
2225 /**
2226 * Format PCI bus:dev.fn setting value
2227 *
2228 * @v type Setting type
2229 * @v raw Raw setting value
2230 * @v raw_len Length of raw setting value
2231 * @v buf Buffer to contain formatted value
2232 * @v len Length of buffer
2233 * @ret len Length of formatted value, or negative error
2234 */
2235 static int format_busdevfn_setting ( const struct setting_type *type __unused,
2236 const void *raw, size_t raw_len, char *buf,
2237 size_t len ) {
2238 unsigned long busdevfn;
2239 unsigned int seg;
2240 unsigned int bus;
2241 unsigned int slot;
2242 unsigned int func;
2243 int check_len;
2244
2245 /* Extract numeric value */
2246 check_len = numeric_setting_value ( 0, raw, raw_len, &busdevfn );
2247 if ( check_len < 0 )
2248 return check_len;
2249 assert ( check_len == ( int ) raw_len );
2250
2251 /* Extract PCI address components */
2252 seg = PCI_SEG ( busdevfn );
2253 bus = PCI_BUS ( busdevfn );
2254 slot = PCI_SLOT ( busdevfn );
2255 func = PCI_FUNC ( busdevfn );
2256
2257 /* Format value */
2258 return snprintf ( buf, len, "%04x:%02x:%02x.%x", seg, bus, slot, func );
2259 }
2260
2261 /** PCI bus:dev.fn setting type */
2262 const struct setting_type setting_type_busdevfn __setting_type = {
2263 .name = "busdevfn",
2264 .format = format_busdevfn_setting,
2265 };
2266
2267 /******************************************************************************
2268 *
2269 * Setting expansion
2270 *
2271 ******************************************************************************
2272 */
2273
2274 /**
2275 * Expand variables within string
2276 *
2277 * @v string String
2278 * @ret expstr Expanded string
2279 *
2280 * The expanded string is allocated with malloc() and the caller must
2281 * eventually free() it.
2282 */
2283 char * expand_settings ( const char *string ) {
2284 struct settings *settings;
2285 struct setting setting;
2286 char *expstr;
2287 char *start;
2288 char *end;
2289 char *head;
2290 char *name;
2291 char *tail;
2292 char *value;
2293 char *tmp;
2294 int new_len;
2295 int rc;
2296
2297 /* Obtain temporary modifiable copy of string */
2298 expstr = strdup ( string );
2299 if ( ! expstr )
2300 return NULL;
2301
2302 /* Expand while expansions remain */
2303 while ( 1 ) {
2304
2305 head = expstr;
2306
2307 /* Locate setting to be expanded */
2308 start = NULL;
2309 end = NULL;
2310 for ( tmp = expstr ; *tmp ; tmp++ ) {
2311 if ( ( tmp[0] == '$' ) && ( tmp[1] == '{' ) )
2312 start = tmp;
2313 if ( start && ( tmp[0] == '}' ) ) {
2314 end = tmp;
2315 break;
2316 }
2317 }
2318 if ( ! end )
2319 break;
2320 *start = '\0';
2321 name = ( start + 2 );
2322 *end = '\0';
2323 tail = ( end + 1 );
2324
2325 /* Expand setting */
2326 if ( ( rc = parse_setting_name ( name, find_child_settings,
2327 &settings,
2328 &setting ) ) != 0 ) {
2329 /* Treat invalid setting names as empty */
2330 value = NULL;
2331 } else {
2332 /* Fetch and format setting value. Ignore
2333 * errors; treat non-existent settings as empty.
2334 */
2335 fetchf_setting_copy ( settings, &setting, NULL, NULL,
2336 &value );
2337 }
2338
2339 /* Construct expanded string and discard old string */
2340 tmp = expstr;
2341 new_len = asprintf ( &expstr, "%s%s%s",
2342 head, ( value ? value : "" ), tail );
2343 free ( value );
2344 free ( tmp );
2345 if ( new_len < 0 )
2346 return NULL;
2347 }
2348
2349 return expstr;
2350 }
2351
2352 /******************************************************************************
2353 *
2354 * Settings
2355 *
2356 ******************************************************************************
2357 */
2358
2359 /** Hostname setting */
2360 const struct setting hostname_setting __setting ( SETTING_HOST, hostname ) = {
2361 .name = "hostname",
2362 .description = "Host name",
2363 .tag = DHCP_HOST_NAME,
2364 .type = &setting_type_string,
2365 };
2366
2367 /** Domain name setting */
2368 const struct setting domain_setting __setting ( SETTING_IP_EXTRA, domain ) = {
2369 .name = "domain",
2370 .description = "DNS domain",
2371 .tag = DHCP_DOMAIN_NAME,
2372 .type = &setting_type_string,
2373 };
2374
2375 /** TFTP server setting */
2376 const struct setting next_server_setting __setting ( SETTING_BOOT,next-server)={
2377 .name = "next-server",
2378 .description = "TFTP server",
2379 .tag = DHCP_EB_SIADDR,
2380 .type = &setting_type_ipv4,
2381 };
2382
2383 /** Filename setting */
2384 const struct setting filename_setting __setting ( SETTING_BOOT, filename ) = {
2385 .name = "filename",
2386 .description = "Boot filename",
2387 .tag = DHCP_BOOTFILE_NAME,
2388 .type = &setting_type_string,
2389 };
2390
2391 /** Root path setting */
2392 const struct setting root_path_setting __setting ( SETTING_SANBOOT, root-path)={
2393 .name = "root-path",
2394 .description = "SAN root path",
2395 .tag = DHCP_ROOT_PATH,
2396 .type = &setting_type_string,
2397 };
2398
2399 /** SAN filename setting */
2400 const struct setting san_filename_setting __setting ( SETTING_SANBOOT,
2401 san-filename ) = {
2402 .name = "san-filename",
2403 .description = "SAN filename",
2404 .tag = DHCP_EB_SAN_FILENAME,
2405 .type = &setting_type_string,
2406 };
2407
2408 /** Username setting */
2409 const struct setting username_setting __setting ( SETTING_AUTH, username ) = {
2410 .name = "username",
2411 .description = "User name",
2412 .tag = DHCP_EB_USERNAME,
2413 .type = &setting_type_string,
2414 };
2415
2416 /** Password setting */
2417 const struct setting password_setting __setting ( SETTING_AUTH, password ) = {
2418 .name = "password",
2419 .description = "Password",
2420 .tag = DHCP_EB_PASSWORD,
2421 .type = &setting_type_string,
2422 };
2423
2424 /** Priority setting */
2425 const struct setting priority_setting __setting ( SETTING_MISC, priority ) = {
2426 .name = "priority",
2427 .description = "Settings priority",
2428 .tag = DHCP_EB_PRIORITY,
2429 .type = &setting_type_int8,
2430 };
2431
2432 /** DHCP user class setting */
2433 const struct setting user_class_setting __setting ( SETTING_HOST_EXTRA,
2434 user-class ) = {
2435 .name = "user-class",
2436 .description = "DHCP user class",
2437 .tag = DHCP_USER_CLASS_ID,
2438 .type = &setting_type_string,
2439 };
2440
2441 /** DHCP vendor class setting */
2442 const struct setting vendor_class_setting __setting ( SETTING_HOST_EXTRA,
2443 vendor-class ) = {
2444 .name = "vendor-class",
2445 .description = "DHCP vendor class",
2446 .tag = DHCP_VENDOR_CLASS_ID,
2447 .type = &setting_type_string,
2448 };
2449
2450 /******************************************************************************
2451 *
2452 * Built-in settings block
2453 *
2454 ******************************************************************************
2455 */
2456
2457 /** Built-in setting scope */
2458 const struct settings_scope builtin_scope;
2459
2460 /**
2461 * Fetch error number setting
2462 *
2463 * @v data Buffer to fill with setting data
2464 * @v len Length of buffer
2465 * @ret len Length of setting data, or negative error
2466 */
2467 static int errno_fetch ( void *data, size_t len ) {
2468 uint32_t content;
2469
2470 /* Return current error */
2471 content = htonl ( errno );
2472 if ( len > sizeof ( content ) )
2473 len = sizeof ( content );
2474 memcpy ( data, &content, len );
2475 return sizeof ( content );
2476 }
2477
2478 /** Error number setting */
2479 const struct setting errno_setting __setting ( SETTING_MISC, errno ) = {
2480 .name = "errno",
2481 .description = "Last error",
2482 .type = &setting_type_uint32,
2483 .scope = &builtin_scope,
2484 };
2485
2486 /** Error number built-in setting */
2487 struct builtin_setting errno_builtin_setting __builtin_setting = {
2488 .setting = &errno_setting,
2489 .fetch = errno_fetch,
2490 };
2491
2492 /**
2493 * Fetch build architecture setting
2494 *
2495 * @v data Buffer to fill with setting data
2496 * @v len Length of buffer
2497 * @ret len Length of setting data, or negative error
2498 */
2499 static int buildarch_fetch ( void *data, size_t len ) {
2500 static const char buildarch[] = _S2 ( ARCH );
2501
2502 strncpy ( data, buildarch, len );
2503 return ( sizeof ( buildarch ) - 1 /* NUL */ );
2504 }
2505
2506 /** Build architecture setting */
2507 const struct setting buildarch_setting __setting ( SETTING_MISC, buildarch ) = {
2508 .name = "buildarch",
2509 .description = "Build architecture",
2510 .type = &setting_type_string,
2511 .scope = &builtin_scope,
2512 };
2513
2514 /** Build architecture built-in setting */
2515 struct builtin_setting buildarch_builtin_setting __builtin_setting = {
2516 .setting = &buildarch_setting,
2517 .fetch = buildarch_fetch,
2518 };
2519
2520 /**
2521 * Fetch platform setting
2522 *
2523 * @v data Buffer to fill with setting data
2524 * @v len Length of buffer
2525 * @ret len Length of setting data, or negative error
2526 */
2527 static int platform_fetch ( void *data, size_t len ) {
2528 static const char platform[] = _S2 ( PLATFORM );
2529
2530 strncpy ( data, platform, len );
2531 return ( sizeof ( platform ) - 1 /* NUL */ );
2532 }
2533
2534 /** Platform setting */
2535 const struct setting platform_setting __setting ( SETTING_MISC, platform ) = {
2536 .name = "platform",
2537 .description = "Platform",
2538 .type = &setting_type_string,
2539 .scope = &builtin_scope,
2540 };
2541
2542 /** Platform built-in setting */
2543 struct builtin_setting platform_builtin_setting __builtin_setting = {
2544 .setting = &platform_setting,
2545 .fetch = platform_fetch,
2546 };
2547
2548 /**
2549 * Fetch version setting
2550 *
2551 * @v data Buffer to fill with setting data
2552 * @v len Length of buffer
2553 * @ret len Length of setting data, or negative error
2554 */
2555 static int version_fetch ( void *data, size_t len ) {
2556 strncpy ( data, product_version, len );
2557 return ( strlen ( product_version ) );
2558 }
2559
2560 /** Version setting */
2561 const struct setting version_setting __setting ( SETTING_MISC, version ) = {
2562 .name = "version",
2563 .description = "Version",
2564 .type = &setting_type_string,
2565 .scope = &builtin_scope,
2566 };
2567
2568 /** Version built-in setting */
2569 struct builtin_setting version_builtin_setting __builtin_setting = {
2570 .setting = &version_setting,
2571 .fetch = version_fetch,
2572 };
2573
2574 /**
2575 * Fetch current time setting
2576 *
2577 * @v data Buffer to fill with setting data
2578 * @v len Length of buffer
2579 * @ret len Length of setting data, or negative error
2580 */
2581 static int unixtime_fetch ( void *data, size_t len ) {
2582 uint32_t content;
2583
2584 /* Return current time */
2585 content = htonl ( time(NULL) );
2586 if ( len > sizeof ( content ) )
2587 len = sizeof ( content );
2588 memcpy ( data, &content, len );
2589 return sizeof ( content );
2590 }
2591
2592 /** Current time setting */
2593 const struct setting unixtime_setting __setting ( SETTING_MISC, unixtime ) = {
2594 .name = "unixtime",
2595 .description = "Seconds since the Epoch",
2596 .type = &setting_type_uint32,
2597 .scope = &builtin_scope,
2598 };
2599
2600 /** Current time built-in setting */
2601 struct builtin_setting unixtime_builtin_setting __builtin_setting = {
2602 .setting = &unixtime_setting,
2603 .fetch = unixtime_fetch,
2604 };
2605
2606 /**
2607 * Fetch built-in setting
2608 *
2609 * @v settings Settings block
2610 * @v setting Setting to fetch
2611 * @v data Buffer to fill with setting data
2612 * @v len Length of buffer
2613 * @ret len Length of setting data, or negative error
2614 */
2615 static int builtin_fetch ( struct settings *settings __unused,
2616 struct setting *setting,
2617 void *data, size_t len ) {
2618 struct builtin_setting *builtin;
2619
2620 for_each_table_entry ( builtin, BUILTIN_SETTINGS ) {
2621 if ( setting_cmp ( setting, builtin->setting ) == 0 )
2622 return builtin->fetch ( data, len );
2623 }
2624 return -ENOENT;
2625 }
2626
2627 /**
2628 * Check applicability of built-in setting
2629 *
2630 * @v settings Settings block
2631 * @v setting Setting
2632 * @ret applies Setting applies within this settings block
2633 */
2634 static int builtin_applies ( struct settings *settings __unused,
2635 const struct setting *setting ) {
2636
2637 return ( setting->scope == &builtin_scope );
2638 }
2639
2640 /** Built-in settings operations */
2641 static struct settings_operations builtin_settings_operations = {
2642 .applies = builtin_applies,
2643 .fetch = builtin_fetch,
2644 };
2645
2646 /** Built-in settings */
2647 static struct settings builtin_settings = {
2648 .refcnt = NULL,
2649 .siblings = LIST_HEAD_INIT ( builtin_settings.siblings ),
2650 .children = LIST_HEAD_INIT ( builtin_settings.children ),
2651 .op = &builtin_settings_operations,
2652 };
2653
2654 /** Initialise built-in settings */
2655 static void builtin_init ( void ) {
2656 int rc;
2657
2658 if ( ( rc = register_settings ( &builtin_settings, NULL,
2659 "builtin" ) ) != 0 ) {
2660 DBG ( "Could not register built-in settings: %s\n",
2661 strerror ( rc ) );
2662 return;
2663 }
2664 }
2665
2666 /** Built-in settings initialiser */
2667 struct init_fn builtin_init_fn __init_fn ( INIT_NORMAL ) = {
2668 .initialise = builtin_init,
2669 };