1 /* env.c - Environment variables */
3 * GRUB -- GRand Unified Bootloader
4 * Copyright (C) 2003,2005,2006,2007,2008,2009 Free Software Foundation, Inc.
6 * GRUB is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * GRUB is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
21 #include <grub/env_private.h>
22 #include <grub/misc.h>
25 /* The initial context. */
26 static struct grub_env_context initial_context
;
28 /* The current context. */
29 struct grub_env_context
*grub_current_context
= &initial_context
;
31 static grub_env_read_hook_t vtoy_menu_lang_read_hook
;
33 /* Return the hash representation of the string S. */
35 grub_env_hashval (const char *s
)
39 /* XXX: This can be done much more efficiently. */
46 static struct grub_env_var
*
47 grub_env_find (const char *name
)
49 struct grub_env_var
*var
;
50 int idx
= grub_env_hashval (name
);
52 /* Look for the variable in the current context. */
53 for (var
= grub_current_context
->vars
[idx
]; var
; var
= var
->next
)
54 if (grub_strcmp (var
->name
, name
) == 0)
61 grub_env_insert (struct grub_env_context
*context
,
62 struct grub_env_var
*var
)
64 int idx
= grub_env_hashval (var
->name
);
66 /* Insert the variable into the hashtable. */
67 var
->prevp
= &context
->vars
[idx
];
68 var
->next
= context
->vars
[idx
];
70 var
->next
->prevp
= &(var
->next
);
71 context
->vars
[idx
] = var
;
75 grub_env_remove (struct grub_env_var
*var
)
77 /* Remove the entry from the variable table. */
78 *var
->prevp
= var
->next
;
80 var
->next
->prevp
= var
->prevp
;
84 grub_env_set (const char *name
, const char *val
)
86 struct grub_env_var
*var
;
88 /* If the variable does already exist, just update the variable. */
89 var
= grub_env_find (name
);
92 char *old
= var
->value
;
95 var
->value
= var
->write_hook (var
, val
);
97 var
->value
= grub_strdup (val
);
106 return GRUB_ERR_NONE
;
109 /* The variable does not exist, so create a new one. */
110 var
= grub_zalloc (sizeof (*var
));
114 var
->name
= grub_strdup (name
);
118 var
->value
= grub_strdup (val
);
122 grub_env_insert (grub_current_context
, var
);
124 return GRUB_ERR_NONE
;
127 grub_free (var
->name
);
128 grub_free (var
->value
);
135 grub_env_get (const char *name
)
137 struct grub_env_var
*var
;
139 if (name
&& vtoy_menu_lang_read_hook
&& grub_strncmp(name
, "VTLANG_", 7) == 0)
140 return vtoy_menu_lang_read_hook(NULL
, name
);
142 var
= grub_env_find (name
);
147 return var
->read_hook (var
, var
->value
);
153 grub_env_unset (const char *name
)
155 struct grub_env_var
*var
;
157 var
= grub_env_find (name
);
161 if (var
->read_hook
|| var
->write_hook
)
163 grub_env_set (name
, "");
167 grub_env_remove (var
);
169 grub_free (var
->name
);
170 grub_free (var
->value
);
174 struct grub_env_var
*
175 grub_env_update_get_sorted (void)
177 struct grub_env_var
*sorted_list
= 0;
180 /* Add variables associated with this context into a sorted list. */
181 for (i
= 0; i
< HASHSZ
; i
++)
183 struct grub_env_var
*var
;
185 for (var
= grub_current_context
->vars
[i
]; var
; var
= var
->next
)
187 struct grub_env_var
*p
, **q
;
189 for (q
= &sorted_list
, p
= *q
; p
; q
= &((*q
)->sorted_next
), p
= *q
)
191 if (grub_strcmp (p
->name
, var
->name
) > 0)
195 var
->sorted_next
= *q
;
204 grub_register_variable_hook (const char *name
,
205 grub_env_read_hook_t read_hook
,
206 grub_env_write_hook_t write_hook
)
208 struct grub_env_var
*var
= grub_env_find (name
);
212 if (grub_env_set (name
, "") != GRUB_ERR_NONE
)
215 var
= grub_env_find (name
);
216 /* XXX Insert an assertion? */
219 var
->read_hook
= read_hook
;
220 var
->write_hook
= write_hook
;
222 return GRUB_ERR_NONE
;
226 grub_register_vtoy_menu_lang_hook(grub_env_read_hook_t read_hook
)
228 vtoy_menu_lang_read_hook
= read_hook
;
229 return GRUB_ERR_NONE
;
233 grub_env_export (const char *name
)
235 struct grub_env_var
*var
;
237 var
= grub_env_find (name
);
242 err
= grub_env_set (name
, "");
245 var
= grub_env_find (name
);
249 return GRUB_ERR_NONE
;