|
@@ -55,19 +55,27 @@ static size_t script_offset;
|
55
|
55
|
* @ret rc Return status code
|
56
|
56
|
*/
|
57
|
57
|
static int process_script ( struct image *image,
|
58
|
|
- int ( * process_line ) ( const char *line ),
|
|
58
|
+ int ( * process_line ) ( struct image *image,
|
|
59
|
+ size_t offset,
|
|
60
|
+ const char *label,
|
|
61
|
+ const char *command ),
|
59
|
62
|
int ( * terminate ) ( int rc ) ) {
|
60
|
63
|
size_t len = 0;
|
61
|
64
|
char *line = NULL;
|
|
65
|
+ size_t line_offset;
|
|
66
|
+ char *label;
|
|
67
|
+ char *command;
|
62
|
68
|
off_t eol;
|
63
|
69
|
size_t frag_len;
|
64
|
70
|
char *tmp;
|
65
|
71
|
int rc;
|
66
|
72
|
|
|
73
|
+ /* Initialise script and line offsets */
|
67
|
74
|
script_offset = 0;
|
|
75
|
+ line_offset = 0;
|
68
|
76
|
|
69
|
77
|
do {
|
70
|
|
-
|
|
78
|
+
|
71
|
79
|
/* Find length of next line, excluding any terminating '\n' */
|
72
|
80
|
eol = memchr_user ( image->data, script_offset, '\n',
|
73
|
81
|
( image->len - script_offset ) );
|
|
@@ -104,10 +112,23 @@ static int process_script ( struct image *image,
|
104
|
112
|
|
105
|
113
|
/* Terminate line */
|
106
|
114
|
line[len] = '\0';
|
107
|
|
- DBG ( "$ %s\n", line );
|
|
115
|
+
|
|
116
|
+ /* Split line into (optional) label and command */
|
|
117
|
+ command = line;
|
|
118
|
+ while ( isspace ( *command ) )
|
|
119
|
+ command++;
|
|
120
|
+ if ( *command == ':' ) {
|
|
121
|
+ label = ++command;
|
|
122
|
+ while ( *command && ! isspace ( *command ) )
|
|
123
|
+ command++;
|
|
124
|
+ if ( *command )
|
|
125
|
+ *(command++) = '\0';
|
|
126
|
+ } else {
|
|
127
|
+ label = NULL;
|
|
128
|
+ }
|
108
|
129
|
|
109
|
130
|
/* Process line */
|
110
|
|
- rc = process_line ( line );
|
|
131
|
+ rc = process_line ( image, line_offset, label, command );
|
111
|
132
|
if ( terminate ( rc ) )
|
112
|
133
|
goto err_process;
|
113
|
134
|
|
|
@@ -116,6 +137,9 @@ static int process_script ( struct image *image,
|
116
|
137
|
line = NULL;
|
117
|
138
|
len = 0;
|
118
|
139
|
|
|
140
|
+ /* Update line offset */
|
|
141
|
+ line_offset = script_offset;
|
|
142
|
+
|
119
|
143
|
} while ( script_offset < image->len );
|
120
|
144
|
|
121
|
145
|
err_process:
|
|
@@ -136,41 +160,24 @@ static int terminate_on_exit_or_failure ( int rc ) {
|
136
|
160
|
( rc != 0 ) );
|
137
|
161
|
}
|
138
|
162
|
|
139
|
|
-/**
|
140
|
|
- * Find label within script line
|
141
|
|
- *
|
142
|
|
- * @v line Line of script
|
143
|
|
- * @ret label Start of label name, or NULL if not found
|
144
|
|
- */
|
145
|
|
-static const char * find_label ( const char *line ) {
|
146
|
|
-
|
147
|
|
- /* Skip any leading whitespace */
|
148
|
|
- while ( isspace ( *line ) )
|
149
|
|
- line++;
|
150
|
|
-
|
151
|
|
- /* If first non-whitespace character is a ':', then we have a label */
|
152
|
|
- if ( *line == ':' ) {
|
153
|
|
- return ( line + 1 );
|
154
|
|
- } else {
|
155
|
|
- return NULL;
|
156
|
|
- }
|
157
|
|
-}
|
158
|
|
-
|
159
|
163
|
/**
|
160
|
164
|
* Execute script line
|
161
|
165
|
*
|
162
|
|
- * @v line Line of script
|
|
166
|
+ * @v image Script
|
|
167
|
+ * @v offset Offset within script
|
|
168
|
+ * @v label Label, or NULL
|
|
169
|
+ * @v command Command
|
163
|
170
|
* @ret rc Return status code
|
164
|
171
|
*/
|
165
|
|
-static int script_exec_line ( const char *line ) {
|
|
172
|
+static int script_exec_line ( struct image *image, size_t offset,
|
|
173
|
+ const char *label __unused,
|
|
174
|
+ const char *command ) {
|
166
|
175
|
int rc;
|
167
|
176
|
|
168
|
|
- /* Skip label lines */
|
169
|
|
- if ( find_label ( line ) != NULL )
|
170
|
|
- return 0;
|
|
177
|
+ DBGC ( image, "[%04zx] $ %s\n", offset, command );
|
171
|
178
|
|
172
|
179
|
/* Execute command */
|
173
|
|
- if ( ( rc = system ( line ) ) != 0 )
|
|
180
|
+ if ( ( rc = system ( command ) ) != 0 )
|
174
|
181
|
return rc;
|
175
|
182
|
|
176
|
183
|
return 0;
|
|
@@ -224,7 +231,7 @@ static int script_probe ( struct image *image ) {
|
224
|
231
|
|
225
|
232
|
/* Sanity check */
|
226
|
233
|
if ( image->len < sizeof ( test ) ) {
|
227
|
|
- DBG ( "Too short to be a script\n" );
|
|
234
|
+ DBGC ( image, "Too short to be a script\n" );
|
228
|
235
|
return -ENOEXEC;
|
229
|
236
|
}
|
230
|
237
|
|
|
@@ -233,7 +240,7 @@ static int script_probe ( struct image *image ) {
|
233
|
240
|
if ( ! ( ( ( memcmp ( test, ipxe_magic, sizeof ( test ) - 1 ) == 0 ) ||
|
234
|
241
|
( memcmp ( test, gpxe_magic, sizeof ( test ) - 1 ) == 0 )) &&
|
235
|
242
|
isspace ( test[ sizeof ( test ) - 1 ] ) ) ) {
|
236
|
|
- DBG ( "Invalid magic signature\n" );
|
|
243
|
+ DBGC ( image, "Invalid magic signature\n" );
|
237
|
244
|
return -ENOEXEC;
|
238
|
245
|
}
|
239
|
246
|
|
|
@@ -267,25 +274,26 @@ static const char *goto_label;
|
267
|
274
|
/**
|
268
|
275
|
* Check for presence of label
|
269
|
276
|
*
|
270
|
|
- * @v line Script line
|
|
277
|
+ * @v image Script
|
|
278
|
+ * @v offset Offset within script
|
|
279
|
+ * @v label Label
|
|
280
|
+ * @v command Command
|
271
|
281
|
* @ret rc Return status code
|
272
|
282
|
*/
|
273
|
|
-static int goto_find_label ( const char *line ) {
|
274
|
|
- size_t len = strlen ( goto_label );
|
275
|
|
- const char *label;
|
|
283
|
+static int goto_find_label ( struct image *image, size_t offset,
|
|
284
|
+ const char *label, const char *command __unused ) {
|
276
|
285
|
|
277
|
|
- /* Find label */
|
278
|
|
- label = find_label ( line );
|
|
286
|
+ /* Check label exists */
|
279
|
287
|
if ( ! label )
|
280
|
288
|
return -ENOENT;
|
281
|
289
|
|
282
|
|
- /* Check if label matches */
|
283
|
|
- if ( strncmp ( goto_label, label, len ) != 0 )
|
|
290
|
+ /* Check label matches */
|
|
291
|
+ if ( strcmp ( goto_label, label ) != 0 )
|
284
|
292
|
return -ENOENT;
|
285
|
293
|
|
286
|
|
- /* Check label is terminated by a NUL or whitespace */
|
287
|
|
- if ( label[len] && ! isspace ( label[len] ) )
|
288
|
|
- return -ENOENT;
|
|
294
|
+ /* Update script offset */
|
|
295
|
+ script_offset = offset;
|
|
296
|
+ DBGC ( image, "[%04zx] Gone to :%s\n", offset, label );
|
289
|
297
|
|
290
|
298
|
return 0;
|
291
|
299
|
}
|
|
@@ -331,6 +339,8 @@ static int goto_exec ( int argc, char **argv ) {
|
331
|
339
|
if ( ( rc = process_script ( current_image, goto_find_label,
|
332
|
340
|
terminate_on_label_found ) ) != 0 ) {
|
333
|
341
|
script_offset = saved_offset;
|
|
342
|
+ DBGC ( current_image, "[%04zx] No such label :%s\n",
|
|
343
|
+ script_offset, goto_label );
|
334
|
344
|
return rc;
|
335
|
345
|
}
|
336
|
346
|
|