normal/handler.c normal/auth.c normal/autofs.c \
normal/completion.c normal/main.c normal/color.c \
normal/menu.c normal/menu_entry.c normal/menu_viewer.c \
- normal/menu_text.c \
+ normal/menu_text.c normal/context.c \
script/main.c script/execute.c script/function.c \
script/lexer.c script/script.c grub_script.tab.c \
partmap/amiga.c partmap/apple.c partmap/msdos.c partmap/sun.c \
normal/auth.c normal/autofs.c normal/handler.c \
normal/color.c normal/completion.c normal/datetime.c normal/menu.c \
normal/menu_entry.c normal/menu_text.c normal/menu_viewer.c \
- normal/misc.c
+ normal/misc.c normal/context.c
normal_mod_CFLAGS = $(COMMON_CFLAGS)
normal_mod_LDFLAGS = $(COMMON_LDFLAGS)
env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \
partition.h msdos_partition.h reader.h symbol.h term.h time.h types.h \
machine/boot.h machine/console.h machine/init.h \
- machine/memory.h machine/loader.h list.h handler.h command.h i18n.h
+ machine/memory.h machine/loader.h list.h handler.h command.h i18n.h \
+ env_private.h
kernel_img_CFLAGS = $(COMMON_CFLAGS)
kernel_img_ASFLAGS = $(COMMON_ASFLAGS)
kernel_img_LDFLAGS = $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,$(GRUB_KERNEL_MACHINE_LINK_ADDR),-Bstatic
kernel_img_HEADERS = boot.h cache.h device.h disk.h dl.h elf.h elfload.h \
env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \
partition.h msdos_partition.h reader.h symbol.h term.h time.h types.h \
- efi/efi.h efi/time.h efi/disk.h i386/pit.h list.h handler.h command.h i18n.h
+ efi/efi.h efi/time.h efi/disk.h i386/pit.h list.h handler.h command.h \
+ i18n.h env_private.h
kernel_img_CFLAGS = $(COMMON_CFLAGS)
kernel_img_ASFLAGS = $(COMMON_ASFLAGS)
kernel_img_LDFLAGS = $(COMMON_LDFLAGS)
env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \
partition.h msdos_partition.h reader.h symbol.h term.h time.h types.h \
ieee1275/ieee1275.h machine/kernel.h machine/loader.h machine/memory.h \
- list.h handler.h command.h i18n.h
+ list.h handler.h command.h i18n.h env_private.h
kernel_img_CFLAGS = $(COMMON_CFLAGS)
kernel_img_ASFLAGS = $(COMMON_ASFLAGS)
kernel_img_LDFLAGS = $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,0x10000,-Bstatic
partition.h msdos_partition.h reader.h symbol.h term.h time.h types.h \
machine/biosdisk.h machine/boot.h machine/console.h machine/init.h \
machine/memory.h machine/loader.h machine/vga.h machine/vbe.h \
- machine/kernel.h machine/pxe.h i386/pit.h list.h handler.h command.h i18n.h
+ machine/kernel.h machine/pxe.h i386/pit.h list.h handler.h command.h \
+ i18n.h env_private.h
kernel_img_CFLAGS = $(COMMON_CFLAGS) $(TARGET_IMG_CFLAGS)
kernel_img_ASFLAGS = $(COMMON_ASFLAGS)
kernel_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)$(GRUB_KERNEL_MACHINE_LINK_ADDR) $(COMMON_CFLAGS)
env.h err.h file.h fs.h kernel.h misc.h mm.h net.h parser.h reader.h \
symbol.h term.h time.h types.h powerpc/libgcc.h loader.h partition.h \
msdos_partition.h ieee1275/ieee1275.h machine/kernel.h handler.h list.h \
- command.h i18n.h
+ command.h i18n.h env_private.h
symlist.c: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h gensymlist.sh
/bin/sh gensymlist.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1)
partition.h msdos_partition.h reader.h symbol.h term.h time.h types.h \
list.h handler.h command.h i18n.h \
sparc64/libgcc.h ieee1275/ieee1275.h machine/kernel.h \
- sparc64/ieee1275/ieee1275.h
+ sparc64/ieee1275/ieee1275.h env_private.h
kernel_img_SOURCES = kern/sparc64/ieee1275/crt0.S kern/ieee1275/cmain.c \
kern/ieee1275/ieee1275.c kern/main.c kern/device.c \
kern/disk.c kern/dl.c kern/err.c kern/file.c kern/fs.c \
env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \
partition.h msdos_partition.h reader.h symbol.h term.h time.h types.h \
efi/efi.h efi/time.h efi/disk.h machine/loader.h i386/pit.h list.h \
- handler.h command.h i18n.h
+ handler.h command.h i18n.h env_private.h
kernel_img_CFLAGS = $(COMMON_CFLAGS)
kernel_img_ASFLAGS = $(COMMON_ASFLAGS)
kernel_img_LDFLAGS = $(COMMON_LDFLAGS)
#include <grub/symbol.h>
#include <grub/err.h>
#include <grub/types.h>
+#include <grub/menu.h>
struct grub_env_var;
typedef char *(*grub_env_write_hook_t) (struct grub_env_var *var,
const char *val);
-enum grub_env_var_type
- {
- /* The default variable type which is local in current context. */
- GRUB_ENV_VAR_LOCAL,
-
- /* The exported type, which is passed to new contexts. */
- GRUB_ENV_VAR_GLOBAL,
-
- /* The data slot type, which is used to store arbitrary data. */
- GRUB_ENV_VAR_DATA
- };
-
struct grub_env_var
{
char *name;
grub_env_write_hook_t write_hook;
struct grub_env_var *next;
struct grub_env_var **prevp;
- enum grub_env_var_type type;
+ int global;
};
grub_err_t EXPORT_FUNC(grub_env_set) (const char *name, const char *val);
char *EXPORT_FUNC(grub_env_get) (const char *name);
void EXPORT_FUNC(grub_env_unset) (const char *name);
void EXPORT_FUNC(grub_env_iterate) (int (*func) (struct grub_env_var *var));
+struct grub_env_var *EXPORT_FUNC(grub_env_find) (const char *name);
grub_err_t EXPORT_FUNC(grub_register_variable_hook) (const char *name,
grub_env_read_hook_t read_hook,
grub_env_write_hook_t write_hook);
-grub_err_t EXPORT_FUNC(grub_env_context_open) (int export);
-grub_err_t EXPORT_FUNC(grub_env_context_close) (void);
-grub_err_t EXPORT_FUNC(grub_env_export) (const char *name);
-grub_err_t EXPORT_FUNC(grub_env_set_data_slot) (const char *name,
- const void *ptr);
-void *EXPORT_FUNC(grub_env_get_data_slot) (const char *name);
-void EXPORT_FUNC(grub_env_unset_data_slot) (const char *name);
+grub_err_t grub_env_context_open (int export);
+grub_err_t grub_env_context_close (void);
+grub_err_t grub_env_export (const char *name);
+
+void grub_env_unset_menu (void);
+grub_menu_t grub_env_get_menu (void);
+void grub_env_set_menu (grub_menu_t nmenu);
#endif /* ! GRUB_ENV_HEADER */
--- /dev/null
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2003,2005,2006,2007,2009 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_ENV_PRIVATE_HEADER
+#define GRUB_ENV_PRIVATE_HEADER 1
+
+#include <grub/env.h>
+
+/* The size of the hash table. */
+#define HASHSZ 13
+
+/* A hashtable for quick lookup of variables. */
+struct grub_env_context
+{
+ /* A hash table for variables. */
+ struct grub_env_var *vars[HASHSZ];
+
+ /* One level deeper on the stack. */
+ struct grub_env_context *prev;
+};
+
+/* This is used for sorting only. */
+struct grub_env_sorted_var
+{
+ struct grub_env_var *var;
+ struct grub_env_sorted_var *next;
+};
+
+extern struct grub_env_context *EXPORT_VAR(grub_current_context);
+
+#endif /* ! GRUB_ENV_PRIVATE_HEADER */
/* Defined in `autofs.c'. */
void read_fs_list (void);
+void grub_context_init (void);
+void grub_context_fini (void);
#ifdef GRUB_UTIL
void grub_normal_init (void);
return 0;
}
-static grub_err_t
-grub_core_cmd_export (struct grub_command *cmd __attribute__ ((unused)),
- int argc, char **args)
-{
- if (argc < 1)
- return grub_error (GRUB_ERR_BAD_ARGUMENT,
- "no environment variable specified");
-
- grub_env_export (args[0]);
- return 0;
-}
-
/* insmod MODULE */
static grub_err_t
grub_core_cmd_insmod (struct grub_command *cmd __attribute__ ((unused)),
"set [ENVVAR=VALUE]", "set an environment variable");
grub_register_command ("unset", grub_core_cmd_unset,
"unset ENVVAR", "remove an environment variable");
- grub_register_command ("export", grub_core_cmd_export,
- "export ENVVAR", "Export a variable.");
grub_register_command ("ls", grub_core_cmd_ls,
"ls [ARG]", "list devices or files");
grub_register_command ("insmod", grub_core_cmd_insmod,
*/
#include <grub/env.h>
+#include <grub/env_private.h>
#include <grub/misc.h>
#include <grub/mm.h>
-/* The size of the hash table. */
-#define HASHSZ 13
-
-/* A hashtable for quick lookup of variables. */
-struct grub_env_context
-{
- /* A hash table for variables. */
- struct grub_env_var *vars[HASHSZ];
-
- /* One level deeper on the stack. */
- struct grub_env_context *prev;
-};
-
-/* This is used for sorting only. */
-struct grub_env_sorted_var
-{
- struct grub_env_var *var;
- struct grub_env_sorted_var *next;
-};
-
/* The initial context. */
static struct grub_env_context initial_context;
/* The current context. */
-static struct grub_env_context *current_context = &initial_context;
+struct grub_env_context *grub_current_context = &initial_context;
/* Return the hash representation of the string S. */
static unsigned int
return i % HASHSZ;
}
-static struct grub_env_var *
+struct grub_env_var *
grub_env_find (const char *name)
{
struct grub_env_var *var;
int idx = grub_env_hashval (name);
/* Look for the variable in the current context. */
- for (var = current_context->vars[idx]; var; var = var->next)
+ for (var = grub_current_context->vars[idx]; var; var = var->next)
if (grub_strcmp (var->name, name) == 0)
return var;
return 0;
}
-grub_err_t
-grub_env_context_open (int export)
-{
- struct grub_env_context *context;
- int i;
-
- context = grub_zalloc (sizeof (*context));
- if (! context)
- return grub_errno;
-
- context->prev = current_context;
- current_context = context;
-
- /* 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 (export && var->type == GRUB_ENV_VAR_GLOBAL)
- {
- if (grub_env_set (var->name, var->value) != GRUB_ERR_NONE)
- {
- grub_env_context_close ();
- return grub_errno;
- }
- grub_register_variable_hook (var->name, var->read_hook, var->write_hook);
- }
- }
- }
-
- return GRUB_ERR_NONE;
-}
-
-grub_err_t
-grub_env_context_close (void)
-{
- struct grub_env_context *context;
- int i;
-
- if (! current_context->prev)
- grub_fatal ("cannot close the initial context");
-
- /* Free the variables associated with this context. */
- for (i = 0; i < HASHSZ; i++)
- {
- struct grub_env_var *p, *q;
-
- for (p = current_context->vars[i]; p; p = q)
- {
- q = p->next;
- grub_free (p->name);
- if (p->type != GRUB_ENV_VAR_DATA)
- grub_free (p->value);
- grub_free (p);
- }
- }
-
- /* Restore the previous context. */
- context = current_context->prev;
- grub_free (current_context);
- current_context = context;
-
- return GRUB_ERR_NONE;
-}
-
static void
grub_env_insert (struct grub_env_context *context,
struct grub_env_var *var)
var->next->prevp = var->prevp;
}
-grub_err_t
-grub_env_export (const char *name)
-{
- struct grub_env_var *var;
-
- var = grub_env_find (name);
- if (var)
- var->type = GRUB_ENV_VAR_GLOBAL;
-
- return GRUB_ERR_NONE;
-}
-
grub_err_t
grub_env_set (const char *name, const char *val)
{
if (! var)
return grub_errno;
- /* This is not necessary, because GRUB_ENV_VAR_LOCAL == 0. But leave
- this for readability. */
- var->type = GRUB_ENV_VAR_LOCAL;
+ /* This is not necessary. But leave this for readability. */
+ var->global = 0;
var->name = grub_strdup (name);
if (! var->name)
if (! var->value)
goto fail;
- grub_env_insert (current_context, var);
+ grub_env_insert (grub_current_context, var);
return GRUB_ERR_NONE;
grub_env_remove (var);
grub_free (var->name);
- if (var->type != GRUB_ENV_VAR_DATA)
- grub_free (var->value);
+ grub_free (var->value);
grub_free (var);
}
{
struct grub_env_var *var;
- for (var = current_context->vars[i]; var; var = var->next)
+ for (var = grub_current_context->vars[i]; var; var = var->next)
{
struct grub_env_sorted_var *p, **q;
- /* Ignore data slots. */
- if (var->type == GRUB_ENV_VAR_DATA)
- continue;
-
sorted_var = grub_malloc (sizeof (*sorted_var));
if (! sorted_var)
goto fail;
return GRUB_ERR_NONE;
}
-
-static char *
-mangle_data_slot_name (const char *name)
-{
- char *mangled_name;
-
- mangled_name = grub_malloc (grub_strlen (name) + 2);
- if (! mangled_name)
- return 0;
-
- grub_sprintf (mangled_name, "\e%s", name);
- return mangled_name;
-}
-
-grub_err_t
-grub_env_set_data_slot (const char *name, const void *ptr)
-{
- char *mangled_name;
- struct grub_env_var *var;
-
- mangled_name = mangle_data_slot_name (name);
- if (! mangled_name)
- goto fail;
-
- /* If the variable does already exist, just update the variable. */
- var = grub_env_find (mangled_name);
- if (var)
- {
- var->value = (char *) ptr;
- return GRUB_ERR_NONE;
- }
-
- /* The variable does not exist, so create a new one. */
- var = grub_zalloc (sizeof (*var));
- if (! var)
- goto fail;
-
- var->type = GRUB_ENV_VAR_DATA;
- var->name = mangled_name;
- var->value = (char *) ptr;
-
- grub_env_insert (current_context, var);
-
- return GRUB_ERR_NONE;
-
- fail:
-
- grub_free (mangled_name);
- return grub_errno;
-}
-
-void *
-grub_env_get_data_slot (const char *name)
-{
- char *mangled_name;
- void *ptr = 0;
-
- mangled_name = mangle_data_slot_name (name);
- if (! mangled_name)
- goto fail;
-
- ptr = grub_env_get (mangled_name);
- grub_free (mangled_name);
-
- fail:
-
- return ptr;
-}
-
-void
-grub_env_unset_data_slot (const char *name)
-{
- char *mangled_name;
-
- mangled_name = mangle_data_slot_name (name);
- if (! mangled_name)
- return;
-
- grub_env_unset (mangled_name);
- grub_free (mangled_name);
-}
const char *prefix;
grub_register_variable_hook ("root", 0, grub_env_write_root);
- grub_env_export ("root");
prefix = grub_env_get ("prefix");
/* It is better to set the root device as soon as possible,
for convenience. */
grub_machine_set_prefix ();
- grub_env_export ("prefix");
grub_set_root_dev ();
grub_register_core_commands ();
--- /dev/null
+/* env.c - Environment variables */
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2003,2005,2006,2007,2008,2009 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/env.h>
+#include <grub/env_private.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/command.h>
+
+struct menu_pointer
+{
+ grub_menu_t menu;
+ struct menu_pointer *prev;
+};
+
+struct menu_pointer initial_menu;
+struct menu_pointer *current_menu = &initial_menu;
+
+void
+grub_env_unset_menu (void)
+{
+ current_menu->menu = NULL;
+}
+
+grub_menu_t
+grub_env_get_menu (void)
+{
+ return current_menu->menu;
+}
+
+void
+grub_env_set_menu (grub_menu_t nmenu)
+{
+ current_menu->menu = nmenu;
+}
+
+grub_err_t
+grub_env_context_open (int export)
+{
+ 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)
+ 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 (export && var->global)
+ {
+ if (grub_env_set (var->name, var->value) != GRUB_ERR_NONE)
+ {
+ grub_env_context_close ();
+ return grub_errno;
+ }
+ grub_register_variable_hook (var->name, var->read_hook, var->write_hook);
+ }
+ }
+ }
+
+ return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_env_context_close (void)
+{
+ struct grub_env_context *context;
+ int i;
+ struct menu_pointer *menu;
+
+ if (! grub_current_context->prev)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
+ "cannot close the initial context");
+
+ /* Free the variables associated with this context. */
+ for (i = 0; i < HASHSZ; i++)
+ {
+ struct grub_env_var *p, *q;
+
+ for (p = grub_current_context->vars[i]; p; p = q)
+ {
+ q = p->next;
+ grub_free (p->name);
+ grub_free (p->value);
+ grub_free (p);
+ }
+ }
+
+ /* Restore the previous context. */
+ context = grub_current_context->prev;
+ grub_free (grub_current_context);
+ grub_current_context = context;
+
+ menu = current_menu->prev;
+ grub_free (current_menu);
+ current_menu = menu;
+
+ return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_env_export (const char *name)
+{
+ struct grub_env_var *var;
+
+ var = grub_env_find (name);
+ if (var)
+ var->global = 1;
+
+ return GRUB_ERR_NONE;
+}
+
+static grub_command_t export_cmd;
+
+static grub_err_t
+grub_cmd_export (struct grub_command *cmd __attribute__ ((unused)),
+ int argc, char **args)
+{
+ if (argc < 1)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
+ "no environment variable specified");
+
+ grub_env_export (args[0]);
+ return 0;
+}
+
+void
+grub_context_init (void)
+{
+ grub_env_export ("root");
+ grub_env_export ("prefix");
+
+ export_cmd = grub_register_command ("export", grub_cmd_export,
+ "export ENVVAR", "Export a variable.");
+}
+
+void
+grub_context_fini (void)
+{
+ grub_unregister_command (export_cmd);
+}
}
grub_free (menu);
- grub_env_unset_data_slot ("menu");
+ grub_env_unset_menu ();
}
static void
return grub_errno;
classes_tail = classes_head;
- menu = grub_env_get_data_slot ("menu");
+ menu = grub_env_get_menu ();
if (! menu)
return grub_error (GRUB_ERR_MENU, "no menu context");
grub_menu_t newmenu;
- newmenu = grub_env_get_data_slot ("menu");
+ newmenu = grub_env_get_menu ();
if (! newmenu)
{
newmenu = grub_zalloc (sizeof (*newmenu));
if (! newmenu)
return 0;
- grub_env_set_data_slot ("menu", newmenu);
+ grub_env_set_menu (newmenu);
}
/* Try to open the config file. */
GRUB_MOD_INIT(normal)
{
+ grub_context_init ();
+
/* Normal mode shouldn't be unloaded. */
if (mod)
grub_dl_ref (mod);
GRUB_MOD_FINI(normal)
{
+ grub_context_fini ();
+
grub_set_history (0);
grub_reader_unregister (&grub_normal_reader);
grub_register_variable_hook ("pager", 0, 0);