1 diff -urN grub-2.04.orig/grub-core/commands/blscfg.c grub-2.04/grub-core/commands/blscfg.c
2 --- grub-2.04.orig/grub-core/commands/blscfg.c 1970-01-01 01:00:00.000000000 +0100
3 +++ grub-2.04/grub-core/commands/blscfg.c 2019-08-18 16:14:44.723000000 +0200
5 +/*-*- Mode: C; c-basic-offset: 2; indent-tabs-mode: t -*-*/
7 +/* bls.c - implementation of the boot loader spec */
10 + * GRUB -- GRand Unified Bootloader
12 + * GRUB is free software: you can redistribute it and/or modify
13 + * it under the terms of the GNU General Public License as published by
14 + * the Free Software Foundation, either version 3 of the License, or
15 + * (at your option) any later version.
17 + * GRUB is distributed in the hope that it will be useful,
18 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 + * GNU General Public License for more details.
22 + * You should have received a copy of the GNU General Public License
23 + * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
26 +#include <grub/list.h>
27 +#include <grub/types.h>
28 +#include <grub/misc.h>
30 +#include <grub/err.h>
32 +#include <grub/extcmd.h>
33 +#include <grub/i18n.h>
35 +#include <grub/env.h>
36 +#include <grub/file.h>
37 +#include <grub/normal.h>
38 +#include <grub/lib/envblk.h>
42 +GRUB_MOD_LICENSE ("GPLv3+");
46 +#define GRUB_BLS_CONFIG_PATH "/loader/entries/"
47 +#ifdef GRUB_MACHINE_EMU
48 +#define GRUB_BOOT_DEVICE "/boot"
50 +#define GRUB_BOOT_DEVICE "($root)"
59 +static struct bls_entry *entries = NULL;
61 +#define FOR_BLS_ENTRIES(var) FOR_LIST_ELEMENTS (var, entries)
63 +static int bls_add_keyval(struct bls_entry *entry, char *key, char *val)
66 + struct keyval **kvs, *kv;
67 + int new_n = entry->nkeyvals + 1;
69 + kvs = grub_realloc (entry->keyvals, new_n * sizeof (struct keyval *));
71 + return grub_error (GRUB_ERR_OUT_OF_MEMORY,
72 + "couldn't find space for BLS entry");
73 + entry->keyvals = kvs;
75 + kv = grub_malloc (sizeof (struct keyval));
77 + return grub_error (GRUB_ERR_OUT_OF_MEMORY,
78 + "couldn't find space for BLS entry");
80 + k = grub_strdup (key);
84 + return grub_error (GRUB_ERR_OUT_OF_MEMORY,
85 + "couldn't find space for BLS entry");
88 + v = grub_strdup (val);
93 + return grub_error (GRUB_ERR_OUT_OF_MEMORY,
94 + "couldn't find space for BLS entry");
100 + entry->keyvals[entry->nkeyvals] = kv;
101 + grub_dprintf("blscfg", "new keyval at %p:%s:%s\n", entry->keyvals[entry->nkeyvals], k, v);
102 + entry->nkeyvals = new_n;
107 +/* Find they value of the key named by keyname. If there are allowed to be
108 + * more than one, pass a pointer to an int set to -1 the first time, and pass
109 + * the same pointer through each time after, and it'll return them in sorted
110 + * order as defined in the BLS fragment file */
111 +static char *bls_get_val(struct bls_entry *entry, const char *keyname, int *last)
113 + int idx, start = 0;
114 + struct keyval *kv = NULL;
119 + for (idx = start; idx < entry->nkeyvals; idx++) {
120 + kv = entry->keyvals[idx];
122 + if (!grub_strcmp (keyname, kv->key))
126 + if (idx == entry->nkeyvals) {
138 +#define goto_return(x) ({ ret = (x); goto finish; })
140 +/* compare alpha and numeric segments of two versions */
141 +/* return 1: a is newer than b */
142 +/* 0: a and b are the same version */
143 +/* -1: b is newer than a */
144 +static int vercmp(const char * a, const char * b)
146 + char oldch1, oldch2;
154 + grub_dprintf("blscfg", "%s comparing %s and %s\n", __func__, a, b);
155 + if (!grub_strcmp(a, b))
158 + abuf = grub_malloc(grub_strlen(a) + 1);
159 + bbuf = grub_malloc(grub_strlen(b) + 1);
162 + grub_strcpy(str1, a);
163 + grub_strcpy(str2, b);
168 + /* loop through each version segment of str1 and str2 and compare them */
169 + while (*one || *two) {
170 + while (*one && !grub_isalnum(*one) && *one != '~') one++;
171 + while (*two && !grub_isalnum(*two) && *two != '~') two++;
173 + /* handle the tilde separator, it sorts before everything else */
174 + if (*one == '~' || *two == '~') {
175 + if (*one != '~') goto_return (1);
176 + if (*two != '~') goto_return (-1);
182 + /* If we ran to the end of either, we are finished with the loop */
183 + if (!(*one && *two)) break;
188 + /* grab first completely alpha or completely numeric segment */
189 + /* leave one and two pointing to the start of the alpha or numeric */
190 + /* segment and walk str1 and str2 to end of segment */
191 + if (grub_isdigit(*str1)) {
192 + while (*str1 && grub_isdigit(*str1)) str1++;
193 + while (*str2 && grub_isdigit(*str2)) str2++;
196 + while (*str1 && grub_isalpha(*str1)) str1++;
197 + while (*str2 && grub_isalpha(*str2)) str2++;
201 + /* save character at the end of the alpha or numeric segment */
202 + /* so that they can be restored after the comparison */
208 + /* this cannot happen, as we previously tested to make sure that */
209 + /* the first string has a non-null segment */
210 + if (one == str1) goto_return(-1); /* arbitrary */
212 + /* take care of the case where the two version segments are */
213 + /* different types: one numeric, the other alpha (i.e. empty) */
214 + /* numeric segments are always newer than alpha segments */
215 + /* XXX See patch #60884 (and details) from bugzilla #50977. */
216 + if (two == str2) goto_return (isnum ? 1 : -1);
219 + grub_size_t onelen, twolen;
220 + /* this used to be done by converting the digit segments */
221 + /* to ints using atoi() - it's changed because long */
222 + /* digit segments can overflow an int - this should fix that. */
224 + /* throw away any leading zeros - it's a number, right? */
225 + while (*one == '0') one++;
226 + while (*two == '0') two++;
228 + /* whichever number has more digits wins */
229 + onelen = grub_strlen(one);
230 + twolen = grub_strlen(two);
231 + if (onelen > twolen) goto_return (1);
232 + if (twolen > onelen) goto_return (-1);
235 + /* grub_strcmp will return which one is greater - even if the two */
236 + /* segments are alpha or if they are numeric. don't return */
237 + /* if they are equal because there might be more segments to */
239 + rc = grub_strcmp(one, two);
240 + if (rc) goto_return (rc < 1 ? -1 : 1);
242 + /* restore character that was replaced by null above */
249 + /* this catches the case where all numeric and alpha segments have */
250 + /* compared identically but the segment sepparating characters were */
252 + if ((!*one) && (!*two)) goto_return (0);
254 + /* whichever version still has characters left over wins */
255 + if (!*one) goto_return (-1); else goto_return (1);
263 +/* returns name/version/release */
264 +/* NULL string pointer returned if nothing found */
266 +split_package_string (char *package_string, char **name,
267 + char **version, char **release)
269 + char *package_version, *package_release;
272 + package_release = grub_strrchr (package_string, '-');
274 + if (package_release != NULL)
275 + *package_release++ = '\0';
277 + *release = package_release;
281 + *version = package_string;
286 + package_version = grub_strrchr(package_string, '-');
288 + if (package_version != NULL)
289 + *package_version++ = '\0';
291 + *version = package_version;
293 + *name = package_string;
296 + /* Bubble up non-null values from release to name */
297 + if (name != NULL && *name == NULL)
299 + *name = (*version == NULL ? *release : *version);
300 + *version = *release;
303 + if (*version == NULL)
305 + *version = *release;
311 +split_cmp(char *nvr0, char *nvr1, int has_name)
314 + char *name0, *version0, *release0;
315 + char *name1, *version1, *release1;
317 + split_package_string(nvr0, has_name ? &name0 : NULL, &version0, &release0);
318 + split_package_string(nvr1, has_name ? &name1 : NULL, &version1, &release1);
322 + ret = vercmp(name0 == NULL ? "" : name0,
323 + name1 == NULL ? "" : name1);
328 + ret = vercmp(version0 == NULL ? "" : version0,
329 + version1 == NULL ? "" : version1);
333 + ret = vercmp(release0 == NULL ? "" : release0,
334 + release1 == NULL ? "" : release1);
338 +/* return 1: e0 is newer than e1 */
339 +/* 0: e0 and e1 are the same version */
340 +/* -1: e1 is newer than e0 */
341 +static int bls_cmp(const struct bls_entry *e0, const struct bls_entry *e1)
346 + id0 = grub_strdup(e0->filename);
347 + id1 = grub_strdup(e1->filename);
349 + r = split_cmp(id0, id1, 1);
357 +static void list_add_tail(struct bls_entry *head, struct bls_entry *item)
361 + head->prev->next = item;
362 + item->prev = head->prev;
366 +static int bls_add_entry(struct bls_entry *entry)
368 + struct bls_entry *e, *last = NULL;
372 + grub_dprintf ("blscfg", "Add entry with id \"%s\"\n", entry->filename);
377 + FOR_BLS_ENTRIES(e) {
378 + rc = bls_cmp(entry, e);
381 + return GRUB_ERR_BAD_ARGUMENT;
384 + grub_dprintf ("blscfg", "Add entry with id \"%s\"\n", entry->filename);
385 + list_add_tail (e, entry);
386 + if (e == entries) {
388 + entry->prev = NULL;
396 + grub_dprintf ("blscfg", "Add entry with id \"%s\"\n", entry->filename);
397 + last->next = entry;
398 + entry->prev = last;
404 +struct read_entry_info {
406 + const char *dirname;
410 +static int read_entry (
411 + const char *filename,
412 + const struct grub_dirhook_info *dirhook_info UNUSED,
415 + grub_size_t m = 0, n, clip = 0;
418 + grub_file_t f = NULL;
419 + struct bls_entry *entry;
420 + struct read_entry_info *info = (struct read_entry_info *)data;
422 + grub_dprintf ("blscfg", "filename: \"%s\"\n", filename);
424 + n = grub_strlen (filename);
432 + if (filename[0] == '.')
438 + if (grub_strcmp (filename + n - 5, ".conf") != 0)
441 + p = grub_xasprintf ("(%s)%s/%s", info->devid, info->dirname, filename);
443 + f = grub_file_open (p, GRUB_FILE_TYPE_CONFIG);
448 + entry = grub_zalloc (sizeof (*entry));
456 + if (n > 5 && !grub_strcmp (filename + n - 5, ".conf") == 0)
459 + slash = grub_strrchr (filename, '/');
461 + slash = grub_strrchr (filename, '\\');
463 + while (*slash == '/' || *slash == '\\')
466 + m = slash ? slash - filename : 0;
475 + entry->filename = grub_strndup(filename + m, n - clip);
476 + if (!entry->filename)
479 + entry->filename[n - 5] = '\0';
486 + buf = grub_file_getline (f);
490 + while (buf && buf[0] && (buf[0] == ' ' || buf[0] == '\t'))
495 + separator = grub_strchr (buf, ' ');
498 + separator = grub_strchr (buf, '\t');
500 + if (!separator || separator[1] == '\0')
506 + separator[0] = '\0';
510 + } while (*separator == ' ' || *separator == '\t');
512 + rc = bls_add_keyval (entry, buf, separator);
519 + bls_add_entry(entry);
526 + grub_file_close (f);
531 +static grub_envblk_t saved_env = NULL;
534 +save_var (const char *name, const char *value, void *whitelist UNUSED)
536 + const char *val = grub_env_get (name);
537 + grub_dprintf("blscfg", "saving \"%s\"\n", name);
540 + grub_envblk_set (saved_env, name, value);
546 +unset_var (const char *name, const char *value UNUSED, void *whitelist)
548 + grub_dprintf("blscfg", "restoring \"%s\"\n", name);
551 + grub_env_unset (name);
555 + if (test_whitelist_membership (name,
556 + (const grub_env_whitelist_t *) whitelist))
557 + grub_env_unset (name);
562 +static char **bls_make_list (struct bls_entry *entry, const char *key, int *num)
568 + char **list = NULL;
570 + list = grub_malloc (sizeof (char *));
579 + val = bls_get_val (entry, key, &last);
583 + new = grub_realloc (list, (nlist + 2) * sizeof (char *));
588 + list[nlist++] = val;
589 + list[nlist] = NULL;
598 +static char *field_append(bool is_var, char *buffer, char *start, char *end)
600 + char *temp = grub_strndup(start, end - start + 1);
601 + const char *field = temp;
604 + field = grub_env_get (temp);
610 + buffer = grub_strdup(field);
614 + buffer = grub_realloc (buffer, grub_strlen(buffer) + grub_strlen(field));
618 + grub_stpcpy (buffer + grub_strlen(buffer), field);
624 +static char *expand_val(char *value)
626 + char *buffer = NULL;
627 + char *start = value;
629 + bool is_var = false;
635 + if (*value == '$') {
636 + if (start != end) {
637 + buffer = field_append(is_var, buffer, start, end);
644 + } else if (is_var) {
645 + if (!grub_isalnum(*value) && *value != '_') {
646 + buffer = field_append(is_var, buffer, start, end);
656 + if (start != end) {
657 + buffer = field_append(is_var, buffer, start, end);
665 +static char **early_initrd_list (const char *initrd)
668 + char **list = NULL;
671 + while ((separator = grub_strchr (initrd, ' ')))
673 + list = grub_realloc (list, (nlist + 2) * sizeof (char *));
677 + list[nlist++] = grub_strndup(initrd, separator - initrd);
678 + list[nlist] = NULL;
679 + initrd = separator + 1;
682 + list = grub_realloc (list, (nlist + 2) * sizeof (char *));
686 + list[nlist++] = grub_strndup(initrd, grub_strlen(initrd));
687 + list[nlist] = NULL;
692 +static void create_entry (struct bls_entry *entry)
695 + const char **argv = NULL;
697 + char *title = NULL;
698 + char *clinux = NULL;
699 + char *options = NULL;
700 + char **initrds = NULL;
701 + char *initrd = NULL;
702 + const char *early_initrd = NULL;
703 + char **early_initrds = NULL;
704 + char *initrd_prefix = NULL;
705 + char *id = entry->filename;
706 + char *dotconf = id;
707 + char *hotkey = NULL;
709 + char *users = NULL;
710 + char **classes = NULL;
712 + char **args = NULL;
717 + grub_dprintf("blscfg", "%s got here\n", __func__);
718 + clinux = bls_get_val (entry, "linux", NULL);
721 + grub_dprintf ("blscfg", "Skipping file %s with no 'linux' key.\n", entry->filename);
726 + * strip the ".conf" off the end before we make it our "id" field.
730 + dotconf = grub_strstr(dotconf, ".conf");
731 + } while (dotconf != NULL && dotconf[5] != '\0');
735 + title = bls_get_val (entry, "title", NULL);
736 + options = expand_val (bls_get_val (entry, "options", NULL));
739 + options = expand_val (grub_env_get("default_kernelopts"));
741 + initrds = bls_make_list (entry, "initrd", NULL);
743 + hotkey = bls_get_val (entry, "grub_hotkey", NULL);
744 + users = expand_val (bls_get_val (entry, "grub_users", NULL));
745 + classes = bls_make_list (entry, "grub_class", NULL);
746 + args = bls_make_list (entry, "grub_arg", &argc);
749 + argv = grub_malloc ((argc + 1) * sizeof (char *));
750 + argv[0] = title ? title : clinux;
751 + for (i = 1; i < argc; i++)
752 + argv[i] = args[i-1];
755 + early_initrd = grub_env_get("early_initrd");
757 + grub_dprintf ("blscfg", "adding menu entry for \"%s\" with id \"%s\"\n",
761 + early_initrds = early_initrd_list(early_initrd);
762 + if (!early_initrds)
764 + grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
768 + if (initrds != NULL && initrds[0] != NULL)
770 + initrd_prefix = grub_strrchr (initrds[0], '/');
771 + initrd_prefix = grub_strndup(initrds[0], initrd_prefix - initrds[0] + 1);
775 + initrd_prefix = grub_strrchr (clinux, '/');
776 + initrd_prefix = grub_strndup(clinux, initrd_prefix - clinux + 1);
779 + if (!initrd_prefix)
781 + grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
786 + if (early_initrds || initrds)
788 + int initrd_size = sizeof ("initrd");
791 + for (i = 0; early_initrds != NULL && early_initrds[i] != NULL; i++)
792 + initrd_size += sizeof (" " GRUB_BOOT_DEVICE) \
793 + + grub_strlen(initrd_prefix) \
794 + + grub_strlen (early_initrds[i]) + 1;
796 + for (i = 0; initrds != NULL && initrds[i] != NULL; i++)
797 + initrd_size += sizeof (" " GRUB_BOOT_DEVICE) \
798 + + grub_strlen (initrds[i]) + 1;
801 + initrd = grub_malloc (initrd_size);
804 + grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
809 + tmp = grub_stpcpy(initrd, "initrd");
810 + for (i = 0; early_initrds != NULL && early_initrds[i] != NULL; i++)
812 + grub_dprintf ("blscfg", "adding early initrd %s\n", early_initrds[i]);
813 + tmp = grub_stpcpy (tmp, " " GRUB_BOOT_DEVICE);
814 + tmp = grub_stpcpy (tmp, initrd_prefix);
815 + tmp = grub_stpcpy (tmp, early_initrds[i]);
816 + grub_free(early_initrds[i]);
819 + for (i = 0; initrds != NULL && initrds[i] != NULL; i++)
821 + grub_dprintf ("blscfg", "adding initrd %s\n", initrds[i]);
822 + tmp = grub_stpcpy (tmp, " " GRUB_BOOT_DEVICE);
823 + tmp = grub_stpcpy (tmp, initrds[i]);
825 + tmp = grub_stpcpy (tmp, "\n");
828 + src = grub_xasprintf ("load_video\n"
829 + "set gfxpayload=keep\n"
833 + GRUB_BOOT_DEVICE, clinux, options ? " " : "", options ? options : "",
834 + initrd ? initrd : "");
836 + grub_normal_add_menu_entry (argc, argv, classes, id, users, hotkey, NULL, src, 0, &index, entry);
837 + grub_dprintf ("blscfg", "Added entry %d id:\"%s\"\n", index, id);
840 + grub_free (initrd);
841 + grub_free (initrd_prefix);
842 + grub_free (early_initrds);
843 + grub_free (initrds);
844 + grub_free (options);
845 + grub_free (classes);
851 +struct find_entry_info {
852 + const char *dirname;
859 + * info: the filesystem object the file is on.
861 +static int find_entry (struct find_entry_info *info)
863 + struct read_entry_info read_entry_info;
864 + grub_fs_t blsdir_fs = NULL;
865 + grub_device_t blsdir_dev = NULL;
866 + const char *blsdir = info->dirname;
871 + blsdir = grub_env_get ("blsdir");
873 + blsdir = GRUB_BLS_CONFIG_PATH;
876 + read_entry_info.file = NULL;
877 + read_entry_info.dirname = blsdir;
879 + grub_dprintf ("blscfg", "scanning blsdir: %s\n", blsdir);
881 + blsdir_dev = info->dev;
882 + blsdir_fs = info->fs;
883 + read_entry_info.devid = info->devid;
886 + r = blsdir_fs->fs_dir (blsdir_dev, read_entry_info.dirname, read_entry,
889 + grub_dprintf ("blscfg", "read_entry returned error\n");
893 + e = grub_error_pop();
897 + if (r && !info->dirname && !fallback) {
898 + read_entry_info.dirname = "/boot" GRUB_BLS_CONFIG_PATH;
899 + grub_dprintf ("blscfg", "Entries weren't found in %s, fallback to %s\n",
900 + blsdir, read_entry_info.dirname);
902 + goto read_fallback;
909 +bls_load_entries (const char *path)
914 + static grub_err_t r;
915 + const char *devid = NULL;
916 + char *blsdir = NULL;
917 + struct find_entry_info info = {
922 + struct read_entry_info rei = {
928 + len = grub_strlen (path);
929 + if (grub_strcmp (path + len - 5, ".conf") == 0) {
930 + rei.file = grub_file_open (path, GRUB_FILE_TYPE_CONFIG);
934 + * read_entry() closes the file
936 + return read_entry(path, NULL, &rei);
937 + } else if (path[0] == '(') {
940 + blsdir = grub_strchr (path, ')');
942 + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Filepath isn't correct"));
945 + blsdir = blsdir + 1;
950 +#ifdef GRUB_MACHINE_EMU
952 +#elif defined(GRUB_MACHINE_EFI)
953 + devid = grub_env_get ("root");
955 + devid = grub_env_get ("boot");
958 + return grub_error (GRUB_ERR_FILE_NOT_FOUND,
959 + N_("variable `%s' isn't set"), "boot");
962 + grub_dprintf ("blscfg", "opening %s\n", devid);
963 + dev = grub_device_open (devid);
967 + grub_dprintf ("blscfg", "probing fs\n");
968 + fs = grub_fs_probe (dev);
975 + info.dirname = blsdir;
976 + info.devid = devid;
983 + grub_device_close (dev);
989 +is_default_entry(const char *def_entry, struct bls_entry *entry, int idx)
997 + if (grub_strcmp(def_entry, entry->filename) == 0)
1000 + title = bls_get_val(entry, "title", NULL);
1002 + if (title && grub_strcmp(def_entry, title) == 0)
1005 + def_idx = (int)grub_strtol(def_entry, NULL, 0);
1006 + if (grub_errno == GRUB_ERR_BAD_NUMBER) {
1007 + grub_errno = GRUB_ERR_NONE;
1011 + if (def_idx == idx)
1018 +bls_create_entries (bool show_default, bool show_non_default, char *entry_id)
1020 + const char *def_entry = NULL;
1021 + struct bls_entry *entry = NULL;
1024 + def_entry = grub_env_get("default");
1026 + grub_dprintf ("blscfg", "%s Creating entries from bls\n", __func__);
1027 + FOR_BLS_ENTRIES(entry) {
1028 + if (entry->visible) {
1033 + if ((show_default && is_default_entry(def_entry, entry, idx)) ||
1034 + (show_non_default && !is_default_entry(def_entry, entry, idx)) ||
1035 + (entry_id && grub_strcmp(entry_id, entry->filename) == 0)) {
1036 + create_entry(entry);
1037 + entry->visible = 1;
1042 + return GRUB_ERR_NONE;
1046 +grub_cmd_blscfg (grub_extcmd_context_t ctxt UNUSED,
1047 + int argc, char **args)
1050 + char *path = NULL;
1051 + char *entry_id = NULL;
1052 + bool show_default = true;
1053 + bool show_non_default = true;
1056 + if (grub_strcmp (args[0], "default") == 0) {
1057 + show_non_default = false;
1058 + } else if (grub_strcmp (args[0], "non-default") == 0) {
1059 + show_default = false;
1060 + } else if (args[0][0] == '(') {
1063 + entry_id = args[0];
1064 + show_default = false;
1065 + show_non_default = false;
1069 + r = bls_load_entries(path);
1073 + return bls_create_entries(show_default, show_non_default, entry_id);
1076 +static grub_extcmd_t cmd;
1077 +static grub_extcmd_t oldcmd;
1079 +GRUB_MOD_INIT(blscfg)
1081 + grub_dprintf("blscfg", "%s got here\n", __func__);
1082 + cmd = grub_register_extcmd ("blscfg",
1086 + N_("Import Boot Loader Specification snippets."),
1088 + oldcmd = grub_register_extcmd ("bls_import",
1092 + N_("Import Boot Loader Specification snippets."),
1096 +GRUB_MOD_FINI(blscfg)
1098 + grub_unregister_extcmd (cmd);
1099 + grub_unregister_extcmd (oldcmd);
1101 diff -urN grub-2.04.orig/grub-core/commands/legacycfg.c grub-2.04/grub-core/commands/legacycfg.c
1102 --- grub-2.04.orig/grub-core/commands/legacycfg.c 2018-11-24 18:13:02.000000000 +0100
1103 +++ grub-2.04/grub-core/commands/legacycfg.c 2019-08-18 16:14:44.723000000 +0200
1106 grub_normal_add_menu_entry (1, args, NULL, NULL, "legacy",
1109 + entrysrc, 0, NULL, NULL);
1112 grub_free (oldname);
1115 args[0] = entryname;
1116 grub_normal_add_menu_entry (1, args, NULL, NULL, NULL,
1117 - NULL, NULL, entrysrc, 0);
1118 + NULL, NULL, entrysrc, 0, NULL,
1123 diff -urN grub-2.04.orig/grub-core/commands/loadenv.c grub-2.04/grub-core/commands/loadenv.c
1124 --- grub-2.04.orig/grub-core/commands/loadenv.c 2018-11-24 18:13:02.000000000 +0100
1125 +++ grub-2.04/grub-core/commands/loadenv.c 2019-08-18 16:14:44.723000000 +0200
1127 #include <grub/extcmd.h>
1128 #include <grub/i18n.h>
1130 +#include "loadenv.h"
1132 GRUB_MOD_LICENSE ("GPLv3+");
1134 static const struct grub_arg_option options[] =
1139 -static grub_envblk_t
1140 -read_envblk_file (grub_file_t file)
1142 - grub_off_t offset = 0;
1144 - grub_size_t size = grub_file_size (file);
1145 - grub_envblk_t envblk;
1147 - buf = grub_malloc (size);
1155 - ret = grub_file_read (file, buf + offset, size);
1166 - envblk = grub_envblk_open (buf, offset);
1170 - grub_error (GRUB_ERR_BAD_FILE_TYPE, "invalid environment block");
1177 -struct grub_env_whitelist
1182 -typedef struct grub_env_whitelist grub_env_whitelist_t;
1185 -test_whitelist_membership (const char* name,
1186 - const grub_env_whitelist_t* whitelist)
1190 - for (i = 0; i < whitelist->len; i++)
1191 - if (grub_strcmp (name, whitelist->list[i]) == 0)
1192 - return 1; /* found it */
1194 - return 0; /* not found */
1197 -/* Helper for grub_cmd_load_env. */
1199 -set_var (const char *name, const char *value, void *whitelist)
1203 - grub_env_set (name, value);
1207 - if (test_whitelist_membership (name,
1208 - (const grub_env_whitelist_t *) whitelist))
1209 - grub_env_set (name, value);
1215 grub_cmd_load_env (grub_extcmd_context_t ctxt, int argc, char **args)
1217 diff -urN grub-2.04.orig/grub-core/commands/loadenv.h grub-2.04/grub-core/commands/loadenv.h
1218 --- grub-2.04.orig/grub-core/commands/loadenv.h 1970-01-01 01:00:00.000000000 +0100
1219 +++ grub-2.04/grub-core/commands/loadenv.h 2019-08-18 16:14:44.724000000 +0200
1221 +/* loadenv.c - command to load/save environment variable. */
1223 + * GRUB -- GRand Unified Bootloader
1224 + * Copyright (C) 2008,2009,2010 Free Software Foundation, Inc.
1226 + * GRUB is free software: you can redistribute it and/or modify
1227 + * it under the terms of the GNU General Public License as published by
1228 + * the Free Software Foundation, either version 3 of the License, or
1229 + * (at your option) any later version.
1231 + * GRUB is distributed in the hope that it will be useful,
1232 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1233 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1234 + * GNU General Public License for more details.
1236 + * You should have received a copy of the GNU General Public License
1237 + * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
1240 +static grub_envblk_t UNUSED
1241 +read_envblk_file (grub_file_t file)
1243 + grub_off_t offset = 0;
1245 + grub_size_t size = grub_file_size (file);
1246 + grub_envblk_t envblk;
1248 + buf = grub_malloc (size);
1256 + ret = grub_file_read (file, buf + offset, size);
1267 + envblk = grub_envblk_open (buf, offset);
1271 + grub_error (GRUB_ERR_BAD_FILE_TYPE, "invalid environment block");
1278 +struct grub_env_whitelist
1283 +typedef struct grub_env_whitelist grub_env_whitelist_t;
1286 +test_whitelist_membership (const char* name,
1287 + const grub_env_whitelist_t* whitelist)
1291 + for (i = 0; i < whitelist->len; i++)
1292 + if (grub_strcmp (name, whitelist->list[i]) == 0)
1293 + return 1; /* found it */
1295 + return 0; /* not found */
1298 +/* Helper for grub_cmd_load_env. */
1300 +set_var (const char *name, const char *value, void *whitelist)
1304 + grub_env_set (name, value);
1308 + if (test_whitelist_membership (name,
1309 + (const grub_env_whitelist_t *) whitelist))
1310 + grub_env_set (name, value);
1314 diff -urN grub-2.04.orig/grub-core/commands/menuentry.c grub-2.04/grub-core/commands/menuentry.c
1315 --- grub-2.04.orig/grub-core/commands/menuentry.c 2018-11-24 18:13:02.000000000 +0100
1316 +++ grub-2.04/grub-core/commands/menuentry.c 2019-08-18 16:14:44.723000000 +0200
1318 char **classes, const char *id,
1319 const char *users, const char *hotkey,
1320 const char *prefix, const char *sourcecode,
1322 + int submenu, int *index, struct bls_entry *bls)
1324 int menu_hotkey = 0;
1325 char **menu_args = NULL;
1326 @@ -149,9 +149,12 @@
1330 + grub_dprintf ("menu", "id:\"%s\"\n", id);
1331 + grub_dprintf ("menu", "title:\"%s\"\n", menu_title);
1332 menu_id = grub_strdup (id ? : menu_title);
1335 + grub_dprintf ("menu", "menu_id:\"%s\"\n", menu_id);
1337 /* Save argc, args to pass as parameters to block arg later. */
1338 menu_args = grub_malloc (sizeof (char*) * (argc + 1));
1339 @@ -170,8 +173,12 @@
1342 /* Add the menu entry at the end of the list. */
1345 - last = &(*last)->next;
1348 + last = &(*last)->next;
1351 *last = grub_zalloc (sizeof (**last));
1353 @@ -188,8 +195,11 @@
1354 (*last)->args = menu_args;
1355 (*last)->sourcecode = menu_sourcecode;
1356 (*last)->submenu = submenu;
1357 + (*last)->bls = bls;
1362 return GRUB_ERR_NONE;
1367 ctxt->state[2].arg, 0,
1369 - ctxt->extcmd->cmd->name[0] == 's');
1370 + ctxt->extcmd->cmd->name[0] == 's',
1373 src = args[argc - 1];
1374 args[argc - 1] = NULL;
1376 ctxt->state[0].args, ctxt->state[4].arg,
1378 ctxt->state[2].arg, prefix, src + 1,
1379 - ctxt->extcmd->cmd->name[0] == 's');
1380 + ctxt->extcmd->cmd->name[0] == 's', NULL,
1384 args[argc - 1] = src;
1385 diff -urN grub-2.04.orig/grub-core/Makefile.core.def grub-2.04/grub-core/Makefile.core.def
1386 --- grub-2.04.orig/grub-core/Makefile.core.def 2019-04-23 10:54:47.000000000 +0200
1387 +++ grub-2.04/grub-core/Makefile.core.def 2019-08-18 16:14:44.723000000 +0200
1388 @@ -810,6 +810,16 @@
1393 + common = commands/blscfg.c;
1394 + common = commands/loadenv.h;
1395 + enable = powerpc_ieee1275;
1403 common = commands/boot.c;
1404 i386_pc = lib/i386/pc/biosnum.c;
1408 common = commands/loadenv.c;
1409 + common = commands/loadenv.h;
1410 common = lib/envblk.c;
1413 diff -urN grub-2.04.orig/grub-core/normal/main.c grub-2.04/grub-core/normal/main.c
1414 --- grub-2.04.orig/grub-core/normal/main.c 2018-11-24 18:13:02.000000000 +0100
1415 +++ grub-2.04/grub-core/normal/main.c 2019-08-18 16:14:44.724000000 +0200
1417 #include <grub/kernel.h>
1418 #include <grub/normal.h>
1419 #include <grub/dl.h>
1420 +#include <grub/menu.h>
1421 #include <grub/misc.h>
1422 #include <grub/file.h>
1423 #include <grub/mm.h>
1425 grub_free (entry->args);
1430 + entry->bls->visible = 0;
1433 grub_free ((void *) entry->id);
1434 grub_free ((void *) entry->users);
1435 grub_free ((void *) entry->title);
1436 diff -urN grub-2.04.orig/include/grub/compiler.h grub-2.04/include/grub/compiler.h
1437 --- grub-2.04.orig/include/grub/compiler.h 2018-11-24 18:13:02.000000000 +0100
1438 +++ grub-2.04/include/grub/compiler.h 2019-08-18 16:14:44.724000000 +0200
1440 # define WARN_UNUSED_RESULT
1443 +#define UNUSED __attribute__((__unused__))
1445 #endif /* ! GRUB_COMPILER_HEADER */
1446 diff -urN grub-2.04.orig/include/grub/menu.h grub-2.04/include/grub/menu.h
1447 --- grub-2.04.orig/include/grub/menu.h 2018-11-24 18:13:02.000000000 +0100
1448 +++ grub-2.04/include/grub/menu.h 2019-08-18 16:14:44.724000000 +0200
1450 #ifndef GRUB_MENU_HEADER
1451 #define GRUB_MENU_HEADER 1
1455 + struct bls_entry *next;
1456 + struct bls_entry *prev;
1457 + struct keyval **keyvals;
1463 struct grub_menu_entry_class
1468 /* The next element. */
1469 struct grub_menu_entry *next;
1471 + /* BLS used to populate the entry */
1472 + struct bls_entry *bls;
1474 typedef struct grub_menu_entry *grub_menu_entry_t;
1476 diff -urN grub-2.04.orig/include/grub/normal.h grub-2.04/include/grub/normal.h
1477 --- grub-2.04.orig/include/grub/normal.h 2018-11-24 18:13:02.000000000 +0100
1478 +++ grub-2.04/include/grub/normal.h 2019-08-18 16:14:44.724000000 +0200
1481 const char *users, const char *hotkey,
1482 const char *prefix, const char *sourcecode,
1484 + int submenu, int *index, struct bls_entry *bls);
1487 grub_normal_set_password (const char *user, const char *password);