11b49b8
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
11b49b8
From: Javier Martinez Canillas <javierm@redhat.com>
11b49b8
Date: Wed, 23 Jan 2019 16:33:32 +0100
11b49b8
Subject: [PATCH] blscfg: add more options to blscfg command to make it more
11b49b8
 flexible
11b49b8
11b49b8
Currently the blscfg command is not flexible, it just loads all the BLS
11b49b8
entries from a predefined path and populate the menu entries at the same
11b49b8
time. But a user might want more control over what BLS snippets are used
11b49b8
to populate the entries and in which order.
11b49b8
11b49b8
So lets make the BLS support more flexible by allowing to blscfg command
11b49b8
to populate only the default entry, the non-default entries or choose a
11b49b8
custom path to a BLS snippet or a BLS directory to load the entries from.
11b49b8
11b49b8
The blscfg command now supports the following arguments:
11b49b8
11b49b8
blscfg default
11b49b8
blscfg non-default
11b49b8
blscfg (hd0,gpt2)/boot/loader/entries/
11b49b8
blscfg (hd0,gpt2)/boot/loader/entries/custom_entry.conf
11b49b8
11b49b8
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
11b49b8
---
11b49b8
 grub-core/commands/blscfg.c    | 241 +++++++++++++++++++++++++++++++----------
11b49b8
 grub-core/commands/legacycfg.c |   5 +-
11b49b8
 grub-core/commands/menuentry.c |   8 +-
11b49b8
 grub-core/normal/main.c        |   6 +
11b49b8
 include/grub/menu.h            |  13 +++
11b49b8
 include/grub/normal.h          |   2 +-
11b49b8
 6 files changed, 213 insertions(+), 62 deletions(-)
11b49b8
11b49b8
diff --git a/grub-core/commands/blscfg.c b/grub-core/commands/blscfg.c
11b49b8
index 304d73908ae..aa5bf0d3220 100644
11b49b8
--- a/grub-core/commands/blscfg.c
11b49b8
+++ b/grub-core/commands/blscfg.c
11b49b8
@@ -52,16 +52,6 @@ struct keyval
11b49b8
   char *val;
11b49b8
 };
11b49b8
 
11b49b8
-struct bls_entry
11b49b8
-{
11b49b8
-  struct bls_entry *next;
11b49b8
-  struct bls_entry **prev;
11b49b8
-  struct keyval **keyvals;
11b49b8
-  int nkeyvals;
11b49b8
-  char *filename;
11b49b8
-  bool visible;
11b49b8
-};
11b49b8
-
11b49b8
 static struct bls_entry *entries = NULL;
11b49b8
 
11b49b8
 #define FOR_BLS_ENTRIES(var) FOR_LIST_ELEMENTS (var, entries)
11b49b8
@@ -410,6 +400,7 @@ static int bls_add_entry(struct bls_entry *entry)
11b49b8
 struct read_entry_info {
11b49b8
   const char *devid;
11b49b8
   const char *dirname;
11b49b8
+  grub_file_t file;
11b49b8
 };
11b49b8
 
11b49b8
 static int read_entry (
11b49b8
@@ -417,9 +408,9 @@ static int read_entry (
11b49b8
     const struct grub_dirhook_info *dirhook_info UNUSED,
11b49b8
     void *data)
11b49b8
 {
11b49b8
+  grub_size_t m = 0, n, clip = 0;
11b49b8
   int rc = 0;
11b49b8
-  grub_size_t n;
11b49b8
-  char *p;
11b49b8
+  char *p = NULL;
11b49b8
   grub_file_t f = NULL;
11b49b8
   grub_off_t sz;
11b49b8
   struct bls_entry *entry;
11b49b8
@@ -427,21 +418,29 @@ static int read_entry (
11b49b8
 
11b49b8
   grub_dprintf ("blscfg", "filename: \"%s\"\n", filename);
11b49b8
 
11b49b8
-  if (filename[0] == '.')
11b49b8
-    return 0;
11b49b8
-
11b49b8
   n = grub_strlen (filename);
11b49b8
-  if (n <= 5)
11b49b8
-    return 0;
11b49b8
 
11b49b8
-  if (grub_strcmp (filename + n - 5, ".conf") != 0)
11b49b8
-    return 0;
11b49b8
+  if (info->file)
11b49b8
+    {
11b49b8
+      f = info->file;
11b49b8
+    }
11b49b8
+  else
11b49b8
+    {
11b49b8
+      if (filename[0] == '.')
11b49b8
+	return 0;
11b49b8
 
11b49b8
-  p = grub_xasprintf ("(%s)%s/%s", info->devid, info->dirname, filename);
11b49b8
+      if (n <= 5)
11b49b8
+	return 0;
11b49b8
 
11b49b8
-  f = grub_file_open (p);
11b49b8
-  if (!f)
11b49b8
-    goto finish;
11b49b8
+      if (grub_strcmp (filename + n - 5, ".conf") != 0)
11b49b8
+	return 0;
11b49b8
+
11b49b8
+      p = grub_xasprintf ("(%s)%s/%s", info->devid, info->dirname, filename);
11b49b8
+
11b49b8
+      f = grub_file_open (p);
11b49b8
+      if (!f)
11b49b8
+	goto finish;
11b49b8
+    }
11b49b8
 
11b49b8
   sz = grub_file_size (f);
11b49b8
   if (sz == GRUB_FILE_SIZE_UNKNOWN || sz > 1024*1024)
11b49b8
@@ -451,7 +450,30 @@ static int read_entry (
11b49b8
   if (!entry)
11b49b8
     goto finish;
11b49b8
 
11b49b8
-  entry->filename = grub_strndup(filename, n - 5);
11b49b8
+  if (info->file)
11b49b8
+    {
11b49b8
+      char *slash;
11b49b8
+
11b49b8
+      if (n > 5 && !grub_strcmp (filename + n - 5, ".conf") == 0)
11b49b8
+	clip = 5;
11b49b8
+
11b49b8
+      slash = grub_strrchr (filename, '/');
11b49b8
+      if (!slash)
11b49b8
+	slash = grub_strrchr (filename, '\\');
11b49b8
+
11b49b8
+      while (*slash == '/' || *slash == '\\')
11b49b8
+	slash++;
11b49b8
+
11b49b8
+      m = slash ? slash - filename : 0;
11b49b8
+    }
11b49b8
+  else
11b49b8
+    {
11b49b8
+      m = 0;
11b49b8
+      clip = 5;
11b49b8
+    }
11b49b8
+  n -= m;
11b49b8
+
11b49b8
+  entry->filename = grub_strndup(filename + m, n - clip);
11b49b8
   if (!entry->filename)
11b49b8
     goto finish;
11b49b8
 
11b49b8
@@ -498,7 +520,8 @@ static int read_entry (
11b49b8
       bls_add_entry(entry);
11b49b8
 
11b49b8
 finish:
11b49b8
-  grub_free (p);
11b49b8
+  if (p)
11b49b8
+    grub_free (p);
11b49b8
 
11b49b8
   if (f)
11b49b8
     grub_file_close (f);
11b49b8
@@ -731,7 +754,7 @@ static void create_entry (struct bls_entry *entry)
11b49b8
 			GRUB_BOOT_DEVICE, clinux, options ? " " : "", options ? options : "",
11b49b8
 			initrd ? initrd : "");
11b49b8
 
11b49b8
-  grub_normal_add_menu_entry (argc, argv, classes, id, users, hotkey, NULL, src, 0, &index);
11b49b8
+  grub_normal_add_menu_entry (argc, argv, classes, id, users, hotkey, NULL, src, 0, &index, entry);
11b49b8
   grub_dprintf ("blscfg", "Added entry %d id:\"%s\"\n", index, id);
11b49b8
 
11b49b8
 finish:
11b49b8
@@ -745,10 +768,10 @@ finish:
11b49b8
 }
11b49b8
 
11b49b8
 struct find_entry_info {
11b49b8
+	const char *dirname;
11b49b8
 	const char *devid;
11b49b8
 	grub_device_t dev;
11b49b8
 	grub_fs_t fs;
11b49b8
-	int platform;
11b49b8
 };
11b49b8
 
11b49b8
 /*
11b49b8
@@ -757,20 +780,22 @@ struct find_entry_info {
11b49b8
 static int find_entry (struct find_entry_info *info)
11b49b8
 {
11b49b8
   struct read_entry_info read_entry_info;
11b49b8
-  struct bls_entry *entry = NULL;
11b49b8
   grub_fs_t blsdir_fs = NULL;
11b49b8
   grub_device_t blsdir_dev = NULL;
11b49b8
-  const char *blsdir = NULL;
11b49b8
+  const char *blsdir = info->dirname;
11b49b8
   int fallback = 0;
11b49b8
   int r = 0;
11b49b8
 
11b49b8
-  blsdir = grub_env_get ("blsdir");
11b49b8
-  if (!blsdir)
11b49b8
-    blsdir = GRUB_BLS_CONFIG_PATH;
11b49b8
+  if (!blsdir) {
11b49b8
+    blsdir = grub_env_get ("blsdir");
11b49b8
+    if (!blsdir)
11b49b8
+      blsdir = GRUB_BLS_CONFIG_PATH;
11b49b8
+  }
11b49b8
 
11b49b8
+  read_entry_info.file = NULL;
11b49b8
   read_entry_info.dirname = blsdir;
11b49b8
 
11b49b8
-  grub_dprintf ("blscfg", "scanning blsdir: %s\n", GRUB_BLS_CONFIG_PATH);
11b49b8
+  grub_dprintf ("blscfg", "scanning blsdir: %s\n", blsdir);
11b49b8
 
11b49b8
   blsdir_dev = info->dev;
11b49b8
   blsdir_fs = info->fs;
11b49b8
@@ -788,7 +813,7 @@ read_fallback:
11b49b8
 	} while (e);
11b49b8
   }
11b49b8
 
11b49b8
-  if (!entries && !fallback) {
11b49b8
+  if (r && !info->dirname && !fallback) {
11b49b8
     read_entry_info.dirname = "/boot" GRUB_BLS_CONFIG_PATH;
11b49b8
     grub_dprintf ("blscfg", "Entries weren't found in %s, fallback to %s\n",
11b49b8
 		  blsdir, read_entry_info.dirname);
11b49b8
@@ -796,45 +821,62 @@ read_fallback:
11b49b8
     goto read_fallback;
11b49b8
   }
11b49b8
 
11b49b8
-  grub_dprintf ("blscfg", "%s Creating entries from bls\n", __func__);
11b49b8
-  FOR_BLS_ENTRIES(entry) {
11b49b8
-    if (entry->visible)
11b49b8
-      continue;
11b49b8
-
11b49b8
-    create_entry(entry);
11b49b8
-    entry->visible = true;
11b49b8
-  }
11b49b8
   return 0;
11b49b8
 }
11b49b8
 
11b49b8
 static grub_err_t
11b49b8
-grub_cmd_blscfg (grub_extcmd_context_t ctxt UNUSED,
11b49b8
-		     int argc UNUSED,
11b49b8
-		     char **args UNUSED)
11b49b8
+bls_load_entries (const char *path)
11b49b8
 {
11b49b8
+  grub_size_t len;
11b49b8
   grub_fs_t fs;
11b49b8
   grub_device_t dev;
11b49b8
   static grub_err_t r;
11b49b8
-  const char *devid;
11b49b8
-  struct find_entry_info info =
11b49b8
-    {
11b49b8
+  const char *devid = NULL;
11b49b8
+  char *blsdir = NULL;
11b49b8
+  struct find_entry_info info = {
11b49b8
       .dev = NULL,
11b49b8
       .fs = NULL,
11b49b8
-    };
11b49b8
+      .dirname = NULL,
11b49b8
+  };
11b49b8
+  struct read_entry_info rei = {
11b49b8
+      .devid = NULL,
11b49b8
+      .dirname = NULL,
11b49b8
+  };
11b49b8
 
11b49b8
+  if (path) {
11b49b8
+    len = grub_strlen (path);
11b49b8
+    if (grub_strcmp (path + len - 5, ".conf") == 0) {
11b49b8
+      rei.file = grub_file_open (path);
11b49b8
+      if (!rei.file)
11b49b8
+	return grub_errno;
11b49b8
+      /*
11b49b8
+       * read_entry() closes the file
11b49b8
+       */
11b49b8
+      return read_entry(path, NULL, &rei;;
11b49b8
+    } else if (path[0] == '(') {
11b49b8
+      devid = path + 1;
11b49b8
 
11b49b8
-  grub_dprintf ("blscfg", "finding boot\n");
11b49b8
+      blsdir = grub_strchr (path, ')');
11b49b8
+      if (!blsdir)
11b49b8
+	return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Filepath isn't correct"));
11b49b8
 
11b49b8
+      *blsdir = '\0';
11b49b8
+      blsdir = blsdir + 1;
11b49b8
+    }
11b49b8
+  }
11b49b8
+
11b49b8
+  if (!devid) {
11b49b8
 #ifdef GRUB_MACHINE_EMU
11b49b8
-  devid = "host";
11b49b8
+    devid = "host";
11b49b8
 #elif defined(GRUB_MACHINE_EFI)
11b49b8
-  devid = grub_env_get ("root");
11b49b8
+    devid = grub_env_get ("root");
11b49b8
 #else
11b49b8
-  devid = grub_env_get ("boot");
11b49b8
+    devid = grub_env_get ("boot");
11b49b8
 #endif
11b49b8
-  if (!devid)
11b49b8
-    return grub_error (GRUB_ERR_FILE_NOT_FOUND,
11b49b8
-		       N_("variable `%s' isn't set"), "boot");
11b49b8
+    if (!devid)
11b49b8
+      return grub_error (GRUB_ERR_FILE_NOT_FOUND,
11b49b8
+			 N_("variable `%s' isn't set"), "boot");
11b49b8
+  }
11b49b8
 
11b49b8
   grub_dprintf ("blscfg", "opening %s\n", devid);
11b49b8
   dev = grub_device_open (devid);
11b49b8
@@ -849,6 +891,7 @@ grub_cmd_blscfg (grub_extcmd_context_t ctxt UNUSED,
11b49b8
       goto finish;
11b49b8
     }
11b49b8
 
11b49b8
+  info.dirname = blsdir;
11b49b8
   info.devid = devid;
11b49b8
   info.dev = dev;
11b49b8
   info.fs = fs;
11b49b8
@@ -861,6 +904,92 @@ finish:
11b49b8
   return r;
11b49b8
 }
11b49b8
 
11b49b8
+static bool
11b49b8
+is_default_entry(const char *def_entry, struct bls_entry *entry, int idx)
11b49b8
+{
11b49b8
+  const char *title;
11b49b8
+  int def_idx;
11b49b8
+
11b49b8
+  if (!def_entry)
11b49b8
+    return false;
11b49b8
+
11b49b8
+  if (grub_strcmp(def_entry, entry->filename) == 0)
11b49b8
+    return true;
11b49b8
+
11b49b8
+  title = bls_get_val(entry, "title", NULL);
11b49b8
+
11b49b8
+  if (title && grub_strcmp(def_entry, title) == 0)
11b49b8
+    return true;
11b49b8
+
11b49b8
+  def_idx = (int)grub_strtol(def_entry, NULL, 0);
11b49b8
+  if (grub_errno == GRUB_ERR_BAD_NUMBER)
11b49b8
+    return false;
11b49b8
+
11b49b8
+  if (def_idx == idx)
11b49b8
+    return true;
11b49b8
+
11b49b8
+  return false;
11b49b8
+}
11b49b8
+
11b49b8
+static grub_err_t
11b49b8
+bls_create_entries (bool show_default, bool show_non_default, char *entry_id)
11b49b8
+{
11b49b8
+  const char *def_entry = NULL;
11b49b8
+  struct bls_entry *entry = NULL;
11b49b8
+  int idx = 0;
11b49b8
+
11b49b8
+  def_entry = grub_env_get("default");
11b49b8
+
11b49b8
+  grub_dprintf ("blscfg", "%s Creating entries from bls\n", __func__);
11b49b8
+  FOR_BLS_ENTRIES(entry) {
11b49b8
+    if (entry->visible) {
11b49b8
+      idx++;
11b49b8
+      continue;
11b49b8
+    }
11b49b8
+
11b49b8
+    if ((show_default && is_default_entry(def_entry, entry, idx)) ||
11b49b8
+	(show_non_default && !is_default_entry(def_entry, entry, idx)) ||
11b49b8
+	(entry_id && grub_strcmp(entry_id, entry->filename) == 0)) {
11b49b8
+      create_entry(entry);
11b49b8
+      entry->visible = 1;
11b49b8
+    }
11b49b8
+    idx++;
11b49b8
+  }
11b49b8
+
11b49b8
+  return GRUB_ERR_NONE;
11b49b8
+}
11b49b8
+
11b49b8
+static grub_err_t
11b49b8
+grub_cmd_blscfg (grub_extcmd_context_t ctxt UNUSED,
11b49b8
+		 int argc, char **args)
11b49b8
+{
11b49b8
+  grub_err_t r;
11b49b8
+  char *path = NULL;
11b49b8
+  char *entry_id = NULL;
11b49b8
+  bool show_default = true;
11b49b8
+  bool show_non_default = true;
11b49b8
+
11b49b8
+  if (argc == 1) {
11b49b8
+    if (grub_strcmp (args[0], "default") == 0) {
11b49b8
+      show_non_default = false;
11b49b8
+    } else if (grub_strcmp (args[0], "non-default") == 0) {
11b49b8
+      show_default = false;
11b49b8
+    } else if (args[0][0] == '(') {
11b49b8
+      path = args[0];
11b49b8
+    } else {
11b49b8
+      entry_id = args[0];
11b49b8
+      show_default = false;
11b49b8
+      show_non_default = false;
11b49b8
+    }
11b49b8
+  }
11b49b8
+
11b49b8
+  r = bls_load_entries(path);
11b49b8
+  if (r)
11b49b8
+    return r;
11b49b8
+
11b49b8
+  return bls_create_entries(show_default, show_non_default, entry_id);
11b49b8
+}
11b49b8
+
11b49b8
 static grub_extcmd_t cmd;
11b49b8
 static grub_extcmd_t oldcmd;
11b49b8
 
11b49b8
diff --git a/grub-core/commands/legacycfg.c b/grub-core/commands/legacycfg.c
11b49b8
index f9d7627bdc3..ef8dd74c589 100644
11b49b8
--- a/grub-core/commands/legacycfg.c
11b49b8
+++ b/grub-core/commands/legacycfg.c
11b49b8
@@ -133,7 +133,7 @@ legacy_file (const char *filename)
11b49b8
 	    args[0] = oldname;
11b49b8
 	    grub_normal_add_menu_entry (1, args, NULL, NULL, "legacy",
11b49b8
 					NULL, NULL,
11b49b8
-					entrysrc, 0, NULL);
11b49b8
+					entrysrc, 0, NULL, NULL);
11b49b8
 	    grub_free (args);
11b49b8
 	    entrysrc[0] = 0;
11b49b8
 	    grub_free (oldname);
11b49b8
@@ -186,7 +186,8 @@ legacy_file (const char *filename)
11b49b8
 	}
11b49b8
       args[0] = entryname;
11b49b8
       grub_normal_add_menu_entry (1, args, NULL, NULL, NULL,
11b49b8
-				  NULL, NULL, entrysrc, 0, NULL);
11b49b8
+				  NULL, NULL, entrysrc, 0, NULL,
11b49b8
+				  NULL);
11b49b8
       grub_free (args);
11b49b8
     }
11b49b8
 
11b49b8
diff --git a/grub-core/commands/menuentry.c b/grub-core/commands/menuentry.c
11b49b8
index 7004e08ce78..29736f5cd03 100644
11b49b8
--- a/grub-core/commands/menuentry.c
11b49b8
+++ b/grub-core/commands/menuentry.c
11b49b8
@@ -78,7 +78,7 @@ grub_normal_add_menu_entry (int argc, const char **args,
11b49b8
 			    char **classes, const char *id,
11b49b8
 			    const char *users, const char *hotkey,
11b49b8
 			    const char *prefix, const char *sourcecode,
11b49b8
-			    int submenu, int *index)
11b49b8
+			    int submenu, int *index, struct bls_entry *bls)
11b49b8
 {
11b49b8
   int menu_hotkey = 0;
11b49b8
   char **menu_args = NULL;
11b49b8
@@ -195,6 +195,7 @@ grub_normal_add_menu_entry (int argc, const char **args,
11b49b8
   (*last)->args = menu_args;
11b49b8
   (*last)->sourcecode = menu_sourcecode;
11b49b8
   (*last)->submenu = submenu;
11b49b8
+  (*last)->bls = bls;
11b49b8
 
11b49b8
   menu->size++;
11b49b8
   if (index)
11b49b8
@@ -296,7 +297,7 @@ grub_cmd_menuentry (grub_extcmd_context_t ctxt, int argc, char **args)
11b49b8
 				       ctxt->state[2].arg, 0,
11b49b8
 				       ctxt->state[3].arg,
11b49b8
 				       ctxt->extcmd->cmd->name[0] == 's',
11b49b8
-				       NULL);
11b49b8
+				       NULL, NULL);
11b49b8
 
11b49b8
   src = args[argc - 1];
11b49b8
   args[argc - 1] = NULL;
11b49b8
@@ -313,7 +314,8 @@ grub_cmd_menuentry (grub_extcmd_context_t ctxt, int argc, char **args)
11b49b8
 				  ctxt->state[0].args, ctxt->state[4].arg,
11b49b8
 				  users,
11b49b8
 				  ctxt->state[2].arg, prefix, src + 1,
11b49b8
-				  ctxt->extcmd->cmd->name[0] == 's', NULL);
11b49b8
+				  ctxt->extcmd->cmd->name[0] == 's', NULL,
11b49b8
+				  NULL);
11b49b8
 
11b49b8
   src[len - 1] = ch;
11b49b8
   args[argc - 1] = src;
11b49b8
diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c
11b49b8
index 04ae9ed02f6..4117317c4c4 100644
11b49b8
--- a/grub-core/normal/main.c
11b49b8
+++ b/grub-core/normal/main.c
11b49b8
@@ -20,6 +20,7 @@
11b49b8
 #include <grub/kernel.h>
11b49b8
 #include <grub/normal.h>
11b49b8
 #include <grub/dl.h>
11b49b8
+#include <grub/menu.h>
11b49b8
 #include <grub/misc.h>
11b49b8
 #include <grub/file.h>
11b49b8
 #include <grub/mm.h>
11b49b8
@@ -70,6 +71,11 @@ grub_normal_free_menu (grub_menu_t menu)
11b49b8
 	  grub_free (entry->args);
11b49b8
 	}
11b49b8
 
11b49b8
+      if (entry->bls)
11b49b8
+	{
11b49b8
+	  entry->bls->visible = 0;
11b49b8
+	}
11b49b8
+
11b49b8
       grub_free ((void *) entry->id);
11b49b8
       grub_free ((void *) entry->users);
11b49b8
       grub_free ((void *) entry->title);
11b49b8
diff --git a/include/grub/menu.h b/include/grub/menu.h
11b49b8
index ee2b5e91045..eea493f74b1 100644
11b49b8
--- a/include/grub/menu.h
11b49b8
+++ b/include/grub/menu.h
11b49b8
@@ -20,6 +20,16 @@
11b49b8
 #ifndef GRUB_MENU_HEADER
11b49b8
 #define GRUB_MENU_HEADER 1
11b49b8
 
11b49b8
+struct bls_entry
11b49b8
+{
11b49b8
+  struct bls_entry *next;
11b49b8
+  struct bls_entry **prev;
11b49b8
+  struct keyval **keyvals;
11b49b8
+  int nkeyvals;
11b49b8
+  char *filename;
11b49b8
+  int visible;
11b49b8
+};
11b49b8
+
11b49b8
 struct grub_menu_entry_class
11b49b8
 {
11b49b8
   char *name;
11b49b8
@@ -60,6 +70,9 @@ struct grub_menu_entry
11b49b8
 
11b49b8
   /* The next element.  */
11b49b8
   struct grub_menu_entry *next;
11b49b8
+
11b49b8
+  /* BLS used to populate the entry */
11b49b8
+  struct bls_entry *bls;
11b49b8
 };
11b49b8
 typedef struct grub_menu_entry *grub_menu_entry_t;
11b49b8
 
11b49b8
diff --git a/include/grub/normal.h b/include/grub/normal.h
11b49b8
index cb9901f41b3..8839ad85a19 100644
11b49b8
--- a/include/grub/normal.h
11b49b8
+++ b/include/grub/normal.h
11b49b8
@@ -145,7 +145,7 @@ grub_normal_add_menu_entry (int argc, const char **args, char **classes,
11b49b8
 			    const char *id,
11b49b8
 			    const char *users, const char *hotkey,
11b49b8
 			    const char *prefix, const char *sourcecode,
11b49b8
-			    int submenu, int *index);
11b49b8
+			    int submenu, int *index, struct bls_entry *bls);
11b49b8
 
11b49b8
 grub_err_t
11b49b8
 grub_normal_set_password (const char *user, const char *password);