[settings] Unregister the children when unregistering the parent
[people/mdc/gpxe.git/.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                 struct net_device *netdev;
332
333                 subname = remainder;
334                 remainder = strchr ( subname, '.' );
335                 if ( remainder )
336                         *(remainder++) = '\0';
337
338                 /* Special case "netX" root settings block */
339                 if ( ( subname == name_copy ) && ! strcmp ( subname, "netX" ) &&
340                      ( ( netdev = last_opened_netdev() ) != NULL ) )
341                         settings = get_child ( settings, netdev->name );
342                 else
343                         settings = get_child ( settings, subname );
344
345                 if ( ! settings )
346                         break;
347         }
348
349         return settings;
350 }
351
352 /**
353  * Find named settings block
354  *
355  * @v name              Name
356  * @ret settings        Settings block, or NULL
357  */
358 struct settings * find_settings ( const char *name ) {
359
360         return parse_settings_name ( name, find_child_settings );
361 }
362
363 /**
364  * Apply all settings
365  *
366  * @ret rc              Return status code
367  */
368 static int apply_settings ( void ) {
369         struct settings_applicator *applicator;
370         int rc;
371
372         /* Call all settings applicators */
373         for_each_table_entry ( applicator, SETTINGS_APPLICATORS ) {
374                 if ( ( rc = applicator->apply() ) != 0 ) {
375                         DBG ( "Could not apply settings using applicator "
376                               "%p: %s\n", applicator, strerror ( rc ) );
377                         return rc;
378                 }
379         }
380
381         return 0;
382 }
383
384 /**
385  * Reprioritise settings
386  *
387  * @v settings          Settings block
388  *
389  * Reorders the settings block amongst its siblings according to its
390  * priority.
391  */
392 static void reprioritise_settings ( struct settings *settings ) {
393         struct settings *parent = settings->parent;
394         long priority;
395         struct settings *tmp;
396         long tmp_priority;
397
398         /* Stop when we reach the top of the tree */
399         if ( ! parent )
400                 return;
401
402         /* Read priority, if present */
403         priority = fetch_intz_setting ( settings, &priority_setting );
404
405         /* Remove from siblings list */
406         list_del ( &settings->siblings );
407
408         /* Reinsert after any existing blocks which have a higher priority */
409         list_for_each_entry ( tmp, &parent->children, siblings ) {
410                 tmp_priority = fetch_intz_setting ( tmp, &priority_setting );
411                 if ( priority > tmp_priority )
412                         break;
413         }
414         list_add_tail ( &settings->siblings, &tmp->siblings );
415
416         /* Recurse up the tree */
417         reprioritise_settings ( parent );
418 }
419
420 /**
421  * Register settings block
422  *
423  * @v settings          Settings block
424  * @v parent            Parent settings block, or NULL
425  * @ret rc              Return status code
426  */
427 int register_settings ( struct settings *settings, struct settings *parent ) {
428         struct settings *old_settings;
429
430         /* NULL parent => add to settings root */
431         assert ( settings != NULL );
432         if ( parent == NULL )
433                 parent = &settings_root;
434
435         /* Remove any existing settings with the same name */
436         if ( ( old_settings = find_child_settings ( parent, settings->name ) ))
437                 unregister_settings ( old_settings );
438
439         /* Add to list of settings */
440         ref_get ( settings->refcnt );
441         ref_get ( parent->refcnt );
442         settings->parent = parent;
443         list_add_tail ( &settings->siblings, &parent->children );
444         DBGC ( settings, "Settings %p (\"%s\") registered\n",
445                settings, settings_name ( settings ) );
446
447         /* Fix up settings priority */
448         reprioritise_settings ( settings );
449
450         /* Apply potentially-updated settings */
451         apply_settings();
452
453         return 0;
454 }
455
456 /**
457  * Unregister settings block
458  *
459  * @v settings          Settings block
460  */
461 void unregister_settings ( struct settings *settings ) {
462         struct settings *child;
463         struct settings *tmp;
464
465         /* Unregister child settings */
466         list_for_each_entry_safe ( child, tmp, &settings->children, siblings ) {
467                 unregister_settings ( child );
468         }
469
470         DBGC ( settings, "Settings %p (\"%s\") unregistered\n",
471                settings, settings_name ( settings ) );
472
473         /* Remove from list of settings */
474         ref_put ( settings->parent->refcnt );
475         settings->parent = NULL;
476         list_del ( &settings->siblings );
477         ref_put ( settings->refcnt );
478
479         /* Apply potentially-updated settings */
480         apply_settings();
481 }
482
483 /******************************************************************************
484  *
485  * Core settings routines
486  *
487  ******************************************************************************
488  */
489
490 /**
491  * Store value of setting
492  *
493  * @v settings          Settings block, or NULL
494  * @v setting           Setting to store
495  * @v data              Setting data, or NULL to clear setting
496  * @v len               Length of setting data
497  * @ret rc              Return status code
498  */
499 int store_setting ( struct settings *settings, struct setting *setting,
500                     const void *data, size_t len ) {
501         int rc;
502
503         /* NULL settings implies storing into the global settings root */
504         if ( ! settings )
505                 settings = &settings_root;
506
507         /* Sanity check */
508         if ( ! settings->op->store )
509                 return -ENOTSUP;
510
511         /* Store setting */
512         if ( ( rc = settings->op->store ( settings, setting,
513                                           data, len ) ) != 0 )
514                 return rc;
515
516         /* Reprioritise settings if necessary */
517         if ( setting_cmp ( setting, &priority_setting ) == 0 )
518                 reprioritise_settings ( settings );
519
520         /* If these settings are registered, apply potentially-updated
521          * settings
522          */
523         for ( ; settings ; settings = settings->parent ) {
524                 if ( settings == &settings_root ) {
525                         if ( ( rc = apply_settings() ) != 0 )
526                                 return rc;
527                         break;
528                 }
529         }
530
531         return 0;
532 }
533
534 /**
535  * Fetch value of setting
536  *
537  * @v settings          Settings block, or NULL to search all blocks
538  * @v setting           Setting to fetch
539  * @v data              Buffer to fill with setting data
540  * @v len               Length of buffer
541  * @ret len             Length of setting data, or negative error
542  *
543  * The actual length of the setting will be returned even if
544  * the buffer was too small.
545  */
546 int fetch_setting ( struct settings *settings, struct setting *setting,
547                     void *data, size_t len ) {
548         struct settings *child;
549         int ret;
550
551         /* Avoid returning uninitialised data on error */
552         memset ( data, 0, len );
553
554         /* NULL settings implies starting at the global settings root */
555         if ( ! settings )
556                 settings = &settings_root;
557
558         /* Sanity check */
559         if ( ! settings->op->fetch )
560                 return -ENOTSUP;
561
562         /* Try this block first */
563         if ( ( ret = settings->op->fetch ( settings, setting,
564                                            data, len ) ) >= 0 )
565                 return ret;
566
567         /* Recurse into each child block in turn */
568         list_for_each_entry ( child, &settings->children, siblings ) {
569                 if ( ( ret = fetch_setting ( child, setting,
570                                              data, len ) ) >= 0 )
571                         return ret;
572         }
573
574         return -ENOENT;
575 }
576
577 /**
578  * Fetch length of setting
579  *
580  * @v settings          Settings block, or NULL to search all blocks
581  * @v setting           Setting to fetch
582  * @ret len             Length of setting data, or negative error
583  *
584  * This function can also be used as an existence check for the
585  * setting.
586  */
587 int fetch_setting_len ( struct settings *settings, struct setting *setting ) {
588         return fetch_setting ( settings, setting, NULL, 0 );
589 }
590
591 /**
592  * Fetch value of string setting
593  *
594  * @v settings          Settings block, or NULL to search all blocks
595  * @v setting           Setting to fetch
596  * @v data              Buffer to fill with setting string data
597  * @v len               Length of buffer
598  * @ret len             Length of string setting, or negative error
599  *
600  * The resulting string is guaranteed to be correctly NUL-terminated.
601  * The returned length will be the length of the underlying setting
602  * data.
603  */
604 int fetch_string_setting ( struct settings *settings, struct setting *setting,
605                            char *data, size_t len ) {
606         memset ( data, 0, len );
607         return fetch_setting ( settings, setting, data,
608                                ( ( len > 0 ) ? ( len - 1 ) : 0 ) );
609 }
610
611 /**
612  * Fetch value of string setting
613  *
614  * @v settings          Settings block, or NULL to search all blocks
615  * @v setting           Setting to fetch
616  * @v data              Buffer to allocate and fill with setting string data
617  * @ret len             Length of string setting, or negative error
618  *
619  * The resulting string is guaranteed to be correctly NUL-terminated.
620  * The returned length will be the length of the underlying setting
621  * data.  The caller is responsible for eventually freeing the
622  * allocated buffer.
623  */
624 int fetch_string_setting_copy ( struct settings *settings,
625                                 struct setting *setting,
626                                 char **data ) {
627         int len;
628         int check_len = 0;
629
630         len = fetch_setting_len ( settings, setting );
631         if ( len < 0 )
632                 return len;
633
634         *data = malloc ( len + 1 );
635         if ( ! *data )
636                 return -ENOMEM;
637
638         check_len = fetch_string_setting ( settings, setting, *data,
639                                            ( len + 1 ) );
640         assert ( check_len == len );
641         return len;
642 }
643
644 /**
645  * Fetch value of IPv4 address setting
646  *
647  * @v settings          Settings block, or NULL to search all blocks
648  * @v setting           Setting to fetch
649  * @v inp               IPv4 address to fill in
650  * @ret len             Length of setting, or negative error
651  */
652 int fetch_ipv4_setting ( struct settings *settings, struct setting *setting,
653                          struct in_addr *inp ) {
654         int len;
655
656         len = fetch_setting ( settings, setting, inp, sizeof ( *inp ) );
657         if ( len < 0 )
658                 return len;
659         if ( len < ( int ) sizeof ( *inp ) )
660                 return -ERANGE;
661         return len;
662 }
663
664 /**
665  * Fetch value of signed integer setting
666  *
667  * @v settings          Settings block, or NULL to search all blocks
668  * @v setting           Setting to fetch
669  * @v value             Integer value to fill in
670  * @ret len             Length of setting, or negative error
671  */
672 int fetch_int_setting ( struct settings *settings, struct setting *setting,
673                         long *value ) {
674         union {
675                 uint8_t u8[ sizeof ( long ) ];
676                 int8_t s8[ sizeof ( long ) ];
677         } buf;
678         int len;
679         int i;
680
681         /* Avoid returning uninitialised data on error */
682         *value = 0;
683
684         /* Fetch raw (network-ordered, variable-length) setting */
685         len = fetch_setting ( settings, setting, &buf, sizeof ( buf ) );
686         if ( len < 0 )
687                 return len;
688         if ( len > ( int ) sizeof ( buf ) )
689                 return -ERANGE;
690
691         /* Convert to host-ordered signed long */
692         *value = ( ( buf.s8[0] >= 0 ) ? 0 : -1L );
693         for ( i = 0 ; i < len ; i++ ) {
694                 *value = ( ( *value << 8 ) | buf.u8[i] );
695         }
696
697         return len;
698 }
699
700 /**
701  * Fetch value of unsigned integer setting
702  *
703  * @v settings          Settings block, or NULL to search all blocks
704  * @v setting           Setting to fetch
705  * @v value             Integer value to fill in
706  * @ret len             Length of setting, or negative error
707  */
708 int fetch_uint_setting ( struct settings *settings, struct setting *setting,
709                          unsigned long *value ) {
710         long svalue;
711         int len;
712
713         /* Avoid returning uninitialised data on error */
714         *value = 0;
715
716         /* Fetch as a signed long */
717         len = fetch_int_setting ( settings, setting, &svalue );
718         if ( len < 0 )
719                 return len;
720
721         /* Mask off sign-extended bits */
722         assert ( len <= ( int ) sizeof ( long ) );
723         *value = ( svalue & ( -1UL >> ( 8 * ( sizeof ( long ) - len ) ) ) );
724
725         return len;
726 }
727
728 /**
729  * Fetch value of signed integer setting, or zero
730  *
731  * @v settings          Settings block, or NULL to search all blocks
732  * @v setting           Setting to fetch
733  * @ret value           Setting value, or zero
734  */
735 long fetch_intz_setting ( struct settings *settings, struct setting *setting ){
736         long value;
737
738         fetch_int_setting ( settings, setting, &value );
739         return value;
740 }
741
742 /**
743  * Fetch value of unsigned integer setting, or zero
744  *
745  * @v settings          Settings block, or NULL to search all blocks
746  * @v setting           Setting to fetch
747  * @ret value           Setting value, or zero
748  */
749 unsigned long fetch_uintz_setting ( struct settings *settings,
750                                     struct setting *setting ) {
751         unsigned long value;
752
753         fetch_uint_setting ( settings, setting, &value );
754         return value;
755 }
756
757 /**
758  * Fetch value of UUID setting
759  *
760  * @v settings          Settings block, or NULL to search all blocks
761  * @v setting           Setting to fetch
762  * @v uuid              UUID to fill in
763  * @ret len             Length of setting, or negative error
764  */
765 int fetch_uuid_setting ( struct settings *settings, struct setting *setting,
766                          union uuid *uuid ) {
767         int len;
768
769         len = fetch_setting ( settings, setting, uuid, sizeof ( *uuid ) );
770         if ( len < 0 )
771                 return len;
772         if ( len != sizeof ( *uuid ) )
773                 return -ERANGE;
774         return len;
775 }
776
777 /**
778  * Clear settings block
779  *
780  * @v settings          Settings block
781  */
782 void clear_settings ( struct settings *settings ) {
783         if ( settings->op->clear )
784                 settings->op->clear ( settings );
785 }
786
787 /**
788  * Compare two settings
789  *
790  * @v a                 Setting to compare
791  * @v b                 Setting to compare
792  * @ret 0               Settings are the same
793  * @ret non-zero        Settings are not the same
794  */
795 int setting_cmp ( struct setting *a, struct setting *b ) {
796
797         /* If the settings have tags, compare them */
798         if ( a->tag && ( a->tag == b->tag ) )
799                 return 0;
800
801         /* Otherwise, if the settings have names, compare them */
802         if ( a->name && b->name && a->name[0] )
803                 return strcmp ( a->name, b->name );
804
805         /* Otherwise, return a non-match */
806         return ( ! 0 );
807 }
808
809 /******************************************************************************
810  *
811  * Formatted setting routines
812  *
813  ******************************************************************************
814  */
815
816 /**
817  * Store value of typed setting
818  *
819  * @v settings          Settings block
820  * @v setting           Setting to store
821  * @v type              Settings type
822  * @v value             Formatted setting data, or NULL
823  * @ret rc              Return status code
824  */
825 int storef_setting ( struct settings *settings, struct setting *setting,
826                      const char *value ) {
827
828         /* NULL value implies deletion.  Avoid imposing the burden of
829          * checking for NULL values on each typed setting's storef()
830          * method.
831          */
832         if ( ! value )
833                 return delete_setting ( settings, setting );
834                 
835         return setting->type->storef ( settings, setting, value );
836 }
837
838 /**
839  * Find named setting
840  *
841  * @v name              Name
842  * @ret setting         Named setting, or NULL
843  */
844 static struct setting * find_setting ( const char *name ) {
845         struct setting *setting;
846
847         for_each_table_entry ( setting, SETTINGS ) {
848                 if ( strcmp ( name, setting->name ) == 0 )
849                         return setting;
850         }
851         return NULL;
852 }
853
854 /**
855  * Parse setting name as tag number
856  *
857  * @v name              Name
858  * @ret tag             Tag number, or 0 if not a valid number
859  */
860 static unsigned int parse_setting_tag ( const char *name ) {
861         char *tmp = ( ( char * ) name );
862         unsigned int tag = 0;
863
864         while ( 1 ) {
865                 tag = ( ( tag << 8 ) | strtoul ( tmp, &tmp, 0 ) );
866                 if ( *tmp == 0 )
867                         return tag;
868                 if ( *tmp != '.' )
869                         return 0;
870                 tmp++;
871         }
872 }
873
874 /**
875  * Find setting type
876  *
877  * @v name              Name
878  * @ret type            Setting type, or NULL
879  */
880 static struct setting_type * find_setting_type ( const char *name ) {
881         struct setting_type *type;
882
883         for_each_table_entry ( type, SETTING_TYPES ) {
884                 if ( strcmp ( name, type->name ) == 0 )
885                         return type;
886         }
887         return NULL;
888 }
889
890 /**
891  * Parse setting name
892  *
893  * @v name              Name of setting
894  * @v get_child         Function to find or create child settings block
895  * @v settings          Settings block to fill in
896  * @v setting           Setting to fill in
897  * @v tmp_name          Buffer for copy of setting name
898  * @ret rc              Return status code
899  *
900  * Interprets a name of the form
901  * "[settings_name/]tag_name[:type_name]" and fills in the appropriate
902  * fields.
903  *
904  * The @c tmp_name buffer must be large enough to hold a copy of the
905  * setting name.
906  */
907 static int
908 parse_setting_name ( const char *name,
909                      struct settings * ( * get_child ) ( struct settings *,
910                                                          const char * ),
911                      struct settings **settings, struct setting *setting,
912                      char *tmp_name ) {
913         char *settings_name;
914         char *setting_name;
915         char *type_name;
916         struct setting *named_setting;
917
918         /* Set defaults */
919         *settings = &settings_root;
920         memset ( setting, 0, sizeof ( *setting ) );
921         setting->name = "";
922         setting->type = &setting_type_string;
923
924         /* Split name into "[settings_name/]setting_name[:type_name]" */
925         strcpy ( tmp_name, name );
926         if ( ( setting_name = strchr ( tmp_name, '/' ) ) != NULL ) {
927                 *(setting_name++) = 0;
928                 settings_name = tmp_name;
929         } else {
930                 setting_name = tmp_name;
931                 settings_name = NULL;
932         }
933         if ( ( type_name = strchr ( setting_name, ':' ) ) != NULL )
934                 *(type_name++) = 0;
935
936         /* Identify settings block, if specified */
937         if ( settings_name ) {
938                 *settings = parse_settings_name ( settings_name, get_child );
939                 if ( *settings == NULL ) {
940                         DBG ( "Unrecognised settings block \"%s\" in \"%s\"\n",
941                               settings_name, name );
942                         return -ENODEV;
943                 }
944         }
945
946         /* Identify setting */
947         if ( ( named_setting = find_setting ( setting_name ) ) != NULL ) {
948                 /* Matches a defined named setting; use that setting */
949                 memcpy ( setting, named_setting, sizeof ( *setting ) );
950         } else if ( ( setting->tag = parse_setting_tag ( setting_name ) ) !=0){
951                 /* Is a valid numeric tag; use the tag */
952                 setting->tag |= (*settings)->tag_magic;
953         } else {
954                 /* Use the arbitrary name */
955                 setting->name = setting_name;
956         }
957
958         /* Identify setting type, if specified */
959         if ( type_name ) {
960                 setting->type = find_setting_type ( type_name );
961                 if ( setting->type == NULL ) {
962                         DBG ( "Invalid setting type \"%s\" in \"%s\"\n",
963                               type_name, name );
964                         return -ENOTSUP;
965                 }
966         }
967
968         return 0;
969 }
970
971 /**
972  * Parse and store value of named setting
973  *
974  * @v name              Name of setting
975  * @v value             Formatted setting data, or NULL
976  * @ret rc              Return status code
977  */
978 int storef_named_setting ( const char *name, const char *value ) {
979         struct settings *settings;
980         struct setting setting;
981         char tmp_name[ strlen ( name ) + 1 ];
982         int rc;
983
984         if ( ( rc = parse_setting_name ( name, autovivify_child_settings,
985                                          &settings, &setting, tmp_name )) != 0)
986                 return rc;
987         return storef_setting ( settings, &setting, value );
988 }
989
990 /**
991  * Fetch and format value of named setting
992  *
993  * @v name              Name of setting
994  * @v buf               Buffer to contain formatted value
995  * @v len               Length of buffer
996  * @ret len             Length of formatted value, or negative error
997  */
998 int fetchf_named_setting ( const char *name, char *buf, size_t len ) {
999         struct settings *settings;
1000         struct setting setting;
1001         char tmp_name[ strlen ( name ) + 1 ];
1002         int rc;
1003
1004         if ( ( rc = parse_setting_name ( name, find_child_settings,
1005                                          &settings, &setting, tmp_name )) != 0)
1006                 return rc;
1007         return fetchf_setting ( settings, &setting, buf, len );
1008 }
1009
1010 /******************************************************************************
1011  *
1012  * Setting types
1013  *
1014  ******************************************************************************
1015  */
1016
1017 /**
1018  * Parse and store value of string setting
1019  *
1020  * @v settings          Settings block
1021  * @v setting           Setting to store
1022  * @v value             Formatted setting data
1023  * @ret rc              Return status code
1024  */
1025 static int storef_string ( struct settings *settings, struct setting *setting,
1026                            const char *value ) {
1027         return store_setting ( settings, setting, value, strlen ( value ) );
1028 }
1029
1030 /**
1031  * Fetch and format value of string setting
1032  *
1033  * @v settings          Settings block, or NULL to search all blocks
1034  * @v setting           Setting to fetch
1035  * @v buf               Buffer to contain formatted value
1036  * @v len               Length of buffer
1037  * @ret len             Length of formatted value, or negative error
1038  */
1039 static int fetchf_string ( struct settings *settings, struct setting *setting,
1040                            char *buf, size_t len ) {
1041         return fetch_string_setting ( settings, setting, buf, len );
1042 }
1043
1044 /** A string setting type */
1045 struct setting_type setting_type_string __setting_type = {
1046         .name = "string",
1047         .storef = storef_string,
1048         .fetchf = fetchf_string,
1049 };
1050
1051 /**
1052  * Parse and store value of URI-encoded string setting
1053  *
1054  * @v settings          Settings block
1055  * @v setting           Setting to store
1056  * @v value             Formatted setting data
1057  * @ret rc              Return status code
1058  */
1059 static int storef_uristring ( struct settings *settings,
1060                               struct setting *setting,
1061                               const char *value ) {
1062         char buf[ strlen ( value ) + 1 ]; /* Decoding never expands string */
1063         size_t len;
1064
1065         len = uri_decode ( value, buf, sizeof ( buf ) );
1066         return store_setting ( settings, setting, buf, len );
1067 }
1068
1069 /**
1070  * Fetch and format value of URI-encoded string setting
1071  *
1072  * @v settings          Settings block, or NULL to search all blocks
1073  * @v setting           Setting to fetch
1074  * @v buf               Buffer to contain formatted value
1075  * @v len               Length of buffer
1076  * @ret len             Length of formatted value, or negative error
1077  */
1078 static int fetchf_uristring ( struct settings *settings,
1079                               struct setting *setting,
1080                               char *buf, size_t len ) {
1081         ssize_t raw_len;
1082
1083         /* We need to always retrieve the full raw string to know the
1084          * length of the encoded string.
1085          */
1086         raw_len = fetch_setting ( settings, setting, NULL, 0 );
1087         if ( raw_len < 0 )
1088                 return raw_len;
1089
1090         {
1091                 char raw_buf[ raw_len + 1 ];
1092        
1093                 fetch_string_setting ( settings, setting, raw_buf,
1094                                        sizeof ( raw_buf ) );
1095                 return uri_encode ( raw_buf, buf, len, URI_FRAGMENT );
1096         }
1097 }
1098
1099 /** A URI-encoded string setting type */
1100 struct setting_type setting_type_uristring __setting_type = {
1101         .name = "uristring",
1102         .storef = storef_uristring,
1103         .fetchf = fetchf_uristring,
1104 };
1105
1106 /**
1107  * Parse and store value of IPv4 address setting
1108  *
1109  * @v settings          Settings block
1110  * @v setting           Setting to store
1111  * @v value             Formatted setting data
1112  * @ret rc              Return status code
1113  */
1114 static int storef_ipv4 ( struct settings *settings, struct setting *setting,
1115                          const char *value ) {
1116         struct in_addr ipv4;
1117
1118         if ( inet_aton ( value, &ipv4 ) == 0 )
1119                 return -EINVAL;
1120         return store_setting ( settings, setting, &ipv4, sizeof ( ipv4 ) );
1121 }
1122
1123 /**
1124  * Fetch and format value of IPv4 address setting
1125  *
1126  * @v settings          Settings block, or NULL to search all blocks
1127  * @v setting           Setting to fetch
1128  * @v buf               Buffer to contain formatted value
1129  * @v len               Length of buffer
1130  * @ret len             Length of formatted value, or negative error
1131  */
1132 static int fetchf_ipv4 ( struct settings *settings, struct setting *setting,
1133                          char *buf, size_t len ) {
1134         struct in_addr ipv4;
1135         int raw_len;
1136
1137         if ( ( raw_len = fetch_ipv4_setting ( settings, setting, &ipv4 ) ) < 0)
1138                 return raw_len;
1139         return snprintf ( buf, len, "%s", inet_ntoa ( ipv4 ) );
1140 }
1141
1142 /** An IPv4 address setting type */
1143 struct setting_type setting_type_ipv4 __setting_type = {
1144         .name = "ipv4",
1145         .storef = storef_ipv4,
1146         .fetchf = fetchf_ipv4,
1147 };
1148
1149 /**
1150  * Parse and store value of integer setting
1151  *
1152  * @v settings          Settings block
1153  * @v setting           Setting to store
1154  * @v value             Formatted setting data
1155  * @v size              Integer size, in bytes
1156  * @ret rc              Return status code
1157  */
1158 static int storef_int ( struct settings *settings, struct setting *setting,
1159                         const char *value, unsigned int size ) {
1160         union {
1161                 uint32_t num;
1162                 uint8_t bytes[4];
1163         } u;
1164         char *endp;
1165
1166         u.num = htonl ( strtoul ( value, &endp, 0 ) );
1167         if ( *endp )
1168                 return -EINVAL;
1169         return store_setting ( settings, setting, 
1170                                &u.bytes[ sizeof ( u ) - size ], size );
1171 }
1172
1173 /**
1174  * Parse and store value of 8-bit integer setting
1175  *
1176  * @v settings          Settings block
1177  * @v setting           Setting to store
1178  * @v value             Formatted setting data
1179  * @v size              Integer size, in bytes
1180  * @ret rc              Return status code
1181  */
1182 static int storef_int8 ( struct settings *settings, struct setting *setting,
1183                          const char *value ) {
1184         return storef_int ( settings, setting, value, 1 );
1185 }
1186
1187 /**
1188  * Parse and store value of 16-bit integer setting
1189  *
1190  * @v settings          Settings block
1191  * @v setting           Setting to store
1192  * @v value             Formatted setting data
1193  * @v size              Integer size, in bytes
1194  * @ret rc              Return status code
1195  */
1196 static int storef_int16 ( struct settings *settings, struct setting *setting,
1197                           const char *value ) {
1198         return storef_int ( settings, setting, value, 2 );
1199 }
1200
1201 /**
1202  * Parse and store value of 32-bit integer setting
1203  *
1204  * @v settings          Settings block
1205  * @v setting           Setting to store
1206  * @v value             Formatted setting data
1207  * @v size              Integer size, in bytes
1208  * @ret rc              Return status code
1209  */
1210 static int storef_int32 ( struct settings *settings, struct setting *setting,
1211                           const char *value ) {
1212         return storef_int ( settings, setting, value, 4 );
1213 }
1214
1215 /**
1216  * Fetch and format value of signed integer setting
1217  *
1218  * @v settings          Settings block, or NULL to search all blocks
1219  * @v setting           Setting to fetch
1220  * @v buf               Buffer to contain formatted value
1221  * @v len               Length of buffer
1222  * @ret len             Length of formatted value, or negative error
1223  */
1224 static int fetchf_int ( struct settings *settings, struct setting *setting,
1225                         char *buf, size_t len ) {
1226         long value;
1227         int rc;
1228
1229         if ( ( rc = fetch_int_setting ( settings, setting, &value ) ) < 0 )
1230                 return rc;
1231         return snprintf ( buf, len, "%ld", value );
1232 }
1233
1234 /**
1235  * Fetch and format value of unsigned integer setting
1236  *
1237  * @v settings          Settings block, or NULL to search all blocks
1238  * @v setting           Setting to fetch
1239  * @v buf               Buffer to contain formatted value
1240  * @v len               Length of buffer
1241  * @ret len             Length of formatted value, or negative error
1242  */
1243 static int fetchf_uint ( struct settings *settings, struct setting *setting,
1244                          char *buf, size_t len ) {
1245         unsigned long value;
1246         int rc;
1247
1248         if ( ( rc = fetch_uint_setting ( settings, setting, &value ) ) < 0 )
1249                 return rc;
1250         return snprintf ( buf, len, "%#lx", value );
1251 }
1252
1253 /** A signed 8-bit integer setting type */
1254 struct setting_type setting_type_int8 __setting_type = {
1255         .name = "int8",
1256         .storef = storef_int8,
1257         .fetchf = fetchf_int,
1258 };
1259
1260 /** A signed 16-bit integer setting type */
1261 struct setting_type setting_type_int16 __setting_type = {
1262         .name = "int16",
1263         .storef = storef_int16,
1264         .fetchf = fetchf_int,
1265 };
1266
1267 /** A signed 32-bit integer setting type */
1268 struct setting_type setting_type_int32 __setting_type = {
1269         .name = "int32",
1270         .storef = storef_int32,
1271         .fetchf = fetchf_int,
1272 };
1273
1274 /** An unsigned 8-bit integer setting type */
1275 struct setting_type setting_type_uint8 __setting_type = {
1276         .name = "uint8",
1277         .storef = storef_int8,
1278         .fetchf = fetchf_uint,
1279 };
1280
1281 /** An unsigned 16-bit integer setting type */
1282 struct setting_type setting_type_uint16 __setting_type = {
1283         .name = "uint16",
1284         .storef = storef_int16,
1285         .fetchf = fetchf_uint,
1286 };
1287
1288 /** An unsigned 32-bit integer setting type */
1289 struct setting_type setting_type_uint32 __setting_type = {
1290         .name = "uint32",
1291         .storef = storef_int32,
1292         .fetchf = fetchf_uint,
1293 };
1294
1295 /**
1296  * Parse and store value of hex string setting
1297  *
1298  * @v settings          Settings block
1299  * @v setting           Setting to store
1300  * @v value             Formatted setting data
1301  * @ret rc              Return status code
1302  */
1303 static int storef_hex ( struct settings *settings, struct setting *setting,
1304                         const char *value ) {
1305         char *ptr = ( char * ) value;
1306         uint8_t bytes[ strlen ( value ) ]; /* cannot exceed strlen(value) */
1307         unsigned int len = 0;
1308
1309         while ( 1 ) {
1310                 bytes[len++] = strtoul ( ptr, &ptr, 16 );
1311                 switch ( *ptr ) {
1312                 case '\0' :
1313                         return store_setting ( settings, setting, bytes, len );
1314                 case ':' :
1315                         ptr++;
1316                         break;
1317                 default :
1318                         return -EINVAL;
1319                 }
1320         }
1321 }
1322
1323 /**
1324  * Fetch and format value of hex string setting
1325  *
1326  * @v settings          Settings block, or NULL to search all blocks
1327  * @v setting           Setting to fetch
1328  * @v buf               Buffer to contain formatted value
1329  * @v len               Length of buffer
1330  * @ret len             Length of formatted value, or negative error
1331  */
1332 static int fetchf_hex ( struct settings *settings, struct setting *setting,
1333                         char *buf, size_t len ) {
1334         int raw_len;
1335         int check_len;
1336         int used = 0;
1337         int i;
1338
1339         raw_len = fetch_setting_len ( settings, setting );
1340         if ( raw_len < 0 )
1341                 return raw_len;
1342
1343         {
1344                 uint8_t raw[raw_len];
1345
1346                 check_len = fetch_setting ( settings, setting, raw,
1347                                             sizeof ( raw ) );
1348                 if ( check_len < 0 )
1349                         return check_len;
1350                 assert ( check_len == raw_len );
1351                 
1352                 if ( len )
1353                         buf[0] = 0; /* Ensure that a terminating NUL exists */
1354                 for ( i = 0 ; i < raw_len ; i++ ) {
1355                         used += ssnprintf ( ( buf + used ), ( len - used ),
1356                                             "%s%02x", ( used ? ":" : "" ),
1357                                             raw[i] );
1358                 }
1359                 return used;
1360         }
1361 }
1362
1363 /** A hex-string setting */
1364 struct setting_type setting_type_hex __setting_type = {
1365         .name = "hex",
1366         .storef = storef_hex,
1367         .fetchf = fetchf_hex,
1368 };
1369
1370 /**
1371  * Parse and store value of UUID setting
1372  *
1373  * @v settings          Settings block
1374  * @v setting           Setting to store
1375  * @v value             Formatted setting data
1376  * @ret rc              Return status code
1377  */
1378 static int storef_uuid ( struct settings *settings __unused,
1379                          struct setting *setting __unused,
1380                          const char *value __unused ) {
1381         return -ENOTSUP;
1382 }
1383
1384 /**
1385  * Fetch and format value of UUID setting
1386  *
1387  * @v settings          Settings block, or NULL to search all blocks
1388  * @v setting           Setting to fetch
1389  * @v buf               Buffer to contain formatted value
1390  * @v len               Length of buffer
1391  * @ret len             Length of formatted value, or negative error
1392  */
1393 static int fetchf_uuid ( struct settings *settings, struct setting *setting,
1394                          char *buf, size_t len ) {
1395         union uuid uuid;
1396         int raw_len;
1397
1398         if ( ( raw_len = fetch_uuid_setting ( settings, setting, &uuid ) ) < 0)
1399                 return raw_len;
1400         return snprintf ( buf, len, "%s", uuid_ntoa ( &uuid ) );
1401 }
1402
1403 /** UUID setting type */
1404 struct setting_type setting_type_uuid __setting_type = {
1405         .name = "uuid",
1406         .storef = storef_uuid,
1407         .fetchf = fetchf_uuid,
1408 };
1409
1410 /******************************************************************************
1411  *
1412  * Settings
1413  *
1414  ******************************************************************************
1415  */
1416
1417 /** Hostname setting */
1418 struct setting hostname_setting __setting = {
1419         .name = "hostname",
1420         .description = "Host name",
1421         .tag = DHCP_HOST_NAME,
1422         .type = &setting_type_string,
1423 };
1424
1425 /** Filename setting */
1426 struct setting filename_setting __setting = {
1427         .name = "filename",
1428         .description = "Boot filename",
1429         .tag = DHCP_BOOTFILE_NAME,
1430         .type = &setting_type_string,
1431 };
1432
1433 /** Root path setting */
1434 struct setting root_path_setting __setting = {
1435         .name = "root-path",
1436         .description = "iSCSI root path",
1437         .tag = DHCP_ROOT_PATH,
1438         .type = &setting_type_string,
1439 };
1440
1441 /** Username setting */
1442 struct setting username_setting __setting = {
1443         .name = "username",
1444         .description = "User name",
1445         .tag = DHCP_EB_USERNAME,
1446         .type = &setting_type_string,
1447 };
1448
1449 /** Password setting */
1450 struct setting password_setting __setting = {
1451         .name = "password",
1452         .description = "Password",
1453         .tag = DHCP_EB_PASSWORD,
1454         .type = &setting_type_string,
1455 };
1456
1457 /** Priority setting */
1458 struct setting priority_setting __setting = {
1459         .name = "priority",
1460         .description = "Priority of these settings",
1461         .tag = DHCP_EB_PRIORITY,
1462         .type = &setting_type_int8,
1463 };