2 * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>.
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * License, or any later version.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 * You can also choose to distribute this program under the terms of
20 * the Unmodified Binary Distribution Licence (as given in the file
21 * COPYING.UBDL), provided that you have satisfied its requirements.
24 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
31 #include <ipxe/image.h>
32 #include <ipxe/command.h>
33 #include <ipxe/parseopt.h>
34 #include <ipxe/shell.h>
35 #include <usr/imgmgmt.h>
39 * Image management commands
43 /** "img{single}" options */
44 struct imgsingle_options {
47 /** Download timeout */
48 unsigned long timeout;
51 /** Free image after execution */
55 /** "img{single}" option list */
57 /* "imgexec" takes all three options */
58 struct option_descriptor imgexec[4];
59 /* Other "img{single}" commands take only --name, --timeout,
62 struct option_descriptor imgsingle[3];
65 OPTION_DESC ( "name", 'n', required_argument,
66 struct imgsingle_options, name, parse_string ),
67 OPTION_DESC ( "timeout", 't', required_argument,
68 struct imgsingle_options, timeout, parse_timeout),
69 OPTION_DESC ( "autofree", 'a', no_argument,
70 struct imgsingle_options, autofree, parse_flag ),
71 OPTION_DESC ( "replace", 'r', no_argument,
72 struct imgsingle_options, replace, parse_flag ),
76 /** An "img{single}" family command descriptor */
77 struct imgsingle_descriptor {
78 /** Command descriptor */
79 struct command_descriptor *cmd;
80 /** Function to use to acquire the image */
81 int ( * acquire ) ( const char *name, unsigned long timeout,
82 struct image **image );
83 /** Pre-action to take upon image, or NULL */
84 void ( * preaction ) ( struct image *image );
85 /** Action to take upon image, or NULL */
86 int ( * action ) ( struct image *image,
87 struct imgsingle_options *opts );
88 /** Verb to describe action */
93 * The "img{single}" family of commands
95 * @v argc Argument count
96 * @v argv Argument list
97 * @v desc "img{single}" command descriptor
98 * @v action_name Action name (for error messages)
99 * @v action Action to take upon image
100 * @ret rc Return status code
102 static int imgsingle_exec ( int argc, char **argv,
103 struct imgsingle_descriptor *desc ) {
104 struct imgsingle_options opts;
105 char *name_uri = NULL;
106 char *cmdline = NULL;
111 if ( ( rc = parse_options ( argc, argv, desc->cmd, &opts ) ) != 0 )
112 goto err_parse_options;
114 /* Parse name/URI string and command line, if present */
115 if ( optind < argc ) {
116 name_uri = argv[optind];
117 if ( argv[ optind + 1 ] != NULL ) {
118 cmdline = concat_args ( &argv[ optind + 1 ] );
121 goto err_parse_cmdline;
126 /* Acquire the image */
128 if ( ( rc = desc->acquire ( name_uri, opts.timeout,
132 image = image_find_selected();
134 printf ( "No image selected\n" );
139 /* Carry out command pre-action, if applicable */
140 if ( desc->preaction )
141 desc->preaction ( image );
143 /* Set the image name, if applicable */
145 if ( ( rc = image_set_name ( image, opts.name ) ) != 0 ) {
146 printf ( "Could not name image: %s\n",
152 /* Set the command-line arguments, if applicable */
154 if ( ( rc = image_set_cmdline ( image, cmdline ) ) != 0 ) {
155 printf ( "Could not set arguments: %s\n",
157 goto err_set_cmdline;
161 /* Set the auto-unregister flag, if applicable */
163 image->flags |= IMAGE_AUTO_UNREGISTER;
165 /* Carry out command action, if applicable */
166 if ( desc->action ) {
167 if ( ( rc = desc->action ( image, &opts ) ) != 0 ) {
168 printf ( "Could not %s: %s\n",
169 desc->verb, strerror ( rc ) );
187 /** "imgfetch" command descriptor */
188 static struct command_descriptor imgfetch_cmd =
189 COMMAND_DESC ( struct imgsingle_options, opts.imgsingle,
190 1, MAX_ARGUMENTS, "<uri> [<arguments>...]" );
192 /** "imgfetch" family command descriptor */
193 struct imgsingle_descriptor imgfetch_desc = {
194 .cmd = &imgfetch_cmd,
195 .acquire = imgdownload_string,
199 * The "imgfetch" command
201 * @v argc Argument count
202 * @v argv Argument list
203 * @ret rc Return status code
205 static int imgfetch_exec ( int argc, char **argv ) {
206 return imgsingle_exec ( argc, argv, &imgfetch_desc );
210 * "imgselect" command action
214 * @ret rc Return status code
216 static int imgselect ( struct image *image,
217 struct imgsingle_options *opts __unused ) {
218 return image_select ( image );
221 /** "imgselect" command descriptor */
222 static struct command_descriptor imgselect_cmd =
223 COMMAND_DESC ( struct imgsingle_options, opts.imgsingle,
224 1, MAX_ARGUMENTS, "<uri|image> [<arguments>...]" );
226 /** "imgselect" family command descriptor */
227 struct imgsingle_descriptor imgselect_desc = {
228 .cmd = &imgselect_cmd,
229 .acquire = imgacquire,
235 * The "imgselect" command
237 * @v argc Argument count
238 * @v argv Argument list
239 * @ret rc Return status code
241 static int imgselect_exec ( int argc, char **argv ) {
242 return imgsingle_exec ( argc, argv, &imgselect_desc );
245 /** "imgexec" command descriptor */
246 static struct command_descriptor imgexec_cmd =
247 COMMAND_DESC ( struct imgsingle_options, opts.imgexec,
248 0, MAX_ARGUMENTS, "[<uri|image> [<arguments>...]]" );
251 * "imgexec" command action
255 * @ret rc Return status code
257 static int imgexec ( struct image *image, struct imgsingle_options *opts ) {
260 /* Perform replacement or execution as applicable */
261 if ( opts->replace ) {
263 /* Try to replace image */
264 if ( ( rc = image_replace ( image ) ) != 0 )
267 /* Stop script and tail-recurse into replacement image */
268 shell_stop ( SHELL_STOP_COMMAND_SEQUENCE );
272 /* Try to execute image */
273 if ( ( rc = image_exec ( image ) ) != 0 )
280 /** "imgexec" family command descriptor */
281 struct imgsingle_descriptor imgexec_desc = {
283 .acquire = imgacquire,
289 * The "imgexec" command
291 * @v argc Argument count
292 * @v argv Argument list
293 * @ret rc Return status code
295 static int imgexec_exec ( int argc, char **argv) {
296 return imgsingle_exec ( argc, argv, &imgexec_desc );
299 /** "imgargs" command descriptor */
300 static struct command_descriptor imgargs_cmd =
301 COMMAND_DESC ( struct imgsingle_options, opts.imgsingle,
302 1, MAX_ARGUMENTS, "<uri|image> [<arguments>...]" );
304 /** "imgargs" family command descriptor */
305 struct imgsingle_descriptor imgargs_desc = {
307 .acquire = imgacquire,
308 .preaction = image_clear_cmdline,
312 * The "imgargs" command body
314 * @v argc Argument count
315 * @v argv Argument list
316 * @ret rc Return status code
318 static int imgargs_exec ( int argc, char **argv ) {
319 return imgsingle_exec ( argc, argv, &imgargs_desc );
322 /** "img{multi}" options */
323 struct imgmulti_options {};
325 /** "img{multi}" option list */
326 static struct option_descriptor imgmulti_opts[] = {};
328 /** "img{multi}" command descriptor */
329 static struct command_descriptor imgmulti_cmd =
330 COMMAND_DESC ( struct imgmulti_options, imgmulti_opts, 0, MAX_ARGUMENTS,
334 * The "img{multi}" family of commands
336 * @v argc Argument count
337 * @v argv Argument list
338 * @v payload Function to execute on each image
339 * @ret rc Return status code
341 static int imgmulti_exec ( int argc, char **argv,
342 void ( * payload ) ( struct image *image ) ) {
343 struct imgmulti_options opts;
350 if ( ( rc = parse_options ( argc, argv, &imgmulti_cmd, &opts ) ) != 0 )
353 /* If no images are explicitly specified, process all images */
354 if ( optind == argc ) {
355 for_each_image_safe ( image, tmp )
360 /* Otherwise, process specified images */
361 for ( i = optind ; i < argc ; i++ ) {
362 image = find_image ( argv[i] );
364 printf ( "\"%s\": no such image\n", argv[i] );
374 * The "imgstat" command
376 * @v argc Argument count
377 * @v argv Argument list
378 * @ret rc Return status code
380 static int imgstat_exec ( int argc, char **argv ) {
381 return imgmulti_exec ( argc, argv, imgstat );
385 * The "imgfree" command
387 * @v argc Argument count
388 * @v argv Argument list
389 * @ret rc Return status code
391 static int imgfree_exec ( int argc, char **argv ) {
392 return imgmulti_exec ( argc, argv, unregister_image );
395 /** Image management commands */
396 struct command image_commands[] __command = {
399 .exec = imgfetch_exec,
403 .exec = imgfetch_exec, /* synonym for "imgfetch" */
407 .exec = imgfetch_exec, /* synonym for "imgfetch" */
411 .exec = imgselect_exec, /* synonym for "imgselect" */
415 .exec = imgexec_exec, /* synonym for "imgexec" */
419 .exec = imgselect_exec,
423 .exec = imgselect_exec, /* synonym for "imgselect" */
427 .exec = imgargs_exec,
431 .exec = imgexec_exec,
434 .name = "boot", /* synonym for "imgexec" */
435 .exec = imgexec_exec,
439 .exec = imgstat_exec,
443 .exec = imgfree_exec,