dcavalca / rpms / grub2

Forked from rpms/grub2 3 years ago
Clone

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

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