87d84a08331ec78c340d6281cc2350ab23954bef
[people/cooldavid/gpxe.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., 675 Mass Ave, Cambridge, MA 02139, USA.
17  */
18
19 FILE_LICENCE ( GPL2_OR_LATER );
20
21 #include <stdint.h>
22 #include <stdlib.h>
23 #include <stdio.h>
24 #include <string.h>
25 #include <strings.h>
26 #include <byteswap.h>
27 #include <errno.h>
28 #include <assert.h>
29 #include <gpxe/in.h>
30 #include <gpxe/vsprintf.h>
31 #include <gpxe/dhcp.h>
32 #include <gpxe/uuid.h>
33 #include <gpxe/uri.h>
34 #include <gpxe/settings.h>
35
36 /** @file
37  *
38  * Configuration settings
39  *
40  */
41
42 /******************************************************************************
43  *
44  * Generic settings blocks
45  *
46  ******************************************************************************
47  */
48
49 /**
50  * A generic setting
51  *
52  */
53 struct generic_setting {
54         /** List of generic settings */
55         struct list_head list;
56         /** Setting */
57         struct setting setting;
58         /** Size of setting name */
59         size_t name_len;
60         /** Size of setting data */
61         size_t data_len;
62 };
63
64 /**
65  * Get generic setting name
66  *
67  * @v generic           Generic setting
68  * @ret name            Generic setting name
69  */
70 static inline void * generic_setting_name ( struct generic_setting *generic ) {
71         return ( ( ( void * ) generic ) + sizeof ( *generic ) );
72 }
73
74 /**
75  * Get generic setting data
76  *
77  * @v generic           Generic setting
78  * @ret data            Generic setting data
79  */
80 static inline void * generic_setting_data ( struct generic_setting *generic ) {
81         return ( ( ( void * ) generic ) + sizeof ( *generic ) +
82                  generic->name_len );
83 }
84
85 /**
86  * Find generic setting
87  *
88  * @v generics          Generic settings block
89  * @v setting           Setting to find
90  * @ret generic         Generic setting, or NULL
91  */
92 static struct generic_setting *
93 find_generic_setting ( struct generic_settings *generics,
94                        struct setting *setting ) {
95         struct generic_setting *generic;
96
97         list_for_each_entry ( generic, &generics->list, list ) {
98                 if ( setting_cmp ( &generic->setting, setting ) == 0 )
99                         return generic;
100         }
101         return NULL;
102 }
103
104 /**
105  * Store value of generic setting
106  *
107  * @v settings          Settings block
108  * @v setting           Setting to store
109  * @v data              Setting data, or NULL to clear setting
110  * @v len               Length of setting data
111  * @ret rc              Return status code
112  */
113 int generic_settings_store ( struct settings *settings,
114                              struct setting *setting,
115                              const void *data, size_t len ) {
116         struct generic_settings *generics =
117                 container_of ( settings, struct generic_settings, settings );
118         struct generic_setting *old;
119         struct generic_setting *new = NULL;
120         size_t name_len;
121
122         /* Identify existing generic setting, if any */
123         old = find_generic_setting ( generics, setting );
124
125         /* Create new generic setting, if required */
126         if ( len ) {
127                 /* Allocate new generic setting */
128                 name_len = ( strlen ( setting->name ) + 1 );
129                 new = zalloc ( sizeof ( *new ) + name_len + len );
130                 if ( ! new )
131                         return -ENOMEM;
132
133                 /* Populate new generic setting */
134                 new->name_len = name_len;
135                 new->data_len = len;
136                 memcpy ( &new->setting, setting, sizeof ( new->setting ) );
137                 new->setting.name = generic_setting_name ( new );
138                 memcpy ( generic_setting_name ( new ),
139                          setting->name, name_len );
140                 memcpy ( generic_setting_data ( new ), data, len );
141         }
142
143         /* Delete existing generic setting, if any */
144         if ( old ) {
145                 list_del ( &old->list );
146                 free ( old );
147         }
148
149         /* Add new setting to list, if any */
150         if ( new )
151                 list_add ( &new->list, &generics->list );
152
153         return 0;
154 }
155
156 /**
157  * Fetch value of generic setting
158  *
159  * @v settings          Settings block
160  * @v setting           Setting to fetch
161  * @v data              Buffer to fill with setting data
162  * @v len               Length of buffer
163  * @ret len             Length of setting data, or negative error
164  */
165 int generic_settings_fetch ( struct settings *settings,
166                              struct setting *setting,
167                              void *data, size_t len ) {
168         struct generic_settings *generics =
169                 container_of ( settings, struct generic_settings, settings );
170         struct generic_setting *generic;
171
172         /* Find generic setting */
173         generic = find_generic_setting ( generics, setting );
174         if ( ! generic )
175                 return -ENOENT;
176
177         /* Copy out generic setting data */
178         if ( len > generic->data_len )
179                 len = generic->data_len;
180         memcpy ( data, generic_setting_data ( generic ), len );
181         return generic->data_len;
182 }
183
184 /**
185  * Clear generic settings block
186  *
187  * @v settings          Settings block
188  */
189 void generic_settings_clear ( struct settings *settings ) {
190         struct generic_settings *generics =
191                 container_of ( settings, struct generic_settings, settings );
192         struct generic_setting *generic;
193         struct generic_setting *tmp;
194
195         list_for_each_entry_safe ( generic, tmp, &generics->list, list ) {
196                 list_del ( &generic->list );
197                 free ( generic );
198         }
199         assert ( list_empty ( &generics->list ) );
200 }
201
202 /** Generic settings operations */
203 struct settings_operations generic_settings_operations = {
204         .store = generic_settings_store,
205         .fetch = generic_settings_fetch,
206         .clear = generic_settings_clear,
207 };
208
209 /******************************************************************************
210  *
211  * Registered settings blocks
212  *
213  ******************************************************************************
214  */
215
216 /** Root generic settings block */
217 struct generic_settings generic_settings_root = {
218         .settings = {
219                 .refcnt = NULL,
220                 .name = "",
221                 .siblings =
222                     LIST_HEAD_INIT ( generic_settings_root.settings.siblings ),
223                 .children =
224                     LIST_HEAD_INIT ( generic_settings_root.settings.children ),
225                 .op = &generic_settings_operations,
226         },
227         .list = LIST_HEAD_INIT ( generic_settings_root.list ),
228 };
229
230 /** Root settings block */
231 #define settings_root generic_settings_root.settings
232
233 /**
234  * Find child named settings block
235  *
236  * @v parent            Parent settings block
237  * @v name              Name within this parent
238  * @ret settings        Settings block, or NULL
239  */
240 static struct settings * find_child_settings ( struct settings *parent,
241                                                const char *name ) {
242         struct settings *settings;
243
244         /* Treat empty name as meaning "this block" */
245         if ( ! *name )
246                 return parent;
247
248         /* Look for child with matching name */
249         list_for_each_entry ( settings, &parent->children, siblings ) {
250                 if ( strcmp ( settings->name, name ) == 0 )
251                         return settings;
252         }
253
254         return NULL;
255 }
256
257 /**
258  * Find or create child named settings block
259  *
260  * @v parent            Parent settings block
261  * @v name              Name within this parent
262  * @ret settings        Settings block, or NULL
263  */
264 static struct settings * autovivify_child_settings ( struct settings *parent,
265                                                      const char *name ) {
266         struct {
267                 struct generic_settings generic;
268                 char name[ strlen ( name ) + 1 /* NUL */ ];
269         } *new_child;
270         struct settings *settings;
271
272         /* Return existing settings, if existent */
273         if ( ( settings = find_child_settings ( parent, name ) ) != NULL )
274                 return settings;
275
276         /* Create new generic settings block */
277         new_child = zalloc ( sizeof ( *new_child ) );
278         if ( ! new_child ) {
279                 DBGC ( parent, "Settings %p could not create child %s\n",
280                        parent, name );
281                 return NULL;
282         }
283         memcpy ( new_child->name, name, sizeof ( new_child->name ) );
284         generic_settings_init ( &new_child->generic, NULL, new_child->name );
285         settings = &new_child->generic.settings;
286         register_settings ( settings, parent );
287         return settings;
288 }
289
290 /**
291  * Return settings block name (for debug only)
292  *
293  * @v settings          Settings block
294  * @ret name            Settings block name
295  */
296 static const char * settings_name ( struct settings *settings ) {
297         static char buf[64];
298         char tmp[ sizeof ( buf ) ];
299         int count;
300
301         for ( count = 0 ; settings ; settings = settings->parent ) {
302                 memcpy ( tmp, buf, sizeof ( tmp ) );
303                 snprintf ( buf, sizeof ( buf ), "%s%c%s", settings->name,
304                            ( count++ ? '.' : '\0' ), tmp );
305         }
306         return ( buf + 1 );
307 }
308
309 /**
310  * Parse settings block name
311  *
312  * @v name              Name
313  * @v get_child         Function to find or create child settings block
314  * @ret settings        Settings block, or NULL
315  */
316 static struct settings *
317 parse_settings_name ( const char *name,
318                       struct settings * ( * get_child ) ( struct settings *,
319                                                           const char * ) ) {
320         struct settings *settings = &settings_root;
321         char name_copy[ strlen ( name ) + 1 ];
322         char *subname;
323         char *remainder;
324
325         /* Create modifiable copy of name */
326         memcpy ( name_copy, name, sizeof ( name_copy ) );
327         remainder = name_copy;
328
329         /* Parse each name component in turn */
330         while ( remainder ) {
331                 subname = remainder;
332                 remainder = strchr ( subname, '.' );
333                 if ( remainder )
334                         *(remainder++) = '\0';
335                 settings = get_child ( settings, subname );
336                 if ( ! settings )
337                         break;
338         }
339
340         return settings;
341 }
342
343 /**
344  * Find named settings block
345  *
346  * @v name              Name
347  * @ret settings        Settings block, or NULL
348  */
349 struct settings * find_settings ( const char *name ) {
350
351         return parse_settings_name ( name, find_child_settings );
352 }
353
354 /**
355  * Apply all settings
356  *
357  * @ret rc              Return status code
358  */
359 static int apply_settings ( void ) {
360         struct settings_applicator *applicator;
361         int rc;
362
363         /* Call all settings applicators */
364         for_each_table_entry ( applicator, SETTINGS_APPLICATORS ) {
365                 if ( ( rc = applicator->apply() ) != 0 ) {
366                         DBG ( "Could not apply settings using applicator "
367                               "%p: %s\n", applicator, strerror ( rc ) );
368                         return rc;
369                 }
370         }
371
372         return 0;
373 }
374
375 /**
376  * Reprioritise settings
377  *
378  * @v settings          Settings block
379  *
380  * Reorders the settings block amongst its siblings according to its
381  * priority.
382  */
383 static void reprioritise_settings ( struct settings *settings ) {
384         struct settings *parent = settings->parent;
385         long priority;
386         struct settings *tmp;
387         long tmp_priority;
388
389         /* Stop when we reach the top of the tree */
390         if ( ! parent )
391                 return;
392
393         /* Read priority, if present */
394         priority = fetch_intz_setting ( settings, &priority_setting );
395
396         /* Remove from siblings list */
397         list_del ( &settings->siblings );
398
399         /* Reinsert after any existing blocks which have a higher priority */
400         list_for_each_entry ( tmp, &parent->children, siblings ) {
401                 tmp_priority = fetch_intz_setting ( tmp, &priority_setting );
402                 if ( priority > tmp_priority )
403                         break;
404         }
405         list_add_tail ( &settings->siblings, &tmp->siblings );
406
407         /* Recurse up the tree */
408         reprioritise_settings ( parent );
409 }
410
411 /**
412  * Register settings block
413  *
414  * @v settings          Settings block
415  * @v parent            Parent settings block, or NULL
416  * @ret rc              Return status code
417  */
418 int register_settings ( struct settings *settings, struct settings *parent ) {
419         struct settings *old_settings;
420
421         /* NULL parent => add to settings root */
422         assert ( settings != NULL );
423         if ( parent == NULL )
424                 parent = &settings_root;
425
426         /* Remove any existing settings with the same name */
427         if ( ( old_settings = find_child_settings ( parent, settings->name ) ))
428                 unregister_settings ( old_settings );
429
430         /* Add to list of settings */
431         ref_get ( settings->refcnt );
432         ref_get ( parent->refcnt );
433         settings->parent = parent;
434         list_add_tail ( &settings->siblings, &parent->children );
435         DBGC ( settings, "Settings %p (\"%s\") registered\n",
436                settings, settings_name ( settings ) );
437
438         /* Fix up settings priority */
439         reprioritise_settings ( settings );
440
441         /* Apply potentially-updated settings */
442         apply_settings();
443
444         return 0;
445 }
446
447 /**
448  * Unregister settings block
449  *
450  * @v settings          Settings block
451  */
452 void unregister_settings ( struct settings *settings ) {
453
454         DBGC ( settings, "Settings %p (\"%s\") unregistered\n",
455                settings, settings_name ( settings ) );
456
457         /* Remove from list of settings */
458         ref_put ( settings->refcnt );
459         ref_put ( settings->parent->refcnt );
460         settings->parent = NULL;
461         list_del ( &settings->siblings );
462
463         /* Apply potentially-updated settings */
464         apply_settings();
465 }
466
467 /******************************************************************************
468  *
469  * Core settings routines
470  *
471  ******************************************************************************
472  */
473
474 /**
475  * Store value of setting
476  *
477  * @v settings          Settings block, or NULL
478  * @v setting           Setting to store
479  * @v data              Setting data, or NULL to clear setting
480  * @v len               Length of setting data
481  * @ret rc              Return status code
482  */
483 int store_setting ( struct settings *settings, struct setting *setting,
484                     const void *data, size_t len ) {
485         int rc;
486
487         /* NULL settings implies storing into the global settings root */
488         if ( ! settings )
489                 settings = &settings_root;
490
491         /* Sanity check */
492         if ( ! settings->op->store )
493                 return -ENOTSUP;
494
495         /* Store setting */
496         if ( ( rc = settings->op->store ( settings, setting,
497                                           data, len ) ) != 0 )
498                 return rc;
499
500         /* Reprioritise settings if necessary */
501         if ( setting_cmp ( setting, &priority_setting ) == 0 )
502                 reprioritise_settings ( settings );
503
504         /* If these settings are registered, apply potentially-updated
505          * settings
506          */
507         for ( ; settings ; settings = settings->parent ) {
508                 if ( settings == &settings_root ) {
509                         if ( ( rc = apply_settings() ) != 0 )
510                                 return rc;
511                         break;
512                 }
513         }
514
515         return 0;
516 }
517
518 /**
519  * Fetch value of setting
520  *
521  * @v settings          Settings block, or NULL to search all blocks
522  * @v setting           Setting to fetch
523  * @v data              Buffer to fill with setting data
524  * @v len               Length of buffer
525  * @ret len             Length of setting data, or negative error
526  *
527  * The actual length of the setting will be returned even if
528  * the buffer was too small.
529  */
530 int fetch_setting ( struct settings *settings, struct setting *setting,
531                     void *data, size_t len ) {
532         struct settings *child;
533         int ret;
534
535         /* Avoid returning uninitialised data on error */
536         memset ( data, 0, len );
537
538         /* NULL settings implies starting at the global settings root */
539         if ( ! settings )
540                 settings = &settings_root;
541
542         /* Sanity check */
543         if ( ! settings->op->fetch )
544                 return -ENOTSUP;
545
546         /* Try this block first */
547         if ( ( ret = settings->op->fetch ( settings, setting,
548                                            data, len ) ) >= 0 )
549                 return ret;
550
551         /* Recurse into each child block in turn */
552         list_for_each_entry ( child, &settings->children, siblings ) {
553                 if ( ( ret = fetch_setting ( child, setting,
554                                              data, len ) ) >= 0 )
555                         return ret;
556         }
557
558         return -ENOENT;
559 }
560
561 /**
562  * Fetch length of setting
563  *
564  * @v settings          Settings block, or NULL to search all blocks
565  * @v setting           Setting to fetch
566  * @ret len             Length of setting data, or negative error
567  *
568  * This function can also be used as an existence check for the
569  * setting.
570  */
571 int fetch_setting_len ( struct settings *settings, struct setting *setting ) {
572         return fetch_setting ( settings, setting, NULL, 0 );
573 }
574
575 /**
576  * Fetch value of string setting
577  *
578  * @v settings          Settings block, or NULL to search all blocks
579  * @v setting           Setting to fetch
580  * @v data              Buffer to fill with setting string data
581  * @v len               Length of buffer
582  * @ret len             Length of string setting, or negative error
583  *
584  * The resulting string is guaranteed to be correctly NUL-terminated.
585  * The returned length will be the length of the underlying setting
586  * data.
587  */
588 int fetch_string_setting ( struct settings *settings, struct setting *setting,
589                            char *data, size_t len ) {
590         memset ( data, 0, len );
591         return fetch_setting ( settings, setting, data,
592                                ( ( len > 0 ) ? ( len - 1 ) : 0 ) );
593 }
594
595 /**
596  * Fetch value of string setting
597  *
598  * @v settings          Settings block, or NULL to search all blocks
599  * @v setting           Setting to fetch
600  * @v data              Buffer to allocate and fill with setting string data
601  * @ret len             Length of string setting, or negative error
602  *
603  * The resulting string is guaranteed to be correctly NUL-terminated.
604  * The returned length will be the length of the underlying setting
605  * data.  The caller is responsible for eventually freeing the
606  * allocated buffer.
607  */
608 int fetch_string_setting_copy ( struct settings *settings,
609                                 struct setting *setting,
610                                 char **data ) {
611         int len;
612         int check_len = 0;
613
614         len = fetch_setting_len ( settings, setting );
615         if ( len < 0 )
616                 return len;
617
618         *data = malloc ( len + 1 );
619         if ( ! *data )
620                 return -ENOMEM;
621
622         check_len = fetch_string_setting ( settings, setting, *data,
623                                            ( len + 1 ) );
624         assert ( check_len == len );
625         return len;
626 }
627
628 /**
629  * Fetch value of IPv4 address setting
630  *
631  * @v settings          Settings block, or NULL to search all blocks
632  * @v setting           Setting to fetch
633  * @v inp               IPv4 address to fill in
634  * @ret len             Length of setting, or negative error
635  */
636 int fetch_ipv4_setting ( struct settings *settings, struct setting *setting,
637                          struct in_addr *inp ) {
638         int len;
639
640         len = fetch_setting ( settings, setting, inp, sizeof ( *inp ) );
641         if ( len < 0 )
642                 return len;
643         if ( len < ( int ) sizeof ( *inp ) )
644                 return -ERANGE;
645         return len;
646 }
647
648 /**
649  * Fetch value of signed integer setting
650  *
651  * @v settings          Settings block, or NULL to search all blocks
652  * @v setting           Setting to fetch
653  * @v value             Integer value to fill in
654  * @ret len             Length of setting, or negative error
655  */
656 int fetch_int_setting ( struct settings *settings, struct setting *setting,
657                         long *value ) {
658         union {
659                 uint8_t u8[ sizeof ( long ) ];
660                 int8_t s8[ sizeof ( long ) ];
661         } buf;
662         int len;
663         int i;
664
665         /* Avoid returning uninitialised data on error */
666         *value = 0;
667
668         /* Fetch raw (network-ordered, variable-length) setting */
669         len = fetch_setting ( settings, setting, &buf, sizeof ( buf ) );
670         if ( len < 0 )
671                 return len;
672         if ( len > ( int ) sizeof ( buf ) )
673                 return -ERANGE;
674
675         /* Convert to host-ordered signed long */
676         *value = ( ( buf.s8[0] >= 0 ) ? 0 : -1L );
677         for ( i = 0 ; i < len ; i++ ) {
678                 *value = ( ( *value << 8 ) | buf.u8[i] );
679         }
680
681         return len;
682 }
683
684 /**
685  * Fetch value of unsigned integer setting
686  *
687  * @v settings          Settings block, or NULL to search all blocks
688  * @v setting           Setting to fetch
689  * @v value             Integer value to fill in
690  * @ret len             Length of setting, or negative error
691  */
692 int fetch_uint_setting ( struct settings *settings, struct setting *setting,
693                          unsigned long *value ) {
694         long svalue;
695         int len;
696
697         /* Avoid returning uninitialised data on error */
698         *value = 0;
699
700         /* Fetch as a signed long */
701         len = fetch_int_setting ( settings, setting, &svalue );
702         if ( len < 0 )
703                 return len;
704
705         /* Mask off sign-extended bits */
706         assert ( len <= ( int ) sizeof ( long ) );
707         *value = ( svalue & ( -1UL >> ( 8 * ( sizeof ( long ) - len ) ) ) );
708
709         return len;
710 }
711
712 /**
713  * Fetch value of signed integer setting, or zero
714  *
715  * @v settings          Settings block, or NULL to search all blocks
716  * @v setting           Setting to fetch
717  * @ret value           Setting value, or zero
718  */
719 long fetch_intz_setting ( struct settings *settings, struct setting *setting ){
720         long value;
721
722         fetch_int_setting ( settings, setting, &value );
723         return value;
724 }
725
726 /**
727  * Fetch value of unsigned integer setting, or zero
728  *
729  * @v settings          Settings block, or NULL to search all blocks
730  * @v setting           Setting to fetch
731  * @ret value           Setting value, or zero
732  */
733 unsigned long fetch_uintz_setting ( struct settings *settings,
734                                     struct setting *setting ) {
735         unsigned long value;
736
737         fetch_uint_setting ( settings, setting, &value );
738         return value;
739 }
740
741 /**
742  * Fetch value of UUID setting
743  *
744  * @v settings          Settings block, or NULL to search all blocks
745  * @v setting           Setting to fetch
746  * @v uuid              UUID to fill in
747  * @ret len             Length of setting, or negative error
748  */
749 int fetch_uuid_setting ( struct settings *settings, struct setting *setting,
750                          union uuid *uuid ) {
751         int len;
752
753         len = fetch_setting ( settings, setting, uuid, sizeof ( *uuid ) );
754         if ( len < 0 )
755                 return len;
756         if ( len != sizeof ( *uuid ) )
757                 return -ERANGE;
758         return len;
759 }
760
761 /**
762  * Clear settings block
763  *
764  * @v settings          Settings block
765  */
766 void clear_settings ( struct settings *settings ) {
767         if ( settings->op->clear )
768                 settings->op->clear ( settings );
769 }
770
771 /**
772  * Compare two settings
773  *
774  * @v a                 Setting to compare
775  * @v b                 Setting to compare
776  * @ret 0               Settings are the same
777  * @ret non-zero        Settings are not the same
778  */
779 int setting_cmp ( struct setting *a, struct setting *b ) {
780
781         /* If the settings have tags, compare them */
782         if ( a->tag && ( a->tag == b->tag ) )
783                 return 0;
784
785         /* Otherwise, if the settings have names, compare them */
786         if ( a->name && b->name && a->name[0] )
787                 return strcmp ( a->name, b->name );
788
789         /* Otherwise, return a non-match */
790         return ( ! 0 );
791 }
792
793 /******************************************************************************
794  *
795  * Formatted setting routines
796  *
797  ******************************************************************************
798  */
799
800 /**
801  * Store value of typed setting
802  *
803  * @v settings          Settings block
804  * @v setting           Setting to store
805  * @v type              Settings type
806  * @v value             Formatted setting data, or NULL
807  * @ret rc              Return status code
808  */
809 int storef_setting ( struct settings *settings, struct setting *setting,
810                      const char *value ) {
811
812         /* NULL value implies deletion.  Avoid imposing the burden of
813          * checking for NULL values on each typed setting's storef()
814          * method.
815          */
816         if ( ! value )
817                 return delete_setting ( settings, setting );
818                 
819         return setting->type->storef ( settings, setting, value );
820 }
821
822 /**
823  * Find named setting
824  *
825  * @v name              Name
826  * @ret setting         Named setting, or NULL
827  */
828 static struct setting * find_setting ( const char *name ) {
829         struct setting *setting;
830
831         for_each_table_entry ( setting, SETTINGS ) {
832                 if ( strcmp ( name, setting->name ) == 0 )
833                         return setting;
834         }
835         return NULL;
836 }
837
838 /**
839  * Parse setting name as tag number
840  *
841  * @v name              Name
842  * @ret tag             Tag number, or 0 if not a valid number
843  */
844 static unsigned int parse_setting_tag ( const char *name ) {
845         char *tmp = ( ( char * ) name );
846         unsigned int tag = 0;
847
848         while ( 1 ) {
849                 tag = ( ( tag << 8 ) | strtoul ( tmp, &tmp, 0 ) );
850                 if ( *tmp == 0 )
851                         return tag;
852                 if ( *tmp != '.' )
853                         return 0;
854                 tmp++;
855         }
856 }
857
858 /**
859  * Find setting type
860  *
861  * @v name              Name
862  * @ret type            Setting type, or NULL
863  */
864 static struct setting_type * find_setting_type ( const char *name ) {
865         struct setting_type *type;
866
867         for_each_table_entry ( type, SETTING_TYPES ) {
868                 if ( strcmp ( name, type->name ) == 0 )
869                         return type;
870         }
871         return NULL;
872 }
873
874 /**
875  * Parse setting name
876  *
877  * @v name              Name of setting
878  * @v get_child         Function to find or create child settings block
879  * @v settings          Settings block to fill in
880  * @v setting           Setting to fill in
881  * @v tmp_name          Buffer for copy of setting name
882  * @ret rc              Return status code
883  *
884  * Interprets a name of the form
885  * "[settings_name/]tag_name[:type_name]" and fills in the appropriate
886  * fields.
887  *
888  * The @c tmp_name buffer must be large enough to hold a copy of the
889  * setting name.
890  */
891 static int
892 parse_setting_name ( const char *name,
893                      struct settings * ( * get_child ) ( struct settings *,
894                                                          const char * ),
895                      struct settings **settings, struct setting *setting,
896                      char *tmp_name ) {
897         char *settings_name;
898         char *setting_name;
899         char *type_name;
900         struct setting *named_setting;
901
902         /* Set defaults */
903         *settings = &settings_root;
904         memset ( setting, 0, sizeof ( *setting ) );
905         setting->name = "";
906         setting->type = &setting_type_string;
907
908         /* Split name into "[settings_name/]setting_name[:type_name]" */
909         strcpy ( tmp_name, name );
910         if ( ( setting_name = strchr ( tmp_name, '/' ) ) != NULL ) {
911                 *(setting_name++) = 0;
912                 settings_name = tmp_name;
913         } else {
914                 setting_name = tmp_name;
915                 settings_name = NULL;
916         }
917         if ( ( type_name = strchr ( setting_name, ':' ) ) != NULL )
918                 *(type_name++) = 0;
919
920         /* Identify settings block, if specified */
921         if ( settings_name ) {
922                 *settings = parse_settings_name ( settings_name, get_child );
923                 if ( *settings == NULL ) {
924                         DBG ( "Unrecognised settings block \"%s\" in \"%s\"\n",
925                               settings_name, name );
926                         return -ENODEV;
927                 }
928         }
929
930         /* Identify setting */
931         if ( ( named_setting = find_setting ( setting_name ) ) != NULL ) {
932                 /* Matches a defined named setting; use that setting */
933                 memcpy ( setting, named_setting, sizeof ( *setting ) );
934         } else if ( ( setting->tag = parse_setting_tag ( setting_name ) ) !=0){
935                 /* Is a valid numeric tag; use the tag */
936                 setting->tag |= (*settings)->tag_magic;
937         } else {
938                 /* Use the arbitrary name */
939                 setting->name = setting_name;
940         }
941
942         /* Identify setting type, if specified */
943         if ( type_name ) {
944                 setting->type = find_setting_type ( type_name );
945                 if ( setting->type == NULL ) {
946                         DBG ( "Invalid setting type \"%s\" in \"%s\"\n",
947                               type_name, name );
948                         return -ENOTSUP;
949                 }
950         }
951
952         return 0;
953 }
954
955 /**
956  * Parse and store value of named setting
957  *
958  * @v name              Name of setting
959  * @v value             Formatted setting data, or NULL
960  * @ret rc              Return status code
961  */
962 int storef_named_setting ( const char *name, const char *value ) {
963         struct settings *settings;
964         struct setting setting;
965         char tmp_name[ strlen ( name ) + 1 ];
966         int rc;
967
968         if ( ( rc = parse_setting_name ( name, autovivify_child_settings,
969                                          &settings, &setting, tmp_name )) != 0)
970                 return rc;
971         return storef_setting ( settings, &setting, value );
972 }
973
974 /**
975  * Fetch and format value of named setting
976  *
977  * @v name              Name of setting
978  * @v buf               Buffer to contain formatted value
979  * @v len               Length of buffer
980  * @ret len             Length of formatted value, or negative error
981  */
982 int fetchf_named_setting ( const char *name, char *buf, size_t len ) {
983         struct settings *settings;
984         struct setting setting;
985         char tmp_name[ strlen ( name ) + 1 ];
986         int rc;
987
988         if ( ( rc = parse_setting_name ( name, find_child_settings,
989                                          &settings, &setting, tmp_name )) != 0)
990                 return rc;
991         return fetchf_setting ( settings, &setting, buf, len );
992 }
993
994 /******************************************************************************
995  *
996  * Setting types
997  *
998  ******************************************************************************
999  */
1000
1001 /**
1002  * Parse and store value of string setting
1003  *
1004  * @v settings          Settings block
1005  * @v setting           Setting to store
1006  * @v value             Formatted setting data
1007  * @ret rc              Return status code
1008  */
1009 static int storef_string ( struct settings *settings, struct setting *setting,
1010                            const char *value ) {
1011         return store_setting ( settings, setting, value, strlen ( value ) );
1012 }
1013
1014 /**
1015  * Fetch and format value of string setting
1016  *
1017  * @v settings          Settings block, or NULL to search all blocks
1018  * @v setting           Setting to fetch
1019  * @v buf               Buffer to contain formatted value
1020  * @v len               Length of buffer
1021  * @ret len             Length of formatted value, or negative error
1022  */
1023 static int fetchf_string ( struct settings *settings, struct setting *setting,
1024                            char *buf, size_t len ) {
1025         return fetch_string_setting ( settings, setting, buf, len );
1026 }
1027
1028 /** A string setting type */
1029 struct setting_type setting_type_string __setting_type = {
1030         .name = "string",
1031         .storef = storef_string,
1032         .fetchf = fetchf_string,
1033 };
1034
1035 /**
1036  * Parse and store value of URI-encoded string setting
1037  *
1038  * @v settings          Settings block
1039  * @v setting           Setting to store
1040  * @v value             Formatted setting data
1041  * @ret rc              Return status code
1042  */
1043 static int storef_uristring ( struct settings *settings,
1044                               struct setting *setting,
1045                               const char *value ) {
1046         char buf[ strlen ( value ) + 1 ]; /* Decoding never expands string */
1047         size_t len;
1048
1049         len = uri_decode ( value, buf, sizeof ( buf ) );
1050         return store_setting ( settings, setting, buf, len );
1051 }
1052
1053 /**
1054  * Fetch and format value of URI-encoded string setting
1055  *
1056  * @v settings          Settings block, or NULL to search all blocks
1057  * @v setting           Setting to fetch
1058  * @v buf               Buffer to contain formatted value
1059  * @v len               Length of buffer
1060  * @ret len             Length of formatted value, or negative error
1061  */
1062 static int fetchf_uristring ( struct settings *settings,
1063                               struct setting *setting,
1064                               char *buf, size_t len ) {
1065         ssize_t raw_len;
1066
1067         /* We need to always retrieve the full raw string to know the
1068          * length of the encoded string.
1069          */
1070         raw_len = fetch_setting ( settings, setting, NULL, 0 );
1071         if ( raw_len < 0 )
1072                 return raw_len;
1073
1074         {
1075                 char raw_buf[ raw_len + 1 ];
1076        
1077                 fetch_string_setting ( settings, setting, raw_buf,
1078                                        sizeof ( raw_buf ) );
1079                 return uri_encode ( raw_buf, buf, len );
1080         }
1081 }
1082
1083 /** A URI-encoded string setting type */
1084 struct setting_type setting_type_uristring __setting_type = {
1085         .name = "uristring",
1086         .storef = storef_uristring,
1087         .fetchf = fetchf_uristring,
1088 };
1089
1090 /**
1091  * Parse and store value of IPv4 address setting
1092  *
1093  * @v settings          Settings block
1094  * @v setting           Setting to store
1095  * @v value             Formatted setting data
1096  * @ret rc              Return status code
1097  */
1098 static int storef_ipv4 ( struct settings *settings, struct setting *setting,
1099                          const char *value ) {
1100         struct in_addr ipv4;
1101
1102         if ( inet_aton ( value, &ipv4 ) == 0 )
1103                 return -EINVAL;
1104         return store_setting ( settings, setting, &ipv4, sizeof ( ipv4 ) );
1105 }
1106
1107 /**
1108  * Fetch and format value of IPv4 address setting
1109  *
1110  * @v settings          Settings block, or NULL to search all blocks
1111  * @v setting           Setting to fetch
1112  * @v buf               Buffer to contain formatted value
1113  * @v len               Length of buffer
1114  * @ret len             Length of formatted value, or negative error
1115  */
1116 static int fetchf_ipv4 ( struct settings *settings, struct setting *setting,
1117                          char *buf, size_t len ) {
1118         struct in_addr ipv4;
1119         int raw_len;
1120
1121         if ( ( raw_len = fetch_ipv4_setting ( settings, setting, &ipv4 ) ) < 0)
1122                 return raw_len;
1123         return snprintf ( buf, len, "%s", inet_ntoa ( ipv4 ) );
1124 }
1125
1126 /** An IPv4 address setting type */
1127 struct setting_type setting_type_ipv4 __setting_type = {
1128         .name = "ipv4",
1129         .storef = storef_ipv4,
1130         .fetchf = fetchf_ipv4,
1131 };
1132
1133 /**
1134  * Parse and store value of integer setting
1135  *
1136  * @v settings          Settings block
1137  * @v setting           Setting to store
1138  * @v value             Formatted setting data
1139  * @v size              Integer size, in bytes
1140  * @ret rc              Return status code
1141  */
1142 static int storef_int ( struct settings *settings, struct setting *setting,
1143                         const char *value, unsigned int size ) {
1144         union {
1145                 uint32_t num;
1146                 uint8_t bytes[4];
1147         } u;
1148         char *endp;
1149
1150         u.num = htonl ( strtoul ( value, &endp, 0 ) );
1151         if ( *endp )
1152                 return -EINVAL;
1153         return store_setting ( settings, setting, 
1154                                &u.bytes[ sizeof ( u ) - size ], size );
1155 }
1156
1157 /**
1158  * Parse and store value of 8-bit integer setting
1159  *
1160  * @v settings          Settings block
1161  * @v setting           Setting to store
1162  * @v value             Formatted setting data
1163  * @v size              Integer size, in bytes
1164  * @ret rc              Return status code
1165  */
1166 static int storef_int8 ( struct settings *settings, struct setting *setting,
1167                          const char *value ) {
1168         return storef_int ( settings, setting, value, 1 );
1169 }
1170
1171 /**
1172  * Parse and store value of 16-bit integer setting
1173  *
1174  * @v settings          Settings block
1175  * @v setting           Setting to store
1176  * @v value             Formatted setting data
1177  * @v size              Integer size, in bytes
1178  * @ret rc              Return status code
1179  */
1180 static int storef_int16 ( struct settings *settings, struct setting *setting,
1181                           const char *value ) {
1182         return storef_int ( settings, setting, value, 2 );
1183 }
1184
1185 /**
1186  * Parse and store value of 32-bit integer setting
1187  *
1188  * @v settings          Settings block
1189  * @v setting           Setting to store
1190  * @v value             Formatted setting data
1191  * @v size              Integer size, in bytes
1192  * @ret rc              Return status code
1193  */
1194 static int storef_int32 ( struct settings *settings, struct setting *setting,
1195                           const char *value ) {
1196         return storef_int ( settings, setting, value, 4 );
1197 }
1198
1199 /**
1200  * Fetch and format value of signed integer setting
1201  *
1202  * @v settings          Settings block, or NULL to search all blocks
1203  * @v setting           Setting to fetch
1204  * @v buf               Buffer to contain formatted value
1205  * @v len               Length of buffer
1206  * @ret len             Length of formatted value, or negative error
1207  */
1208 static int fetchf_int ( struct settings *settings, struct setting *setting,
1209                         char *buf, size_t len ) {
1210         long value;
1211         int rc;
1212
1213         if ( ( rc = fetch_int_setting ( settings, setting, &value ) ) < 0 )
1214                 return rc;
1215         return snprintf ( buf, len, "%ld", value );
1216 }
1217
1218 /**
1219  * Fetch and format value of unsigned integer setting
1220  *
1221  * @v settings          Settings block, or NULL to search all blocks
1222  * @v setting           Setting to fetch
1223  * @v buf               Buffer to contain formatted value
1224  * @v len               Length of buffer
1225  * @ret len             Length of formatted value, or negative error
1226  */
1227 static int fetchf_uint ( struct settings *settings, struct setting *setting,
1228                          char *buf, size_t len ) {
1229         unsigned long value;
1230         int rc;
1231
1232         if ( ( rc = fetch_uint_setting ( settings, setting, &value ) ) < 0 )
1233                 return rc;
1234         return snprintf ( buf, len, "%#lx", value );
1235 }
1236
1237 /** A signed 8-bit integer setting type */
1238 struct setting_type setting_type_int8 __setting_type = {
1239         .name = "int8",
1240         .storef = storef_int8,
1241         .fetchf = fetchf_int,
1242 };
1243
1244 /** A signed 16-bit integer setting type */
1245 struct setting_type setting_type_int16 __setting_type = {
1246         .name = "int16",
1247         .storef = storef_int16,
1248         .fetchf = fetchf_int,
1249 };
1250
1251 /** A signed 32-bit integer setting type */
1252 struct setting_type setting_type_int32 __setting_type = {
1253         .name = "int32",
1254         .storef = storef_int32,
1255         .fetchf = fetchf_int,
1256 };
1257
1258 /** An unsigned 8-bit integer setting type */
1259 struct setting_type setting_type_uint8 __setting_type = {
1260         .name = "uint8",
1261         .storef = storef_int8,
1262         .fetchf = fetchf_uint,
1263 };
1264
1265 /** An unsigned 16-bit integer setting type */
1266 struct setting_type setting_type_uint16 __setting_type = {
1267         .name = "uint16",
1268         .storef = storef_int16,
1269         .fetchf = fetchf_uint,
1270 };
1271
1272 /** An unsigned 32-bit integer setting type */
1273 struct setting_type setting_type_uint32 __setting_type = {
1274         .name = "uint32",
1275         .storef = storef_int32,
1276         .fetchf = fetchf_uint,
1277 };
1278
1279 /**
1280  * Parse and store value of hex string setting
1281  *
1282  * @v settings          Settings block
1283  * @v setting           Setting to store
1284  * @v value             Formatted setting data
1285  * @ret rc              Return status code
1286  */
1287 static int storef_hex ( struct settings *settings, struct setting *setting,
1288                         const char *value ) {
1289         char *ptr = ( char * ) value;
1290         uint8_t bytes[ strlen ( value ) ]; /* cannot exceed strlen(value) */
1291         unsigned int len = 0;
1292
1293         while ( 1 ) {
1294                 bytes[len++] = strtoul ( ptr, &ptr, 16 );
1295                 switch ( *ptr ) {
1296                 case '\0' :
1297                         return store_setting ( settings, setting, bytes, len );
1298                 case ':' :
1299                         ptr++;
1300                         break;
1301                 default :
1302                         return -EINVAL;
1303                 }
1304         }
1305 }
1306
1307 /**
1308  * Fetch and format value of hex string setting
1309  *
1310  * @v settings          Settings block, or NULL to search all blocks
1311  * @v setting           Setting to fetch
1312  * @v buf               Buffer to contain formatted value
1313  * @v len               Length of buffer
1314  * @ret len             Length of formatted value, or negative error
1315  */
1316 static int fetchf_hex ( struct settings *settings, struct setting *setting,
1317                         char *buf, size_t len ) {
1318         int raw_len;
1319         int check_len;
1320         int used = 0;
1321         int i;
1322
1323         raw_len = fetch_setting_len ( settings, setting );
1324         if ( raw_len < 0 )
1325                 return raw_len;
1326
1327         {
1328                 uint8_t raw[raw_len];
1329
1330                 check_len = fetch_setting ( settings, setting, raw,
1331                                             sizeof ( raw ) );
1332                 if ( check_len < 0 )
1333                         return check_len;
1334                 assert ( check_len == raw_len );
1335                 
1336                 if ( len )
1337                         buf[0] = 0; /* Ensure that a terminating NUL exists */
1338                 for ( i = 0 ; i < raw_len ; i++ ) {
1339                         used += ssnprintf ( ( buf + used ), ( len - used ),
1340                                             "%s%02x", ( used ? ":" : "" ),
1341                                             raw[i] );
1342                 }
1343                 return used;
1344         }
1345 }
1346
1347 /** A hex-string setting */
1348 struct setting_type setting_type_hex __setting_type = {
1349         .name = "hex",
1350         .storef = storef_hex,
1351         .fetchf = fetchf_hex,
1352 };
1353
1354 /**
1355  * Parse and store value of UUID setting
1356  *
1357  * @v settings          Settings block
1358  * @v setting           Setting to store
1359  * @v value             Formatted setting data
1360  * @ret rc              Return status code
1361  */
1362 static int storef_uuid ( struct settings *settings __unused,
1363                          struct setting *setting __unused,
1364                          const char *value __unused ) {
1365         return -ENOTSUP;
1366 }
1367
1368 /**
1369  * Fetch and format value of UUID setting
1370  *
1371  * @v settings          Settings block, or NULL to search all blocks
1372  * @v setting           Setting to fetch
1373  * @v buf               Buffer to contain formatted value
1374  * @v len               Length of buffer
1375  * @ret len             Length of formatted value, or negative error
1376  */
1377 static int fetchf_uuid ( struct settings *settings, struct setting *setting,
1378                          char *buf, size_t len ) {
1379         union uuid uuid;
1380         int raw_len;
1381
1382         if ( ( raw_len = fetch_uuid_setting ( settings, setting, &uuid ) ) < 0)
1383                 return raw_len;
1384         return snprintf ( buf, len, "%s", uuid_ntoa ( &uuid ) );
1385 }
1386
1387 /** UUID setting type */
1388 struct setting_type setting_type_uuid __setting_type = {
1389         .name = "uuid",
1390         .storef = storef_uuid,
1391         .fetchf = fetchf_uuid,
1392 };
1393
1394 /******************************************************************************
1395  *
1396  * Settings
1397  *
1398  ******************************************************************************
1399  */
1400
1401 /** Hostname setting */
1402 struct setting hostname_setting __setting = {
1403         .name = "hostname",
1404         .description = "Host name",
1405         .tag = DHCP_HOST_NAME,
1406         .type = &setting_type_string,
1407 };
1408
1409 /** Filename setting */
1410 struct setting filename_setting __setting = {
1411         .name = "filename",
1412         .description = "Boot filename",
1413         .tag = DHCP_BOOTFILE_NAME,
1414         .type = &setting_type_string,
1415 };
1416
1417 /** Root path setting */
1418 struct setting root_path_setting __setting = {
1419         .name = "root-path",
1420         .description = "NFS/iSCSI root path",
1421         .tag = DHCP_ROOT_PATH,
1422         .type = &setting_type_string,
1423 };
1424
1425 /** Username setting */
1426 struct setting username_setting __setting = {
1427         .name = "username",
1428         .description = "User name",
1429         .tag = DHCP_EB_USERNAME,
1430         .type = &setting_type_string,
1431 };
1432
1433 /** Password setting */
1434 struct setting password_setting __setting = {
1435         .name = "password",
1436         .description = "Password",
1437         .tag = DHCP_EB_PASSWORD,
1438         .type = &setting_type_string,
1439 };
1440
1441 /** Priority setting */
1442 struct setting priority_setting __setting = {
1443         .name = "priority",
1444         .description = "Priority of these settings",
1445         .tag = DHCP_EB_PRIORITY,
1446         .type = &setting_type_int8,
1447 };