1Index: grub/stage2/builtins.c
2===================================================================
3--- grub.orig/stage2/builtins.c	2008-06-02 18:06:08.942580000 +0100
4+++ grub/stage2/builtins.c	2008-06-06 18:35:07.548390000 +0100
5@@ -86,6 +86,10 @@
6    inside other functions.  */
7 static int configfile_func (char *arg, int flags);
8
9+static int savedefault_helper (char *arg, int flags);
10+
11+static int savedefault_shell (char *arg, int flags);
12+
13 /* Initialize the data for builtins.  */
14 void
15 init_builtins (void)
16@@ -3512,7 +3516,109 @@
17 static int
18 savedefault_func (char *arg, int flags)
19 {
20-#if !defined(SUPPORT_DISKLESS) && !defined(GRUB_UTIL)
21+#if !defined(SUPPORT_DISKLESS)
22+  #if !defined(GRUB_UTIL)
23+	return savedefault_helper(arg, flags);
24+  #else
25+	return savedefault_shell(arg, flags);
26+  #endif
27+#else /* !SUPPORT_DISKLESS */
28+  errnum = ERR_UNRECOGNIZED;
29+  return 1;
30+#endif /* !SUPPORT_DISKLESS */
31+}
32+
33+#if !defined(SUPPORT_DISKLESS) && defined(GRUB_UTIL)
34+/* savedefault_shell */
35+static int
36+savedefault_shell(char *arg, int flags)
37+ {
38+  int once_only = 0;
39+  int new_default;
40+  int curr_default = -1;
41+  int curr_prev_default = -1;
42+  int new_prev_default = -1;
43+  FILE *fp;
44+  size_t bytes = 10;
45+  char line[bytes];
46+  char *default_file = (char *) DEFAULT_FILE_BUF;
47+  char buf[bytes];
48+  int i;
49+
50+  while (1)
51+    {
52+      if (grub_memcmp ("--default=", arg, sizeof ("--default=") - 1) == 0)
53+        {
54+          char *p = arg + sizeof ("--default=") - 1;
55+          if (! safe_parse_maxint (&p, &new_default))
56+            return 1;
57+          arg = skip_to (0, arg);
58+        }
59+      else if (grub_memcmp ("--once", arg, sizeof ("--once") - 1) == 0)
60+        {
61+         once_only = 1;
62+         arg = skip_to (0, arg);
63+	}
64+      else
65+        break;
66+    }
67+
68+  *default_file = 0;
69+  grub_strncat (default_file, config_file, DEFAULT_FILE_BUFLEN);
70+  for (i = grub_strlen(default_file); i >= 0; i--)
71+    if (default_file[i] == '/')
72+    {
73+      i++;
74+      break;
75+    }
76+  default_file[i] = 0;
77+  grub_strncat (default_file + i, "default", DEFAULT_FILE_BUFLEN - i);
78+
79+  if(!(fp = fopen(default_file,"r")))
80+    {
81+      errnum = ERR_READ;
82+      goto fail;
83+    }
84+
85+  fgets(line, bytes, fp);
86+  fclose(fp);
87+
88+  sscanf(line, "%d:%d", &curr_prev_default, &curr_default);
89+
90+  if(curr_default != -1)
91+    new_prev_default = curr_default;
92+  else
93+    {
94+      if(curr_prev_default != -1)
95+        new_prev_default = curr_prev_default;
96+      else
97+        new_prev_default = 0;
98+    }
99+
100+  if(once_only)
101+    sprintf(buf, "%d:%d", new_prev_default, new_default);
102+  else
103+    sprintf(buf, "%d", new_default);
104+
105+  if(!(fp = fopen(default_file,"w")))
106+    {
107+      errnum = ERR_READ;
108+      goto fail;
109+    }
110+
111+  fprintf(fp, buf);
112+
113+fail:
114+  fclose(fp);
115+  return errnum;
116+}
117+#endif
118+
119+/* savedefault_helper */
120+static int
121+savedefault_helper (char *arg, int flags)
122+{
123+#if !defined(SUPPORT_DISKLESS)
124   unsigned long tmp_drive = saved_drive;
125   unsigned long tmp_partition = saved_partition;
126   char *default_file = (char *) DEFAULT_FILE_BUF;
127@@ -3588,22 +3694,26 @@
128
129       disk_read_hook = disk_read_savesect_func;
130       len = grub_read (buf, sizeof (buf));
131+      buf[9]='\0';/* Make sure grub_strstr() below terminates */
132       disk_read_hook = 0;
133       grub_close ();
134
135-      if (len != sizeof (buf))
136-	{
137-	  /* This is too small. Do not modify the file manually, please!  */
138-	  errnum = ERR_READ;
139-	  goto fail;
140-	}
141-
142       if (sector_count > 2)
143 	{
144 	  /* Is this possible?! Too fragmented!  */
145 	  errnum = ERR_FSYS_CORRUPT;
146 	  goto fail;
147 	}
148+
149+      char *tmp;
150+      if((tmp = grub_strstr(buf, ":")) != NULL)
151+      {
152+       int f_len = grub_strlen(buf) - grub_strlen(tmp);
153+       char *def;
154+       buf[f_len] = '\0';
155+       def = buf;
156+       safe_parse_maxint (&def, &entryno);
157+      }
158
159       /* Set up a string to be written.  */
160       grub_memset (buf, '\n', sizeof (buf));
161Index: grub/stage2/stage2.c
162===================================================================
163--- grub.orig/stage2/stage2.c	2008-06-02 18:06:08.858579000 +0100
164+++ grub/stage2/stage2.c	2008-06-06 18:04:03.585354000 +0100
165@@ -49,7 +49,8 @@
166     return 0;
167 #endif /* GRUB_UTIL */
168
169-  preset_menu_offset = 0;
170+  if (preset_menu_offset)
171+    return 0;
172   return preset_menu != 0;
173 }
174
175@@ -934,7 +935,11 @@
176 	      len = grub_read (buf, sizeof (buf));
177 	      if (len > 0)
178 		{
179+		  char *tmp;
180 		  buf[sizeof (buf) - 1] = 0;
181+		  if((tmp = grub_strstr(p, ":")) != NULL)
182+		    p = tmp + 1;
183+
184 		  safe_parse_maxint (&p, &saved_entryno);
185 		}
186
187