]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
normal_exit command
authorVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Fri, 25 Dec 2009 15:28:31 +0000 (16:28 +0100)
committerVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Fri, 25 Dec 2009 15:28:31 +0000 (16:28 +0100)
include/grub/normal.h
normal/main.c
normal/menu.c
normal/menu_entry.c

index af8e00a71740aa67db775f8c0a6aaf494a2c2500..58b2c7966159d769d63cfd31a8023c392cbbdeae 100644 (file)
@@ -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);
index 3ee4d295dda5daa55f79a501ee2570676b5a7056..14e8971b0272923874ad5c5017f0799d22dc350e 100644 (file)
@@ -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);
index 8cf0e158df01a0e838724bf007f2cc1718d0fbb1..62f33b61bc026c5ae9939d9367b578373222b17e 100644 (file)
@@ -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)
        {
index 9599abd97b294aa41c9dd3e75e00e2a4b5b3b031..7236f78e150296e755aa8228f0945a207dfdf0fd 100644 (file)
@@ -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 */