1 --- grub-0.97/stage2/builtins.c.bootonce 2005-12-12 18:23:12.000000000 -0500
2 +++ grub-0.97/stage2/builtins.c 2005-12-12 18:29:20.000000000 -0500
3 @@ -3217,146 +3217,175 @@
9 +#if !defined(SUPPORT_DISKLESS) && !defined(GRUB_UTIL)
10 +/* Write specified default entry number into stage2 file. */
12 -savedefault_func (char *arg, int flags)
13 +savedefault_helper(int new_default)
15 -#if !defined(SUPPORT_DISKLESS) && !defined(GRUB_UTIL)
16 - unsigned long tmp_drive = saved_drive;
17 - unsigned long tmp_partition = saved_partition;
18 - char *default_file = (char *) DEFAULT_FILE_BUF;
20 - char sect[SECTOR_SIZE];
22 - int sector_count = 0;
23 - int saved_sectors[2];
24 - int saved_offsets[2];
25 - int saved_lengths[2];
27 - /* Save sector information about at most two sectors. */
28 - auto void disk_read_savesect_func (int sector, int offset, int length);
29 - void disk_read_savesect_func (int sector, int offset, int length)
31 - if (sector_count < 2)
33 - saved_sectors[sector_count] = sector;
34 - saved_offsets[sector_count] = offset;
35 - saved_lengths[sector_count] = length;
40 - /* This command is only useful when you boot an entry from the menu
42 - if (! (flags & BUILTIN_SCRIPT))
46 + /* Get the geometry of the boot drive (i.e. the disk which contains
48 + if (get_diskinfo (boot_drive, &buf_geom))
50 - errnum = ERR_UNRECOGNIZED;
51 + errnum = ERR_NO_DISK;
55 - /* Determine a saved entry number. */
57 + /* Load the second sector of this stage2. */
58 + if (! rawread (boot_drive, install_second_sector, 0, SECTOR_SIZE, buffer))
60 - if (grub_memcmp (arg, "fallback", sizeof ("fallback") - 1) == 0)
65 - for (i = 0; i < MAX_FALLBACK_ENTRIES; i++)
67 - if (fallback_entries[i] < 0)
69 - if (fallback_entries[i] == current_entryno)
76 - if (index >= MAX_FALLBACK_ENTRIES || fallback_entries[index] < 0)
78 - /* This is the last. */
79 - errnum = ERR_BAD_ARGUMENT;
85 - entryno = fallback_entries[index];
87 - else if (! safe_parse_maxint (&arg, &entryno))
90 + if (buffer[STAGE2_STAGE2_ID] != STAGE2_ID_STAGE2
91 + || *((short *) (buffer + STAGE2_VER_MAJ_OFFS)) != COMPAT_VERSION)
93 + errnum = ERR_BAD_VERSION;
97 - entryno = current_entryno;
99 + entryno_ptr = (int *) (buffer + STAGE2_SAVED_ENTRYNO);
101 - /* Open the default file. */
102 - saved_drive = boot_drive;
103 - saved_partition = install_partition;
104 - if (grub_open (default_file))
105 + /* Check if the saved entry number differs from current entry number. */
106 + if (*entryno_ptr != new_default)
109 + /* Overwrite the saved entry number. */
110 + *entryno_ptr = new_default;
112 - disk_read_hook = disk_read_savesect_func;
113 - len = grub_read (buf, sizeof (buf));
114 - disk_read_hook = 0;
116 + /* Save the image in the disk. */
117 + if (! rawwrite (boot_drive, install_second_sector, buffer))
120 - if (len != sizeof (buf))
122 - /* This is too small. Do not modify the file manually, please! */
126 + /* Clear the cache. */
130 - if (sector_count > 2)
132 - /* Is this possible?! Too fragmented! */
133 - errnum = ERR_FSYS_CORRUPT;
137 - /* Set up a string to be written. */
138 - grub_memset (buf, '\n', sizeof (buf));
139 - grub_sprintf (buf, "%d", entryno);
141 - if (saved_lengths[0] < sizeof (buf))
143 - /* The file is anchored to another file and the first few bytes
144 - are spanned in two sectors. Uggh... */
145 - if (! rawread (current_drive, saved_sectors[0], 0, SECTOR_SIZE,
148 - grub_memmove (sect + saved_offsets[0], buf, saved_lengths[0]);
149 - if (! rawwrite (current_drive, saved_sectors[0], sect))
155 - if (! rawread (current_drive, saved_sectors[1], 0, SECTOR_SIZE,
158 - grub_memmove (sect + saved_offsets[1],
159 - buf + saved_lengths[0],
160 - sizeof (buf) - saved_lengths[0]);
161 - if (! rawwrite (current_drive, saved_sectors[1], sect))
164 +#if !defined(SUPPORT_DISKLESS) && defined(GRUB_UTIL)
166 + * Full implementation of new `savedefault' for GRUB shell.
167 + * XXX This needs fixing for stage2 files which aren't accessible
168 + * through a mounted filesystem.
171 +savedefault_shell(char *arg, int flags)
173 + char *stage2_os_file = "/boot/grub/stage2"; /* Default filename */
177 + int new_default = 0;
178 + int old_default = 0;
182 + if (grub_memcmp ("--stage2=", arg, sizeof ("--stage2=") - 1) == 0)
184 + stage2_os_file = arg + sizeof ("--stage2=") - 1;
185 + arg = skip_to (0, arg);
186 + nul_terminate (stage2_os_file);
188 + else if (grub_memcmp ("--default=", arg, sizeof ("--default=") - 1) == 0)
190 + char *p = arg + sizeof ("--default=") - 1;
191 + if (! safe_parse_maxint (&p, &new_default))
193 + arg = skip_to (0, arg);
195 + else if (grub_memcmp ("--once", arg, sizeof ("--once") - 1) == 0)
198 + new_default |= STAGE2_ONCEONLY_ENTRY;
199 + arg = skip_to (0, arg);
203 - /* This is a simple case. It fits into a single sector. */
204 - if (! rawread (current_drive, saved_sectors[0], 0, SECTOR_SIZE,
207 - grub_memmove (sect + saved_offsets[0], buf, sizeof (buf));
208 - if (! rawwrite (current_drive, saved_sectors[0], sect))
214 - /* Clear the cache. */
216 + if (! (fp = fopen(stage2_os_file, "r+")))
218 + errnum = ERR_FILE_NOT_FOUND;
222 + if (fseek (fp, SECTOR_SIZE, SEEK_SET) != 0)
225 + errnum = ERR_BAD_VERSION;
229 + if (fread (buffer, 1, SECTOR_SIZE, fp) != SECTOR_SIZE)
237 - saved_drive = tmp_drive;
238 - saved_partition = tmp_partition;
240 + /* Sanity check. */
241 + if (buffer[STAGE2_STAGE2_ID] != STAGE2_ID_STAGE2
242 + || *((short *) (buffer + STAGE2_VER_MAJ_OFFS)) != COMPAT_VERSION)
244 + errnum = ERR_BAD_VERSION;
248 + entryno_ptr = (int *) (buffer + STAGE2_SAVED_ENTRYNO);
249 + if (new_default & STAGE2_ONCEONLY_ENTRY)
251 + old_default=*entryno_ptr;
252 + *entryno_ptr = new_default + (old_default & 0xFF);
256 + *entryno_ptr = new_default;
259 + if (fseek (fp, SECTOR_SIZE, SEEK_SET) != 0)
262 + errnum = ERR_BAD_VERSION;
266 + if (fwrite (buffer, 1, SECTOR_SIZE, fp) != SECTOR_SIZE)
269 + errnum = ERR_WRITE;
281 +savedefault_func (char *arg, int flags)
283 +#if !defined(SUPPORT_DISKLESS)
284 +#if !defined(GRUB_UTIL)
285 + /* This command is only useful when you boot an entry from the menu
287 + if (! (flags & BUILTIN_SCRIPT))
289 + errnum = ERR_UNRECOGNIZED;
293 + return savedefault_helper(current_entryno);
294 +#else /* defined(GRUB_UTIL) */
295 + return savedefault_shell(arg, flags);
297 #else /* ! SUPPORT_DISKLESS && ! GRUB_UTIL */
298 errnum = ERR_UNRECOGNIZED;
300 @@ -3368,10 +3397,14 @@
304 - "savedefault [NUM | `fallback']",
305 - "Save the current entry as the default boot entry if no argument is"
306 - " specified. If a number is specified, this number is saved. If"
307 - " `fallback' is used, next fallback entry is saved."
309 + "savedefault [--stage2=STAGE2_FILE] [--default=DEFAULT] [--once]",
310 + "Save DEFAULT as the default boot entry in STAGE2_FILE. If '--once'"
311 + " is specified, the default is reset after the next reboot."
314 + "Save the current entry as the default boot entry."
319 @@ -4598,6 +4631,15 @@
321 timeout_func (char *arg, int flags)
323 + /* One-shot default shenanigans -- don't piss around with the menu! */
324 + if (grub_timeout != -1)
326 + if ((saved_entryno & STAGE2_ONCEONLY_ENTRY) != 0)
332 if (! safe_parse_maxint (&arg, &grub_timeout))
335 --- grub-0.97/stage2/shared.h.bootonce 2005-12-12 18:23:13.000000000 -0500
336 +++ grub-0.97/stage2/shared.h 2005-12-12 18:23:13.000000000 -0500
338 #define STAGE2_FORCE_LBA 0x11
339 #define STAGE2_VER_STR_OFFS 0x12
341 +#define STAGE2_ONCEONLY_ENTRY 0x10000
343 /* Stage 2 identifiers */
344 #define STAGE2_ID_STAGE2 0
345 #define STAGE2_ID_FFS_STAGE1_5 1
346 --- grub-0.97/stage2/builtins.c.bootonce 2006-03-13 16:55:11.000000000 -0500
347 +++ grub-0.97/stage2/builtins.c 2006-03-13 16:56:01.000000000 -0500
348 @@ -761,11 +761,25 @@
352 +#if !defined(SUPPORT_DISKLESS) && !defined(GRUB_UTIL)
353 +static int savedefault_helper(int);
357 default_func (char *arg, int flags)
359 #ifndef SUPPORT_DISKLESS
361 + /* Has a forced once-only default been specified? */
362 + if ((saved_entryno & STAGE2_ONCEONLY_ENTRY) != 0)
364 + int old_defaults=saved_entryno & ~STAGE2_ONCEONLY_ENTRY;
366 + default_entry = old_defaults >> 8;
367 + savedefault_helper(old_defaults & 0xff);
371 if (grub_strcmp (arg, "saved") == 0)
373 default_entry = saved_entryno;
374 --- grub-0.97/stage2/stage2.c.bootonce 2006-03-13 17:27:40.000000000 -0500
375 +++ grub-0.97/stage2/stage2.c 2006-03-13 17:29:11.000000000 -0500
378 #endif /* GRUB_UTIL */
380 - char *default_file = (char *) DEFAULT_FILE_BUF;
383 - /* Get a saved default entry if possible. */
386 - grub_strncat (default_file, config_file, DEFAULT_FILE_BUFLEN);
387 - for (i = grub_strlen(default_file); i >= 0; i--)
388 - if (default_file[i] == '/')
393 - default_file[i] = 0;
394 - grub_strncat (default_file + i, "default", DEFAULT_FILE_BUFLEN - i);
395 - if (grub_open (default_file))
397 - char buf[10]; /* This is good enough. */
401 - len = grub_read (buf, sizeof (buf));
404 - buf[sizeof (buf) - 1] = 0;
405 - safe_parse_maxint (&p, &saved_entryno);
414 /* STATE 0: Before any title command.
415 --- grub-0.97/util/grub-install.in.bootonce 2006-03-13 17:39:35.000000000 -0500
416 +++ grub-0.97/util/grub-install.in 2006-03-13 17:39:50.000000000 -0500
418 pkglibdir=${libdir}/${PACKAGE}/${host_cpu}-${host_vendor}
420 grub_shell=${sbindir}/grub
421 -grub_set_default=${sbindir}/grub-set-default
422 log_file=/tmp/grub-install.log.$$
423 img_file=/tmp/grub-install.img.$$
429 -# Make a default file.
430 -${grub_set_default} --root-directory=${rootdir} default
432 # Make sure that GRUB reads the same images as the host OS.
433 test -n "$mkimg" && img_file=`$mkimg`
434 test -n "$mklog" && log_file=`$mklog`
435 --- grub-0.97/configure.bootonce 2006-03-13 17:49:05.000000000 -0500
436 +++ grub-0.97/configure 2006-03-13 17:49:16.000000000 -0500
437 @@ -6135,7 +6135,7 @@
441 - 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"
442 + 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"
444 cat >confcache <<\_ACEOF
445 # This file is a shell script that caches the results of configure
446 @@ -6754,7 +6754,6 @@
447 "util/grub-install" ) CONFIG_FILES="$CONFIG_FILES util/grub-install" ;;
448 "util/grub-md5-crypt" ) CONFIG_FILES="$CONFIG_FILES util/grub-md5-crypt" ;;
449 "util/grub-terminfo" ) CONFIG_FILES="$CONFIG_FILES util/grub-terminfo" ;;
450 - "util/grub-set-default" ) CONFIG_FILES="$CONFIG_FILES util/grub-set-default" ;;
451 "depfiles" ) CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;;
452 "config.h" ) CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;;
453 *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
454 --- grub-0.97/configure.ac.bootonce 2006-03-13 17:47:24.000000000 -0500
455 +++ grub-0.97/configure.ac 2006-03-13 17:47:37.000000000 -0500
457 docs/Makefile lib/Makefile util/Makefile \
458 grub/Makefile netboot/Makefile util/grub-image \
459 util/grub-install util/grub-md5-crypt \
460 - util/grub-terminfo util/grub-set-default])
461 + util/grub-terminfo])
463 --- grub-0.97/util/Makefile.am.bootonce 2006-03-13 17:48:39.000000000 -0500
464 +++ grub-0.97/util/Makefile.am 2006-03-13 17:48:45.000000000 -0500
467 -sbin_SCRIPTS = grub-install grub-md5-crypt grub-terminfo \
469 +sbin_SCRIPTS = grub-install grub-md5-crypt grub-terminfo
470 noinst_SCRIPTS = grub-image mkbimage
472 EXTRA_DIST = mkbimage
473 --- grub-0.97/util/Makefile.in.bootonce 2006-03-13 17:47:56.000000000 -0500
474 +++ grub-0.97/util/Makefile.in 2006-03-13 17:48:34.000000000 -0500
477 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
478 $(srcdir)/grub-image.in $(srcdir)/grub-install.in \
479 - $(srcdir)/grub-md5-crypt.in $(srcdir)/grub-set-default.in \
480 - $(srcdir)/grub-terminfo.in
481 + $(srcdir)/grub-md5-crypt.in $(srcdir)/grub-terminfo.in
482 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
483 am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
484 $(top_srcdir)/configure.ac
487 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
488 CONFIG_HEADER = $(top_builddir)/config.h
489 -CONFIG_CLEAN_FILES = grub-image grub-install grub-md5-crypt \
490 - grub-terminfo grub-set-default
491 +CONFIG_CLEAN_FILES = grub-image grub-install grub-md5-crypt grub-terminfo
492 am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(sbindir)"
493 binPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
494 PROGRAMS = $(bin_PROGRAMS)
496 sharedstatedir = @sharedstatedir@
497 sysconfdir = @sysconfdir@
498 target_alias = @target_alias@
499 -sbin_SCRIPTS = grub-install grub-md5-crypt grub-terminfo \
501 +sbin_SCRIPTS = grub-install grub-md5-crypt grub-terminfo
503 noinst_SCRIPTS = grub-image mkbimage
504 EXTRA_DIST = mkbimage
506 cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
507 grub-terminfo: $(top_builddir)/config.status $(srcdir)/grub-terminfo.in
508 cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
509 -grub-set-default: $(top_builddir)/config.status $(srcdir)/grub-set-default.in
510 - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
511 install-binPROGRAMS: $(bin_PROGRAMS)
513 test -z "$(bindir)" || $(mkdir_p) "$(DESTDIR)$(bindir)"