|  | @@ -18,11 +18,11 @@
 | 
		
	
		
			
			| 18 | 18 |  
 | 
		
	
		
			
			| 19 | 19 |  #include <stdint.h>
 | 
		
	
		
			
			| 20 | 20 |  #include <stdlib.h>
 | 
		
	
		
			
			|  | 21 | +#include <libgen.h>
 | 
		
	
		
			
			| 21 | 22 |  #include <getopt.h>
 | 
		
	
		
			
			| 22 | 23 |  #include <vsprintf.h>
 | 
		
	
		
			
			| 23 | 24 |  #include <gpxe/image.h>
 | 
		
	
		
			
			| 24 | 25 |  #include <gpxe/command.h>
 | 
		
	
		
			
			| 25 |  | -#include <usr/fetch.h>
 | 
		
	
		
			
			| 26 | 26 |  #include <usr/imgmgmt.h>
 | 
		
	
		
			
			| 27 | 27 |  
 | 
		
	
		
			
			| 28 | 28 |  /** @file
 | 
		
	
	
		
			
			|  | @@ -37,36 +37,53 @@
 | 
		
	
		
			
			| 37 | 37 |   */
 | 
		
	
		
			
			| 38 | 38 |  
 | 
		
	
		
			
			| 39 | 39 |  /**
 | 
		
	
		
			
			| 40 |  | - * "fetch"/"module"/"kernel" command syntax message
 | 
		
	
		
			
			|  | 40 | + * Fill in image command line
 | 
		
	
		
			
			|  | 41 | + *
 | 
		
	
		
			
			|  | 42 | + * @v image		Image
 | 
		
	
		
			
			|  | 43 | + * @v nargs		Argument count
 | 
		
	
		
			
			|  | 44 | + * @v args		Argument list
 | 
		
	
		
			
			|  | 45 | + */
 | 
		
	
		
			
			|  | 46 | +void imgfill_cmdline ( struct image *image, unsigned int nargs, char **args ) {
 | 
		
	
		
			
			|  | 47 | +	size_t used = 0;
 | 
		
	
		
			
			|  | 48 | +
 | 
		
	
		
			
			|  | 49 | +	image->cmdline[0] = '\0';
 | 
		
	
		
			
			|  | 50 | +	while ( ( used < sizeof ( image->cmdline ) ) && nargs-- ) {
 | 
		
	
		
			
			|  | 51 | +		used += snprintf ( &image->cmdline[used],
 | 
		
	
		
			
			|  | 52 | +				   ( sizeof ( image->cmdline ) - used ),
 | 
		
	
		
			
			|  | 53 | +				   "%s%s", ( used ? " " : "" ), *(args++) );
 | 
		
	
		
			
			|  | 54 | +	}
 | 
		
	
		
			
			|  | 55 | +}
 | 
		
	
		
			
			|  | 56 | +
 | 
		
	
		
			
			|  | 57 | +/**
 | 
		
	
		
			
			|  | 58 | + * "imgfetch"/"module"/"kernel" command syntax message
 | 
		
	
		
			
			| 41 | 59 |   *
 | 
		
	
		
			
			| 42 | 60 |   * @v argv		Argument list
 | 
		
	
		
			
			| 43 | 61 |   */
 | 
		
	
		
			
			| 44 |  | -static void fetch_syntax ( char **argv ) {
 | 
		
	
		
			
			|  | 62 | +static void imgfetch_core_syntax ( char **argv, int load ) {
 | 
		
	
		
			
			| 45 | 63 |  	printf ( "Usage:\n"
 | 
		
	
		
			
			| 46 | 64 |  		 "  %s [-n|--name <name>] filename [arguments...]\n"
 | 
		
	
		
			
			| 47 | 65 |  		 "\n"
 | 
		
	
		
			
			| 48 |  | -		 "Fetch executable/loadable image\n",
 | 
		
	
		
			
			| 49 |  | -		 argv[0] );
 | 
		
	
		
			
			|  | 66 | +		 "%s executable/loadable image\n",
 | 
		
	
		
			
			|  | 67 | +		 argv[0], ( load ? "Fetch and load" : "Fetch" ) );
 | 
		
	
		
			
			| 50 | 68 |  }
 | 
		
	
		
			
			| 51 | 69 |  
 | 
		
	
		
			
			| 52 | 70 |  /**
 | 
		
	
		
			
			| 53 |  | - * The "fetch"/"module"/"kernel" command body
 | 
		
	
		
			
			|  | 71 | + * The "imgfetch"/"module"/"kernel" command body
 | 
		
	
		
			
			| 54 | 72 |   *
 | 
		
	
		
			
			| 55 | 73 |   * @v argc		Argument count
 | 
		
	
		
			
			| 56 | 74 |   * @v argv		Argument list
 | 
		
	
		
			
			| 57 |  | - * @v name		Default name for image, or NULL
 | 
		
	
		
			
			|  | 75 | + * @v load		Load image after fetching
 | 
		
	
		
			
			| 58 | 76 |   * @ret rc		Exit code
 | 
		
	
		
			
			| 59 | 77 |   */
 | 
		
	
		
			
			| 60 |  | -static int fetch_exec_name ( int argc, char **argv, const char *name ) {
 | 
		
	
		
			
			|  | 78 | +static int imgfetch_core_exec ( int argc, char **argv, int load ) {
 | 
		
	
		
			
			| 61 | 79 |  	static struct option longopts[] = {
 | 
		
	
		
			
			| 62 | 80 |  		{ "help", 0, NULL, 'h' },
 | 
		
	
		
			
			| 63 | 81 |  		{ "name", required_argument, NULL, 'n' },
 | 
		
	
		
			
			| 64 | 82 |  		{ NULL, 0, NULL, 0 },
 | 
		
	
		
			
			| 65 | 83 |  	};
 | 
		
	
		
			
			| 66 | 84 |  	struct image *image;
 | 
		
	
		
			
			| 67 |  | -	const char *filename;
 | 
		
	
		
			
			| 68 |  | -	char cmdline[ sizeof ( image->cmdline ) ];
 | 
		
	
		
			
			| 69 |  | -	size_t used = 0;
 | 
		
	
		
			
			|  | 85 | +	const char *name = NULL;
 | 
		
	
		
			
			|  | 86 | +	char *filename;
 | 
		
	
		
			
			| 70 | 87 |  	int c;
 | 
		
	
		
			
			| 71 | 88 |  	int rc;
 | 
		
	
		
			
			| 72 | 89 |  
 | 
		
	
	
		
			
			|  | @@ -82,76 +99,246 @@ static int fetch_exec_name ( int argc, char **argv, const char *name ) {
 | 
		
	
		
			
			| 82 | 99 |  			/* Display help text */
 | 
		
	
		
			
			| 83 | 100 |  		default:
 | 
		
	
		
			
			| 84 | 101 |  			/* Unrecognised/invalid option */
 | 
		
	
		
			
			| 85 |  | -			fetch_syntax ( argv );
 | 
		
	
		
			
			|  | 102 | +			imgfetch_core_syntax ( argv, load );
 | 
		
	
		
			
			| 86 | 103 |  			return 1;
 | 
		
	
		
			
			| 87 | 104 |  		}
 | 
		
	
		
			
			| 88 | 105 |  	}
 | 
		
	
		
			
			| 89 | 106 |  
 | 
		
	
		
			
			| 90 | 107 |  	/* Need at least a filename remaining after the options */
 | 
		
	
		
			
			| 91 |  | -	if ( optind >= argc ) {
 | 
		
	
		
			
			| 92 |  | -		fetch_syntax ( argv );
 | 
		
	
		
			
			|  | 108 | +	if ( optind == argc ) {
 | 
		
	
		
			
			|  | 109 | +		imgfetch_core_syntax ( argv, load );
 | 
		
	
		
			
			| 93 | 110 |  		return 1;
 | 
		
	
		
			
			| 94 | 111 |  	}
 | 
		
	
		
			
			| 95 | 112 |  	filename = argv[optind++];
 | 
		
	
		
			
			|  | 113 | +	if ( ! name )
 | 
		
	
		
			
			|  | 114 | +		name = basename ( filename );
 | 
		
	
		
			
			| 96 | 115 |  
 | 
		
	
		
			
			| 97 |  | -	/* Build command line */
 | 
		
	
		
			
			| 98 |  | -	while ( ( used < sizeof ( cmdline ) ) && ( optind < argc ) ) {
 | 
		
	
		
			
			| 99 |  | -		used += snprintf ( &cmdline[used], sizeof ( cmdline ) - used,
 | 
		
	
		
			
			| 100 |  | -				   " %s",  argv[optind++] );
 | 
		
	
		
			
			|  | 116 | +	/* Fetch the image */
 | 
		
	
		
			
			|  | 117 | +	if ( ( rc = imgfetch ( filename, name, &image ) ) != 0 ) {
 | 
		
	
		
			
			|  | 118 | +		printf ( "Could not fetch %s: %s\n", name, strerror ( rc ) );
 | 
		
	
		
			
			|  | 119 | +		return 1;
 | 
		
	
		
			
			| 101 | 120 |  	}
 | 
		
	
		
			
			| 102 | 121 |  
 | 
		
	
		
			
			| 103 |  | -	/* Allocate and fill struct image */
 | 
		
	
		
			
			| 104 |  | -	image = malloc ( sizeof ( *image ) );
 | 
		
	
		
			
			| 105 |  | -	if ( ! image ) {
 | 
		
	
		
			
			| 106 |  | -		printf ( "Out of memory\n" );
 | 
		
	
		
			
			| 107 |  | -		return 1;
 | 
		
	
		
			
			|  | 122 | +	/* Fill in command line */
 | 
		
	
		
			
			|  | 123 | +	imgfill_cmdline ( image, ( argc - optind ), &argv[optind] );
 | 
		
	
		
			
			|  | 124 | +
 | 
		
	
		
			
			|  | 125 | +	/* Load image if required */
 | 
		
	
		
			
			|  | 126 | +	if ( load ) {
 | 
		
	
		
			
			|  | 127 | +		if ( ( rc = imgload ( image ) ) != 0 ) {
 | 
		
	
		
			
			|  | 128 | +			printf ( "Could not load %s: %s\n", name,
 | 
		
	
		
			
			|  | 129 | +				 strerror ( rc ) );
 | 
		
	
		
			
			|  | 130 | +			return 1;
 | 
		
	
		
			
			|  | 131 | +		}
 | 
		
	
		
			
			| 108 | 132 |  	}
 | 
		
	
		
			
			| 109 |  | -	memset ( image, 0, sizeof ( *image ) );
 | 
		
	
		
			
			| 110 |  | -	if ( name )
 | 
		
	
		
			
			| 111 |  | -		strncpy ( image->name, name, ( sizeof ( image->name ) - 1 ) );
 | 
		
	
		
			
			| 112 |  | -	if ( used )
 | 
		
	
		
			
			| 113 |  | -		memcpy ( image->cmdline, cmdline, sizeof ( image->cmdline ) );
 | 
		
	
		
			
			| 114 |  | -
 | 
		
	
		
			
			| 115 |  | -	/* Fetch the file */
 | 
		
	
		
			
			| 116 |  | -	if ( ( rc = fetch ( image, filename ) ) != 0 ) {
 | 
		
	
		
			
			| 117 |  | -		printf ( "Could not fetch %s: %s\n", filename,
 | 
		
	
		
			
			| 118 |  | -			 strerror ( rc ) );
 | 
		
	
		
			
			| 119 |  | -		free ( image );
 | 
		
	
		
			
			|  | 133 | +
 | 
		
	
		
			
			|  | 134 | +	return 0;
 | 
		
	
		
			
			|  | 135 | +}
 | 
		
	
		
			
			|  | 136 | +
 | 
		
	
		
			
			|  | 137 | +/**
 | 
		
	
		
			
			|  | 138 | + * The "imgfetch"/"module" command
 | 
		
	
		
			
			|  | 139 | + *
 | 
		
	
		
			
			|  | 140 | + * @v argc		Argument count
 | 
		
	
		
			
			|  | 141 | + * @v argv		Argument list
 | 
		
	
		
			
			|  | 142 | + * @ret rc		Exit code
 | 
		
	
		
			
			|  | 143 | + */
 | 
		
	
		
			
			|  | 144 | +static int imgfetch_exec ( int argc, char **argv ) {
 | 
		
	
		
			
			|  | 145 | +	return imgfetch_core_exec ( argc, argv, 0 );
 | 
		
	
		
			
			|  | 146 | +}
 | 
		
	
		
			
			|  | 147 | +
 | 
		
	
		
			
			|  | 148 | +/**
 | 
		
	
		
			
			|  | 149 | + * The "kernel" command
 | 
		
	
		
			
			|  | 150 | + *
 | 
		
	
		
			
			|  | 151 | + * @v argc		Argument count
 | 
		
	
		
			
			|  | 152 | + * @v argv		Argument list
 | 
		
	
		
			
			|  | 153 | + * @ret rc		Exit code
 | 
		
	
		
			
			|  | 154 | + */
 | 
		
	
		
			
			|  | 155 | +static int kernel_exec ( int argc, char **argv ) {
 | 
		
	
		
			
			|  | 156 | +	return imgfetch_core_exec ( argc, argv, 1  );
 | 
		
	
		
			
			|  | 157 | +}
 | 
		
	
		
			
			|  | 158 | +
 | 
		
	
		
			
			|  | 159 | +/**
 | 
		
	
		
			
			|  | 160 | + * "imgload" command syntax message
 | 
		
	
		
			
			|  | 161 | + *
 | 
		
	
		
			
			|  | 162 | + * @v argv		Argument list
 | 
		
	
		
			
			|  | 163 | + */
 | 
		
	
		
			
			|  | 164 | +static void imgload_syntax ( char **argv ) {
 | 
		
	
		
			
			|  | 165 | +	printf ( "Usage:\n"
 | 
		
	
		
			
			|  | 166 | +		 "  %s <image name>\n"
 | 
		
	
		
			
			|  | 167 | +		 "\n"
 | 
		
	
		
			
			|  | 168 | +		 "Load executable/loadable image\n",
 | 
		
	
		
			
			|  | 169 | +		 argv[0] );
 | 
		
	
		
			
			|  | 170 | +}
 | 
		
	
		
			
			|  | 171 | +
 | 
		
	
		
			
			|  | 172 | +/**
 | 
		
	
		
			
			|  | 173 | + * The "imgload" command
 | 
		
	
		
			
			|  | 174 | + *
 | 
		
	
		
			
			|  | 175 | + * @v argc		Argument count
 | 
		
	
		
			
			|  | 176 | + * @v argv		Argument list
 | 
		
	
		
			
			|  | 177 | + * @ret rc		Exit code
 | 
		
	
		
			
			|  | 178 | + */
 | 
		
	
		
			
			|  | 179 | +static int imgload_exec ( int argc, char **argv ) {
 | 
		
	
		
			
			|  | 180 | +	static struct option longopts[] = {
 | 
		
	
		
			
			|  | 181 | +		{ "help", 0, NULL, 'h' },
 | 
		
	
		
			
			|  | 182 | +		{ NULL, 0, NULL, 0 },
 | 
		
	
		
			
			|  | 183 | +	};
 | 
		
	
		
			
			|  | 184 | +	struct image *image;
 | 
		
	
		
			
			|  | 185 | +	const char *name;
 | 
		
	
		
			
			|  | 186 | +	int c;
 | 
		
	
		
			
			|  | 187 | +	int rc;
 | 
		
	
		
			
			|  | 188 | +
 | 
		
	
		
			
			|  | 189 | +	/* Parse options */
 | 
		
	
		
			
			|  | 190 | +	while ( ( c = getopt_long ( argc, argv, "h", longopts, NULL ) ) >= 0 ){
 | 
		
	
		
			
			|  | 191 | +		switch ( c ) {
 | 
		
	
		
			
			|  | 192 | +		case 'h':
 | 
		
	
		
			
			|  | 193 | +			/* Display help text */
 | 
		
	
		
			
			|  | 194 | +		default:
 | 
		
	
		
			
			|  | 195 | +			/* Unrecognised/invalid option */
 | 
		
	
		
			
			|  | 196 | +			imgload_syntax ( argv );
 | 
		
	
		
			
			|  | 197 | +			return 1;
 | 
		
	
		
			
			|  | 198 | +		}
 | 
		
	
		
			
			|  | 199 | +	}
 | 
		
	
		
			
			|  | 200 | +
 | 
		
	
		
			
			|  | 201 | +	/* Need exactly one image name remaining after the options */
 | 
		
	
		
			
			|  | 202 | +	if ( optind != ( argc - 1 ) ) {
 | 
		
	
		
			
			|  | 203 | +		imgload_syntax ( argv );
 | 
		
	
		
			
			| 120 | 204 |  		return 1;
 | 
		
	
		
			
			| 121 | 205 |  	}
 | 
		
	
		
			
			|  | 206 | +	name = argv[optind];
 | 
		
	
		
			
			| 122 | 207 |  
 | 
		
	
		
			
			| 123 |  | -	/* Register the image */
 | 
		
	
		
			
			| 124 |  | -	if ( ( rc = register_image ( image ) ) != 0 ) {
 | 
		
	
		
			
			| 125 |  | -		printf ( "Could not register %s: %s\n", filename,
 | 
		
	
		
			
			| 126 |  | -			 strerror ( rc ) );
 | 
		
	
		
			
			| 127 |  | -		free ( image );
 | 
		
	
		
			
			|  | 208 | +	/* Load all specified images */
 | 
		
	
		
			
			|  | 209 | +	image = find_image ( name );
 | 
		
	
		
			
			|  | 210 | +	if ( ! image ) {
 | 
		
	
		
			
			|  | 211 | +		printf ( "No such image: %s\n", name );
 | 
		
	
		
			
			|  | 212 | +		return 1;
 | 
		
	
		
			
			|  | 213 | +	}
 | 
		
	
		
			
			|  | 214 | +	if ( ( rc = imgload ( image ) ) != 0 ) {
 | 
		
	
		
			
			|  | 215 | +		printf ( "Could not load %s: %s\n", name, strerror ( rc ) );
 | 
		
	
		
			
			| 128 | 216 |  		return 1;
 | 
		
	
		
			
			| 129 | 217 |  	}
 | 
		
	
		
			
			| 130 | 218 |  
 | 
		
	
		
			
			| 131 |  | -	imgstat ( image );
 | 
		
	
		
			
			| 132 | 219 |  	return 0;
 | 
		
	
		
			
			| 133 | 220 |  }
 | 
		
	
		
			
			| 134 | 221 |  
 | 
		
	
		
			
			| 135 | 222 |  /**
 | 
		
	
		
			
			| 136 |  | - * The "fetch"/"module" command
 | 
		
	
		
			
			|  | 223 | + * "imgargs" command syntax message
 | 
		
	
		
			
			|  | 224 | + *
 | 
		
	
		
			
			|  | 225 | + * @v argv		Argument list
 | 
		
	
		
			
			|  | 226 | + */
 | 
		
	
		
			
			|  | 227 | +static void imgargs_syntax ( char **argv ) {
 | 
		
	
		
			
			|  | 228 | +	printf ( "Usage:\n"
 | 
		
	
		
			
			|  | 229 | +		 "  %s <image name> [<arguments>...]\n"
 | 
		
	
		
			
			|  | 230 | +		 "\n"
 | 
		
	
		
			
			|  | 231 | +		 "Set arguments for executable/loadable image\n",
 | 
		
	
		
			
			|  | 232 | +		 argv[0] );
 | 
		
	
		
			
			|  | 233 | +}
 | 
		
	
		
			
			|  | 234 | +
 | 
		
	
		
			
			|  | 235 | +/**
 | 
		
	
		
			
			|  | 236 | + * The "imgargs" command body
 | 
		
	
		
			
			| 137 | 237 |   *
 | 
		
	
		
			
			| 138 | 238 |   * @v argc		Argument count
 | 
		
	
		
			
			| 139 | 239 |   * @v argv		Argument list
 | 
		
	
		
			
			| 140 | 240 |   * @ret rc		Exit code
 | 
		
	
		
			
			| 141 | 241 |   */
 | 
		
	
		
			
			| 142 |  | -static int fetch_exec ( int argc, char **argv ) {
 | 
		
	
		
			
			| 143 |  | -	return fetch_exec_name ( argc, argv, NULL );
 | 
		
	
		
			
			|  | 242 | +static int imgargs_exec ( int argc, char **argv ) {
 | 
		
	
		
			
			|  | 243 | +	static struct option longopts[] = {
 | 
		
	
		
			
			|  | 244 | +		{ "help", 0, NULL, 'h' },
 | 
		
	
		
			
			|  | 245 | +		{ NULL, 0, NULL, 0 },
 | 
		
	
		
			
			|  | 246 | +	};
 | 
		
	
		
			
			|  | 247 | +	struct image *image;
 | 
		
	
		
			
			|  | 248 | +	const char *name;
 | 
		
	
		
			
			|  | 249 | +	int c;
 | 
		
	
		
			
			|  | 250 | +
 | 
		
	
		
			
			|  | 251 | +	/* Parse options */
 | 
		
	
		
			
			|  | 252 | +	while ( ( c = getopt_long ( argc, argv, "h", longopts, NULL ) ) >= 0 ){
 | 
		
	
		
			
			|  | 253 | +		switch ( c ) {
 | 
		
	
		
			
			|  | 254 | +		case 'h':
 | 
		
	
		
			
			|  | 255 | +			/* Display help text */
 | 
		
	
		
			
			|  | 256 | +		default:
 | 
		
	
		
			
			|  | 257 | +			/* Unrecognised/invalid option */
 | 
		
	
		
			
			|  | 258 | +			imgargs_syntax ( argv );
 | 
		
	
		
			
			|  | 259 | +			return 1;
 | 
		
	
		
			
			|  | 260 | +		}
 | 
		
	
		
			
			|  | 261 | +	}
 | 
		
	
		
			
			|  | 262 | +
 | 
		
	
		
			
			|  | 263 | +	/* Need at least an image name remaining after the options */
 | 
		
	
		
			
			|  | 264 | +	if ( optind == argc ) {
 | 
		
	
		
			
			|  | 265 | +		imgargs_syntax ( argv );
 | 
		
	
		
			
			|  | 266 | +		return 1;
 | 
		
	
		
			
			|  | 267 | +	}
 | 
		
	
		
			
			|  | 268 | +	name = argv[optind++];
 | 
		
	
		
			
			|  | 269 | +
 | 
		
	
		
			
			|  | 270 | +	/* Fill in command line */
 | 
		
	
		
			
			|  | 271 | +	image = find_image ( name );
 | 
		
	
		
			
			|  | 272 | +	if ( ! image ) {
 | 
		
	
		
			
			|  | 273 | +		printf ( "No such image: %s\n", name );
 | 
		
	
		
			
			|  | 274 | +		return 1;
 | 
		
	
		
			
			|  | 275 | +	}
 | 
		
	
		
			
			|  | 276 | +	imgfill_cmdline ( image, ( argc - optind ), &argv[optind] );
 | 
		
	
		
			
			|  | 277 | +
 | 
		
	
		
			
			|  | 278 | +	return 0;
 | 
		
	
		
			
			|  | 279 | +}
 | 
		
	
		
			
			|  | 280 | +
 | 
		
	
		
			
			|  | 281 | +/**
 | 
		
	
		
			
			|  | 282 | + * "imgexec" command syntax message
 | 
		
	
		
			
			|  | 283 | + *
 | 
		
	
		
			
			|  | 284 | + * @v argv		Argument list
 | 
		
	
		
			
			|  | 285 | + */
 | 
		
	
		
			
			|  | 286 | +static void imgexec_syntax ( char **argv ) {
 | 
		
	
		
			
			|  | 287 | +	printf ( "Usage:\n"
 | 
		
	
		
			
			|  | 288 | +		 "  %s <image name>\n"
 | 
		
	
		
			
			|  | 289 | +		 "\n"
 | 
		
	
		
			
			|  | 290 | +		 "Execute executable/loadable image\n",
 | 
		
	
		
			
			|  | 291 | +		 argv[0] );
 | 
		
	
		
			
			| 144 | 292 |  }
 | 
		
	
		
			
			| 145 | 293 |  
 | 
		
	
		
			
			| 146 | 294 |  /**
 | 
		
	
		
			
			| 147 |  | - * The "kernel" command
 | 
		
	
		
			
			|  | 295 | + * The "imgexec" command
 | 
		
	
		
			
			| 148 | 296 |   *
 | 
		
	
		
			
			| 149 | 297 |   * @v argc		Argument count
 | 
		
	
		
			
			| 150 | 298 |   * @v argv		Argument list
 | 
		
	
		
			
			| 151 | 299 |   * @ret rc		Exit code
 | 
		
	
		
			
			| 152 | 300 |   */
 | 
		
	
		
			
			| 153 |  | -static int kernel_exec ( int argc, char **argv ) {
 | 
		
	
		
			
			| 154 |  | -	return fetch_exec_name ( argc, argv, "kernel" );
 | 
		
	
		
			
			|  | 301 | +static int imgexec_exec ( int argc, char **argv ) {
 | 
		
	
		
			
			|  | 302 | +	static struct option longopts[] = {
 | 
		
	
		
			
			|  | 303 | +		{ "help", 0, NULL, 'h' },
 | 
		
	
		
			
			|  | 304 | +		{ NULL, 0, NULL, 0 },
 | 
		
	
		
			
			|  | 305 | +	};
 | 
		
	
		
			
			|  | 306 | +	struct image *image;
 | 
		
	
		
			
			|  | 307 | +	const char *name;
 | 
		
	
		
			
			|  | 308 | +	int c;
 | 
		
	
		
			
			|  | 309 | +	int rc;
 | 
		
	
		
			
			|  | 310 | +
 | 
		
	
		
			
			|  | 311 | +	/* Parse options */
 | 
		
	
		
			
			|  | 312 | +	while ( ( c = getopt_long ( argc, argv, "h", longopts, NULL ) ) >= 0 ){
 | 
		
	
		
			
			|  | 313 | +		switch ( c ) {
 | 
		
	
		
			
			|  | 314 | +		case 'h':
 | 
		
	
		
			
			|  | 315 | +			/* Display help text */
 | 
		
	
		
			
			|  | 316 | +		default:
 | 
		
	
		
			
			|  | 317 | +			/* Unrecognised/invalid option */
 | 
		
	
		
			
			|  | 318 | +			imgexec_syntax ( argv );
 | 
		
	
		
			
			|  | 319 | +			return 1;
 | 
		
	
		
			
			|  | 320 | +		}
 | 
		
	
		
			
			|  | 321 | +	}
 | 
		
	
		
			
			|  | 322 | +
 | 
		
	
		
			
			|  | 323 | +	/* Need exactly one image name */
 | 
		
	
		
			
			|  | 324 | +	if ( optind != ( argc - 1 ) ) {
 | 
		
	
		
			
			|  | 325 | +		imgexec_syntax ( argv );
 | 
		
	
		
			
			|  | 326 | +		return 1;
 | 
		
	
		
			
			|  | 327 | +	}
 | 
		
	
		
			
			|  | 328 | +	name = argv[optind];
 | 
		
	
		
			
			|  | 329 | +	
 | 
		
	
		
			
			|  | 330 | +	/* Execute specified image */
 | 
		
	
		
			
			|  | 331 | +	image = find_image ( name );
 | 
		
	
		
			
			|  | 332 | +	if ( ! image ) {
 | 
		
	
		
			
			|  | 333 | +		printf ( "No such image: %s\n", name );
 | 
		
	
		
			
			|  | 334 | +		return 1;
 | 
		
	
		
			
			|  | 335 | +	}
 | 
		
	
		
			
			|  | 336 | +	if ( ( rc = imgexec ( image ) ) != 0 ) {
 | 
		
	
		
			
			|  | 337 | +		printf ( "Could not execute %s: %s\n", name, strerror ( rc ) );
 | 
		
	
		
			
			|  | 338 | +		return 1;
 | 
		
	
		
			
			|  | 339 | +	}
 | 
		
	
		
			
			|  | 340 | +
 | 
		
	
		
			
			|  | 341 | +	return 0;
 | 
		
	
		
			
			| 155 | 342 |  }
 | 
		
	
		
			
			| 156 | 343 |  
 | 
		
	
		
			
			| 157 | 344 |  /**
 | 
		
	
	
		
			
			|  | @@ -174,7 +361,7 @@ static void imgstat_syntax ( char **argv ) {
 | 
		
	
		
			
			| 174 | 361 |   * @v argv		Argument list
 | 
		
	
		
			
			| 175 | 362 |   * @ret rc		Exit code
 | 
		
	
		
			
			| 176 | 363 |   */
 | 
		
	
		
			
			| 177 |  | -static int imgstat_exec ( int argc __unused, char **argv __unused ) {
 | 
		
	
		
			
			|  | 364 | +static int imgstat_exec ( int argc, char **argv ) {
 | 
		
	
		
			
			| 178 | 365 |  	static struct option longopts[] = {
 | 
		
	
		
			
			| 179 | 366 |  		{ "help", 0, NULL, 'h' },
 | 
		
	
		
			
			| 180 | 367 |  		{ NULL, 0, NULL, 0 },
 | 
		
	
	
		
			
			|  | @@ -194,7 +381,7 @@ static int imgstat_exec ( int argc __unused, char **argv __unused ) {
 | 
		
	
		
			
			| 194 | 381 |  		}
 | 
		
	
		
			
			| 195 | 382 |  	}
 | 
		
	
		
			
			| 196 | 383 |  
 | 
		
	
		
			
			| 197 |  | -	/* Need at least a filename remaining after the options */
 | 
		
	
		
			
			|  | 384 | +	/* No arguments */
 | 
		
	
		
			
			| 198 | 385 |  	if ( optind != argc ) {
 | 
		
	
		
			
			| 199 | 386 |  		imgstat_syntax ( argv );
 | 
		
	
		
			
			| 200 | 387 |  		return 1;
 | 
		
	
	
		
			
			|  | @@ -207,22 +394,93 @@ static int imgstat_exec ( int argc __unused, char **argv __unused ) {
 | 
		
	
		
			
			| 207 | 394 |  	return 0;
 | 
		
	
		
			
			| 208 | 395 |  }
 | 
		
	
		
			
			| 209 | 396 |  
 | 
		
	
		
			
			|  | 397 | +/**
 | 
		
	
		
			
			|  | 398 | + * "imgstat" command syntax message
 | 
		
	
		
			
			|  | 399 | + *
 | 
		
	
		
			
			|  | 400 | + * @v argv		Argument list
 | 
		
	
		
			
			|  | 401 | + */
 | 
		
	
		
			
			|  | 402 | +static void imgfree_syntax ( char **argv ) {
 | 
		
	
		
			
			|  | 403 | +	printf ( "Usage:\n"
 | 
		
	
		
			
			|  | 404 | +		 "  %s\n"
 | 
		
	
		
			
			|  | 405 | +		 "\n"
 | 
		
	
		
			
			|  | 406 | +		 "Free all executable/loadable images\n",
 | 
		
	
		
			
			|  | 407 | +		 argv[0] );
 | 
		
	
		
			
			|  | 408 | +}
 | 
		
	
		
			
			|  | 409 | +
 | 
		
	
		
			
			|  | 410 | +/**
 | 
		
	
		
			
			|  | 411 | + * The "imgfree" command
 | 
		
	
		
			
			|  | 412 | + *
 | 
		
	
		
			
			|  | 413 | + * @v argc		Argument count
 | 
		
	
		
			
			|  | 414 | + * @v argv		Argument list
 | 
		
	
		
			
			|  | 415 | + * @ret rc		Exit code
 | 
		
	
		
			
			|  | 416 | + */
 | 
		
	
		
			
			|  | 417 | +static int imgfree_exec ( int argc, char **argv ) {
 | 
		
	
		
			
			|  | 418 | +	static struct option longopts[] = {
 | 
		
	
		
			
			|  | 419 | +		{ "help", 0, NULL, 'h' },
 | 
		
	
		
			
			|  | 420 | +		{ NULL, 0, NULL, 0 },
 | 
		
	
		
			
			|  | 421 | +	};
 | 
		
	
		
			
			|  | 422 | +	struct image *image;
 | 
		
	
		
			
			|  | 423 | +	struct image *tmp;
 | 
		
	
		
			
			|  | 424 | +	int c;
 | 
		
	
		
			
			|  | 425 | +
 | 
		
	
		
			
			|  | 426 | +	/* Parse options */
 | 
		
	
		
			
			|  | 427 | +	while ( ( c = getopt_long ( argc, argv, "h", longopts, NULL ) ) >= 0 ){
 | 
		
	
		
			
			|  | 428 | +		switch ( c ) {
 | 
		
	
		
			
			|  | 429 | +		case 'h':
 | 
		
	
		
			
			|  | 430 | +			/* Display help text */
 | 
		
	
		
			
			|  | 431 | +		default:
 | 
		
	
		
			
			|  | 432 | +			/* Unrecognised/invalid option */
 | 
		
	
		
			
			|  | 433 | +			imgfree_syntax ( argv );
 | 
		
	
		
			
			|  | 434 | +			return 1;
 | 
		
	
		
			
			|  | 435 | +		}
 | 
		
	
		
			
			|  | 436 | +	}
 | 
		
	
		
			
			|  | 437 | +
 | 
		
	
		
			
			|  | 438 | +	/* No arguments */
 | 
		
	
		
			
			|  | 439 | +	if ( optind != argc ) {
 | 
		
	
		
			
			|  | 440 | +		imgfree_syntax ( argv );
 | 
		
	
		
			
			|  | 441 | +		return 1;
 | 
		
	
		
			
			|  | 442 | +	}
 | 
		
	
		
			
			|  | 443 | +
 | 
		
	
		
			
			|  | 444 | +	/* Free all images */
 | 
		
	
		
			
			|  | 445 | +	list_for_each_entry_safe ( image, tmp, &images, list ) {
 | 
		
	
		
			
			|  | 446 | +		imgfree ( image );
 | 
		
	
		
			
			|  | 447 | +	}
 | 
		
	
		
			
			|  | 448 | +	return 0;
 | 
		
	
		
			
			|  | 449 | +}
 | 
		
	
		
			
			|  | 450 | +
 | 
		
	
		
			
			|  | 451 | +
 | 
		
	
		
			
			| 210 | 452 |  /** Image management commands */
 | 
		
	
		
			
			| 211 | 453 |  struct command image_commands[] __command = {
 | 
		
	
		
			
			| 212 | 454 |  	{
 | 
		
	
		
			
			| 213 |  | -		.name = "fetch",
 | 
		
	
		
			
			| 214 |  | -		.exec = fetch_exec,
 | 
		
	
		
			
			|  | 455 | +		.name = "imgfetch",
 | 
		
	
		
			
			|  | 456 | +		.exec = imgfetch_exec,
 | 
		
	
		
			
			| 215 | 457 |  	},
 | 
		
	
		
			
			| 216 | 458 |  	{
 | 
		
	
		
			
			| 217 | 459 |  		.name = "module",
 | 
		
	
		
			
			| 218 |  | -		.exec = fetch_exec, /* synonym for "fetch" */
 | 
		
	
		
			
			|  | 460 | +		.exec = imgfetch_exec, /* synonym for "imgfetch" */
 | 
		
	
		
			
			| 219 | 461 |  	},
 | 
		
	
		
			
			| 220 | 462 |  	{
 | 
		
	
		
			
			| 221 | 463 |  		.name = "kernel",
 | 
		
	
		
			
			| 222 | 464 |  		.exec = kernel_exec,
 | 
		
	
		
			
			| 223 | 465 |  	},
 | 
		
	
		
			
			|  | 466 | +	{
 | 
		
	
		
			
			|  | 467 | +		.name = "imgload",
 | 
		
	
		
			
			|  | 468 | +		.exec = imgload_exec,
 | 
		
	
		
			
			|  | 469 | +	},
 | 
		
	
		
			
			|  | 470 | +	{
 | 
		
	
		
			
			|  | 471 | +		.name = "imgargs",
 | 
		
	
		
			
			|  | 472 | +		.exec = imgargs_exec,
 | 
		
	
		
			
			|  | 473 | +	},
 | 
		
	
		
			
			|  | 474 | +	{
 | 
		
	
		
			
			|  | 475 | +		.name = "imgexec",
 | 
		
	
		
			
			|  | 476 | +		.exec = imgexec_exec,
 | 
		
	
		
			
			|  | 477 | +	},
 | 
		
	
		
			
			| 224 | 478 |  	{
 | 
		
	
		
			
			| 225 | 479 |  		.name = "imgstat",
 | 
		
	
		
			
			| 226 | 480 |  		.exec = imgstat_exec,
 | 
		
	
		
			
			| 227 | 481 |  	},
 | 
		
	
		
			
			|  | 482 | +	{
 | 
		
	
		
			
			|  | 483 | +		.name = "imgfree",
 | 
		
	
		
			
			|  | 484 | +		.exec = imgfree_exec,
 | 
		
	
		
			
			|  | 485 | +	},
 | 
		
	
		
			
			| 228 | 486 |  };
 |