You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426
  1. /*
  2. * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>.
  3. *
  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.
  8. *
  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.
  13. *
  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.
  17. */
  18. FILE_LICENCE ( GPL2_OR_LATER );
  19. #include <stdint.h>
  20. #include <stdlib.h>
  21. #include <stdio.h>
  22. #include <errno.h>
  23. #include <libgen.h>
  24. #include <getopt.h>
  25. #include <ipxe/image.h>
  26. #include <ipxe/command.h>
  27. #include <ipxe/parseopt.h>
  28. #include <usr/imgmgmt.h>
  29. /** @file
  30. *
  31. * Image management commands
  32. *
  33. */
  34. /** "imgfetch" options */
  35. struct imgfetch_options {
  36. /** Image name */
  37. const char *name;
  38. };
  39. /** "imgfetch" option list */
  40. static struct option_descriptor imgfetch_opts[] = {
  41. OPTION_DESC ( "name", 'n', required_argument,
  42. struct imgfetch_options, name, parse_string ),
  43. };
  44. /** "imgfetch" command descriptor */
  45. static struct command_descriptor imgfetch_cmd =
  46. COMMAND_DESC ( struct imgfetch_options, imgfetch_opts, 1, MAX_ARGUMENTS,
  47. "[--name <name>] <uri> [<arguments>...]" );
  48. /**
  49. * The "imgfetch" and friends command body
  50. *
  51. * @v argc Argument count
  52. * @v argv Argument list
  53. * @v cmd Command descriptor
  54. * @v action_name Action name (for error messages)
  55. * @v action Action to take upon a successful download
  56. * @ret rc Return status code
  57. */
  58. static int imgfetch_core_exec ( int argc, char **argv,
  59. const char *action_name,
  60. int ( * action ) ( struct image *image ) ) {
  61. struct imgfetch_options opts;
  62. char *uri_string;
  63. char *cmdline = NULL;
  64. int rc;
  65. /* Parse options */
  66. if ( ( rc = parse_options ( argc, argv, &imgfetch_cmd, &opts ) ) != 0 )
  67. goto err_parse_options;
  68. /* Parse URI string */
  69. uri_string = argv[optind];
  70. if ( ! opts.name )
  71. opts.name = basename ( uri_string );
  72. /* Parse command line */
  73. if ( argv[ optind + 1 ] != NULL ) {
  74. cmdline = concat_args ( &argv[ optind + 1 ] );
  75. if ( ! cmdline ) {
  76. rc = -ENOMEM;
  77. goto err_cmdline;
  78. }
  79. }
  80. /* Fetch the image */
  81. if ( ( rc = imgdownload_string ( uri_string, opts.name, cmdline,
  82. action ) ) != 0 ) {
  83. printf ( "Could not %s %s: %s\n",
  84. action_name, uri_string, strerror ( rc ) );
  85. goto err_imgdownload;
  86. }
  87. /* Free command line */
  88. free ( cmdline );
  89. return 0;
  90. err_imgdownload:
  91. free ( cmdline );
  92. err_cmdline:
  93. err_parse_options:
  94. return rc;
  95. }
  96. /**
  97. * The "imgfetch"/"module" command
  98. *
  99. * @v argc Argument count
  100. * @v argv Argument list
  101. * @ret rc Return status code
  102. */
  103. static int imgfetch_exec ( int argc, char **argv ) {
  104. return imgfetch_core_exec ( argc, argv, "fetch",
  105. register_and_put_image );
  106. }
  107. /**
  108. * The "kernel" command
  109. *
  110. * @v argc Argument count
  111. * @v argv Argument list
  112. * @ret rc Return status code
  113. */
  114. static int kernel_exec ( int argc, char **argv ) {
  115. return imgfetch_core_exec ( argc, argv, "select",
  116. register_and_select_image );
  117. }
  118. /**
  119. * The "chain" command
  120. *
  121. * @v argc Argument count
  122. * @v argv Argument list
  123. * @ret rc Return status code
  124. */
  125. static int chain_exec ( int argc, char **argv) {
  126. return imgfetch_core_exec ( argc, argv, "boot",
  127. register_and_boot_image );
  128. }
  129. /** "imgselect" options */
  130. struct imgselect_options {};
  131. /** "imgselect" option list */
  132. static struct option_descriptor imgselect_opts[] = {};
  133. /** "imgselect" command descriptor */
  134. static struct command_descriptor imgselect_cmd =
  135. COMMAND_DESC ( struct imgselect_options, imgselect_opts, 1, 1,
  136. "<image>" );
  137. /**
  138. * The "imgselect" command
  139. *
  140. * @v argc Argument count
  141. * @v argv Argument list
  142. * @ret rc Return status code
  143. */
  144. static int imgselect_exec ( int argc, char **argv ) {
  145. struct imgselect_options opts;
  146. struct image *image;
  147. int rc;
  148. /* Parse options */
  149. if ( ( rc = parse_options ( argc, argv, &imgselect_cmd, &opts ) ) != 0 )
  150. return rc;
  151. /* Parse image name */
  152. if ( ( rc = parse_image ( argv[optind], &image ) ) != 0 )
  153. return rc;
  154. /* Load image */
  155. if ( ( rc = imgselect ( image ) ) != 0 ) {
  156. printf ( "Could not select %s: %s\n",
  157. image->name, strerror ( rc ) );
  158. return rc;
  159. }
  160. return 0;
  161. }
  162. /** "imgargs" options */
  163. struct imgargs_options {};
  164. /** "imgargs" option list */
  165. static struct option_descriptor imgargs_opts[] = {};
  166. /** "imgargs" command descriptor */
  167. static struct command_descriptor imgargs_cmd =
  168. COMMAND_DESC ( struct imgargs_options, imgargs_opts, 1, MAX_ARGUMENTS,
  169. "<image> [<arguments>...]" );
  170. /**
  171. * The "imgargs" command body
  172. *
  173. * @v argc Argument count
  174. * @v argv Argument list
  175. * @ret rc Return status code
  176. */
  177. static int imgargs_exec ( int argc, char **argv ) {
  178. struct imgargs_options opts;
  179. struct image *image;
  180. char *cmdline = NULL;
  181. int rc;
  182. /* Parse options */
  183. if ( ( rc = parse_options ( argc, argv, &imgargs_cmd, &opts ) ) != 0 )
  184. goto err_parse_options;
  185. /* Parse image name */
  186. if ( ( rc = parse_image ( argv[optind], &image ) ) != 0 )
  187. goto err_parse_image;
  188. /* Parse command line */
  189. if ( argv[ optind + 1 ] != NULL ) {
  190. cmdline = concat_args ( &argv[ optind + 1 ] );
  191. if ( ! cmdline ) {
  192. rc = -ENOMEM;
  193. goto err_cmdline;
  194. }
  195. }
  196. /* Set command line */
  197. if ( ( rc = image_set_cmdline ( image, cmdline ) ) != 0 )
  198. goto err_set_cmdline;
  199. /* Free command line */
  200. free ( cmdline );
  201. return 0;
  202. err_set_cmdline:
  203. free ( cmdline );
  204. err_cmdline:
  205. err_parse_image:
  206. err_parse_options:
  207. return rc;
  208. }
  209. /** "imgexec" options */
  210. struct imgexec_options {};
  211. /** "imgexec" option list */
  212. static struct option_descriptor imgexec_opts[] = {};
  213. /** "imgexec" command descriptor */
  214. static struct command_descriptor imgexec_cmd =
  215. COMMAND_DESC ( struct imgexec_options, imgexec_opts, 0, 1,
  216. "[<image>]" );
  217. /**
  218. * The "imgexec" command
  219. *
  220. * @v argc Argument count
  221. * @v argv Argument list
  222. * @ret rc Return status code
  223. */
  224. static int imgexec_exec ( int argc, char **argv ) {
  225. struct imgexec_options opts;
  226. struct image *image;
  227. int rc;
  228. /* Parse options */
  229. if ( ( rc = parse_options ( argc, argv, &imgexec_cmd, &opts ) ) != 0 )
  230. return rc;
  231. /* Parse image name */
  232. if ( optind < argc ) {
  233. if ( ( rc = parse_image ( argv[optind], &image ) ) != 0 )
  234. return rc;
  235. } else {
  236. image = imgautoselect();
  237. if ( ! image ) {
  238. rc = -ENOTTY;
  239. printf ( "No image selected: %s\n", strerror ( rc ) );
  240. return rc;
  241. }
  242. }
  243. /* Execute image */
  244. if ( ( rc = imgexec ( image ) ) != 0 ) {
  245. printf ( "Could not execute %s: %s\n",
  246. image->name, strerror ( rc ) );
  247. return rc;
  248. }
  249. return 0;
  250. }
  251. /** "imgstat" options */
  252. struct imgstat_options {};
  253. /** "imgstat" option list */
  254. static struct option_descriptor imgstat_opts[] = {};
  255. /** "imgstat" command descriptor */
  256. static struct command_descriptor imgstat_cmd =
  257. COMMAND_DESC ( struct imgstat_options, imgstat_opts, 0, 0, "" );
  258. /**
  259. * The "imgstat" command
  260. *
  261. * @v argc Argument count
  262. * @v argv Argument list
  263. * @ret rc Return status code
  264. */
  265. static int imgstat_exec ( int argc, char **argv ) {
  266. struct imgstat_options opts;
  267. struct image *image;
  268. int rc;
  269. /* Parse options */
  270. if ( ( rc = parse_options ( argc, argv, &imgstat_cmd, &opts ) ) != 0 )
  271. return rc;
  272. /* Show status of all images */
  273. for_each_image ( image ) {
  274. imgstat ( image );
  275. }
  276. return 0;
  277. }
  278. /** "imgfree" options */
  279. struct imgfree_options {};
  280. /** "imgfree" option list */
  281. static struct option_descriptor imgfree_opts[] = {};
  282. /** "imgfree" command descriptor */
  283. static struct command_descriptor imgfree_cmd =
  284. COMMAND_DESC ( struct imgfree_options, imgfree_opts, 0, 1,
  285. "[<image>]" );
  286. /**
  287. * The "imgfree" command
  288. *
  289. * @v argc Argument count
  290. * @v argv Argument list
  291. * @ret rc Return status code
  292. */
  293. static int imgfree_exec ( int argc, char **argv ) {
  294. struct imgfree_options opts;
  295. struct image *image;
  296. struct image *tmp;
  297. int rc;
  298. /* Parse options */
  299. if ( ( rc = parse_options ( argc, argv, &imgfree_cmd, &opts ) ) != 0 )
  300. return rc;
  301. if ( optind < argc ) {
  302. /* Free specified image */
  303. if ( ( rc = parse_image ( argv[optind], &image ) ) != 0 )
  304. return rc;
  305. imgfree ( image );
  306. } else {
  307. /* Free all images */
  308. list_for_each_entry_safe ( image, tmp, &images, list ) {
  309. imgfree ( image );
  310. }
  311. }
  312. return 0;
  313. }
  314. /** Image management commands */
  315. struct command image_commands[] __command = {
  316. {
  317. .name = "imgfetch",
  318. .exec = imgfetch_exec,
  319. },
  320. {
  321. .name = "module",
  322. .exec = imgfetch_exec, /* synonym for "imgfetch" */
  323. },
  324. {
  325. .name = "initrd",
  326. .exec = imgfetch_exec, /* synonym for "imgfetch" */
  327. },
  328. {
  329. .name = "kernel",
  330. .exec = kernel_exec,
  331. },
  332. {
  333. .name = "chain",
  334. .exec = chain_exec,
  335. },
  336. {
  337. .name = "imgselect",
  338. .exec = imgselect_exec,
  339. },
  340. {
  341. .name = "imgload", /* synonym for "imgselect" */
  342. .exec = imgselect_exec,
  343. },
  344. {
  345. .name = "imgargs",
  346. .exec = imgargs_exec,
  347. },
  348. {
  349. .name = "imgexec",
  350. .exec = imgexec_exec,
  351. },
  352. {
  353. .name = "boot", /* synonym for "imgexec" */
  354. .exec = imgexec_exec,
  355. },
  356. {
  357. .name = "imgstat",
  358. .exec = imgstat_exec,
  359. },
  360. {
  361. .name = "imgfree",
  362. .exec = imgfree_exec,
  363. },
  364. };