diff options
author | Michael Brown | 2013-07-15 11:13:33 +0200 |
---|---|---|
committer | Michael Brown | 2013-07-15 11:20:04 +0200 |
commit | bba5a3902663a52670a47f48980843594af23bcd (patch) | |
tree | f8a80d195e7f0d652b471f9b924b71558f2733cf /src | |
parent | [realtek] Report RX error detail in debug messages (diff) | |
download | ipxe-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.c | 54 |
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; } |