nalika / rpms / grub2

Forked from rpms/grub2 2 years ago
Clone

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

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