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
20 FILE_LICENCE ( GPL2_OR_LATER );
27 #include <ipxe/image.h>
28 #include <ipxe/command.h>
29 #include <ipxe/parseopt.h>
30 #include <ipxe/shell.h>
31 #include <usr/imgmgmt.h>
35 * Image management commands
39 /** "img{single}" options */
40 struct imgsingle_options {
45 /** Free image after execution */
49 /** "img{single}" option list */
50 static struct option_descriptor imgsingle_opts[] = {
51 OPTION_DESC ( "name", 'n', required_argument,
52 struct imgsingle_options, name, parse_string ),
53 OPTION_DESC ( "replace", 'r', no_argument,
54 struct imgsingle_options, replace, parse_flag ),
55 OPTION_DESC ( "autofree", 'a', no_argument,
56 struct imgsingle_options, autofree, parse_flag ),
59 /** "img{single}" command descriptor */
60 static struct command_descriptor imgsingle_cmd =
61 COMMAND_DESC ( struct imgsingle_options, imgsingle_opts,
63 "[--name <name>] [--autofree] "
64 "<uri|image> [<arguments>...]" );
66 /** An "img{single}" family command descriptor */
67 struct imgsingle_descriptor {
68 /** Command descriptor */
69 struct command_descriptor *cmd;
70 /** Function to use to acquire the image */
71 int ( * acquire ) ( const char *name, struct image **image );
72 /** Pre-action to take upon image, or NULL */
73 void ( * preaction ) ( struct image *image );
74 /** Action to take upon image, or NULL */
75 int ( * action ) ( struct image *image,
76 struct imgsingle_options *opts );
77 /** Verb to describe action */
82 * The "img{single}" family of commands
84 * @v argc Argument count
85 * @v argv Argument list
86 * @v desc "img{single}" command descriptor
87 * @v action_name Action name (for error messages)
88 * @v action Action to take upon image
89 * @ret rc Return status code
91 static int imgsingle_exec ( int argc, char **argv,
92 struct imgsingle_descriptor *desc ) {
93 struct imgsingle_options opts;
94 char *name_uri = NULL;
100 if ( ( rc = parse_options ( argc, argv, desc->cmd, &opts ) ) != 0 )
101 goto err_parse_options;
103 /* Parse name/URI string and command line, if present */
104 if ( optind < argc ) {
105 name_uri = argv[optind];
106 if ( argv[ optind + 1 ] != NULL ) {
107 cmdline = concat_args ( &argv[ optind + 1 ] );
110 goto err_parse_cmdline;
115 /* Acquire the image */
117 if ( ( rc = desc->acquire ( name_uri, &image ) ) != 0 )
120 image = image_find_selected();
122 printf ( "No image selected\n" );
127 /* Carry out command pre-action, if applicable */
128 if ( desc->preaction )
129 desc->preaction ( image );
131 /* Set the image name, if applicable */
133 if ( ( rc = image_set_name ( image, opts.name ) ) != 0 ) {
134 printf ( "Could not name image: %s\n",
140 /* Set the command-line arguments, if applicable */
142 if ( ( rc = image_set_cmdline ( image, cmdline ) ) != 0 ) {
143 printf ( "Could not set arguments: %s\n",
145 goto err_set_cmdline;
149 /* Set the auto-unregister flag, if applicable */
151 image->flags |= IMAGE_AUTO_UNREGISTER;
153 /* Carry out command action, if applicable */
154 if ( desc->action ) {
155 if ( ( rc = desc->action ( image, &opts ) ) != 0 ) {
156 printf ( "Could not %s: %s\n",
157 desc->verb, strerror ( rc ) );
175 /** "imgfetch" command descriptor */
176 static struct command_descriptor imgfetch_cmd =
177 COMMAND_DESC ( struct imgsingle_options, imgsingle_opts,
179 "[--name <name>] [--autofree] <uri> [<arguments>...]" );
181 /** "imgfetch" family command descriptor */
182 struct imgsingle_descriptor imgfetch_desc = {
183 .cmd = &imgfetch_cmd,
184 .acquire = imgdownload_string,
188 * The "imgfetch" command
190 * @v argc Argument count
191 * @v argv Argument list
192 * @ret rc Return status code
194 static int imgfetch_exec ( int argc, char **argv ) {
195 return imgsingle_exec ( argc, argv, &imgfetch_desc );
199 * "imgselect" command action
203 * @ret rc Return status code
205 static int imgselect ( struct image *image,
206 struct imgsingle_options *opts __unused ) {
207 return image_select ( image );
210 /** "imgselect" family command descriptor */
211 struct imgsingle_descriptor imgselect_desc = {
212 .cmd = &imgsingle_cmd,
213 .acquire = imgacquire,
219 * The "imgselect" command
221 * @v argc Argument count
222 * @v argv Argument list
223 * @ret rc Return status code
225 static int imgselect_exec ( int argc, char **argv ) {
226 return imgsingle_exec ( argc, argv, &imgselect_desc );
229 /** "imgexec" command descriptor */
230 static struct command_descriptor imgexec_cmd =
231 COMMAND_DESC ( struct imgsingle_options, imgsingle_opts,
233 "[--autofree] [--replace] "
234 "[<uri|image> [<arguments>...]]" );
237 * "imgexec" command action
241 * @ret rc Return status code
243 static int imgexec ( struct image *image, struct imgsingle_options *opts ) {
246 /* Perform replacement or execution as applicable */
247 if ( opts->replace ) {
249 /* Try to replace image */
250 if ( ( rc = image_replace ( image ) ) != 0 )
253 /* Stop script and tail-recurse into replacement image */
254 shell_stop ( SHELL_STOP_COMMAND_SEQUENCE );
258 /* Try to execute image */
259 if ( ( rc = image_exec ( image ) ) != 0 )
266 /** "imgexec" family command descriptor */
267 struct imgsingle_descriptor imgexec_desc = {
269 .acquire = imgacquire,
275 * The "imgexec" command
277 * @v argc Argument count
278 * @v argv Argument list
279 * @ret rc Return status code
281 static int imgexec_exec ( int argc, char **argv) {
282 return imgsingle_exec ( argc, argv, &imgexec_desc );
285 /** "imgargs" family command descriptor */
286 struct imgsingle_descriptor imgargs_desc = {
287 .cmd = &imgsingle_cmd,
288 .acquire = imgacquire,
289 .preaction = image_clear_cmdline,
293 * The "imgargs" command body
295 * @v argc Argument count
296 * @v argv Argument list
297 * @ret rc Return status code
299 static int imgargs_exec ( int argc, char **argv ) {
300 return imgsingle_exec ( argc, argv, &imgargs_desc );
303 /** "img{multi}" options */
304 struct imgmulti_options {};
306 /** "img{multi}" option list */
307 static struct option_descriptor imgmulti_opts[] = {};
309 /** "img{multi}" command descriptor */
310 static struct command_descriptor imgmulti_cmd =
311 COMMAND_DESC ( struct imgmulti_options, imgmulti_opts, 0, MAX_ARGUMENTS,
315 * The "img{multi}" family of commands
317 * @v argc Argument count
318 * @v argv Argument list
319 * @v payload Function to execute on each image
320 * @ret rc Return status code
322 static int imgmulti_exec ( int argc, char **argv,
323 void ( * payload ) ( struct image *image ) ) {
324 struct imgmulti_options opts;
331 if ( ( rc = parse_options ( argc, argv, &imgmulti_cmd, &opts ) ) != 0 )
334 /* If no images are explicitly specified, process all images */
335 if ( optind == argc ) {
336 for_each_image_safe ( image, tmp )
341 /* Otherwise, process specified images */
342 for ( i = optind ; i < argc ; i++ ) {
343 image = find_image ( argv[i] );
345 printf ( "\"%s\": no such image\n", argv[i] );
355 * The "imgstat" command
357 * @v argc Argument count
358 * @v argv Argument list
359 * @ret rc Return status code
361 static int imgstat_exec ( int argc, char **argv ) {
362 return imgmulti_exec ( argc, argv, imgstat );
366 * The "imgfree" command
368 * @v argc Argument count
369 * @v argv Argument list
370 * @ret rc Return status code
372 static int imgfree_exec ( int argc, char **argv ) {
373 return imgmulti_exec ( argc, argv, unregister_image );
376 /** Image management commands */
377 struct command image_commands[] __command = {
380 .exec = imgfetch_exec,
384 .exec = imgfetch_exec, /* synonym for "imgfetch" */
388 .exec = imgfetch_exec, /* synonym for "imgfetch" */
392 .exec = imgselect_exec, /* synonym for "imgselect" */
396 .exec = imgexec_exec, /* synonym for "imgexec" */
400 .exec = imgselect_exec,
404 .exec = imgselect_exec, /* synonym for "imgselect" */
408 .exec = imgargs_exec,
412 .exec = imgexec_exec,
415 .name = "boot", /* synonym for "imgexec" */
416 .exec = imgexec_exec,
420 .exec = imgstat_exec,
424 .exec = imgfree_exec,