]>
Commit | Line | Data |
---|---|---|
cd1a2927 MT |
1 | To: bug-grub@gnu.org |
2 | cc: Keir.Fraser@cl.cam.ac.uk | |
3 | Subject: PATCH (updated): 'lilo -R' functionality | |
4 | From: Keir Fraser <Keir.Fraser@cl.cam.ac.uk> | |
5 | Message-Id: <E16iFu3-0002VK-00@wisbech.cl.cam.ac.uk> | |
6 | ||
7 | The following is a slight modification to the patch I submitted a week | |
8 | or so ago. This will cause GRUB to skip displaying the boot menu if a | |
9 | one-shot default has been specified (just as lilo does with '-R'). | |
10 | ||
11 | Same caveats as for previous patch: | |
12 | * The new 'savedefault' function in the GRUB shell is incomplete. | |
13 | Only works if the filesystem containing stage2 file is mounted. | |
14 | * Patch is against grub-0.90, but patches directly to 0.91 | |
15 | ||
16 | I hope this goes into CVS in the next round of updates :-) | |
17 | ||
18 | -- Keir Fraser | |
19 | ||
20 | ||
21 | ||
22 | diff -urBP grub-0.90-old/stage2/builtins.c grub-0.90-modified/stage2/builtins.c | |
23 | --- grub-0.90-old/stage2/builtins.c Fri Feb 22 11:59:57 2002 | |
24 | +++ grub-0.90-modified/stage2/builtins.c Fri Feb 22 13:48:36 2002 | |
25 | @@ -785,6 +785,17 @@ | |
26 | default_func (char *arg, int flags) | |
27 | { | |
28 | #ifndef SUPPORT_DISKLESS | |
29 | +#ifndef GRUB_UTIL | |
30 | + /* Has a forced once-only default been specified? */ | |
31 | + static int savedefault_helper(int); | |
32 | + if ((saved_entryno & STAGE2_ONCEONLY_ENTRY) != 0) | |
33 | + { | |
34 | + grub_timeout = 0; | |
35 | + default_entry = saved_entryno & ~STAGE2_ONCEONLY_ENTRY; | |
36 | + savedefault_helper(0); | |
37 | + return 0; | |
38 | + } | |
39 | +#endif | |
40 | if (grub_strcmp (arg, "saved") == 0) | |
41 | { | |
42 | default_entry = saved_entryno; | |
43 | @@ -3074,22 +3085,15 @@ | |
44 | }; | |
45 | ||
46 | \f | |
47 | -/* savedefault */ | |
48 | + | |
49 | +#if !defined(SUPPORT_DISKLESS) && !defined(GRUB_UTIL) | |
50 | +/* Write specified default entry number into stage2 file. */ | |
51 | static int | |
52 | -savedefault_func (char *arg, int flags) | |
53 | +savedefault_helper(int new_default) | |
54 | { | |
55 | -#if !defined(SUPPORT_DISKLESS) && !defined(GRUB_UTIL) | |
56 | char buffer[512]; | |
57 | int *entryno_ptr; | |
58 | - | |
59 | - /* This command is only useful when you boot an entry from the menu | |
60 | - interface. */ | |
61 | - if (! (flags & BUILTIN_SCRIPT)) | |
62 | - { | |
63 | - errnum = ERR_UNRECOGNIZED; | |
64 | - return 1; | |
65 | - } | |
66 | - | |
67 | + | |
68 | /* Get the geometry of the boot drive (i.e. the disk which contains | |
69 | this stage2). */ | |
70 | if (get_diskinfo (boot_drive, &buf_geom)) | |
71 | @@ -3115,10 +3119,10 @@ | |
72 | entryno_ptr = (int *) (buffer + STAGE2_SAVED_ENTRYNO); | |
73 | ||
74 | /* Check if the saved entry number differs from current entry number. */ | |
75 | - if (*entryno_ptr != current_entryno) | |
76 | + if (*entryno_ptr != new_default) | |
77 | { | |
78 | /* Overwrite the saved entry number. */ | |
79 | - *entryno_ptr = current_entryno; | |
80 | + *entryno_ptr = new_default; | |
81 | ||
82 | /* Save the image in the disk. */ | |
83 | if (! rawwrite (boot_drive, install_second_sector, buffer)) | |
84 | @@ -3129,6 +3133,117 @@ | |
85 | } | |
86 | ||
87 | return 0; | |
88 | +} | |
89 | +#endif | |
90 | + | |
91 | +#if !defined(SUPPORT_DISKLESS) && defined(GRUB_UTIL) | |
92 | +/* | |
93 | + * Full implementation of new `savedefault' for GRUB shell. | |
94 | + * XXX This needs fixing for stage2 files which aren't accessible | |
95 | + * through a mounted filesystem. | |
96 | + */ | |
97 | +static int | |
98 | +savedefault_shell(char *arg, int flags) | |
99 | +{ | |
100 | + char *stage2_os_file = "/boot/grub/stage2"; /* Default filename */ | |
101 | + FILE *fp; | |
102 | + char buffer[512]; | |
103 | + int *entryno_ptr; | |
104 | + int new_default = 0; | |
105 | + | |
106 | + while (1) | |
107 | + { | |
108 | + if (grub_memcmp ("--stage2=", arg, sizeof ("--stage2=") - 1) == 0) | |
109 | + { | |
110 | + stage2_os_file = arg + sizeof ("--stage2=") - 1; | |
111 | + arg = skip_to (0, arg); | |
112 | + nul_terminate (stage2_os_file); | |
113 | + } | |
114 | + else if (grub_memcmp ("--default=", arg, sizeof ("--default=") - 1) == 0) | |
115 | + { | |
116 | + char *p = arg + sizeof ("--default=") - 1; | |
117 | + if (! safe_parse_maxint (&p, &new_default)) | |
118 | + return 1; | |
119 | + arg = skip_to (0, arg); | |
120 | + } | |
121 | + else if (grub_memcmp ("--once", arg, sizeof ("--once") - 1) == 0) | |
122 | + { | |
123 | + new_default |= STAGE2_ONCEONLY_ENTRY; | |
124 | + arg = skip_to (0, arg); | |
125 | + } | |
126 | + else | |
127 | + break; | |
128 | + } | |
129 | + | |
130 | + if (! (fp = fopen(stage2_os_file, "r+"))) | |
131 | + { | |
132 | + errnum = ERR_FILE_NOT_FOUND; | |
133 | + return 1; | |
134 | + } | |
135 | + | |
136 | + if (fseek (fp, SECTOR_SIZE, SEEK_SET) != 0) | |
137 | + { | |
138 | + fclose (fp); | |
139 | + errnum = ERR_BAD_VERSION; | |
140 | + return 1; | |
141 | + } | |
142 | + | |
143 | + if (fread (buffer, 1, SECTOR_SIZE, fp) != SECTOR_SIZE) | |
144 | + { | |
145 | + fclose (fp); | |
146 | + errnum = ERR_READ; | |
147 | + return 1; | |
148 | + } | |
149 | + | |
150 | + /* Sanity check. */ | |
151 | + if (buffer[STAGE2_STAGE2_ID] != STAGE2_ID_STAGE2 | |
152 | + || *((short *) (buffer + STAGE2_VER_MAJ_OFFS)) != COMPAT_VERSION) | |
153 | + { | |
154 | + errnum = ERR_BAD_VERSION; | |
155 | + return 1; | |
156 | + } | |
157 | + | |
158 | + entryno_ptr = (int *) (buffer + STAGE2_SAVED_ENTRYNO); | |
159 | + *entryno_ptr = new_default; | |
160 | + | |
161 | + if (fseek (fp, SECTOR_SIZE, SEEK_SET) != 0) | |
162 | + { | |
163 | + fclose (fp); | |
164 | + errnum = ERR_BAD_VERSION; | |
165 | + return 1; | |
166 | + } | |
167 | + | |
168 | + if (fwrite (buffer, 1, SECTOR_SIZE, fp) != SECTOR_SIZE) | |
169 | + { | |
170 | + fclose (fp); | |
171 | + errnum = ERR_WRITE; | |
172 | + return 1; | |
173 | + } | |
174 | + | |
175 | + (void)fflush (fp); | |
176 | + fclose (fp); | |
177 | + return 0; | |
178 | +} | |
179 | +#endif | |
180 | + | |
181 | +/* savedefault */ | |
182 | +static int | |
183 | +savedefault_func (char *arg, int flags) | |
184 | +{ | |
185 | +#if !defined(SUPPORT_DISKLESS) | |
186 | +#if !defined(GRUB_UTIL) | |
187 | + /* This command is only useful when you boot an entry from the menu | |
188 | + interface. */ | |
189 | + if (! (flags & BUILTIN_SCRIPT)) | |
190 | + { | |
191 | + errnum = ERR_UNRECOGNIZED; | |
192 | + return 1; | |
193 | + } | |
194 | + | |
195 | + return savedefault_helper(current_entryno); | |
196 | +#else /* defined(GRUB_UTIL) */ | |
197 | + return savedefault_shell(arg, flags); | |
198 | +#endif | |
199 | #else /* ! SUPPORT_DISKLESS && ! GRUB_UTIL */ | |
200 | errnum = ERR_UNRECOGNIZED; | |
201 | return 1; | |
202 | @@ -3140,8 +3255,14 @@ | |
203 | "savedefault", | |
204 | savedefault_func, | |
205 | BUILTIN_CMDLINE, | |
206 | +#ifdef GRUB_UTIL | |
207 | + "savedefault [--stage2=STAGE2_FILE] [--default=DEFAULT] [--once]", | |
208 | + "Save DEFAULT as the default boot entry in STAGE2_FILE. If '--once'" | |
209 | + " is specified, the default is reset after the next reboot." | |
210 | +#else | |
211 | "savedefault", | |
212 | "Save the current entry as the default boot entry." | |
213 | +#endif | |
214 | }; | |
215 | ||
216 | \f | |
217 | @@ -4217,6 +4338,15 @@ | |
218 | static int | |
219 | timeout_func (char *arg, int flags) | |
220 | { | |
221 | + /* One-shot default shenanigans -- don't piss around with the menu! */ | |
222 | + if (grub_timeout != -1) | |
223 | + return 0; | |
224 | + if ((saved_entryno & STAGE2_ONCEONLY_ENTRY) != 0) | |
225 | + { | |
226 | + grub_timeout = 0; | |
227 | + return 0; | |
228 | + } | |
229 | + | |
230 | if (! safe_parse_maxint (&arg, &grub_timeout)) | |
231 | return 1; | |
232 | ||
233 | diff -urBP grub-0.90-old/stage2/shared.h grub-0.90-modified/stage2/shared.h | |
234 | --- grub-0.90-old/stage2/shared.h Fri Feb 22 11:59:53 2002 | |
235 | +++ grub-0.90-modified/stage2/shared.h Fri Feb 22 10:51:49 2002 | |
236 | @@ -199,6 +199,8 @@ | |
237 | #define STAGE2_FORCE_LBA 0x11 | |
238 | #define STAGE2_VER_STR_OFFS 0x12 | |
239 | ||
240 | +#define STAGE2_ONCEONLY_ENTRY 0x10000 | |
241 | + | |
242 | /* Stage 2 identifiers */ | |
243 | #define STAGE2_ID_STAGE2 0 | |
244 | #define STAGE2_ID_FFS_STAGE1_5 1 | |
245 | ||
246 | _______________________________________________ | |
247 | Bug-grub mailing list | |
248 | Bug-grub@gnu.org | |
249 | http://mail.gnu.org/mailman/listinfo/bug-grub |