diff --git a/grub-core/commands/legacycfg.c b/grub-core/commands/legacycfg.c index e9e9d94ef..54e08a1b4 100644 --- a/grub-core/commands/legacycfg.c +++ b/grub-core/commands/legacycfg.c @@ -143,7 +143,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); @@ -205,7 +205,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 720e6d8ea..50632ccce 100644 --- a/grub-core/commands/menuentry.c +++ b/grub-core/commands/menuentry.c @@ -78,7 +78,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 +188,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: @@ -286,7 +289,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', + ctxt->extcmd->cmd->name[0] == 'h'); src = args[argc - 1]; args[argc - 1] = NULL; @@ -303,7 +307,8 @@ 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', + ctxt->extcmd->cmd->name[0] == 'h'); src[len - 1] = ch; args[argc - 1] = src; @@ -311,7 +316,7 @@ grub_cmd_menuentry (grub_extcmd_context_t ctxt, int argc, char **args) 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,12 @@ grub_menu_init (void) | 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 diff --git a/grub-core/normal/menu.c b/grub-core/normal/menu.c index 6a90e091f..4236f55bc 100644 --- a/grub-core/normal/menu.c +++ b/grub-core/normal/menu.c @@ -37,6 +37,8 @@ entry failing to boot. */ #define DEFAULT_ENTRY_ERROR_DELAY_MS 2500 +#define MENU_INCLUDE_HIDDEN 0x10000 + grub_err_t (*grub_gfxmenu_try_hook) (int entry, grub_menu_t menu, int nested) = NULL; @@ -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; } @@ -509,6 +523,10 @@ get_entry_number (grub_menu_t menu, const char *name) 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++) @@ -520,6 +538,10 @@ get_entry_number (grub_menu_t menu, const char *name) break; } e = e->next; + + /* Skip hidden entries */ + while (e && e->hidden) + e = e->next; } if (! e) diff --git a/grub-core/normal/menu_text.c b/grub-core/normal/menu_text.c index b1321eb26..d2e46cac8 100644 --- a/grub-core/normal/menu_text.c +++ b/grub-core/normal/menu_text.c @@ -289,7 +289,11 @@ print_entries (grub_menu_t menu, const struct menu_viewer_data *data) print_entry (data->geo.first_entry_y + i, data->offset == i, e, data); if (e) - e = e->next; + 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 ee2b5e910..eb8a86ba9 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 218cbabcc..bcb412466 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);