merge mainline to ia64

This commit is contained in:
Vladimir 'phcoder' Serbinenko 2011-01-03 00:04:39 +01:00
commit 0f35c665e6
595 changed files with 62746 additions and 9109 deletions

View file

@ -161,7 +161,7 @@ grub_username_get (char buf[], unsigned buf_size)
while (1)
{
key = GRUB_TERM_ASCII_CHAR (grub_getkey ());
key = grub_getkey ();
if (key == '\n' || key == '\r')
break;
@ -201,7 +201,6 @@ grub_auth_check_authentication (const char *userlist)
{
char login[1024];
struct grub_auth_user *cur = NULL;
grub_err_t err;
static unsigned long punishment_delay = 1;
char entered[GRUB_AUTH_MAX_PASSLEN];
struct grub_auth_user *user;
@ -233,7 +232,7 @@ grub_auth_check_authentication (const char *userlist)
if (!cur || ! cur->callback)
goto access_denied;
err = cur->callback (login, entered, cur->arg);
cur->callback (login, entered, cur->arg);
if (is_authenticated (userlist))
{
punishment_delay = 1;
@ -248,3 +247,27 @@ grub_auth_check_authentication (const char *userlist)
return GRUB_ACCESS_DENIED;
}
static grub_err_t
grub_cmd_authenticate (struct grub_command *cmd __attribute__ ((unused)),
int argc, char **args)
{
return grub_auth_check_authentication ((argc >= 1) ? args[0] : "");
}
static grub_command_t cmd;
void
grub_normal_auth_init (void)
{
cmd = grub_register_command ("authenticate",
grub_cmd_authenticate,
N_("[USERLIST]"), N_("Authenticate users"));
}
void
grub_normal_auth_fini (void)
{
grub_unregister_command (cmd);
}

View file

@ -113,16 +113,6 @@ grub_utf8_to_utf16 (grub_uint16_t *dest, grub_size_t destsize,
count = 3;
code = c & GRUB_UINT8_3_TRAILINGBITS;
}
else if ((c & GRUB_UINT8_6_LEADINGBITS) == GRUB_UINT8_5_LEADINGBITS)
{
count = 4;
code = c & GRUB_UINT8_2_TRAILINGBITS;
}
else if ((c & GRUB_UINT8_7_LEADINGBITS) == GRUB_UINT8_6_LEADINGBITS)
{
count = 5;
code = c & GRUB_UINT8_1_TRAILINGBIT;
}
else
return -1;
}
@ -177,7 +167,7 @@ grub_ucs4_to_utf8 (grub_uint32_t *src, grub_size_t size,
/* No surrogates in UCS-4... */
*dest++ = '?';
}
else
else if (code < 0x10000)
{
if (dest + 2 >= destend)
break;
@ -185,6 +175,15 @@ grub_ucs4_to_utf8 (grub_uint32_t *src, grub_size_t size,
*dest++ = ((code >> 6) & 0x3F) | 0x80;
*dest++ = (code & 0x3F) | 0x80;
}
else
{
if (dest + 3 >= destend)
break;
*dest++ = (code >> 18) | 0xF0;
*dest++ = ((code >> 12) & 0x3F) | 0x80;
*dest++ = ((code >> 6) & 0x3F) | 0x80;
*dest++ = (code & 0x3F) | 0x80;
}
}
*dest = 0;
}
@ -212,8 +211,10 @@ grub_ucs4_to_utf8_alloc (grub_uint32_t *src, grub_size_t size)
|| (code >= 0xD800 && code <= 0xDBFF))
/* No surrogates in UCS-4... */
cnt++;
else
else if (code < 0x10000)
cnt += 3;
else
cnt += 4;
}
cnt++;
@ -273,16 +274,6 @@ grub_is_valid_utf8 (const grub_uint8_t *src, grub_size_t srcsize)
count = 3;
code = c & 0x07;
}
else if ((c & 0xfc) == 0xf8)
{
count = 4;
code = c & 0x03;
}
else if ((c & 0xfe) == 0xfc)
{
count = 5;
code = c & 0x01;
}
else
return 0;
}
@ -375,16 +366,6 @@ grub_utf8_to_ucs4 (grub_uint32_t *dest, grub_size_t destsize,
count = 3;
code = c & 0x07;
}
else if ((c & 0xfc) == 0xf8)
{
count = 4;
code = c & 0x03;
}
else if ((c & 0xfe) == 0xfc)
{
count = 5;
code = c & 0x01;
}
else
{
/* invalid */

View file

@ -388,16 +388,18 @@ grub_cmdline_get (const char *prompt)
grub_refresh ();
while ((key = GRUB_TERM_ASCII_CHAR (grub_getkey ())) != '\n' && key != '\r')
while ((key = grub_getkey ()) != '\n' && key != '\r')
{
switch (key)
{
case 1: /* Ctrl-a */
case GRUB_TERM_CTRL | 'a':
case GRUB_TERM_KEY_HOME:
lpos = 0;
cl_set_pos_all ();
break;
case 2: /* Ctrl-b */
case GRUB_TERM_CTRL | 'b':
case GRUB_TERM_KEY_LEFT:
if (lpos > 0)
{
lpos--;
@ -405,12 +407,14 @@ grub_cmdline_get (const char *prompt)
}
break;
case 5: /* Ctrl-e */
case GRUB_TERM_CTRL | 'e':
case GRUB_TERM_KEY_END:
lpos = llen;
cl_set_pos_all ();
break;
case 6: /* Ctrl-f */
case GRUB_TERM_CTRL | 'f':
case GRUB_TERM_KEY_RIGHT:
if (lpos < llen)
{
lpos++;
@ -418,7 +422,8 @@ grub_cmdline_get (const char *prompt)
}
break;
case 9: /* Ctrl-i or TAB */
case GRUB_TERM_CTRL | 'i':
case '\t':
{
int restore;
char *insertu8;
@ -492,7 +497,7 @@ grub_cmdline_get (const char *prompt)
}
break;
case 11: /* Ctrl-k */
case GRUB_TERM_CTRL | 'k':
if (lpos < llen)
{
if (kill_buf)
@ -516,7 +521,8 @@ grub_cmdline_get (const char *prompt)
}
break;
case 14: /* Ctrl-n */
case GRUB_TERM_CTRL | 'n':
case GRUB_TERM_KEY_DOWN:
{
grub_uint32_t *hist;
@ -534,7 +540,9 @@ grub_cmdline_get (const char *prompt)
break;
}
case 16: /* Ctrl-p */
case GRUB_TERM_KEY_UP:
case GRUB_TERM_CTRL | 'p':
{
grub_uint32_t *hist;
@ -553,7 +561,7 @@ grub_cmdline_get (const char *prompt)
}
break;
case 21: /* Ctrl-u */
case GRUB_TERM_CTRL | 'u':
if (lpos > 0)
{
grub_size_t n = lpos;
@ -579,7 +587,7 @@ grub_cmdline_get (const char *prompt)
}
break;
case 25: /* Ctrl-y */
case GRUB_TERM_CTRL | 'y':
if (kill_buf)
cl_insert (kill_buf);
break;
@ -598,7 +606,8 @@ grub_cmdline_get (const char *prompt)
break;
/* fall through */
case 4: /* Ctrl-d */
case GRUB_TERM_CTRL | 'd':
case GRUB_TERM_KEY_DC:
if (lpos < llen)
cl_delete (1);
break;

View file

@ -100,15 +100,16 @@ static int
iterate_partition (grub_disk_t disk, const grub_partition_t p)
{
const char *disk_name = disk->name;
char *partition_name = grub_partition_get_name (p);
char *name;
int ret;
char *part_name;
if (! partition_name)
part_name = grub_partition_get_name (p);
if (! part_name)
return 1;
name = grub_xasprintf ("%s,%s", disk_name, partition_name);
grub_free (partition_name);
name = grub_xasprintf ("%s,%s", disk_name, part_name);
grub_free (part_name);
if (! name)
return 1;
@ -160,14 +161,23 @@ iterate_dev (const char *devname)
if (dev)
{
if (dev->disk && dev->disk->has_partitions)
char tmp[grub_strlen (devname) + sizeof (",")];
grub_memcpy (tmp, devname, grub_strlen (devname));
if (grub_strcmp (devname, current_word) == 0)
{
if (add_completion (devname, ",", GRUB_COMPLETION_TYPE_DEVICE))
if (add_completion (devname, ")", GRUB_COMPLETION_TYPE_PARTITION))
return 1;
if (dev->disk)
if (grub_partition_iterate (dev->disk, iterate_partition))
return 1;
}
else
{
if (add_completion (devname, ")", GRUB_COMPLETION_TYPE_DEVICE))
grub_memcpy (tmp + grub_strlen (devname), "", sizeof (""));
if (add_completion (tmp, "", GRUB_COMPLETION_TYPE_DEVICE))
return 1;
}
}
@ -200,7 +210,7 @@ complete_device (void)
if (dev)
{
if (dev->disk && dev->disk->has_partitions)
if (dev->disk)
{
if (grub_partition_iterate (dev->disk, iterate_partition))
{
@ -247,7 +257,8 @@ complete_file (void)
goto fail;
}
dir = grub_strchr (current_word, '/');
dir = grub_strchr (current_word + (device ? 2 + grub_strlen (device) : 0),
'/');
last_dir = grub_strrchr (current_word, '/');
if (dir)
{
@ -419,11 +430,8 @@ grub_normal_do_completion (char *buf, int *restore,
{
if (cmd->prio & GRUB_PRIO_LIST_FLAG_ACTIVE)
{
if (cmd->flags & GRUB_COMMAND_FLAG_CMDLINE)
{
if (add_completion (cmd->name, " ", GRUB_COMPLETION_TYPE_COMMAND))
goto fail;
}
if (add_completion (cmd->name, " ", GRUB_COMPLETION_TYPE_COMMAND))
goto fail;
}
}
}
@ -500,8 +508,8 @@ grub_normal_do_completion (char *buf, int *restore,
fail:
if (argc != 0)
{
grub_free (argv);
grub_free (argv[0]);
grub_free (argv);
}
grub_free (match);
grub_errno = GRUB_ERR_NONE;

View file

@ -52,8 +52,8 @@ grub_env_set_menu (grub_menu_t nmenu)
current_menu->menu = nmenu;
}
grub_err_t
grub_env_context_open (int export)
static grub_err_t
grub_env_new_context (int export_all)
{
struct grub_env_context *context;
int i;
@ -78,23 +78,36 @@ grub_env_context_open (int export)
struct grub_env_var *var;
for (var = context->prev->vars[i]; var; var = var->next)
{
if (export && var->global)
{
if (grub_env_set (var->name, var->value) != GRUB_ERR_NONE)
{
grub_env_context_close ();
return grub_errno;
}
grub_env_export (var->name);
grub_register_variable_hook (var->name, var->read_hook, var->write_hook);
}
}
if (var->global || export_all)
{
if (grub_env_set (var->name, var->value) != GRUB_ERR_NONE)
{
grub_env_context_close ();
return grub_errno;
}
grub_env_export (var->name);
grub_register_variable_hook (var->name, var->read_hook, var->write_hook);
}
}
return GRUB_ERR_NONE;
}
grub_err_t
grub_env_context_open (void)
{
return grub_env_new_context (0);
}
int grub_extractor_level = 0;
grub_err_t
grub_env_extractor_open (int source)
{
grub_extractor_level++;
return grub_env_new_context (source);
}
grub_err_t
grub_env_context_close (void)
{
@ -132,6 +145,36 @@ grub_env_context_close (void)
return GRUB_ERR_NONE;
}
grub_err_t
grub_env_extractor_close (int source)
{
grub_menu_t menu, menu2;
grub_menu_entry_t *last;
grub_err_t err;
if (source)
{
menu = grub_env_get_menu ();
grub_env_unset_menu ();
}
err = grub_env_context_close ();
if (source)
{
menu2 = grub_env_get_menu ();
last = &menu2->entry_list;
while (*last)
last = &(*last)->next;
*last = menu->entry_list;
menu2->size += menu->size;
}
grub_extractor_level--;
return err;
}
grub_err_t
grub_env_export (const char *name)
{

View file

@ -23,16 +23,21 @@
#include <grub/misc.h>
#include <grub/command.h>
#include <grub/normal.h>
#include <grub/extcmd.h>
#include <grub/script_sh.h>
#include <grub/i18n.h>
static grub_err_t
grub_dyncmd_dispatcher (struct grub_command *cmd,
grub_dyncmd_dispatcher (struct grub_extcmd_context *ctxt,
int argc, char **args)
{
char *modname = cmd->data;
char *modname;
grub_dl_t mod;
grub_err_t ret;
grub_extcmd_t extcmd = ctxt->extcmd;
grub_command_t cmd = extcmd->cmd;
modname = extcmd->data;
mod = grub_dl_load (modname);
if (mod)
{
@ -42,11 +47,17 @@ grub_dyncmd_dispatcher (struct grub_command *cmd,
grub_dl_ref (mod);
name = (char *) cmd->name;
grub_unregister_command (cmd);
grub_unregister_extcmd (extcmd);
cmd = grub_command_find (name);
if (cmd)
ret = (cmd->func) (cmd, argc, args);
{
if (cmd->flags & GRUB_COMMAND_FLAG_BLOCKS &&
cmd->flags & GRUB_COMMAND_FLAG_EXTCMD)
ret = grub_extcmd_dispatcher (cmd, argc, args, ctxt->script);
else
ret = (cmd->func) (cmd, argc, args);
}
else
ret = grub_errno;
@ -81,13 +92,14 @@ read_command_list (const char *prefix)
for (ptr = grub_command_list; ptr; ptr = next)
{
next = ptr->next;
if (ptr->func == grub_dyncmd_dispatcher)
if (ptr->flags & GRUB_COMMAND_FLAG_DYNCMD)
{
if (last)
last->next = ptr->next;
else
grub_command_list = ptr->next;
grub_free (ptr);
grub_free (ptr->data); /* extcmd struct */
}
else
last = ptr;
@ -96,7 +108,7 @@ read_command_list (const char *prefix)
for (;; grub_free (buf))
{
char *p, *name, *modname;
grub_command_t cmd;
grub_extcmd_t cmd;
int prio = 0;
buf = grub_file_getline (file);
@ -139,16 +151,19 @@ read_command_list (const char *prefix)
continue;
}
cmd = grub_register_command_prio (name,
grub_dyncmd_dispatcher,
0, N_("not loaded"), prio);
cmd = grub_register_extcmd_prio (name,
grub_dyncmd_dispatcher,
GRUB_COMMAND_FLAG_BLOCKS
| GRUB_COMMAND_FLAG_EXTCMD
| GRUB_COMMAND_FLAG_DYNCMD,
0, N_("not loaded"), 0,
prio);
if (! cmd)
{
grub_free (name);
grub_free (modname);
continue;
}
cmd->flags |= GRUB_COMMAND_FLAG_DYNCMD;
cmd->data = modname;
/* Update the active flag. */

View file

@ -123,8 +123,8 @@ grub_file_getline (grub_file_t file)
return cmdline;
}
static void
free_menu (grub_menu_t menu)
void
grub_normal_free_menu (grub_menu_t menu)
{
grub_menu_entry_t entry = menu->entry_list;
@ -141,209 +141,6 @@ free_menu (grub_menu_t menu)
grub_env_unset_menu ();
}
static void
free_menu_entry_classes (struct grub_menu_entry_class *head)
{
/* Free all the classes. */
while (head)
{
struct grub_menu_entry_class *next;
grub_free (head->name);
next = head->next;
grub_free (head);
head = next;
}
}
static struct
{
char *name;
int key;
} hotkey_aliases[] =
{
{"backspace", '\b'},
{"tab", '\t'},
{"delete", GRUB_TERM_DC}
};
/* Add a menu entry to the current menu context (as given by the environment
variable data slot `menu'). As the configuration file is read, the script
parser calls this when a menu entry is to be created. */
grub_err_t
grub_normal_add_menu_entry (int argc, const char **args,
const char *sourcecode)
{
const char *menutitle = 0;
const char *menusourcecode;
grub_menu_t menu;
grub_menu_entry_t *last;
int failed = 0;
int i;
struct grub_menu_entry_class *classes_head; /* Dummy head node for list. */
struct grub_menu_entry_class *classes_tail;
char *users = NULL;
int hotkey = 0;
/* Allocate dummy head node for class list. */
classes_head = grub_zalloc (sizeof (struct grub_menu_entry_class));
if (! classes_head)
return grub_errno;
classes_tail = classes_head;
menu = grub_env_get_menu ();
if (! menu)
return grub_error (GRUB_ERR_MENU, "no menu context");
last = &menu->entry_list;
menusourcecode = grub_strdup (sourcecode);
if (! menusourcecode)
return grub_errno;
/* Parse menu arguments. */
for (i = 0; i < argc; i++)
{
/* Capture arguments. */
if (grub_strncmp ("--", args[i], 2) == 0 && i + 1 < argc)
{
const char *arg = &args[i][2];
/* Handle menu class. */
if (grub_strcmp(arg, "class") == 0)
{
char *class_name;
struct grub_menu_entry_class *new_class;
i++;
class_name = grub_strdup (args[i]);
if (! class_name)
{
failed = 1;
break;
}
/* Create a new class and add it at the tail of the list. */
new_class = grub_zalloc (sizeof (struct grub_menu_entry_class));
if (! new_class)
{
grub_free (class_name);
failed = 1;
break;
}
/* Fill in the new class node. */
new_class->name = class_name;
/* Link the tail to it, and make it the new tail. */
classes_tail->next = new_class;
classes_tail = new_class;
continue;
}
else if (grub_strcmp(arg, "users") == 0)
{
i++;
users = grub_strdup (args[i]);
if (! users)
{
failed = 1;
break;
}
continue;
}
else if (grub_strcmp(arg, "hotkey") == 0)
{
unsigned j;
i++;
if (args[i][1] == 0)
{
hotkey = args[i][0];
continue;
}
for (j = 0; j < ARRAY_SIZE (hotkey_aliases); j++)
if (grub_strcmp (args[i], hotkey_aliases[j].name) == 0)
{
hotkey = hotkey_aliases[j].key;
break;
}
if (j < ARRAY_SIZE (hotkey_aliases))
continue;
failed = 1;
grub_error (GRUB_ERR_MENU,
"Invalid hotkey: '%s'.", args[i]);
break;
}
else
{
/* Handle invalid argument. */
failed = 1;
grub_error (GRUB_ERR_MENU,
"invalid argument for menuentry: %s", args[i]);
break;
}
}
/* Capture title. */
if (! menutitle)
{
menutitle = grub_strdup (args[i]);
}
else
{
failed = 1;
grub_error (GRUB_ERR_MENU,
"too many titles for menuentry: %s", args[i]);
break;
}
}
/* Validate arguments. */
if ((! failed) && (! menutitle))
{
grub_error (GRUB_ERR_MENU, "menuentry is missing title");
failed = 1;
}
/* If argument parsing failed, free any allocated resources. */
if (failed)
{
free_menu_entry_classes (classes_head);
grub_free ((void *) menutitle);
grub_free ((void *) menusourcecode);
/* Here we assume that grub_error has been used to specify failure details. */
return grub_errno;
}
/* Add the menu entry at the end of the list. */
while (*last)
last = &(*last)->next;
*last = grub_zalloc (sizeof (**last));
if (! *last)
{
free_menu_entry_classes (classes_head);
grub_free ((void *) menutitle);
grub_free ((void *) menusourcecode);
return grub_errno;
}
(*last)->title = menutitle;
(*last)->hotkey = hotkey;
(*last)->classes = classes_head;
if (users)
(*last)->restricted = 1;
(*last)->users = users;
(*last)->sourcecode = menusourcecode;
menu->size++;
return GRUB_ERR_NONE;
}
static grub_menu_t
read_config_file (const char *config)
{
@ -492,7 +289,7 @@ grub_normal_execute (const char *config, int nested, int batch)
{
grub_show_menu (menu, nested);
if (nested)
free_menu (menu);
grub_normal_free_menu (menu);
}
}
}
@ -677,8 +474,13 @@ static void (*grub_xputs_saved) (const char *str);
GRUB_MOD_INIT(normal)
{
/* Previously many modules depended on gzio. Be nice to user and load it. */
grub_dl_load ("gzio");
grub_normal_auth_init ();
grub_context_init ();
grub_script_init ();
grub_menu_init ();
grub_xputs_saved = grub_xputs;
grub_xputs = grub_xputs_normal;
@ -718,6 +520,8 @@ GRUB_MOD_FINI(normal)
{
grub_context_fini ();
grub_script_fini ();
grub_menu_fini ();
grub_normal_auth_fini ();
grub_xputs = grub_xputs_saved;

View file

@ -153,49 +153,13 @@ get_and_remove_first_entry_number (const char *name)
return entry;
}
static void
grub_menu_execute_entry_real (grub_menu_entry_t entry)
{
const char *source;
auto grub_err_t getline (char **line, int cont);
grub_err_t getline (char **line, int cont __attribute__ ((unused)))
{
const char *p;
if (!source)
{
*line = 0;
return 0;
}
p = grub_strchr (source, '\n');
if (p)
*line = grub_strndup (source, p - source);
else
*line = grub_strdup (source);
source = p ? p + 1 : 0;
return 0;
}
source = entry->sourcecode;
while (source)
{
char *line;
getline (&line, 0);
grub_normal_parse_line (line, getline);
grub_free (line);
}
}
/* Run a menu entry. */
void
grub_menu_execute_entry(grub_menu_entry_t entry)
{
grub_err_t err = GRUB_ERR_NONE;
int errs_before;
grub_menu_t menu;
if (entry->restricted)
err = grub_auth_check_authentication (entry->users);
@ -207,13 +171,36 @@ grub_menu_execute_entry(grub_menu_entry_t entry)
return;
}
grub_env_set ("chosen", entry->title);
errs_before = grub_err_printed_errors;
grub_menu_execute_entry_real (entry);
if (entry->submenu)
{
grub_env_context_open ();
menu = grub_zalloc (sizeof (*menu));
if (! menu)
return;
grub_env_set_menu (menu);
}
grub_env_set ("chosen", entry->title);
grub_script_execute_sourcecode (entry->sourcecode, entry->argc, entry->args);
if (errs_before != grub_err_printed_errors)
grub_wait_after_message ();
if (grub_errno == GRUB_ERR_NONE && grub_loader_is_loaded ())
/* Implicit execution of boot, only if something is loaded. */
grub_command_execute ("boot", 0, 0);
if (entry->submenu)
{
if (menu && menu->size)
{
grub_show_menu (menu, 1);
grub_normal_free_menu (menu);
}
grub_env_context_close ();
}
}
/* Execute ENTRY from the menu MENU, falling back to entries specified
@ -446,7 +433,7 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot)
if (grub_checkkey () >= 0 || timeout < 0)
{
c = GRUB_TERM_ASCII_CHAR (grub_getkey ());
c = grub_getkey ();
if (timeout >= 0)
{
@ -457,31 +444,36 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot)
switch (c)
{
case GRUB_TERM_HOME:
case GRUB_TERM_KEY_HOME:
case GRUB_TERM_CTRL | 'a':
current_entry = 0;
menu_set_chosen_entry (current_entry);
break;
case GRUB_TERM_END:
case GRUB_TERM_KEY_END:
case GRUB_TERM_CTRL | 'e':
current_entry = menu->size - 1;
menu_set_chosen_entry (current_entry);
break;
case GRUB_TERM_UP:
case GRUB_TERM_KEY_UP:
case GRUB_TERM_CTRL | 'p':
case '^':
if (current_entry > 0)
current_entry--;
menu_set_chosen_entry (current_entry);
break;
case GRUB_TERM_DOWN:
case GRUB_TERM_CTRL | 'n':
case GRUB_TERM_KEY_DOWN:
case 'v':
if (current_entry < menu->size - 1)
current_entry++;
menu_set_chosen_entry (current_entry);
break;
case GRUB_TERM_PPAGE:
case GRUB_TERM_CTRL | 'g':
case GRUB_TERM_KEY_PPAGE:
if (current_entry < GRUB_MENU_PAGE_SIZE)
current_entry = 0;
else
@ -489,7 +481,8 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot)
menu_set_chosen_entry (current_entry);
break;
case GRUB_TERM_NPAGE:
case GRUB_TERM_CTRL | 'c':
case GRUB_TERM_KEY_NPAGE:
if (current_entry + GRUB_MENU_PAGE_SIZE < menu->size)
current_entry += GRUB_MENU_PAGE_SIZE;
else
@ -499,7 +492,8 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot)
case '\n':
case '\r':
case 6:
case GRUB_TERM_KEY_RIGHT:
case GRUB_TERM_CTRL | 'f':
menu_fini ();
*auto_boot = 0;
return current_entry;
@ -615,20 +609,9 @@ show_menu (grub_menu_t menu, int nested)
grub_cls ();
if (auto_boot)
{
grub_menu_execute_with_fallback (menu, e, &execution_callback, 0);
}
grub_menu_execute_with_fallback (menu, e, &execution_callback, 0);
else
{
int chars_before = grub_normal_get_char_counter ();
grub_errno = GRUB_ERR_NONE;
grub_menu_execute_entry (e);
grub_print_error ();
grub_errno = GRUB_ERR_NONE;
if (chars_before != grub_normal_get_char_counter ())
grub_wait_after_message ();
}
grub_menu_execute_entry (e);
}
return GRUB_ERR_NONE;

View file

@ -71,6 +71,8 @@ struct screen
/* The flag of a completion window. */
int completion_shown;
int submenu;
struct per_term_screen *terms;
unsigned nterms;
};
@ -170,7 +172,7 @@ static void
print_up (int flag, struct per_term_screen *term_screen)
{
grub_term_gotoxy (term_screen->term, GRUB_TERM_LEFT_BORDER_X
+ grub_term_entry_width (term_screen->term),
+ grub_term_border_width (term_screen->term),
GRUB_TERM_FIRST_ENTRY_Y);
if (flag)
@ -496,6 +498,8 @@ make_screen (grub_menu_entry_t entry)
if (! screen)
return 0;
screen->submenu = entry->submenu;
screen->num_lines = 1;
screen->lines = grub_malloc (sizeof (struct line));
if (! screen->lines)
@ -1159,54 +1163,76 @@ clear_completions_all (struct screen *screen)
static int
run (struct screen *screen)
{
int currline = 0;
char *nextline;
char *script;
int errs_before;
grub_menu_t menu;
char *dummy[1] = { NULL };
auto grub_err_t editor_getline (char **line, int cont);
grub_err_t editor_getline (char **line, int cont __attribute__ ((unused)))
{
struct line *linep = screen->lines + currline;
char *p;
auto char * editor_getsource (void);
char * editor_getsource (void)
{
int i;
int size = 0;
char *source;
if (currline > screen->num_lines)
{
*line = 0;
return 0;
}
for (i = 0; i < screen->num_lines; i++)
size += screen->lines[i].len + 1;
/* Trim down space characters. */
for (p = linep->buf + linep->len - 1;
p >= linep->buf && grub_isspace (*p);
p--)
;
*++p = '\0';
source = grub_malloc (size + 1);
if (! source)
return NULL;
linep->len = p - linep->buf;
for (p = linep->buf; grub_isspace (*p); p++)
;
*line = grub_strdup (p);
currline++;
return 0;
}
size = 0;
for (i = 0; i < screen->num_lines; i++)
{
grub_strcpy (source + size, screen->lines[i].buf);
size += screen->lines[i].len;
source[size++] = '\n';
}
source[size] = '\0';
return source;
}
grub_cls ();
grub_printf (" ");
grub_printf_ (N_("Booting a command list"));
grub_printf ("\n\n");
errs_before = grub_err_printed_errors;
if (screen->submenu)
{
grub_env_context_open ();
menu = grub_zalloc (sizeof (*menu));
if (! menu)
return 0;
grub_env_set_menu (menu);
}
/* Execute the script, line for line. */
while (currline < screen->num_lines)
{
editor_getline (&nextline, 0);
if (grub_normal_parse_line (nextline, editor_getline))
break;
}
script = editor_getsource ();
if (! script)
return 0;
grub_script_execute_sourcecode (script, 0, dummy);
grub_free (script);
if (errs_before != grub_err_printed_errors)
grub_wait_after_message ();
if (grub_errno == GRUB_ERR_NONE && grub_loader_is_loaded ())
/* Implicit execution of boot, only if something is loaded. */
grub_command_execute ("boot", 0, 0);
if (screen->submenu)
{
if (menu && menu->size)
{
grub_show_menu (menu, 1);
grub_normal_free_menu (menu);
}
grub_env_context_close ();
}
if (grub_errno != GRUB_ERR_NONE)
{
grub_print_error ();
@ -1272,7 +1298,7 @@ grub_menu_entry_run (grub_menu_entry_t entry)
while (1)
{
int c = GRUB_TERM_ASCII_CHAR (grub_getkey ());
int c = grub_getkey ();
if (screen->completion_shown)
{
@ -1288,70 +1314,79 @@ grub_menu_entry_run (grub_menu_entry_t entry)
switch (c)
{
case 16: /* C-p */
case GRUB_TERM_KEY_UP:
case GRUB_TERM_CTRL | 'p':
if (! previous_line (screen, 1))
goto fail;
break;
case 14: /* C-n */
case GRUB_TERM_CTRL | 'n':
case GRUB_TERM_KEY_DOWN:
if (! next_line (screen, 1))
goto fail;
break;
case 6: /* C-f */
case GRUB_TERM_CTRL | 'f':
case GRUB_TERM_KEY_RIGHT:
if (! forward_char (screen, 1))
goto fail;
break;
case 2: /* C-b */
case GRUB_TERM_CTRL | 'b':
case GRUB_TERM_KEY_LEFT:
if (! backward_char (screen, 1))
goto fail;
break;
case 1: /* C-a */
case GRUB_TERM_CTRL | 'a':
case GRUB_TERM_KEY_HOME:
if (! beginning_of_line (screen, 1))
goto fail;
break;
case 5: /* C-e */
case GRUB_TERM_CTRL | 'e':
case GRUB_TERM_KEY_END:
if (! end_of_line (screen, 1))
goto fail;
break;
case '\t': /* C-i */
case GRUB_TERM_CTRL | 'i':
case '\t':
if (! complete (screen, prev_c == c, 1))
goto fail;
break;
case 4: /* C-d */
case GRUB_TERM_CTRL | 'd':
case GRUB_TERM_KEY_DC:
if (! delete_char (screen, 1))
goto fail;
break;
case 8: /* C-h */
case GRUB_TERM_CTRL | 'h':
case '\b':
if (! backward_delete_char (screen, 1))
goto fail;
break;
case 11: /* C-k */
case GRUB_TERM_CTRL | 'k':
if (! kill_line (screen, prev_c == c, 1))
goto fail;
break;
case 21: /* C-u */
case GRUB_TERM_CTRL | 'u':
/* FIXME: What behavior is good for this key? */
break;
case 25: /* C-y */
case GRUB_TERM_CTRL | 'y':
if (! yank (screen, 1))
goto fail;
break;
case 12: /* C-l */
case GRUB_TERM_CTRL | 'l':
/* FIXME: centering. */
goto refresh;
case 15: /* C-o */
case GRUB_TERM_CTRL | 'o':
if (! open_line (screen, 1))
goto fail;
break;
@ -1366,23 +1401,19 @@ grub_menu_entry_run (grub_menu_entry_t entry)
destroy_screen (screen);
return;
case 3: /* C-c */
case GRUB_TERM_CTRL | 'c':
case GRUB_TERM_KEY_F2:
grub_cmdline_run (1);
goto refresh;
case 24: /* C-x */
{
int chars_before = grub_normal_get_char_counter ();
run (screen);
if (chars_before != grub_normal_get_char_counter ())
grub_wait_after_message ();
}
case GRUB_TERM_CTRL | 'x':
case GRUB_TERM_KEY_F10:
run (screen);
goto refresh;
case 18: /* C-r */
case 19: /* C-s */
case 20: /* C-t */
case GRUB_TERM_CTRL | 'r':
case GRUB_TERM_CTRL | 's':
case GRUB_TERM_CTRL | 't':
/* FIXME */
break;

View file

@ -120,17 +120,10 @@ print_message (int nested, int edit, struct grub_term_output *term)
if (edit)
{
grub_putcode ('\n', term);
#ifdef GRUB_MACHINE_EFI
grub_print_message_indented (_("Minimum Emacs-like screen editing is \
supported. TAB lists completions. Press F1 to boot, F2=Ctrl-a, F3=Ctrl-e, \
F4 for a command-line or ESC to discard edits and return to the GRUB menu."),
STANDARD_MARGIN, STANDARD_MARGIN, term);
#else
grub_print_message_indented (_("Minimum Emacs-like screen editing is \
supported. TAB lists completions. Press Ctrl-x to boot, Ctrl-c for a \
supported. TAB lists completions. Press Ctrl-x or F10 to boot, Ctrl-c or F2 for a \
command-line or ESC to discard edits and return to the GRUB menu."),
STANDARD_MARGIN, STANDARD_MARGIN, term);
#endif
}
else
{

View file

@ -26,6 +26,7 @@
#include <grub/datetime.h>
#include <grub/term.h>
#include <grub/i18n.h>
#include <grub/partition.h>
/* Print the information on the device NAME. */
grub_err_t
@ -107,10 +108,18 @@ grub_normal_print_device_info (const char *name)
grub_errno = GRUB_ERR_NONE;
}
}
else if (! dev->disk->has_partitions || dev->disk->partition)
grub_printf ("%s", _("Unknown filesystem"));
else
grub_printf ("%s", _("Partition table"));
grub_printf ("%s", _("Not a known filesystem"));
if (dev->disk->partition)
grub_printf (_(" - Partition start at %u"),
grub_partition_get_start (dev->disk->partition));
if (grub_disk_get_size (dev->disk) == GRUB_DISK_SIZE_UNKNOWN)
grub_printf (_(" - Total size unknown"),
grub_disk_get_size (dev->disk));
else
grub_printf (_(" - Total size %u sectors"),
grub_disk_get_size (dev->disk));
grub_device_close (dev);
}

View file

@ -42,17 +42,9 @@ static struct term_state *term_states = NULL;
/* If the more pager is active. */
static int grub_more;
static int grub_normal_char_counter = 0;
static void
putcode_real (grub_uint32_t code, struct grub_term_output *term);
int
grub_normal_get_char_counter (void)
{
return grub_normal_char_counter;
}
void
grub_normal_reset_more (void)
{
@ -99,16 +91,16 @@ print_more (void)
grub_term_restore_pos (pos);
grub_free (pos);
/* Scroll one lines or an entire page, depending on the key. */
/* Scroll one line or an entire page, depending on the key. */
if (key == '\r' || key =='\n')
grub_normal_reset_more ();
else
{
static struct term_state *state;
for (state = term_states; state; state = state->next)
state->num_lines -= 2;
state->num_lines--;
}
else
grub_normal_reset_more ();
}
void
@ -384,8 +376,8 @@ read_terminal_list (const char *prefix)
if (! cur->modname)
{
grub_errno = GRUB_ERR_NONE;
grub_free (cur);
grub_free (cur->name);
grub_free (cur);
continue;
}
cur->next = *target;
@ -409,8 +401,6 @@ putglyph (const struct grub_unicode_glyph *c, struct grub_term_output *term)
.estimated_width = 1
};
grub_normal_char_counter++;
if (c->base == '\t' && term->getxy)
{
int n;
@ -657,7 +647,7 @@ put_glyphs_terminal (const struct grub_unicode_glyph *visual,
>= (grub_ssize_t) grub_term_height (term) - 2)
{
state->backlog_glyphs = visual_ptr + 1;
state->backlog_len = visual_len - (visual - visual_ptr) - 1;
state->backlog_len = visual_len - (visual_ptr - visual) - 1;
return 1;
}
@ -688,6 +678,7 @@ print_backlog (struct grub_term_output *term,
grub_free (state->free);
state->free = NULL;
state->backlog_len = 0;
state->backlog_ucs4 = 0;
}
return ret;
}
@ -703,6 +694,7 @@ print_backlog (struct grub_term_output *term,
grub_free (state->free);
state->free = NULL;
state->backlog_len = 0;
state->backlog_glyphs = 0;
}
return ret;
}