]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blob - src/patches/SuSE10.2/stage2-wildcard.diff
Hinzugefuegt:
[people/pmueller/ipfire-2.x.git] / src / patches / SuSE10.2 / stage2-wildcard.diff
1 Index: grub-0.95/stage2/shared.h
2 ===================================================================
3 --- grub-0.95.orig/stage2/shared.h
4 +++ grub-0.95/stage2/shared.h
5 @@ -1008,9 +1008,11 @@ int grub_seek (int offset);
6 /* Close a file. */
7 void grub_close (void);
8
9 -/* List the contents of the directory that was opened with GRUB_OPEN,
10 - printing all completions. */
11 -int dir (char *dirname);
12 +/* List the contents of DIRECTORY. */
13 +int dir (char *dirname, void (*handle)(char *));
14 +
15 +/* Wildcard expand the last pathname component of GLOB. */
16 +char *wildcard (char *glob);
17
18 int set_bootdev (int hdbias);
19
20 Index: grub-0.95/stage2/stage2.c
21 ===================================================================
22 --- grub-0.95.orig/stage2/stage2.c
23 +++ grub-0.95/stage2/stage2.c
24 @@ -1240,6 +1240,192 @@ get_line_from_config (char *cmdline, int
25 }
26
27
28 +char *wildcard_prefix, *wildcard_suffix;
29 +char wildcard_matches[1024], *end_wildcard_matches;
30 +
31 +static void wildcard_handler(char *name);
32 +
33 +/* Match one directory entry against the current wildcard. If the entry
34 + matches, store it in WILDCARD_MATCHES. Silently ignore entries that
35 + don't fit into WILDCARD_MATCHES anymore. */
36 +static void
37 +wildcard_handler(char *name)
38 +{
39 + char *n = name, *p = wildcard_prefix;
40 +
41 + while (*p && *p == *n)
42 + {
43 + p++;
44 + n++;
45 + }
46 + if (*p)
47 + return; /* prefix mismatch */
48 +
49 + p = name + grub_strlen (name) - grub_strlen (wildcard_suffix);
50 + /* [n .. p) is the part matching the asterisk */
51 +
52 + if (p <= n || grub_strcmp (p, wildcard_suffix) != 0)
53 + return; /* zero-length match or suffix mismatch */
54 +
55 + /* store this match */
56 + if (p - n + 2 > sizeof (wildcard_matches) -
57 + (end_wildcard_matches - wildcard_matches))
58 + return; /* out of space */
59 + while (n < p)
60 + *end_wildcard_matches++ = *n++;
61 + *end_wildcard_matches++ = 0;
62 +}
63 +
64 +/* Wildcard expand the GLOB argument. Return NULL upon failure, or
65 + a list of 0-terminated expansions, terminated by a zero-length string. */
66 +char *
67 +wildcard (char *glob)
68 +{
69 + char path[128], *p;
70 + int ret;
71 +
72 + end_wildcard_matches = wildcard_matches;
73 + if (grub_strlen (glob) + 1 > sizeof (path)) {
74 + errnum = ERR_FILELENGTH;
75 + return NULL; /* cannot handle pathnames this long */
76 + }
77 + grub_strcpy (path, glob);
78 + p = path;
79 + while (*p)
80 + p++;
81 + wildcard_suffix = p;
82 + while (p > path && *p != '/')
83 + p--;
84 + if (*p != '/')
85 + {
86 + errnum = ERR_BAD_FILETYPE;
87 + return NULL; /* Cannot wildcard device names */
88 + }
89 + *(++p) = 0;
90 + wildcard_prefix = glob + (p - path);
91 + for (p = wildcard_prefix;; p++)
92 + {
93 + if (*p == 0)
94 + {
95 + /* We cannot do exact matches: this cannot be represented in the
96 + result list. */
97 + return NULL;
98 + }
99 + else if (*p == '*')
100 + {
101 + *p++ = 0;
102 + wildcard_suffix = p;
103 + break;
104 + }
105 + }
106 +
107 + ret = dir (path, wildcard_handler);
108 + /* restore original argument */
109 + wildcard_prefix[grub_strlen (wildcard_prefix)] = '*';
110 + if (!ret)
111 + return NULL;
112 + *end_wildcard_matches++ = 0;
113 + return wildcard_matches;
114 +}
115 +
116 +#define skip(str) ((str) + grub_strlen (str) + 1)
117 +
118 +static void inplace_sort (char *str);
119 +
120 +static void
121 +inplace_sort (char *str)
122 +{
123 + int m, n = 0;
124 + char *s, *t, *x;
125 +
126 + for (s = str; *s; s = skip (s))
127 + n++;
128 +
129 + /* we use x as temporary storage */
130 + x = s + 1;
131 +
132 + for (; n >= 2; n--)
133 + {
134 + s = str;
135 + t = skip (s);
136 +
137 + for (m = n; m >= 2; m--)
138 + {
139 + if (grub_strcmp (s, t) > 0)
140 + {
141 + int ls = skip (s) - s;
142 + int lt = skip (t) - t;
143 +
144 + memcpy (x, s, ls);
145 + grub_memmove (s + ls, s + lt, t - (s + ls));
146 + memcpy (s, t, lt);
147 + t = t + lt - ls;
148 + memcpy (t, x, ls);
149 + }
150 + s = t;
151 + t = skip (t);
152 + }
153 + }
154 +}
155 +
156 +static int this_config_len (const char *config);
157 +static int
158 +this_config_len (const char *config)
159 +{
160 + const char *c = config;
161 + while (*c)
162 + {
163 + while (*c)
164 + c++;
165 + c++;
166 + }
167 + c++;
168 + return c - config;
169 +}
170 +
171 +static const char * expand_asterisks (const char *str, int *len,
172 + const char *subst);
173 +
174 +/* Expand all asterisks (*) in a menu entry or commands section with its
175 + substitution. Use a backslash as escape character. */
176 +static const char *
177 +expand_asterisks (const char *str, int *len, const char *subst)
178 +{
179 + static char buffer[1024];
180 + char *b = buffer, escaped = 0;
181 + const char *end = str + *len;
182 +
183 + while (str < end)
184 + {
185 + if (*str == '*' && !escaped)
186 + {
187 + if (b - buffer + grub_strlen (subst) > sizeof (buffer))
188 + {
189 + errnum = ERR_FILELENGTH;
190 + return NULL;
191 + }
192 + grub_strcpy (b, subst);
193 + b += grub_strlen (subst);
194 + }
195 + else if (*str == '\\' && !escaped)
196 + escaped = 1;
197 + else
198 + {
199 + escaped = 0;
200 + if (b - buffer + 1 > sizeof (buffer))
201 + {
202 + errnum = ERR_FILELENGTH;
203 + return NULL;
204 + }
205 + *b++ = *str;
206 + }
207 + str++;
208 + }
209 + *len = b - buffer;
210 +
211 + return buffer;
212 +}
213 +
214 /* This is the starting function in C. */
215 void
216 cmain (void)
217 @@ -1260,6 +1446,96 @@ cmain (void)
218 init_config ();
219 }
220
221 + auto void expand_wildcard_entries (void);
222 + void expand_wildcard_entries (void)
223 + {
224 + char *config_entry = config_entries;
225 + char *menu_entry = menu_entries;
226 +
227 + while (*menu_entry)
228 + {
229 + char *command = config_entry;
230 +
231 + do
232 + {
233 + char *c = command;
234 + const char *w = "wildcard";
235 +
236 + while (*w && *c == *w)
237 + {
238 + c++;
239 + w++;
240 + }
241 + if (*w == 0 && (*c == ' ' || *c == '\t' || *c == '='))
242 + {
243 + int len;
244 +
245 + /* This is a wildcard command. Advance to the argument. */
246 + while (*c == ' ' || *c == '\t' || *c == '=')
247 + c++;
248 +
249 + /* Expand wildcard entry. */
250 + w = wildcard (c);
251 + if (w)
252 + inplace_sort (w);
253 +
254 + /* Remove the wildcard command from the command section;
255 + it has no meaning beyond the wildcard expansion just
256 + performed. */
257 + len = grub_strlen (command) + 1;
258 + grub_memmove (command, command + len,
259 + config_len - (command - config_entries));
260 + config_len -= len;
261 +
262 + while (w && *w)
263 + {
264 + /* Insert expansion before the wildcard entry in the
265 + list of entry names. */
266 + len = grub_strlen (menu_entry) + 1;
267 + const char *x = expand_asterisks (menu_entry, &len, w);
268 + grub_memmove (menu_entry + len, menu_entry,
269 + menu_len - (menu_entry - menu_entries));
270 + memcpy (menu_entry, x, len);
271 + menu_entry += len;
272 + menu_len += len;
273 +
274 + /* Insert expansion before the wildcard command section
275 + in the list of command sections. */
276 + len = this_config_len (config_entry);
277 + x = expand_asterisks (config_entry, &len, w);
278 + grub_memmove (config_entry + len, config_entry,
279 + config_len - (config_entry -
280 + config_entries));
281 + memcpy (config_entry, x, len);
282 + config_entry += len;
283 + config_len += len;
284 +
285 + num_entries++;
286 + w += grub_strlen (w) + 1;
287 + }
288 +
289 + /* Remove the wildcard command section; it has just
290 + been expanded. */
291 + len = grub_strlen (menu_entry) + 1;
292 + grub_memmove (menu_entry, menu_entry + len,
293 + menu_len - (menu_entry - menu_entries));
294 + menu_len -= len;
295 +
296 + len = this_config_len(config_entry);
297 + grub_memmove (config_entry, config_entry + len,
298 + config_len - (config_entry - config_entries));
299 + config_len -= len;
300 +
301 + num_entries--;
302 + }
303 + command += grub_strlen (command) + 1;
304 + }
305 + while (*command);
306 + menu_entry += grub_strlen (menu_entry) + 1;
307 + config_entry += this_config_len(config_entry);
308 + }
309 + }
310 +
311 /* Initialize the environment for restarting Stage 2. */
312 grub_setjmp (restart_env);
313
314 @@ -1379,8 +1655,16 @@ cmain (void)
315 config_len = prev_config_len;
316 }
317
318 + if (is_preset)
319 + close_preset_menu ();
320 + else
321 + grub_close ();
322 +
323 menu_entries[menu_len++] = 0;
324 config_entries[config_len++] = 0;
325 +
326 + expand_wildcard_entries();
327 +
328 grub_memmove (config_entries + config_len, menu_entries,
329 menu_len);
330 menu_entries = config_entries + config_len;
331 @@ -1395,11 +1679,6 @@ cmain (void)
332 else
333 default_entry = fallback_entry;
334 }
335 -
336 - if (is_preset)
337 - close_preset_menu ();
338 - else
339 - grub_close ();
340 }
341 while (is_preset);
342 }
343 Index: grub-0.95/stage2/builtins.c
344 ===================================================================
345 --- grub-0.95.orig/stage2/builtins.c
346 +++ grub-0.95/stage2/builtins.c
347 @@ -4831,6 +4831,49 @@ static struct builtin builtin_vbeprobe =
348 };
349
350 \f
351 +/* wildcard */
352 + static int
353 +wildcard_func (char *arg, int flags)
354 +{
355 +#ifdef DEBUG_WILDCARD
356 + char *w = wildcard (arg);
357 +
358 + if (w)
359 + {
360 + while (*w)
361 + {
362 + grub_printf("%s ", w);
363 + w += strlen (w) + 1;
364 + }
365 + grub_printf("\n");
366 + return 1;
367 + }
368 + else
369 + print_error();
370 +#endif
371 +
372 + /* This special command is interpreted in the config file parser. */
373 + return 0;
374 +}
375 +
376 +static struct builtin builtin_wildcard =
377 + {
378 + "wildcard",
379 + wildcard_func,
380 +#ifndef DEBUG_WILDCARD
381 + BUILTIN_MENU,
382 +#else
383 + BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST,
384 + "wildcard GLOB",
385 + "Declare this menu entry as a wildcard entry. GLOB is a path containing"
386 + " one asterisk. All files matching this expression are looked up; the"
387 + " menu entry is duplicated for each match with asterisks in other"
388 + " commands replaced by the string matching the asterisk in the wildcard"
389 + " command."
390 +#endif
391 +};
392 +
393 +\f
394 /* The table of builtin commands. Sorted in dictionary order. */
395 struct builtin *builtin_table[] =
396 {
397 @@ -4920,5 +4963,6 @@ struct builtin *builtin_table[] =
398 &builtin_unhide,
399 &builtin_uppermem,
400 &builtin_vbeprobe,
401 + &builtin_wildcard,
402 0
403 };