iPXE
settings.c
Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2008 Michael Brown <mbrown@fensystems.co.uk>.
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License as
00006  * published by the Free Software Foundation; either version 2 of the
00007  * License, or any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful, but
00010  * WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software
00016  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
00017  * 02110-1301, USA.
00018  *
00019  * You can also choose to distribute this program under the terms of
00020  * the Unmodified Binary Distribution Licence (as given in the file
00021  * COPYING.UBDL), provided that you have satisfied its requirements.
00022  */
00023 
00024 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
00025 
00026 #include <stdint.h>
00027 #include <stdlib.h>
00028 #include <stdio.h>
00029 #include <string.h>
00030 #include <strings.h>
00031 #include <byteswap.h>
00032 #include <errno.h>
00033 #include <assert.h>
00034 #include <time.h>
00035 #include <ipxe/in.h>
00036 #include <ipxe/ip.h>
00037 #include <ipxe/ipv6.h>
00038 #include <ipxe/vsprintf.h>
00039 #include <ipxe/dhcp.h>
00040 #include <ipxe/uuid.h>
00041 #include <ipxe/uri.h>
00042 #include <ipxe/base16.h>
00043 #include <ipxe/base64.h>
00044 #include <ipxe/pci.h>
00045 #include <ipxe/init.h>
00046 #include <ipxe/version.h>
00047 #include <ipxe/settings.h>
00048 
00049 /** @file
00050  *
00051  * Configuration settings
00052  *
00053  */
00054 
00055 /******************************************************************************
00056  *
00057  * Generic settings blocks
00058  *
00059  ******************************************************************************
00060  */
00061 
00062 /**
00063  * A generic setting
00064  *
00065  */
00066 struct generic_setting {
00067         /** List of generic settings */
00068         struct list_head list;
00069         /** Setting */
00070         struct setting setting;
00071         /** Size of setting name */
00072         size_t name_len;
00073         /** Size of setting data */
00074         size_t data_len;
00075 };
00076 
00077 /**
00078  * Get generic setting name
00079  *
00080  * @v generic           Generic setting
00081  * @ret name            Generic setting name
00082  */
00083 static inline void * generic_setting_name ( struct generic_setting *generic ) {
00084         return ( ( ( void * ) generic ) + sizeof ( *generic ) );
00085 }
00086 
00087 /**
00088  * Get generic setting data
00089  *
00090  * @v generic           Generic setting
00091  * @ret data            Generic setting data
00092  */
00093 static inline void * generic_setting_data ( struct generic_setting *generic ) {
00094         return ( ( ( void * ) generic ) + sizeof ( *generic ) +
00095                  generic->name_len );
00096 }
00097 
00098 /**
00099  * Find generic setting
00100  *
00101  * @v generics          Generic settings block
00102  * @v setting           Setting to find
00103  * @ret generic         Generic setting, or NULL
00104  */
00105 static struct generic_setting *
00106 find_generic_setting ( struct generic_settings *generics,
00107                        const struct setting *setting ) {
00108         struct generic_setting *generic;
00109 
00110         list_for_each_entry ( generic, &generics->list, list ) {
00111                 if ( setting_cmp ( &generic->setting, setting ) == 0 )
00112                         return generic;
00113         }
00114         return NULL;
00115 }
00116 
00117 /**
00118  * Store value of generic setting
00119  *
00120  * @v settings          Settings block
00121  * @v setting           Setting to store
00122  * @v data              Setting data, or NULL to clear setting
00123  * @v len               Length of setting data
00124  * @ret rc              Return status code
00125  */
00126 int generic_settings_store ( struct settings *settings,
00127                              const struct setting *setting,
00128                              const void *data, size_t len ) {
00129         struct generic_settings *generics =
00130                 container_of ( settings, struct generic_settings, settings );
00131         struct generic_setting *old;
00132         struct generic_setting *new = NULL;
00133         size_t name_len;
00134 
00135         /* Identify existing generic setting, if any */
00136         old = find_generic_setting ( generics, setting );
00137 
00138         /* Create new generic setting, if required */
00139         if ( len ) {
00140                 /* Allocate new generic setting */
00141                 name_len = ( strlen ( setting->name ) + 1 );
00142                 new = zalloc ( sizeof ( *new ) + name_len + len );
00143                 if ( ! new )
00144                         return -ENOMEM;
00145 
00146                 /* Populate new generic setting */
00147                 new->name_len = name_len;
00148                 new->data_len = len;
00149                 memcpy ( &new->setting, setting, sizeof ( new->setting ) );
00150                 new->setting.name = generic_setting_name ( new );
00151                 memcpy ( generic_setting_name ( new ),
00152                          setting->name, name_len );
00153                 memcpy ( generic_setting_data ( new ), data, len );
00154         }
00155 
00156         /* Delete existing generic setting, if any */
00157         if ( old ) {
00158                 list_del ( &old->list );
00159                 free ( old );
00160         }
00161 
00162         /* Add new setting to list, if any */
00163         if ( new )
00164                 list_add ( &new->list, &generics->list );
00165 
00166         return 0;
00167 }
00168 
00169 /**
00170  * Fetch value of generic setting
00171  *
00172  * @v settings          Settings block
00173  * @v setting           Setting to fetch
00174  * @v data              Buffer to fill with setting data
00175  * @v len               Length of buffer
00176  * @ret len             Length of setting data, or negative error
00177  */
00178 int generic_settings_fetch ( struct settings *settings,
00179                              struct setting *setting,
00180                              void *data, size_t len ) {
00181         struct generic_settings *generics =
00182                 container_of ( settings, struct generic_settings, settings );
00183         struct generic_setting *generic;
00184 
00185         /* Find generic setting */
00186         generic = find_generic_setting ( generics, setting );
00187         if ( ! generic )
00188                 return -ENOENT;
00189 
00190         /* Copy out generic setting data */
00191         if ( len > generic->data_len )
00192                 len = generic->data_len;
00193         memcpy ( data, generic_setting_data ( generic ), len );
00194 
00195         /* Set setting type, if not yet specified */
00196         if ( ! setting->type )
00197                 setting->type = generic->setting.type;
00198 
00199         return generic->data_len;
00200 }
00201 
00202 /**
00203  * Clear generic settings block
00204  *
00205  * @v settings          Settings block
00206  */
00207 void generic_settings_clear ( struct settings *settings ) {
00208         struct generic_settings *generics =
00209                 container_of ( settings, struct generic_settings, settings );
00210         struct generic_setting *generic;
00211         struct generic_setting *tmp;
00212 
00213         list_for_each_entry_safe ( generic, tmp, &generics->list, list ) {
00214                 list_del ( &generic->list );
00215                 free ( generic );
00216         }
00217         assert ( list_empty ( &generics->list ) );
00218 }
00219 
00220 /** Generic settings operations */
00221 struct settings_operations generic_settings_operations = {
00222         .store = generic_settings_store,
00223         .fetch = generic_settings_fetch,
00224         .clear = generic_settings_clear,
00225 };
00226 
00227 /******************************************************************************
00228  *
00229  * Registered settings blocks
00230  *
00231  ******************************************************************************
00232  */
00233 
00234 /** Root generic settings block */
00235 struct generic_settings generic_settings_root = {
00236         .settings = {
00237                 .refcnt = NULL,
00238                 .name = "",
00239                 .siblings =
00240                     LIST_HEAD_INIT ( generic_settings_root.settings.siblings ),
00241                 .children =
00242                     LIST_HEAD_INIT ( generic_settings_root.settings.children ),
00243                 .op = &generic_settings_operations,
00244         },
00245         .list = LIST_HEAD_INIT ( generic_settings_root.list ),
00246 };
00247 
00248 /** Root settings block */
00249 #define settings_root generic_settings_root.settings
00250 
00251 /** Autovivified settings block */
00252 struct autovivified_settings {
00253         /** Reference count */
00254         struct refcnt refcnt;
00255         /** Generic settings block */
00256         struct generic_settings generic;
00257 };
00258 
00259 /**
00260  * Free autovivified settings block
00261  *
00262  * @v refcnt            Reference count
00263  */
00264 static void autovivified_settings_free ( struct refcnt *refcnt ) {
00265         struct autovivified_settings *autovivified =
00266                 container_of ( refcnt, struct autovivified_settings, refcnt );
00267 
00268         generic_settings_clear ( &autovivified->generic.settings );
00269         free ( autovivified );
00270 }
00271 
00272 /**
00273  * Find child settings block
00274  *
00275  * @v parent            Parent settings block
00276  * @v name              Name within this parent
00277  * @ret settings        Settings block, or NULL
00278  */
00279 struct settings * find_child_settings ( struct settings *parent,
00280                                         const char *name ) {
00281         struct settings *settings;
00282 
00283         /* Find target parent settings block */
00284         parent = settings_target ( parent );
00285 
00286         /* Treat empty name as meaning "this block" */
00287         if ( ! *name )
00288                 return parent;
00289 
00290         /* Look for child with matching name */
00291         list_for_each_entry ( settings, &parent->children, siblings ) {
00292                 if ( strcmp ( settings->name, name ) == 0 )
00293                         return settings_target ( settings );
00294         }
00295 
00296         return NULL;
00297 }
00298 
00299 /**
00300  * Find or create child settings block
00301  *
00302  * @v parent            Parent settings block
00303  * @v name              Name within this parent
00304  * @ret settings        Settings block, or NULL
00305  */
00306 struct settings * autovivify_child_settings ( struct settings *parent,
00307                                               const char *name ) {
00308         struct {
00309                 struct autovivified_settings autovivified;
00310                 char name[ strlen ( name ) + 1 /* NUL */ ];
00311         } *new_child;
00312         struct settings *settings;
00313 
00314         /* Find target parent settings block */
00315         parent = settings_target ( parent );
00316 
00317         /* Return existing settings, if existent */
00318         if ( ( settings = find_child_settings ( parent, name ) ) != NULL )
00319                 return settings;
00320 
00321         /* Create new generic settings block */
00322         new_child = zalloc ( sizeof ( *new_child ) );
00323         if ( ! new_child ) {
00324                 DBGC ( parent, "Settings %p could not create child %s\n",
00325                        parent, name );
00326                 return NULL;
00327         }
00328         memcpy ( new_child->name, name, sizeof ( new_child->name ) );
00329         ref_init ( &new_child->autovivified.refcnt,
00330                    autovivified_settings_free );
00331         generic_settings_init ( &new_child->autovivified.generic,
00332                                 &new_child->autovivified.refcnt );
00333         settings = &new_child->autovivified.generic.settings;
00334         register_settings ( settings, parent, new_child->name );
00335         ref_put ( settings->refcnt );
00336         return settings;
00337 }
00338 
00339 /**
00340  * Return settings block name
00341  *
00342  * @v settings          Settings block
00343  * @ret name            Settings block name
00344  */
00345 const char * settings_name ( struct settings *settings ) {
00346         static char buf[16];
00347         char tmp[ 1 /* '.' */ + sizeof ( buf ) ];
00348 
00349         /* Find target settings block */
00350         settings = settings_target ( settings );
00351 
00352         /* Construct name */
00353         buf[0] = '\0';
00354         tmp[0] = '\0';
00355         for ( ; settings->parent ; settings = settings->parent ) {
00356                 memcpy ( ( tmp + 1 ), buf, ( sizeof ( tmp ) - 1 ) );
00357                 snprintf ( buf, sizeof ( buf ), "%s%s", settings->name, tmp );
00358                 tmp[0] = '.';
00359         }
00360         return buf;
00361 }
00362 
00363 /**
00364  * Parse settings block name
00365  *
00366  * @v name              Name
00367  * @v get_child         Function to find or create child settings block
00368  * @ret settings        Settings block, or NULL
00369  */
00370 static struct settings *
00371 parse_settings_name ( const char *name, get_child_settings_t get_child ) {
00372         struct settings *settings = &settings_root;
00373         char name_copy[ strlen ( name ) + 1 ];
00374         char *subname;
00375         char *remainder;
00376 
00377         /* Create modifiable copy of name */
00378         memcpy ( name_copy, name, sizeof ( name_copy ) );
00379         remainder = name_copy;
00380 
00381         /* Parse each name component in turn */
00382         while ( remainder ) {
00383                 subname = remainder;
00384                 remainder = strchr ( subname, '.' );
00385                 if ( remainder )
00386                         *(remainder++) = '\0';
00387                 settings = get_child ( settings, subname );
00388                 if ( ! settings )
00389                         break;
00390         }
00391 
00392         return settings;
00393 }
00394 
00395 /**
00396  * Find settings block
00397  *
00398  * @v name              Name
00399  * @ret settings        Settings block, or NULL
00400  */
00401 struct settings * find_settings ( const char *name ) {
00402 
00403         return parse_settings_name ( name, find_child_settings );
00404 }
00405 
00406 /**
00407  * Apply all settings
00408  *
00409  * @ret rc              Return status code
00410  */
00411 static int apply_settings ( void ) {
00412         struct settings_applicator *applicator;
00413         int rc;
00414 
00415         /* Call all settings applicators */
00416         for_each_table_entry ( applicator, SETTINGS_APPLICATORS ) {
00417                 if ( ( rc = applicator->apply() ) != 0 ) {
00418                         DBG ( "Could not apply settings using applicator "
00419                               "%p: %s\n", applicator, strerror ( rc ) );
00420                         return rc;
00421                 }
00422         }
00423 
00424         return 0;
00425 }
00426 
00427 /**
00428  * Reprioritise settings
00429  *
00430  * @v settings          Settings block
00431  *
00432  * Reorders the settings block amongst its siblings according to its
00433  * priority.
00434  */
00435 static void reprioritise_settings ( struct settings *settings ) {
00436         struct settings *parent = settings->parent;
00437         long priority;
00438         struct settings *tmp;
00439         long tmp_priority;
00440 
00441         /* Stop when we reach the top of the tree */
00442         if ( ! parent )
00443                 return;
00444 
00445         /* Read priority, if present */
00446         priority = fetch_intz_setting ( settings, &priority_setting );
00447 
00448         /* Remove from siblings list */
00449         list_del ( &settings->siblings );
00450 
00451         /* Reinsert after any existing blocks which have a higher priority */
00452         list_for_each_entry ( tmp, &parent->children, siblings ) {
00453                 tmp_priority = fetch_intz_setting ( tmp, &priority_setting );
00454                 if ( priority > tmp_priority )
00455                         break;
00456                 if ( settings->order > tmp->order )
00457                         break;
00458         }
00459         list_add_tail ( &settings->siblings, &tmp->siblings );
00460 
00461         /* Recurse up the tree */
00462         reprioritise_settings ( parent );
00463 }
00464 
00465 /**
00466  * Register settings block
00467  *
00468  * @v settings          Settings block
00469  * @v parent            Parent settings block, or NULL
00470  * @v name              Settings block name
00471  * @ret rc              Return status code
00472  */
00473 int register_settings ( struct settings *settings, struct settings *parent,
00474                         const char *name ) {
00475         struct settings *old_settings;
00476 
00477         /* Sanity check */
00478         assert ( settings != NULL );
00479 
00480         /* Find target parent settings block */
00481         parent = settings_target ( parent );
00482 
00483         /* Apply settings block name */
00484         settings->name = name;
00485 
00486         /* Remove any existing settings with the same name */
00487         if ( ( old_settings = find_child_settings ( parent, settings->name ) ))
00488                 unregister_settings ( old_settings );
00489 
00490         /* Add to list of settings */
00491         ref_get ( settings->refcnt );
00492         ref_get ( parent->refcnt );
00493         settings->parent = parent;
00494         list_add_tail ( &settings->siblings, &parent->children );
00495         DBGC ( settings, "Settings %p (\"%s\") registered\n",
00496                settings, settings_name ( settings ) );
00497 
00498         /* Fix up settings priority */
00499         reprioritise_settings ( settings );
00500 
00501         /* Apply potentially-updated settings */
00502         apply_settings();
00503 
00504         return 0;
00505 }
00506 
00507 /**
00508  * Unregister settings block
00509  *
00510  * @v settings          Settings block
00511  */
00512 void unregister_settings ( struct settings *settings ) {
00513         struct settings *child;
00514 
00515         /* Unregister child settings */
00516         while ( ( child = list_first_entry ( &settings->children,
00517                                              struct settings, siblings ) ) ) {
00518                 unregister_settings ( child );
00519         }
00520 
00521         DBGC ( settings, "Settings %p (\"%s\") unregistered\n",
00522                settings, settings_name ( settings ) );
00523 
00524         /* Remove from list of settings */
00525         ref_put ( settings->parent->refcnt );
00526         settings->parent = NULL;
00527         list_del ( &settings->siblings );
00528         ref_put ( settings->refcnt );
00529 
00530         /* Apply potentially-updated settings */
00531         apply_settings();
00532 }
00533 
00534 /******************************************************************************
00535  *
00536  * Core settings routines
00537  *
00538  ******************************************************************************
00539  */
00540 
00541 /**
00542  * Redirect to target settings block
00543  *
00544  * @v settings          Settings block, or NULL
00545  * @ret settings        Underlying settings block
00546  */
00547 struct settings * settings_target ( struct settings *settings ) {
00548 
00549         /* NULL settings implies the global settings root */
00550         if ( ! settings )
00551                 settings = &settings_root;
00552 
00553         /* Redirect to underlying settings block, if applicable */
00554         if ( settings->op->redirect )
00555                 return settings->op->redirect ( settings );
00556 
00557         /* Otherwise, return this settings block */
00558         return settings;
00559 }
00560 
00561 /**
00562  * Check applicability of setting
00563  *
00564  * @v settings          Settings block
00565  * @v setting           Setting
00566  * @ret applies         Setting applies within this settings block
00567  */
00568 int setting_applies ( struct settings *settings,
00569                       const struct setting *setting ) {
00570 
00571         /* Find target settings block */
00572         settings = settings_target ( settings );
00573 
00574         /* Check applicability of setting */
00575         return ( settings->op->applies ?
00576                  settings->op->applies ( settings, setting ) : 1 );
00577 }
00578 
00579 /**
00580  * Find setting applicable to settings block, if any
00581  *
00582  * @v settings          Settings block
00583  * @v setting           Setting
00584  * @ret setting         Applicable setting, if any
00585  */
00586 static const struct setting *
00587 applicable_setting ( struct settings *settings, const struct setting *setting ){
00588         const struct setting *applicable;
00589 
00590         /* If setting is already applicable, use it */
00591         if ( setting_applies ( settings, setting ) )
00592                 return setting;
00593 
00594         /* Otherwise, look for a matching predefined setting which does apply */
00595         for_each_table_entry ( applicable, SETTINGS ) {
00596                 if ( ( setting_cmp ( setting, applicable ) == 0 ) &&
00597                      ( setting_applies ( settings, applicable ) ) )
00598                         return applicable;
00599         }
00600 
00601         return NULL;
00602 }
00603 
00604 /**
00605  * Store value of setting
00606  *
00607  * @v settings          Settings block, or NULL
00608  * @v setting           Setting to store
00609  * @v data              Setting data, or NULL to clear setting
00610  * @v len               Length of setting data
00611  * @ret rc              Return status code
00612  */
00613 int store_setting ( struct settings *settings, const struct setting *setting,
00614                     const void *data, size_t len ) {
00615         int rc;
00616 
00617         /* Find target settings block */
00618         settings = settings_target ( settings );
00619 
00620         /* Fail if setting does not apply to this settings block */
00621         if ( ! setting_applies ( settings, setting ) )
00622                 return -ENOTTY;
00623 
00624         /* Sanity check */
00625         if ( ! settings->op->store )
00626                 return -ENOTSUP;
00627 
00628         /* Store setting */
00629         if ( ( rc = settings->op->store ( settings, setting,
00630                                           data, len ) ) != 0 )
00631                 return rc;
00632 
00633         /* Reprioritise settings if necessary */
00634         if ( setting_cmp ( setting, &priority_setting ) == 0 )
00635                 reprioritise_settings ( settings );
00636 
00637         /* If these settings are registered, apply potentially-updated
00638          * settings
00639          */
00640         for ( ; settings ; settings = settings->parent ) {
00641                 if ( settings == &settings_root ) {
00642                         if ( ( rc = apply_settings() ) != 0 )
00643                                 return rc;
00644                         break;
00645                 }
00646         }
00647 
00648         return 0;
00649 }
00650 
00651 /**
00652  * Fetch setting
00653  *
00654  * @v settings          Settings block, or NULL to search all blocks
00655  * @v setting           Setting to fetch
00656  * @v origin            Origin of setting to fill in, or NULL
00657  * @v fetched           Fetched setting to fill in, or NULL
00658  * @v data              Buffer to fill with setting data
00659  * @v len               Length of buffer
00660  * @ret len             Length of setting data, or negative error
00661  *
00662  * The actual length of the setting will be returned even if
00663  * the buffer was too small.
00664  */
00665 int fetch_setting ( struct settings *settings, const struct setting *setting,
00666                     struct settings **origin, struct setting *fetched,
00667                     void *data, size_t len ) {
00668         const struct setting *applicable;
00669         struct settings *child;
00670         struct setting tmp;
00671         int ret;
00672 
00673         /* Avoid returning uninitialised data on error */
00674         memset ( data, 0, len );
00675         if ( origin )
00676                 *origin = NULL;
00677         if ( fetched )
00678                 memcpy ( fetched, setting, sizeof ( *fetched ) );
00679 
00680         /* Find target settings block */
00681         settings = settings_target ( settings );
00682 
00683         /* Sanity check */
00684         if ( ! settings->op->fetch )
00685                 return -ENOTSUP;
00686 
00687         /* Try this block first, if an applicable setting exists */
00688         if ( ( applicable = applicable_setting ( settings, setting ) ) ) {
00689 
00690                 /* Create modifiable copy of setting */
00691                 memcpy ( &tmp, applicable, sizeof ( tmp ) );
00692                 if ( ( ret = settings->op->fetch ( settings, &tmp,
00693                                                    data, len ) ) >= 0 ) {
00694 
00695                         /* Default to string type, if not yet specified */
00696                         if ( ! tmp.type )
00697                                 tmp.type = &setting_type_string;
00698 
00699                         /* Record origin, if applicable */
00700                         if ( origin )
00701                                 *origin = settings;
00702 
00703                         /* Record fetched setting, if applicable */
00704                         if ( fetched )
00705                                 memcpy ( fetched, &tmp, sizeof ( *fetched ) );
00706 
00707                         return ret;
00708                 }
00709         }
00710 
00711         /* Recurse into each child block in turn */
00712         list_for_each_entry ( child, &settings->children, siblings ) {
00713                 if ( ( ret = fetch_setting ( child, setting, origin, fetched,
00714                                              data, len ) ) >= 0 )
00715                         return ret;
00716         }
00717 
00718         return -ENOENT;
00719 }
00720 
00721 /**
00722  * Fetch allocated copy of setting
00723  *
00724  * @v settings          Settings block, or NULL to search all blocks
00725  * @v setting           Setting to fetch
00726  * @v origin            Origin of setting to fill in, or NULL
00727  * @v fetched           Fetched setting to fill in, or NULL
00728  * @v data              Buffer to allocate and fill with setting data
00729  * @v alloc             Allocation function
00730  * @ret len             Length of setting, or negative error
00731  *
00732  * The caller is responsible for eventually freeing the allocated
00733  * buffer.
00734  */
00735 static int fetch_setting_alloc ( struct settings *settings,
00736                                  const struct setting *setting,
00737                                  struct settings **origin,
00738                                  struct setting *fetched,
00739                                  void **data,
00740                                  void * ( * alloc ) ( size_t len ) ) {
00741         struct settings *tmp_origin;
00742         struct setting tmp_fetched;
00743         int len;
00744         int check_len;
00745 
00746         /* Use local buffers if necessary */
00747         if ( ! origin )
00748                 origin = &tmp_origin;
00749         if ( ! fetched )
00750                 fetched = &tmp_fetched;
00751 
00752         /* Avoid returning uninitialised data on error */
00753         *data = NULL;
00754 
00755         /* Check existence, and fetch setting length */
00756         len = fetch_setting ( settings, setting, origin, fetched, NULL, 0 );
00757         if ( len < 0 )
00758                 return len;
00759 
00760         /* Allocate buffer */
00761         *data = alloc ( len );
00762         if ( ! *data )
00763                 return -ENOMEM;
00764 
00765         /* Fetch setting value */
00766         check_len = fetch_setting ( *origin, fetched, NULL, NULL, *data, len );
00767         assert ( check_len == len );
00768         return len;
00769 }
00770 
00771 /**
00772  * Fetch copy of setting
00773  *
00774  * @v settings          Settings block, or NULL to search all blocks
00775  * @v setting           Setting to fetch
00776  * @v origin            Origin of setting to fill in, or NULL
00777  * @v fetched           Fetched setting to fill in, or NULL
00778  * @v data              Buffer to allocate and fill with setting data
00779  * @ret len             Length of setting, or negative error
00780  *
00781  * The caller is responsible for eventually freeing the allocated
00782  * buffer.
00783  */
00784 int fetch_setting_copy ( struct settings *settings,
00785                          const struct setting *setting,
00786                          struct settings **origin, struct setting *fetched,
00787                          void **data ) {
00788 
00789         return fetch_setting_alloc ( settings, setting, origin, fetched,
00790                                      data, malloc );
00791 }
00792 
00793 /**
00794  * Fetch value of setting
00795  *
00796  * @v settings          Settings block, or NULL to search all blocks
00797  * @v setting           Setting to fetch
00798  * @v data              Buffer to fill with setting string data
00799  * @v len               Length of buffer
00800  * @ret len             Length of setting, or negative error
00801  */
00802 int fetch_raw_setting ( struct settings *settings,
00803                         const struct setting *setting,
00804                         void *data, size_t len ) {
00805 
00806         return fetch_setting ( settings, setting, NULL, NULL, data, len );
00807 }
00808 
00809 /**
00810  * Fetch value of setting
00811  *
00812  * @v settings          Settings block, or NULL to search all blocks
00813  * @v setting           Setting to fetch
00814  * @v data              Buffer to allocate and fill with setting data
00815  * @ret len             Length of setting, or negative error
00816  *
00817  * The caller is responsible for eventually freeing the allocated
00818  * buffer.
00819  */
00820 int fetch_raw_setting_copy ( struct settings *settings,
00821                              const struct setting *setting,
00822                              void **data ) {
00823 
00824         return fetch_setting_copy ( settings, setting, NULL, NULL, data );
00825 }
00826 
00827 /**
00828  * Fetch value of string setting
00829  *
00830  * @v settings          Settings block, or NULL to search all blocks
00831  * @v setting           Setting to fetch
00832  * @v data              Buffer to fill with setting string data
00833  * @v len               Length of buffer
00834  * @ret len             Length of string setting, or negative error
00835  *
00836  * The resulting string is guaranteed to be correctly NUL-terminated.
00837  * The returned length will be the length of the underlying setting
00838  * data.
00839  */
00840 int fetch_string_setting ( struct settings *settings,
00841                            const struct setting *setting,
00842                            char *data, size_t len ) {
00843 
00844         memset ( data, 0, len );
00845         return fetch_raw_setting ( settings, setting, data,
00846                                    ( ( len > 0 ) ? ( len - 1 ) : 0 ) );
00847 }
00848 
00849 /**
00850  * Allocate memory for copy of string setting
00851  *
00852  * @v len               Length of setting
00853  * @ret ptr             Allocated memory
00854  */
00855 static void * fetch_string_setting_copy_alloc ( size_t len ) {
00856         return zalloc ( len + 1 /* NUL */ );
00857 }
00858 
00859 /**
00860  * Fetch value of string setting
00861  *
00862  * @v settings          Settings block, or NULL to search all blocks
00863  * @v setting           Setting to fetch
00864  * @v data              Buffer to allocate and fill with setting string data
00865  * @ret len             Length of string setting, or negative error
00866  *
00867  * The resulting string is guaranteed to be correctly NUL-terminated.
00868  * The returned length will be the length of the underlying setting
00869  * data.  The caller is responsible for eventually freeing the
00870  * allocated buffer.
00871  */
00872 int fetch_string_setting_copy ( struct settings *settings,
00873                                 const struct setting *setting, char **data ) {
00874 
00875         return fetch_setting_alloc ( settings, setting, NULL, NULL,
00876                                      ( ( void ** ) data ),
00877                                      fetch_string_setting_copy_alloc );
00878 }
00879 
00880 /**
00881  * Fetch value of IPv4 address setting
00882  *
00883  * @v settings          Settings block, or NULL to search all blocks
00884  * @v setting           Setting to fetch
00885  * @v inp               IPv4 addresses to fill in
00886  * @v count             Maximum number of IPv4 addresses
00887  * @ret len             Length of setting, or negative error
00888  */
00889 int fetch_ipv4_array_setting ( struct settings *settings,
00890                                const struct setting *setting,
00891                                struct in_addr *inp, unsigned int count ) {
00892         int len;
00893 
00894         len = fetch_raw_setting ( settings, setting, inp,
00895                                   ( sizeof ( *inp ) * count ) );
00896         if ( len < 0 )
00897                 return len;
00898         if ( ( len % sizeof ( *inp ) ) != 0 )
00899                 return -ERANGE;
00900         return len;
00901 }
00902 
00903 /**
00904  * Fetch value of IPv4 address setting
00905  *
00906  * @v settings          Settings block, or NULL to search all blocks
00907  * @v setting           Setting to fetch
00908  * @v inp               IPv4 address to fill in
00909  * @ret len             Length of setting, or negative error
00910  */
00911 int fetch_ipv4_setting ( struct settings *settings,
00912                          const struct setting *setting,
00913                          struct in_addr *inp ) {
00914 
00915         return fetch_ipv4_array_setting ( settings, setting, inp, 1 );
00916 }
00917 
00918 /**
00919  * Fetch value of IPv6 address setting
00920  *
00921  * @v settings          Settings block, or NULL to search all blocks
00922  * @v setting           Setting to fetch
00923  * @v inp               IPv6 addresses to fill in
00924  * @v count             Maximum number of IPv6 addresses
00925  * @ret len             Length of setting, or negative error
00926  */
00927 int fetch_ipv6_array_setting ( struct settings *settings,
00928                                const struct setting *setting,
00929                                struct in6_addr *inp, unsigned int count ) {
00930         int len;
00931 
00932         len = fetch_raw_setting ( settings, setting, inp,
00933                                   ( sizeof ( *inp ) * count ) );
00934         if ( len < 0 )
00935                 return len;
00936         if ( ( len % sizeof ( *inp ) ) != 0 )
00937                 return -ERANGE;
00938         return len;
00939 }
00940 
00941 /**
00942  * Fetch value of IPv6 address setting
00943  *
00944  * @v settings          Settings block, or NULL to search all blocks
00945  * @v setting           Setting to fetch
00946  * @v inp               IPv6 address to fill in
00947  * @ret len             Length of setting, or negative error
00948  */
00949 int fetch_ipv6_setting ( struct settings *settings,
00950                          const struct setting *setting,
00951                          struct in6_addr *inp ) {
00952 
00953         return fetch_ipv6_array_setting ( settings, setting, inp, 1 );
00954 }
00955 
00956 /**
00957  * Extract numeric value of setting
00958  *
00959  * @v is_signed         Treat value as a signed integer
00960  * @v raw               Raw setting data
00961  * @v len               Length of raw setting data
00962  * @ret value           Numeric value
00963  * @ret len             Length of setting, or negative error
00964  */
00965 static int numeric_setting_value ( int is_signed, const void *raw, size_t len,
00966                                    unsigned long *value ) {
00967         const uint8_t *unsigned_bytes = raw;
00968         const int8_t *signed_bytes = raw;
00969         int is_negative;
00970         unsigned int i;
00971         uint8_t pad;
00972         uint8_t byte;
00973 
00974         /* Convert to host-ordered longs */
00975         is_negative = ( len && ( signed_bytes[0] < 0 ) );
00976         *value = ( ( is_signed && is_negative ) ? -1L : 0 );
00977         pad = *value;
00978         for ( i = 0 ; i < len ; i++ ) {
00979                 byte = unsigned_bytes[i];
00980                 *value = ( ( *value << 8 ) | byte );
00981                 if ( ( ( i + sizeof ( *value ) ) < len ) && ( byte != pad ) )
00982                         return -ERANGE;
00983         }
00984 
00985         return len;
00986 }
00987 
00988 /**
00989  * Fetch value of numeric setting
00990  *
00991  * @v settings          Settings block, or NULL to search all blocks
00992  * @v setting           Setting to fetch
00993  * @v value             Integer value to fill in
00994  * @ret len             Length of setting, or negative error
00995  */
00996 int fetch_numeric_setting ( struct settings *settings,
00997                             const struct setting *setting,
00998                             unsigned long *value, int is_signed ) {
00999         unsigned long tmp;
01000         int len;
01001 
01002         /* Avoid returning uninitialised data on error */
01003         *value = 0;
01004 
01005         /* Fetch raw (network-ordered, variable-length) setting */
01006         len = fetch_raw_setting ( settings, setting, &tmp, sizeof ( tmp ) );
01007         if ( len < 0 )
01008                 return len;
01009 
01010         /* Extract numeric value */
01011         return numeric_setting_value ( is_signed, &tmp, len, value );
01012 }
01013 
01014 /**
01015  * Fetch value of signed integer setting
01016  *
01017  * @v settings          Settings block, or NULL to search all blocks
01018  * @v setting           Setting to fetch
01019  * @v value             Integer value to fill in
01020  * @ret len             Length of setting, or negative error
01021  */
01022 int fetch_int_setting ( struct settings *settings,
01023                         const struct setting *setting,
01024                         long *value ) {
01025 
01026         return fetch_numeric_setting ( settings, setting,
01027                                        ( ( unsigned long * ) value ), 1 );
01028 }
01029 
01030 /**
01031  * Fetch value of unsigned integer setting
01032  *
01033  * @v settings          Settings block, or NULL to search all blocks
01034  * @v setting           Setting to fetch
01035  * @v value             Integer value to fill in
01036  * @ret len             Length of setting, or negative error
01037  */
01038 int fetch_uint_setting ( struct settings *settings,
01039                          const struct setting *setting,
01040                          unsigned long *value ) {
01041 
01042         return fetch_numeric_setting ( settings, setting, value, 0 );
01043 }
01044 
01045 /**
01046  * Fetch value of signed integer setting, or zero
01047  *
01048  * @v settings          Settings block, or NULL to search all blocks
01049  * @v setting           Setting to fetch
01050  * @ret value           Setting value, or zero
01051  */
01052 long fetch_intz_setting ( struct settings *settings,
01053                           const struct setting *setting ) {
01054         unsigned long value;
01055 
01056         fetch_numeric_setting ( settings, setting, &value, 1 );
01057         return value;
01058 }
01059 
01060 /**
01061  * Fetch value of unsigned integer setting, or zero
01062  *
01063  * @v settings          Settings block, or NULL to search all blocks
01064  * @v setting           Setting to fetch
01065  * @ret value           Setting value, or zero
01066  */
01067 unsigned long fetch_uintz_setting ( struct settings *settings,
01068                                     const struct setting *setting ) {
01069         unsigned long value;
01070 
01071         fetch_numeric_setting ( settings, setting, &value, 0 );
01072         return value;
01073 }
01074 
01075 /**
01076  * Fetch value of UUID setting
01077  *
01078  * @v settings          Settings block, or NULL to search all blocks
01079  * @v setting           Setting to fetch
01080  * @v uuid              UUID to fill in
01081  * @ret len             Length of setting, or negative error
01082  */
01083 int fetch_uuid_setting ( struct settings *settings,
01084                          const struct setting *setting,
01085                          union uuid *uuid ) {
01086         int len;
01087 
01088         len = fetch_raw_setting ( settings, setting, uuid, sizeof ( *uuid ) );
01089         if ( len < 0 )
01090                 return len;
01091         if ( len != sizeof ( *uuid ) )
01092                 return -ERANGE;
01093         return len;
01094 }
01095 
01096 /**
01097  * Clear settings block
01098  *
01099  * @v settings          Settings block
01100  */
01101 void clear_settings ( struct settings *settings ) {
01102 
01103         /* Find target settings block */
01104         settings = settings_target ( settings );
01105 
01106         /* Clear settings, if applicable */
01107         if ( settings->op->clear )
01108                 settings->op->clear ( settings );
01109 }
01110 
01111 /**
01112  * Compare two settings
01113  *
01114  * @v a                 Setting to compare
01115  * @v b                 Setting to compare
01116  * @ret 0               Settings are the same
01117  * @ret non-zero        Settings are not the same
01118  */
01119 int setting_cmp ( const struct setting *a, const struct setting *b ) {
01120 
01121         /* If the settings have tags, compare them */
01122         if ( a->tag && ( a->tag == b->tag ) && ( a->scope == b->scope ) )
01123                 return 0;
01124 
01125         /* Otherwise, if the settings have names, compare them */
01126         if ( a->name && b->name && a->name[0] )
01127                 return strcmp ( a->name, b->name );
01128 
01129         /* Otherwise, return a non-match */
01130         return ( ! 0 );
01131 }
01132 
01133 /******************************************************************************
01134  *
01135  * Formatted setting routines
01136  *
01137  ******************************************************************************
01138  */
01139 
01140 /**
01141  * Format setting value as a string
01142  *
01143  * @v type              Setting type
01144  * @v raw               Raw setting value
01145  * @v raw_len           Length of raw setting value
01146  * @v buf               Buffer to contain formatted value
01147  * @v len               Length of buffer
01148  * @ret len             Length of formatted value, or negative error
01149  */
01150 int setting_format ( const struct setting_type *type, const void *raw,
01151                      size_t raw_len, char *buf, size_t len ) {
01152 
01153         /* Sanity check */
01154         if ( ! type->format )
01155                 return -ENOTSUP;
01156 
01157         return type->format ( type, raw, raw_len, buf, len );
01158 }
01159 
01160 /**
01161  * Parse formatted string to setting value
01162  *
01163  * @v type              Setting type
01164  * @v value             Formatted setting value
01165  * @v buf               Buffer to contain raw value
01166  * @v len               Length of buffer
01167  * @ret len             Length of raw value, or negative error
01168  */
01169 int setting_parse ( const struct setting_type *type, const char *value,
01170                     void *buf, size_t len ) {
01171 
01172         /* Sanity check */
01173         if ( ! type->parse )
01174                 return -ENOTSUP;
01175 
01176         return type->parse ( type, value, buf, len );
01177 }
01178 
01179 /**
01180  * Convert setting value to number
01181  *
01182  * @v type              Setting type
01183  * @v raw               Raw setting value
01184  * @v raw_len           Length of raw setting value
01185  * @ret value           Numeric value
01186  * @ret rc              Return status code
01187  */
01188 int setting_numerate ( const struct setting_type *type, const void *raw,
01189                        size_t raw_len, unsigned long *value ) {
01190 
01191         /* Sanity check */
01192         if ( ! type->numerate )
01193                 return -ENOTSUP;
01194 
01195         return type->numerate ( type, raw, raw_len, value );
01196 }
01197 
01198 /**
01199  * Convert number to setting value
01200  *
01201  * @v type              Setting type
01202  * @v value             Numeric value
01203  * @v buf               Buffer to contain raw value
01204  * @v len               Length of buffer
01205  * @ret len             Length of raw value, or negative error
01206  */
01207 int setting_denumerate ( const struct setting_type *type, unsigned long value,
01208                          void *buf, size_t len ) {
01209 
01210         /* Sanity check */
01211         if ( ! type->denumerate )
01212                 return -ENOTSUP;
01213 
01214         return type->denumerate ( type, value, buf, len );
01215 }
01216 
01217 /**
01218  * Fetch formatted value of setting
01219  *
01220  * @v settings          Settings block, or NULL to search all blocks
01221  * @v setting           Setting to fetch
01222  * @v origin            Origin of setting to fill in, or NULL
01223  * @v fetched           Fetched setting to fill in, or NULL
01224  * @v buf               Buffer to contain formatted value
01225  * @v len               Length of buffer
01226  * @ret len             Length of formatted value, or negative error
01227  */
01228 int fetchf_setting ( struct settings *settings, const struct setting *setting,
01229                      struct settings **origin, struct setting *fetched,
01230                      char *buf, size_t len ) {
01231         struct setting tmp_fetched;
01232         void *raw;
01233         int raw_len;
01234         int ret;
01235 
01236         /* Use local buffers if necessary */
01237         if ( ! fetched )
01238                 fetched = &tmp_fetched;
01239 
01240         /* Fetch raw value */
01241         raw_len = fetch_setting_copy ( settings, setting, origin, fetched,
01242                                        &raw );
01243         if ( raw_len < 0 ) {
01244                 ret = raw_len;
01245                 goto err_fetch_copy;
01246         }
01247 
01248         /* Sanity check */
01249         assert ( fetched->type != NULL );
01250 
01251         /* Format setting */
01252         if ( ( ret = setting_format ( fetched->type, raw, raw_len, buf,
01253                                       len ) ) < 0 )
01254                 goto err_format;
01255 
01256  err_format:
01257         free ( raw );
01258  err_fetch_copy:
01259         return ret;
01260 }
01261 
01262 /**
01263  * Fetch copy of formatted value of setting
01264  *
01265  * @v settings          Settings block, or NULL to search all blocks
01266  * @v setting           Setting to fetch
01267  * @v origin            Origin of setting to fill in, or NULL
01268  * @v fetched           Fetched setting to fill in, or NULL
01269  * @v value             Buffer to allocate and fill with formatted value
01270  * @ret len             Length of formatted value, or negative error
01271  *
01272  * The caller is responsible for eventually freeing the allocated
01273  * buffer.
01274  */
01275 int fetchf_setting_copy ( struct settings *settings,
01276                           const struct setting *setting,
01277                           struct settings **origin, struct setting *fetched,
01278                           char **value ) {
01279         struct settings *tmp_origin;
01280         struct setting tmp_fetched;
01281         int len;
01282         int check_len;
01283 
01284         /* Use local buffers if necessary */
01285         if ( ! origin )
01286                 origin = &tmp_origin;
01287         if ( ! fetched )
01288                 fetched = &tmp_fetched;
01289 
01290         /* Avoid returning uninitialised data on error */
01291         *value = NULL;
01292 
01293         /* Check existence, and fetch formatted value length */
01294         len = fetchf_setting ( settings, setting, origin, fetched, NULL, 0 );
01295         if ( len < 0 )
01296                 return len;
01297 
01298         /* Allocate buffer */
01299         *value = zalloc ( len + 1 /* NUL */ );
01300         if ( ! *value )
01301                 return -ENOMEM;
01302 
01303         /* Fetch formatted value */
01304         check_len = fetchf_setting ( *origin, fetched, NULL, NULL, *value,
01305                                      ( len + 1 /* NUL */ ) );
01306         assert ( check_len == len );
01307         return len;
01308 }
01309 
01310 /**
01311  * Store formatted value of setting
01312  *
01313  * @v settings          Settings block
01314  * @v setting           Setting to store
01315  * @v value             Formatted setting data, or NULL
01316  * @ret rc              Return status code
01317  */
01318 int storef_setting ( struct settings *settings, const struct setting *setting,
01319                      const char *value ) {
01320         void *raw;
01321         int raw_len;
01322         int check_len;
01323         int rc;
01324 
01325         /* NULL value or empty string implies deletion */
01326         if ( ( ! value ) || ( ! value[0] ) )
01327                 return delete_setting ( settings, setting );
01328 
01329         /* Sanity check */
01330         assert ( setting->type != NULL );
01331 
01332         /* Get raw value length */
01333         raw_len = setting_parse ( setting->type, value, NULL, 0 );
01334         if ( raw_len < 0 ) {
01335                 rc = raw_len;
01336                 goto err_raw_len;
01337         }
01338 
01339         /* Allocate buffer for raw value */
01340         raw = malloc ( raw_len );
01341         if ( ! raw ) {
01342                 rc = -ENOMEM;
01343                 goto err_alloc_raw;
01344         }
01345 
01346         /* Parse formatted value */
01347         check_len = setting_parse ( setting->type, value, raw, raw_len );
01348         assert ( check_len == raw_len );
01349 
01350         /* Store raw value */
01351         if ( ( rc = store_setting ( settings, setting, raw, raw_len ) ) != 0 )
01352                 goto err_store;
01353 
01354  err_store:
01355         free ( raw );
01356  err_alloc_raw:
01357  err_raw_len:
01358         return rc;
01359 }
01360 
01361 /**
01362  * Fetch numeric value of setting
01363  *
01364  * @v settings          Settings block, or NULL to search all blocks
01365  * @v setting           Setting to fetch
01366  * @v origin            Origin of setting to fill in, or NULL
01367  * @v fetched           Fetched setting to fill in, or NULL
01368  * @v value             Numeric value to fill in
01369  * @ret rc              Return status code
01370  */
01371 int fetchn_setting ( struct settings *settings, const struct setting *setting,
01372                      struct settings **origin, struct setting *fetched,
01373                      unsigned long *value ) {
01374         struct setting tmp_fetched;
01375         void *raw;
01376         int raw_len;
01377         int rc;
01378 
01379         /* Use local buffers if necessary */
01380         if ( ! fetched )
01381                 fetched = &tmp_fetched;
01382 
01383         /* Fetch raw value */
01384         raw_len = fetch_setting_copy ( settings, setting, origin, fetched,
01385                                        &raw );
01386         if ( raw_len < 0 ) {
01387                 rc = raw_len;
01388                 goto err_fetch_copy;
01389         }
01390 
01391         /* Sanity check */
01392         assert ( fetched->type != NULL );
01393 
01394         /* Numerate setting */
01395         if ( ( rc = setting_numerate ( fetched->type, raw, raw_len,
01396                                        value ) ) < 0 )
01397                 goto err_numerate;
01398 
01399  err_numerate:
01400         free ( raw );
01401  err_fetch_copy:
01402         return rc;
01403 }
01404 
01405 /**
01406  * Store numeric value of setting
01407  *
01408  * @v settings          Settings block
01409  * @v setting           Setting
01410  * @v value             Numeric value
01411  * @ret rc              Return status code
01412  */
01413 int storen_setting ( struct settings *settings, const struct setting *setting,
01414                      unsigned long value ) {
01415         void *raw;
01416         int raw_len;
01417         int check_len;
01418         int rc;
01419 
01420         /* Sanity check */
01421         assert ( setting->type != NULL );
01422 
01423         /* Get raw value length */
01424         raw_len = setting_denumerate ( setting->type, value, NULL, 0 );
01425         if ( raw_len < 0 ) {
01426                 rc = raw_len;
01427                 goto err_raw_len;
01428         }
01429 
01430         /* Allocate buffer for raw value */
01431         raw = malloc ( raw_len );
01432         if ( ! raw ) {
01433                 rc = -ENOMEM;
01434                 goto err_alloc_raw;
01435         }
01436 
01437         /* Denumerate value */
01438         check_len = setting_denumerate ( setting->type, value, raw, raw_len );
01439         assert ( check_len == raw_len );
01440 
01441         /* Store raw value */
01442         if ( ( rc = store_setting ( settings, setting, raw, raw_len ) ) != 0 )
01443                 goto err_store;
01444 
01445  err_store:
01446         free ( raw );
01447  err_alloc_raw:
01448  err_raw_len:
01449         return rc;
01450 }
01451 
01452 /******************************************************************************
01453  *
01454  * Named settings
01455  *
01456  ******************************************************************************
01457  */
01458 
01459 /**
01460  * Find predefined setting
01461  *
01462  * @v name              Name
01463  * @ret setting         Setting, or NULL
01464  */
01465 struct setting * find_setting ( const char *name ) {
01466         struct setting *setting;
01467 
01468         for_each_table_entry ( setting, SETTINGS ) {
01469                 if ( strcmp ( name, setting->name ) == 0 )
01470                         return setting;
01471         }
01472         return NULL;
01473 }
01474 
01475 /**
01476  * Parse setting name as tag number
01477  *
01478  * @v name              Name
01479  * @ret tag             Tag number, or 0 if not a valid number
01480  */
01481 static uint64_t parse_setting_tag ( const char *name ) {
01482         char *tmp = ( ( char * ) name );
01483         uint64_t tag = 0;
01484 
01485         while ( 1 ) {
01486                 tag = ( ( tag << 8 ) | strtoul ( tmp, &tmp, 0 ) );
01487                 if ( *tmp == 0 )
01488                         return tag;
01489                 if ( *tmp != '.' )
01490                         return 0;
01491                 tmp++;
01492         }
01493 }
01494 
01495 /**
01496  * Find setting type
01497  *
01498  * @v name              Name
01499  * @ret type            Setting type, or NULL
01500  */
01501 static const struct setting_type * find_setting_type ( const char *name ) {
01502         const struct setting_type *type;
01503 
01504         for_each_table_entry ( type, SETTING_TYPES ) {
01505                 if ( strcmp ( name, type->name ) == 0 )
01506                         return type;
01507         }
01508         return NULL;
01509 }
01510 
01511 /**
01512  * Parse setting name
01513  *
01514  * @v name              Name of setting
01515  * @v get_child         Function to find or create child settings block
01516  * @v settings          Settings block to fill in
01517  * @v setting           Setting to fill in
01518  * @ret rc              Return status code
01519  *
01520  * Interprets a name of the form
01521  * "[settings_name/]tag_name[:type_name]" and fills in the appropriate
01522  * fields.
01523  *
01524  * Note that on success, this function will have modified the original
01525  * setting @c name.
01526  */
01527 int parse_setting_name ( char *name, get_child_settings_t get_child,
01528                          struct settings **settings, struct setting *setting ) {
01529         char *settings_name;
01530         char *setting_name;
01531         char *type_name;
01532         struct setting *predefined;
01533         int rc;
01534 
01535         /* Set defaults */
01536         *settings = &settings_root;
01537         memset ( setting, 0, sizeof ( *setting ) );
01538         setting->name = "";
01539 
01540         /* Split name into "[settings_name/]setting_name[:type_name]" */
01541         if ( ( setting_name = strchr ( name, '/' ) ) != NULL ) {
01542                 *(setting_name++) = 0;
01543                 settings_name = name;
01544         } else {
01545                 setting_name = name;
01546                 settings_name = NULL;
01547         }
01548         if ( ( type_name = strchr ( setting_name, ':' ) ) != NULL )
01549                 *(type_name++) = 0;
01550 
01551         /* Identify settings block, if specified */
01552         if ( settings_name ) {
01553                 *settings = parse_settings_name ( settings_name, get_child );
01554                 if ( *settings == NULL ) {
01555                         DBG ( "Unrecognised settings block \"%s\" in \"%s\"\n",
01556                               settings_name, name );
01557                         rc = -ENODEV;
01558                         goto err;
01559                 }
01560         }
01561 
01562         /* Identify setting */
01563         setting->tag = parse_setting_tag ( setting_name );
01564         setting->scope = (*settings)->default_scope;
01565         setting->name = setting_name;
01566         for_each_table_entry ( predefined, SETTINGS ) {
01567                 /* Matches a predefined setting; use that setting */
01568                 if ( setting_cmp ( predefined, setting ) == 0 ) {
01569                         memcpy ( setting, predefined, sizeof ( *setting ) );
01570                         break;
01571                 }
01572         }
01573 
01574         /* Identify setting type, if specified */
01575         if ( type_name ) {
01576                 setting->type = find_setting_type ( type_name );
01577                 if ( setting->type == NULL ) {
01578                         DBG ( "Invalid setting type \"%s\" in \"%s\"\n",
01579                               type_name, name );
01580                         rc = -ENOTSUP;
01581                         goto err;
01582                 }
01583         }
01584 
01585         return 0;
01586 
01587  err:
01588         /* Restore original name */
01589         if ( settings_name )
01590                 *( setting_name - 1 ) = '/';
01591         if ( type_name )
01592                 *( type_name - 1 ) = ':';
01593         return rc;
01594 }
01595 
01596 /**
01597  * Return full setting name
01598  *
01599  * @v settings          Settings block, or NULL
01600  * @v setting           Setting
01601  * @v buf               Buffer
01602  * @v len               Length of buffer
01603  * @ret len             Length of setting name, or negative error
01604  */
01605 int setting_name ( struct settings *settings, const struct setting *setting,
01606                    char *buf, size_t len ) {
01607         const char *name;
01608 
01609         settings = settings_target ( settings );
01610         name = settings_name ( settings );
01611         return snprintf ( buf, len, "%s%s%s:%s", name, ( name[0] ? "/" : "" ),
01612                           setting->name, setting->type->name );
01613 }
01614 
01615 /******************************************************************************
01616  *
01617  * Setting types
01618  *
01619  ******************************************************************************
01620  */
01621 
01622 /**
01623  * Parse string setting value
01624  *
01625  * @v type              Setting type
01626  * @v value             Formatted setting value
01627  * @v buf               Buffer to contain raw value
01628  * @v len               Length of buffer
01629  * @ret len             Length of raw value, or negative error
01630  */
01631 static int parse_string_setting ( const struct setting_type *type __unused,
01632                                   const char *value, void *buf, size_t len ) {
01633         size_t raw_len = strlen ( value ); /* Exclude terminating NUL */
01634 
01635         /* Copy string to buffer */
01636         if ( len > raw_len )
01637                 len = raw_len;
01638         memcpy ( buf, value, len );
01639 
01640         return raw_len;
01641 }
01642 
01643 /**
01644  * Format string setting value
01645  *
01646  * @v type              Setting type
01647  * @v raw               Raw setting value
01648  * @v raw_len           Length of raw setting value
01649  * @v buf               Buffer to contain formatted value
01650  * @v len               Length of buffer
01651  * @ret len             Length of formatted value, or negative error
01652  */
01653 static int format_string_setting ( const struct setting_type *type __unused,
01654                                    const void *raw, size_t raw_len, char *buf,
01655                                    size_t len ) {
01656 
01657         /* Copy string to buffer, and terminate */
01658         memset ( buf, 0, len );
01659         if ( len > raw_len )
01660                 len = raw_len;
01661         memcpy ( buf, raw, len );
01662 
01663         return raw_len;
01664 }
01665 
01666 /** A string setting type */
01667 const struct setting_type setting_type_string __setting_type = {
01668         .name = "string",
01669         .parse = parse_string_setting,
01670         .format = format_string_setting,
01671 };
01672 
01673 /**
01674  * Parse URI-encoded string setting value
01675  *
01676  * @v type              Setting type
01677  * @v value             Formatted setting value
01678  * @v buf               Buffer to contain raw value
01679  * @v len               Length of buffer
01680  * @ret len             Length of raw value, or negative error
01681  */
01682 static int parse_uristring_setting ( const struct setting_type *type __unused,
01683                                      const char *value, void *buf, size_t len ){
01684 
01685         return uri_decode ( value, buf, len );
01686 }
01687 
01688 /**
01689  * Format URI-encoded string setting value
01690  *
01691  * @v type              Setting type
01692  * @v raw               Raw setting value
01693  * @v raw_len           Length of raw setting value
01694  * @v buf               Buffer to contain formatted value
01695  * @v len               Length of buffer
01696  * @ret len             Length of formatted value, or negative error
01697  */
01698 static int format_uristring_setting ( const struct setting_type *type __unused,
01699                                       const void *raw, size_t raw_len,
01700                                       char *buf, size_t len ) {
01701 
01702         return uri_encode ( 0, raw, raw_len, buf, len );
01703 }
01704 
01705 /** A URI-encoded string setting type */
01706 const struct setting_type setting_type_uristring __setting_type = {
01707         .name = "uristring",
01708         .parse = parse_uristring_setting,
01709         .format = format_uristring_setting,
01710 };
01711 
01712 /**
01713  * Parse IPv4 address setting value (when IPv4 support is not present)
01714  *
01715  * @v type              Setting type
01716  * @v value             Formatted setting value
01717  * @v buf               Buffer to contain raw value
01718  * @v len               Length of buffer
01719  * @ret len             Length of raw value, or negative error
01720  */
01721 __weak int parse_ipv4_setting ( const struct setting_type *type __unused,
01722                                 const char *value __unused, void *buf __unused,
01723                                 size_t len __unused ) {
01724         return -ENOTSUP;
01725 }
01726 
01727 /**
01728  * Format IPv4 address setting value (when IPv4 support is not present)
01729  *
01730  * @v type              Setting type
01731  * @v raw               Raw setting value
01732  * @v raw_len           Length of raw setting value
01733  * @v buf               Buffer to contain formatted value
01734  * @v len               Length of buffer
01735  * @ret len             Length of formatted value, or negative error
01736  */
01737 __weak int format_ipv4_setting ( const struct setting_type *type __unused,
01738                                  const void *raw __unused,
01739                                  size_t raw_len __unused, char *buf __unused,
01740                                  size_t len __unused ) {
01741         return -ENOTSUP;
01742 }
01743 
01744 /** An IPv4 address setting type */
01745 const struct setting_type setting_type_ipv4 __setting_type = {
01746         .name = "ipv4",
01747         .parse = parse_ipv4_setting,
01748         .format = format_ipv4_setting,
01749 };
01750 
01751 /**
01752  * Parse IPv6 address setting value (when IPv6 support is not present)
01753  *
01754  * @v type              Setting type
01755  * @v value             Formatted setting value
01756  * @v buf               Buffer to contain raw value
01757  * @v len               Length of buffer
01758  * @ret len             Length of raw value, or negative error
01759  */
01760 __weak int parse_ipv6_setting ( const struct setting_type *type __unused,
01761                                 const char *value __unused, void *buf __unused,
01762                                 size_t len __unused ) {
01763         return -ENOTSUP;
01764 }
01765 
01766 /**
01767  * Format IPv6 address setting value (when IPv6 support is not present)
01768  *
01769  * @v type              Setting type
01770  * @v raw               Raw setting value
01771  * @v raw_len           Length of raw setting value
01772  * @v buf               Buffer to contain formatted value
01773  * @v len               Length of buffer
01774  * @ret len             Length of formatted value, or negative error
01775  */
01776 __weak int format_ipv6_setting ( const struct setting_type *type __unused,
01777                                  const void *raw __unused,
01778                                  size_t raw_len __unused, char *buf __unused,
01779                                  size_t len __unused ) {
01780         return -ENOTSUP;
01781 }
01782 
01783 /** An IPv6 address setting type */
01784 const struct setting_type setting_type_ipv6 __setting_type = {
01785         .name = "ipv6",
01786         .parse = parse_ipv6_setting,
01787         .format = format_ipv6_setting,
01788 };
01789 
01790 /** IPv6 settings scope */
01791 const struct settings_scope dhcpv6_scope;
01792 
01793 /**
01794  * Integer setting type indices
01795  *
01796  * These indexes are defined such that (1<<index) gives the width of
01797  * the integer, in bytes.
01798  */
01799 enum setting_type_int_index {
01800         SETTING_TYPE_INT8 = 0,
01801         SETTING_TYPE_INT16 = 1,
01802         SETTING_TYPE_INT32 = 2,
01803 };
01804 
01805 /**
01806  * Integer setting type names
01807  *
01808  * These names exist as a static array in order to allow the type's
01809  * integer size and signedness to be determined from the type's name.
01810  * Note that there are no separate entries for the signed integer
01811  * types: the name pointers simply point to the second character of
01812  * the relevant string.
01813  */
01814 static const char setting_type_int_name[][8] = {
01815         [SETTING_TYPE_INT8] = "uint8",
01816         [SETTING_TYPE_INT16] = "uint16",
01817         [SETTING_TYPE_INT32] = "uint32",
01818 };
01819 
01820 /**
01821  * Get unsigned integer setting type name
01822  *
01823  * @v index             Integer setting type index
01824  * @ret name            Setting type name
01825  */
01826 #define SETTING_TYPE_UINT_NAME( index ) setting_type_int_name[index]
01827 
01828 /**
01829  * Get signed integer setting type name
01830  *
01831  * @v index             Integer setting type index
01832  * @ret name            Setting type name
01833  */
01834 #define SETTING_TYPE_INT_NAME( index ) ( setting_type_int_name[index] + 1 )
01835 
01836 /**
01837  * Get integer setting type index
01838  *
01839  * @v type              Setting type
01840  * @ret index           Integer setting type index
01841  */
01842 static unsigned int setting_type_int_index ( const struct setting_type *type ) {
01843 
01844         return ( ( type->name - setting_type_int_name[0] ) /
01845                  sizeof ( setting_type_int_name[0] ) );
01846 }
01847 
01848 /**
01849  * Get integer setting type width
01850  *
01851  * @v type              Setting type
01852  * @ret index           Integer setting type width
01853  */
01854 static unsigned int setting_type_int_width ( const struct setting_type *type ) {
01855 
01856         return ( 1 << setting_type_int_index ( type ) );
01857 }
01858 
01859 /**
01860  * Get integer setting type signedness
01861  *
01862  * @v type              Setting type
01863  * @ret is_signed       Integer setting type is signed
01864  */
01865 static int setting_type_int_is_signed ( const struct setting_type *type ) {
01866         return ( ( type->name - setting_type_int_name[0] ) & 1 );
01867 }
01868 
01869 /**
01870  * Convert number to setting value
01871  *
01872  * @v type              Setting type
01873  * @v value             Numeric value
01874  * @v buf               Buffer to contain raw value
01875  * @v len               Length of buffer
01876  * @ret len             Length of raw value, or negative error
01877  */
01878 static int denumerate_int_setting ( const struct setting_type *type,
01879                                     unsigned long value, void *buf,
01880                                     size_t len ) {
01881         unsigned int size = setting_type_int_width ( type );
01882         union {
01883                 uint32_t num;
01884                 uint8_t bytes[4];
01885         } u;
01886 
01887         u.num = htonl ( value );
01888         if ( len > size )
01889                 len = size;
01890         memcpy ( buf, &u.bytes[ sizeof ( u ) - size ], len );
01891 
01892         return size;
01893 }
01894 
01895 /**
01896  * Convert setting value to number
01897  *
01898  * @v type              Setting type
01899  * @v raw               Raw setting value
01900  * @v raw_len           Length of raw setting value
01901  * @v value             Numeric value to fill in
01902  * @ret rc              Return status code
01903  */
01904 static int numerate_int_setting ( const struct setting_type *type,
01905                                   const void *raw, size_t raw_len,
01906                                   unsigned long *value ) {
01907         int is_signed = setting_type_int_is_signed ( type );
01908         int check_len;
01909 
01910         /* Extract numeric value */
01911         check_len = numeric_setting_value ( is_signed, raw, raw_len, value );
01912         if ( check_len < 0 )
01913                 return check_len;
01914         assert ( check_len == ( int ) raw_len );
01915 
01916         return 0;
01917 }
01918 
01919 /**
01920  * Parse integer setting value
01921  *
01922  * @v type              Setting type
01923  * @v value             Formatted setting value
01924  * @v buf               Buffer to contain raw value
01925  * @v len               Length of buffer
01926  * @ret len             Length of raw value, or negative error
01927  */
01928 static int parse_int_setting ( const struct setting_type *type,
01929                                const char *value, void *buf, size_t len ) {
01930         char *endp;
01931         unsigned long num_value;
01932 
01933         /* Parse value */
01934         num_value = strtoul ( value, &endp, 0 );
01935         if ( *endp )
01936                 return -EINVAL;
01937 
01938         return type->denumerate ( type, num_value, buf, len );
01939 }
01940 
01941 /**
01942  * Format signed integer setting value
01943  *
01944  * @v type              Setting type
01945  * @v raw               Raw setting value
01946  * @v raw_len           Length of raw setting value
01947  * @v buf               Buffer to contain formatted value
01948  * @v len               Length of buffer
01949  * @ret len             Length of formatted value, or negative error
01950  */
01951 static int format_int_setting ( const struct setting_type *type,
01952                                 const void *raw, size_t raw_len,
01953                                 char *buf, size_t len ) {
01954         unsigned long value;
01955         int ret;
01956 
01957         /* Extract numeric value */
01958         if ( ( ret = type->numerate ( type, raw, raw_len, &value ) ) < 0 )
01959                 return ret;
01960 
01961         /* Format value */
01962         return snprintf ( buf, len, "%ld", value );
01963 }
01964 
01965 /**
01966  * Format unsigned integer setting value
01967  *
01968  * @v type              Setting type
01969  * @v raw               Raw setting value
01970  * @v raw_len           Length of raw setting value
01971  * @v buf               Buffer to contain formatted value
01972  * @v len               Length of buffer
01973  * @ret len             Length of formatted value, or negative error
01974  */
01975 static int format_uint_setting ( const struct setting_type *type,
01976                                  const void *raw, size_t raw_len,
01977                                  char *buf, size_t len ) {
01978         unsigned long value;
01979         int ret;
01980 
01981         /* Extract numeric value */
01982         if ( ( ret = type->numerate ( type, raw, raw_len, &value ) ) < 0 )
01983                 return ret;
01984 
01985         /* Format value */
01986         return snprintf ( buf, len, "%#lx", value );
01987 }
01988 
01989 /**
01990  * Define a signed integer setting type
01991  *
01992  * @v index             Integer setting type index
01993  * @ret type            Setting type
01994  */
01995 #define SETTING_TYPE_INT( index ) {                             \
01996         .name = SETTING_TYPE_INT_NAME ( index ),                \
01997         .parse = parse_int_setting,                             \
01998         .format = format_int_setting,                           \
01999         .denumerate = denumerate_int_setting,                   \
02000         .numerate = numerate_int_setting,                       \
02001 }
02002 
02003 /**
02004  * Define an unsigned integer setting type
02005  *
02006  * @v index             Integer setting type index
02007  * @ret type            Setting type
02008  */
02009 #define SETTING_TYPE_UINT( index ) {                            \
02010         .name = SETTING_TYPE_UINT_NAME ( index ),               \
02011         .parse = parse_int_setting,                             \
02012         .format = format_uint_setting,                          \
02013         .denumerate = denumerate_int_setting,                   \
02014         .numerate = numerate_int_setting,                       \
02015 }
02016 
02017 /** A signed 8-bit integer setting type */
02018 const struct setting_type setting_type_int8 __setting_type =
02019         SETTING_TYPE_INT ( SETTING_TYPE_INT8 );
02020 
02021 /** A signed 16-bit integer setting type */
02022 const struct setting_type setting_type_int16 __setting_type =
02023         SETTING_TYPE_INT ( SETTING_TYPE_INT16 );
02024 
02025 /** A signed 32-bit integer setting type */
02026 const struct setting_type setting_type_int32 __setting_type =
02027         SETTING_TYPE_INT ( SETTING_TYPE_INT32 );
02028 
02029 /** An unsigned 8-bit integer setting type */
02030 const struct setting_type setting_type_uint8 __setting_type =
02031         SETTING_TYPE_UINT ( SETTING_TYPE_INT8 );
02032 
02033 /** An unsigned 16-bit integer setting type */
02034 const struct setting_type setting_type_uint16 __setting_type =
02035         SETTING_TYPE_UINT ( SETTING_TYPE_INT16 );
02036 
02037 /** An unsigned 32-bit integer setting type */
02038 const struct setting_type setting_type_uint32 __setting_type =
02039         SETTING_TYPE_UINT ( SETTING_TYPE_INT32 );
02040 
02041 /**
02042  * Parse hex string setting value (using colon delimiter)
02043  *
02044  * @v type              Setting type
02045  * @v value             Formatted setting value
02046  * @v buf               Buffer to contain raw value
02047  * @v len               Length of buffer
02048  * @v size              Integer size, in bytes
02049  * @ret len             Length of raw value, or negative error
02050  */
02051 static int parse_hex_setting ( const struct setting_type *type __unused,
02052                                const char *value, void *buf, size_t len ) {
02053         return hex_decode ( ':', value, buf, len );
02054 }
02055 
02056 /**
02057  * Format hex string setting value (using colon delimiter)
02058  *
02059  * @v type              Setting type
02060  * @v raw               Raw setting value
02061  * @v raw_len           Length of raw setting value
02062  * @v buf               Buffer to contain formatted value
02063  * @v len               Length of buffer
02064  * @ret len             Length of formatted value, or negative error
02065  */
02066 static int format_hex_colon_setting ( const struct setting_type *type __unused,
02067                                       const void *raw, size_t raw_len,
02068                                       char *buf, size_t len ) {
02069         return hex_encode ( ':', raw, raw_len, buf, len );
02070 }
02071 
02072 /**
02073  * Parse hex string setting value (using hyphen delimiter)
02074  *
02075  * @v type              Setting type
02076  * @v value             Formatted setting value
02077  * @v buf               Buffer to contain raw value
02078  * @v len               Length of buffer
02079  * @v size              Integer size, in bytes
02080  * @ret len             Length of raw value, or negative error
02081  */
02082 static int parse_hex_hyphen_setting ( const struct setting_type *type __unused,
02083                                       const char *value, void *buf,
02084                                       size_t len ) {
02085         return hex_decode ( '-', value, buf, len );
02086 }
02087 
02088 /**
02089  * Format hex string setting value (using hyphen delimiter)
02090  *
02091  * @v type              Setting type
02092  * @v raw               Raw setting value
02093  * @v raw_len           Length of raw setting value
02094  * @v buf               Buffer to contain formatted value
02095  * @v len               Length of buffer
02096  * @ret len             Length of formatted value, or negative error
02097  */
02098 static int format_hex_hyphen_setting ( const struct setting_type *type __unused,
02099                                        const void *raw, size_t raw_len,
02100                                        char *buf, size_t len ) {
02101         return hex_encode ( '-', raw, raw_len, buf, len );
02102 }
02103 
02104 /**
02105  * Parse hex string setting value (using no delimiter)
02106  *
02107  * @v type              Setting type
02108  * @v value             Formatted setting value
02109  * @v buf               Buffer to contain raw value
02110  * @v len               Length of buffer
02111  * @v size              Integer size, in bytes
02112  * @ret len             Length of raw value, or negative error
02113  */
02114 static int parse_hex_raw_setting ( const struct setting_type *type __unused,
02115                                    const char *value, void *buf, size_t len ) {
02116         return hex_decode ( 0, value, buf, len );
02117 }
02118 
02119 /**
02120  * Format hex string setting value (using no delimiter)
02121  *
02122  * @v type              Setting type
02123  * @v raw               Raw setting value
02124  * @v raw_len           Length of raw setting value
02125  * @v buf               Buffer to contain formatted value
02126  * @v len               Length of buffer
02127  * @ret len             Length of formatted value, or negative error
02128  */
02129 static int format_hex_raw_setting ( const struct setting_type *type __unused,
02130                                     const void *raw, size_t raw_len,
02131                                     char *buf, size_t len ) {
02132         return hex_encode ( 0, raw, raw_len, buf, len );
02133 }
02134 
02135 /** A hex-string setting (colon-delimited) */
02136 const struct setting_type setting_type_hex __setting_type = {
02137         .name = "hex",
02138         .parse = parse_hex_setting,
02139         .format = format_hex_colon_setting,
02140 };
02141 
02142 /** A hex-string setting (hyphen-delimited) */
02143 const struct setting_type setting_type_hexhyp __setting_type = {
02144         .name = "hexhyp",
02145         .parse = parse_hex_hyphen_setting,
02146         .format = format_hex_hyphen_setting,
02147 };
02148 
02149 /** A hex-string setting (non-delimited) */
02150 const struct setting_type setting_type_hexraw __setting_type = {
02151         .name = "hexraw",
02152         .parse = parse_hex_raw_setting,
02153         .format = format_hex_raw_setting,
02154 };
02155 
02156 /**
02157  * Parse Base64-encoded setting value
02158  *
02159  * @v type              Setting type
02160  * @v value             Formatted setting value
02161  * @v buf               Buffer to contain raw value
02162  * @v len               Length of buffer
02163  * @v size              Integer size, in bytes
02164  * @ret len             Length of raw value, or negative error
02165  */
02166 static int parse_base64_setting ( const struct setting_type *type __unused,
02167                                   const char *value, void *buf, size_t len ) {
02168 
02169         return base64_decode ( value, buf, len );
02170 }
02171 
02172 /**
02173  * Format Base64-encoded setting value
02174  *
02175  * @v type              Setting type
02176  * @v raw               Raw setting value
02177  * @v raw_len           Length of raw setting value
02178  * @v buf               Buffer to contain formatted value
02179  * @v len               Length of buffer
02180  * @ret len             Length of formatted value, or negative error
02181  */
02182 static int format_base64_setting ( const struct setting_type *type __unused,
02183                                    const void *raw, size_t raw_len,
02184                                    char *buf, size_t len ) {
02185 
02186         return base64_encode ( raw, raw_len, buf, len );
02187 }
02188 
02189 /** A Base64-encoded setting */
02190 const struct setting_type setting_type_base64 __setting_type = {
02191         .name = "base64",
02192         .parse = parse_base64_setting,
02193         .format = format_base64_setting,
02194 };
02195 
02196 /**
02197  * Format UUID setting value
02198  *
02199  * @v type              Setting type
02200  * @v raw               Raw setting value
02201  * @v raw_len           Length of raw setting value
02202  * @v buf               Buffer to contain formatted value
02203  * @v len               Length of buffer
02204  * @ret len             Length of formatted value, or negative error
02205  */
02206 static int format_uuid_setting ( const struct setting_type *type __unused,
02207                                  const void *raw, size_t raw_len, char *buf,
02208                                  size_t len ) {
02209         const union uuid *uuid = raw;
02210 
02211         /* Range check */
02212         if ( raw_len != sizeof ( *uuid ) )
02213                 return -ERANGE;
02214 
02215         /* Format value */
02216         return snprintf ( buf, len, "%s", uuid_ntoa ( uuid ) );
02217 }
02218 
02219 /** UUID setting type */
02220 const struct setting_type setting_type_uuid __setting_type = {
02221         .name = "uuid",
02222         .format = format_uuid_setting,
02223 };
02224 
02225 /**
02226  * Format PCI bus:dev.fn setting value
02227  *
02228  * @v type              Setting type
02229  * @v raw               Raw setting value
02230  * @v raw_len           Length of raw setting value
02231  * @v buf               Buffer to contain formatted value
02232  * @v len               Length of buffer
02233  * @ret len             Length of formatted value, or negative error
02234  */
02235 static int format_busdevfn_setting ( const struct setting_type *type __unused,
02236                                      const void *raw, size_t raw_len, char *buf,
02237                                      size_t len ) {
02238         unsigned long busdevfn;
02239         unsigned int seg;
02240         unsigned int bus;
02241         unsigned int slot;
02242         unsigned int func;
02243         int check_len;
02244 
02245         /* Extract numeric value */
02246         check_len = numeric_setting_value ( 0, raw, raw_len, &busdevfn );
02247         if ( check_len < 0 )
02248                 return check_len;
02249         assert ( check_len == ( int ) raw_len );
02250 
02251         /* Extract PCI address components */
02252         seg = PCI_SEG ( busdevfn );
02253         bus = PCI_BUS ( busdevfn );
02254         slot = PCI_SLOT ( busdevfn );
02255         func = PCI_FUNC ( busdevfn );
02256 
02257         /* Format value */
02258         return snprintf ( buf, len, "%04x:%02x:%02x.%x", seg, bus, slot, func );
02259 }
02260 
02261 /** PCI bus:dev.fn setting type */
02262 const struct setting_type setting_type_busdevfn __setting_type = {
02263         .name = "busdevfn",
02264         .format = format_busdevfn_setting,
02265 };
02266 
02267 /******************************************************************************
02268  *
02269  * Setting expansion
02270  *
02271  ******************************************************************************
02272  */
02273 
02274 /**
02275  * Expand variables within string
02276  *
02277  * @v string            String
02278  * @ret expstr          Expanded string
02279  *
02280  * The expanded string is allocated with malloc() and the caller must
02281  * eventually free() it.
02282  */
02283 char * expand_settings ( const char *string ) {
02284         struct settings *settings;
02285         struct setting setting;
02286         char *expstr;
02287         char *start;
02288         char *end;
02289         char *head;
02290         char *name;
02291         char *tail;
02292         char *value;
02293         char *tmp;
02294         int new_len;
02295         int rc;
02296 
02297         /* Obtain temporary modifiable copy of string */
02298         expstr = strdup ( string );
02299         if ( ! expstr )
02300                 return NULL;
02301 
02302         /* Expand while expansions remain */
02303         while ( 1 ) {
02304 
02305                 head = expstr;
02306 
02307                 /* Locate setting to be expanded */
02308                 start = NULL;
02309                 end = NULL;
02310                 for ( tmp = expstr ; *tmp ; tmp++ ) {
02311                         if ( ( tmp[0] == '$' ) && ( tmp[1] == '{' ) )
02312                                 start = tmp;
02313                         if ( start && ( tmp[0] == '}' ) ) {
02314                                 end = tmp;
02315                                 break;
02316                         }
02317                 }
02318                 if ( ! end )
02319                         break;
02320                 *start = '\0';
02321                 name = ( start + 2 );
02322                 *end = '\0';
02323                 tail = ( end + 1 );
02324 
02325                 /* Expand setting */
02326                 if ( ( rc = parse_setting_name ( name, find_child_settings,
02327                                                  &settings,
02328                                                  &setting ) ) != 0 ) {
02329                         /* Treat invalid setting names as empty */
02330                         value = NULL;
02331                 } else {
02332                         /* Fetch and format setting value.  Ignore
02333                          * errors; treat non-existent settings as empty.
02334                          */
02335                         fetchf_setting_copy ( settings, &setting, NULL, NULL,
02336                                               &value );
02337                 }
02338 
02339                 /* Construct expanded string and discard old string */
02340                 tmp = expstr;
02341                 new_len = asprintf ( &expstr, "%s%s%s",
02342                                      head, ( value ? value : "" ), tail );
02343                 free ( value );
02344                 free ( tmp );
02345                 if ( new_len < 0 )
02346                         return NULL;
02347         }
02348 
02349         return expstr;
02350 }
02351 
02352 /******************************************************************************
02353  *
02354  * Settings
02355  *
02356  ******************************************************************************
02357  */
02358 
02359 /** Hostname setting */
02360 const struct setting hostname_setting __setting ( SETTING_HOST, hostname ) = {
02361         .name = "hostname",
02362         .description = "Host name",
02363         .tag = DHCP_HOST_NAME,
02364         .type = &setting_type_string,
02365 };
02366 
02367 /** Domain name setting */
02368 const struct setting domain_setting __setting ( SETTING_IP_EXTRA, domain ) = {
02369         .name = "domain",
02370         .description = "DNS domain",
02371         .tag = DHCP_DOMAIN_NAME,
02372         .type = &setting_type_string,
02373 };
02374 
02375 /** TFTP server setting */
02376 const struct setting next_server_setting __setting ( SETTING_BOOT,next-server)={
02377         .name = "next-server",
02378         .description = "TFTP server",
02379         .tag = DHCP_EB_SIADDR,
02380         .type = &setting_type_ipv4,
02381 };
02382 
02383 /** Filename setting */
02384 const struct setting filename_setting __setting ( SETTING_BOOT, filename ) = {
02385         .name = "filename",
02386         .description = "Boot filename",
02387         .tag = DHCP_BOOTFILE_NAME,
02388         .type = &setting_type_string,
02389 };
02390 
02391 /** Root path setting */
02392 const struct setting root_path_setting __setting ( SETTING_SANBOOT, root-path)={
02393         .name = "root-path",
02394         .description = "SAN root path",
02395         .tag = DHCP_ROOT_PATH,
02396         .type = &setting_type_string,
02397 };
02398 
02399 /** SAN filename setting */
02400 const struct setting san_filename_setting __setting ( SETTING_SANBOOT,
02401                                                       san-filename ) = {
02402         .name = "san-filename",
02403         .description = "SAN filename",
02404         .tag = DHCP_EB_SAN_FILENAME,
02405         .type = &setting_type_string,
02406 };
02407 
02408 /** Username setting */
02409 const struct setting username_setting __setting ( SETTING_AUTH, username ) = {
02410         .name = "username",
02411         .description = "User name",
02412         .tag = DHCP_EB_USERNAME,
02413         .type = &setting_type_string,
02414 };
02415 
02416 /** Password setting */
02417 const struct setting password_setting __setting ( SETTING_AUTH, password ) = {
02418         .name = "password",
02419         .description = "Password",
02420         .tag = DHCP_EB_PASSWORD,
02421         .type = &setting_type_string,
02422 };
02423 
02424 /** Priority setting */
02425 const struct setting priority_setting __setting ( SETTING_MISC, priority ) = {
02426         .name = "priority",
02427         .description = "Settings priority",
02428         .tag = DHCP_EB_PRIORITY,
02429         .type = &setting_type_int8,
02430 };
02431 
02432 /** DHCP user class setting */
02433 const struct setting user_class_setting __setting ( SETTING_HOST_EXTRA,
02434                                                     user-class ) = {
02435         .name = "user-class",
02436         .description = "DHCP user class",
02437         .tag = DHCP_USER_CLASS_ID,
02438         .type = &setting_type_string,
02439 };
02440 
02441 /** DHCP vendor class setting */
02442 const struct setting vendor_class_setting __setting ( SETTING_HOST_EXTRA,
02443                                                       vendor-class ) = {
02444         .name = "vendor-class",
02445         .description = "DHCP vendor class",
02446         .tag = DHCP_VENDOR_CLASS_ID,
02447         .type = &setting_type_string,
02448 };
02449 
02450 /******************************************************************************
02451  *
02452  * Built-in settings block
02453  *
02454  ******************************************************************************
02455  */
02456 
02457 /** Built-in setting scope */
02458 const struct settings_scope builtin_scope;
02459 
02460 /**
02461  * Fetch error number setting
02462  *
02463  * @v data              Buffer to fill with setting data
02464  * @v len               Length of buffer
02465  * @ret len             Length of setting data, or negative error
02466  */
02467 static int errno_fetch ( void *data, size_t len ) {
02468         uint32_t content;
02469 
02470         /* Return current error */
02471         content = htonl ( errno );
02472         if ( len > sizeof ( content ) )
02473                 len = sizeof ( content );
02474         memcpy ( data, &content, len );
02475         return sizeof ( content );
02476 }
02477 
02478 /** Error number setting */
02479 const struct setting errno_setting __setting ( SETTING_MISC, errno ) = {
02480         .name = "errno",
02481         .description = "Last error",
02482         .type = &setting_type_uint32,
02483         .scope = &builtin_scope,
02484 };
02485 
02486 /** Error number built-in setting */
02487 struct builtin_setting errno_builtin_setting __builtin_setting = {
02488         .setting = &errno_setting,
02489         .fetch = errno_fetch,
02490 };
02491 
02492 /**
02493  * Fetch build architecture setting
02494  *
02495  * @v data              Buffer to fill with setting data
02496  * @v len               Length of buffer
02497  * @ret len             Length of setting data, or negative error
02498  */
02499 static int buildarch_fetch ( void *data, size_t len ) {
02500         static const char buildarch[] = _S2 ( ARCH );
02501 
02502         strncpy ( data, buildarch, len );
02503         return ( sizeof ( buildarch ) - 1 /* NUL */ );
02504 }
02505 
02506 /** Build architecture setting */
02507 const struct setting buildarch_setting __setting ( SETTING_MISC, buildarch ) = {
02508         .name = "buildarch",
02509         .description = "Build architecture",
02510         .type = &setting_type_string,
02511         .scope = &builtin_scope,
02512 };
02513 
02514 /** Build architecture built-in setting */
02515 struct builtin_setting buildarch_builtin_setting __builtin_setting = {
02516         .setting = &buildarch_setting,
02517         .fetch = buildarch_fetch,
02518 };
02519 
02520 /**
02521  * Fetch platform setting
02522  *
02523  * @v data              Buffer to fill with setting data
02524  * @v len               Length of buffer
02525  * @ret len             Length of setting data, or negative error
02526  */
02527 static int platform_fetch ( void *data, size_t len ) {
02528         static const char platform[] = _S2 ( PLATFORM );
02529 
02530         strncpy ( data, platform, len );
02531         return ( sizeof ( platform ) - 1 /* NUL */ );
02532 }
02533 
02534 /** Platform setting */
02535 const struct setting platform_setting __setting ( SETTING_MISC, platform ) = {
02536         .name = "platform",
02537         .description = "Platform",
02538         .type = &setting_type_string,
02539         .scope = &builtin_scope,
02540 };
02541 
02542 /** Platform built-in setting */
02543 struct builtin_setting platform_builtin_setting __builtin_setting = {
02544         .setting = &platform_setting,
02545         .fetch = platform_fetch,
02546 };
02547 
02548 /**
02549  * Fetch version setting
02550  *
02551  * @v data              Buffer to fill with setting data
02552  * @v len               Length of buffer
02553  * @ret len             Length of setting data, or negative error
02554  */
02555 static int version_fetch ( void *data, size_t len ) {
02556         strncpy ( data, product_version, len );
02557         return ( strlen ( product_version ) );
02558 }
02559 
02560 /** Version setting */
02561 const struct setting version_setting __setting ( SETTING_MISC, version ) = {
02562         .name = "version",
02563         .description = "Version",
02564         .type = &setting_type_string,
02565         .scope = &builtin_scope,
02566 };
02567 
02568 /** Version built-in setting */
02569 struct builtin_setting version_builtin_setting __builtin_setting = {
02570         .setting = &version_setting,
02571         .fetch = version_fetch,
02572 };
02573 
02574 /**
02575  * Fetch current time setting
02576  *
02577  * @v data              Buffer to fill with setting data
02578  * @v len               Length of buffer
02579  * @ret len             Length of setting data, or negative error
02580  */
02581 static int unixtime_fetch ( void *data, size_t len ) {
02582         uint32_t content;
02583 
02584         /* Return current time */
02585         content = htonl ( time(NULL) );
02586         if ( len > sizeof ( content ) )
02587                 len = sizeof ( content );
02588         memcpy ( data, &content, len );
02589         return sizeof ( content );
02590 }
02591 
02592 /** Current time setting */
02593 const struct setting unixtime_setting __setting ( SETTING_MISC, unixtime ) = {
02594         .name = "unixtime",
02595         .description = "Seconds since the Epoch",
02596         .type = &setting_type_uint32,
02597         .scope = &builtin_scope,
02598 };
02599 
02600 /** Current time built-in setting */
02601 struct builtin_setting unixtime_builtin_setting __builtin_setting = {
02602         .setting = &unixtime_setting,
02603         .fetch = unixtime_fetch,
02604 };
02605 
02606 /**
02607  * Fetch built-in setting
02608  *
02609  * @v settings          Settings block
02610  * @v setting           Setting to fetch
02611  * @v data              Buffer to fill with setting data
02612  * @v len               Length of buffer
02613  * @ret len             Length of setting data, or negative error
02614  */
02615 static int builtin_fetch ( struct settings *settings __unused,
02616                            struct setting *setting,
02617                            void *data, size_t len ) {
02618         struct builtin_setting *builtin;
02619 
02620         for_each_table_entry ( builtin, BUILTIN_SETTINGS ) {
02621                 if ( setting_cmp ( setting, builtin->setting ) == 0 )
02622                         return builtin->fetch ( data, len );
02623         }
02624         return -ENOENT;
02625 }
02626 
02627 /**
02628  * Check applicability of built-in setting
02629  *
02630  * @v settings          Settings block
02631  * @v setting           Setting
02632  * @ret applies         Setting applies within this settings block
02633  */
02634 static int builtin_applies ( struct settings *settings __unused,
02635                              const struct setting *setting ) {
02636 
02637         return ( setting->scope == &builtin_scope );
02638 }
02639 
02640 /** Built-in settings operations */
02641 static struct settings_operations builtin_settings_operations = {
02642         .applies = builtin_applies,
02643         .fetch = builtin_fetch,
02644 };
02645 
02646 /** Built-in settings */
02647 static struct settings builtin_settings = {
02648         .refcnt = NULL,
02649         .siblings = LIST_HEAD_INIT ( builtin_settings.siblings ),
02650         .children = LIST_HEAD_INIT ( builtin_settings.children ),
02651         .op = &builtin_settings_operations,
02652 };
02653 
02654 /** Initialise built-in settings */
02655 static void builtin_init ( void ) {
02656         int rc;
02657 
02658         if ( ( rc = register_settings ( &builtin_settings, NULL,
02659                                         "builtin" ) ) != 0 ) {
02660                 DBG ( "Could not register built-in settings: %s\n",
02661                       strerror ( rc ) );
02662                 return;
02663         }
02664 }
02665 
02666 /** Built-in settings initialiser */
02667 struct init_fn builtin_init_fn __init_fn ( INIT_NORMAL ) = {
02668         .initialise = builtin_init,
02669 };