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., 675 Mass Ave, Cambridge, MA 02139, USA.
19 FILE_LICENCE ( GPL2_OR_LATER
);
27 #include <gpxe/image.h>
28 #include <gpxe/command.h>
29 #include <usr/imgmgmt.h>
33 * Image management commands
44 * Fill in image command line
47 * @v nargs Argument count
48 * @v args Argument list
49 * @ret rc Return status code
51 static int imgfill_cmdline ( struct image
*image
, unsigned int nargs
,
56 /* Determine total length of command line */
58 for ( i
= 0 ; i
< nargs
; i
++ )
59 len
+= ( 1 /* possible space */ + strlen ( args
[i
] ) );
65 /* Assemble command line */
67 for ( i
= 0 ; i
< nargs
; i
++ ) {
68 ptr
+= sprintf ( ptr
, "%s%s", ( i
? " " : "" ),
71 assert ( ptr
< ( buf
+ len
) );
73 return image_set_cmdline ( image
, buf
);
78 * "imgfetch"/"module"/"kernel" command syntax message
80 * @v argv Argument list
82 static void imgfetch_core_syntax ( char **argv
, enum image_action action
) {
83 static const char *actions
[] = {
84 [IMG_FETCH
] = "Fetch",
85 [IMG_LOAD
] = "Fetch and load",
86 [IMG_EXEC
] = "Fetch and execute",
90 " %s [-n|--name <name>] filename [arguments...]\n"
92 "%s executable/loadable image\n",
93 argv
[0], actions
[action
] );
97 * The "imgfetch"/"module"/"kernel" command body
99 * @v image_type Image type to assign (or NULL)
100 * @v load Image will be automatically loaded after fetching
101 * @v argc Argument count
102 * @v argv Argument list
103 * @ret rc Return status code
105 static int imgfetch_core_exec ( struct image_type
*image_type
,
106 enum image_action action
,
107 int argc
, char **argv
) {
108 static struct option longopts
[] = {
109 { "help", 0, NULL
, 'h' },
110 { "name", required_argument
, NULL
, 'n' },
111 { NULL
, 0, NULL
, 0 },
114 const char *name
= NULL
;
116 int ( * image_register
) ( struct image
*image
);
121 while ( ( c
= getopt_long ( argc
, argv
, "hn:",
122 longopts
, NULL
) ) >= 0 ) {
129 /* Display help text */
131 /* Unrecognised/invalid option */
132 imgfetch_core_syntax ( argv
, action
);
137 /* Need at least a filename remaining after the options */
138 if ( optind
== argc
) {
139 imgfetch_core_syntax ( argv
, action
);
142 filename
= argv
[optind
++];
144 name
= basename ( filename
);
147 image
= alloc_image();
149 printf ( "%s\n", strerror ( -ENOMEM
) );
153 /* Fill in image name */
155 if ( ( rc
= image_set_name ( image
, name
) ) != 0 )
159 /* Set image type (if specified) */
160 image
->type
= image_type
;
162 /* Fill in command line */
163 if ( ( rc
= imgfill_cmdline ( image
, ( argc
- optind
),
164 &argv
[optind
] ) ) != 0 )
167 /* Fetch the image */
170 image_register
= register_image
;
173 image_register
= register_and_autoload_image
;
176 image_register
= register_and_autoexec_image
;
182 if ( ( rc
= imgfetch ( image
, filename
, image_register
) ) != 0 ) {
183 printf ( "Could not fetch %s: %s\n",
184 filename
, strerror ( rc
) );
194 * The "imgfetch"/"module" command
196 * @v argc Argument count
197 * @v argv Argument list
200 static int imgfetch_exec ( int argc
, char **argv
) {
203 if ( ( rc
= imgfetch_core_exec ( NULL
, IMG_FETCH
,
204 argc
, argv
) ) != 0 )
211 * The "kernel" command
213 * @v argc Argument count
214 * @v argv Argument list
217 static int kernel_exec ( int argc
, char **argv
) {
220 if ( ( rc
= imgfetch_core_exec ( NULL
, IMG_LOAD
, argc
, argv
) ) != 0 )
227 * The "chain" command
229 * @v argc Argument count
230 * @v argv Argument list
233 static int chain_exec ( int argc
, char **argv
) {
236 if ( ( rc
= imgfetch_core_exec ( NULL
, IMG_EXEC
, argc
, argv
) ) != 0 )
243 * "imgload" command syntax message
245 * @v argv Argument list
247 static void imgload_syntax ( char **argv
) {
251 "Load executable/loadable image\n",
256 * The "imgload" command
258 * @v argc Argument count
259 * @v argv Argument list
262 static int imgload_exec ( int argc
, char **argv
) {
263 static struct option longopts
[] = {
264 { "help", 0, NULL
, 'h' },
265 { NULL
, 0, NULL
, 0 },
273 while ( ( c
= getopt_long ( argc
, argv
, "h", longopts
, NULL
) ) >= 0 ){
276 /* Display help text */
278 /* Unrecognised/invalid option */
279 imgload_syntax ( argv
);
284 /* Need exactly one image name remaining after the options */
285 if ( optind
!= ( argc
- 1 ) ) {
286 imgload_syntax ( argv
);
291 /* Load all specified images */
292 image
= find_image ( name
);
294 printf ( "No such image: %s\n", name
);
297 if ( ( rc
= imgload ( image
) ) != 0 ) {
298 printf ( "Could not load %s: %s\n", name
, strerror ( rc
) );
306 * "imgargs" command syntax message
308 * @v argv Argument list
310 static void imgargs_syntax ( char **argv
) {
312 " %s <image name> [<arguments>...]\n"
314 "Set arguments for executable/loadable image\n",
319 * The "imgargs" command body
321 * @v argc Argument count
322 * @v argv Argument list
325 static int imgargs_exec ( int argc
, char **argv
) {
326 static struct option longopts
[] = {
327 { "help", 0, NULL
, 'h' },
328 { NULL
, 0, NULL
, 0 },
336 while ( ( c
= getopt_long ( argc
, argv
, "h", longopts
, NULL
) ) >= 0 ){
339 /* Display help text */
341 /* Unrecognised/invalid option */
342 imgargs_syntax ( argv
);
347 /* Need at least an image name remaining after the options */
348 if ( optind
== argc
) {
349 imgargs_syntax ( argv
);
352 name
= argv
[optind
++];
354 /* Fill in command line */
355 image
= find_image ( name
);
357 printf ( "No such image: %s\n", name
);
360 if ( ( rc
= imgfill_cmdline ( image
, ( argc
- optind
),
361 &argv
[optind
] ) ) != 0 )
369 * "imgexec" command syntax message
371 * @v argv Argument list
373 static void imgexec_syntax ( char **argv
) {
377 "Execute executable/loadable image\n",
382 * The "imgexec" command
384 * @v argc Argument count
385 * @v argv Argument list
388 static int imgexec_exec ( int argc
, char **argv
) {
389 static struct option longopts
[] = {
390 { "help", 0, NULL
, 'h' },
391 { NULL
, 0, NULL
, 0 },
394 const char *name
= NULL
;
399 while ( ( c
= getopt_long ( argc
, argv
, "h", longopts
, NULL
) ) >= 0 ){
402 /* Display help text */
404 /* Unrecognised/invalid option */
405 imgexec_syntax ( argv
);
410 /* Need no more than one image name */
411 if ( optind
!= argc
)
412 name
= argv
[optind
++];
413 if ( optind
!= argc
) {
414 imgexec_syntax ( argv
);
418 /* Execute specified image */
420 image
= find_image ( name
);
422 printf ( "No such image: %s\n", name
);
426 image
= imgautoselect();
428 printf ( "No (unique) loaded image\n" );
433 if ( ( rc
= imgexec ( image
) ) != 0 ) {
434 printf ( "Could not execute %s: %s\n",
435 image
->name
, strerror ( rc
) );
443 * "imgstat" command syntax message
445 * @v argv Argument list
447 static void imgstat_syntax ( char **argv
) {
451 "List executable/loadable images\n",
456 * The "imgstat" command
458 * @v argc Argument count
459 * @v argv Argument list
462 static int imgstat_exec ( int argc
, char **argv
) {
463 static struct option longopts
[] = {
464 { "help", 0, NULL
, 'h' },
465 { NULL
, 0, NULL
, 0 },
471 while ( ( c
= getopt_long ( argc
, argv
, "h", longopts
, NULL
) ) >= 0 ){
474 /* Display help text */
476 /* Unrecognised/invalid option */
477 imgstat_syntax ( argv
);
483 if ( optind
!= argc
) {
484 imgstat_syntax ( argv
);
488 /* Show status of all images */
489 for_each_image ( image
) {
496 * "imgstat" command syntax message
498 * @v argv Argument list
500 static void imgfree_syntax ( char **argv
) {
502 " %s [<image name>]\n"
504 "Free one or all executable/loadable images\n",
509 * The "imgfree" command
511 * @v argc Argument count
512 * @v argv Argument list
515 static int imgfree_exec ( int argc
, char **argv
) {
516 static struct option longopts
[] = {
517 { "help", 0, NULL
, 'h' },
518 { NULL
, 0, NULL
, 0 },
522 const char *name
= NULL
;
526 while ( ( c
= getopt_long ( argc
, argv
, "h", longopts
, NULL
) ) >= 0 ){
529 /* Display help text */
531 /* Unrecognised/invalid option */
532 imgfree_syntax ( argv
);
537 /* Need no more than one image name */
538 if ( optind
!= argc
)
539 name
= argv
[optind
++];
540 if ( optind
!= argc
) {
541 imgfree_syntax ( argv
);
546 /* Free specified image (may leak) */
547 image
= find_image ( name
);
549 printf ( "No such image: %s\n", name
);
554 /* Free all images */
555 list_for_each_entry_safe ( image
, tmp
, &images
, list
) {
562 /** Image management commands */
563 struct command image_commands
[] __command
= {
566 .exec
= imgfetch_exec
,
570 .exec
= imgfetch_exec
, /* synonym for "imgfetch" */
574 .exec
= imgfetch_exec
, /* synonym for "imgfetch" */
586 .exec
= imgload_exec
,
590 .exec
= imgargs_exec
,
594 .exec
= imgexec_exec
,
597 .name
= "boot", /* synonym for "imgexec" */
598 .exec
= imgexec_exec
,
602 .exec
= imgstat_exec
,
606 .exec
= imgfree_exec
,