You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
94 lines
2.9 KiB
94 lines
2.9 KiB
2 years ago
|
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 db6f187cc63..948eec8a114 100644
|
||
|
--- a/util/grub-editenv.c
|
||
|
+++ b/util/grub-editenv.c
|
||
|
@@ -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},
|
||
|
@@ -253,6 +256,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[])
|
||
|
{
|
||
|
@@ -292,6 +340,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);
|