Blame SOURCES/0187-grub-editenv-Add-incr-command-to-increment-integer-v.patch

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