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
 static int process_script ( struct image *image,
57
 static int process_script ( struct image *image,
58
 			    int ( * process_line ) ( const char *line ),
58
 			    int ( * process_line ) ( const char *line ),
59
 			    int ( * terminate ) ( int rc ) ) {
59
 			    int ( * terminate ) ( int rc ) ) {
60
+	size_t len = 0;
61
+	char *line = NULL;
60
 	off_t eol;
62
 	off_t eol;
61
-	size_t len;
62
-	char *line;
63
+	size_t frag_len;
64
+	char *tmp;
63
 	int rc;
65
 	int rc;
64
 
66
 
65
 	script_offset = 0;
67
 	script_offset = 0;
71
 				    ( image->len - script_offset ) );
73
 				    ( image->len - script_offset ) );
72
 		if ( eol < 0 )
74
 		if ( eol < 0 )
73
 			eol = image->len;
75
 			eol = image->len;
74
-		len = ( eol - script_offset );
76
+		frag_len = ( eol - script_offset );
75
 
77
 
76
 		/* Allocate buffer for line */
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
 		/* Copy line */
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
 		DBG ( "$ %s\n", line );
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
 		rc = process_line ( line );
110
 		rc = process_line ( line );
90
-		free ( line );
91
 		if ( terminate ( rc ) )
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
 	} while ( script_offset < image->len );
119
 	} while ( script_offset < image->len );
95
 
120
 
121
+ err_process:
122
+ err_alloc:
123
+	free ( line );
96
 	return rc;
124
 	return rc;
97
 }
125
 }
98
 
126
 

Loading…
Cancel
Save