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,