	Gilbert Ashley <amigo@ibiblio.org>
	This patch was written by Chris Semler <csemler@mail.com>
	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 <csemler@mail.com>).
+ */
 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,
