Gilbert Ashley This patch was written by Chris Semler It adds a set-root feature to the find builtin. --- ./stage2/cmdline.c.01 2007-10-04 16:33:45.000000000 +0200 +++ ./stage2/cmdline.c 2007-10-04 16:34:48.000000000 +0200 @@ -115,6 +115,8 @@ init_builtins (); } +extern int commandline_func (char *arg, int flags); + /* Enter the command-line interface. HEAP is used for the command-line buffer. Return only if FOREVER is nonzero and get_cmdline returns nonzero (ESC is pushed). */ @@ -169,7 +171,7 @@ count_lines = 0; /* Run BUILTIN->FUNC. */ - arg = skip_to (1, heap); + arg = (builtin->func) == commandline_func ? heap : skip_to (1, heap); (builtin->func) (arg, BUILTIN_CMDLINE); /* Finish the line count. */ @@ -252,7 +254,7 @@ buf_drive = -1; /* Run BUILTIN->FUNC. */ - arg = skip_to (1, heap); + arg = (builtin->func) == commandline_func ? heap : skip_to (1, heap); (builtin->func) (arg, BUILTIN_SCRIPT); } } --- ./stage2/stage2.c.01 2007-10-04 16:33:45.000000000 +0200 +++ ./stage2/stage2.c 2007-10-04 16:34:48.000000000 +0200 @@ -1016,7 +1016,8 @@ /* Run a command found is possible. */ if (builtin->flags & BUILTIN_MENU) { - char *arg = skip_to (1, cmdline); + extern int commandline_func (char *arg, int flags); + char *arg = (builtin->func) == commandline_func ? cmdline : skip_to (1, cmdline); (builtin->func) (arg, BUILTIN_MENU); errnum = 0; } --- ./stage2/builtins.c.01 2007-10-04 16:33:45.000000000 +0200 +++ ./stage2/builtins.c 2007-10-04 16:34:48.000000000 +0200 @@ -85,6 +85,7 @@ /* Prototypes for allowing straightfoward calling of builtins functions inside other functions. */ static int configfile_func (char *arg, int flags); +int commandline_func (char *arg, int flags); /* Initialize the data for builtins. */ void @@ -1451,8 +1452,8 @@ { "fallback", fallback_func, - BUILTIN_MENU, -#if 0 + BUILTIN_MENU | BUILTIN_CMDLINE | BUILTIN_HELP_LIST, +#if 1 "fallback NUM...", "Go into unattended boot mode: if the default boot entry has any" " errors, instead of waiting for the user to do anything, it" @@ -1463,8 +1464,38 @@ }; +/* commandline */ +int +commandline_func (char *arg, int flags) +{ + int forever = 0; + char *config_entries = arg; + + //config_entries = (char *) mbi.drives_addr + mbi.drives_length; + + //if (! safe_parse_maxint (&arg, &forever)) + // return 1; + enter_cmdline(config_entries, forever); + + return 0; +} + +static struct builtin builtin_commandline = +{ + "commandline", + commandline_func, + BUILTIN_MENU | BUILTIN_CMDLINE | BUILTIN_HELP_LIST, +#if 1 + "commandline", + "Enter command-line prompt mode." +#endif +}; + + /* find */ -/* Search for the filename ARG in all of partitions. */ +/* Search for the filename ARG in all of partitions and optionally make that + * partition root("--set-root", Thanks to Chris Semler ). + */ static int find_func (char *arg, int flags) { @@ -1473,30 +1504,24 @@ unsigned long tmp_drive = saved_drive; unsigned long tmp_partition = saved_partition; int got_file = 0; + int set_root = 0; + //char *in_drives = NULL; /* search in drive list */ + char root_found[16]; - /* Floppies. */ - for (drive = 0; drive < 8; drive++) + if (grub_memcmp (arg, "--set-root", 10) == 0) { - current_drive = drive; - current_partition = 0xFFFFFF; - - if (open_device ()) - { - saved_drive = current_drive; - saved_partition = current_partition; - if (grub_open (filename)) - { - grub_close (); - grub_printf (" (fd%d)\n", drive); - got_file = 1; - } - } - - errnum = ERR_NONE; + set_root = 1; + filename = skip_to (0, arg); } - /* Hard disks. */ - for (drive = 0x80; drive < 0x88; drive++) + /* Hard disks. Search in hard disks first, since floppies are slow */ +#ifdef GRUB_UTIL +#define FIND_DRIVES 8 +#else +#define FIND_DRIVES (*((char *)0x475)) +#endif + for (drive = 0x80; drive < 0x80 + FIND_DRIVES; drive++) +#undef FIND_DRIVES { unsigned long part = 0xFFFFFF; unsigned long start, len, offset, ext_offset; @@ -1525,13 +1550,16 @@ grub_close (); if (bsd_part == 0xFF) - grub_printf (" (hd%d,%d)\n", + grub_sprintf (root_found, "(hd%d,%d)", drive - 0x80, pc_slice); else - grub_printf (" (hd%d,%d,%c)\n", + grub_sprintf (root_found, "(hd%d,%d,%c)", drive - 0x80, pc_slice, bsd_part + 'a'); + grub_printf (" %s\n", root_found); got_file = 1; + if (set_root) + goto found; } } } @@ -1545,12 +1573,78 @@ errnum = ERR_NONE; } + /* CD-ROM. */ + if (cdrom_drive != GRUB_INVALID_DRIVE) + { + current_drive = cdrom_drive; + current_partition = 0xFFFFFF; + + if (open_device ()) + { + saved_drive = current_drive; + saved_partition = current_partition; + if (grub_open (filename)) + { + grub_close (); + grub_sprintf (root_found, "(cd)"); + grub_printf (" %s\n", root_found); + got_file = 1; + if (set_root) + goto found; + } + } + + errnum = ERR_NONE; + } + + /* Floppies. */ +#ifdef GRUB_UTIL +#define FIND_DRIVES 8 +#else +#define FIND_DRIVES ((*(char*)0x410 & 1)?(*(char*)0x410 >> 6) + 1 : 0) +#endif + for (drive = 0; drive < 0 + FIND_DRIVES; drive++) +#undef FIND_DRIVES + { + extern int biosdisk_standard (int ah, int drv, int coff, int hoff, int soff, int nsec, int segment); + +#ifndef GRUB_UTIL + /* Check if the media is present using int13/ah=04h (verify sectors) */ + if (biosdisk_standard (0x04, drive, 0, 0, 1, 1, SCRATCHSEG)) + continue; +#endif + + current_drive = drive; + current_partition = 0xFFFFFF; + + if (open_device ()) + { + saved_drive = current_drive; + saved_partition = current_partition; + if (grub_open (filename)) + { + grub_close (); + grub_sprintf (root_found, "(fd%d)", drive); + grub_printf (" %s\n", root_found); + got_file = 1; + if (set_root) + goto found; + } + } + + errnum = ERR_NONE; + } + +found: saved_drive = tmp_drive; saved_partition = tmp_partition; if (got_file) { + static int real_root_func (char *arg1, int attempt_mount); errnum = ERR_NONE; + if (set_root) + return real_root_func (root_found, 1); return 0; } @@ -1563,9 +1657,11 @@ "find", find_func, BUILTIN_CMDLINE | BUILTIN_HELP_LIST, - "find FILENAME", + "find [--set-root] FILENAME", "Search for the filename FILENAME in all of partitions and print the list of" - " the devices which contain the file." + " the devices which contain the file. If the option --set-root is used and " + "FILENAME is found on a device, then stop the find immediately and set the " + "device as new root." }; @@ -5095,6 +5191,7 @@ &builtin_clear, &builtin_cmp, &builtin_color, + &builtin_commandline, &builtin_configfile, &builtin_debug, &builtin_default,