From 990cbb8f2c69224d88c32006ad16a28d454352fa Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Fri, 28 Jan 2011 00:16:18 +0000 Subject: [PATCH] [settings] Generalise expand_command() to expand_settings() Signed-off-by: Michael Brown --- src/core/exec.c | 76 +--------------------------------- src/core/settings.c | 81 +++++++++++++++++++++++++++++++++++++ src/include/ipxe/settings.h | 1 + 3 files changed, 83 insertions(+), 75 deletions(-) diff --git a/src/core/exec.c b/src/core/exec.c index bb3b343d..57b2df58 100644 --- a/src/core/exec.c +++ b/src/core/exec.c @@ -86,80 +86,6 @@ int execv ( const char *command, char * const argv[] ) { return -ENOEXEC; } -/** - * Expand variables within command line - * - * @v command Command line - * @ret expcmd Expanded command line - * - * The expanded command line is allocated with malloc() and the caller - * must eventually free() it. - */ -static char * expand_command ( const char *command ) { - char *expcmd; - char *start; - char *end; - char *head; - char *name; - char *tail; - int setting_len; - int new_len; - char *tmp; - - /* Obtain temporary modifiable copy of command line */ - expcmd = strdup ( command ); - if ( ! expcmd ) - return NULL; - - /* Expand while expansions remain */ - while ( 1 ) { - - head = expcmd; - - /* Locate setting to be expanded */ - start = NULL; - end = NULL; - for ( tmp = expcmd ; *tmp ; tmp++ ) { - if ( ( tmp[0] == '$' ) && ( tmp[1] == '{' ) ) - start = tmp; - if ( start && ( tmp[0] == '}' ) ) { - end = tmp; - break; - } - } - if ( ! end ) - break; - *start = '\0'; - name = ( start + 2 ); - *end = '\0'; - tail = ( end + 1 ); - - /* Determine setting length */ - setting_len = fetchf_named_setting ( name, NULL, 0 ); - if ( setting_len < 0 ) - setting_len = 0; /* Treat error as empty setting */ - - /* Read setting into temporary buffer */ - { - char setting_buf[ setting_len + 1 ]; - - setting_buf[0] = '\0'; - fetchf_named_setting ( name, setting_buf, - sizeof ( setting_buf ) ); - - /* Construct expanded string and discard old string */ - tmp = expcmd; - new_len = asprintf ( &expcmd, "%s%s%s", - head, setting_buf, tail ); - free ( tmp ); - if ( new_len < 0 ) - return NULL; - } - } - - return expcmd; -} - /** * Split command line into tokens * @@ -294,7 +220,7 @@ int system ( const char *command ) { int rc = 0; /* Perform variable expansion */ - expcmd = expand_command ( command ); + expcmd = expand_settings ( command ); if ( ! expcmd ) return -ENOMEM; diff --git a/src/core/settings.c b/src/core/settings.c index e2b48263..da662e61 100644 --- a/src/core/settings.c +++ b/src/core/settings.c @@ -1467,6 +1467,87 @@ struct setting_type setting_type_uuid __setting_type = { .fetchf = fetchf_uuid, }; +/****************************************************************************** + * + * Setting expansion + * + ****************************************************************************** + */ + +/** + * Expand variables within string + * + * @v string String + * @ret expstr Expanded string + * + * The expanded string is allocated with malloc() and the caller must + * eventually free() it. + */ +char * expand_settings ( const char *string ) { + char *expstr; + char *start; + char *end; + char *head; + char *name; + char *tail; + int setting_len; + int new_len; + char *tmp; + + /* Obtain temporary modifiable copy of string */ + expstr = strdup ( string ); + if ( ! expstr ) + return NULL; + + /* Expand while expansions remain */ + while ( 1 ) { + + head = expstr; + + /* Locate setting to be expanded */ + start = NULL; + end = NULL; + for ( tmp = expstr ; *tmp ; tmp++ ) { + if ( ( tmp[0] == '$' ) && ( tmp[1] == '{' ) ) + start = tmp; + if ( start && ( tmp[0] == '}' ) ) { + end = tmp; + break; + } + } + if ( ! end ) + break; + *start = '\0'; + name = ( start + 2 ); + *end = '\0'; + tail = ( end + 1 ); + + /* Determine setting length */ + setting_len = fetchf_named_setting ( name, NULL, 0 ); + if ( setting_len < 0 ) + setting_len = 0; /* Treat error as empty setting */ + + /* Read setting into temporary buffer */ + { + char setting_buf[ setting_len + 1 ]; + + setting_buf[0] = '\0'; + fetchf_named_setting ( name, setting_buf, + sizeof ( setting_buf ) ); + + /* Construct expanded string and discard old string */ + tmp = expstr; + new_len = asprintf ( &expstr, "%s%s%s", + head, setting_buf, tail ); + free ( tmp ); + if ( new_len < 0 ) + return NULL; + } + } + + return expstr; +} + /****************************************************************************** * * Settings diff --git a/src/include/ipxe/settings.h b/src/include/ipxe/settings.h index a764bf0e..d99e5ec0 100644 --- a/src/include/ipxe/settings.h +++ b/src/include/ipxe/settings.h @@ -221,6 +221,7 @@ extern int storef_setting ( struct settings *settings, const char *value ); extern int storef_named_setting ( const char *name, const char *value ); extern int fetchf_named_setting ( const char *name, char *buf, size_t len ); +extern char * expand_settings ( const char *string ); extern struct setting_type setting_type_string __setting_type; extern struct setting_type setting_type_ipv4 __setting_type;