|  | @@ -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 |  
 |