|  | @@ -26,6 +26,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
 | 
		
	
		
			
			| 26 | 26 |  #include <getopt.h>
 | 
		
	
		
			
			| 27 | 27 |  #include <ipxe/image.h>
 | 
		
	
		
			
			| 28 | 28 |  #include <ipxe/command.h>
 | 
		
	
		
			
			|  | 29 | +#include <ipxe/parseopt.h>
 | 
		
	
		
			
			| 29 | 30 |  #include <usr/imgmgmt.h>
 | 
		
	
		
			
			| 30 | 31 |  
 | 
		
	
		
			
			| 31 | 32 |  /** @file
 | 
		
	
	
		
			
			|  | @@ -34,12 +35,6 @@ FILE_LICENCE ( GPL2_OR_LATER );
 | 
		
	
		
			
			| 34 | 35 |   *
 | 
		
	
		
			
			| 35 | 36 |   */
 | 
		
	
		
			
			| 36 | 37 |  
 | 
		
	
		
			
			| 37 |  | -enum image_action {
 | 
		
	
		
			
			| 38 |  | -	IMG_FETCH = 0,
 | 
		
	
		
			
			| 39 |  | -	IMG_LOAD,
 | 
		
	
		
			
			| 40 |  | -	IMG_EXEC,
 | 
		
	
		
			
			| 41 |  | -};
 | 
		
	
		
			
			| 42 |  | -
 | 
		
	
		
			
			| 43 | 38 |  /**
 | 
		
	
		
			
			| 44 | 39 |   * Fill in image command line
 | 
		
	
		
			
			| 45 | 40 |   *
 | 
		
	
	
		
			
			|  | @@ -74,74 +69,61 @@ static int imgfill_cmdline ( struct image *image, unsigned int nargs,
 | 
		
	
		
			
			| 74 | 69 |  	}
 | 
		
	
		
			
			| 75 | 70 |  }
 | 
		
	
		
			
			| 76 | 71 |  
 | 
		
	
		
			
			| 77 |  | -/**
 | 
		
	
		
			
			| 78 |  | - * "imgfetch"/"module"/"kernel" command syntax message
 | 
		
	
		
			
			| 79 |  | - *
 | 
		
	
		
			
			| 80 |  | - * @v argv		Argument list
 | 
		
	
		
			
			| 81 |  | - */
 | 
		
	
		
			
			| 82 |  | -static void imgfetch_core_syntax ( char **argv, enum image_action action ) {
 | 
		
	
		
			
			| 83 |  | -	static const char *actions[] = {
 | 
		
	
		
			
			| 84 |  | -		[IMG_FETCH]	= "Fetch",
 | 
		
	
		
			
			| 85 |  | -		[IMG_LOAD]	= "Fetch and load",
 | 
		
	
		
			
			| 86 |  | -		[IMG_EXEC]	= "Fetch and execute",
 | 
		
	
		
			
			| 87 |  | -	};
 | 
		
	
		
			
			| 88 |  | -
 | 
		
	
		
			
			| 89 |  | -	printf ( "Usage:\n"
 | 
		
	
		
			
			| 90 |  | -		 "  %s [-n|--name <name>] filename [arguments...]\n"
 | 
		
	
		
			
			| 91 |  | -		 "\n"
 | 
		
	
		
			
			| 92 |  | -		 "%s executable/loadable image\n",
 | 
		
	
		
			
			| 93 |  | -		 argv[0], actions[action] );
 | 
		
	
		
			
			| 94 |  | -}
 | 
		
	
		
			
			|  | 72 | +/** "imgfetch" options */
 | 
		
	
		
			
			|  | 73 | +struct imgfetch_options {
 | 
		
	
		
			
			|  | 74 | +	/** Image name */
 | 
		
	
		
			
			|  | 75 | +	const char *name;
 | 
		
	
		
			
			|  | 76 | +};
 | 
		
	
		
			
			|  | 77 | +
 | 
		
	
		
			
			|  | 78 | +/** "imgfetch" option list */
 | 
		
	
		
			
			|  | 79 | +static struct option_descriptor imgfetch_opts[] = {
 | 
		
	
		
			
			|  | 80 | +	OPTION_DESC ( "name", 'n', required_argument,
 | 
		
	
		
			
			|  | 81 | +		      struct imgfetch_options, name, parse_string ),
 | 
		
	
		
			
			|  | 82 | +};
 | 
		
	
		
			
			|  | 83 | +
 | 
		
	
		
			
			|  | 84 | +/** "imgfetch" command descriptor */
 | 
		
	
		
			
			|  | 85 | +static struct command_descriptor imgfetch_cmd =
 | 
		
	
		
			
			|  | 86 | +	COMMAND_DESC ( struct imgfetch_options, imgfetch_opts, 1, MAX_ARGUMENTS,
 | 
		
	
		
			
			|  | 87 | +		       "[--name <name>] <image_url> [<arguments>...]",
 | 
		
	
		
			
			|  | 88 | +		       "Fetch image" );
 | 
		
	
		
			
			|  | 89 | +
 | 
		
	
		
			
			|  | 90 | +/** "kernel" command descriptor */
 | 
		
	
		
			
			|  | 91 | +static struct command_descriptor kernel_cmd =
 | 
		
	
		
			
			|  | 92 | +	COMMAND_DESC ( struct imgfetch_options, imgfetch_opts, 1, MAX_ARGUMENTS,
 | 
		
	
		
			
			|  | 93 | +		       "[--name <name>] <image_url> [<arguments>...]",
 | 
		
	
		
			
			|  | 94 | +		       "Fetch and load image" );
 | 
		
	
		
			
			|  | 95 | +
 | 
		
	
		
			
			|  | 96 | +/** "chain" command descriptor */
 | 
		
	
		
			
			|  | 97 | +static struct command_descriptor chain_cmd =
 | 
		
	
		
			
			|  | 98 | +	COMMAND_DESC ( struct imgfetch_options, imgfetch_opts, 1, MAX_ARGUMENTS,
 | 
		
	
		
			
			|  | 99 | +		       "[--name <name>] <image_url> [<arguments>...]",
 | 
		
	
		
			
			|  | 100 | +		       "Fetch and execute image" );
 | 
		
	
		
			
			| 95 | 101 |  
 | 
		
	
		
			
			| 96 | 102 |  /**
 | 
		
	
		
			
			| 97 |  | - * The "imgfetch"/"module"/"kernel" command body
 | 
		
	
		
			
			|  | 103 | + * The "imgfetch" and friends command body
 | 
		
	
		
			
			| 98 | 104 |   *
 | 
		
	
		
			
			| 99 |  | - * @v image_type	Image type to assign (or NULL)
 | 
		
	
		
			
			| 100 |  | - * @v load		Image will be automatically loaded after fetching
 | 
		
	
		
			
			| 101 | 105 |   * @v argc		Argument count
 | 
		
	
		
			
			| 102 | 106 |   * @v argv		Argument list
 | 
		
	
		
			
			|  | 107 | + * @v cmd		Command descriptor
 | 
		
	
		
			
			|  | 108 | + * @v image_register	Image registration action
 | 
		
	
		
			
			| 103 | 109 |   * @ret rc		Return status code
 | 
		
	
		
			
			| 104 | 110 |   */
 | 
		
	
		
			
			| 105 |  | -static int imgfetch_core_exec ( struct image_type *image_type,
 | 
		
	
		
			
			| 106 |  | -				enum image_action action,
 | 
		
	
		
			
			| 107 |  | -				int argc, char **argv ) {
 | 
		
	
		
			
			| 108 |  | -	static struct option longopts[] = {
 | 
		
	
		
			
			| 109 |  | -		{ "help", 0, NULL, 'h' },
 | 
		
	
		
			
			| 110 |  | -		{ "name", required_argument, NULL, 'n' },
 | 
		
	
		
			
			| 111 |  | -		{ NULL, 0, NULL, 0 },
 | 
		
	
		
			
			| 112 |  | -	};
 | 
		
	
		
			
			|  | 111 | +static int imgfetch_core_exec ( int argc, char **argv,
 | 
		
	
		
			
			|  | 112 | +				struct command_descriptor *cmd,
 | 
		
	
		
			
			|  | 113 | +				int ( * image_register ) ( struct image * ) ) {
 | 
		
	
		
			
			|  | 114 | +	struct imgfetch_options opts;
 | 
		
	
		
			
			| 113 | 115 |  	struct image *image;
 | 
		
	
		
			
			| 114 |  | -	const char *name = NULL;
 | 
		
	
		
			
			| 115 |  | -	char *filename;
 | 
		
	
		
			
			| 116 |  | -	int ( * image_register ) ( struct image *image );
 | 
		
	
		
			
			| 117 |  | -	int c;
 | 
		
	
		
			
			|  | 116 | +	char *uri_string;
 | 
		
	
		
			
			| 118 | 117 |  	int rc;
 | 
		
	
		
			
			| 119 | 118 |  
 | 
		
	
		
			
			| 120 | 119 |  	/* Parse options */
 | 
		
	
		
			
			| 121 |  | -	while ( ( c = getopt_long ( argc, argv, "hn:",
 | 
		
	
		
			
			| 122 |  | -				    longopts, NULL ) ) >= 0 ) {
 | 
		
	
		
			
			| 123 |  | -		switch ( c ) {
 | 
		
	
		
			
			| 124 |  | -		case 'n':
 | 
		
	
		
			
			| 125 |  | -			/* Set image name */
 | 
		
	
		
			
			| 126 |  | -			name = optarg;
 | 
		
	
		
			
			| 127 |  | -			break;
 | 
		
	
		
			
			| 128 |  | -		case 'h':
 | 
		
	
		
			
			| 129 |  | -			/* Display help text */
 | 
		
	
		
			
			| 130 |  | -		default:
 | 
		
	
		
			
			| 131 |  | -			/* Unrecognised/invalid option */
 | 
		
	
		
			
			| 132 |  | -			imgfetch_core_syntax ( argv, action );
 | 
		
	
		
			
			| 133 |  | -			return -EINVAL;
 | 
		
	
		
			
			| 134 |  | -		}
 | 
		
	
		
			
			| 135 |  | -	}
 | 
		
	
		
			
			|  | 120 | +	if ( ( rc = parse_options ( argc, argv, cmd, &opts ) ) != 0 )
 | 
		
	
		
			
			|  | 121 | +		return rc;
 | 
		
	
		
			
			| 136 | 122 |  
 | 
		
	
		
			
			| 137 |  | -	/* Need at least a filename remaining after the options */
 | 
		
	
		
			
			| 138 |  | -	if ( optind == argc ) {
 | 
		
	
		
			
			| 139 |  | -		imgfetch_core_syntax ( argv, action );
 | 
		
	
		
			
			| 140 |  | -		return -EINVAL;
 | 
		
	
		
			
			| 141 |  | -	}
 | 
		
	
		
			
			| 142 |  | -	filename = argv[optind++];
 | 
		
	
		
			
			| 143 |  | -	if ( ! name )
 | 
		
	
		
			
			| 144 |  | -		name = basename ( filename );
 | 
		
	
		
			
			|  | 123 | +	/* Parse URI string */
 | 
		
	
		
			
			|  | 124 | +	uri_string = argv[optind];
 | 
		
	
		
			
			|  | 125 | +	if ( ! opts.name )
 | 
		
	
		
			
			|  | 126 | +		opts.name = basename ( uri_string );
 | 
		
	
		
			
			| 145 | 127 |  
 | 
		
	
		
			
			| 146 | 128 |  	/* Allocate image */
 | 
		
	
		
			
			| 147 | 129 |  	image = alloc_image();
 | 
		
	
	
		
			
			|  | @@ -151,37 +133,18 @@ static int imgfetch_core_exec ( struct image_type *image_type,
 | 
		
	
		
			
			| 151 | 133 |  	}
 | 
		
	
		
			
			| 152 | 134 |  
 | 
		
	
		
			
			| 153 | 135 |  	/* Fill in image name */
 | 
		
	
		
			
			| 154 |  | -	if ( name ) {
 | 
		
	
		
			
			| 155 |  | -		if ( ( rc = image_set_name ( image, name ) ) != 0 )
 | 
		
	
		
			
			| 156 |  | -			return rc;
 | 
		
	
		
			
			| 157 |  | -	}
 | 
		
	
		
			
			| 158 |  | -
 | 
		
	
		
			
			| 159 |  | -	/* Set image type (if specified) */
 | 
		
	
		
			
			| 160 |  | -	image->type = image_type;
 | 
		
	
		
			
			|  | 136 | +	if ( ( rc = image_set_name ( image, opts.name ) ) != 0 )
 | 
		
	
		
			
			|  | 137 | +		return rc;
 | 
		
	
		
			
			| 161 | 138 |  
 | 
		
	
		
			
			| 162 | 139 |  	/* Fill in command line */
 | 
		
	
		
			
			| 163 |  | -	if ( ( rc = imgfill_cmdline ( image, ( argc - optind ),
 | 
		
	
		
			
			| 164 |  | -				      &argv[optind] ) ) != 0 )
 | 
		
	
		
			
			|  | 140 | +	if ( ( rc = imgfill_cmdline ( image, ( argc - optind - 1 ),
 | 
		
	
		
			
			|  | 141 | +				      &argv[ optind + 1 ] ) ) != 0 )
 | 
		
	
		
			
			| 165 | 142 |  		return rc;
 | 
		
	
		
			
			| 166 | 143 |  
 | 
		
	
		
			
			| 167 | 144 |  	/* Fetch the image */
 | 
		
	
		
			
			| 168 |  | -	switch ( action ) {
 | 
		
	
		
			
			| 169 |  | -	case IMG_FETCH:
 | 
		
	
		
			
			| 170 |  | -		image_register = register_image;
 | 
		
	
		
			
			| 171 |  | -		break;
 | 
		
	
		
			
			| 172 |  | -	case IMG_LOAD:
 | 
		
	
		
			
			| 173 |  | -		image_register = register_and_autoload_image;
 | 
		
	
		
			
			| 174 |  | -		break;
 | 
		
	
		
			
			| 175 |  | -	case IMG_EXEC:
 | 
		
	
		
			
			| 176 |  | -		image_register = register_and_autoexec_image;
 | 
		
	
		
			
			| 177 |  | -		break;
 | 
		
	
		
			
			| 178 |  | -	default:
 | 
		
	
		
			
			| 179 |  | -		assert ( 0 );
 | 
		
	
		
			
			| 180 |  | -		return -EINVAL;
 | 
		
	
		
			
			| 181 |  | -	}
 | 
		
	
		
			
			| 182 |  | -	if ( ( rc = imgfetch ( image, filename, image_register ) ) != 0 ) {
 | 
		
	
		
			
			|  | 145 | +	if ( ( rc = imgfetch ( image, uri_string, image_register ) ) != 0 ) {
 | 
		
	
		
			
			| 183 | 146 |  		printf ( "Could not fetch %s: %s\n",
 | 
		
	
		
			
			| 184 |  | -			 filename, strerror ( rc ) );
 | 
		
	
		
			
			|  | 147 | +			 uri_string, strerror ( rc ) );
 | 
		
	
		
			
			| 185 | 148 |  		image_put ( image );
 | 
		
	
		
			
			| 186 | 149 |  		return rc;
 | 
		
	
		
			
			| 187 | 150 |  	}
 | 
		
	
	
		
			
			|  | @@ -195,16 +158,12 @@ static int imgfetch_core_exec ( struct image_type *image_type,
 | 
		
	
		
			
			| 195 | 158 |   *
 | 
		
	
		
			
			| 196 | 159 |   * @v argc		Argument count
 | 
		
	
		
			
			| 197 | 160 |   * @v argv		Argument list
 | 
		
	
		
			
			| 198 |  | - * @ret rc		Exit code
 | 
		
	
		
			
			|  | 161 | + * @ret rc		Return status code
 | 
		
	
		
			
			| 199 | 162 |   */
 | 
		
	
		
			
			| 200 | 163 |  static int imgfetch_exec ( int argc, char **argv ) {
 | 
		
	
		
			
			| 201 |  | -	int rc;
 | 
		
	
		
			
			| 202 |  | -
 | 
		
	
		
			
			| 203 |  | -	if ( ( rc = imgfetch_core_exec ( NULL, IMG_FETCH,
 | 
		
	
		
			
			| 204 |  | -					 argc, argv ) ) != 0 )
 | 
		
	
		
			
			| 205 |  | -		return rc;
 | 
		
	
		
			
			| 206 | 164 |  
 | 
		
	
		
			
			| 207 |  | -	return 0;
 | 
		
	
		
			
			|  | 165 | +	return imgfetch_core_exec ( argc, argv, &imgfetch_cmd,
 | 
		
	
		
			
			|  | 166 | +				    register_image );
 | 
		
	
		
			
			| 208 | 167 |  }
 | 
		
	
		
			
			| 209 | 168 |  
 | 
		
	
		
			
			| 210 | 169 |  /**
 | 
		
	
	
		
			
			|  | @@ -212,15 +171,12 @@ static int imgfetch_exec ( int argc, char **argv ) {
 | 
		
	
		
			
			| 212 | 171 |   *
 | 
		
	
		
			
			| 213 | 172 |   * @v argc		Argument count
 | 
		
	
		
			
			| 214 | 173 |   * @v argv		Argument list
 | 
		
	
		
			
			| 215 |  | - * @ret rc		Exit code
 | 
		
	
		
			
			|  | 174 | + * @ret rc		Return status code
 | 
		
	
		
			
			| 216 | 175 |   */
 | 
		
	
		
			
			| 217 | 176 |  static int kernel_exec ( int argc, char **argv ) {
 | 
		
	
		
			
			| 218 |  | -	int rc;
 | 
		
	
		
			
			| 219 | 177 |  
 | 
		
	
		
			
			| 220 |  | -	if ( ( rc = imgfetch_core_exec ( NULL, IMG_LOAD, argc, argv ) ) != 0 )
 | 
		
	
		
			
			| 221 |  | -		return rc;
 | 
		
	
		
			
			| 222 |  | -
 | 
		
	
		
			
			| 223 |  | -	return 0;
 | 
		
	
		
			
			|  | 178 | +	return imgfetch_core_exec ( argc, argv, &kernel_cmd,
 | 
		
	
		
			
			|  | 179 | +				    register_and_autoload_image );
 | 
		
	
		
			
			| 224 | 180 |  }
 | 
		
	
		
			
			| 225 | 181 |  
 | 
		
	
		
			
			| 226 | 182 |  /**
 | 
		
	
	
		
			
			|  | @@ -228,327 +184,211 @@ static int kernel_exec ( int argc, char **argv ) {
 | 
		
	
		
			
			| 228 | 184 |   *
 | 
		
	
		
			
			| 229 | 185 |   * @v argc		Argument count
 | 
		
	
		
			
			| 230 | 186 |   * @v argv		Argument list
 | 
		
	
		
			
			| 231 |  | - * @ret rc		Exit code
 | 
		
	
		
			
			|  | 187 | + * @ret rc		Return status code
 | 
		
	
		
			
			| 232 | 188 |   */
 | 
		
	
		
			
			| 233 | 189 |  static int chain_exec ( int argc, char **argv) {
 | 
		
	
		
			
			| 234 |  | -	int rc;
 | 
		
	
		
			
			| 235 | 190 |  
 | 
		
	
		
			
			| 236 |  | -	if ( ( rc = imgfetch_core_exec ( NULL, IMG_EXEC, argc, argv ) ) != 0 )
 | 
		
	
		
			
			| 237 |  | -		return rc;
 | 
		
	
		
			
			| 238 |  | -
 | 
		
	
		
			
			| 239 |  | -	return 0;
 | 
		
	
		
			
			|  | 191 | +	return imgfetch_core_exec ( argc, argv, &chain_cmd,
 | 
		
	
		
			
			|  | 192 | +				    register_and_autoexec_image );
 | 
		
	
		
			
			| 240 | 193 |  }
 | 
		
	
		
			
			| 241 | 194 |  
 | 
		
	
		
			
			| 242 |  | -/**
 | 
		
	
		
			
			| 243 |  | - * "imgload" command syntax message
 | 
		
	
		
			
			| 244 |  | - *
 | 
		
	
		
			
			| 245 |  | - * @v argv		Argument list
 | 
		
	
		
			
			| 246 |  | - */
 | 
		
	
		
			
			| 247 |  | -static void imgload_syntax ( char **argv ) {
 | 
		
	
		
			
			| 248 |  | -	printf ( "Usage:\n"
 | 
		
	
		
			
			| 249 |  | -		 "  %s <image name>\n"
 | 
		
	
		
			
			| 250 |  | -		 "\n"
 | 
		
	
		
			
			| 251 |  | -		 "Load executable/loadable image\n",
 | 
		
	
		
			
			| 252 |  | -		 argv[0] );
 | 
		
	
		
			
			| 253 |  | -}
 | 
		
	
		
			
			|  | 195 | +/** "imgload" options */
 | 
		
	
		
			
			|  | 196 | +struct imgload_options {};
 | 
		
	
		
			
			|  | 197 | +
 | 
		
	
		
			
			|  | 198 | +/** "imgload" option list */
 | 
		
	
		
			
			|  | 199 | +static struct option_descriptor imgload_opts[] = {};
 | 
		
	
		
			
			|  | 200 | +
 | 
		
	
		
			
			|  | 201 | +/** "imgload" command descriptor */
 | 
		
	
		
			
			|  | 202 | +static struct command_descriptor imgload_cmd =
 | 
		
	
		
			
			|  | 203 | +	COMMAND_DESC ( struct imgload_options, imgload_opts, 1, 1,
 | 
		
	
		
			
			|  | 204 | +		       "<image>", "Load image" );
 | 
		
	
		
			
			| 254 | 205 |  
 | 
		
	
		
			
			| 255 | 206 |  /**
 | 
		
	
		
			
			| 256 | 207 |   * The "imgload" command
 | 
		
	
		
			
			| 257 | 208 |   *
 | 
		
	
		
			
			| 258 | 209 |   * @v argc		Argument count
 | 
		
	
		
			
			| 259 | 210 |   * @v argv		Argument list
 | 
		
	
		
			
			| 260 |  | - * @ret rc		Exit code
 | 
		
	
		
			
			|  | 211 | + * @ret rc		Return status code
 | 
		
	
		
			
			| 261 | 212 |   */
 | 
		
	
		
			
			| 262 | 213 |  static int imgload_exec ( int argc, char **argv ) {
 | 
		
	
		
			
			| 263 |  | -	static struct option longopts[] = {
 | 
		
	
		
			
			| 264 |  | -		{ "help", 0, NULL, 'h' },
 | 
		
	
		
			
			| 265 |  | -		{ NULL, 0, NULL, 0 },
 | 
		
	
		
			
			| 266 |  | -	};
 | 
		
	
		
			
			|  | 214 | +	struct imgload_options opts;
 | 
		
	
		
			
			| 267 | 215 |  	struct image *image;
 | 
		
	
		
			
			| 268 |  | -	const char *name;
 | 
		
	
		
			
			| 269 |  | -	int c;
 | 
		
	
		
			
			| 270 | 216 |  	int rc;
 | 
		
	
		
			
			| 271 | 217 |  
 | 
		
	
		
			
			| 272 | 218 |  	/* Parse options */
 | 
		
	
		
			
			| 273 |  | -	while ( ( c = getopt_long ( argc, argv, "h", longopts, NULL ) ) >= 0 ){
 | 
		
	
		
			
			| 274 |  | -		switch ( c ) {
 | 
		
	
		
			
			| 275 |  | -		case 'h':
 | 
		
	
		
			
			| 276 |  | -			/* Display help text */
 | 
		
	
		
			
			| 277 |  | -		default:
 | 
		
	
		
			
			| 278 |  | -			/* Unrecognised/invalid option */
 | 
		
	
		
			
			| 279 |  | -			imgload_syntax ( argv );
 | 
		
	
		
			
			| 280 |  | -			return 1;
 | 
		
	
		
			
			| 281 |  | -		}
 | 
		
	
		
			
			| 282 |  | -	}
 | 
		
	
		
			
			|  | 219 | +	if ( ( rc = parse_options ( argc, argv, &imgload_cmd, &opts ) ) != 0 )
 | 
		
	
		
			
			|  | 220 | +		return rc;
 | 
		
	
		
			
			| 283 | 221 |  
 | 
		
	
		
			
			| 284 |  | -	/* Need exactly one image name remaining after the options */
 | 
		
	
		
			
			| 285 |  | -	if ( optind != ( argc - 1 ) ) {
 | 
		
	
		
			
			| 286 |  | -		imgload_syntax ( argv );
 | 
		
	
		
			
			| 287 |  | -		return 1;
 | 
		
	
		
			
			| 288 |  | -	}
 | 
		
	
		
			
			| 289 |  | -	name = argv[optind];
 | 
		
	
		
			
			|  | 222 | +	/* Parse image name */
 | 
		
	
		
			
			|  | 223 | +	if ( ( rc = parse_image ( argv[optind], &image ) ) != 0 )
 | 
		
	
		
			
			|  | 224 | +		return rc;
 | 
		
	
		
			
			| 290 | 225 |  
 | 
		
	
		
			
			| 291 |  | -	/* Load all specified images */
 | 
		
	
		
			
			| 292 |  | -	image = find_image ( name );
 | 
		
	
		
			
			| 293 |  | -	if ( ! image ) {
 | 
		
	
		
			
			| 294 |  | -		printf ( "No such image: %s\n", name );
 | 
		
	
		
			
			| 295 |  | -		return 1;
 | 
		
	
		
			
			| 296 |  | -	}
 | 
		
	
		
			
			|  | 226 | +	/* Load image */
 | 
		
	
		
			
			| 297 | 227 |  	if ( ( rc = imgload ( image ) ) != 0 ) {
 | 
		
	
		
			
			| 298 |  | -		printf ( "Could not load %s: %s\n", name, strerror ( rc ) );
 | 
		
	
		
			
			|  | 228 | +		printf ( "Could not load %s: %s\n",
 | 
		
	
		
			
			|  | 229 | +			 image->name, strerror ( rc ) );
 | 
		
	
		
			
			| 299 | 230 |  		return rc;
 | 
		
	
		
			
			| 300 | 231 |  	}
 | 
		
	
		
			
			| 301 | 232 |  
 | 
		
	
		
			
			| 302 | 233 |  	return 0;
 | 
		
	
		
			
			| 303 | 234 |  }
 | 
		
	
		
			
			| 304 | 235 |  
 | 
		
	
		
			
			| 305 |  | -/**
 | 
		
	
		
			
			| 306 |  | - * "imgargs" command syntax message
 | 
		
	
		
			
			| 307 |  | - *
 | 
		
	
		
			
			| 308 |  | - * @v argv		Argument list
 | 
		
	
		
			
			| 309 |  | - */
 | 
		
	
		
			
			| 310 |  | -static void imgargs_syntax ( char **argv ) {
 | 
		
	
		
			
			| 311 |  | -	printf ( "Usage:\n"
 | 
		
	
		
			
			| 312 |  | -		 "  %s <image name> [<arguments>...]\n"
 | 
		
	
		
			
			| 313 |  | -		 "\n"
 | 
		
	
		
			
			| 314 |  | -		 "Set arguments for executable/loadable image\n",
 | 
		
	
		
			
			| 315 |  | -		 argv[0] );
 | 
		
	
		
			
			| 316 |  | -}
 | 
		
	
		
			
			|  | 236 | +/** "imgargs" options */
 | 
		
	
		
			
			|  | 237 | +struct imgargs_options {};
 | 
		
	
		
			
			|  | 238 | +
 | 
		
	
		
			
			|  | 239 | +/** "imgargs" option list */
 | 
		
	
		
			
			|  | 240 | +static struct option_descriptor imgargs_opts[] = {};
 | 
		
	
		
			
			|  | 241 | +
 | 
		
	
		
			
			|  | 242 | +/** "imgargs" command descriptor */
 | 
		
	
		
			
			|  | 243 | +static struct command_descriptor imgargs_cmd =
 | 
		
	
		
			
			|  | 244 | +	COMMAND_DESC ( struct imgargs_options, imgargs_opts, 1, MAX_ARGUMENTS,
 | 
		
	
		
			
			|  | 245 | +		       "<image> [<arguments>...]",
 | 
		
	
		
			
			|  | 246 | +		       "Set arguments for image" );
 | 
		
	
		
			
			| 317 | 247 |  
 | 
		
	
		
			
			| 318 | 248 |  /**
 | 
		
	
		
			
			| 319 | 249 |   * The "imgargs" command body
 | 
		
	
		
			
			| 320 | 250 |   *
 | 
		
	
		
			
			| 321 | 251 |   * @v argc		Argument count
 | 
		
	
		
			
			| 322 | 252 |   * @v argv		Argument list
 | 
		
	
		
			
			| 323 |  | - * @ret rc		Exit code
 | 
		
	
		
			
			|  | 253 | + * @ret rc		Return status code
 | 
		
	
		
			
			| 324 | 254 |   */
 | 
		
	
		
			
			| 325 | 255 |  static int imgargs_exec ( int argc, char **argv ) {
 | 
		
	
		
			
			| 326 |  | -	static struct option longopts[] = {
 | 
		
	
		
			
			| 327 |  | -		{ "help", 0, NULL, 'h' },
 | 
		
	
		
			
			| 328 |  | -		{ NULL, 0, NULL, 0 },
 | 
		
	
		
			
			| 329 |  | -	};
 | 
		
	
		
			
			|  | 256 | +	struct imgargs_options opts;
 | 
		
	
		
			
			| 330 | 257 |  	struct image *image;
 | 
		
	
		
			
			| 331 |  | -	const char *name;
 | 
		
	
		
			
			| 332 |  | -	int c;
 | 
		
	
		
			
			| 333 | 258 |  	int rc;
 | 
		
	
		
			
			| 334 | 259 |  
 | 
		
	
		
			
			| 335 | 260 |  	/* Parse options */
 | 
		
	
		
			
			| 336 |  | -	while ( ( c = getopt_long ( argc, argv, "h", longopts, NULL ) ) >= 0 ){
 | 
		
	
		
			
			| 337 |  | -		switch ( c ) {
 | 
		
	
		
			
			| 338 |  | -		case 'h':
 | 
		
	
		
			
			| 339 |  | -			/* Display help text */
 | 
		
	
		
			
			| 340 |  | -		default:
 | 
		
	
		
			
			| 341 |  | -			/* Unrecognised/invalid option */
 | 
		
	
		
			
			| 342 |  | -			imgargs_syntax ( argv );
 | 
		
	
		
			
			| 343 |  | -			return 1;
 | 
		
	
		
			
			| 344 |  | -		}
 | 
		
	
		
			
			| 345 |  | -	}
 | 
		
	
		
			
			|  | 261 | +	if ( ( rc = parse_options ( argc, argv, &imgargs_cmd, &opts ) ) != 0 )
 | 
		
	
		
			
			|  | 262 | +		return rc;
 | 
		
	
		
			
			| 346 | 263 |  
 | 
		
	
		
			
			| 347 |  | -	/* Need at least an image name remaining after the options */
 | 
		
	
		
			
			| 348 |  | -	if ( optind == argc ) {
 | 
		
	
		
			
			| 349 |  | -		imgargs_syntax ( argv );
 | 
		
	
		
			
			| 350 |  | -		return 1;
 | 
		
	
		
			
			| 351 |  | -	}
 | 
		
	
		
			
			| 352 |  | -	name = argv[optind++];
 | 
		
	
		
			
			|  | 264 | +	/* Parse image name */
 | 
		
	
		
			
			|  | 265 | +	if ( ( rc = parse_image ( argv[optind], &image ) ) != 0 )
 | 
		
	
		
			
			|  | 266 | +		return rc;
 | 
		
	
		
			
			| 353 | 267 |  
 | 
		
	
		
			
			| 354 | 268 |  	/* Fill in command line */
 | 
		
	
		
			
			| 355 |  | -	image = find_image ( name );
 | 
		
	
		
			
			| 356 |  | -	if ( ! image ) {
 | 
		
	
		
			
			| 357 |  | -		printf ( "No such image: %s\n", name );
 | 
		
	
		
			
			| 358 |  | -		return 1;
 | 
		
	
		
			
			| 359 |  | -	}
 | 
		
	
		
			
			| 360 |  | -	if ( ( rc = imgfill_cmdline ( image, ( argc - optind ),
 | 
		
	
		
			
			| 361 |  | -				      &argv[optind] ) ) != 0 )
 | 
		
	
		
			
			|  | 269 | +	if ( ( rc = imgfill_cmdline ( image, ( argc - optind - 1 ),
 | 
		
	
		
			
			|  | 270 | +				      &argv[ optind + 1 ] ) ) != 0 )
 | 
		
	
		
			
			| 362 | 271 |  		return rc;
 | 
		
	
		
			
			| 363 | 272 |  
 | 
		
	
		
			
			| 364 |  | -
 | 
		
	
		
			
			| 365 | 273 |  	return 0;
 | 
		
	
		
			
			| 366 | 274 |  }
 | 
		
	
		
			
			| 367 | 275 |  
 | 
		
	
		
			
			| 368 |  | -/**
 | 
		
	
		
			
			| 369 |  | - * "imgexec" command syntax message
 | 
		
	
		
			
			| 370 |  | - *
 | 
		
	
		
			
			| 371 |  | - * @v argv		Argument list
 | 
		
	
		
			
			| 372 |  | - */
 | 
		
	
		
			
			| 373 |  | -static void imgexec_syntax ( char **argv ) {
 | 
		
	
		
			
			| 374 |  | -	printf ( "Usage:\n"
 | 
		
	
		
			
			| 375 |  | -		 "  %s <image name>\n"
 | 
		
	
		
			
			| 376 |  | -		 "\n"
 | 
		
	
		
			
			| 377 |  | -		 "Execute executable/loadable image\n",
 | 
		
	
		
			
			| 378 |  | -		 argv[0] );
 | 
		
	
		
			
			| 379 |  | -}
 | 
		
	
		
			
			|  | 276 | +/** "imgexec" options */
 | 
		
	
		
			
			|  | 277 | +struct imgexec_options {};
 | 
		
	
		
			
			|  | 278 | +
 | 
		
	
		
			
			|  | 279 | +/** "imgexec" option list */
 | 
		
	
		
			
			|  | 280 | +static struct option_descriptor imgexec_opts[] = {};
 | 
		
	
		
			
			|  | 281 | +
 | 
		
	
		
			
			|  | 282 | +/** "imgexec" command descriptor */
 | 
		
	
		
			
			|  | 283 | +static struct command_descriptor imgexec_cmd =
 | 
		
	
		
			
			|  | 284 | +	COMMAND_DESC ( struct imgexec_options, imgexec_opts, 0, 1,
 | 
		
	
		
			
			|  | 285 | +		       "[<image>]", "Execute image" );
 | 
		
	
		
			
			| 380 | 286 |  
 | 
		
	
		
			
			| 381 | 287 |  /**
 | 
		
	
		
			
			| 382 | 288 |   * The "imgexec" command
 | 
		
	
		
			
			| 383 | 289 |   *
 | 
		
	
		
			
			| 384 | 290 |   * @v argc		Argument count
 | 
		
	
		
			
			| 385 | 291 |   * @v argv		Argument list
 | 
		
	
		
			
			| 386 |  | - * @ret rc		Exit code
 | 
		
	
		
			
			|  | 292 | + * @ret rc		Return status code
 | 
		
	
		
			
			| 387 | 293 |   */
 | 
		
	
		
			
			| 388 | 294 |  static int imgexec_exec ( int argc, char **argv ) {
 | 
		
	
		
			
			| 389 |  | -	static struct option longopts[] = {
 | 
		
	
		
			
			| 390 |  | -		{ "help", 0, NULL, 'h' },
 | 
		
	
		
			
			| 391 |  | -		{ NULL, 0, NULL, 0 },
 | 
		
	
		
			
			| 392 |  | -	};
 | 
		
	
		
			
			|  | 295 | +	struct imgexec_options opts;
 | 
		
	
		
			
			| 393 | 296 |  	struct image *image;
 | 
		
	
		
			
			| 394 |  | -	const char *name = NULL;
 | 
		
	
		
			
			| 395 |  | -	int c;
 | 
		
	
		
			
			| 396 | 297 |  	int rc;
 | 
		
	
		
			
			| 397 | 298 |  
 | 
		
	
		
			
			| 398 | 299 |  	/* Parse options */
 | 
		
	
		
			
			| 399 |  | -	while ( ( c = getopt_long ( argc, argv, "h", longopts, NULL ) ) >= 0 ){
 | 
		
	
		
			
			| 400 |  | -		switch ( c ) {
 | 
		
	
		
			
			| 401 |  | -		case 'h':
 | 
		
	
		
			
			| 402 |  | -			/* Display help text */
 | 
		
	
		
			
			| 403 |  | -		default:
 | 
		
	
		
			
			| 404 |  | -			/* Unrecognised/invalid option */
 | 
		
	
		
			
			| 405 |  | -			imgexec_syntax ( argv );
 | 
		
	
		
			
			| 406 |  | -			return 1;
 | 
		
	
		
			
			| 407 |  | -		}
 | 
		
	
		
			
			| 408 |  | -	}
 | 
		
	
		
			
			|  | 300 | +	if ( ( rc = parse_options ( argc, argv, &imgexec_cmd, &opts ) ) != 0 )
 | 
		
	
		
			
			|  | 301 | +		return rc;
 | 
		
	
		
			
			| 409 | 302 |  
 | 
		
	
		
			
			| 410 |  | -	/* Need no more than one image name */
 | 
		
	
		
			
			| 411 |  | -	if ( optind != argc )
 | 
		
	
		
			
			| 412 |  | -		name = argv[optind++];
 | 
		
	
		
			
			| 413 |  | -	if ( optind != argc ) {
 | 
		
	
		
			
			| 414 |  | -		imgexec_syntax ( argv );
 | 
		
	
		
			
			| 415 |  | -		return 1;
 | 
		
	
		
			
			| 416 |  | -	}
 | 
		
	
		
			
			| 417 |  | -	
 | 
		
	
		
			
			| 418 |  | -	/* Execute specified image */
 | 
		
	
		
			
			| 419 |  | -	if ( name ) {
 | 
		
	
		
			
			| 420 |  | -		image = find_image ( name );
 | 
		
	
		
			
			| 421 |  | -		if ( ! image ) {
 | 
		
	
		
			
			| 422 |  | -			printf ( "No such image: %s\n", name );
 | 
		
	
		
			
			| 423 |  | -			return 1;
 | 
		
	
		
			
			| 424 |  | -		}
 | 
		
	
		
			
			|  | 303 | +	/* Parse image name */
 | 
		
	
		
			
			|  | 304 | +	if ( optind < argc ) {
 | 
		
	
		
			
			|  | 305 | +		if ( ( rc = parse_image ( argv[optind], &image ) ) != 0 )
 | 
		
	
		
			
			|  | 306 | +			return rc;
 | 
		
	
		
			
			| 425 | 307 |  	} else {
 | 
		
	
		
			
			| 426 | 308 |  		image = imgautoselect();
 | 
		
	
		
			
			| 427 | 309 |  		if ( ! image ) {
 | 
		
	
		
			
			| 428 | 310 |  			printf ( "No (unique) loaded image\n" );
 | 
		
	
		
			
			| 429 |  | -			return 1;
 | 
		
	
		
			
			|  | 311 | +			return -ENOTTY;
 | 
		
	
		
			
			| 430 | 312 |  		}
 | 
		
	
		
			
			| 431 | 313 |  	}
 | 
		
	
		
			
			| 432 | 314 |  
 | 
		
	
		
			
			|  | 315 | +	/* Execute image */
 | 
		
	
		
			
			| 433 | 316 |  	if ( ( rc = imgexec ( image ) ) != 0 ) {
 | 
		
	
		
			
			| 434 | 317 |  		printf ( "Could not execute %s: %s\n",
 | 
		
	
		
			
			| 435 | 318 |  			 image->name, strerror ( rc ) );
 | 
		
	
		
			
			| 436 |  | -		return 1;
 | 
		
	
		
			
			|  | 319 | +		return rc;
 | 
		
	
		
			
			| 437 | 320 |  	}
 | 
		
	
		
			
			| 438 | 321 |  
 | 
		
	
		
			
			| 439 | 322 |  	return 0;
 | 
		
	
		
			
			| 440 | 323 |  }
 | 
		
	
		
			
			| 441 | 324 |  
 | 
		
	
		
			
			| 442 |  | -/**
 | 
		
	
		
			
			| 443 |  | - * "imgstat" command syntax message
 | 
		
	
		
			
			| 444 |  | - *
 | 
		
	
		
			
			| 445 |  | - * @v argv		Argument list
 | 
		
	
		
			
			| 446 |  | - */
 | 
		
	
		
			
			| 447 |  | -static void imgstat_syntax ( char **argv ) {
 | 
		
	
		
			
			| 448 |  | -	printf ( "Usage:\n"
 | 
		
	
		
			
			| 449 |  | -		 "  %s\n"
 | 
		
	
		
			
			| 450 |  | -		 "\n"
 | 
		
	
		
			
			| 451 |  | -		 "List executable/loadable images\n",
 | 
		
	
		
			
			| 452 |  | -		 argv[0] );
 | 
		
	
		
			
			| 453 |  | -}
 | 
		
	
		
			
			|  | 325 | +/** "imgstat" options */
 | 
		
	
		
			
			|  | 326 | +struct imgstat_options {};
 | 
		
	
		
			
			|  | 327 | +
 | 
		
	
		
			
			|  | 328 | +/** "imgstat" option list */
 | 
		
	
		
			
			|  | 329 | +static struct option_descriptor imgstat_opts[] = {};
 | 
		
	
		
			
			|  | 330 | +
 | 
		
	
		
			
			|  | 331 | +/** "imgstat" command descriptor */
 | 
		
	
		
			
			|  | 332 | +static struct command_descriptor imgstat_cmd =
 | 
		
	
		
			
			|  | 333 | +	COMMAND_DESC ( struct imgstat_options, imgstat_opts, 0, 0,
 | 
		
	
		
			
			|  | 334 | +		       "", "List images" );
 | 
		
	
		
			
			| 454 | 335 |  
 | 
		
	
		
			
			| 455 | 336 |  /**
 | 
		
	
		
			
			| 456 | 337 |   * The "imgstat" command
 | 
		
	
		
			
			| 457 | 338 |   *
 | 
		
	
		
			
			| 458 | 339 |   * @v argc		Argument count
 | 
		
	
		
			
			| 459 | 340 |   * @v argv		Argument list
 | 
		
	
		
			
			| 460 |  | - * @ret rc		Exit code
 | 
		
	
		
			
			|  | 341 | + * @ret rc		Return status code
 | 
		
	
		
			
			| 461 | 342 |   */
 | 
		
	
		
			
			| 462 | 343 |  static int imgstat_exec ( int argc, char **argv ) {
 | 
		
	
		
			
			| 463 |  | -	static struct option longopts[] = {
 | 
		
	
		
			
			| 464 |  | -		{ "help", 0, NULL, 'h' },
 | 
		
	
		
			
			| 465 |  | -		{ NULL, 0, NULL, 0 },
 | 
		
	
		
			
			| 466 |  | -	};
 | 
		
	
		
			
			|  | 344 | +	struct imgstat_options opts;
 | 
		
	
		
			
			| 467 | 345 |  	struct image *image;
 | 
		
	
		
			
			| 468 |  | -	int c;
 | 
		
	
		
			
			|  | 346 | +	int rc;
 | 
		
	
		
			
			| 469 | 347 |  
 | 
		
	
		
			
			| 470 | 348 |  	/* Parse options */
 | 
		
	
		
			
			| 471 |  | -	while ( ( c = getopt_long ( argc, argv, "h", longopts, NULL ) ) >= 0 ){
 | 
		
	
		
			
			| 472 |  | -		switch ( c ) {
 | 
		
	
		
			
			| 473 |  | -		case 'h':
 | 
		
	
		
			
			| 474 |  | -			/* Display help text */
 | 
		
	
		
			
			| 475 |  | -		default:
 | 
		
	
		
			
			| 476 |  | -			/* Unrecognised/invalid option */
 | 
		
	
		
			
			| 477 |  | -			imgstat_syntax ( argv );
 | 
		
	
		
			
			| 478 |  | -			return 1;
 | 
		
	
		
			
			| 479 |  | -		}
 | 
		
	
		
			
			| 480 |  | -	}
 | 
		
	
		
			
			| 481 |  | -
 | 
		
	
		
			
			| 482 |  | -	/* No arguments */
 | 
		
	
		
			
			| 483 |  | -	if ( optind != argc ) {
 | 
		
	
		
			
			| 484 |  | -		imgstat_syntax ( argv );
 | 
		
	
		
			
			| 485 |  | -		return 1;
 | 
		
	
		
			
			| 486 |  | -	}
 | 
		
	
		
			
			|  | 349 | +	if ( ( rc = parse_options ( argc, argv, &imgstat_cmd, &opts ) ) != 0 )
 | 
		
	
		
			
			|  | 350 | +		return rc;
 | 
		
	
		
			
			| 487 | 351 |  
 | 
		
	
		
			
			| 488 | 352 |  	/* Show status of all images */
 | 
		
	
		
			
			| 489 | 353 |  	for_each_image ( image ) {
 | 
		
	
		
			
			| 490 | 354 |  		imgstat ( image );
 | 
		
	
		
			
			| 491 | 355 |  	}
 | 
		
	
		
			
			|  | 356 | +
 | 
		
	
		
			
			| 492 | 357 |  	return 0;
 | 
		
	
		
			
			| 493 | 358 |  }
 | 
		
	
		
			
			| 494 | 359 |  
 | 
		
	
		
			
			| 495 |  | -/**
 | 
		
	
		
			
			| 496 |  | - * "imgstat" command syntax message
 | 
		
	
		
			
			| 497 |  | - *
 | 
		
	
		
			
			| 498 |  | - * @v argv		Argument list
 | 
		
	
		
			
			| 499 |  | - */
 | 
		
	
		
			
			| 500 |  | -static void imgfree_syntax ( char **argv ) {
 | 
		
	
		
			
			| 501 |  | -	printf ( "Usage:\n"
 | 
		
	
		
			
			| 502 |  | -		 "  %s [<image name>]\n"
 | 
		
	
		
			
			| 503 |  | -		 "\n"
 | 
		
	
		
			
			| 504 |  | -		 "Free one or all executable/loadable images\n",
 | 
		
	
		
			
			| 505 |  | -		 argv[0] );
 | 
		
	
		
			
			| 506 |  | -}
 | 
		
	
		
			
			|  | 360 | +/** "imgfree" options */
 | 
		
	
		
			
			|  | 361 | +struct imgfree_options {};
 | 
		
	
		
			
			|  | 362 | +
 | 
		
	
		
			
			|  | 363 | +/** "imgfree" option list */
 | 
		
	
		
			
			|  | 364 | +static struct option_descriptor imgfree_opts[] = {};
 | 
		
	
		
			
			|  | 365 | +
 | 
		
	
		
			
			|  | 366 | +/** "imgfree" command descriptor */
 | 
		
	
		
			
			|  | 367 | +static struct command_descriptor imgfree_cmd =
 | 
		
	
		
			
			|  | 368 | +	COMMAND_DESC ( struct imgfree_options, imgfree_opts, 0, 1,
 | 
		
	
		
			
			|  | 369 | +		       "[<image>]", "Free image(s)" );
 | 
		
	
		
			
			| 507 | 370 |  
 | 
		
	
		
			
			| 508 | 371 |  /**
 | 
		
	
		
			
			| 509 | 372 |   * The "imgfree" command
 | 
		
	
		
			
			| 510 | 373 |   *
 | 
		
	
		
			
			| 511 | 374 |   * @v argc		Argument count
 | 
		
	
		
			
			| 512 | 375 |   * @v argv		Argument list
 | 
		
	
		
			
			| 513 |  | - * @ret rc		Exit code
 | 
		
	
		
			
			|  | 376 | + * @ret rc		Return status code
 | 
		
	
		
			
			| 514 | 377 |   */
 | 
		
	
		
			
			| 515 | 378 |  static int imgfree_exec ( int argc, char **argv ) {
 | 
		
	
		
			
			| 516 |  | -	static struct option longopts[] = {
 | 
		
	
		
			
			| 517 |  | -		{ "help", 0, NULL, 'h' },
 | 
		
	
		
			
			| 518 |  | -		{ NULL, 0, NULL, 0 },
 | 
		
	
		
			
			| 519 |  | -	};
 | 
		
	
		
			
			|  | 379 | +	struct imgfree_options opts;
 | 
		
	
		
			
			| 520 | 380 |  	struct image *image;
 | 
		
	
		
			
			| 521 | 381 |  	struct image *tmp;
 | 
		
	
		
			
			| 522 |  | -	const char *name = NULL;
 | 
		
	
		
			
			| 523 |  | -	int c;
 | 
		
	
		
			
			|  | 382 | +	int rc;
 | 
		
	
		
			
			| 524 | 383 |  
 | 
		
	
		
			
			| 525 | 384 |  	/* Parse options */
 | 
		
	
		
			
			| 526 |  | -	while ( ( c = getopt_long ( argc, argv, "h", longopts, NULL ) ) >= 0 ){
 | 
		
	
		
			
			| 527 |  | -		switch ( c ) {
 | 
		
	
		
			
			| 528 |  | -		case 'h':
 | 
		
	
		
			
			| 529 |  | -			/* Display help text */
 | 
		
	
		
			
			| 530 |  | -		default:
 | 
		
	
		
			
			| 531 |  | -			/* Unrecognised/invalid option */
 | 
		
	
		
			
			| 532 |  | -			imgfree_syntax ( argv );
 | 
		
	
		
			
			| 533 |  | -			return 1;
 | 
		
	
		
			
			| 534 |  | -		}
 | 
		
	
		
			
			| 535 |  | -	}
 | 
		
	
		
			
			| 536 |  | -
 | 
		
	
		
			
			| 537 |  | -	/* Need no more than one image name */
 | 
		
	
		
			
			| 538 |  | -	if ( optind != argc )
 | 
		
	
		
			
			| 539 |  | -		name = argv[optind++];
 | 
		
	
		
			
			| 540 |  | -	if ( optind != argc ) {
 | 
		
	
		
			
			| 541 |  | -		imgfree_syntax ( argv );
 | 
		
	
		
			
			| 542 |  | -		return 1;
 | 
		
	
		
			
			| 543 |  | -	}
 | 
		
	
		
			
			|  | 385 | +	if ( ( rc = parse_options ( argc, argv, &imgfree_cmd, &opts ) ) != 0 )
 | 
		
	
		
			
			|  | 386 | +		return rc;
 | 
		
	
		
			
			| 544 | 387 |  
 | 
		
	
		
			
			| 545 |  | -	if ( name ) {
 | 
		
	
		
			
			| 546 |  | -		/* Free specified image (may leak) */
 | 
		
	
		
			
			| 547 |  | -		image = find_image ( name );
 | 
		
	
		
			
			| 548 |  | -		if ( ! image ) {
 | 
		
	
		
			
			| 549 |  | -			printf ( "No such image: %s\n", name );
 | 
		
	
		
			
			| 550 |  | -			return 1;
 | 
		
	
		
			
			| 551 |  | -		}
 | 
		
	
		
			
			|  | 388 | +	if ( optind < argc ) {
 | 
		
	
		
			
			|  | 389 | +		/* Free specified image */
 | 
		
	
		
			
			|  | 390 | +		if ( ( rc = parse_image ( argv[optind], &image ) ) != 0 )
 | 
		
	
		
			
			|  | 391 | +			return rc;
 | 
		
	
		
			
			| 552 | 392 |  		imgfree ( image );
 | 
		
	
		
			
			| 553 | 393 |  	} else {
 | 
		
	
		
			
			| 554 | 394 |  		/* Free all images */
 | 
		
	
	
		
			
			|  | @@ -556,6 +396,7 @@ static int imgfree_exec ( int argc, char **argv ) {
 | 
		
	
		
			
			| 556 | 396 |  			imgfree ( image );
 | 
		
	
		
			
			| 557 | 397 |  		}
 | 
		
	
		
			
			| 558 | 398 |  	}
 | 
		
	
		
			
			|  | 399 | +
 | 
		
	
		
			
			| 559 | 400 |  	return 0;
 | 
		
	
		
			
			| 560 | 401 |  }
 | 
		
	
		
			
			| 561 | 402 |  
 |