You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
140 lines
3.4 KiB
140 lines
3.4 KiB
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
|
From: Peter Jones <pjones@redhat.com> |
|
Date: Fri, 5 Sep 2014 10:07:04 -0400 |
|
Subject: [PATCH] Allow "fallback" to include entries by title, not just |
|
number. |
|
|
|
Resolves: rhbz#1026084 |
|
|
|
Signed-off-by: Peter Jones <pjones@redhat.com> |
|
--- |
|
grub-core/normal/menu.c | 85 +++++++++++++++++++++++++++++++++---------------- |
|
1 file changed, 58 insertions(+), 27 deletions(-) |
|
|
|
diff --git a/grub-core/normal/menu.c b/grub-core/normal/menu.c |
|
index 8397886fa05..d7a222e681b 100644 |
|
--- a/grub-core/normal/menu.c |
|
+++ b/grub-core/normal/menu.c |
|
@@ -163,15 +163,40 @@ grub_menu_set_timeout (int timeout) |
|
} |
|
} |
|
|
|
+static int |
|
+menuentry_eq (const char *id, const char *spec) |
|
+{ |
|
+ const char *ptr1, *ptr2; |
|
+ ptr1 = id; |
|
+ ptr2 = spec; |
|
+ while (1) |
|
+ { |
|
+ if (*ptr2 == '>' && ptr2[1] != '>' && *ptr1 == 0) |
|
+ return ptr2 - spec; |
|
+ if (*ptr2 == '>' && ptr2[1] != '>') |
|
+ return 0; |
|
+ if (*ptr2 == '>') |
|
+ ptr2++; |
|
+ if (*ptr1 != *ptr2) |
|
+ return 0; |
|
+ if (*ptr1 == 0) |
|
+ return ptr1 - id; |
|
+ ptr1++; |
|
+ ptr2++; |
|
+ } |
|
+ return 0; |
|
+} |
|
+ |
|
/* Get the first entry number from the value of the environment variable NAME, |
|
which is a space-separated list of non-negative integers. The entry number |
|
which is returned is stripped from the value of NAME. If no entry number |
|
can be found, -1 is returned. */ |
|
static int |
|
-get_and_remove_first_entry_number (const char *name) |
|
+get_and_remove_first_entry_number (grub_menu_t menu, const char *name) |
|
{ |
|
const char *val, *tail; |
|
int entry; |
|
+ int sz = 0; |
|
|
|
val = grub_env_get (name); |
|
if (! val) |
|
@@ -181,9 +206,39 @@ get_and_remove_first_entry_number (const char *name) |
|
|
|
entry = (int) grub_strtoul (val, &tail, 0); |
|
|
|
+ if (grub_errno == GRUB_ERR_BAD_NUMBER) |
|
+ { |
|
+ /* See if the variable matches the title of a menu entry. */ |
|
+ grub_menu_entry_t e = menu->entry_list; |
|
+ int i; |
|
+ |
|
+ for (i = 0; e; i++) |
|
+ { |
|
+ sz = menuentry_eq (e->title, val); |
|
+ if (sz < 1) |
|
+ sz = menuentry_eq (e->id, val); |
|
+ |
|
+ if (sz >= 1) |
|
+ { |
|
+ entry = i; |
|
+ break; |
|
+ } |
|
+ e = e->next; |
|
+ } |
|
+ |
|
+ if (sz > 0) |
|
+ grub_errno = GRUB_ERR_NONE; |
|
+ |
|
+ if (! e) |
|
+ entry = -1; |
|
+ } |
|
+ |
|
if (grub_errno == GRUB_ERR_NONE) |
|
{ |
|
- /* Skip whitespace to find the next digit. */ |
|
+ if (sz > 0) |
|
+ tail += sz; |
|
+ |
|
+ /* Skip whitespace to find the next entry. */ |
|
while (*tail && grub_isspace (*tail)) |
|
tail++; |
|
grub_env_set (name, tail); |
|
@@ -346,7 +401,7 @@ grub_menu_execute_with_fallback (grub_menu_t menu, |
|
grub_menu_execute_entry (entry, 1); |
|
|
|
/* Deal with fallback entries. */ |
|
- while ((fallback_entry = get_and_remove_first_entry_number ("fallback")) |
|
+ while ((fallback_entry = get_and_remove_first_entry_number (menu, "fallback")) |
|
>= 0) |
|
{ |
|
grub_print_error (); |
|
@@ -464,30 +519,6 @@ grub_menu_register_viewer (struct grub_menu_viewer *viewer) |
|
viewers = viewer; |
|
} |
|
|
|
-static int |
|
-menuentry_eq (const char *id, const char *spec) |
|
-{ |
|
- const char *ptr1, *ptr2; |
|
- ptr1 = id; |
|
- ptr2 = spec; |
|
- while (1) |
|
- { |
|
- if (*ptr2 == '>' && ptr2[1] != '>' && *ptr1 == 0) |
|
- return 1; |
|
- if (*ptr2 == '>' && ptr2[1] != '>') |
|
- return 0; |
|
- if (*ptr2 == '>') |
|
- ptr2++; |
|
- if (*ptr1 != *ptr2) |
|
- return 0; |
|
- if (*ptr1 == 0) |
|
- return 1; |
|
- ptr1++; |
|
- ptr2++; |
|
- } |
|
-} |
|
- |
|
- |
|
/* Get the entry number from the variable NAME. */ |
|
static int |
|
get_entry_number (grub_menu_t menu, const char *name)
|
|
|