This allows to specify a list of fields which are printed.

Example:

$ bg_printenv --current --output ustate
Using latest config partition
Values:
ustate:           0 (OK)

Signed-off-by: Michael Adler <[email protected]>
---
 tests/bg_setenv.bats |  20 +++++++
 tools/bg_setenv.c    | 132 ++++++++++++++++++++++++++++++++-----------
 2 files changed, 119 insertions(+), 33 deletions(-)

diff --git a/tests/bg_setenv.bats b/tests/bg_setenv.bats
index 87779e6..f4739fd 100755
--- a/tests/bg_setenv.bats
+++ b/tests/bg_setenv.bats
@@ -114,3 +114,23 @@ foo = bar" ]]
     run md5sum "$envfile"
     [[ "$output" =~ ^a24b154a48e1f33b79b87e0fa5eff8a1\s*.* ]]
 }
+
+@test "bg_printenv ustate" {
+    local envfile
+    envfile="$(mktemp -d)/BGENV.DAT"
+
+    create_sample_bgenv "$envfile"
+    run bg_printenv "--filepath=$envfile" --output ustate
+    [[ "$output" = "Values:
+ustate:           0 (OK)" ]]
+}
+
+@test "bg_printenv with all fields is the same as omitting fields" {
+    local envfile
+    envfile="$(mktemp -d)/BGENV.DAT"
+
+    create_sample_bgenv "$envfile"
+    expected_output=$(bg_printenv "--filepath=$envfile")
+    run bg_printenv "--filepath=$envfile" --output 
in_progress,revision,kernel,kernelargs,watchdog_timeout,ustate,user
+    [[ "$output" = "$expected_output" ]]
+}
diff --git a/tools/bg_setenv.c b/tools/bg_setenv.c
index 5ce4809..2f6105f 100644
--- a/tools/bg_setenv.c
+++ b/tools/bg_setenv.c
@@ -59,6 +59,11 @@ static struct argp_option options_printenv[] = {
        BG_CLI_OPTIONS_COMMON,
        {"current", 'c', 0, 0,
         "Only print values from the current environment"},
+       {"output", 'o', "LIST", 0,
+        "Comma-separated list of fields which are printed. "
+        "Available fields: in_progress, revision, kernel, kernelargs, "
+        "watchdog_timeout, ustate, user. "
+        "If omitted, all available fields are printed."},
        {},
 };
 
@@ -88,8 +93,19 @@ struct arguments_setenv {
 struct arguments_printenv {
        struct arguments_common common;
        bool current;
+       /* a bitset to decide which fields are printed */
+       int output_fields;
 };
 
+#define MASK_IN_PROGRESS  (1 << 0)
+#define MASK_REVISION    (1 << 1)
+#define MASK_KERNEL      (1 << 2)
+#define MASK_KERNELARGS          (1 << 3)
+#define MASK_WDOG_TIMEOUT (1 << 4)
+#define MASK_USTATE      (1 << 5)
+#define MASK_USER        (1 << 6)
+#define MASK_ALL         0x7F /* binary: 1111111 */
+
 typedef enum { ENV_TASK_SET, ENV_TASK_DEL } BGENV_TASK;
 
 struct stailhead *headp;
@@ -460,14 +476,47 @@ static error_t parse_setenv_opt(int key, char *arg, 
struct argp_state *state)
        return e;
 }
 
+static error_t parse_output_fields(char *fields, int *output_fields)
+{
+       char *token;
+       /* reset */
+       *output_fields = 0;
+       while ((token = strsep(&fields, ","))) {
+               if (*token == '\0') continue;
+               if (strcmp(token, "in_progress") == 0) {
+                       *output_fields |= MASK_IN_PROGRESS;
+               } else if (strcmp(token, "revision") == 0) {
+                       *output_fields |= MASK_REVISION;
+               } else if (strcmp(token, "kernel") == 0) {
+                       *output_fields |= MASK_KERNEL;
+               } else if (strcmp(token, "kernelargs") == 0) {
+                       *output_fields |= MASK_KERNELARGS;
+               } else if (strcmp(token, "watchdog_timeout") == 0) {
+                       *output_fields |= MASK_WDOG_TIMEOUT;
+               } else if (strcmp(token, "ustate") == 0) {
+                       *output_fields |= MASK_USTATE;
+               } else if (strcmp(token, "user") == 0) {
+                       *output_fields |= MASK_USER;
+               } else {
+                       fprintf(stderr, "Unknown output field: %s\n", token);
+                       return 1;
+               }
+       }
+       return 0;
+}
+
 static error_t parse_printenv_opt(int key, char *arg, struct argp_state *state)
 {
        struct arguments_printenv *arguments = state->input;
+       error_t e = 0;
 
        switch (key) {
        case 'c':
                arguments->current = true;
                break;
+       case 'o':
+               e = parse_output_fields(arg, &arguments->output_fields);
+               break;
        case ARGP_KEY_ARG:
                /* too many arguments - program terminates with call to
                 * argp_usage with non-zero return code */
@@ -477,7 +526,7 @@ static error_t parse_printenv_opt(int key, char *arg, 
struct argp_state *state)
                return parse_common_opt(key, arg, false, &arguments->common);
        }
 
-       return 0;
+       return e;
 }
 
 static void dump_uservars(uint8_t *udata)
@@ -549,24 +598,38 @@ static void dump_uservars(uint8_t *udata)
        }
 }
 
-static void dump_env(BG_ENVDATA *env)
+static void dump_env(BG_ENVDATA *env, int output_fields)
 {
        char buffer[ENV_STRING_LENGTH];
        fprintf(stdout, "Values:\n");
-       fprintf(stdout,
-               "in_progress:      %s\n",env->in_progress ? "yes" : "no");
-       fprintf(stdout, "revision:         %u\n", env->revision);
-       fprintf(stdout,
-               "kernel:           %s\n", str16to8(buffer, env->kernelfile));
-       fprintf(stdout,
-               "kernelargs:       %s\n", str16to8(buffer, env->kernelparams));
-       fprintf(stdout,
-               "watchdog timeout: %u seconds\n", env->watchdog_timeout_sec);
-       fprintf(stdout, "ustate:           %u (%s)\n", (uint8_t)env->ustate,
-              ustate2str(env->ustate));
-       fprintf(stdout, "\n");
-       fprintf(stdout, "user variables:\n");
-       dump_uservars(env->userdata);
+       if (output_fields & MASK_IN_PROGRESS) {
+               fprintf(stdout, "in_progress:      %s\n",
+                       env->in_progress ? "yes" : "no");
+       }
+       if (output_fields & MASK_REVISION) {
+               fprintf(stdout, "revision:         %u\n", env->revision);
+       }
+       if (output_fields & MASK_KERNEL) {
+               fprintf(stdout, "kernel:           %s\n",
+                       str16to8(buffer, env->kernelfile));
+       }
+       if (output_fields & MASK_KERNELARGS) {
+               fprintf(stdout, "kernelargs:       %s\n",
+                       str16to8(buffer, env->kernelparams));
+       }
+       if (output_fields & MASK_WDOG_TIMEOUT) {
+               fprintf(stdout, "watchdog timeout: %u seconds\n",
+                       env->watchdog_timeout_sec);
+       }
+       if (output_fields & MASK_USTATE) {
+               fprintf(stdout, "ustate:           %u (%s)\n",
+                       (uint8_t)env->ustate, ustate2str(env->ustate));
+       }
+       if (output_fields & MASK_USER) {
+               fprintf(stdout, "\n");
+               fprintf(stdout, "user variables:\n");
+               dump_uservars(env->userdata);
+       }
        fprintf(stdout, "\n\n");
 }
 
@@ -589,7 +652,7 @@ static void update_environment(BGENV *env, bool verbosity)
 
 }
 
-static void dump_envs(void)
+static void dump_envs(int output_fields)
 {
        for (int i = 0; i < ENV_NUM_CONFIG_PARTS; i++) {
                fprintf(stdout, "\n----------------------------\n");
@@ -601,30 +664,30 @@ static void dump_envs(void)
                                i);
                        return;
                }
-               dump_env(env->data);
+               dump_env(env->data, output_fields);
                bgenv_close(env);
        }
 }
 
-static void dump_latest_env(void)
+static void dump_latest_env(int output_fields)
 {
        BGENV *env = bgenv_open_latest();
        if (!env) {
                fprintf(stderr, "Failed to retrieve latest environment.\n");
                return;
        }
-       dump_env(env->data);
+       dump_env(env->data, output_fields);
        bgenv_close(env);
 }
 
-static void dump_env_by_index(uint32_t index)
+static void dump_env_by_index(uint32_t index, int output_fields)
 {
        BGENV *env = bgenv_open_by_index(index);
        if (!env) {
                fprintf(stderr, "Failed to retrieve latest environment.\n");
                return;
        }
-       dump_env(env->data);
+       dump_env(env->data, output_fields);
        bgenv_close(env);
 }
 
@@ -653,13 +716,14 @@ static bool get_env(char *configfilepath, BG_ENVDATA 
*data)
        return result;
 }
 
-static int printenv_from_file(char *envfilepath) {
+static int printenv_from_file(char *envfilepath, int output_fields)
+{
        int success = 0;
        BG_ENVDATA data;
 
        success = get_env(envfilepath, &data);
        if (success) {
-               dump_env(&data);
+               dump_env(&data, output_fields);
                return 0;
        } else {
                fprintf(stderr, "Error reading environment file.\n");
@@ -684,7 +748,7 @@ static int dumpenv_to_file(char *envfilepath, bool 
verbosity, bool preserve_env)
 
        update_environment(&env, verbosity);
        if (verbosity) {
-               dump_env(env.data);
+               dump_env(env.data, MASK_ALL);
        }
        FILE *of = fopen(envfilepath, "wb");
        if (of) {
@@ -718,8 +782,9 @@ static error_t bg_printenv(int argc, char **argv)
                .doc = doc,
        };
 
-       struct arguments_printenv arguments;
-       memset(&arguments, 0, sizeof(struct arguments_printenv));
+       struct arguments_printenv arguments = {
+               .output_fields = MASK_ALL,
+       };
 
        error_t e = argp_parse(&argp_printenv, argc, argv, 0, 0, &arguments);
        if (e) {
@@ -741,7 +806,8 @@ static error_t bg_printenv(int argc, char **argv)
        }
 
        if (common->envfilepath) {
-               e = printenv_from_file(common->envfilepath);
+               e = printenv_from_file(common->envfilepath,
+                                      arguments.output_fields);
                free(common->envfilepath);
                return e;
        }
@@ -754,13 +820,13 @@ static error_t bg_printenv(int argc, char **argv)
 
        if (arguments.current) {
                fprintf(stdout, "Using latest config partition\n");
-               dump_latest_env();
+               dump_latest_env(arguments.output_fields);
        } else if (common->part_specified) {
                fprintf(stdout, "Using config partition #%d\n",
                        arguments.common.which_part);
-               dump_env_by_index(common->which_part);
+               dump_env_by_index(common->which_part, arguments.output_fields);
        } else {
-               dump_envs();
+               dump_envs(arguments.output_fields);
        }
 
        bgenv_finalize();
@@ -821,7 +887,7 @@ static error_t bg_setenv(int argc, char **argv)
        }
 
        if (arguments.common.verbosity) {
-               dump_envs();
+               dump_envs(MASK_ALL);
        }
 
        BGENV *env_new = NULL;
@@ -883,7 +949,7 @@ static error_t bg_setenv(int argc, char **argv)
        if (arguments.common.verbosity) {
                fprintf(stdout, "New environment data:\n");
                fprintf(stdout, "---------------------\n");
-               dump_env(env_new->data);
+               dump_env(env_new->data, MASK_ALL);
        }
        if (!bgenv_write(env_new)) {
                fprintf(stderr, "Error storing environment.\n");
-- 
2.33.0

-- 
You received this message because you are subscribed to the Google Groups "EFI 
Boot Guard" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/efibootguard-dev/20211103145707.3012399-9-michael.adler%40siemens.com.

Reply via email to