/* rescue.c - rescue mode */ /* * GRUB -- GRand Unified Bootloader * Copyright (C) 2002,2003,2005,2007 Free Software Foundation, Inc. * * GRUB is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GRUB is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GRUB. If not, see . */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define GRUB_RESCUE_BUF_SIZE 256 #define GRUB_RESCUE_MAX_ARGS 20 static char linebuf[GRUB_RESCUE_BUF_SIZE]; /* Prompt to input a command and read the line. */ static void grub_rescue_get_command_line (const char *prompt) { int c; int pos = 0; grub_printf (prompt); grub_memset (linebuf, 0, GRUB_RESCUE_BUF_SIZE); while ((c = GRUB_TERM_ASCII_CHAR (grub_getkey ())) != '\n' && c != '\r') { if (grub_isprint (c)) { if (pos < GRUB_RESCUE_BUF_SIZE - 1) { linebuf[pos++] = c; grub_putchar (c); } } else if (c == '\b') { if (pos > 0) { linebuf[--pos] = 0; grub_putchar (c); grub_putchar (' '); grub_putchar (c); } } grub_refresh (); } grub_putchar ('\n'); grub_refresh (); } static void attempt_normal_mode (void) { grub_command_t cmd; cmd = grub_command_find ("normal"); if (cmd) (cmd->func) (cmd, 0, 0); } /* Enter the rescue mode. */ void grub_enter_rescue_mode (void) { auto grub_err_t getline (char **line); grub_err_t getline (char **line) { grub_rescue_get_command_line ("> "); *line = linebuf; return 0; } grub_register_core_commands (); /* First of all, attempt to execute the normal mode. */ attempt_normal_mode (); grub_printf ("Entering rescue mode...\n"); while (1) { char *line = linebuf; char *name; int n; grub_command_t cmd; char **args; /* Print an error, if any. */ grub_print_error (); grub_errno = GRUB_ERR_NONE; /* Get a command line. */ grub_rescue_get_command_line ("grub rescue> "); if (line[0] == 0) continue; if (grub_parser_split_cmdline (line, getline, &n, &args) || n < 0) continue; /* In case of an assignment set the environment accordingly instead of calling a function. */ if (n == 0 && grub_strchr (line, '=')) { char *val = grub_strchr (args[0], '='); val[0] = 0; grub_env_set (args[0], val + 1); val[0] = '='; grub_free (args[0]); continue; } /* Get the command name. */ name = args[0]; /* If nothing is specified, restart. */ if (*name == '\0') { grub_free (args[0]); continue; } cmd = grub_command_find (name); if (cmd) { (cmd->func) (cmd, n, &args[1]); } else { grub_printf ("Unknown command `%s'\n", name); grub_printf ("Try `help' for usage\n"); } grub_free (args[0]); } }