diff options
| author | Simon Rettberg | 2026-01-28 12:53:53 +0100 |
|---|---|---|
| committer | Simon Rettberg | 2026-01-28 12:53:53 +0100 |
| commit | 8e82785c584dc13e20f9229decb95bd17bbe9cd1 (patch) | |
| tree | a8b359e59196be5b2e3862bed189107f4bc9975f /src/hci/commands | |
| parent | Merge branch 'master' into openslx (diff) | |
| parent | [prefix] Make unlzma.S compatible with 386 class CPUs (diff) | |
| download | ipxe-openslx.tar.gz ipxe-openslx.tar.xz ipxe-openslx.zip | |
Merge branch 'master' into openslxopenslx
Diffstat (limited to 'src/hci/commands')
39 files changed, 636 insertions, 423 deletions
diff --git a/src/hci/commands/autoboot_cmd.c b/src/hci/commands/autoboot_cmd.c index 56f39a1ce..a61333a9d 100644 --- a/src/hci/commands/autoboot_cmd.c +++ b/src/hci/commands/autoboot_cmd.c @@ -30,6 +30,7 @@ #include <usr/autoboot.h> FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); +FILE_SECBOOT ( PERMITTED ); /** @file * @@ -73,9 +74,4 @@ static int autoboot_exec ( int argc, char **argv ) { } /** Booting commands */ -struct command autoboot_commands[] __command = { - { - .name = "autoboot", - .exec = autoboot_exec, - }, -}; +COMMAND ( autoboot, autoboot_exec ); diff --git a/src/hci/commands/cert_cmd.c b/src/hci/commands/cert_cmd.c index 24b18bf5c..ebd9a25cd 100644 --- a/src/hci/commands/cert_cmd.c +++ b/src/hci/commands/cert_cmd.c @@ -22,8 +22,10 @@ */ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); +FILE_SECBOOT ( PERMITTED ); #include <stdio.h> +#include <string.h> #include <errno.h> #include <getopt.h> #include <ipxe/x509.h> @@ -288,17 +290,6 @@ static int certfree_exec ( int argc, char **argv ) { } /** Certificate management commands */ -struct command certmgmt_commands[] __command = { - { - .name = "certstat", - .exec = certstat_exec, - }, - { - .name = "certstore", - .exec = certstore_exec, - }, - { - .name = "certfree", - .exec = certfree_exec, - }, -}; +COMMAND ( certstat, certstat_exec ); +COMMAND ( certstore, certstore_exec ); +COMMAND ( certfree, certfree_exec ); diff --git a/src/hci/commands/config_cmd.c b/src/hci/commands/config_cmd.c index ad415e045..cc21ad3fe 100644 --- a/src/hci/commands/config_cmd.c +++ b/src/hci/commands/config_cmd.c @@ -31,6 +31,7 @@ #include <ipxe/settings_ui.h> FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); +FILE_SECBOOT ( PERMITTED ); /** @file * @@ -79,7 +80,4 @@ static int config_exec ( int argc, char **argv ) { } /** Configuration UI commands */ -struct command config_command __command = { - .name = "config", - .exec = config_exec, -}; +COMMAND ( config, config_exec ); diff --git a/src/hci/commands/console_cmd.c b/src/hci/commands/console_cmd.c index bd5647261..479e14efc 100644 --- a/src/hci/commands/console_cmd.c +++ b/src/hci/commands/console_cmd.c @@ -22,6 +22,7 @@ */ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); +FILE_SECBOOT ( PERMITTED ); /** @file * @@ -253,17 +254,6 @@ static int cpair_exec ( int argc, char **argv ) { } /** Console management commands */ -struct command console_commands[] __command = { - { - .name = "console", - .exec = console_exec, - }, - { - .name = "colour", - .exec = colour_exec, - }, - { - .name = "cpair", - .exec = cpair_exec, - }, -}; +COMMAND ( console, console_exec ); +COMMAND ( colour, colour_exec ); +COMMAND ( cpair, cpair_exec ); diff --git a/src/hci/commands/dhcp_cmd.c b/src/hci/commands/dhcp_cmd.c index 45a922b51..ccc115b87 100644 --- a/src/hci/commands/dhcp_cmd.c +++ b/src/hci/commands/dhcp_cmd.c @@ -22,6 +22,7 @@ */ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); +FILE_SECBOOT ( PERMITTED ); #include <stdio.h> #include <stdint.h> @@ -92,13 +93,5 @@ static int pxebs_exec ( int argc, char **argv ) { } /** DHCP management commands */ -struct command dhcp_commands[] __command = { - { - .name = "dhcp", - .exec = ifconf_exec, /* synonym for "ifconf" */ - }, - { - .name = "pxebs", - .exec = pxebs_exec, - }, -}; +COMMAND ( dhcp, ifconf_exec ); /* synonym for "ifconf" */ +COMMAND ( pxebs, pxebs_exec ); diff --git a/src/hci/commands/digest_cmd.c b/src/hci/commands/digest_cmd.c index 71308064f..4d7da0385 100644 --- a/src/hci/commands/digest_cmd.c +++ b/src/hci/commands/digest_cmd.c @@ -18,6 +18,7 @@ */ FILE_LICENCE ( GPL2_OR_LATER ); +FILE_SECBOOT ( PERMITTED ); #include <stdio.h> #include <string.h> @@ -26,10 +27,12 @@ FILE_LICENCE ( GPL2_OR_LATER ); #include <ipxe/command.h> #include <ipxe/parseopt.h> #include <ipxe/image.h> +#include <ipxe/settings.h> #include <ipxe/crypto.h> #include <ipxe/md5.h> #include <ipxe/sha1.h> #include <usr/imgmgmt.h> +#include <hci/digest_cmd.h> /** @file * @@ -38,10 +41,16 @@ FILE_LICENCE ( GPL2_OR_LATER ); */ /** "digest" options */ -struct digest_options {}; +struct digest_options { + /** Setting */ + struct named_setting setting; +}; /** "digest" option list */ -static struct option_descriptor digest_opts[] = {}; +static struct option_descriptor digest_opts[] = { + OPTION_DESC ( "set", 's', required_argument, struct digest_options, + setting, parse_autovivified_setting ), +}; /** "digest" command descriptor */ static struct command_descriptor digest_cmd = @@ -56,54 +65,62 @@ static struct command_descriptor digest_cmd = * @v digest Digest algorithm * @ret rc Return status code */ -static int digest_exec ( int argc, char **argv, - struct digest_algorithm *digest ) { +int digest_exec ( int argc, char **argv, struct digest_algorithm *digest ) { struct digest_options opts; struct image *image; - uint8_t digest_ctx[digest->ctxsize]; - uint8_t digest_out[digest->digestsize]; - uint8_t buf[128]; - size_t offset; - size_t len; - size_t frag_len; + uint8_t ctx[digest->ctxsize]; + uint8_t out[digest->digestsize]; + unsigned int j; int i; - unsigned j; int rc; /* Parse options */ if ( ( rc = parse_options ( argc, argv, &digest_cmd, &opts ) ) != 0 ) return rc; + /* Use default setting type, if not specified */ + if ( ! opts.setting.setting.type ) + opts.setting.setting.type = &setting_type_hexraw; + + /* Calculate digests for each image */ for ( i = optind ; i < argc ; i++ ) { /* Acquire image */ if ( ( rc = imgacquire ( argv[i], 0, &image ) ) != 0 ) - continue; - offset = 0; - len = image->len; - - /* calculate digest */ - digest_init ( digest, digest_ctx ); - while ( len ) { - frag_len = len; - if ( frag_len > sizeof ( buf ) ) - frag_len = sizeof ( buf ); - copy_from_user ( buf, image->data, offset, frag_len ); - digest_update ( digest, digest_ctx, buf, frag_len ); - len -= frag_len; - offset += frag_len; + return rc; + + /* Calculate digest */ + digest_init ( digest, ctx ); + digest_update ( digest, ctx, image->data, image->len ); + digest_final ( digest, ctx, out ); + + /* Display or store digest as directed */ + if ( opts.setting.settings ) { + + /* Store digest */ + if ( ( rc = store_setting ( opts.setting.settings, + &opts.setting.setting, out, + sizeof ( out ) ) ) != 0 ) { + printf ( "Could not store \"%s\": %s\n", + opts.setting.setting.name, + strerror ( rc ) ); + return rc; + } + + } else { + + /* Print digest */ + for ( j = 0 ; j < sizeof ( out ) ; j++ ) + printf ( "%02x", out[j] ); + printf ( " %s\n", image->name ); } - digest_final ( digest, digest_ctx, digest_out ); - - for ( j = 0 ; j < sizeof ( digest_out ) ; j++ ) - printf ( "%02x", digest_out[j] ); - - printf ( " %s\n", image->name ); } return 0; } +/* Include "md5sum" and "sha1sum" commands unconditionally */ + static int md5sum_exec ( int argc, char **argv ) { return digest_exec ( argc, argv, &md5_algorithm ); } @@ -112,12 +129,9 @@ static int sha1sum_exec ( int argc, char **argv ) { return digest_exec ( argc, argv, &sha1_algorithm ); } -struct command md5sum_command __command = { - .name = "md5sum", - .exec = md5sum_exec, -}; +COMMAND ( md5sum, md5sum_exec ); +COMMAND ( sha1sum, sha1sum_exec ); -struct command sha1sum_command __command = { - .name = "sha1sum", - .exec = sha1sum_exec, -}; +/* Drag in commands for any other enabled algorithms */ +REQUIRING_SYMBOL ( digest_exec ); +REQUIRE_OBJECT ( config_digest_cmd ); diff --git a/src/hci/commands/menu_cmd.c b/src/hci/commands/dynui_cmd.c index c8692f1a7..b70211050 100644 --- a/src/hci/commands/menu_cmd.c +++ b/src/hci/commands/dynui_cmd.c @@ -22,10 +22,11 @@ */ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); +FILE_SECBOOT ( PERMITTED ); /** @file * - * Menu commands + * Dynamic user interface commands * */ @@ -34,7 +35,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #include <string.h> #include <errno.h> #include <getopt.h> -#include <ipxe/menu.h> +#include <ipxe/dynui.h> #include <ipxe/command.h> #include <ipxe/parseopt.h> #include <ipxe/settings.h> @@ -42,42 +43,42 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); FEATURE ( FEATURE_MISC, "Menu", DHCP_EB_FEATURE_MENU, 1 ); -/** "menu" options */ -struct menu_options { +/** "dynui" options */ +struct dynui_options { /** Name */ char *name; /** Delete */ int delete; }; -/** "menu" option list */ -static struct option_descriptor menu_opts[] = { +/** "dynui" option list */ +static struct option_descriptor dynui_opts[] = { OPTION_DESC ( "name", 'n', required_argument, - struct menu_options, name, parse_string ), + struct dynui_options, name, parse_string ), OPTION_DESC ( "delete", 'd', no_argument, - struct menu_options, delete, parse_flag ), + struct dynui_options, delete, parse_flag ), }; -/** "menu" command descriptor */ -static struct command_descriptor menu_cmd = - COMMAND_DESC ( struct menu_options, menu_opts, 0, MAX_ARGUMENTS, +/** "dynui" command descriptor */ +static struct command_descriptor dynui_cmd = + COMMAND_DESC ( struct dynui_options, dynui_opts, 0, MAX_ARGUMENTS, "[<title>]" ); /** - * The "menu" command + * The "dynui" command * * @v argc Argument count * @v argv Argument list * @ret rc Return status code */ -static int menu_exec ( int argc, char **argv ) { - struct menu_options opts; - struct menu *menu; +static int dynui_exec ( int argc, char **argv ) { + struct dynui_options opts; + struct dynamic_ui *dynui; char *title; int rc; /* Parse options */ - if ( ( rc = parse_options ( argc, argv, &menu_cmd, &opts ) ) != 0 ) + if ( ( rc = parse_options ( argc, argv, &dynui_cmd, &opts ) ) != 0 ) goto err_parse_options; /* Parse title */ @@ -87,21 +88,21 @@ static int menu_exec ( int argc, char **argv ) { goto err_parse_title; } - /* Create menu */ - menu = create_menu ( opts.name, title ); - if ( ! menu ) { + /* Create dynamic user interface */ + dynui = create_dynui ( opts.name, title ); + if ( ! dynui ) { rc = -ENOMEM; - goto err_create_menu; + goto err_create_dynui; } - /* Destroy menu, if applicable */ + /* Destroy dynamic user interface, if applicable */ if ( opts.delete ) - destroy_menu ( menu ); + destroy_dynui ( dynui ); /* Success */ rc = 0; - err_create_menu: + err_create_dynui: free ( title ); err_parse_title: err_parse_options: @@ -110,12 +111,14 @@ static int menu_exec ( int argc, char **argv ) { /** "item" options */ struct item_options { - /** Menu name */ - char *menu; + /** Dynamic user interface name */ + char *dynui; /** Shortcut key */ unsigned int key; /** Use as default */ int is_default; + /** Value is a secret */ + int is_secret; /** Use as a separator */ int is_gap; /** Don't show; hotkey only */ @@ -125,11 +128,15 @@ struct item_options { /** "item" option list */ static struct option_descriptor item_opts[] = { OPTION_DESC ( "menu", 'm', required_argument, - struct item_options, menu, parse_string ), + struct item_options, dynui, parse_string ), + OPTION_DESC ( "form", 'f', required_argument, + struct item_options, dynui, parse_string ), OPTION_DESC ( "key", 'k', required_argument, struct item_options, key, parse_key ), OPTION_DESC ( "default", 'd', no_argument, struct item_options, is_default, parse_flag ), + OPTION_DESC ( "secret", 's', no_argument, + struct item_options, is_secret, parse_flag ), OPTION_DESC ( "gap", 'g', no_argument, struct item_options, is_gap, parse_flag ), OPTION_DESC ( "hidden", 'i', no_argument, @@ -139,7 +146,7 @@ static struct option_descriptor item_opts[] = { /** "item" command descriptor */ static struct command_descriptor item_cmd = COMMAND_DESC ( struct item_options, item_opts, 0, MAX_ARGUMENTS, - "[<label> [<text>]]" ); + "[<name> [<text>]]" ); /** * The "item" command @@ -150,9 +157,10 @@ static struct command_descriptor item_cmd = */ static int item_exec ( int argc, char **argv ) { struct item_options opts; - struct menu *menu; - struct menu_item *item; - char *label = NULL; + struct dynamic_ui *dynui; + struct dynamic_item *item; + unsigned int flags = 0; + char *name = NULL; char *text = NULL; int rc; @@ -160,12 +168,12 @@ static int item_exec ( int argc, char **argv ) { if ( ( rc = parse_options ( argc, argv, &item_cmd, &opts ) ) != 0 ) goto err_parse_options; - /* Parse label, if present */ + /* Parse name, if present */ if ( ! opts.is_gap ) - label = argv[optind++]; /* May be NULL */ + name = argv[optind++]; /* May be NULL */ /* Hidden entry without label and shortcut is pointless */ - if ( opts.is_hidden && ( ! opts.key || ! label || ! *label ) ) { + if ( opts.is_hidden && ( ! opts.key || ! name || ! *name ) ) { rc = -EINVAL; goto err_invalid_argument; } @@ -179,23 +187,29 @@ static int item_exec ( int argc, char **argv ) { } } - /* Identify menu */ - if ( ( rc = parse_menu ( opts.menu, &menu ) ) != 0 ) - goto err_parse_menu; - - /* Add menu item */ - item = add_menu_item ( menu, label, ( text ? text : "" ), - opts.key, opts.is_default, opts.is_hidden ); + /* Identify dynamic user interface */ + if ( ( rc = parse_dynui ( opts.dynui, &dynui ) ) != 0 ) + goto err_parse_dynui; + + /* Add dynamic user interface item */ + if ( opts.is_default ) + flags |= DYNUI_DEFAULT; + if ( opts.is_secret ) + flags |= DYNUI_SECRET; + if ( opts.is_hidden ) + flags |= DYNUI_HIDDEN; + item = add_dynui_item ( dynui, name, ( text ? text : "" ), flags, + opts.key ); if ( ! item ) { rc = -ENOMEM; - goto err_add_menu_item; + goto err_add_dynui_item; } /* Success */ rc = 0; - err_add_menu_item: - err_parse_menu: + err_add_dynui_item: + err_parse_dynui: free ( text ); err_parse_text: err_invalid_argument: @@ -205,24 +219,28 @@ static int item_exec ( int argc, char **argv ) { /** "choose" options */ struct choose_options { - /** Menu name */ - char *menu; - /** Timeout */ + /** Dynamic user interface name */ + char *dynui; + /** Initial timeout */ unsigned long timeout; + /** Post-activity timeout */ + unsigned long retimeout; /** Default selection */ char *select; - /** Keep menu */ + /** Keep dynamic user interface */ int keep; }; /** "choose" option list */ static struct option_descriptor choose_opts[] = { OPTION_DESC ( "menu", 'm', required_argument, - struct choose_options, menu, parse_string ), + struct choose_options, dynui, parse_string ), OPTION_DESC ( "default", 'd', required_argument, struct choose_options, select, parse_string ), OPTION_DESC ( "timeout", 't', required_argument, struct choose_options, timeout, parse_timeout ), + OPTION_DESC ( "retimeout", 'r', required_argument, + struct choose_options, retimeout, parse_timeout ), OPTION_DESC ( "keep", 'k', no_argument, struct choose_options, keep, parse_flag ), }; @@ -241,8 +259,8 @@ static struct command_descriptor choose_cmd = static int choose_exec ( int argc, char **argv ) { struct choose_options opts; struct named_setting setting; - struct menu *menu; - struct menu_item *item; + struct dynamic_ui *dynui; + struct dynamic_item *item; int rc; /* Parse options */ @@ -254,12 +272,13 @@ static int choose_exec ( int argc, char **argv ) { &setting ) ) != 0 ) goto err_parse_setting; - /* Identify menu */ - if ( ( rc = parse_menu ( opts.menu, &menu ) ) != 0 ) - goto err_parse_menu; + /* Identify dynamic user interface */ + if ( ( rc = parse_dynui ( opts.dynui, &dynui ) ) != 0 ) + goto err_parse_dynui; - /* Show menu */ - if ( ( rc = show_menu ( menu, opts.timeout, opts.select, &item ) ) != 0) + /* Show as menu */ + if ( ( rc = show_menu ( dynui, opts.timeout, opts.retimeout, + opts.select, &item ) ) != 0 ) goto err_show_menu; /* Apply default type if necessary */ @@ -268,7 +287,7 @@ static int choose_exec ( int argc, char **argv ) { /* Store setting */ if ( ( rc = storef_setting ( setting.settings, &setting.setting, - item->label ) ) != 0 ) { + item->name ) ) != 0 ) { printf ( "Could not store \"%s\": %s\n", setting.setting.name, strerror ( rc ) ); goto err_store; @@ -279,27 +298,74 @@ static int choose_exec ( int argc, char **argv ) { err_store: err_show_menu: - /* Destroy menu, if applicable */ + /* Destroy dynamic user interface, if applicable */ if ( ! opts.keep ) - destroy_menu ( menu ); - err_parse_menu: + destroy_dynui ( dynui ); + err_parse_dynui: err_parse_setting: err_parse_options: return rc; } -/** Menu commands */ -struct command menu_commands[] __command = { - { - .name = "menu", - .exec = menu_exec, - }, - { - .name = "item", - .exec = item_exec, - }, - { - .name = "choose", - .exec = choose_exec, - }, +/** "present" options */ +struct present_options { + /** Dynamic user interface name */ + char *dynui; + /** Keep dynamic user interface */ + int keep; }; + +/** "present" option list */ +static struct option_descriptor present_opts[] = { + OPTION_DESC ( "form", 'f', required_argument, + struct present_options, dynui, parse_string ), + OPTION_DESC ( "keep", 'k', no_argument, + struct present_options, keep, parse_flag ), +}; + +/** "present" command descriptor */ +static struct command_descriptor present_cmd = + COMMAND_DESC ( struct present_options, present_opts, 0, 0, NULL ); + +/** + * The "present" command + * + * @v argc Argument count + * @v argv Argument list + * @ret rc Return status code + */ +static int present_exec ( int argc, char **argv ) { + struct present_options opts; + struct dynamic_ui *dynui; + int rc; + + /* Parse options */ + if ( ( rc = parse_options ( argc, argv, &present_cmd, &opts ) ) != 0 ) + goto err_parse_options; + + /* Identify dynamic user interface */ + if ( ( rc = parse_dynui ( opts.dynui, &dynui ) ) != 0 ) + goto err_parse_dynui; + + /* Show as form */ + if ( ( rc = show_form ( dynui ) ) != 0 ) + goto err_show_form; + + /* Success */ + rc = 0; + + err_show_form: + /* Destroy dynamic user interface, if applicable */ + if ( ! opts.keep ) + destroy_dynui ( dynui ); + err_parse_dynui: + err_parse_options: + return rc; +} + +/** Dynamic user interface commands */ +COMMAND ( menu, dynui_exec ); +COMMAND ( form, dynui_exec ); +COMMAND ( item, item_exec ); +COMMAND ( choose, choose_exec ); +COMMAND ( present, present_exec ); diff --git a/src/hci/commands/efimap_cmd.c b/src/hci/commands/efimap_cmd.c index c183cbc30..7e8bdb19f 100644 --- a/src/hci/commands/efimap_cmd.c +++ b/src/hci/commands/efimap_cmd.c @@ -69,9 +69,4 @@ static int efimap_exec ( int argc, char **argv ) { } /** EFIMAP command */ -struct command efimap_commands[] __command = { - { - .name = "efimap", - .exec = efimap_exec, - }, -}; +COMMAND ( efimap, efimap_exec ); diff --git a/src/hci/commands/fcmgmt_cmd.c b/src/hci/commands/fcmgmt_cmd.c index 97f10f4dd..c03ebb05f 100644 --- a/src/hci/commands/fcmgmt_cmd.c +++ b/src/hci/commands/fcmgmt_cmd.c @@ -207,13 +207,5 @@ static int fcels_exec ( int argc, char **argv ) { } /** Fibre Channel management commands */ -struct command fcmgmt_commands[] __command = { - { - .name = "fcstat", - .exec = fcstat_exec, - }, - { - .name = "fcels", - .exec = fcels_exec, - }, -}; +COMMAND ( fcstat, fcstat_exec ); +COMMAND ( fcels, fcels_exec ); diff --git a/src/hci/commands/fdt_cmd.c b/src/hci/commands/fdt_cmd.c new file mode 100644 index 000000000..7cd39279b --- /dev/null +++ b/src/hci/commands/fdt_cmd.c @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2025 Michael Brown <mbrown@fensystems.co.uk>. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + * + * You can also choose to distribute this program under the terms of + * the Unmodified Binary Distribution Licence (as given in the file + * COPYING.UBDL), provided that you have satisfied its requirements. + */ + +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); + +#include <getopt.h> +#include <ipxe/command.h> +#include <ipxe/parseopt.h> +#include <usr/imgmgmt.h> +#include <usr/fdtmgmt.h> + +/** @file + * + * Flattened Device Tree commands + * + */ + +/** "fdt" options */ +struct fdt_options { + /** Download timeout */ + unsigned long timeout; +}; + +/** "fdt" option list */ +static struct option_descriptor fdt_opts[] = { + OPTION_DESC ( "timeout", 't', required_argument, + struct fdt_options, timeout, parse_timeout ), +}; + +/** "fdt" command descriptor */ +static struct command_descriptor fdt_cmd = + COMMAND_DESC ( struct fdt_options, fdt_opts, 0, 1, "[<uri>]" ); + +/** + * The "fdt" command + * + * @v argc Argument count + * @v argv Argument list + * @ret rc Return status code + */ +static int fdt_exec ( int argc, char **argv ) { + struct fdt_options opts; + struct image *image = NULL; + char *name_uri; + int rc; + + /* Parse options */ + if ( ( rc = parse_options ( argc, argv, &fdt_cmd, &opts ) ) != 0 ) + goto err_parse; + + /* Parse name/URI string */ + name_uri = argv[optind]; + + /* Acquire image, if applicable */ + if ( name_uri && ( ( rc = imgacquire ( name_uri, opts.timeout, + &image ) ) != 0 ) ) { + goto err_image; + } + + /* (Un)register as FDT */ + if ( ( rc = imgfdt ( image ) ) != 0 ) + goto err_fdt; + + err_fdt: + err_image: + err_parse: + return rc; +} + +/** Flattened Device Tree commands */ +COMMAND ( fdt, fdt_exec ); diff --git a/src/hci/commands/gdbstub_cmd.c b/src/hci/commands/gdbstub_cmd.c index c4a831e7a..ba5edde3a 100644 --- a/src/hci/commands/gdbstub_cmd.c +++ b/src/hci/commands/gdbstub_cmd.c @@ -107,9 +107,4 @@ static int gdbstub_exec ( int argc, char **argv ) { } /** GDB stub commands */ -struct command gdbstub_commands[] __command = { - { - .name = "gdbstub", - .exec = gdbstub_exec, - }, -}; +COMMAND ( gdbstub, gdbstub_exec ); diff --git a/src/hci/commands/ibmgmt_cmd.c b/src/hci/commands/ibmgmt_cmd.c index 1154d749e..be8b58cc2 100644 --- a/src/hci/commands/ibmgmt_cmd.c +++ b/src/hci/commands/ibmgmt_cmd.c @@ -71,9 +71,4 @@ static int ibstat_exec ( int argc, char **argv ) { } /** Infiniband commands */ -struct command ibmgmt_commands[] __command = { - { - .name = "ibstat", - .exec = ibstat_exec, - }, -}; +COMMAND ( ibstat, ibstat_exec ); diff --git a/src/hci/commands/ifmgmt_cmd.c b/src/hci/commands/ifmgmt_cmd.c index 591cb3da8..f4b9fef3a 100644 --- a/src/hci/commands/ifmgmt_cmd.c +++ b/src/hci/commands/ifmgmt_cmd.c @@ -22,6 +22,7 @@ */ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); +FILE_SECBOOT ( PERMITTED ); #include <stdio.h> #include <errno.h> @@ -303,25 +304,8 @@ static int iflinkwait_exec ( int argc, char **argv ) { } /** Interface management commands */ -struct command ifmgmt_commands[] __command = { - { - .name = "ifopen", - .exec = ifopen_exec, - }, - { - .name = "ifclose", - .exec = ifclose_exec, - }, - { - .name = "ifstat", - .exec = ifstat_exec, - }, - { - .name = "ifconf", - .exec = ifconf_exec, - }, - { - .name = "iflinkwait", - .exec = iflinkwait_exec, - }, -}; +COMMAND ( ifopen, ifopen_exec ); +COMMAND ( ifclose, ifclose_exec ); +COMMAND ( ifstat, ifstat_exec ); +COMMAND ( ifconf, ifconf_exec ); +COMMAND ( iflinkwait, iflinkwait_exec ); diff --git a/src/hci/commands/image_archive_cmd.c b/src/hci/commands/image_archive_cmd.c index a2212aecf..6b907830e 100644 --- a/src/hci/commands/image_archive_cmd.c +++ b/src/hci/commands/image_archive_cmd.c @@ -97,9 +97,4 @@ static int imgextract_exec ( int argc, char **argv ) { } /** Archive image commands */ -struct command image_archive_commands[] __command = { - { - .name = "imgextract", - .exec = imgextract_exec, - }, -}; +COMMAND ( imgextract, imgextract_exec ); diff --git a/src/hci/commands/image_cmd.c b/src/hci/commands/image_cmd.c index bf97b4deb..aaed0ea9b 100644 --- a/src/hci/commands/image_cmd.c +++ b/src/hci/commands/image_cmd.c @@ -22,10 +22,12 @@ */ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); +FILE_SECBOOT ( PERMITTED ); #include <stdint.h> #include <stdlib.h> #include <stdio.h> +#include <string.h> #include <errno.h> #include <getopt.h> #include <ipxe/image.h> @@ -392,54 +394,22 @@ static int imgfree_exec ( int argc, char **argv ) { return imgmulti_exec ( argc, argv, unregister_image ); } -/** Image management commands */ -struct command image_commands[] __command = { - { - .name = "imgfetch", - .exec = imgfetch_exec, - }, - { - .name = "module", - .exec = imgfetch_exec, /* synonym for "imgfetch" */ - }, - { - .name = "initrd", - .exec = imgfetch_exec, /* synonym for "imgfetch" */ - }, - { - .name = "kernel", - .exec = imgselect_exec, /* synonym for "imgselect" */ - }, - { - .name = "chain", - .exec = imgexec_exec, /* synonym for "imgexec" */ - }, - { - .name = "imgselect", - .exec = imgselect_exec, - }, - { - .name = "imgload", - .exec = imgselect_exec, /* synonym for "imgselect" */ - }, - { - .name = "imgargs", - .exec = imgargs_exec, - }, - { - .name = "imgexec", - .exec = imgexec_exec, - }, - { - .name = "boot", /* synonym for "imgexec" */ - .exec = imgexec_exec, - }, - { - .name = "imgstat", - .exec = imgstat_exec, - }, - { - .name = "imgfree", - .exec = imgfree_exec, - }, -}; +/* "imgfetch" and synonyms */ +COMMAND ( imgfetch, imgfetch_exec ); +COMMAND ( module, imgfetch_exec ); +COMMAND ( initrd, imgfetch_exec ); + +/* "imgselect" and synonyms */ +COMMAND ( imgselect, imgselect_exec ); +COMMAND ( imgload, imgselect_exec ); +COMMAND ( kernel, imgselect_exec ); + +/* "imgexec" and synonyms */ +COMMAND ( imgexec, imgexec_exec ); +COMMAND ( chain, imgexec_exec ); +COMMAND ( boot, imgexec_exec ); + +/* Other image management commands */ +COMMAND ( imgargs, imgargs_exec ); +COMMAND ( imgstat, imgstat_exec ); +COMMAND ( imgfree, imgfree_exec ); diff --git a/src/hci/commands/image_crypt_cmd.c b/src/hci/commands/image_crypt_cmd.c new file mode 100644 index 000000000..54568cc28 --- /dev/null +++ b/src/hci/commands/image_crypt_cmd.c @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2024 Michael Brown <mbrown@fensystems.co.uk>. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + * + * You can also choose to distribute this program under the terms of + * the Unmodified Binary Distribution Licence (as given in the file + * COPYING.UBDL), provided that you have satisfied its requirements. + */ + +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); + +#include <stdint.h> +#include <stdio.h> +#include <string.h> +#include <getopt.h> +#include <ipxe/image.h> +#include <ipxe/command.h> +#include <ipxe/parseopt.h> +#include <usr/imgmgmt.h> +#include <usr/imgcrypt.h> + +/** @file + * + * Image encryption management commands + * + */ + +/** "imgdecrypt" options */ +struct imgdecrypt_options { + /** Decrypted image name */ + char *name; + /** Keep envelope after decryption */ + int keep; + /** Download timeout */ + unsigned long timeout; +}; + +/** "imgdecrypt" option list */ +static struct option_descriptor imgdecrypt_opts[] = { + OPTION_DESC ( "name", 'n', required_argument, + struct imgdecrypt_options, name, parse_string ), + OPTION_DESC ( "keep", 'k', no_argument, + struct imgdecrypt_options, keep, parse_flag ), + OPTION_DESC ( "timeout", 't', required_argument, + struct imgdecrypt_options, timeout, parse_timeout), +}; + +/** "imgdecrypt" command descriptor */ +static struct command_descriptor imgdecrypt_cmd = + COMMAND_DESC ( struct imgdecrypt_options, imgdecrypt_opts, 2, 2, + "<uri|image> <envelope uri|image>" ); + +/** + * The "imgdecrypt" command + * + * @v argc Argument count + * @v argv Argument list + * @ret rc Return status code + */ +static int imgdecrypt_exec ( int argc, char **argv ) { + struct imgdecrypt_options opts; + const char *image_name_uri; + const char *envelope_name_uri; + struct image *image; + struct image *envelope; + int rc; + + /* Parse options */ + if ( ( rc = parse_options ( argc, argv, &imgdecrypt_cmd, &opts ) ) != 0) + return rc; + + /* Parse image name/URI string */ + image_name_uri = argv[optind]; + + /* Parse envelope name/URI string */ + envelope_name_uri = argv[ optind + 1 ]; + + /* Acquire the image */ + if ( ( rc = imgacquire ( image_name_uri, opts.timeout, &image ) ) != 0 ) + goto err_acquire_image; + + /* Acquire the envelope image */ + if ( ( rc = imgacquire ( envelope_name_uri, opts.timeout, + &envelope ) ) != 0 ) + goto err_acquire_envelope; + + /* Decrypt image */ + if ( ( rc = imgdecrypt ( image, envelope, opts.name ) ) != 0 ) { + printf ( "Could not decrypt: %s\n", strerror ( rc ) ); + goto err_decrypt; + } + + /* Success */ + rc = 0; + + err_decrypt: + /* Discard envelope unless --keep was specified */ + if ( ! opts.keep ) + unregister_image ( envelope ); + err_acquire_envelope: + err_acquire_image: + return rc; +} + +/** Image encryption management commands */ +COMMAND ( imgdecrypt, imgdecrypt_exec ); diff --git a/src/hci/commands/image_mem_cmd.c b/src/hci/commands/image_mem_cmd.c index c8bfab1ad..60c0bf92a 100644 --- a/src/hci/commands/image_mem_cmd.c +++ b/src/hci/commands/image_mem_cmd.c @@ -24,6 +24,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #include <getopt.h> +#include <ipxe/uaccess.h> #include <ipxe/command.h> #include <ipxe/parseopt.h> #include <usr/imgmgmt.h> @@ -81,16 +82,11 @@ static int imgmem_exec ( int argc, char **argv ) { return rc; /* Create image */ - if ( ( rc = imgmem ( opts.name, phys_to_user ( data ), len ) ) != 0 ) + if ( ( rc = imgmem ( opts.name, phys_to_virt ( data ), len ) ) != 0 ) return rc; return 0; } /** Read memory command */ -struct command imgmem_commands[] __command = { - { - .name = "imgmem", - .exec = imgmem_exec, - }, -}; +COMMAND ( imgmem, imgmem_exec ); diff --git a/src/hci/commands/image_trust_cmd.c b/src/hci/commands/image_trust_cmd.c index b34378f93..a8ec5784e 100644 --- a/src/hci/commands/image_trust_cmd.c +++ b/src/hci/commands/image_trust_cmd.c @@ -22,9 +22,11 @@ */ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); +FILE_SECBOOT ( PERMITTED ); #include <stdint.h> #include <stdio.h> +#include <string.h> #include <getopt.h> #include <ipxe/image.h> #include <ipxe/command.h> @@ -162,13 +164,5 @@ static int imgverify_exec ( int argc, char **argv ) { } /** Image trust management commands */ -struct command image_trust_commands[] __command = { - { - .name = "imgtrust", - .exec = imgtrust_exec, - }, - { - .name = "imgverify", - .exec = imgverify_exec, - }, -}; +COMMAND ( imgtrust, imgtrust_exec ); +COMMAND ( imgverify, imgverify_exec ); diff --git a/src/hci/commands/ipstat_cmd.c b/src/hci/commands/ipstat_cmd.c index 763e4dfd6..fc454c57d 100644 --- a/src/hci/commands/ipstat_cmd.c +++ b/src/hci/commands/ipstat_cmd.c @@ -22,6 +22,7 @@ */ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); +FILE_SECBOOT ( PERMITTED ); #include <stdio.h> #include <getopt.h> @@ -66,9 +67,4 @@ static int ipstat_exec ( int argc, char **argv ) { } /** Routing table management commands */ -struct command ipstat_commands[] __command = { - { - .name = "ipstat", - .exec = ipstat_exec, - }, -}; +COMMAND ( ipstat, ipstat_exec ); diff --git a/src/hci/commands/iwmgmt_cmd.c b/src/hci/commands/iwmgmt_cmd.c index b61ee8c7b..b430353d9 100644 --- a/src/hci/commands/iwmgmt_cmd.c +++ b/src/hci/commands/iwmgmt_cmd.c @@ -113,13 +113,5 @@ static int iwlist_exec ( int argc, char **argv ) { } /** Wireless interface management commands */ -struct command iwmgmt_commands[] __command = { - { - .name = "iwstat", - .exec = iwstat_exec, - }, - { - .name = "iwlist", - .exec = iwlist_exec, - }, -}; +COMMAND ( iwstat, iwstat_exec ); +COMMAND ( iwlist, iwlist_exec ); diff --git a/src/hci/commands/login_cmd.c b/src/hci/commands/login_cmd.c index 6ed76c6f2..faa8d9852 100644 --- a/src/hci/commands/login_cmd.c +++ b/src/hci/commands/login_cmd.c @@ -29,6 +29,7 @@ #include <ipxe/login_ui.h> FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); +FILE_SECBOOT ( PERMITTED ); /** @file * @@ -78,7 +79,4 @@ static int login_exec ( int argc, char **argv ) { } /** Login commands */ -struct command login_command __command = { - .name = "login", - .exec = login_exec, -}; +COMMAND ( login, login_exec ); diff --git a/src/hci/commands/lotest_cmd.c b/src/hci/commands/lotest_cmd.c index 393b3c36e..ee3b0d3b5 100644 --- a/src/hci/commands/lotest_cmd.c +++ b/src/hci/commands/lotest_cmd.c @@ -100,7 +100,4 @@ static int lotest_exec ( int argc, char **argv ) { } /** Loopback testing commands */ -struct command lotest_command __command = { - .name = "lotest", - .exec = lotest_exec, -}; +COMMAND ( lotest, lotest_exec ); diff --git a/src/hci/commands/neighbour_cmd.c b/src/hci/commands/neighbour_cmd.c index 816e87357..870024ee0 100644 --- a/src/hci/commands/neighbour_cmd.c +++ b/src/hci/commands/neighbour_cmd.c @@ -22,6 +22,7 @@ */ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); +FILE_SECBOOT ( PERMITTED ); /** @file * @@ -65,9 +66,4 @@ static int nstat_exec ( int argc, char **argv ) { } /** Neighbour management commands */ -struct command neighbour_commands[] __command = { - { - .name = "nstat", - .exec = nstat_exec, - }, -}; +COMMAND ( nstat, nstat_exec ); diff --git a/src/hci/commands/nslookup_cmd.c b/src/hci/commands/nslookup_cmd.c index 265afdc3d..b13127dd4 100644 --- a/src/hci/commands/nslookup_cmd.c +++ b/src/hci/commands/nslookup_cmd.c @@ -18,6 +18,7 @@ */ FILE_LICENCE ( GPL2_OR_LATER ); +FILE_SECBOOT ( PERMITTED ); #include <stdio.h> #include <getopt.h> @@ -73,7 +74,4 @@ static int nslookup_exec ( int argc, char **argv ) { } /** The "nslookup" command */ -struct command nslookup_command __command = { - .name = "nslookup", - .exec = nslookup_exec, -}; +COMMAND ( nslookup, nslookup_exec ); diff --git a/src/hci/commands/ntp_cmd.c b/src/hci/commands/ntp_cmd.c index 8f741a512..d7604227a 100644 --- a/src/hci/commands/ntp_cmd.c +++ b/src/hci/commands/ntp_cmd.c @@ -22,6 +22,7 @@ */ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); +FILE_SECBOOT ( PERMITTED ); #include <stdio.h> #include <string.h> @@ -75,7 +76,4 @@ static int ntp_exec ( int argc, char **argv ) { } /** NTP command */ -struct command ntp_command __command = { - .name = "ntp", - .exec = ntp_exec, -}; +COMMAND ( ntp, ntp_exec ); diff --git a/src/hci/commands/nvo_cmd.c b/src/hci/commands/nvo_cmd.c index 6ad7e7428..70086afce 100644 --- a/src/hci/commands/nvo_cmd.c +++ b/src/hci/commands/nvo_cmd.c @@ -34,6 +34,7 @@ #include <readline/readline.h> FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); +FILE_SECBOOT ( PERMITTED ); /** @file * @@ -356,25 +357,8 @@ static int inc_exec ( int argc, char **argv ) { } /** Non-volatile option commands */ -struct command nvo_commands[] __command = { - { - .name = "show", - .exec = show_exec, - }, - { - .name = "set", - .exec = set_exec, - }, - { - .name = "clear", - .exec = clear_exec, - }, - { - .name = "read", - .exec = read_exec, - }, - { - .name = "inc", - .exec = inc_exec, - }, -}; +COMMAND ( show, show_exec ); +COMMAND ( set, set_exec ); +COMMAND ( clear, clear_exec ); +COMMAND ( read, read_exec ); +COMMAND ( inc, inc_exec ); diff --git a/src/hci/commands/param_cmd.c b/src/hci/commands/param_cmd.c index dad99f840..ed57c5eaa 100644 --- a/src/hci/commands/param_cmd.c +++ b/src/hci/commands/param_cmd.c @@ -22,6 +22,7 @@ */ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); +FILE_SECBOOT ( PERMITTED ); /** @file * @@ -163,13 +164,5 @@ static int param_exec ( int argc, char **argv ) { } /** Request parameter commands */ -struct command param_commands[] __command = { - { - .name = "params", - .exec = params_exec, - }, - { - .name = "param", - .exec = param_exec, - }, -}; +COMMAND ( params, params_exec ); +COMMAND ( param, param_exec ); diff --git a/src/hci/commands/pci_cmd.c b/src/hci/commands/pci_cmd.c index 5bae66fbe..2e9505752 100644 --- a/src/hci/commands/pci_cmd.c +++ b/src/hci/commands/pci_cmd.c @@ -22,6 +22,7 @@ */ #include <stdio.h> +#include <string.h> #include <errno.h> #include <getopt.h> #include <ipxe/pci.h> @@ -29,6 +30,7 @@ #include <ipxe/parseopt.h> FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); +FILE_SECBOOT ( PERMITTED ); /** @file * @@ -114,9 +116,4 @@ static int pciscan_exec ( int argc, char **argv ) { } /** PCI commands */ -struct command pci_commands[] __command = { - { - .name = "pciscan", - .exec = pciscan_exec, - }, -}; +COMMAND ( pciscan, pciscan_exec ); diff --git a/src/hci/commands/ping_cmd.c b/src/hci/commands/ping_cmd.c index ab271e75a..e132fb457 100644 --- a/src/hci/commands/ping_cmd.c +++ b/src/hci/commands/ping_cmd.c @@ -22,6 +22,7 @@ */ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); +FILE_SECBOOT ( PERMITTED ); #include <stdint.h> #include <stdlib.h> @@ -107,7 +108,4 @@ static int ping_exec ( int argc, char **argv ) { } /** Ping command */ -struct command ping_command __command = { - .name = "ping", - .exec = ping_exec, -}; +COMMAND ( ping, ping_exec ); diff --git a/src/hci/commands/poweroff_cmd.c b/src/hci/commands/poweroff_cmd.c index afdf12dde..63aeb3d5b 100644 --- a/src/hci/commands/poweroff_cmd.c +++ b/src/hci/commands/poweroff_cmd.c @@ -29,6 +29,7 @@ #include <ipxe/reboot.h> FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); +FILE_SECBOOT ( PERMITTED ); /** @file * @@ -70,7 +71,4 @@ static int poweroff_exec ( int argc, char **argv ) { } /** "poweroff" command */ -struct command poweroff_command __command = { - .name = "poweroff", - .exec = poweroff_exec, -}; +COMMAND ( poweroff, poweroff_exec ); diff --git a/src/hci/commands/profstat_cmd.c b/src/hci/commands/profstat_cmd.c index dc6f649e3..3303ebcf3 100644 --- a/src/hci/commands/profstat_cmd.c +++ b/src/hci/commands/profstat_cmd.c @@ -22,6 +22,7 @@ */ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); +FILE_SECBOOT ( PERMITTED ); #include <stdio.h> #include <getopt.h> @@ -66,9 +67,4 @@ static int profstat_exec ( int argc, char **argv ) { } /** Profiling commands */ -struct command profstat_commands[] __command = { - { - .name = "profstat", - .exec = profstat_exec, - }, -}; +COMMAND ( profstat, profstat_exec ); diff --git a/src/hci/commands/reboot_cmd.c b/src/hci/commands/reboot_cmd.c index 45d54cc2c..daef92dc0 100644 --- a/src/hci/commands/reboot_cmd.c +++ b/src/hci/commands/reboot_cmd.c @@ -27,6 +27,7 @@ #include <ipxe/reboot.h> FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); +FILE_SECBOOT ( PERMITTED ); /** @file * @@ -38,12 +39,16 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); struct reboot_options { /** Perform a warm reboot */ int warm; + /** Reboot to firmware setup */ + int setup; }; /** "reboot" option list */ static struct option_descriptor reboot_opts[] = { OPTION_DESC ( "warm", 'w', no_argument, struct reboot_options, warm, parse_flag ), + OPTION_DESC ( "setup", 's', no_argument, + struct reboot_options, setup, parse_flag ), }; /** "reboot" command descriptor */ @@ -59,6 +64,7 @@ static struct command_descriptor reboot_cmd = */ static int reboot_exec ( int argc, char **argv ) { struct reboot_options opts; + int flags = 0; int rc; /* Parse options */ @@ -66,13 +72,14 @@ static int reboot_exec ( int argc, char **argv ) { return rc; /* Reboot system */ - reboot ( opts.warm ); + if ( opts.warm ) + flags |= REBOOT_WARM; + if ( opts.setup ) + flags |= REBOOT_SETUP; + reboot ( flags ); return 0; } /** "reboot" command */ -struct command reboot_command __command = { - .name = "reboot", - .exec = reboot_exec, -}; +COMMAND ( reboot, reboot_exec ); diff --git a/src/hci/commands/route_cmd.c b/src/hci/commands/route_cmd.c index 8aa535363..ff841ec15 100644 --- a/src/hci/commands/route_cmd.c +++ b/src/hci/commands/route_cmd.c @@ -22,6 +22,7 @@ */ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); +FILE_SECBOOT ( PERMITTED ); #include <stdio.h> #include <getopt.h> @@ -66,9 +67,4 @@ static int route_exec ( int argc, char **argv ) { } /** Routing table management commands */ -struct command route_commands[] __command = { - { - .name = "route", - .exec = route_exec, - }, -}; +COMMAND ( route, route_exec ); diff --git a/src/hci/commands/sanboot_cmd.c b/src/hci/commands/sanboot_cmd.c index 6ab9e8844..7bc60e641 100644 --- a/src/hci/commands/sanboot_cmd.c +++ b/src/hci/commands/sanboot_cmd.c @@ -32,6 +32,7 @@ #include <usr/autoboot.h> FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); +FILE_SECBOOT ( PERMITTED ); /** @file * @@ -204,17 +205,6 @@ static int sanunhook_exec ( int argc, char **argv ) { } /** SAN commands */ -struct command sanboot_commands[] __command = { - { - .name = "sanhook", - .exec = sanhook_exec, - }, - { - .name = "sanboot", - .exec = sanboot_exec, - }, - { - .name = "sanunhook", - .exec = sanunhook_exec, - }, -}; +COMMAND ( sanhook, sanhook_exec ); +COMMAND ( sanboot, sanboot_exec ); +COMMAND ( sanunhook, sanunhook_exec ); diff --git a/src/hci/commands/shim_cmd.c b/src/hci/commands/shim_cmd.c index 11956290a..1566af4e9 100644 --- a/src/hci/commands/shim_cmd.c +++ b/src/hci/commands/shim_cmd.c @@ -22,6 +22,7 @@ */ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); +FILE_SECBOOT ( PERMITTED ); #include <getopt.h> #include <ipxe/command.h> @@ -123,9 +124,4 @@ static int shim_exec ( int argc, char **argv ) { } /** Shim commands */ -struct command shim_commands[] __command = { - { - .name = "shim", - .exec = shim_exec, - }, -}; +COMMAND ( shim, shim_exec ); diff --git a/src/hci/commands/sync_cmd.c b/src/hci/commands/sync_cmd.c index 54799d422..e3b97298c 100644 --- a/src/hci/commands/sync_cmd.c +++ b/src/hci/commands/sync_cmd.c @@ -22,6 +22,7 @@ */ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); +FILE_SECBOOT ( PERMITTED ); #include <string.h> #include <stdio.h> @@ -77,7 +78,4 @@ static int sync_exec ( int argc, char **argv ) { } /** Sync commands */ -struct command sync_command __command = { - .name = "sync", - .exec = sync_exec, -}; +COMMAND ( sync, sync_exec ); diff --git a/src/hci/commands/time_cmd.c b/src/hci/commands/time_cmd.c index 08148bf38..2199321c7 100644 --- a/src/hci/commands/time_cmd.c +++ b/src/hci/commands/time_cmd.c @@ -21,6 +21,7 @@ */ FILE_LICENCE ( GPL2_OR_LATER ); +FILE_SECBOOT ( PERMITTED ); #include <stdio.h> #include <stdlib.h> @@ -77,7 +78,4 @@ static int time_exec ( int argc, char **argv ) { } /** "time" command */ -struct command time_command __command = { - .name = "time", - .exec = time_exec, -}; +COMMAND ( time, time_exec ); diff --git a/src/hci/commands/usb_cmd.c b/src/hci/commands/usb_cmd.c new file mode 100644 index 000000000..17affc0d7 --- /dev/null +++ b/src/hci/commands/usb_cmd.c @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2024 Michael Brown <mbrown@fensystems.co.uk>. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + * + * You can also choose to distribute this program under the terms of + * the Unmodified Binary Distribution Licence (as given in the file + * COPYING.UBDL), provided that you have satisfied its requirements. + */ + +#include <stdio.h> +#include <string.h> +#include <errno.h> +#include <getopt.h> +#include <ipxe/usb.h> +#include <ipxe/command.h> +#include <ipxe/parseopt.h> + +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); +FILE_SECBOOT ( PERMITTED ); + +/** @file + * + * USB commands + * + */ + +/** "usbscan" options */ +struct usbscan_options {}; + +/** "usbscan" option list */ +static struct option_descriptor usbscan_opts[] = {}; + +/** "usbscan" command descriptor */ +static struct command_descriptor usbscan_cmd = + COMMAND_DESC ( struct usbscan_options, usbscan_opts, 1, 1, + "<setting>" ); + +/** + * "usbscan" command + * + * @v argc Argument count + * @v argv Argument list + * @ret rc Return status code + */ +static int usbscan_exec ( int argc, char **argv ) { + struct usbscan_options opts; + struct named_setting setting; + struct usb_device *usb; + unsigned long prev; + uint16_t busdev; + int len; + int rc; + + /* Parse options */ + if ( ( rc = parse_options ( argc, argv, &usbscan_cmd, &opts ) ) != 0 ) + goto err_parse_options; + + /* Parse setting name */ + if ( ( rc = parse_autovivified_setting ( argv[optind], + &setting ) ) != 0 ) + goto err_parse_setting; + + /* Determine starting bus:dev.fn address */ + if ( ( len = fetchn_setting ( setting.settings, &setting.setting, + NULL, &setting.setting, &prev ) ) < 0 ) { + /* Setting not yet defined: start searching from 00:00 */ + busdev = 0; + } else { + /* Setting is defined: start searching from next location */ + busdev = ( prev + 1 ); + if ( ! busdev ) { + rc = -ENOENT; + goto err_end; + } + } + + /* Find next existent USB device */ + if ( ( rc = usb_find_next ( &usb, &busdev ) ) != 0 ) + goto err_find_next; + + /* Apply default type if necessary. Use ":uint16" rather than + * ":hex" to allow for easy inclusion within a + * "${usb/${location}....}" constructed setting. + */ + if ( ! setting.setting.type ) + setting.setting.type = &setting_type_uint16; + + /* Store setting */ + if ( ( rc = storen_setting ( setting.settings, &setting.setting, + busdev ) ) != 0 ) { + printf ( "Could not store \"%s\": %s\n", + setting.setting.name, strerror ( rc ) ); + goto err_store; + } + + err_store: + err_end: + err_find_next: + err_parse_setting: + err_parse_options: + return rc; +} + +/** USB commands */ +COMMAND ( usbscan, usbscan_exec ); diff --git a/src/hci/commands/vlan_cmd.c b/src/hci/commands/vlan_cmd.c index 8a2f0c749..69aef9f3c 100644 --- a/src/hci/commands/vlan_cmd.c +++ b/src/hci/commands/vlan_cmd.c @@ -22,6 +22,7 @@ */ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); +FILE_SECBOOT ( PERMITTED ); #include <stdio.h> #include <stdlib.h> @@ -131,13 +132,5 @@ static int vdestroy_exec ( int argc, char **argv ) { } /** VLAN commands */ -struct command vlan_commands[] __command = { - { - .name = "vcreate", - .exec = vcreate_exec, - }, - { - .name = "vdestroy", - .exec = vdestroy_exec, - }, -}; +COMMAND ( vcreate, vcreate_exec ); +COMMAND ( vdestroy, vdestroy_exec ); |
