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