mirror of
https://github.com/vincentmli/bpfire.git
synced 2026-05-11 09:48:24 +02:00
514 lines
16 KiB
Diff
514 lines
16 KiB
Diff
--- grub-0.97/stage2/builtins.c.bootonce 2005-12-12 18:23:12.000000000 -0500
|
||
+++ grub-0.97/stage2/builtins.c 2005-12-12 18:29:20.000000000 -0500
|
||
@@ -3217,146 +3217,175 @@
|
||
};
|
||
|
||
|
||
-/* savedefault */
|
||
+
|
||
+#if !defined(SUPPORT_DISKLESS) && !defined(GRUB_UTIL)
|
||
+/* Write specified default entry number into stage2 file. */
|
||
static int
|
||
-savedefault_func (char *arg, int flags)
|
||
+savedefault_helper(int new_default)
|
||
{
|
||
-#if !defined(SUPPORT_DISKLESS) && !defined(GRUB_UTIL)
|
||
- unsigned long tmp_drive = saved_drive;
|
||
- unsigned long tmp_partition = saved_partition;
|
||
- char *default_file = (char *) DEFAULT_FILE_BUF;
|
||
- char buf[10];
|
||
- char sect[SECTOR_SIZE];
|
||
- int entryno;
|
||
- int sector_count = 0;
|
||
- int saved_sectors[2];
|
||
- int saved_offsets[2];
|
||
- int saved_lengths[2];
|
||
-
|
||
- /* Save sector information about at most two sectors. */
|
||
- auto void disk_read_savesect_func (int sector, int offset, int length);
|
||
- void disk_read_savesect_func (int sector, int offset, int length)
|
||
- {
|
||
- if (sector_count < 2)
|
||
- {
|
||
- saved_sectors[sector_count] = sector;
|
||
- saved_offsets[sector_count] = offset;
|
||
- saved_lengths[sector_count] = length;
|
||
- }
|
||
- sector_count++;
|
||
- }
|
||
-
|
||
- /* This command is only useful when you boot an entry from the menu
|
||
- interface. */
|
||
- if (! (flags & BUILTIN_SCRIPT))
|
||
+ char buffer[512];
|
||
+ int *entryno_ptr;
|
||
+
|
||
+ /* Get the geometry of the boot drive (i.e. the disk which contains
|
||
+ this stage2). */
|
||
+ if (get_diskinfo (boot_drive, &buf_geom))
|
||
{
|
||
- errnum = ERR_UNRECOGNIZED;
|
||
+ errnum = ERR_NO_DISK;
|
||
return 1;
|
||
}
|
||
|
||
- /* Determine a saved entry number. */
|
||
- if (*arg)
|
||
+ /* Load the second sector of this stage2. */
|
||
+ if (! rawread (boot_drive, install_second_sector, 0, SECTOR_SIZE, buffer))
|
||
{
|
||
- if (grub_memcmp (arg, "fallback", sizeof ("fallback") - 1) == 0)
|
||
- {
|
||
- int i;
|
||
- int index = 0;
|
||
-
|
||
- for (i = 0; i < MAX_FALLBACK_ENTRIES; i++)
|
||
- {
|
||
- if (fallback_entries[i] < 0)
|
||
- break;
|
||
- if (fallback_entries[i] == current_entryno)
|
||
- {
|
||
- index = i + 1;
|
||
- break;
|
||
- }
|
||
- }
|
||
-
|
||
- if (index >= MAX_FALLBACK_ENTRIES || fallback_entries[index] < 0)
|
||
- {
|
||
- /* This is the last. */
|
||
- errnum = ERR_BAD_ARGUMENT;
|
||
- return 1;
|
||
- }
|
||
+ return 1;
|
||
+ }
|
||
|
||
- entryno = fallback_entries[index];
|
||
- }
|
||
- else if (! safe_parse_maxint (&arg, &entryno))
|
||
- return 1;
|
||
+ /* Sanity check. */
|
||
+ if (buffer[STAGE2_STAGE2_ID] != STAGE2_ID_STAGE2
|
||
+ || *((short *) (buffer + STAGE2_VER_MAJ_OFFS)) != COMPAT_VERSION)
|
||
+ {
|
||
+ errnum = ERR_BAD_VERSION;
|
||
+ return 1;
|
||
}
|
||
- else
|
||
- entryno = current_entryno;
|
||
+
|
||
+ entryno_ptr = (int *) (buffer + STAGE2_SAVED_ENTRYNO);
|
||
|
||
- /* Open the default file. */
|
||
- saved_drive = boot_drive;
|
||
- saved_partition = install_partition;
|
||
- if (grub_open (default_file))
|
||
+ /* Check if the saved entry number differs from current entry number. */
|
||
+ if (*entryno_ptr != new_default)
|
||
{
|
||
- int len;
|
||
+ /* Overwrite the saved entry number. */
|
||
+ *entryno_ptr = new_default;
|
||
|
||
- disk_read_hook = disk_read_savesect_func;
|
||
- len = grub_read (buf, sizeof (buf));
|
||
- disk_read_hook = 0;
|
||
- grub_close ();
|
||
+ /* Save the image in the disk. */
|
||
+ if (! rawwrite (boot_drive, install_second_sector, buffer))
|
||
+ return 1;
|
||
|
||
- if (len != sizeof (buf))
|
||
- {
|
||
- /* This is too small. Do not modify the file manually, please! */
|
||
- errnum = ERR_READ;
|
||
- goto fail;
|
||
- }
|
||
+ /* Clear the cache. */
|
||
+ buf_track = -1;
|
||
+ }
|
||
|
||
- if (sector_count > 2)
|
||
- {
|
||
- /* Is this possible?! Too fragmented! */
|
||
- errnum = ERR_FSYS_CORRUPT;
|
||
- goto fail;
|
||
- }
|
||
-
|
||
- /* Set up a string to be written. */
|
||
- grub_memset (buf, '\n', sizeof (buf));
|
||
- grub_sprintf (buf, "%d", entryno);
|
||
-
|
||
- if (saved_lengths[0] < sizeof (buf))
|
||
- {
|
||
- /* The file is anchored to another file and the first few bytes
|
||
- are spanned in two sectors. Uggh... */
|
||
- if (! rawread (current_drive, saved_sectors[0], 0, SECTOR_SIZE,
|
||
- sect))
|
||
- goto fail;
|
||
- grub_memmove (sect + saved_offsets[0], buf, saved_lengths[0]);
|
||
- if (! rawwrite (current_drive, saved_sectors[0], sect))
|
||
- goto fail;
|
||
+ return 0;
|
||
+}
|
||
+#endif
|
||
|
||
- if (! rawread (current_drive, saved_sectors[1], 0, SECTOR_SIZE,
|
||
- sect))
|
||
- goto fail;
|
||
- grub_memmove (sect + saved_offsets[1],
|
||
- buf + saved_lengths[0],
|
||
- sizeof (buf) - saved_lengths[0]);
|
||
- if (! rawwrite (current_drive, saved_sectors[1], sect))
|
||
- goto fail;
|
||
- }
|
||
+#if !defined(SUPPORT_DISKLESS) && defined(GRUB_UTIL)
|
||
+/*
|
||
+ * Full implementation of new `savedefault' for GRUB shell.
|
||
+ * XXX This needs fixing for stage2 files which aren't accessible
|
||
+ * through a mounted filesystem.
|
||
+ */
|
||
+static int
|
||
+savedefault_shell(char *arg, int flags)
|
||
+{
|
||
+ char *stage2_os_file = "/boot/grub/stage2"; /* Default filename */
|
||
+ FILE *fp;
|
||
+ char buffer[512];
|
||
+ int *entryno_ptr;
|
||
+ int new_default = 0;
|
||
+ int old_default = 0;
|
||
+
|
||
+ while (1)
|
||
+ {
|
||
+ if (grub_memcmp ("--stage2=", arg, sizeof ("--stage2=") - 1) == 0)
|
||
+ {
|
||
+ stage2_os_file = arg + sizeof ("--stage2=") - 1;
|
||
+ arg = skip_to (0, arg);
|
||
+ nul_terminate (stage2_os_file);
|
||
+ }
|
||
+ else if (grub_memcmp ("--default=", arg, sizeof ("--default=") - 1) == 0)
|
||
+ {
|
||
+ char *p = arg + sizeof ("--default=") - 1;
|
||
+ if (! safe_parse_maxint (&p, &new_default))
|
||
+ return 1;
|
||
+ arg = skip_to (0, arg);
|
||
+ }
|
||
+ else if (grub_memcmp ("--once", arg, sizeof ("--once") - 1) == 0)
|
||
+ {
|
||
+ new_default <<= 8;
|
||
+ new_default |= STAGE2_ONCEONLY_ENTRY;
|
||
+ arg = skip_to (0, arg);
|
||
+ }
|
||
else
|
||
- {
|
||
- /* This is a simple case. It fits into a single sector. */
|
||
- if (! rawread (current_drive, saved_sectors[0], 0, SECTOR_SIZE,
|
||
- sect))
|
||
- goto fail;
|
||
- grub_memmove (sect + saved_offsets[0], buf, sizeof (buf));
|
||
- if (! rawwrite (current_drive, saved_sectors[0], sect))
|
||
- goto fail;
|
||
- }
|
||
+ break;
|
||
+ }
|
||
|
||
- /* Clear the cache. */
|
||
- buf_track = -1;
|
||
+ if (! (fp = fopen(stage2_os_file, "r+")))
|
||
+ {
|
||
+ errnum = ERR_FILE_NOT_FOUND;
|
||
+ return 1;
|
||
+ }
|
||
+
|
||
+ if (fseek (fp, SECTOR_SIZE, SEEK_SET) != 0)
|
||
+ {
|
||
+ fclose (fp);
|
||
+ errnum = ERR_BAD_VERSION;
|
||
+ return 1;
|
||
+ }
|
||
+
|
||
+ if (fread (buffer, 1, SECTOR_SIZE, fp) != SECTOR_SIZE)
|
||
+ {
|
||
+ fclose (fp);
|
||
+ errnum = ERR_READ;
|
||
+ return 1;
|
||
}
|
||
|
||
- fail:
|
||
- saved_drive = tmp_drive;
|
||
- saved_partition = tmp_partition;
|
||
- return errnum;
|
||
+ /* Sanity check. */
|
||
+ if (buffer[STAGE2_STAGE2_ID] != STAGE2_ID_STAGE2
|
||
+ || *((short *) (buffer + STAGE2_VER_MAJ_OFFS)) != COMPAT_VERSION)
|
||
+ {
|
||
+ errnum = ERR_BAD_VERSION;
|
||
+ return 1;
|
||
+ }
|
||
+
|
||
+ entryno_ptr = (int *) (buffer + STAGE2_SAVED_ENTRYNO);
|
||
+ if (new_default & STAGE2_ONCEONLY_ENTRY)
|
||
+ {
|
||
+ old_default=*entryno_ptr;
|
||
+ *entryno_ptr = new_default + (old_default & 0xFF);
|
||
+ }
|
||
+ else
|
||
+ {
|
||
+ *entryno_ptr = new_default;
|
||
+ }
|
||
+
|
||
+ if (fseek (fp, SECTOR_SIZE, SEEK_SET) != 0)
|
||
+ {
|
||
+ fclose (fp);
|
||
+ errnum = ERR_BAD_VERSION;
|
||
+ return 1;
|
||
+ }
|
||
+
|
||
+ if (fwrite (buffer, 1, SECTOR_SIZE, fp) != SECTOR_SIZE)
|
||
+ {
|
||
+ fclose (fp);
|
||
+ errnum = ERR_WRITE;
|
||
+ return 1;
|
||
+ }
|
||
+
|
||
+ (void)fflush (fp);
|
||
+ fclose (fp);
|
||
+ return 0;
|
||
+}
|
||
+#endif
|
||
+
|
||
+/* savedefault */
|
||
+static int
|
||
+savedefault_func (char *arg, int flags)
|
||
+{
|
||
+#if !defined(SUPPORT_DISKLESS)
|
||
+#if !defined(GRUB_UTIL)
|
||
+ /* This command is only useful when you boot an entry from the menu
|
||
+ interface. */
|
||
+ if (! (flags & BUILTIN_SCRIPT))
|
||
+ {
|
||
+ errnum = ERR_UNRECOGNIZED;
|
||
+ return 1;
|
||
+ }
|
||
+
|
||
+ return savedefault_helper(current_entryno);
|
||
+#else /* defined(GRUB_UTIL) */
|
||
+ return savedefault_shell(arg, flags);
|
||
+#endif
|
||
#else /* ! SUPPORT_DISKLESS && ! GRUB_UTIL */
|
||
errnum = ERR_UNRECOGNIZED;
|
||
return 1;
|
||
@@ -3368,10 +3397,14 @@
|
||
"savedefault",
|
||
savedefault_func,
|
||
BUILTIN_CMDLINE,
|
||
- "savedefault [NUM | `fallback']",
|
||
- "Save the current entry as the default boot entry if no argument is"
|
||
- " specified. If a number is specified, this number is saved. If"
|
||
- " `fallback' is used, next fallback entry is saved."
|
||
+#ifdef GRUB_UTIL
|
||
+ "savedefault [--stage2=STAGE2_FILE] [--default=DEFAULT] [--once]",
|
||
+ "Save DEFAULT as the default boot entry in STAGE2_FILE. If '--once'"
|
||
+ " is specified, the default is reset after the next reboot."
|
||
+#else
|
||
+ "savedefault",
|
||
+ "Save the current entry as the default boot entry."
|
||
+#endif
|
||
};
|
||
|
||
|
||
@@ -4598,6 +4631,15 @@
|
||
static int
|
||
timeout_func (char *arg, int flags)
|
||
{
|
||
+ /* One-shot default shenanigans -- don't piss around with the menu! */
|
||
+ if (grub_timeout != -1)
|
||
+ return 0;
|
||
+ if ((saved_entryno & STAGE2_ONCEONLY_ENTRY) != 0)
|
||
+ {
|
||
+ grub_timeout = 0;
|
||
+ return 0;
|
||
+ }
|
||
+
|
||
if (! safe_parse_maxint (&arg, &grub_timeout))
|
||
return 1;
|
||
|
||
--- grub-0.97/stage2/shared.h.bootonce 2005-12-12 18:23:13.000000000 -0500
|
||
+++ grub-0.97/stage2/shared.h 2005-12-12 18:23:13.000000000 -0500
|
||
@@ -200,6 +200,8 @@
|
||
#define STAGE2_FORCE_LBA 0x11
|
||
#define STAGE2_VER_STR_OFFS 0x12
|
||
|
||
+#define STAGE2_ONCEONLY_ENTRY 0x10000
|
||
+
|
||
/* Stage 2 identifiers */
|
||
#define STAGE2_ID_STAGE2 0
|
||
#define STAGE2_ID_FFS_STAGE1_5 1
|
||
--- grub-0.97/stage2/builtins.c.bootonce 2006-03-13 16:55:11.000000000 -0500
|
||
+++ grub-0.97/stage2/builtins.c 2006-03-13 16:56:01.000000000 -0500
|
||
@@ -761,11 +761,25 @@
|
||
};
|
||
|
||
|
||
+#if !defined(SUPPORT_DISKLESS) && !defined(GRUB_UTIL)
|
||
+static int savedefault_helper(int);
|
||
+#endif
|
||
/* default */
|
||
static int
|
||
default_func (char *arg, int flags)
|
||
{
|
||
#ifndef SUPPORT_DISKLESS
|
||
+#ifndef GRUB_UTIL
|
||
+ /* Has a forced once-only default been specified? */
|
||
+ if ((saved_entryno & STAGE2_ONCEONLY_ENTRY) != 0)
|
||
+ {
|
||
+ int old_defaults=saved_entryno & ~STAGE2_ONCEONLY_ENTRY;
|
||
+ grub_timeout = 0;
|
||
+ default_entry = old_defaults >> 8;
|
||
+ savedefault_helper(old_defaults & 0xff);
|
||
+ return 0;
|
||
+ }
|
||
+#endif
|
||
if (grub_strcmp (arg, "saved") == 0)
|
||
{
|
||
default_entry = saved_entryno;
|
||
--- grub-0.97/stage2/stage2.c.bootonce 2006-03-13 17:27:40.000000000 -0500
|
||
+++ grub-0.97/stage2/stage2.c 2006-03-13 17:29:11.000000000 -0500
|
||
@@ -960,38 +960,8 @@
|
||
if (use_config_file)
|
||
#endif /* GRUB_UTIL */
|
||
{
|
||
- char *default_file = (char *) DEFAULT_FILE_BUF;
|
||
int i;
|
||
-
|
||
- /* Get a saved default entry if possible. */
|
||
- saved_entryno = 0;
|
||
- *default_file = 0;
|
||
- grub_strncat (default_file, config_file, DEFAULT_FILE_BUFLEN);
|
||
- for (i = grub_strlen(default_file); i >= 0; i--)
|
||
- if (default_file[i] == '/')
|
||
- {
|
||
- i++;
|
||
- break;
|
||
- }
|
||
- default_file[i] = 0;
|
||
- grub_strncat (default_file + i, "default", DEFAULT_FILE_BUFLEN - i);
|
||
- if (grub_open (default_file))
|
||
- {
|
||
- char buf[10]; /* This is good enough. */
|
||
- char *p = buf;
|
||
- int len;
|
||
-
|
||
- len = grub_read (buf, sizeof (buf));
|
||
- if (len > 0)
|
||
- {
|
||
- buf[sizeof (buf) - 1] = 0;
|
||
- safe_parse_maxint (&p, &saved_entryno);
|
||
- }
|
||
|
||
- grub_close ();
|
||
- }
|
||
- errnum = ERR_NONE;
|
||
-
|
||
do
|
||
{
|
||
/* STATE 0: Before any title command.
|
||
--- grub-0.97/util/grub-install.in.bootonce 2006-03-13 17:39:35.000000000 -0500
|
||
+++ grub-0.97/util/grub-install.in 2006-03-13 17:39:50.000000000 -0500
|
||
@@ -30,7 +30,6 @@
|
||
pkglibdir=${libdir}/${PACKAGE}/${host_cpu}-${host_vendor}
|
||
|
||
grub_shell=${sbindir}/grub
|
||
-grub_set_default=${sbindir}/grub-set-default
|
||
log_file=/tmp/grub-install.log.$$
|
||
img_file=/tmp/grub-install.img.$$
|
||
rootdir=
|
||
@@ -432,9 +431,6 @@
|
||
exit 1
|
||
fi
|
||
|
||
-# Make a default file.
|
||
-${grub_set_default} --root-directory=${rootdir} default
|
||
-
|
||
# Make sure that GRUB reads the same images as the host OS.
|
||
test -n "$mkimg" && img_file=`$mkimg`
|
||
test -n "$mklog" && log_file=`$mklog`
|
||
--- grub-0.97/configure.bootonce 2006-03-13 17:49:05.000000000 -0500
|
||
+++ grub-0.97/configure 2006-03-13 17:49:16.000000000 -0500
|
||
@@ -6135,7 +6135,7 @@
|
||
|
||
|
||
|
||
- ac_config_files="$ac_config_files Makefile stage1/Makefile stage2/Makefile docs/Makefile lib/Makefile util/Makefile grub/Makefile netboot/Makefile util/grub-image util/grub-install util/grub-md5-crypt util/grub-terminfo util/grub-set-default"
|
||
+ ac_config_files="$ac_config_files Makefile stage1/Makefile stage2/Makefile docs/Makefile lib/Makefile util/Makefile grub/Makefile netboot/Makefile util/grub-image util/grub-install util/grub-md5-crypt util/grub-terminfo"
|
||
|
||
cat >confcache <<\_ACEOF
|
||
# This file is a shell script that caches the results of configure
|
||
@@ -6754,7 +6754,6 @@
|
||
"util/grub-install" ) CONFIG_FILES="$CONFIG_FILES util/grub-install" ;;
|
||
"util/grub-md5-crypt" ) CONFIG_FILES="$CONFIG_FILES util/grub-md5-crypt" ;;
|
||
"util/grub-terminfo" ) CONFIG_FILES="$CONFIG_FILES util/grub-terminfo" ;;
|
||
- "util/grub-set-default" ) CONFIG_FILES="$CONFIG_FILES util/grub-set-default" ;;
|
||
"depfiles" ) CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;;
|
||
"config.h" ) CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;;
|
||
*) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
|
||
--- grub-0.97/configure.ac.bootonce 2006-03-13 17:47:24.000000000 -0500
|
||
+++ grub-0.97/configure.ac 2006-03-13 17:47:37.000000000 -0500
|
||
@@ -666,5 +666,5 @@
|
||
docs/Makefile lib/Makefile util/Makefile \
|
||
grub/Makefile netboot/Makefile util/grub-image \
|
||
util/grub-install util/grub-md5-crypt \
|
||
- util/grub-terminfo util/grub-set-default])
|
||
+ util/grub-terminfo])
|
||
AC_OUTPUT
|
||
--- grub-0.97/util/Makefile.am.bootonce 2006-03-13 17:48:39.000000000 -0500
|
||
+++ grub-0.97/util/Makefile.am 2006-03-13 17:48:45.000000000 -0500
|
||
@@ -1,6 +1,5 @@
|
||
bin_PROGRAMS = mbchk
|
||
-sbin_SCRIPTS = grub-install grub-md5-crypt grub-terminfo \
|
||
- grub-set-default
|
||
+sbin_SCRIPTS = grub-install grub-md5-crypt grub-terminfo
|
||
noinst_SCRIPTS = grub-image mkbimage
|
||
|
||
EXTRA_DIST = mkbimage
|
||
--- grub-0.97/util/Makefile.in.bootonce 2006-03-13 17:47:56.000000000 -0500
|
||
+++ grub-0.97/util/Makefile.in 2006-03-13 17:48:34.000000000 -0500
|
||
@@ -43,8 +43,7 @@
|
||
subdir = util
|
||
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
|
||
$(srcdir)/grub-image.in $(srcdir)/grub-install.in \
|
||
- $(srcdir)/grub-md5-crypt.in $(srcdir)/grub-set-default.in \
|
||
- $(srcdir)/grub-terminfo.in
|
||
+ $(srcdir)/grub-md5-crypt.in $(srcdir)/grub-terminfo.in
|
||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||
am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
|
||
$(top_srcdir)/configure.ac
|
||
@@ -52,8 +51,7 @@
|
||
$(ACLOCAL_M4)
|
||
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
|
||
CONFIG_HEADER = $(top_builddir)/config.h
|
||
-CONFIG_CLEAN_FILES = grub-image grub-install grub-md5-crypt \
|
||
- grub-terminfo grub-set-default
|
||
+CONFIG_CLEAN_FILES = grub-image grub-install grub-md5-crypt grub-terminfo
|
||
am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(sbindir)"
|
||
binPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
|
||
PROGRAMS = $(bin_PROGRAMS)
|
||
@@ -183,8 +181,7 @@
|
||
sharedstatedir = @sharedstatedir@
|
||
sysconfdir = @sysconfdir@
|
||
target_alias = @target_alias@
|
||
-sbin_SCRIPTS = grub-install grub-md5-crypt grub-terminfo \
|
||
- grub-set-default
|
||
+sbin_SCRIPTS = grub-install grub-md5-crypt grub-terminfo
|
||
|
||
noinst_SCRIPTS = grub-image mkbimage
|
||
EXTRA_DIST = mkbimage
|
||
@@ -234,8 +231,6 @@
|
||
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
|
||
grub-terminfo: $(top_builddir)/config.status $(srcdir)/grub-terminfo.in
|
||
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
|
||
-grub-set-default: $(top_builddir)/config.status $(srcdir)/grub-set-default.in
|
||
- cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
|
||
install-binPROGRAMS: $(bin_PROGRAMS)
|
||
@$(NORMAL_INSTALL)
|
||
test -z "$(bindir)" || $(mkdir_p) "$(DESTDIR)$(bindir)"
|