The tools bg_setenv and bg_printenv are mostly oriented at running systems
that have the partitions providing BG environments already mounted.
This patch extends bg_printenv so that the environment can be read directly
from whatever valid BG environment file. This usage is very usefull in
development, diagnose, testing,... scenarios.
Signed-off-by: Silvano Cirujano Cuesta <
silvano.cir...@siemens.com>
Signed-off-by: Jan Kiszka <
jan.k...@siemens.com>
---
 env/env_api_fat.c        | 4 +--
 env/env_config_file.c    | 24 +++++++++------
 include/env_config_file.h | 3 +-
 tools/bg_setenv.c        | 64 ++++++++++++++++++++++++++++++++++-----
 4 files changed, 75 insertions(+), 20 deletions(-)
diff --git a/env/env_api_fat.c b/env/env_api_fat.c
index 2b23e7f..3732050 100644
--- a/env/env_api_fat.c
+++ b/env/env_api_fat.c
@@ -67,7 +67,7 @@ bool read_env(CONFIG_PART *part, BG_ENVDATA *env)
          part->mountpoint);
    }
    FILE *config;
-Â Â Â if (!(config = open_config_file(part, "rb"))) {
+Â Â Â if (!(config = open_config_file_from_part(part, "rb"))) {
       return false;
    }
    bool result = true;
@@ -104,7 +104,7 @@ bool write_env(CONFIG_PART *part, BG_ENVDATA *env)
          part->mountpoint);
    }
    FILE *config;
-Â Â Â if (!(config = open_config_file(part, "wb"))) {
+Â Â Â if (!(config = open_config_file_from_part(part, "wb"))) {
       VERBOSE(stderr, "Could not open config file for writing.\n");
       return false;
    }
diff --git a/env/env_config_file.c b/env/env_config_file.c
index 873fe10..4e68b7f 100644
--- a/env/env_config_file.c
+++ b/env/env_config_file.c
@@ -18,7 +18,19 @@
 #include "env_disk_utils.h"
 #include "env_config_file.h"
Â
-FILE *open_config_file(CONFIG_PART *cfgpart, char *mode)
+FILE *open_config_file(char *configfilepath, char *mode)
+{
+Â Â Â if (!configfilepath) {
+Â Â Â Â Â Â return NULL;
+Â Â Â }
+
+Â Â Â VERBOSE(stdout, "Probing config file at %s.\n", configfilepath);
+Â Â Â FILE *config = fopen(configfilepath, mode);
+Â Â Â free(configfilepath);
+Â Â Â return config;
+}
+
+FILE *open_config_file_from_part(CONFIG_PART *cfgpart, char *mode)
 {
    char *configfilepath;
Â
@@ -27,16 +39,10 @@ FILE *open_config_file(CONFIG_PART *cfgpart, char *mode)
    }
    configfilepath = (char *)malloc(strlen(FAT_ENV_FILENAME) +
                strlen(cfgpart->mountpoint) + 2);
-Â Â Â if (!configfilepath) {
-Â Â Â Â Â Â return NULL;
-Â Â Â }
    strcpy(configfilepath, cfgpart->mountpoint);
    strcat(configfilepath, "/");
    strcat(configfilepath, FAT_ENV_FILENAME);
-Â Â Â VERBOSE(stdout, "Probing config file at %s.\n", configfilepath);
-Â Â Â FILE *config = fopen(configfilepath, mode);
-Â Â Â free(configfilepath);
-Â Â Â return config;
+Â Â Â return open_config_file(configfilepath, mode);
 }
Â
 int close_config_file(FILE *config_file_handle)
@@ -74,7 +80,7 @@ bool probe_config_file(CONFIG_PART *cfgpart)
          cfgpart->devpath, cfgpart->mountpoint);
       bool result = false;
       FILE *config;
-Â Â Â Â Â Â if (!(config = open_config_file(cfgpart, "rb"))) {
+Â Â Â Â Â Â if (!(config = open_config_file_from_part(cfgpart, "rb"))) {
          printf_debug(
             "Could not open config file on partition %s.\n",
             FAT_ENV_FILENAME);
diff --git a/include/env_config_file.h b/include/env_config_file.h
index 8fbe8fa..f333ddb 100644
--- a/include/env_config_file.h
+++ b/include/env_config_file.h
@@ -15,7 +15,8 @@
 #ifndef __ENV_CONFIG_FILE_H__
 #define __ENV_CONFIG_FILE_H__
Â
-FILE *open_config_file(CONFIG_PART *cfgpart, char *mode);
+FILE *open_config_file_from_part(CONFIG_PART *cfgpart, char *mode);
+FILE *open_config_file(char *configdirpath, char *mode);
 int close_config_file(FILE *config_file_handle);
 bool probe_config_file(CONFIG_PART *cfgpart);
Â
diff --git a/tools/bg_setenv.c b/tools/bg_setenv.c
index 24b4067..8aace0c 100644
--- a/tools/bg_setenv.c
+++ b/tools/bg_setenv.c
@@ -18,6 +18,7 @@
 #include "ebgenv.h"
 #include "uservars.h"
 #include "version.h"
+#include "env_config_file.h"
Â
 static char doc[] =
    "bg_setenv/bg_printenv - Environment tool for the EFI Boot Guard";
@@ -48,12 +49,15 @@ static struct argp_option options_setenv[] = {
    {0}};
Â
 static struct argp_option options_printenv[] = {
+Â Â Â {"filepath", 'f', "ENVFILE", 0, "Output environment from file. Expects "
+Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â "a valid EFI Boot Guard environment file."},
    {"verbose", 'v', 0, 0, "Be verbose"},
    {"version", 'V', 0, 0, "Print version"},
    {0}};
Â
 struct arguments {
-Â Â Â bool output_to_file;
+Â Â Â bool target_file;
+Â Â Â bool printenv;
    int which_part;
 };
Â
@@ -351,10 +355,17 @@ static error_t parse_opt(int key, char *arg, struct argp_state *state)
                   (uint8_t *)arg, strlen(arg) + 1);
       break;
    case 'f':
-Â Â Â Â Â Â arguments->output_to_file = true;
-Â Â Â Â Â Â res = asprintf(&envfilepath, "%s/%s", arg, FAT_ENV_FILENAME);
-Â Â Â Â Â Â if (res == -1) {
-Â Â Â Â Â Â Â Â Â return ENOMEM;
+Â Â Â Â Â Â arguments->target_file = true;
+Â Â Â Â Â Â if (arguments->printenv) {
+Â Â Â Â Â Â Â Â Â res = asprintf(&envfilepath, "%s", arg);
+Â Â Â Â Â Â Â Â Â if (res == -1) {
+Â Â Â Â Â Â Â Â Â Â Â Â return ENOMEM;
+Â Â Â Â Â Â Â Â Â }
+Â Â Â Â Â Â } else {
+Â Â Â Â Â Â Â Â Â res = asprintf(&envfilepath, "%s/%s", arg, FAT_ENV_FILENAME);
+Â Â Â Â Â Â Â Â Â if (res == -1) {
+Â Â Â Â Â Â Â Â Â Â Â Â return ENOMEM;
+Â Â Â Â Â Â Â Â Â }
       }
       break;
    case 'c':
@@ -533,6 +544,32 @@ static void dump_envs(void)
    }
 }
Â
+static bool get_env(char *configfilepath, BG_ENVDATA *env)
+{
+Â Â Â FILE *config;
+Â Â Â char buffer[ENV_STRING_LENGTH];
+Â Â Â bool result = true;
+
+Â Â Â if (!(config = open_config_file(configfilepath, "rb"))) {
+Â Â Â Â Â Â return false;
+Â Â Â }
+
+Â Â Â if (!(fread(env, sizeof(BG_ENVDATA), 1, config) == 1)) {
+Â Â Â Â Â Â VERBOSE(stderr, "Error reading environment data from %s\n",
+Â Â Â Â Â Â Â Â Â configfilepath);
+Â Â Â Â Â Â if (feof(config)) {
+Â Â Â Â Â Â Â Â Â VERBOSE(stderr, "End of file encountered.\n");
+Â Â Â Â Â Â }
+Â Â Â Â Â Â result = false;
+Â Â Â }
+
+Â Â Â if (close_config_file(config)) {
+Â Â Â Â Â Â VERBOSE(stderr,
+Â Â Â Â Â Â Â Â Â "Error closing environment file after reading.\n");
+Â Â Â };
+Â Â Â return result;
+}
+
 int main(int argc, char **argv)
 {
    static struct argp argp_setenv = {options_setenv, parse_opt, NULL, doc};
@@ -557,7 +594,8 @@ int main(int argc, char **argv)
    }
Â
    struct arguments arguments;
-Â Â Â arguments.output_to_file = false;
+Â Â Â arguments.target_file = false;
+Â Â Â arguments.printenv = !write_mode;
    arguments.which_part = 0;
Â
    STAILQ_INIT(&head);
@@ -572,8 +610,8 @@ int main(int argc, char **argv)
Â
    /* arguments are parsed, journal is filled */
Â
-Â Â Â /* is output to file ? */
-Â Â Â if (arguments.output_to_file) {
+Â Â Â /* is output to file or input from file ? */
+Â Â Â if (arguments.target_file && ! arguments.printenv) {
       /* execute journal and write to file */
       BGENV env;
       BG_ENVDATA data;
@@ -606,6 +644,16 @@ int main(int argc, char **argv)
       }
       free(envfilepath);
Â
+Â Â Â Â Â Â return 0;
+Â Â Â } else if (arguments.target_file && arguments.printenv) {
+Â Â Â Â Â Â BG_ENVDATA env;
+Â Â Â Â Â Â if (!get_env(envfilepath, &env)) {
+Â Â Â Â Â Â Â Â Â fprintf(stderr, "Error reading environment file.\n");
+Â Â Â Â Â Â Â Â Â return 1;
+Â Â Â Â Â Â }
+
+Â Â Â Â Â Â dump_env(&env);
+
       return 0;
    }
Â
--
2.29.2