|  | @@ -34,164 +34,201 @@ FILE_LICENCE ( GPL2_OR_LATER );
 | 
		
	
		
			
			| 34 | 34 |   *
 | 
		
	
		
			
			| 35 | 35 |   */
 | 
		
	
		
			
			| 36 | 36 |  
 | 
		
	
		
			
			| 37 |  | -/** "imgfetch" options */
 | 
		
	
		
			
			| 38 |  | -struct imgfetch_options {
 | 
		
	
		
			
			|  | 37 | +/** "img{single}" options */
 | 
		
	
		
			
			|  | 38 | +struct imgsingle_options {
 | 
		
	
		
			
			| 39 | 39 |  	/** Image name */
 | 
		
	
		
			
			| 40 | 40 |  	const char *name;
 | 
		
	
		
			
			| 41 | 41 |  };
 | 
		
	
		
			
			| 42 | 42 |  
 | 
		
	
		
			
			| 43 |  | -/** "imgfetch" option list */
 | 
		
	
		
			
			| 44 |  | -static struct option_descriptor imgfetch_opts[] = {
 | 
		
	
		
			
			|  | 43 | +/** "img{single}" option list */
 | 
		
	
		
			
			|  | 44 | +static struct option_descriptor imgsingle_opts[] = {
 | 
		
	
		
			
			| 45 | 45 |  	OPTION_DESC ( "name", 'n', required_argument,
 | 
		
	
		
			
			| 46 |  | -		      struct imgfetch_options, name, parse_string ),
 | 
		
	
		
			
			|  | 46 | +		      struct imgsingle_options, name, parse_string ),
 | 
		
	
		
			
			| 47 | 47 |  };
 | 
		
	
		
			
			| 48 | 48 |  
 | 
		
	
		
			
			| 49 |  | -/** "imgfetch" command descriptor */
 | 
		
	
		
			
			| 50 |  | -static struct command_descriptor imgfetch_cmd =
 | 
		
	
		
			
			| 51 |  | -	COMMAND_DESC ( struct imgfetch_options, imgfetch_opts, 1, MAX_ARGUMENTS,
 | 
		
	
		
			
			| 52 |  | -		       "[--name <name>] <uri> [<arguments>...]" );
 | 
		
	
		
			
			|  | 49 | +/** "img{single}" command descriptor */
 | 
		
	
		
			
			|  | 50 | +static struct command_descriptor imgsingle_cmd =
 | 
		
	
		
			
			|  | 51 | +	COMMAND_DESC ( struct imgsingle_options, imgsingle_opts,
 | 
		
	
		
			
			|  | 52 | +		       1, MAX_ARGUMENTS,
 | 
		
	
		
			
			|  | 53 | +		       "[--name <name>] <uri|image> [<arguments>...]" );
 | 
		
	
		
			
			|  | 54 | +
 | 
		
	
		
			
			|  | 55 | +/** An "img{single}" family command descriptor */
 | 
		
	
		
			
			|  | 56 | +struct imgsingle_descriptor {
 | 
		
	
		
			
			|  | 57 | +	/** Command descriptor */
 | 
		
	
		
			
			|  | 58 | +	struct command_descriptor *cmd;
 | 
		
	
		
			
			|  | 59 | +	/** Function to use to acquire the image */
 | 
		
	
		
			
			|  | 60 | +	int ( * acquire ) ( const char *name, struct image **image );
 | 
		
	
		
			
			|  | 61 | +	/** Pre-action to take upon image, or NULL */
 | 
		
	
		
			
			|  | 62 | +	void ( * preaction ) ( struct image *image );
 | 
		
	
		
			
			|  | 63 | +	/** Action to take upon image, or NULL */
 | 
		
	
		
			
			|  | 64 | +	int ( * action ) ( struct image *image );
 | 
		
	
		
			
			|  | 65 | +	/** Verb to describe action */
 | 
		
	
		
			
			|  | 66 | +	const char *verb;
 | 
		
	
		
			
			|  | 67 | +};
 | 
		
	
		
			
			| 53 | 68 |  
 | 
		
	
		
			
			| 54 | 69 |  /**
 | 
		
	
		
			
			| 55 |  | - * The "imgfetch" and friends command body
 | 
		
	
		
			
			|  | 70 | + * The "img{single}" family of commands
 | 
		
	
		
			
			| 56 | 71 |   *
 | 
		
	
		
			
			| 57 | 72 |   * @v argc		Argument count
 | 
		
	
		
			
			| 58 | 73 |   * @v argv		Argument list
 | 
		
	
		
			
			| 59 |  | - * @v cmd		Command descriptor
 | 
		
	
		
			
			|  | 74 | + * @v desc		"img{single}" command descriptor
 | 
		
	
		
			
			| 60 | 75 |   * @v action_name	Action name (for error messages)
 | 
		
	
		
			
			| 61 |  | - * @v action		Action to take upon a successful download
 | 
		
	
		
			
			|  | 76 | + * @v action		Action to take upon image
 | 
		
	
		
			
			| 62 | 77 |   * @ret rc		Return status code
 | 
		
	
		
			
			| 63 | 78 |   */
 | 
		
	
		
			
			| 64 |  | -static int imgfetch_core_exec ( int argc, char **argv,
 | 
		
	
		
			
			| 65 |  | -				const char *action_name,
 | 
		
	
		
			
			| 66 |  | -				int ( * action ) ( struct image *image ) ) {
 | 
		
	
		
			
			| 67 |  | -	struct imgfetch_options opts;
 | 
		
	
		
			
			| 68 |  | -	char *uri_string;
 | 
		
	
		
			
			|  | 79 | +static int imgsingle_exec ( int argc, char **argv,
 | 
		
	
		
			
			|  | 80 | +			    struct imgsingle_descriptor *desc ) {
 | 
		
	
		
			
			|  | 81 | +	struct imgsingle_options opts;
 | 
		
	
		
			
			|  | 82 | +	char *name_uri = NULL;
 | 
		
	
		
			
			| 69 | 83 |  	char *cmdline = NULL;
 | 
		
	
		
			
			|  | 84 | +	struct image *image;
 | 
		
	
		
			
			| 70 | 85 |  	int rc;
 | 
		
	
		
			
			| 71 | 86 |  
 | 
		
	
		
			
			| 72 | 87 |  	/* Parse options */
 | 
		
	
		
			
			| 73 |  | -	if ( ( rc = parse_options ( argc, argv, &imgfetch_cmd, &opts ) ) != 0 )
 | 
		
	
		
			
			|  | 88 | +	if ( ( rc = parse_options ( argc, argv, desc->cmd, &opts ) ) != 0 )
 | 
		
	
		
			
			| 74 | 89 |  		goto err_parse_options;
 | 
		
	
		
			
			| 75 | 90 |  
 | 
		
	
		
			
			| 76 |  | -	/* Parse URI string */
 | 
		
	
		
			
			| 77 |  | -	uri_string = argv[optind];
 | 
		
	
		
			
			|  | 91 | +	/* Parse name/URI string and command line, if present */
 | 
		
	
		
			
			|  | 92 | +	if ( optind < argc ) {
 | 
		
	
		
			
			|  | 93 | +		name_uri = argv[optind];
 | 
		
	
		
			
			|  | 94 | +		if ( argv[ optind + 1 ] != NULL ) {
 | 
		
	
		
			
			|  | 95 | +			cmdline = concat_args ( &argv[ optind + 1 ] );
 | 
		
	
		
			
			|  | 96 | +			if ( ! cmdline ) {
 | 
		
	
		
			
			|  | 97 | +				rc = -ENOMEM;
 | 
		
	
		
			
			|  | 98 | +				goto err_parse_cmdline;
 | 
		
	
		
			
			|  | 99 | +			}
 | 
		
	
		
			
			|  | 100 | +		}
 | 
		
	
		
			
			|  | 101 | +	}
 | 
		
	
		
			
			| 78 | 102 |  
 | 
		
	
		
			
			| 79 |  | -	/* Parse command line */
 | 
		
	
		
			
			| 80 |  | -	if ( argv[ optind + 1 ] != NULL ) {
 | 
		
	
		
			
			| 81 |  | -		cmdline = concat_args ( &argv[ optind + 1 ] );
 | 
		
	
		
			
			| 82 |  | -		if ( ! cmdline ) {
 | 
		
	
		
			
			| 83 |  | -			rc = -ENOMEM;
 | 
		
	
		
			
			| 84 |  | -			goto err_cmdline;
 | 
		
	
		
			
			|  | 103 | +	/* Acquire the image */
 | 
		
	
		
			
			|  | 104 | +	if ( name_uri ) {
 | 
		
	
		
			
			|  | 105 | +		if ( ( rc = desc->acquire ( name_uri, &image ) ) != 0 )
 | 
		
	
		
			
			|  | 106 | +			goto err_acquire;
 | 
		
	
		
			
			|  | 107 | +	} else {
 | 
		
	
		
			
			|  | 108 | +		image = image_find_selected();
 | 
		
	
		
			
			|  | 109 | +		if ( ! image ) {
 | 
		
	
		
			
			|  | 110 | +			printf ( "No image selected\n" );
 | 
		
	
		
			
			|  | 111 | +			goto err_acquire;
 | 
		
	
		
			
			| 85 | 112 |  		}
 | 
		
	
		
			
			| 86 | 113 |  	}
 | 
		
	
		
			
			| 87 | 114 |  
 | 
		
	
		
			
			| 88 |  | -	/* Fetch the image */
 | 
		
	
		
			
			| 89 |  | -	if ( ( rc = imgdownload_string ( uri_string, opts.name, cmdline,
 | 
		
	
		
			
			| 90 |  | -					 action ) ) != 0 ) {
 | 
		
	
		
			
			| 91 |  | -		printf ( "Could not %s %s: %s\n",
 | 
		
	
		
			
			| 92 |  | -			 action_name, uri_string, strerror ( rc ) );
 | 
		
	
		
			
			| 93 |  | -		goto err_imgdownload;
 | 
		
	
		
			
			|  | 115 | +	/* Carry out command pre-action, if applicable */
 | 
		
	
		
			
			|  | 116 | +	if ( desc->preaction )
 | 
		
	
		
			
			|  | 117 | +		desc->preaction ( image );
 | 
		
	
		
			
			|  | 118 | +
 | 
		
	
		
			
			|  | 119 | +	/* Set the image name, if applicable */
 | 
		
	
		
			
			|  | 120 | +	if ( opts.name ) {
 | 
		
	
		
			
			|  | 121 | +		if ( ( rc = image_set_name ( image, opts.name ) ) != 0 ) {
 | 
		
	
		
			
			|  | 122 | +			printf ( "Could not name image: %s\n",
 | 
		
	
		
			
			|  | 123 | +				 strerror ( rc ) );
 | 
		
	
		
			
			|  | 124 | +			goto err_set_name;
 | 
		
	
		
			
			|  | 125 | +		}
 | 
		
	
		
			
			| 94 | 126 |  	}
 | 
		
	
		
			
			| 95 | 127 |  
 | 
		
	
		
			
			| 96 |  | -	/* Free command line */
 | 
		
	
		
			
			| 97 |  | -	free ( cmdline );
 | 
		
	
		
			
			|  | 128 | +	/* Set the command-line arguments, if applicable */
 | 
		
	
		
			
			|  | 129 | +	if ( cmdline ) {
 | 
		
	
		
			
			|  | 130 | +		if ( ( rc = image_set_cmdline ( image, cmdline ) ) != 0 ) {
 | 
		
	
		
			
			|  | 131 | +			printf ( "Could not set arguments: %s\n",
 | 
		
	
		
			
			|  | 132 | +				 strerror ( rc ) );
 | 
		
	
		
			
			|  | 133 | +			goto err_set_cmdline;
 | 
		
	
		
			
			|  | 134 | +		}
 | 
		
	
		
			
			|  | 135 | +	}
 | 
		
	
		
			
			| 98 | 136 |  
 | 
		
	
		
			
			| 99 |  | -	return 0;
 | 
		
	
		
			
			|  | 137 | +	/* Carry out command action, if applicable */
 | 
		
	
		
			
			|  | 138 | +	if ( desc->action ) {
 | 
		
	
		
			
			|  | 139 | +		if ( ( rc = desc->action ( image ) ) != 0 ) {
 | 
		
	
		
			
			|  | 140 | +			printf ( "Could not %s: %s\n",
 | 
		
	
		
			
			|  | 141 | +				 desc->verb, strerror ( rc ) );
 | 
		
	
		
			
			|  | 142 | +			goto err_action;
 | 
		
	
		
			
			|  | 143 | +		}
 | 
		
	
		
			
			|  | 144 | +	}
 | 
		
	
		
			
			| 100 | 145 |  
 | 
		
	
		
			
			| 101 |  | - err_imgdownload:
 | 
		
	
		
			
			|  | 146 | +	/* Success */
 | 
		
	
		
			
			|  | 147 | +	rc = 0;
 | 
		
	
		
			
			|  | 148 | +
 | 
		
	
		
			
			|  | 149 | + err_action:
 | 
		
	
		
			
			|  | 150 | + err_set_cmdline:
 | 
		
	
		
			
			|  | 151 | + err_set_name:
 | 
		
	
		
			
			|  | 152 | + err_acquire:
 | 
		
	
		
			
			| 102 | 153 |  	free ( cmdline );
 | 
		
	
		
			
			| 103 |  | - err_cmdline:
 | 
		
	
		
			
			|  | 154 | + err_parse_cmdline:
 | 
		
	
		
			
			| 104 | 155 |   err_parse_options:
 | 
		
	
		
			
			| 105 | 156 |  	return rc;
 | 
		
	
		
			
			| 106 | 157 |  }
 | 
		
	
		
			
			| 107 | 158 |  
 | 
		
	
		
			
			| 108 |  | -/**
 | 
		
	
		
			
			| 109 |  | - * The "imgfetch"/"module" command
 | 
		
	
		
			
			| 110 |  | - *
 | 
		
	
		
			
			| 111 |  | - * @v argc		Argument count
 | 
		
	
		
			
			| 112 |  | - * @v argv		Argument list
 | 
		
	
		
			
			| 113 |  | - * @ret rc		Return status code
 | 
		
	
		
			
			| 114 |  | - */
 | 
		
	
		
			
			| 115 |  | -static int imgfetch_exec ( int argc, char **argv ) {
 | 
		
	
		
			
			|  | 159 | +/** "imgfetch" command descriptor */
 | 
		
	
		
			
			|  | 160 | +static struct command_descriptor imgfetch_cmd =
 | 
		
	
		
			
			|  | 161 | +	COMMAND_DESC ( struct imgsingle_options, imgsingle_opts,
 | 
		
	
		
			
			|  | 162 | +		       1, MAX_ARGUMENTS,
 | 
		
	
		
			
			|  | 163 | +		       "[--name <name>] <uri> [<arguments>...]" );
 | 
		
	
		
			
			| 116 | 164 |  
 | 
		
	
		
			
			| 117 |  | -	return imgfetch_core_exec ( argc, argv, "fetch", NULL );
 | 
		
	
		
			
			| 118 |  | -}
 | 
		
	
		
			
			|  | 165 | +/** "imgfetch" family command descriptor */
 | 
		
	
		
			
			|  | 166 | +struct imgsingle_descriptor imgfetch_desc = {
 | 
		
	
		
			
			|  | 167 | +	.cmd = &imgfetch_cmd,
 | 
		
	
		
			
			|  | 168 | +	.acquire = imgdownload_string,
 | 
		
	
		
			
			|  | 169 | +};
 | 
		
	
		
			
			| 119 | 170 |  
 | 
		
	
		
			
			| 120 | 171 |  /**
 | 
		
	
		
			
			| 121 |  | - * The "kernel" command
 | 
		
	
		
			
			|  | 172 | + * The "imgfetch" command
 | 
		
	
		
			
			| 122 | 173 |   *
 | 
		
	
		
			
			| 123 | 174 |   * @v argc		Argument count
 | 
		
	
		
			
			| 124 | 175 |   * @v argv		Argument list
 | 
		
	
		
			
			| 125 | 176 |   * @ret rc		Return status code
 | 
		
	
		
			
			| 126 | 177 |   */
 | 
		
	
		
			
			| 127 |  | -static int kernel_exec ( int argc, char **argv ) {
 | 
		
	
		
			
			| 128 |  | -
 | 
		
	
		
			
			| 129 |  | -	return imgfetch_core_exec ( argc, argv, "select", image_select );
 | 
		
	
		
			
			|  | 178 | +static int imgfetch_exec ( int argc, char **argv ) {
 | 
		
	
		
			
			|  | 179 | +	return imgsingle_exec ( argc, argv, &imgfetch_desc );
 | 
		
	
		
			
			| 130 | 180 |  }
 | 
		
	
		
			
			| 131 | 181 |  
 | 
		
	
		
			
			|  | 182 | +/** "imgselect" family command descriptor */
 | 
		
	
		
			
			|  | 183 | +struct imgsingle_descriptor imgselect_desc = {
 | 
		
	
		
			
			|  | 184 | +	.cmd = &imgsingle_cmd,
 | 
		
	
		
			
			|  | 185 | +	.acquire = imgacquire,
 | 
		
	
		
			
			|  | 186 | +	.action = image_select,
 | 
		
	
		
			
			|  | 187 | +	.verb = "select",
 | 
		
	
		
			
			|  | 188 | +};
 | 
		
	
		
			
			|  | 189 | +
 | 
		
	
		
			
			| 132 | 190 |  /**
 | 
		
	
		
			
			| 133 |  | - * The "chain" command
 | 
		
	
		
			
			|  | 191 | + * The "imgselect" command
 | 
		
	
		
			
			| 134 | 192 |   *
 | 
		
	
		
			
			| 135 | 193 |   * @v argc		Argument count
 | 
		
	
		
			
			| 136 | 194 |   * @v argv		Argument list
 | 
		
	
		
			
			| 137 | 195 |   * @ret rc		Return status code
 | 
		
	
		
			
			| 138 | 196 |   */
 | 
		
	
		
			
			| 139 |  | -static int chain_exec ( int argc, char **argv) {
 | 
		
	
		
			
			| 140 |  | -
 | 
		
	
		
			
			| 141 |  | -	return imgfetch_core_exec ( argc, argv, "boot", image_exec );
 | 
		
	
		
			
			|  | 197 | +static int imgselect_exec ( int argc, char **argv ) {
 | 
		
	
		
			
			|  | 198 | +	return imgsingle_exec ( argc, argv, &imgselect_desc );
 | 
		
	
		
			
			| 142 | 199 |  }
 | 
		
	
		
			
			| 143 | 200 |  
 | 
		
	
		
			
			| 144 |  | -/** "imgselect" options */
 | 
		
	
		
			
			| 145 |  | -struct imgselect_options {};
 | 
		
	
		
			
			| 146 |  | -
 | 
		
	
		
			
			| 147 |  | -/** "imgselect" option list */
 | 
		
	
		
			
			| 148 |  | -static struct option_descriptor imgselect_opts[] = {};
 | 
		
	
		
			
			| 149 |  | -
 | 
		
	
		
			
			| 150 |  | -/** "imgselect" command descriptor */
 | 
		
	
		
			
			| 151 |  | -static struct command_descriptor imgselect_cmd =
 | 
		
	
		
			
			| 152 |  | -	COMMAND_DESC ( struct imgselect_options, imgselect_opts, 1, 1,
 | 
		
	
		
			
			| 153 |  | -		       "<image>" );
 | 
		
	
		
			
			|  | 201 | +/** "imgexec" command descriptor */
 | 
		
	
		
			
			|  | 202 | +static struct command_descriptor imgexec_cmd =
 | 
		
	
		
			
			|  | 203 | +	COMMAND_DESC ( struct imgsingle_options, imgsingle_opts,
 | 
		
	
		
			
			|  | 204 | +		       0, MAX_ARGUMENTS,
 | 
		
	
		
			
			|  | 205 | +		       "[--name <name>] [<uri|image> [<arguments>...]]" );
 | 
		
	
		
			
			|  | 206 | +
 | 
		
	
		
			
			|  | 207 | +/** "imgexec" family command descriptor */
 | 
		
	
		
			
			|  | 208 | +struct imgsingle_descriptor imgexec_desc = {
 | 
		
	
		
			
			|  | 209 | +	.cmd = &imgexec_cmd,
 | 
		
	
		
			
			|  | 210 | +	.acquire = imgacquire,
 | 
		
	
		
			
			|  | 211 | +	.action = image_exec,
 | 
		
	
		
			
			|  | 212 | +	.verb = "boot",
 | 
		
	
		
			
			|  | 213 | +};
 | 
		
	
		
			
			| 154 | 214 |  
 | 
		
	
		
			
			| 155 | 215 |  /**
 | 
		
	
		
			
			| 156 |  | - * The "imgselect" command
 | 
		
	
		
			
			|  | 216 | + * The "imgexec" command
 | 
		
	
		
			
			| 157 | 217 |   *
 | 
		
	
		
			
			| 158 | 218 |   * @v argc		Argument count
 | 
		
	
		
			
			| 159 | 219 |   * @v argv		Argument list
 | 
		
	
		
			
			| 160 | 220 |   * @ret rc		Return status code
 | 
		
	
		
			
			| 161 | 221 |   */
 | 
		
	
		
			
			| 162 |  | -static int imgselect_exec ( int argc, char **argv ) {
 | 
		
	
		
			
			| 163 |  | -	struct imgselect_options opts;
 | 
		
	
		
			
			| 164 |  | -	struct image *image;
 | 
		
	
		
			
			| 165 |  | -	int rc;
 | 
		
	
		
			
			| 166 |  | -
 | 
		
	
		
			
			| 167 |  | -	/* Parse options */
 | 
		
	
		
			
			| 168 |  | -	if ( ( rc = parse_options ( argc, argv, &imgselect_cmd, &opts ) ) != 0 )
 | 
		
	
		
			
			| 169 |  | -		return rc;
 | 
		
	
		
			
			| 170 |  | -
 | 
		
	
		
			
			| 171 |  | -	/* Parse image name */
 | 
		
	
		
			
			| 172 |  | -	if ( ( rc = parse_image ( argv[optind], &image ) ) != 0 )
 | 
		
	
		
			
			| 173 |  | -		return rc;
 | 
		
	
		
			
			| 174 |  | -
 | 
		
	
		
			
			| 175 |  | -	/* Load image */
 | 
		
	
		
			
			| 176 |  | -	if ( ( rc = imgselect ( image ) ) != 0 ) {
 | 
		
	
		
			
			| 177 |  | -		printf ( "Could not select %s: %s\n",
 | 
		
	
		
			
			| 178 |  | -			 image->name, strerror ( rc ) );
 | 
		
	
		
			
			| 179 |  | -		return rc;
 | 
		
	
		
			
			| 180 |  | -	}
 | 
		
	
		
			
			| 181 |  | -
 | 
		
	
		
			
			| 182 |  | -	return 0;
 | 
		
	
		
			
			|  | 222 | +static int imgexec_exec ( int argc, char **argv) {
 | 
		
	
		
			
			|  | 223 | +	return imgsingle_exec ( argc, argv, &imgexec_desc );
 | 
		
	
		
			
			| 183 | 224 |  }
 | 
		
	
		
			
			| 184 | 225 |  
 | 
		
	
		
			
			| 185 |  | -/** "imgargs" options */
 | 
		
	
		
			
			| 186 |  | -struct imgargs_options {};
 | 
		
	
		
			
			| 187 |  | -
 | 
		
	
		
			
			| 188 |  | -/** "imgargs" option list */
 | 
		
	
		
			
			| 189 |  | -static struct option_descriptor imgargs_opts[] = {};
 | 
		
	
		
			
			| 190 |  | -
 | 
		
	
		
			
			| 191 |  | -/** "imgargs" command descriptor */
 | 
		
	
		
			
			| 192 |  | -static struct command_descriptor imgargs_cmd =
 | 
		
	
		
			
			| 193 |  | -	COMMAND_DESC ( struct imgargs_options, imgargs_opts, 1, MAX_ARGUMENTS,
 | 
		
	
		
			
			| 194 |  | -		       "<image> [<arguments>...]" );
 | 
		
	
		
			
			|  | 226 | +/** "imgargs" family command descriptor */
 | 
		
	
		
			
			|  | 227 | +struct imgsingle_descriptor imgargs_desc = {
 | 
		
	
		
			
			|  | 228 | +	.cmd = &imgsingle_cmd,
 | 
		
	
		
			
			|  | 229 | +	.acquire = imgacquire,
 | 
		
	
		
			
			|  | 230 | +	.preaction = image_clear_cmdline,
 | 
		
	
		
			
			|  | 231 | +};
 | 
		
	
		
			
			| 195 | 232 |  
 | 
		
	
		
			
			| 196 | 233 |  /**
 | 
		
	
		
			
			| 197 | 234 |   * The "imgargs" command body
 | 
		
	
	
		
			
			|  | @@ -201,105 +238,60 @@ static struct command_descriptor imgargs_cmd =
 | 
		
	
		
			
			| 201 | 238 |   * @ret rc		Return status code
 | 
		
	
		
			
			| 202 | 239 |   */
 | 
		
	
		
			
			| 203 | 240 |  static int imgargs_exec ( int argc, char **argv ) {
 | 
		
	
		
			
			| 204 |  | -	struct imgargs_options opts;
 | 
		
	
		
			
			| 205 |  | -	struct image *image;
 | 
		
	
		
			
			| 206 |  | -	char *cmdline = NULL;
 | 
		
	
		
			
			| 207 |  | -	int rc;
 | 
		
	
		
			
			| 208 |  | -
 | 
		
	
		
			
			| 209 |  | -	/* Parse options */
 | 
		
	
		
			
			| 210 |  | -	if ( ( rc = parse_options ( argc, argv, &imgargs_cmd, &opts ) ) != 0 )
 | 
		
	
		
			
			| 211 |  | -		goto err_parse_options;
 | 
		
	
		
			
			| 212 |  | -
 | 
		
	
		
			
			| 213 |  | -	/* Parse image name */
 | 
		
	
		
			
			| 214 |  | -	if ( ( rc = parse_image ( argv[optind], &image ) ) != 0 )
 | 
		
	
		
			
			| 215 |  | -		goto err_parse_image;
 | 
		
	
		
			
			| 216 |  | -
 | 
		
	
		
			
			| 217 |  | -	/* Parse command line */
 | 
		
	
		
			
			| 218 |  | -	if ( argv[ optind + 1 ] != NULL ) {
 | 
		
	
		
			
			| 219 |  | -		cmdline = concat_args ( &argv[ optind + 1 ] );
 | 
		
	
		
			
			| 220 |  | -		if ( ! cmdline ) {
 | 
		
	
		
			
			| 221 |  | -			rc = -ENOMEM;
 | 
		
	
		
			
			| 222 |  | -			goto err_cmdline;
 | 
		
	
		
			
			| 223 |  | -		}
 | 
		
	
		
			
			| 224 |  | -	}
 | 
		
	
		
			
			| 225 |  | -
 | 
		
	
		
			
			| 226 |  | -	/* Set command line */
 | 
		
	
		
			
			| 227 |  | -	if ( ( rc = image_set_cmdline ( image, cmdline ) ) != 0 )
 | 
		
	
		
			
			| 228 |  | -		goto err_set_cmdline;
 | 
		
	
		
			
			| 229 |  | -
 | 
		
	
		
			
			| 230 |  | -	/* Free command line */
 | 
		
	
		
			
			| 231 |  | -	free ( cmdline );
 | 
		
	
		
			
			| 232 |  | -
 | 
		
	
		
			
			| 233 |  | -	return 0;
 | 
		
	
		
			
			| 234 |  | -
 | 
		
	
		
			
			| 235 |  | - err_set_cmdline:
 | 
		
	
		
			
			| 236 |  | -	free ( cmdline );
 | 
		
	
		
			
			| 237 |  | - err_cmdline:
 | 
		
	
		
			
			| 238 |  | - err_parse_image:
 | 
		
	
		
			
			| 239 |  | - err_parse_options:
 | 
		
	
		
			
			| 240 |  | -	return rc;
 | 
		
	
		
			
			|  | 241 | +	return imgsingle_exec ( argc, argv, &imgargs_desc );
 | 
		
	
		
			
			| 241 | 242 |  }
 | 
		
	
		
			
			| 242 | 243 |  
 | 
		
	
		
			
			| 243 |  | -/** "imgexec" options */
 | 
		
	
		
			
			| 244 |  | -struct imgexec_options {};
 | 
		
	
		
			
			|  | 244 | +/** "img{multi}" options */
 | 
		
	
		
			
			|  | 245 | +struct imgmulti_options {};
 | 
		
	
		
			
			| 245 | 246 |  
 | 
		
	
		
			
			| 246 |  | -/** "imgexec" option list */
 | 
		
	
		
			
			| 247 |  | -static struct option_descriptor imgexec_opts[] = {};
 | 
		
	
		
			
			|  | 247 | +/** "img{multi}" option list */
 | 
		
	
		
			
			|  | 248 | +static struct option_descriptor imgmulti_opts[] = {};
 | 
		
	
		
			
			| 248 | 249 |  
 | 
		
	
		
			
			| 249 |  | -/** "imgexec" command descriptor */
 | 
		
	
		
			
			| 250 |  | -static struct command_descriptor imgexec_cmd =
 | 
		
	
		
			
			| 251 |  | -	COMMAND_DESC ( struct imgexec_options, imgexec_opts, 0, 1,
 | 
		
	
		
			
			| 252 |  | -		       "[<image>]" );
 | 
		
	
		
			
			|  | 250 | +/** "img{multi}" command descriptor */
 | 
		
	
		
			
			|  | 251 | +static struct command_descriptor imgmulti_cmd =
 | 
		
	
		
			
			|  | 252 | +	COMMAND_DESC ( struct imgmulti_options, imgmulti_opts, 0, MAX_ARGUMENTS,
 | 
		
	
		
			
			|  | 253 | +		       "[<image>...]" );
 | 
		
	
		
			
			| 253 | 254 |  
 | 
		
	
		
			
			| 254 | 255 |  /**
 | 
		
	
		
			
			| 255 |  | - * The "imgexec" command
 | 
		
	
		
			
			|  | 256 | + * The "img{multi}" family of commands
 | 
		
	
		
			
			| 256 | 257 |   *
 | 
		
	
		
			
			| 257 | 258 |   * @v argc		Argument count
 | 
		
	
		
			
			| 258 | 259 |   * @v argv		Argument list
 | 
		
	
		
			
			|  | 260 | + * @v payload		Function to execute on each image
 | 
		
	
		
			
			| 259 | 261 |   * @ret rc		Return status code
 | 
		
	
		
			
			| 260 | 262 |   */
 | 
		
	
		
			
			| 261 |  | -static int imgexec_exec ( int argc, char **argv ) {
 | 
		
	
		
			
			| 262 |  | -	struct imgexec_options opts;
 | 
		
	
		
			
			|  | 263 | +static int imgmulti_exec ( int argc, char **argv,
 | 
		
	
		
			
			|  | 264 | +			   void ( * payload ) ( struct image *image ) ) {
 | 
		
	
		
			
			|  | 265 | +	struct imgmulti_options opts;
 | 
		
	
		
			
			| 263 | 266 |  	struct image *image;
 | 
		
	
		
			
			|  | 267 | +	struct image *tmp;
 | 
		
	
		
			
			|  | 268 | +	int i;
 | 
		
	
		
			
			| 264 | 269 |  	int rc;
 | 
		
	
		
			
			| 265 | 270 |  
 | 
		
	
		
			
			| 266 | 271 |  	/* Parse options */
 | 
		
	
		
			
			| 267 |  | -	if ( ( rc = parse_options ( argc, argv, &imgexec_cmd, &opts ) ) != 0 )
 | 
		
	
		
			
			|  | 272 | +	if ( ( rc = parse_options ( argc, argv, &imgmulti_cmd, &opts ) ) != 0 )
 | 
		
	
		
			
			| 268 | 273 |  		return rc;
 | 
		
	
		
			
			| 269 | 274 |  
 | 
		
	
		
			
			| 270 |  | -	/* Parse image name */
 | 
		
	
		
			
			| 271 |  | -	if ( optind < argc ) {
 | 
		
	
		
			
			| 272 |  | -		if ( ( rc = parse_image ( argv[optind], &image ) ) != 0 )
 | 
		
	
		
			
			| 273 |  | -			return rc;
 | 
		
	
		
			
			| 274 |  | -	} else {
 | 
		
	
		
			
			| 275 |  | -		image = imgautoselect();
 | 
		
	
		
			
			| 276 |  | -		if ( ! image ) {
 | 
		
	
		
			
			| 277 |  | -			rc = -ENOTTY;
 | 
		
	
		
			
			| 278 |  | -			printf ( "No image selected: %s\n", strerror ( rc ) );
 | 
		
	
		
			
			| 279 |  | -			return rc;
 | 
		
	
		
			
			| 280 |  | -		}
 | 
		
	
		
			
			|  | 275 | +	/* If no images are explicitly specified, process all images */
 | 
		
	
		
			
			|  | 276 | +	if ( optind == argc ) {
 | 
		
	
		
			
			|  | 277 | +		for_each_image_safe ( image, tmp )
 | 
		
	
		
			
			|  | 278 | +			payload ( image );
 | 
		
	
		
			
			|  | 279 | +		return 0;
 | 
		
	
		
			
			| 281 | 280 |  	}
 | 
		
	
		
			
			| 282 | 281 |  
 | 
		
	
		
			
			| 283 |  | -	/* Execute image */
 | 
		
	
		
			
			| 284 |  | -	if ( ( rc = imgexec ( image ) ) != 0 ) {
 | 
		
	
		
			
			| 285 |  | -		printf ( "Could not execute %s: %s\n",
 | 
		
	
		
			
			| 286 |  | -			 image->name, strerror ( rc ) );
 | 
		
	
		
			
			| 287 |  | -		return rc;
 | 
		
	
		
			
			|  | 282 | +	/* Otherwise, process specified images */
 | 
		
	
		
			
			|  | 283 | +	for ( i = optind ; i < argc ; i++ ) {
 | 
		
	
		
			
			|  | 284 | +		image = find_image ( argv[i] );
 | 
		
	
		
			
			|  | 285 | +		if ( ! image ) {
 | 
		
	
		
			
			|  | 286 | +			printf ( "\"%s\": no such image\n", argv[i] );
 | 
		
	
		
			
			|  | 287 | +			return -ENOENT;
 | 
		
	
		
			
			|  | 288 | +		}
 | 
		
	
		
			
			|  | 289 | +		payload ( image );
 | 
		
	
		
			
			| 288 | 290 |  	}
 | 
		
	
		
			
			| 289 | 291 |  
 | 
		
	
		
			
			| 290 | 292 |  	return 0;
 | 
		
	
		
			
			| 291 | 293 |  }
 | 
		
	
		
			
			| 292 | 294 |  
 | 
		
	
		
			
			| 293 |  | -/** "imgstat" options */
 | 
		
	
		
			
			| 294 |  | -struct imgstat_options {};
 | 
		
	
		
			
			| 295 |  | -
 | 
		
	
		
			
			| 296 |  | -/** "imgstat" option list */
 | 
		
	
		
			
			| 297 |  | -static struct option_descriptor imgstat_opts[] = {};
 | 
		
	
		
			
			| 298 |  | -
 | 
		
	
		
			
			| 299 |  | -/** "imgstat" command descriptor */
 | 
		
	
		
			
			| 300 |  | -static struct command_descriptor imgstat_cmd =
 | 
		
	
		
			
			| 301 |  | -	COMMAND_DESC ( struct imgstat_options, imgstat_opts, 0, 0, "" );
 | 
		
	
		
			
			| 302 |  | -
 | 
		
	
		
			
			| 303 | 295 |  /**
 | 
		
	
		
			
			| 304 | 296 |   * The "imgstat" command
 | 
		
	
		
			
			| 305 | 297 |   *
 | 
		
	
	
		
			
			|  | @@ -308,33 +300,9 @@ static struct command_descriptor imgstat_cmd =
 | 
		
	
		
			
			| 308 | 300 |   * @ret rc		Return status code
 | 
		
	
		
			
			| 309 | 301 |   */
 | 
		
	
		
			
			| 310 | 302 |  static int imgstat_exec ( int argc, char **argv ) {
 | 
		
	
		
			
			| 311 |  | -	struct imgstat_options opts;
 | 
		
	
		
			
			| 312 |  | -	struct image *image;
 | 
		
	
		
			
			| 313 |  | -	int rc;
 | 
		
	
		
			
			| 314 |  | -
 | 
		
	
		
			
			| 315 |  | -	/* Parse options */
 | 
		
	
		
			
			| 316 |  | -	if ( ( rc = parse_options ( argc, argv, &imgstat_cmd, &opts ) ) != 0 )
 | 
		
	
		
			
			| 317 |  | -		return rc;
 | 
		
	
		
			
			| 318 |  | -
 | 
		
	
		
			
			| 319 |  | -	/* Show status of all images */
 | 
		
	
		
			
			| 320 |  | -	for_each_image ( image ) {
 | 
		
	
		
			
			| 321 |  | -		imgstat ( image );
 | 
		
	
		
			
			| 322 |  | -	}
 | 
		
	
		
			
			| 323 |  | -
 | 
		
	
		
			
			| 324 |  | -	return 0;
 | 
		
	
		
			
			|  | 303 | +	return imgmulti_exec ( argc, argv, imgstat );
 | 
		
	
		
			
			| 325 | 304 |  }
 | 
		
	
		
			
			| 326 | 305 |  
 | 
		
	
		
			
			| 327 |  | -/** "imgfree" options */
 | 
		
	
		
			
			| 328 |  | -struct imgfree_options {};
 | 
		
	
		
			
			| 329 |  | -
 | 
		
	
		
			
			| 330 |  | -/** "imgfree" option list */
 | 
		
	
		
			
			| 331 |  | -static struct option_descriptor imgfree_opts[] = {};
 | 
		
	
		
			
			| 332 |  | -
 | 
		
	
		
			
			| 333 |  | -/** "imgfree" command descriptor */
 | 
		
	
		
			
			| 334 |  | -static struct command_descriptor imgfree_cmd =
 | 
		
	
		
			
			| 335 |  | -	COMMAND_DESC ( struct imgfree_options, imgfree_opts, 0, 1,
 | 
		
	
		
			
			| 336 |  | -		       "[<image>]" );
 | 
		
	
		
			
			| 337 |  | -
 | 
		
	
		
			
			| 338 | 306 |  /**
 | 
		
	
		
			
			| 339 | 307 |   * The "imgfree" command
 | 
		
	
		
			
			| 340 | 308 |   *
 | 
		
	
	
		
			
			|  | @@ -343,28 +311,7 @@ static struct command_descriptor imgfree_cmd =
 | 
		
	
		
			
			| 343 | 311 |   * @ret rc		Return status code
 | 
		
	
		
			
			| 344 | 312 |   */
 | 
		
	
		
			
			| 345 | 313 |  static int imgfree_exec ( int argc, char **argv ) {
 | 
		
	
		
			
			| 346 |  | -	struct imgfree_options opts;
 | 
		
	
		
			
			| 347 |  | -	struct image *image;
 | 
		
	
		
			
			| 348 |  | -	struct image *tmp;
 | 
		
	
		
			
			| 349 |  | -	int rc;
 | 
		
	
		
			
			| 350 |  | -
 | 
		
	
		
			
			| 351 |  | -	/* Parse options */
 | 
		
	
		
			
			| 352 |  | -	if ( ( rc = parse_options ( argc, argv, &imgfree_cmd, &opts ) ) != 0 )
 | 
		
	
		
			
			| 353 |  | -		return rc;
 | 
		
	
		
			
			| 354 |  | -
 | 
		
	
		
			
			| 355 |  | -	if ( optind < argc ) {
 | 
		
	
		
			
			| 356 |  | -		/* Free specified image */
 | 
		
	
		
			
			| 357 |  | -		if ( ( rc = parse_image ( argv[optind], &image ) ) != 0 )
 | 
		
	
		
			
			| 358 |  | -			return rc;
 | 
		
	
		
			
			| 359 |  | -		imgfree ( image );
 | 
		
	
		
			
			| 360 |  | -	} else {
 | 
		
	
		
			
			| 361 |  | -		/* Free all images */
 | 
		
	
		
			
			| 362 |  | -		list_for_each_entry_safe ( image, tmp, &images, list ) {
 | 
		
	
		
			
			| 363 |  | -			imgfree ( image );
 | 
		
	
		
			
			| 364 |  | -		}
 | 
		
	
		
			
			| 365 |  | -	}
 | 
		
	
		
			
			| 366 |  | -
 | 
		
	
		
			
			| 367 |  | -	return 0;
 | 
		
	
		
			
			|  | 314 | +	return imgmulti_exec ( argc, argv, unregister_image );
 | 
		
	
		
			
			| 368 | 315 |  }
 | 
		
	
		
			
			| 369 | 316 |  
 | 
		
	
		
			
			| 370 | 317 |  /** Image management commands */
 | 
		
	
	
		
			
			|  | @@ -383,19 +330,19 @@ struct command image_commands[] __command = {
 | 
		
	
		
			
			| 383 | 330 |  	},
 | 
		
	
		
			
			| 384 | 331 |  	{
 | 
		
	
		
			
			| 385 | 332 |  		.name = "kernel",
 | 
		
	
		
			
			| 386 |  | -		.exec = kernel_exec,
 | 
		
	
		
			
			|  | 333 | +		.exec = imgselect_exec, /* synonym for "imgselect" */
 | 
		
	
		
			
			| 387 | 334 |  	},
 | 
		
	
		
			
			| 388 | 335 |  	{
 | 
		
	
		
			
			| 389 | 336 |  		.name = "chain",
 | 
		
	
		
			
			| 390 |  | -		.exec = chain_exec,
 | 
		
	
		
			
			|  | 337 | +		.exec = imgexec_exec, /* synonym for "imgexec" */
 | 
		
	
		
			
			| 391 | 338 |  	},
 | 
		
	
		
			
			| 392 | 339 |  	{
 | 
		
	
		
			
			| 393 | 340 |  		.name = "imgselect",
 | 
		
	
		
			
			| 394 | 341 |  		.exec = imgselect_exec,
 | 
		
	
		
			
			| 395 | 342 |  	},
 | 
		
	
		
			
			| 396 | 343 |  	{
 | 
		
	
		
			
			| 397 |  | -		.name = "imgload", /* synonym for "imgselect" */
 | 
		
	
		
			
			| 398 |  | -		.exec = imgselect_exec,
 | 
		
	
		
			
			|  | 344 | +		.name = "imgload",
 | 
		
	
		
			
			|  | 345 | +		.exec = imgselect_exec, /* synonym for "imgselect" */
 | 
		
	
		
			
			| 399 | 346 |  	},
 | 
		
	
		
			
			| 400 | 347 |  	{
 | 
		
	
		
			
			| 401 | 348 |  		.name = "imgargs",
 |