00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 FILE_LICENCE ( GPL2_OR_LATER );
00020
00021 #include <stdint.h>
00022 #include <stdlib.h>
00023 #include <stdio.h>
00024 #include <errno.h>
00025 #include <libgen.h>
00026 #include <getopt.h>
00027 #include <gpxe/image.h>
00028 #include <gpxe/command.h>
00029 #include <usr/imgmgmt.h>
00030
00031
00032
00033
00034
00035
00036
00037 enum image_action {
00038 IMG_FETCH = 0,
00039 IMG_LOAD,
00040 IMG_EXEC,
00041 };
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051 static int imgfill_cmdline ( struct image *image, unsigned int nargs,
00052 char **args ) {
00053 size_t len;
00054 unsigned int i;
00055
00056
00057 len = 1;
00058 for ( i = 0 ; i < nargs ; i++ )
00059 len += ( 1 + strlen ( args[i] ) );
00060
00061 {
00062 char buf[len];
00063 char *ptr = buf;
00064
00065
00066 buf[0] = '\0';
00067 for ( i = 0 ; i < nargs ; i++ ) {
00068 ptr += sprintf ( ptr, "%s%s", ( i ? " " : "" ),
00069 args[i] );
00070 }
00071 assert ( ptr < ( buf + len ) );
00072
00073 return image_set_cmdline ( image, buf );
00074 }
00075 }
00076
00077
00078
00079
00080
00081
00082 static void imgfetch_core_syntax ( char **argv, enum image_action action ) {
00083 static const char *actions[] = {
00084 [IMG_FETCH] = "Fetch",
00085 [IMG_LOAD] = "Fetch and load",
00086 [IMG_EXEC] = "Fetch and execute",
00087 };
00088
00089 printf ( "Usage:\n"
00090 " %s [-n|--name <name>] filename [arguments...]\n"
00091 "\n"
00092 "%s executable/loadable image\n",
00093 argv[0], actions[action] );
00094 }
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105 static int imgfetch_core_exec ( struct image_type *image_type,
00106 enum image_action action,
00107 int argc, char **argv ) {
00108 static struct option longopts[] = {
00109 { "help", 0, NULL, 'h' },
00110 { "name", required_argument, NULL, 'n' },
00111 { NULL, 0, NULL, 0 },
00112 };
00113 struct image *image;
00114 const char *name = NULL;
00115 char *filename;
00116 int ( * image_register ) ( struct image *image );
00117 int c;
00118 int rc;
00119
00120
00121 while ( ( c = getopt_long ( argc, argv, "hn:",
00122 longopts, NULL ) ) >= 0 ) {
00123 switch ( c ) {
00124 case 'n':
00125
00126 name = optarg;
00127 break;
00128 case 'h':
00129
00130 default:
00131
00132 imgfetch_core_syntax ( argv, action );
00133 return -EINVAL;
00134 }
00135 }
00136
00137
00138 if ( optind == argc ) {
00139 imgfetch_core_syntax ( argv, action );
00140 return -EINVAL;
00141 }
00142 filename = argv[optind++];
00143 if ( ! name )
00144 name = basename ( filename );
00145
00146
00147 image = alloc_image();
00148 if ( ! image ) {
00149 printf ( "%s\n", strerror ( -ENOMEM ) );
00150 return -ENOMEM;
00151 }
00152
00153
00154 if ( name ) {
00155 if ( ( rc = image_set_name ( image, name ) ) != 0 )
00156 return rc;
00157 }
00158
00159
00160 image->type = image_type;
00161
00162
00163 if ( ( rc = imgfill_cmdline ( image, ( argc - optind ),
00164 &argv[optind] ) ) != 0 )
00165 return rc;
00166
00167
00168 switch ( action ) {
00169 case IMG_FETCH:
00170 image_register = register_image;
00171 break;
00172 case IMG_LOAD:
00173 image_register = register_and_autoload_image;
00174 break;
00175 case IMG_EXEC:
00176 image_register = register_and_autoexec_image;
00177 break;
00178 default:
00179 assert ( 0 );
00180 return -EINVAL;
00181 }
00182 if ( ( rc = imgfetch ( image, filename, image_register ) ) != 0 ) {
00183 printf ( "Could not fetch %s: %s\n",
00184 filename, strerror ( rc ) );
00185 image_put ( image );
00186 return rc;
00187 }
00188
00189 image_put ( image );
00190 return 0;
00191 }
00192
00193
00194
00195
00196
00197
00198
00199
00200 static int imgfetch_exec ( int argc, char **argv ) {
00201 int rc;
00202
00203 if ( ( rc = imgfetch_core_exec ( NULL, IMG_FETCH,
00204 argc, argv ) ) != 0 )
00205 return rc;
00206
00207 return 0;
00208 }
00209
00210
00211
00212
00213
00214
00215
00216
00217 static int kernel_exec ( int argc, char **argv ) {
00218 int rc;
00219
00220 if ( ( rc = imgfetch_core_exec ( NULL, IMG_LOAD, argc, argv ) ) != 0 )
00221 return rc;
00222
00223 return 0;
00224 }
00225
00226
00227
00228
00229
00230
00231
00232
00233 static int chain_exec ( int argc, char **argv) {
00234 int rc;
00235
00236 if ( ( rc = imgfetch_core_exec ( NULL, IMG_EXEC, argc, argv ) ) != 0 )
00237 return rc;
00238
00239 return 0;
00240 }
00241
00242
00243
00244
00245
00246
00247 static void imgload_syntax ( char **argv ) {
00248 printf ( "Usage:\n"
00249 " %s <image name>\n"
00250 "\n"
00251 "Load executable/loadable image\n",
00252 argv[0] );
00253 }
00254
00255
00256
00257
00258
00259
00260
00261
00262 static int imgload_exec ( int argc, char **argv ) {
00263 static struct option longopts[] = {
00264 { "help", 0, NULL, 'h' },
00265 { NULL, 0, NULL, 0 },
00266 };
00267 struct image *image;
00268 const char *name;
00269 int c;
00270 int rc;
00271
00272
00273 while ( ( c = getopt_long ( argc, argv, "h", longopts, NULL ) ) >= 0 ){
00274 switch ( c ) {
00275 case 'h':
00276
00277 default:
00278
00279 imgload_syntax ( argv );
00280 return 1;
00281 }
00282 }
00283
00284
00285 if ( optind != ( argc - 1 ) ) {
00286 imgload_syntax ( argv );
00287 return 1;
00288 }
00289 name = argv[optind];
00290
00291
00292 image = find_image ( name );
00293 if ( ! image ) {
00294 printf ( "No such image: %s\n", name );
00295 return 1;
00296 }
00297 if ( ( rc = imgload ( image ) ) != 0 ) {
00298 printf ( "Could not load %s: %s\n", name, strerror ( rc ) );
00299 return rc;
00300 }
00301
00302 return 0;
00303 }
00304
00305
00306
00307
00308
00309
00310 static void imgargs_syntax ( char **argv ) {
00311 printf ( "Usage:\n"
00312 " %s <image name> [<arguments>...]\n"
00313 "\n"
00314 "Set arguments for executable/loadable image\n",
00315 argv[0] );
00316 }
00317
00318
00319
00320
00321
00322
00323
00324
00325 static int imgargs_exec ( int argc, char **argv ) {
00326 static struct option longopts[] = {
00327 { "help", 0, NULL, 'h' },
00328 { NULL, 0, NULL, 0 },
00329 };
00330 struct image *image;
00331 const char *name;
00332 int c;
00333 int rc;
00334
00335
00336 while ( ( c = getopt_long ( argc, argv, "h", longopts, NULL ) ) >= 0 ){
00337 switch ( c ) {
00338 case 'h':
00339
00340 default:
00341
00342 imgargs_syntax ( argv );
00343 return 1;
00344 }
00345 }
00346
00347
00348 if ( optind == argc ) {
00349 imgargs_syntax ( argv );
00350 return 1;
00351 }
00352 name = argv[optind++];
00353
00354
00355 image = find_image ( name );
00356 if ( ! image ) {
00357 printf ( "No such image: %s\n", name );
00358 return 1;
00359 }
00360 if ( ( rc = imgfill_cmdline ( image, ( argc - optind ),
00361 &argv[optind] ) ) != 0 )
00362 return rc;
00363
00364
00365 return 0;
00366 }
00367
00368
00369
00370
00371
00372
00373 static void imgexec_syntax ( char **argv ) {
00374 printf ( "Usage:\n"
00375 " %s <image name>\n"
00376 "\n"
00377 "Execute executable/loadable image\n",
00378 argv[0] );
00379 }
00380
00381
00382
00383
00384
00385
00386
00387
00388 static int imgexec_exec ( int argc, char **argv ) {
00389 static struct option longopts[] = {
00390 { "help", 0, NULL, 'h' },
00391 { NULL, 0, NULL, 0 },
00392 };
00393 struct image *image;
00394 const char *name = NULL;
00395 int c;
00396 int rc;
00397
00398
00399 while ( ( c = getopt_long ( argc, argv, "h", longopts, NULL ) ) >= 0 ){
00400 switch ( c ) {
00401 case 'h':
00402
00403 default:
00404
00405 imgexec_syntax ( argv );
00406 return 1;
00407 }
00408 }
00409
00410
00411 if ( optind != argc )
00412 name = argv[optind++];
00413 if ( optind != argc ) {
00414 imgexec_syntax ( argv );
00415 return 1;
00416 }
00417
00418
00419 if ( name ) {
00420 image = find_image ( name );
00421 if ( ! image ) {
00422 printf ( "No such image: %s\n", name );
00423 return 1;
00424 }
00425 } else {
00426 image = imgautoselect();
00427 if ( ! image ) {
00428 printf ( "No (unique) loaded image\n" );
00429 return 1;
00430 }
00431 }
00432
00433 if ( ( rc = imgexec ( image ) ) != 0 ) {
00434 printf ( "Could not execute %s: %s\n",
00435 image->name, strerror ( rc ) );
00436 return 1;
00437 }
00438
00439 return 0;
00440 }
00441
00442
00443
00444
00445
00446
00447 static void imgstat_syntax ( char **argv ) {
00448 printf ( "Usage:\n"
00449 " %s\n"
00450 "\n"
00451 "List executable/loadable images\n",
00452 argv[0] );
00453 }
00454
00455
00456
00457
00458
00459
00460
00461
00462 static int imgstat_exec ( int argc, char **argv ) {
00463 static struct option longopts[] = {
00464 { "help", 0, NULL, 'h' },
00465 { NULL, 0, NULL, 0 },
00466 };
00467 struct image *image;
00468 int c;
00469
00470
00471 while ( ( c = getopt_long ( argc, argv, "h", longopts, NULL ) ) >= 0 ){
00472 switch ( c ) {
00473 case 'h':
00474
00475 default:
00476
00477 imgstat_syntax ( argv );
00478 return 1;
00479 }
00480 }
00481
00482
00483 if ( optind != argc ) {
00484 imgstat_syntax ( argv );
00485 return 1;
00486 }
00487
00488
00489 for_each_image ( image ) {
00490 imgstat ( image );
00491 }
00492 return 0;
00493 }
00494
00495
00496
00497
00498
00499
00500 static void imgfree_syntax ( char **argv ) {
00501 printf ( "Usage:\n"
00502 " %s [<image name>]\n"
00503 "\n"
00504 "Free one or all executable/loadable images\n",
00505 argv[0] );
00506 }
00507
00508
00509
00510
00511
00512
00513
00514
00515 static int imgfree_exec ( int argc, char **argv ) {
00516 static struct option longopts[] = {
00517 { "help", 0, NULL, 'h' },
00518 { NULL, 0, NULL, 0 },
00519 };
00520 struct image *image;
00521 struct image *tmp;
00522 const char *name = NULL;
00523 int c;
00524
00525
00526 while ( ( c = getopt_long ( argc, argv, "h", longopts, NULL ) ) >= 0 ){
00527 switch ( c ) {
00528 case 'h':
00529
00530 default:
00531
00532 imgfree_syntax ( argv );
00533 return 1;
00534 }
00535 }
00536
00537
00538 if ( optind != argc )
00539 name = argv[optind++];
00540 if ( optind != argc ) {
00541 imgfree_syntax ( argv );
00542 return 1;
00543 }
00544
00545 if ( name ) {
00546
00547 image = find_image ( name );
00548 if ( ! image ) {
00549 printf ( "No such image: %s\n", name );
00550 return 1;
00551 }
00552 imgfree ( image );
00553 } else {
00554
00555 list_for_each_entry_safe ( image, tmp, &images, list ) {
00556 imgfree ( image );
00557 }
00558 }
00559 return 0;
00560 }
00561
00562
00563 struct command image_commands[] __command = {
00564 {
00565 .name = "imgfetch",
00566 .exec = imgfetch_exec,
00567 },
00568 {
00569 .name = "module",
00570 .exec = imgfetch_exec,
00571 },
00572 {
00573 .name = "initrd",
00574 .exec = imgfetch_exec,
00575 },
00576 {
00577 .name = "kernel",
00578 .exec = kernel_exec,
00579 },
00580 {
00581 .name = "chain",
00582 .exec = chain_exec,
00583 },
00584 {
00585 .name = "imgload",
00586 .exec = imgload_exec,
00587 },
00588 {
00589 .name = "imgargs",
00590 .exec = imgargs_exec,
00591 },
00592 {
00593 .name = "imgexec",
00594 .exec = imgexec_exec,
00595 },
00596 {
00597 .name = "boot",
00598 .exec = imgexec_exec,
00599 },
00600 {
00601 .name = "imgstat",
00602 .exec = imgstat_exec,
00603 },
00604 {
00605 .name = "imgfree",
00606 .exec = imgfree_exec,
00607 },
00608 };