nalika / rpms / grub2

Forked from rpms/grub2 2 years ago
Clone

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

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