#include <shared.h>
#include <term.h>
extern struct term_entry *current_term;
#ifdef SUPPORT_DISKLESS
# include <grub.h>
#endif
grub_jmp_buf restart_cmdline_env;
char *
skip_to (int after_equal, char *cmdline)
{
while (*cmdline && *cmdline != ' ' && *cmdline != '\t' &&
! (after_equal && *cmdline == '='))
cmdline ++;
while (*cmdline == ' ' || *cmdline == '\t' ||
(after_equal && *cmdline == '='))
cmdline ++;
return cmdline;
}
void
print_cmdline_message (int forever)
{
printf (" [ Minimal BASH-like line editing is supported. For the first word, TAB\n"
" lists possible command completions. Anywhere else TAB lists the possible\n"
" completions of a device/filename.%s ]\n",
(forever ? "" : " ESC at any time exits."));
}
struct builtin *
find_command (char *command)
{
char *ptr;
char c;
struct builtin **builtin;
ptr = command;
while (*ptr && *ptr != ' ' && *ptr != '\t' && *ptr != '=')
ptr ++;
c = *ptr;
*ptr = 0;
for (builtin = builtin_table; *builtin != 0; builtin++)
{
int ret = grub_strcmp (command, (*builtin)->name);
if (ret == 0)
{
*ptr = c;
return *builtin;
}
else if (ret < 0)
break;
}
errnum = ERR_UNRECOGNIZED;
*ptr = c;
return 0;
}
static void
init_cmdline (void)
{
saved_drive = boot_drive;
saved_partition = install_partition;
current_drive = GRUB_INVALID_DRIVE;
errnum = 0;
count_lines = -1;
mbi.mem_upper = saved_mem_upper;
if (mbi.mmap_length)
mbi.flags |= MB_INFO_MEM_MAP;
init_builtins ();
}
void
enter_cmdline (char *heap, int forever)
{
init_cmdline ();
grub_setjmp (restart_cmdline_env);
init_page ();
#ifdef SUPPORT_DISKLESS
print_network_configuration ();
grub_putchar ('\n');
#endif
print_cmdline_message (forever);
while (1)
{
struct builtin *builtin;
char *arg;
*heap = 0;
print_error ();
errnum = ERR_NONE;
if (get_cmdline (PACKAGE "> ", heap, 2048, 0, 1))
return;
if (! heap[0])
continue;
builtin = find_command (heap);
if (! builtin)
continue;
if (! (builtin->flags & BUILTIN_CMDLINE))
{
errnum = ERR_UNRECOGNIZED;
continue;
}
buf_drive = -1;
if (use_pager)
count_lines = 0;
arg = skip_to (1, heap);
(builtin->func) (arg, BUILTIN_CMDLINE);
count_lines = -1;
}
}
int
run_script (char *script, char *heap)
{
char *old_entry;
char *cur_entry = script;
init_cmdline ();
while (1)
{
struct builtin *builtin;
char *arg;
print_error ();
if (errnum)
{
errnum = ERR_NONE;
builtin = find_command("verbose");
(builtin->func) ("on", BUILTIN_SCRIPT);
if (fallback_entryno < 0)
{
grub_printf ("\nPress any key to continue...");
(void) getkey ();
}
return 1;
}
old_entry = cur_entry;
while (*cur_entry++)
;
grub_memmove (heap, old_entry, (int) cur_entry - (int) old_entry);
if (! *heap)
{
if (kernel_type == KERNEL_TYPE_NONE)
return 0;
if (reset_term)
if (current_term->shutdown) {
(*current_term->shutdown)();
current_term = term_table;
}
grub_memmove (heap, "boot", 5);
}
builtin = find_command (heap);
if (! builtin)
{
grub_printf ("%s\n", old_entry);
continue;
}
if (! (builtin->flags & BUILTIN_NO_ECHO))
grub_printf ("%s\n", old_entry);
if (! (builtin->flags & BUILTIN_CMDLINE))
{
errnum = ERR_UNRECOGNIZED;
continue;
}
buf_drive = -1;
arg = skip_to (1, heap);
(builtin->func) (arg, BUILTIN_SCRIPT);
}
}