Browse Source

[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>
tags/v1.20.1
Michael Brown 11 years ago
parent
commit
bba5a39026
1 changed files with 41 additions and 13 deletions
  1. 41
    13
      src/image/script.c

+ 41
- 13
src/image/script.c View File

@@ -57,9 +57,11 @@ static size_t script_offset;
57 57
 static int process_script ( struct image *image,
58 58
 			    int ( * process_line ) ( const char *line ),
59 59
 			    int ( * terminate ) ( int rc ) ) {
60
+	size_t len = 0;
61
+	char *line = NULL;
60 62
 	off_t eol;
61
-	size_t len;
62
-	char *line;
63
+	size_t frag_len;
64
+	char *tmp;
63 65
 	int rc;
64 66
 
65 67
 	script_offset = 0;
@@ -71,28 +73,54 @@ static int process_script ( struct image *image,
71 73
 				    ( image->len - script_offset ) );
72 74
 		if ( eol < 0 )
73 75
 			eol = image->len;
74
-		len = ( eol - script_offset );
76
+		frag_len = ( eol - script_offset );
75 77
 
76 78
 		/* Allocate buffer for line */
77
-		line = zalloc ( len + 1 /* NUL */ );
78
-		if ( ! line )
79
-			return -ENOMEM;
79
+		tmp = realloc ( line, ( len + frag_len + 1 /* NUL */ ) );
80
+		if ( ! tmp ) {
81
+			rc = -ENOMEM;
82
+			goto err_alloc;
83
+		}
84
+		line = tmp;
80 85
 
81 86
 		/* Copy line */
82
-		copy_from_user ( line, image->data, script_offset, len );
87
+		copy_from_user ( ( line + len ), image->data, script_offset,
88
+				 frag_len );
89
+		len += frag_len;
90
+
91
+		/* Move to next line in script */
92
+		script_offset += ( frag_len + 1 );
93
+
94
+		/* Strip trailing CR, if present */
95
+		if ( line[ len - 1 ] == '\r' )
96
+			len--;
97
+
98
+		/* Handle backslash continuations */
99
+		if ( line[ len - 1 ] == '\\' ) {
100
+			len--;
101
+			rc = -EINVAL;
102
+			continue;
103
+		}
104
+
105
+		/* Terminate line */
106
+		line[len] = '\0';
83 107
 		DBG ( "$ %s\n", line );
84 108
 
85
-		/* Move to next line */
86
-		script_offset += ( len + 1 );
87
-
88
-		/* Process and free line */
109
+		/* Process line */
89 110
 		rc = process_line ( line );
90
-		free ( line );
91 111
 		if ( terminate ( rc ) )
92
-			return rc;
112
+			goto err_process;
113
+
114
+		/* Free line */
115
+		free ( line );
116
+		line = NULL;
117
+		len = 0;
93 118
 
94 119
 	} while ( script_offset < image->len );
95 120
 
121
+ err_process:
122
+ err_alloc:
123
+	free ( line );
96 124
 	return rc;
97 125
 }
98 126
 

Loading…
Cancel
Save