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
,