Blame SOURCES/0209-blscfg-Expand-the-BLS-options-field-instead-of-showi.patch

d9d99f
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
d9d99f
From: Javier Martinez Canillas <javierm@redhat.com>
d9d99f
Date: Wed, 18 Jul 2018 08:08:02 +0200
d9d99f
Subject: [PATCH] blscfg: Expand the BLS options field instead of showing its
d9d99f
 variables
d9d99f
d9d99f
The values of the BLS fragment fields can either be string literals or
d9d99f
grub2 environment variables, the latter will be expanded by grub2 when
d9d99f
the boot entry is selected.
d9d99f
d9d99f
But from a usability point of view, is much more convenient if the BLS
d9d99f
parse code expand any variables that are present in the options field.
d9d99f
d9d99f
That will allow users to select an entry in the menu by pressing the e
d9d99f
key and edit the kernel command line parameters. So for example instead
d9d99f
of showing the following:
d9d99f
d9d99f
kernel /boot/vmlinuz-4.17.0 $kernelopts
d9d99f
d9d99f
It would show something like the following:
d9d99f
d9d99f
kernel /boot/vmlinuz-4.17.0 root=UUID=cec677c9-c890-4103-b94a-bcc191642935
d9d99f
d9d99f
Suggested-by: Hans de Goede <hdegoede@redhat.com>
d9d99f
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
d9d99f
---
d9d99f
 grub-core/commands/blscfg.c | 69 ++++++++++++++++++++++++++++++++++++++++++++-
d9d99f
 1 file changed, 68 insertions(+), 1 deletion(-)
d9d99f
d9d99f
diff --git a/grub-core/commands/blscfg.c b/grub-core/commands/blscfg.c
d9d99f
index c6addc4dc12..80d8814fc3f 100644
d9d99f
--- a/grub-core/commands/blscfg.c
d9d99f
+++ b/grub-core/commands/blscfg.c
d9d99f
@@ -32,6 +32,8 @@
d9d99f
 #include <grub/normal.h>
d9d99f
 #include <grub/lib/envblk.h>
d9d99f
 
d9d99f
+#include <stdbool.h>
d9d99f
+
d9d99f
 GRUB_MOD_LICENSE ("GPLv3+");
d9d99f
 
d9d99f
 #include "loadenv.h"
d9d99f
@@ -506,6 +508,70 @@ static char **bls_make_list (struct bls_entry *entry, const char *key, int *num)
d9d99f
   return list;
d9d99f
 }
d9d99f
 
d9d99f
+static char *field_append(bool is_var, char *buffer, char *start, char *end)
d9d99f
+{
d9d99f
+  char *temp = grub_strndup(start, end - start + 1);
d9d99f
+  const char *field = temp;
d9d99f
+
d9d99f
+  if (is_var) {
d9d99f
+    field = grub_env_get (temp);
d9d99f
+    if (!field)
d9d99f
+      return buffer;
d9d99f
+  }
d9d99f
+
d9d99f
+  if (!buffer) {
d9d99f
+    buffer = grub_strdup(field);
d9d99f
+    if (!buffer)
d9d99f
+      return NULL;
d9d99f
+  } else {
d9d99f
+    buffer = grub_realloc (buffer, grub_strlen(buffer) + grub_strlen(field));
d9d99f
+    if (!buffer)
d9d99f
+      return NULL;
d9d99f
+
d9d99f
+    grub_stpcpy (buffer + grub_strlen(buffer), field);
d9d99f
+  }
d9d99f
+
d9d99f
+  return buffer;
d9d99f
+}
d9d99f
+
d9d99f
+static char *expand_val(char *value)
d9d99f
+{
d9d99f
+  char *buffer = NULL;
d9d99f
+  char *start = value;
d9d99f
+  char *end = value;
d9d99f
+  bool is_var = false;
d9d99f
+
d9d99f
+  while (*value) {
d9d99f
+    if (*value == '$') {
d9d99f
+      if (start != end) {
d9d99f
+	buffer = field_append(is_var, buffer, start, end);
d9d99f
+	if (!buffer)
d9d99f
+	  return NULL;
d9d99f
+      }
d9d99f
+
d9d99f
+      is_var = true;
d9d99f
+      start = value + 1;
d9d99f
+    } else if (is_var) {
d9d99f
+      if (!grub_isalnum(*value) && *value != '_') {
d9d99f
+	buffer = field_append(is_var, buffer, start, end);
d9d99f
+	is_var = false;
d9d99f
+	start = value;
d9d99f
+      }
d9d99f
+    }
d9d99f
+
d9d99f
+    end = value;
d9d99f
+    value++;
d9d99f
+  }
d9d99f
+
d9d99f
+  if (start != end) {
d9d99f
+    buffer = field_append(is_var, buffer, start, end);
d9d99f
+    if (!buffer)
d9d99f
+      return NULL;
d9d99f
+  }
d9d99f
+
d9d99f
+  return buffer;
d9d99f
+}
d9d99f
+
d9d99f
 static void create_entry (struct bls_entry *entry)
d9d99f
 {
d9d99f
   int argc = 0;
d9d99f
@@ -536,7 +602,7 @@ static void create_entry (struct bls_entry *entry)
d9d99f
     }
d9d99f
 
d9d99f
   title = bls_get_val (entry, "title", NULL);
d9d99f
-  options = bls_get_val (entry, "options", NULL);
d9d99f
+  options = expand_val (bls_get_val (entry, "options", NULL));
d9d99f
   initrds = bls_make_list (entry, "initrd", NULL);
d9d99f
 
d9d99f
   hotkey = bls_get_val (entry, "grub_hotkey", NULL);
d9d99f
@@ -594,6 +660,7 @@ static void create_entry (struct bls_entry *entry)
d9d99f
 finish:
d9d99f
   grub_free (initrd);
d9d99f
   grub_free (initrds);
d9d99f
+  grub_free (options);
d9d99f
   grub_free (classes);
d9d99f
   grub_free (args);
d9d99f
   grub_free (argv);