diff -Nru grub-20051128/ChangeLog grub-findconfig/ChangeLog --- grub-20051128/ChangeLog 2005-09-29 00:00:54.000000000 +0100 +++ grub-findconfig/ChangeLog 2005-11-28 11:01:30.533408000 +0000 @@ -1,3 +1,8 @@ +2005-11-28 Tim Deegan + + * stage2/builtins.c: Added findconfig command. + * docs/grub.texi: Likewise. + 2005-09-29 Yoshinori K. Okuji * docs/multiboot.texi: Fix a bug in the byte order of diff -Nru grub-20051128/docs/grub.texi grub-findconfig/docs/grub.texi --- grub-20051128/docs/grub.texi 2004-09-20 22:55:00.000000000 +0100 +++ grub-findconfig/docs/grub.texi 2005-11-28 11:25:55.832033000 +0000 @@ -2669,6 +2669,7 @@ * displaymem:: Display memory configuration * embed:: Embed Stage 1.5 * find:: Find a file +* findconfig:: Find and load a configuration file * fstest:: Test a filesystem * geometry:: Manipulate the geometry of a drive * halt:: Shut down your computer @@ -2832,6 +2833,17 @@ @end deffn +@node findconfig +@subsection findconfig + +@deffn Command findconfig filename +Search for the file name @var{filename} in all mountable partitions +and load the first matching file (if any) as a configuration file. The +file name @var{filename} should be an absolute file name like +@code{/boot/grub/storedconfig}. +@end deffn + + @node fstest @subsection fstest diff -Nru grub-20051128/stage2/builtins.c grub-findconfig/stage2/builtins.c --- grub-20051128/stage2/builtins.c 2005-02-15 22:05:07.000000000 +0000 +++ grub-findconfig/stage2/builtins.c 2005-11-28 13:15:45.002273000 +0000 @@ -81,6 +81,7 @@ /* Prototypes for allowing straightfoward calling of builtins functions inside other functions. */ static int configfile_func (char *arg, int flags); +static int real_root_func (char *arg, int flags); /* Initialize the data for builtins. */ void @@ -1303,6 +1304,133 @@ }; +/* findconfig */ +/* Search for the filename ARG in all of partitions; then use it as our + * config file. */ + + +static int +findconfig_func (char *arg, int flags) +{ + char *filename = arg; + char oldroot[32]; + char *p; + unsigned long drive; + unsigned long tmp_drive = saved_drive; + unsigned long tmp_partition = saved_partition; + unsigned long tmp_cur_drive = current_drive; + unsigned long tmp_cur_partition = current_partition; + unsigned long part, start, len, offset, ext_offset; + int type, entry; + char buf[SECTOR_SIZE]; + + /* Print the *current* device name, so we can get back to it. */ + p = &oldroot[0]; + if (saved_drive == cdrom_drive) + grub_sprintf (p, "(cd)"); + else + { + grub_sprintf (p, "(%cd%d", + (saved_drive & 0x80) ? 'h' : 'f', + saved_drive & ~0x80); + + p += strlen (p); + if ((saved_partition & 0xFF0000) != 0xFF0000) + { + grub_sprintf (p, ",%d", (saved_partition >> 16) & 0xFF); + p += strlen (p); + } + if ((saved_partition & 0x00FF00) != 0x00FF00) + { + grub_sprintf (p, ",%c", 'a' + ((saved_partition >> 8) & 0xFF)); + p += strlen (p); + } + grub_sprintf (p, ")"); + } + + /* Floppies. */ + for (drive = 0; drive < 8; drive++) + { + current_drive = drive; + current_partition = 0xFFFFFF; + + if (open_device ()) + { + saved_drive = current_drive; + saved_partition = current_partition; + if (grub_open (filename)) + { + grub_close (); + boot_drive = saved_drive; + install_partition = saved_partition; + configfile_func (filename, flags); + } + } + + errnum = ERR_NONE; + } + + /* Hard disks. */ + for (drive = 0x80; drive < 0x88; drive++) + { + part = 0xFFFFFF; + current_drive = drive; + while (next_partition (drive, 0xFFFFFF, &part, &type, + &start, &len, &offset, &entry, + &ext_offset, buf)) + { + if (type != PC_SLICE_TYPE_NONE + && ! IS_PC_SLICE_TYPE_BSD (type) + && ! IS_PC_SLICE_TYPE_EXTENDED (type)) + { + current_partition = part; + if (open_device ()) + { + saved_drive = current_drive; + saved_partition = current_partition; + if (grub_open (filename)) + { + grub_close (); + boot_drive = saved_drive; + install_partition = saved_partition; + configfile_func (filename, flags); + } + } + } + + /* We want to ignore any error here. */ + errnum = ERR_NONE; + } + + /* next_partition always sets ERRNUM in the last call, so clear + it. */ + errnum = ERR_NONE; + } + + saved_drive = tmp_drive; + saved_partition = tmp_partition; + current_drive = tmp_cur_drive; + current_partition = tmp_cur_partition; + buf_drive = -1; + open_partition (); + + /* Although we failed here, we don't want the boot sequence to halt */ + grub_printf ("File %s not found.\nReopening %s\n", filename, &oldroot[0]); + errnum = ERR_NONE; + return real_root_func (&oldroot[0], 1); +} + +static struct builtin builtin_findconfig = +{ + "findconfig", + findconfig_func, + BUILTIN_CMDLINE | BUILTIN_HELP_LIST, + "findconfig FILENAME", + "Search for the filename FILENAME in all of partitions and load it as a" + " config file if it exists." +}; + + /* fstest */ static int fstest_func (char *arg, int flags) @@ -4821,6 +4949,7 @@ &builtin_embed, &builtin_fallback, &builtin_find, + &builtin_findconfig, &builtin_fstest, &builtin_geometry, &builtin_halt,