diff --git a/grub-core/commands/legacycfg.c b/grub-core/commands/legacycfg.c index aeff78b8a..82901b0e7 100644 --- a/grub-core/commands/legacycfg.c +++ b/grub-core/commands/legacycfg.c @@ -37,6 +37,18 @@ legacy_file (const char *filename) grub_file_t file; char *entryname = NULL, *entrysrc = NULL; grub_menu_t menu; + char *suffix = grub_strdup (""); + + auto grub_err_t getline (char **line, int cont); + grub_err_t getline (char **line, + int cont __attribute__ ((unused))) + { + *line = 0; + return GRUB_ERR_NONE; + } + + if (!suffix) + return grub_errno; file = grub_file_open (filename); if (! file) @@ -68,10 +80,32 @@ legacy_file (const char *filename) { char *oldname = NULL; + int is_suffix; oldname = entryname; - parsed = grub_legacy_parse (buf, &entryname); + parsed = grub_legacy_parse (buf, &entryname, &is_suffix); grub_free (buf); + if (is_suffix) + { + char *t; + + t = suffix; + suffix = grub_realloc (suffix, grub_strlen (suffix) + + grub_strlen (parsed) + 1); + if (!suffix) + { + grub_free (t); + grub_free (entrysrc); + grub_free (parsed); + grub_free (suffix); + return grub_errno; + } + grub_memcpy (entrysrc + grub_strlen (entrysrc), parsed, + grub_strlen (parsed) + 1); + grub_free (parsed); + parsed = NULL; + continue; + } if (oldname != entryname && oldname) { const char **args = grub_malloc (sizeof (args[0])); @@ -88,13 +122,6 @@ legacy_file (const char *filename) if (parsed && !entryname) { - auto grub_err_t getline (char **line, int cont); - grub_err_t getline (char **line __attribute__ ((unused)), - int cont __attribute__ ((unused))) - { - return GRUB_ERR_NONE; - } - grub_normal_parse_line (parsed, getline); grub_print_error (); grub_free (parsed); @@ -114,6 +141,7 @@ legacy_file (const char *filename) { grub_free (t); grub_free (parsed); + grub_free (suffix); return grub_errno; } grub_memcpy (entrysrc + grub_strlen (entrysrc), parsed, @@ -137,6 +165,10 @@ legacy_file (const char *filename) grub_normal_add_menu_entry (1, args, NULL, NULL, NULL, NULL, entrysrc); } + grub_normal_parse_line (suffix, getline); + grub_print_error (); + grub_free (suffix); + if (menu && menu->size) grub_show_menu (menu, 1); diff --git a/grub-core/lib/legacy_parse.c b/grub-core/lib/legacy_parse.c index 671d0f3f8..3800d6ca5 100644 --- a/grub-core/lib/legacy_parse.c +++ b/grub-core/lib/legacy_parse.c @@ -41,7 +41,8 @@ struct legacy_command TYPE_REST_VERBATIM } argt[4]; enum { - FLAG_IGNORE_REST = 1 + FLAG_IGNORE_REST = 1, + FLAG_SUFFIX = 2 } flags; const char *shortdesc; const char *longdesc; @@ -108,7 +109,8 @@ struct legacy_command legacy_commands[] = "Halt your system. If APM is available on it, turn off the power using" " the APM BIOS, unless you specify the option `--no-apm'."}, /* FIXME: help unsupported. */ /* NUL_TERMINATE */ - /* FIXME: hiddenmenu unsupported. */ + {"hiddenmenu", "if sleep -i $timeout; then timeout=0; else timeout=-1; fi\n", + 0, {}, FLAG_SUFFIX, "", "Hide the menu."}, {"hide", "parttool '%s' hidden+\n", 1, {TYPE_PARTITION}, 0, "PARTITION", "Hide PARTITION by setting the \"hidden\" bit in" " its partition type code."}, @@ -354,12 +356,14 @@ is_option (enum arg_type opt, const char *curarg, grub_size_t len) } char * -grub_legacy_parse (const char *buf, char **entryname) +grub_legacy_parse (const char *buf, char **entryname, int *suffix) { const char *ptr; const char *cmdname; unsigned i, cmdnum; + *suffix = 0; + for (ptr = buf; *ptr && grub_isspace (*ptr); ptr++); if (!*ptr || *ptr == '#') return grub_strdup (buf); @@ -392,6 +396,8 @@ grub_legacy_parse (const char *buf, char **entryname) if (cmdnum == ARRAY_SIZE (legacy_commands)) return grub_xasprintf ("# Unsupported legacy command: %s\n", buf); + *suffix = !!(legacy_commands[cmdnum].flags & FLAG_SUFFIX); + for (; grub_isspace (*ptr) || *ptr == '='; ptr++); char *args[ARRAY_SIZE (legacy_commands[0].argt)]; diff --git a/include/grub/legacy_parse.h b/include/grub/legacy_parse.h index fce4e3e40..a6394496f 100644 --- a/include/grub/legacy_parse.h +++ b/include/grub/legacy_parse.h @@ -21,7 +21,7 @@ #include -char *grub_legacy_parse (const char *buf, char **entryname); +char *grub_legacy_parse (const char *buf, char **entryname, int *suffix); char *grub_legacy_escape (const char *in, grub_size_t len); #endif diff --git a/util/grub-menulst2cfg.c b/util/grub-menulst2cfg.c index 89b792e9a..0184b3fe3 100644 --- a/util/grub-menulst2cfg.c +++ b/util/grub-menulst2cfg.c @@ -28,6 +28,9 @@ main (int argc, char **argv) char *entryname = NULL; char *buf = NULL; size_t bufsize = 0; + char *suffix = xstrdup (""); + int suffixlen = 0; + int is_suffix = 0; if (argc >= 2 && argv[1][0] == '-') { @@ -74,7 +77,14 @@ main (int argc, char **argv) char *oldname = NULL; oldname = entryname; - parsed = grub_legacy_parse (buf, &entryname); + parsed = grub_legacy_parse (buf, &entryname, &is_suffix); + if (is_suffix) + { + suffixlen += strlen (parsed); + suffix = xrealloc (suffix, suffixlen + 1); + strcat (suffix, parsed); + continue; + } if (oldname != entryname && oldname) fprintf (out, "}\n\n"); if (oldname != entryname) @@ -89,6 +99,7 @@ main (int argc, char **argv) if (entryname) fprintf (out, "}\n\n"); + fwrite (out, 1, suffixlen, suffix); if (in != stdin) fclose (in);