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