grub-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] Add hidden menu entries


From: Alexander Graf
Subject: [PATCH] Add hidden menu entries
Date: Tue, 26 Apr 2016 15:46:33 +0200

The menu infrastructure is quite powerful. It allows you to define menu
entries that can contain arbitrary grub commands that can do a lot more
than just boot kernel entries.

For some of these it makes sense to hide them inside the normal menu
though and instead have them available through hotkeys that get advertised
differently. My main use case is to switch to the serial console when
gfxterm is loaded.

So this patch adds support for hidden menu entries that are accessible
using hotkeys, but are not accessible in the grub menu.

Signed-off-by: Alexander Graf <address@hidden>
---
 grub-core/commands/legacycfg.c |  4 ++--
 grub-core/commands/menuentry.c | 18 ++++++++++++++----
 grub-core/normal/menu.c        | 24 +++++++++++++++++++-----
 grub-core/normal/menu_text.c   |  4 ++++
 include/grub/menu.h            |  2 ++
 include/grub/normal.h          |  2 +-
 6 files changed, 42 insertions(+), 12 deletions(-)

diff --git a/grub-core/commands/legacycfg.c b/grub-core/commands/legacycfg.c
index dd9d9f1..b282c4f 100644
--- a/grub-core/commands/legacycfg.c
+++ b/grub-core/commands/legacycfg.c
@@ -133,7 +133,7 @@ legacy_file (const char *filename)
            args[0] = oldname;
            grub_normal_add_menu_entry (1, args, NULL, NULL, "legacy",
                                        NULL, NULL,
-                                       entrysrc, 0);
+                                       entrysrc, 0, 0);
            grub_free (args);
            entrysrc[0] = 0;
            grub_free (oldname);
@@ -186,7 +186,7 @@ legacy_file (const char *filename)
        }
       args[0] = entryname;
       grub_normal_add_menu_entry (1, args, NULL, NULL, NULL,
-                                 NULL, NULL, entrysrc, 0);
+                                 NULL, NULL, entrysrc, 0, 0);
       grub_free (args);
     }
 
diff --git a/grub-core/commands/menuentry.c b/grub-core/commands/menuentry.c
index 58d4dad..d73bbc9 100644
--- a/grub-core/commands/menuentry.c
+++ b/grub-core/commands/menuentry.c
@@ -43,6 +43,8 @@ static const struct grub_arg_option options[] =
        anyone can boot it.  */
     {"unrestricted", 0, 0, N_("This entry can be booted by any user."),
      0, ARG_TYPE_NONE},
+    {"hidden", 0, 0, N_("This entry is invisible in menus."),
+     0, ARG_TYPE_NONE},
     {0, 0, 0, 0, 0, 0}
   };
 
@@ -78,7 +80,7 @@ grub_normal_add_menu_entry (int argc, const char **args,
                            char **classes, const char *id,
                            const char *users, const char *hotkey,
                            const char *prefix, const char *sourcecode,
-                           int submenu)
+                           int submenu, int hidden)
 {
   int menu_hotkey = 0;
   char **menu_args = NULL;
@@ -188,8 +190,11 @@ grub_normal_add_menu_entry (int argc, const char **args,
   (*last)->args = menu_args;
   (*last)->sourcecode = menu_sourcecode;
   (*last)->submenu = submenu;
+  (*last)->hidden = hidden;
+
+  if (!hidden)
+    menu->size++;
 
-  menu->size++;
   return GRUB_ERR_NONE;
 
  fail:
@@ -261,6 +266,7 @@ grub_cmd_menuentry (grub_extcmd_context_t ctxt, int argc, 
char **args)
   unsigned len;
   grub_err_t r;
   const char *users;
+  int hidden = 0;
 
   if (! argc)
     return grub_error (GRUB_ERR_BAD_ARGUMENT, "missing arguments");
@@ -278,6 +284,9 @@ grub_cmd_menuentry (grub_extcmd_context_t ctxt, int argc, 
char **args)
   else
     users = "";
 
+  if (ctxt->state[6].set)
+    hidden = 1;
+
   if (! ctxt->script)
     return grub_normal_add_menu_entry (argc, (const char **) args,
                                       (ctxt->state[0].set ? ctxt->state[0].args
@@ -286,7 +295,8 @@ grub_cmd_menuentry (grub_extcmd_context_t ctxt, int argc, 
char **args)
                                       users,
                                       ctxt->state[2].arg, 0,
                                       ctxt->state[3].arg,
-                                      ctxt->extcmd->cmd->name[0] == 's');
+                                      ctxt->extcmd->cmd->name[0] == 's',
+                                      hidden);
 
   src = args[argc - 1];
   args[argc - 1] = NULL;
@@ -303,7 +313,7 @@ grub_cmd_menuentry (grub_extcmd_context_t ctxt, int argc, 
char **args)
                                  ctxt->state[0].args, ctxt->state[4].arg,
                                  users,
                                  ctxt->state[2].arg, prefix, src + 1,
-                                 ctxt->extcmd->cmd->name[0] == 's');
+                                 ctxt->extcmd->cmd->name[0] == 's', hidden);
 
   src[len - 1] = ch;
   args[argc - 1] = src;
diff --git a/grub-core/normal/menu.c b/grub-core/normal/menu.c
index 719e2fb..3737ce0 100644
--- a/grub-core/normal/menu.c
+++ b/grub-core/normal/menu.c
@@ -40,6 +40,8 @@
 grub_err_t (*grub_gfxmenu_try_hook) (int entry, grub_menu_t menu,
                                     int nested) = NULL;
 
+#define MENU_INCLUDE_HIDDEN 0x10000
+
 enum timeout_style {
   TIMEOUT_STYLE_MENU,
   TIMEOUT_STYLE_COUNTDOWN,
@@ -80,8 +82,20 @@ grub_menu_get_entry (grub_menu_t menu, int no)
 {
   grub_menu_entry_t e;
 
-  for (e = menu->entry_list; e && no > 0; e = e->next, no--)
-    ;
+  if (no & MENU_INCLUDE_HIDDEN) {
+    no &= ~MENU_INCLUDE_HIDDEN;
+
+    for (e = menu->entry_list; e && no > 0; e = e->next, no--)
+      ;
+  } else {
+    for (e = menu->entry_list; e && no > 0; e = e->next, no--) {
+      /* Skip hidden entries */
+      while (e && e->hidden)
+        e = e->next;
+    }
+    while (e && e->hidden)
+      e = e->next;
+  }
 
   return e;
 }
@@ -93,10 +107,10 @@ get_entry_index_by_hotkey (grub_menu_t menu, int hotkey)
   grub_menu_entry_t entry;
   int i;
 
-  for (i = 0, entry = menu->entry_list; i < menu->size;
+  for (i = 0, entry = menu->entry_list; entry;
        i++, entry = entry->next)
     if (entry->hotkey == hotkey)
-      return i;
+      return i | MENU_INCLUDE_HIDDEN;
 
   return -1;
 }
@@ -517,7 +531,7 @@ get_entry_number (grub_menu_t menu, const char *name)
          if (menuentry_eq (e->title, val)
              || menuentry_eq (e->id, val))
            {
-             entry = i;
+             entry = i | MENU_INCLUDE_HIDDEN;
              break;
            }
          e = e->next;
diff --git a/grub-core/normal/menu_text.c b/grub-core/normal/menu_text.c
index e22bb91..4ac2d6b 100644
--- a/grub-core/normal/menu_text.c
+++ b/grub-core/normal/menu_text.c
@@ -290,6 +290,10 @@ print_entries (grub_menu_t menu, const struct 
menu_viewer_data *data)
                   e, data);
       if (e)
        e = e->next;
+
+      /* Skip hidden entries */
+      while (e && e->hidden)
+        e = e->next;
     }
 
   grub_term_gotoxy (data->term,
diff --git a/include/grub/menu.h b/include/grub/menu.h
index ee2b5e9..eb8a86b 100644
--- a/include/grub/menu.h
+++ b/include/grub/menu.h
@@ -58,6 +58,8 @@ struct grub_menu_entry
 
   int submenu;
 
+  int hidden;
+
   /* The next element.  */
   struct grub_menu_entry *next;
 };
diff --git a/include/grub/normal.h b/include/grub/normal.h
index 218cbab..bcb4124 100644
--- a/include/grub/normal.h
+++ b/include/grub/normal.h
@@ -145,7 +145,7 @@ grub_normal_add_menu_entry (int argc, const char **args, 
char **classes,
                            const char *id,
                            const char *users, const char *hotkey,
                            const char *prefix, const char *sourcecode,
-                           int submenu);
+                           int submenu, int hidden);
 
 grub_err_t
 grub_normal_set_password (const char *user, const char *password);
-- 
1.8.5.6




reply via email to

[Prev in Thread] Current Thread [Next in Thread]