From 6066889c88dd92fba5a9e845a8215ab115a96726 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 25 Dec 2009 16:28:31 +0100 Subject: [PATCH] normal_exit command --- include/grub/normal.h | 2 +- normal/main.c | 55 ++++++++++++++++++++++++++++++++----------- normal/menu.c | 6 +++++ normal/menu_entry.c | 6 +++++ 4 files changed, 54 insertions(+), 15 deletions(-) diff --git a/include/grub/normal.h b/include/grub/normal.h index af8e00a71..58b2c7966 100644 --- a/include/grub/normal.h +++ b/include/grub/normal.h @@ -46,7 +46,7 @@ enum grub_completion_type typedef enum grub_completion_type grub_completion_type_t; extern struct grub_menu_viewer grub_normal_text_menu_viewer; - +extern int grub_normal_exit_level; /* Defined in `main.c'. */ void grub_enter_normal_mode (const char *config); diff --git a/normal/main.c b/normal/main.c index 3ee4d295d..14e8971b0 100644 --- a/normal/main.c +++ b/normal/main.c @@ -34,6 +34,9 @@ #define GRUB_DEFAULT_HISTORY_SIZE 50 +static int nested_level = 0; +int grub_normal_exit_level = 0; + /* Read a line from the file FILE. */ char * grub_file_getline (grub_file_t file) @@ -430,8 +433,6 @@ grub_normal_init_page (struct grub_term_output *term) grub_free (unicode_msg); } -static int reader_nested; - /* Read the config file CONFIG and execute the menu interface or the command line interface if BATCH is false. */ void @@ -446,8 +447,6 @@ grub_normal_execute (const char *config, int nested, int batch) read_terminal_list (); grub_command_execute ("parser.grub", 0, 0); - reader_nested = nested; - if (config) { menu = read_config_file (config); @@ -471,8 +470,12 @@ grub_normal_execute (const char *config, int nested, int batch) void grub_enter_normal_mode (const char *config) { + nested_level++; grub_normal_execute (config, 0, 0); - grub_cmdline_run (1); + grub_cmdline_run (0); + nested_level--; + if (grub_normal_exit_level) + grub_normal_exit_level--; } /* Enter normal mode from rescue mode. */ @@ -508,8 +511,20 @@ quit: return 0; } +/* Exit from normal mode to rescue mode. */ static grub_err_t -grub_normal_reader_init (void) +grub_cmd_normal_exit (struct grub_command *cmd __attribute__ ((unused)), + int argc __attribute__ ((unused)), + char *argv[] __attribute__ ((unused))) +{ + if (nested_level <= grub_normal_exit_level) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "not in normal environment"); + grub_normal_exit_level++; + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_normal_reader_init (int nested) { struct grub_term_output *term; const char *msg = _("Minimal BASH-like line editing is supported. For " @@ -519,7 +534,7 @@ grub_normal_reader_init (void) char *msg_formatted = grub_malloc (sizeof (char) * (grub_strlen (msg) + grub_strlen(msg_esc) + 1)); - grub_sprintf (msg_formatted, msg, reader_nested ? msg_esc : ""); + grub_sprintf (msg_formatted, msg, nested ? msg_esc : ""); FOR_ACTIVE_TERM_OUTPUTS(term) { @@ -536,12 +551,15 @@ grub_normal_reader_init (void) static grub_err_t -grub_normal_read_line (char **line, int cont) +grub_normal_read_line_real (char **line, int cont, int nested) { grub_parser_t parser = grub_parser_get_current (); char prompt[sizeof("> ") + grub_strlen (parser->name)]; - grub_sprintf (prompt, "%s> ", parser->name); + if (cont) + grub_sprintf (prompt, "> "); + else + grub_sprintf (prompt, "%s> ", parser->name); while (1) { @@ -549,7 +567,7 @@ grub_normal_read_line (char **line, int cont) if (*line) break; - if ((reader_nested) || (cont)) + if (cont || nested) { grub_free (*line); *line = 0; @@ -560,6 +578,12 @@ grub_normal_read_line (char **line, int cont) return 0; } +static grub_err_t +grub_normal_read_line (char **line, int cont) +{ + return grub_normal_read_line_real (line, cont, 0); +} + void grub_cmdline_run (int nested) { @@ -574,19 +598,20 @@ grub_cmdline_run (int nested) return; } - reader_nested = nested; - - grub_normal_reader_init (); + grub_normal_reader_init (nested); while (1) { char *line; + if (grub_normal_exit_level) + break; + /* Print an error, if any. */ grub_print_error (); grub_errno = GRUB_ERR_NONE; - grub_normal_read_line (&line, 0); + grub_normal_read_line_real (&line, 0, nested); if (! line) break; @@ -623,6 +648,8 @@ GRUB_MOD_INIT(normal) /* Register a command "normal" for the rescue mode. */ grub_register_command ("normal", grub_cmd_normal, 0, "Enter normal mode"); + grub_register_command ("normal_exit", grub_cmd_normal_exit, + 0, "Exit from normal mode"); /* Reload terminal colors when these variables are written to. */ grub_register_variable_hook ("color_normal", NULL, grub_env_write_color_normal); diff --git a/normal/menu.c b/normal/menu.c index 8cf0e158d..62f33b61b 100644 --- a/normal/menu.c +++ b/normal/menu.c @@ -344,6 +344,9 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot) int c; timeout = grub_menu_get_timeout (); + if (grub_normal_exit_level) + return -1; + if (timeout > 0) { grub_uint64_t current_time; @@ -554,6 +557,9 @@ grub_show_menu (grub_menu_t menu, int nested) err1 = show_menu (menu, nested); grub_print_error (); + if (grub_normal_exit_level) + break; + err2 = grub_auth_check_authentication (NULL); if (err2) { diff --git a/normal/menu_entry.c b/normal/menu_entry.c index 9599abd97..7236f78e1 100644 --- a/normal/menu_entry.c +++ b/normal/menu_entry.c @@ -1270,6 +1270,12 @@ grub_menu_entry_run (grub_menu_entry_t entry) screen->completion_shown = 0; } + if (grub_normal_exit_level) + { + destroy_screen (screen); + return; + } + switch (c) { case 16: /* C-p */