|
|
d9d99f |
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
|
d9d99f |
From: Peter Jones <pjones@redhat.com>
|
|
|
d9d99f |
Date: Fri, 5 Sep 2014 10:07:04 -0400
|
|
|
d9d99f |
Subject: [PATCH] Allow "fallback" to include entries by title, not just
|
|
|
d9d99f |
number.
|
|
|
d9d99f |
|
|
|
d9d99f |
Resolves: rhbz#1026084
|
|
|
d9d99f |
|
|
|
d9d99f |
Signed-off-by: Peter Jones <pjones@redhat.com>
|
|
|
d9d99f |
---
|
|
|
d9d99f |
grub-core/normal/menu.c | 85 +++++++++++++++++++++++++++++++++----------------
|
|
|
d9d99f |
1 file changed, 58 insertions(+), 27 deletions(-)
|
|
|
d9d99f |
|
|
|
d9d99f |
diff --git a/grub-core/normal/menu.c b/grub-core/normal/menu.c
|
|
|
d9d99f |
index e7a83c2d6e2..d2f64b05e0a 100644
|
|
|
d9d99f |
--- a/grub-core/normal/menu.c
|
|
|
d9d99f |
+++ b/grub-core/normal/menu.c
|
|
|
d9d99f |
@@ -163,16 +163,41 @@ grub_menu_set_timeout (int timeout)
|
|
|
d9d99f |
}
|
|
|
d9d99f |
}
|
|
|
d9d99f |
|
|
|
d9d99f |
+static int
|
|
|
d9d99f |
+menuentry_eq (const char *id, const char *spec)
|
|
|
d9d99f |
+{
|
|
|
d9d99f |
+ const char *ptr1, *ptr2;
|
|
|
d9d99f |
+ ptr1 = id;
|
|
|
d9d99f |
+ ptr2 = spec;
|
|
|
d9d99f |
+ while (1)
|
|
|
d9d99f |
+ {
|
|
|
d9d99f |
+ if (*ptr2 == '>' && ptr2[1] != '>' && *ptr1 == 0)
|
|
|
d9d99f |
+ return ptr2 - spec;
|
|
|
d9d99f |
+ if (*ptr2 == '>' && ptr2[1] != '>')
|
|
|
d9d99f |
+ return 0;
|
|
|
d9d99f |
+ if (*ptr2 == '>')
|
|
|
d9d99f |
+ ptr2++;
|
|
|
d9d99f |
+ if (*ptr1 != *ptr2)
|
|
|
d9d99f |
+ return 0;
|
|
|
d9d99f |
+ if (*ptr1 == 0)
|
|
|
d9d99f |
+ return ptr1 - id;
|
|
|
d9d99f |
+ ptr1++;
|
|
|
d9d99f |
+ ptr2++;
|
|
|
d9d99f |
+ }
|
|
|
d9d99f |
+ return 0;
|
|
|
d9d99f |
+}
|
|
|
d9d99f |
+
|
|
|
d9d99f |
/* Get the first entry number from the value of the environment variable NAME,
|
|
|
d9d99f |
which is a space-separated list of non-negative integers. The entry number
|
|
|
d9d99f |
which is returned is stripped from the value of NAME. If no entry number
|
|
|
d9d99f |
can be found, -1 is returned. */
|
|
|
d9d99f |
static int
|
|
|
d9d99f |
-get_and_remove_first_entry_number (const char *name)
|
|
|
d9d99f |
+get_and_remove_first_entry_number (grub_menu_t menu, const char *name)
|
|
|
d9d99f |
{
|
|
|
d9d99f |
const char *val;
|
|
|
d9d99f |
char *tail;
|
|
|
d9d99f |
int entry;
|
|
|
d9d99f |
+ int sz = 0;
|
|
|
d9d99f |
|
|
|
d9d99f |
val = grub_env_get (name);
|
|
|
d9d99f |
if (! val)
|
|
|
d9d99f |
@@ -182,9 +207,39 @@ get_and_remove_first_entry_number (const char *name)
|
|
|
d9d99f |
|
|
|
d9d99f |
entry = (int) grub_strtoul (val, &tail, 0);
|
|
|
d9d99f |
|
|
|
d9d99f |
+ if (grub_errno == GRUB_ERR_BAD_NUMBER)
|
|
|
d9d99f |
+ {
|
|
|
d9d99f |
+ /* See if the variable matches the title of a menu entry. */
|
|
|
d9d99f |
+ grub_menu_entry_t e = menu->entry_list;
|
|
|
d9d99f |
+ int i;
|
|
|
d9d99f |
+
|
|
|
d9d99f |
+ for (i = 0; e; i++)
|
|
|
d9d99f |
+ {
|
|
|
d9d99f |
+ sz = menuentry_eq (e->title, val);
|
|
|
d9d99f |
+ if (sz < 1)
|
|
|
d9d99f |
+ sz = menuentry_eq (e->id, val);
|
|
|
d9d99f |
+
|
|
|
d9d99f |
+ if (sz >= 1)
|
|
|
d9d99f |
+ {
|
|
|
d9d99f |
+ entry = i;
|
|
|
d9d99f |
+ break;
|
|
|
d9d99f |
+ }
|
|
|
d9d99f |
+ e = e->next;
|
|
|
d9d99f |
+ }
|
|
|
d9d99f |
+
|
|
|
d9d99f |
+ if (sz > 0)
|
|
|
d9d99f |
+ grub_errno = GRUB_ERR_NONE;
|
|
|
d9d99f |
+
|
|
|
d9d99f |
+ if (! e)
|
|
|
d9d99f |
+ entry = -1;
|
|
|
d9d99f |
+ }
|
|
|
d9d99f |
+
|
|
|
d9d99f |
if (grub_errno == GRUB_ERR_NONE)
|
|
|
d9d99f |
{
|
|
|
d9d99f |
- /* Skip whitespace to find the next digit. */
|
|
|
d9d99f |
+ if (sz > 0)
|
|
|
d9d99f |
+ tail += sz;
|
|
|
d9d99f |
+
|
|
|
d9d99f |
+ /* Skip whitespace to find the next entry. */
|
|
|
d9d99f |
while (*tail && grub_isspace (*tail))
|
|
|
d9d99f |
tail++;
|
|
|
d9d99f |
grub_env_set (name, tail);
|
|
|
d9d99f |
@@ -347,7 +402,7 @@ grub_menu_execute_with_fallback (grub_menu_t menu,
|
|
|
d9d99f |
grub_menu_execute_entry (entry, 1);
|
|
|
d9d99f |
|
|
|
d9d99f |
/* Deal with fallback entries. */
|
|
|
d9d99f |
- while ((fallback_entry = get_and_remove_first_entry_number ("fallback"))
|
|
|
d9d99f |
+ while ((fallback_entry = get_and_remove_first_entry_number (menu, "fallback"))
|
|
|
d9d99f |
>= 0)
|
|
|
d9d99f |
{
|
|
|
d9d99f |
grub_print_error ();
|
|
|
d9d99f |
@@ -465,30 +520,6 @@ grub_menu_register_viewer (struct grub_menu_viewer *viewer)
|
|
|
d9d99f |
viewers = viewer;
|
|
|
d9d99f |
}
|
|
|
d9d99f |
|
|
|
d9d99f |
-static int
|
|
|
d9d99f |
-menuentry_eq (const char *id, const char *spec)
|
|
|
d9d99f |
-{
|
|
|
d9d99f |
- const char *ptr1, *ptr2;
|
|
|
d9d99f |
- ptr1 = id;
|
|
|
d9d99f |
- ptr2 = spec;
|
|
|
d9d99f |
- while (1)
|
|
|
d9d99f |
- {
|
|
|
d9d99f |
- if (*ptr2 == '>' && ptr2[1] != '>' && *ptr1 == 0)
|
|
|
d9d99f |
- return 1;
|
|
|
d9d99f |
- if (*ptr2 == '>' && ptr2[1] != '>')
|
|
|
d9d99f |
- return 0;
|
|
|
d9d99f |
- if (*ptr2 == '>')
|
|
|
d9d99f |
- ptr2++;
|
|
|
d9d99f |
- if (*ptr1 != *ptr2)
|
|
|
d9d99f |
- return 0;
|
|
|
d9d99f |
- if (*ptr1 == 0)
|
|
|
d9d99f |
- return 1;
|
|
|
d9d99f |
- ptr1++;
|
|
|
d9d99f |
- ptr2++;
|
|
|
d9d99f |
- }
|
|
|
d9d99f |
-}
|
|
|
d9d99f |
-
|
|
|
d9d99f |
-
|
|
|
d9d99f |
/* Get the entry number from the variable NAME. */
|
|
|
d9d99f |
static int
|
|
|
d9d99f |
get_entry_number (grub_menu_t menu, const char *name)
|