X-Git-Url: http://git.ozlabs.org/?p=petitboot;a=blobdiff_plain;f=discover%2Fgrub2-parser.c;h=630ea332bdac14368a1c60be892bb068369bbffe;hp=a2308ee687d9ed99ba9190f6d4f80b527c6f43a8;hb=6505dbd5abb00936c3e53b54f97f8aa628699e59;hpb=70ad7ba01b43404585c76512bffe99ede0c0f55a diff --git a/discover/grub2-parser.c b/discover/grub2-parser.c index a2308ee..630ea33 100644 --- a/discover/grub2-parser.c +++ b/discover/grub2-parser.c @@ -39,6 +39,8 @@ struct grub2_root { struct grub2_state { struct discover_boot_option *opt; + int default_idx; + int cur_idx; char *desc_image; char *desc_initrd; const char *const *known_names; @@ -94,6 +96,13 @@ static bool resolve_grub2_resource(struct device_handler *handler, return true; } +static bool current_option_is_default(struct grub2_state *state) +{ + if (state->default_idx < 0) + return false; + return state->cur_idx == state->default_idx; +} + static void grub2_finish(struct conf_context *conf) { struct device *dev = conf->dc->device->device; @@ -123,11 +132,12 @@ static void grub2_finish(struct conf_context *conf) conf_strip_str(opt->boot_args); conf_strip_str(opt->description); - /* opt is persistent, so must be associated with device */ + state->opt->option->is_default = current_option_is_default(state); discover_context_add_boot_option(conf->dc, state->opt); state->opt = NULL; + state->cur_idx++; } static void grub2_process_pair(struct conf_context *conf, const char *name, @@ -141,8 +151,6 @@ static void grub2_process_pair(struct conf_context *conf, const char *name, return; if (streq(name, "menuentry")) { - char *sep; - /* complete any existing option... */ if (state->opt) grub2_finish(conf); @@ -151,10 +159,7 @@ static void grub2_process_pair(struct conf_context *conf, const char *name, opt = discover_boot_option_create(conf->dc, conf->dc->device); opt->option->boot_args = talloc_strdup(opt->option, ""); - sep = strchr(value, '\''); - - if (sep) - *sep = 0; + value = strtok(value, "\'{\""); opt->option->id = talloc_asprintf(opt->option, "%s#%s", dev->id, value); @@ -166,7 +171,7 @@ static void grub2_process_pair(struct conf_context *conf, const char *name, return; } - if (streq(name, "linux")) { + if (streq(name, "linux") || streq(name, "linux16")) { char *sep; sep = strchr(value, ' '); @@ -210,7 +215,6 @@ static void grub2_process_pair(struct conf_context *conf, const char *name, return; uuid++; - pb_log("%s: uuid %s\n", __func__, uuid); if (state->root) talloc_unlink(state, state->root); @@ -221,6 +225,32 @@ static void grub2_process_pair(struct conf_context *conf, const char *name, return; } + if (streq(name, "set")) { + char *sep, *var_name, *var_value; + + /* this is pretty nasty, but works until we implement a proper + * parser... */ + + sep = strchr(value, '='); + if (!sep) + return; + + *sep = '\0'; + + var_name = value; + var_value = sep + 1; + if (var_value[0] == '"' || var_value[0] == '\'') + var_value++; + + if (!strlen(var_name) || !strlen(var_value)) + return; + + if (streq(var_name, "default")) + state->default_idx = atoi(var_value); + + return; + } + pb_log("%s: unknown name: %s\n", __func__, name); } @@ -231,6 +261,7 @@ static const char *const grub2_conf_files[] = { "/grub2/grub.cfg", "/grub/menu.lst", "/boot/grub/grub.cfg", + "/boot/grub2/grub.cfg", "/boot/grub/menu.lst", "/GRUB.CFG", "/MENU.LST", @@ -245,8 +276,10 @@ static const char *const grub2_conf_files[] = { static const char *grub2_known_names[] = { "menuentry", "linux", + "linux16", "initrd", "search", + "set", NULL }; @@ -268,6 +301,7 @@ static int grub2_parse(struct discover_context *dc, char *buf, int len) conf->parser_info = state = talloc_zero(conf, struct grub2_state); state->known_names = grub2_known_names; + state->default_idx = -1; conf_parse_buf(conf, buf, len);