static grub_err_t grub_cmd_source (grub_command_t cmd, int argc, char **args) { int new_env, extractor; if (argc != 1) return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); extractor = (cmd->name[0] == 'e'); new_env = (cmd->name[extractor ? sizeof ("extract_entries_") - 1 : 0] == 'c'); if (new_env) grub_cls (); if (new_env && !extractor) grub_env_context_open (); if (extractor) grub_env_extractor_open (!new_env); grub_normal_execute (args[0], 1, ! new_env); if (new_env && !extractor) grub_env_context_close (); if (extractor) grub_env_extractor_close (!new_env); return 0; }
grub_err_t grub_env_extractor_close (int source) { grub_menu_t menu = NULL; grub_menu_entry_t *last; grub_err_t err; if (source) { menu = grub_env_get_menu (); grub_env_unset_menu (); } err = grub_env_context_close (); if (source && menu) { grub_menu_t menu2; menu2 = grub_env_get_menu (); last = &menu2->entry_list; while (*last) last = &(*last)->next; *last = menu->entry_list; menu2->size += menu->size; } grub_extractor_level--; return err; }
static grub_err_t grub_env_new_context (int export_all) { struct grub_env_context *context; int i; struct menu_pointer *menu; context = grub_zalloc (sizeof (*context)); if (! context) return grub_errno; menu = grub_zalloc (sizeof (*menu)); if (! menu) { grub_free (context); return grub_errno; } context->prev = grub_current_context; grub_current_context = context; menu->prev = current_menu; current_menu = menu; /* Copy exported variables. */ for (i = 0; i < HASHSZ; i++) { struct grub_env_var *var; for (var = context->prev->vars[i]; var; var = var->next) if (var->global || export_all) { if (grub_env_set (var->name, var->value) != GRUB_ERR_NONE) { grub_env_context_close (); return grub_errno; } grub_env_export (var->name); grub_register_variable_hook (var->name, var->read_hook, var->write_hook); } } return GRUB_ERR_NONE; }
static grub_err_t grub_cmd_source (grub_command_t cmd, int argc, char **args) { int new_env; if (argc != 1) return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required"); new_env = (cmd->name[0] == 'c'); if (new_env) { grub_cls (); grub_env_context_open (1); } grub_normal_execute (args[0], 1, ! new_env); if (new_env) grub_env_context_close (); return 0; }
/* Run a menu entry. */ static void grub_menu_execute_entry(grub_menu_entry_t entry, int auto_boot) { grub_err_t err = GRUB_ERR_NONE; int errs_before; grub_menu_t menu = NULL; char *optr, *buf, *oldchosen = NULL, *olddefault = NULL; const char *ptr, *chosen, *def; grub_size_t sz = 0; if (entry->restricted) err = grub_auth_check_authentication (entry->users); if (err) { grub_print_error (); grub_errno = GRUB_ERR_NONE; return; } errs_before = grub_err_printed_errors; chosen = grub_env_get ("chosen"); def = grub_env_get ("default"); if (entry->submenu) { grub_env_context_open (); menu = grub_zalloc (sizeof (*menu)); if (! menu) return; grub_env_set_menu (menu); if (auto_boot) grub_env_set ("timeout", "0"); } for (ptr = entry->id; *ptr; ptr++) sz += (*ptr == '>') ? 2 : 1; if (chosen) { oldchosen = grub_strdup (chosen); if (!oldchosen) grub_print_error (); } if (def) { olddefault = grub_strdup (def); if (!olddefault) grub_print_error (); } sz++; if (chosen) sz += grub_strlen (chosen); sz++; buf = grub_malloc (sz); if (!buf) grub_print_error (); else { optr = buf; if (chosen) { optr = grub_stpcpy (optr, chosen); *optr++ = '>'; } for (ptr = entry->id; *ptr; ptr++) { if (*ptr == '>') *optr++ = '>'; *optr++ = *ptr; } *optr = 0; grub_env_set ("chosen", buf); grub_env_export ("chosen"); grub_free (buf); } for (ptr = def; ptr && *ptr; ptr++) { if (ptr[0] == '>' && ptr[1] == '>') { ptr++; continue; } if (ptr[0] == '>') break; } if (ptr && ptr[0] && ptr[1]) grub_env_set ("default", ptr + 1); else grub_env_unset ("default"); grub_script_execute_sourcecode (entry->sourcecode, entry->argc, entry->args); if (errs_before != grub_err_printed_errors) grub_wait_after_message (); if (grub_errno == GRUB_ERR_NONE && grub_loader_is_loaded ()) /* Implicit execution of boot, only if something is loaded. */ grub_command_execute ("boot", 0, 0); if (entry->submenu) { if (menu && menu->size) { grub_show_menu (menu, 1, auto_boot); grub_normal_free_menu (menu); } grub_env_context_close (); } if (oldchosen) grub_env_set ("chosen", oldchosen); else grub_env_unset ("chosen"); if (olddefault) grub_env_set ("default", olddefault); else grub_env_unset ("default"); grub_env_unset ("timeout"); }