summaryrefslogtreecommitdiffstats
path: root/src/hci
diff options
context:
space:
mode:
Diffstat (limited to 'src/hci')
-rw-r--r--src/hci/commands/image_archive_cmd.c105
-rw-r--r--src/hci/commands/nvo_cmd.c57
-rw-r--r--src/hci/readline.c17
-rw-r--r--src/hci/shell.c2
4 files changed, 163 insertions, 18 deletions
diff --git a/src/hci/commands/image_archive_cmd.c b/src/hci/commands/image_archive_cmd.c
new file mode 100644
index 000000000..a2212aecf
--- /dev/null
+++ b/src/hci/commands/image_archive_cmd.c
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2021 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/imgarchive.h>
+
+/** @file
+ *
+ * Archive image commands
+ *
+ */
+
+/** "imgextract" options */
+struct imgextract_options {
+ /** Image name */
+ char *name;
+ /** Keep original image */
+ int keep;
+ /** Download timeout */
+ unsigned long timeout;
+};
+
+/** "imgextract" option list */
+static struct option_descriptor imgextract_opts[] = {
+ OPTION_DESC ( "name", 'n', required_argument,
+ struct imgextract_options, name, parse_string ),
+ OPTION_DESC ( "keep", 'k', no_argument,
+ struct imgextract_options, keep, parse_flag ),
+ OPTION_DESC ( "timeout", 't', required_argument,
+ struct imgextract_options, timeout, parse_timeout ),
+};
+
+/** "imgextract" command descriptor */
+static struct command_descriptor imgextract_cmd =
+ COMMAND_DESC ( struct imgextract_options, imgextract_opts, 1, 1, NULL );
+
+/**
+ * The "imgextract" command
+ *
+ * @v argc Argument count
+ * @v argv Argument list
+ * @ret rc Return status code
+ */
+static int imgextract_exec ( int argc, char **argv ) {
+ struct imgextract_options opts;
+ struct image *image;
+ int rc;
+
+ /* Parse options */
+ if ( ( rc = parse_options ( argc, argv, &imgextract_cmd,
+ &opts ) ) != 0 )
+ goto err_parse;
+
+ /* Acquire image */
+ if ( ( rc = imgacquire ( argv[optind], opts.timeout, &image ) ) != 0 )
+ goto err_acquire;
+
+ /* Extract archive image */
+ if ( ( rc = imgextract ( image, opts.name ) ) != 0 )
+ goto err_extract;
+
+ /* Success */
+ rc = 0;
+
+ err_extract:
+ /* Discard original image unless --keep was specified */
+ if ( ! opts.keep )
+ unregister_image ( image );
+ err_acquire:
+ err_parse:
+ return rc;
+}
+
+/** Archive image commands */
+struct command image_archive_commands[] __command = {
+ {
+ .name = "imgextract",
+ .exec = imgextract_exec,
+ },
+};
diff --git a/src/hci/commands/nvo_cmd.c b/src/hci/commands/nvo_cmd.c
index ac0d60651..6ad7e7428 100644
--- a/src/hci/commands/nvo_cmd.c
+++ b/src/hci/commands/nvo_cmd.c
@@ -100,20 +100,40 @@ static int show_exec ( int argc, char **argv ) {
}
/** "set", "clear", and "read" options */
-struct set_core_options {};
+struct set_core_options {
+ /** Timeout */
+ unsigned long timeout;
+};
/** "set", "clear", and "read" option list */
-static struct option_descriptor set_core_opts[] = {};
+static union {
+ /* "set" takes no options */
+ struct option_descriptor set[0];
+ /* "clear" takes no options */
+ struct option_descriptor clear[0];
+ /* "read" takes --timeout option */
+ struct option_descriptor read[1];
+} set_core_opts = {
+ .read = {
+ OPTION_DESC ( "timeout", 't', required_argument,
+ struct set_core_options, timeout, parse_timeout ),
+ },
+};
/** "set" command descriptor */
static struct command_descriptor set_cmd =
- COMMAND_DESC ( struct set_core_options, set_core_opts, 1, MAX_ARGUMENTS,
- "<setting> <value>" );
+ COMMAND_DESC ( struct set_core_options, set_core_opts.set,
+ 1, MAX_ARGUMENTS, "<setting> <value>" );
+
+/** "clear" command descriptor */
+static struct command_descriptor clear_cmd =
+ COMMAND_DESC ( struct set_core_options, set_core_opts.clear,
+ 1, 1, "<setting>" );
-/** "clear" and "read" command descriptor */
-static struct command_descriptor clear_read_cmd =
- COMMAND_DESC ( struct set_core_options, set_core_opts, 1, 1,
- "<setting>" );
+/** "read" command descriptor */
+static struct command_descriptor read_cmd =
+ COMMAND_DESC ( struct set_core_options, set_core_opts.read,
+ 1, 1, "<setting>" );
/**
* "set", "clear", and "read" command
@@ -127,6 +147,7 @@ static struct command_descriptor clear_read_cmd =
static int set_core_exec ( int argc, char **argv,
struct command_descriptor *cmd,
int ( * get_value ) ( struct named_setting *setting,
+ struct set_core_options *opts,
char **args, char **value ) ) {
struct set_core_options opts;
struct named_setting setting;
@@ -143,7 +164,8 @@ static int set_core_exec ( int argc, char **argv,
goto err_parse_setting;
/* Parse setting value */
- if ( ( rc = get_value ( &setting, &argv[ optind + 1 ], &value ) ) != 0 )
+ if ( ( rc = get_value ( &setting, &opts, &argv[ optind + 1 ],
+ &value ) ) != 0 )
goto err_get_value;
/* Apply default type if necessary */
@@ -170,11 +192,13 @@ static int set_core_exec ( int argc, char **argv,
* Get setting value for "set" command
*
* @v setting Named setting
+ * @v opts Options list
* @v args Remaining arguments
* @ret value Setting value
* @ret rc Return status code
*/
static int set_value ( struct named_setting *setting __unused,
+ struct set_core_options *opts __unused,
char **args, char **value ) {
*value = concat_args ( args );
@@ -200,10 +224,12 @@ static int set_exec ( int argc, char **argv ) {
*
* @v setting Named setting
* @v args Remaining arguments
+ * @v opts Options list
* @ret value Setting value
* @ret rc Return status code
*/
static int clear_value ( struct named_setting *setting __unused,
+ struct set_core_options *opts __unused,
char **args __unused, char **value ) {
*value = NULL;
@@ -218,7 +244,7 @@ static int clear_value ( struct named_setting *setting __unused,
* @ret rc Return status code
*/
static int clear_exec ( int argc, char **argv ) {
- return set_core_exec ( argc, argv, &clear_read_cmd, clear_value );
+ return set_core_exec ( argc, argv, &clear_cmd, clear_value );
}
/**
@@ -226,11 +252,13 @@ static int clear_exec ( int argc, char **argv ) {
*
* @v setting Named setting
* @v args Remaining arguments
+ * @v opts Options list
* @ret value Setting value
* @ret rc Return status code
*/
-static int read_value ( struct named_setting *setting, char **args __unused,
- char **value ) {
+static int read_value ( struct named_setting *setting,
+ struct set_core_options *opts,
+ char **args __unused, char **value ) {
char *existing;
int rc;
@@ -241,7 +269,8 @@ static int read_value ( struct named_setting *setting, char **args __unused,
NULL, &setting->setting, &existing );
/* Read new value */
- if ( ( rc = readline_history ( NULL, existing, NULL, value ) ) != 0 )
+ if ( ( rc = readline_history ( NULL, existing, NULL, opts->timeout,
+ value ) ) != 0 )
goto err_readline;
err_readline:
@@ -257,7 +286,7 @@ static int read_value ( struct named_setting *setting, char **args __unused,
* @ret rc Return status code
*/
static int read_exec ( int argc, char **argv ) {
- return set_core_exec ( argc, argv, &clear_read_cmd, read_value );
+ return set_core_exec ( argc, argv, &read_cmd, read_value );
}
/** "inc" options */
diff --git a/src/hci/readline.c b/src/hci/readline.c
index 83a2e0b90..852c4503a 100644
--- a/src/hci/readline.c
+++ b/src/hci/readline.c
@@ -248,6 +248,7 @@ void history_free ( struct readline_history *history ) {
* @v prompt Prompt string
* @v prefill Prefill string, or NULL for no prefill
* @v history History buffer, or NULL for no history
+ * @v timeout Timeout period, in ticks (0=indefinite)
* @ret line Line read from console (excluding terminating newline)
* @ret rc Return status code
*
@@ -255,7 +256,8 @@ void history_free ( struct readline_history *history ) {
* eventually call free() to release the storage.
*/
int readline_history ( const char *prompt, const char *prefill,
- struct readline_history *history, char **line ) {
+ struct readline_history *history, unsigned long timeout,
+ char **line ) {
char buf[READLINE_MAX];
struct edit_string string;
int key;
@@ -285,8 +287,17 @@ int readline_history ( const char *prompt, const char *prefill,
}
while ( 1 ) {
+
+ /* Get keypress */
+ key = getkey ( timeout );
+ if ( key < 0 ) {
+ rc = -ETIMEDOUT;
+ goto done;
+ }
+ timeout = 0;
+
/* Handle keypress */
- key = edit_string ( &string, getkey ( 0 ) );
+ key = edit_string ( &string, key );
sync_console ( &string );
move_by = 0;
switch ( key ) {
@@ -342,6 +353,6 @@ int readline_history ( const char *prompt, const char *prefill,
char * readline ( const char *prompt ) {
char *line;
- readline_history ( prompt, NULL, NULL, &line );
+ readline_history ( prompt, NULL, NULL, 0, &line );
return line;
}
diff --git a/src/hci/shell.c b/src/hci/shell.c
index 276eb3527..8ecf73a6f 100644
--- a/src/hci/shell.c
+++ b/src/hci/shell.c
@@ -91,7 +91,7 @@ int shell ( void ) {
/* Read and execute commands */
do {
- readline_history ( shell_prompt, NULL, &history, &line );
+ readline_history ( shell_prompt, NULL, &history, 0, &line );
if ( line ) {
rc = system ( line );
free ( line );