| From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
| From: Hans de Goede <hdegoede@redhat.com> |
| Date: Mon, 4 Jun 2018 19:49:47 +0200 |
| Subject: [PATCH] grub-editenv: Add "incr" command to increment integer value |
| env. variables |
| |
| To be able to automatically detect if the last boot was successful, |
| We want to keep count of succesful / failed boots in some integer |
| environment variable. |
| |
| This commit adds a grub-editenvt "incr" command to increment such |
| integer value env. variables by 1 for use from various boot scripts. |
| |
| Signed-off-by: Hans de Goede <hdegoede@redhat.com> |
| |
| util/grub-editenv.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ |
| 1 file changed, 50 insertions(+) |
| |
| diff --git a/util/grub-editenv.c b/util/grub-editenv.c |
| index 118e89fe57f..2918bb71cfe 100644 |
| |
| |
| @@ -53,6 +53,9 @@ static struct argp_option options[] = { |
| /* TRANSLATORS: "unset" is a keyword. It's a summary of "unset" subcommand. */ |
| {N_("unset [NAME ...]"), 0, 0, OPTION_DOC|OPTION_NO_USAGE, |
| N_("Delete variables."), 0}, |
| + /* TRANSLATORS: "incr" is a keyword. It's a summary of "incr" subcommand. */ |
| + {N_("incr [NAME ...]"), 0, 0, OPTION_DOC|OPTION_NO_USAGE, |
| + N_("Increase value of integer variables."), 0}, |
| |
| {0, 0, 0, OPTION_DOC, N_("Options:"), -1}, |
| {"verbose", 'v', 0, 0, N_("print verbose messages."), 0}, |
| @@ -246,6 +249,51 @@ unset_variables (const char *name, int argc, char *argv[]) |
| grub_envblk_close (envblk); |
| } |
| |
| +struct get_int_value_params { |
| + char *varname; |
| + int value; |
| +}; |
| + |
| +static int |
| +get_int_value (const char *varname, const char *value, void *hook_data) |
| +{ |
| + struct get_int_value_params *params = hook_data; |
| + |
| + if (strcmp (varname, params->varname) == 0) { |
| + params->value = strtol (value, NULL, 10); |
| + return 1; |
| + } |
| + return 0; |
| +} |
| + |
| +static void |
| +incr_variables (const char *name, int argc, char *argv[]) |
| +{ |
| + grub_envblk_t envblk; |
| + char buf[16]; |
| + |
| + envblk = open_envblk_file (name); |
| + while (argc) |
| + { |
| + struct get_int_value_params params = { |
| + .varname = argv[0], |
| + .value = 0, /* Consider unset variables 0 */ |
| + }; |
| + |
| + grub_envblk_iterate (envblk, ¶ms, get_int_value); |
| + snprintf(buf, sizeof(buf), "%d", params.value + 1); |
| + |
| + if (! grub_envblk_set (envblk, argv[0], buf)) |
| + grub_util_error ("%s", _("environment block too small")); |
| + |
| + argc--; |
| + argv++; |
| + } |
| + |
| + write_envblk (name, envblk); |
| + grub_envblk_close (envblk); |
| +} |
| + |
| int |
| main (int argc, char *argv[]) |
| { |
| @@ -285,6 +333,8 @@ main (int argc, char *argv[]) |
| set_variables (filename, argc - curindex, argv + curindex); |
| else if (strcmp (command, "unset") == 0) |
| unset_variables (filename, argc - curindex, argv + curindex); |
| + else if (strcmp (command, "incr") == 0) |
| + incr_variables (filename, argc - curindex, argv + curindex); |
| else |
| { |
| char *program = xstrdup(program_name); |