From a06004f4c668abd7c760a2818d0a8205da7568e7 Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Tue, 26 Apr 2016 15:29:25 +0200 Subject: [PATCH v3] Add hidden menu entries 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 --- v1 -> v2: - fix default entry selection v2 -> v3: - replace "--hidden" parameter with new command "hiddenentry" --- a/grub-core/commands/legacycfg.c +++ b/grub-core/commands/legacycfg.c @@ -143,7 +143,7 @@ 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); @@ -205,7 +205,7 @@ } 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); } --- a/grub-core/commands/menuentry.c +++ b/grub-core/commands/menuentry.c @@ -78,7 +78,7 @@ 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 +188,11 @@ (*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: @@ -286,7 +289,8 @@ users, ctxt->state[2].arg, 0, ctxt->state[3].arg, - ctxt->extcmd->cmd->name[0] == 's'); + ctxt->extcmd->cmd->name[0] == 's', + ctxt->extcmd->cmd->name[0] == 'h'); src = args[argc - 1]; args[argc - 1] = NULL; @@ -303,7 +307,8 @@ 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', + ctxt->extcmd->cmd->name[0] == 'h'); src[len - 1] = ch; args[argc - 1] = src; @@ -311,7 +316,7 @@ return r; } -static grub_extcmd_t cmd, cmd_sub; +static grub_extcmd_t cmd, cmd_sub, cmd_hidden; void grub_menu_init (void) @@ -327,6 +332,13 @@ | GRUB_COMMAND_FLAG_EXTRACTOR, N_("BLOCK"), N_("Define a submenu."), options); + cmd_hidden = grub_register_extcmd ("hiddenentry", grub_cmd_menuentry, + GRUB_COMMAND_FLAG_BLOCKS + | GRUB_COMMAND_ACCEPT_DASH + | GRUB_COMMAND_FLAG_EXTRACTOR, + N_("BLOCK"), + N_("Define a hidden menu entry."), + options); } void --- 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_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 @@ 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; } @@ -519,6 +533,10 @@ grub_menu_entry_t e = menu->entry_list; int i; + /* Skip hidden entries */ + while (e && e->hidden) + e = e->next; + grub_errno = GRUB_ERR_NONE; for (i = 0; e; i++) @@ -530,6 +548,10 @@ break; } e = e->next; + + /* Skip hidden entries */ + while (e && e->hidden) + e = e->next; } if (! e) --- a/grub-core/normal/menu_text.c +++ b/grub-core/normal/menu_text.c @@ -318,6 +318,10 @@ e, data); if (e) e = e->next; + + /* Skip hidden entries */ + while (e && e->hidden) + e = e->next; } grub_term_gotoxy (data->term, --- a/include/grub/menu.h +++ b/include/grub/menu.h @@ -58,6 +58,8 @@ int submenu; + int hidden; + /* The next element. */ struct grub_menu_entry *next; }; --- a/include/grub/normal.h +++ b/include/grub/normal.h @@ -145,7 +145,7 @@ 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);