merge mainline into newenv

This commit is contained in:
Vladimir 'phcoder' Serbinenko 2010-01-20 21:31:39 +01:00
commit 61c501a941
415 changed files with 17977 additions and 6997 deletions

View file

@ -30,9 +30,13 @@
#include <grub/menu_viewer.h>
#include <grub/auth.h>
#include <grub/i18n.h>
#include <grub/charset.h>
#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)
@ -372,7 +376,21 @@ read_config_file (const char *config)
if (! file)
return 0;
grub_reader_loop (getline);
while (1)
{
char *line;
/* Print an error, if any. */
grub_print_error ();
grub_errno = GRUB_ERR_NONE;
if ((getline (&line, 0)) || (! line))
break;
grub_parser_get_current ()->parse_line (line, getline);
grub_free (line);
}
grub_file_close (file);
if (old_parser)
@ -383,40 +401,48 @@ read_config_file (const char *config)
/* Initialize the screen. */
void
grub_normal_init_page (void)
grub_normal_init_page (struct grub_term_output *term)
{
int msg_len;
int posx;
const char *msg = _("GNU GRUB version %s");
char *msg_formatted = grub_malloc (grub_strlen(msg) +
grub_strlen(PACKAGE_VERSION));
grub_cls ();
grub_sprintf (msg_formatted, msg, PACKAGE_VERSION);
char *msg_formatted;
grub_uint32_t *unicode_msg;
grub_uint32_t *last_position;
msg_len = grub_utf8_to_ucs4_alloc (msg_formatted,
grub_term_cls (term);
msg_formatted = grub_xasprintf (msg, PACKAGE_VERSION);
if (!msg_formatted)
return;
msg_len = grub_utf8_to_ucs4_alloc (msg_formatted,
&unicode_msg, &last_position);
if (msg_len < 0)
{
return;
}
posx = grub_getstringwidth (unicode_msg, last_position);
posx = (GRUB_TERM_WIDTH - posx) / 2;
grub_gotoxy (posx, 1);
posx = grub_getstringwidth (unicode_msg, last_position, term);
posx = (grub_term_width (term) - posx) / 2;
grub_term_gotoxy (term, posx, 1);
grub_print_ucs4 (unicode_msg, last_position);
grub_print_ucs4 (unicode_msg, last_position, term);
grub_printf("\n\n");
grub_free (unicode_msg);
}
static int reader_nested;
static char *
read_lists (struct grub_env_var *var __attribute__ ((unused)),
const char *val)
{
read_command_list ();
read_fs_list ();
read_crypto_list ();
read_terminal_list ();
return val ? grub_strdup (val) : NULL;
}
/* Read the config file CONFIG and execute the menu interface or
the command line interface if BATCH is false. */
@ -425,13 +451,11 @@ grub_normal_execute (const char *config, int nested, int batch)
{
grub_menu_t menu = 0;
read_command_list ();
read_fs_list ();
read_lists (NULL, NULL);
read_handler_list ();
grub_register_variable_hook ("prefix", NULL, read_lists);
grub_command_execute ("parser.grub", 0, 0);
reader_nested = nested;
if (config)
{
menu = read_config_file (config);
@ -444,7 +468,7 @@ grub_normal_execute (const char *config, int nested, int batch)
{
if (menu && menu->size)
{
grub_menu_viewer_show_menu (menu, nested);
grub_show_menu (menu, nested);
if (nested)
free_menu (menu);
}
@ -455,31 +479,33 @@ 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 (0);
nested_level--;
if (grub_normal_exit_level)
grub_normal_exit_level--;
}
/* Enter normal mode from rescue mode. */
static grub_err_t
grub_cmd_normal (struct grub_command *cmd,
grub_cmd_normal (struct grub_command *cmd __attribute__ ((unused)),
int argc, char *argv[])
{
grub_unregister_command (cmd);
if (argc == 0)
{
/* Guess the config filename. It is necessary to make CONFIG static,
so that it won't get broken by longjmp. */
static char *config;
char *config;
const char *prefix;
prefix = grub_env_get ("prefix");
if (prefix)
{
config = grub_malloc (grub_strlen (prefix) + sizeof ("/grub.cfg"));
config = grub_xasprintf ("%s/grub.cfg", prefix);
if (! config)
goto quit;
grub_sprintf (config, "%s/grub.cfg", prefix);
grub_enter_normal_mode (config);
grub_free (config);
}
@ -493,10 +519,86 @@ quit:
return 0;
}
/* Exit from normal mode to rescue mode. */
static grub_err_t
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 "
"the first word, TAB lists possible command completions. Anywhere "
"else TAB lists possible device or file completions. %s");
const char *msg_esc = _("ESC at any time exits.");
char *msg_formatted;
msg_formatted = grub_xasprintf (msg, nested ? msg_esc : "");
if (!msg_formatted)
return grub_errno;
FOR_ACTIVE_TERM_OUTPUTS(term)
{
grub_normal_init_page (term);
grub_term_setcursor (term, 1);
grub_print_message_indented (msg_formatted, 3, STANDARD_MARGIN, term);
grub_puts ("\n");
}
grub_free (msg_formatted);
return 0;
}
static grub_err_t
grub_normal_read_line_real (char **line, int cont, int nested)
{
grub_parser_t parser = grub_parser_get_current ();
char *prompt;
if (cont)
prompt = grub_xasprintf (">");
else
prompt = grub_xasprintf ("%s>", parser->name);
if (!prompt)
return grub_errno;
while (1)
{
*line = grub_cmdline_get (prompt);
if (*line)
break;
if (cont || nested)
{
grub_free (*line);
*line = 0;
return grub_errno;
}
}
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)
{
grub_reader_t reader;
grub_err_t err = GRUB_ERR_NONE;
err = grub_auth_check_authentication (NULL);
@ -508,72 +610,28 @@ grub_cmdline_run (int nested)
return;
}
reader = grub_reader_get_current ();
reader_nested = nested;
if (reader->init)
reader->init ();
grub_reader_loop (0);
}
static grub_err_t
grub_normal_reader_init (void)
{
grub_normal_init_page ();
grub_setcursor (1);
const char *msg = _("Minimal BASH-like line editing is supported. For "
"the first word, TAB lists possible command completions. Anywhere "
"else TAB lists possible device or file completions. %s");
const char *msg_esc = _("ESC at any time exits.");
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_print_message_indented (msg_formatted, 3, STANDARD_MARGIN);
grub_puts ("\n");
grub_free (msg_formatted);
return 0;
}
static char cmdline[GRUB_MAX_CMDLINE];
static grub_err_t
grub_normal_read_line (char **line, int cont)
{
grub_parser_t parser = grub_parser_get_current ();
char prompt[sizeof("> ") + grub_strlen (parser->name)];
grub_sprintf (prompt, "%s> ", parser->name);
grub_normal_reader_init (nested);
while (1)
{
cmdline[0] = 0;
if (grub_cmdline_get (prompt, cmdline, sizeof (cmdline), 0, 1, 1))
char *line;
if (grub_normal_exit_level)
break;
if ((reader_nested) || (cont))
{
*line = 0;
return grub_errno;
}
/* Print an error, if any. */
grub_print_error ();
grub_errno = GRUB_ERR_NONE;
grub_normal_read_line_real (&line, 0, nested);
if (! line)
break;
grub_parser_get_current ()->parse_line (line, grub_normal_read_line);
grub_free (line);
}
*line = grub_strdup (cmdline);
return 0;
}
static struct grub_reader grub_normal_reader =
{
.name = "normal",
.init = grub_normal_reader_init,
.read_line = grub_normal_read_line
};
static char *
grub_env_write_pager (struct grub_env_var *var __attribute__ ((unused)),
const char *val)
@ -590,17 +648,15 @@ GRUB_MOD_INIT(normal)
if (mod)
grub_dl_ref (mod);
grub_menu_viewer_register (&grub_normal_text_menu_viewer);
grub_set_history (GRUB_DEFAULT_HISTORY_SIZE);
grub_reader_register ("normal", &grub_normal_reader);
grub_reader_set_current (&grub_normal_reader);
grub_register_variable_hook ("pager", 0, grub_env_write_pager);
/* Register a command "normal" for the rescue mode. */
grub_register_command_prio ("normal", grub_cmd_normal,
0, "Enter normal mode", 0);
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);
@ -616,7 +672,6 @@ GRUB_MOD_FINI(normal)
grub_context_fini ();
grub_set_history (0);
grub_reader_unregister (&grub_normal_reader);
grub_register_variable_hook ("pager", 0, 0);
grub_fs_autoload_hook = 0;
free_handler_list ();