[PATCH] savedefault --once
Leandro Dorileo
ldorileo at gmail.com
Tue Mar 7 11:01:05 UTC 2006
Hi Otavio
I've reimplemented the whole savedefault --once functionality. Grub is
not writting the saved default entry to second sector of stage 2 but,
now it uses the file /boot/grub/default. This patch closes the bug
254475 but I remember to have seen other related bugs, I'll find them
and report here.
--- stage2/builtins.c-orig 2006-03-04 01:52:35.000000000 +0000
+++ stage2/builtins.c 2006-03-07 06:27:16.000000000 +0000
@@ -86,6 +86,10 @@
inside other functions. */
static int configfile_func (char *arg, int flags);
+static int savedefault_helper(char *arg, int flags);
+
+static int savedefault_shell(char *arg, int flags);
+
/* Initialize the data for builtins. */
void
init_builtins (void)
@@ -787,7 +791,7 @@
default_func (char *arg, int flags)
{
#ifndef SUPPORT_DISKLESS
- if (grub_strcmp (arg, "saved") == 0)
+ if (grub_strcmp (arg, "saved") == 0)
{
default_entry = saved_entryno;
return 0;
@@ -3510,9 +3514,92 @@
/* savedefault */
static int
-savedefault_func (char *arg, int flags)
+savedefault_func(char *arg, int flags)
+{
+#if !defined(SUPPORT_DISKLESS)
+ #if !defined(GRUB_UTIL)
+ savedefault_helper(arg, flags);
+ #else
+ savedefault_shell(arg, flags);
+ #endif
+#else /* !SUPPORT_DISKLESS */
+ errnum = ERR_UNRECOGNIZED;
+ return 1;
+#endif /* !SUPPORT_DISKLESS */
+}
+
+#if !defined(SUPPORT_DISKLESS) && defined(GRUB_UTIL)
+/* savedefault_shell */
+static int
+savedefault_shell(char *arg, int flags)
{
-#if !defined(SUPPORT_DISKLESS) && !defined(GRUB_UTIL)
+ int once_only = 0;
+ int new_default;
+ int curr_default = -1;
+ int curr_prev_default = -1;
+ int new_prev_default = -1;
+ FILE *fp;
+ size_t bytes = 10;
+ char line[bytes];
+ char *default_file = (char *) DEFAULT_FILE_BUF;
+ char buf[bytes];
+
+ while (1)
+ {
+ 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)
+ {
+ once_only = 1;
+ arg = skip_to (0, arg);
+ }
+ else
+ break;
+ }
+
+ if(!(fp = fopen(default_file,"w")))
+ {
+ errnum = ERR_READ;
+ goto fail;
+ }
+
+ read(&line, -1);
+
+ sscanf(line, "%d:%d", &curr_prev_default, &curr_default);
+
+ if(curr_default != -1)
+ new_prev_default = curr_default;
+ else
+ {
+ if(curr_prev_default != -1)
+ new_prev_default = curr_prev_default;
+ else
+ new_prev_default = 0;
+ }
+
+ if(once_only)
+ sprintf(buf, "%d:%d\n", new_prev_default, new_default);
+ else
+ sprintf(buf, "%d\n", new_default);
+
+ fprintf(fp, buf);
+
+fail:
+ fclose(fp);
+ return errnum;
+}
+#endif
+
+/* savedefault_helper */
+static int
+savedefault_helper (char *arg, int flags)
+{
+#if !defined(SUPPORT_DISKLESS)
unsigned long tmp_drive = saved_drive;
unsigned long tmp_partition = saved_partition;
char *default_file = (char *) DEFAULT_FILE_BUF;
@@ -3524,6 +3611,7 @@
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)
@@ -3536,9 +3624,9 @@
}
sector_count++;
}
-
+
/* This command is only useful when you boot an entry from the menu
- interface. */
+ interface. */
if (! (flags & BUILTIN_SCRIPT))
{
errnum = ERR_UNRECOGNIZED;
@@ -3585,33 +3673,36 @@
if (grub_open (default_file))
{
int len;
-
disk_read_hook = disk_read_savesect_func;
len = grub_read (buf, sizeof (buf));
disk_read_hook = 0;
grub_close ();
- if (len != sizeof (buf))
- {
- /* This is too small. Do not modify the file manually, please! */
- errnum = ERR_READ;
- goto fail;
- }
-
if (sector_count > 2)
{
/* Is this possible?! Too fragmented! */
errnum = ERR_FSYS_CORRUPT;
goto fail;
}
+
+ char *tmp;
+ if((tmp = grub_strstr(buf, ":")) != NULL)
+ {
+ int f_len = grub_strlen(buf) - grub_strlen(tmp);
+ char *def;
+ int a;
+ for(a = 0; a < f_len; a++)
+ grub_memcpy(&def[a], &buf[a], sizeof(char));
+ safe_parse_maxint (&def, &entryno);
+ }
- /* Set up a string to be written. */
+ /* 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
+ /* 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))
--- stage2/stage2.c-orig 2006-03-07 06:33:40.000000000 +0000
+++ stage2/stage2.c 2006-03-07 06:35:08.000000000 +0000
@@ -901,7 +901,6 @@
reset ();
/* Here load the configuration file. */
-
#ifdef GRUB_UTIL
if (use_config_file)
#endif /* GRUB_UTIL */
@@ -930,8 +929,19 @@
len = grub_read (buf, sizeof (buf));
if (len > 0)
{
+ char *tmp;
+ char *def;
+
buf[sizeof (buf) - 1] = 0;
- safe_parse_maxint (&p, &saved_entryno);
+
+ if((tmp = grub_strstr(p, ":")) != NULL)
+ {
+ *tmp++;
+ grub_memcpy(&def, &tmp, sizeof(p));
+ }else
+ grub_memcpy(&def, &p, sizeof(p));
+
+ safe_parse_maxint (&def, &saved_entryno);
}
grub_close ();
--
Dorileo
More information about the Pkg-grub-devel
mailing list