summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMichael Brown2013-07-15 11:13:33 +0200
committerMichael Brown2013-07-15 11:20:04 +0200
commitbba5a3902663a52670a47f48980843594af23bcd (patch)
treef8a80d195e7f0d652b471f9b924b71558f2733cf /src
parent[realtek] Report RX error detail in debug messages (diff)
downloadipxe-bba5a3902663a52670a47f48980843594af23bcd.tar.gz
ipxe-bba5a3902663a52670a47f48980843594af23bcd.tar.xz
ipxe-bba5a3902663a52670a47f48980843594af23bcd.zip
[script] Allow for backslash continuation of script lines
Allow long script lines to be broken up using backslash continuation. For example: choose --default linux --timeout 3000 os \ && goto boot_${os} || goto cancelled Requested-by: Robin Smidsrød <robin@smidsrod.no> Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src')
-rw-r--r--src/image/script.c54
1 files changed, 41 insertions, 13 deletions
diff --git a/src/image/script.c b/src/image/script.c
index e83180ab..8ef05854 100644
--- a/src/image/script.c
+++ b/src/image/script.c
@@ -57,9 +57,11 @@ static size_t script_offset;
static int process_script ( struct image *image,
int ( * process_line ) ( const char *line ),
int ( * terminate ) ( int rc ) ) {
+ size_t len = 0;
+ char *line = NULL;
off_t eol;
- size_t len;
- char *line;
+ size_t frag_len;
+ char *tmp;
int rc;
script_offset = 0;
@@ -71,28 +73,54 @@ static int process_script ( struct image *image,
( image->len - script_offset ) );
if ( eol < 0 )
eol = image->len;
- len = ( eol - script_offset );
+ frag_len = ( eol - script_offset );
/* Allocate buffer for line */
- line = zalloc ( len + 1 /* NUL */ );
- if ( ! line )
- return -ENOMEM;
+ tmp = realloc ( line, ( len + frag_len + 1 /* NUL */ ) );
+ if ( ! tmp ) {
+ rc = -ENOMEM;
+ goto err_alloc;
+ }
+ line = tmp;
/* Copy line */
- copy_from_user ( line, image->data, script_offset, len );
+ copy_from_user ( ( line + len ), image->data, script_offset,
+ frag_len );
+ len += frag_len;
+
+ /* Move to next line in script */
+ script_offset += ( frag_len + 1 );
+
+ /* Strip trailing CR, if present */
+ if ( line[ len - 1 ] == '\r' )
+ len--;
+
+ /* Handle backslash continuations */
+ if ( line[ len - 1 ] == '\\' ) {
+ len--;
+ rc = -EINVAL;
+ continue;
+ }
+
+ /* Terminate line */
+ line[len] = '\0';
DBG ( "$ %s\n", line );
- /* Move to next line */
- script_offset += ( len + 1 );
-
- /* Process and free line */
+ /* Process line */
rc = process_line ( line );
- free ( line );
if ( terminate ( rc ) )
- return rc;
+ goto err_process;
+
+ /* Free line */
+ free ( line );
+ line = NULL;
+ len = 0;
} while ( script_offset < image->len );
+ err_process:
+ err_alloc:
+ free ( line );
return rc;
}