1
/* execute.c -- Execute a GRUB script. */
3
* GRUB -- GRand Unified Bootloader
4
* Copyright (C) 2005,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/>.
20
#include <grub/misc.h>
23
#include <grub/script_sh.h>
24
#include <grub/command.h>
25
#include <grub/menu.h>
26
#include <grub/lib/arg.h>
27
#include <grub/normal.h>
30
grub_script_execute_cmd (struct grub_script_cmd *cmd)
35
return cmd->exec (cmd);
38
/* Parse ARG and return the textual representation. Add strings are
39
concatenated and all values of the variables are filled in. */
41
grub_script_execute_argument_to_string (struct grub_script_arg *arg)
46
struct grub_script_arg *argi;
48
/* First determine the size of the argument. */
49
for (argi = arg; argi; argi = argi->next)
53
val = grub_env_get (argi->str);
55
size += grub_strlen (val);
58
size += grub_strlen (argi->str);
61
/* Create the argument. */
62
chararg = grub_malloc (size + 1);
67
/* First determine the size of the argument. */
68
for (argi = arg; argi; argi = argi->next)
72
val = grub_env_get (argi->str);
74
grub_strcat (chararg, val);
77
grub_strcat (chararg, argi->str);
83
/* Execute a single command line. */
85
grub_script_execute_cmdline (struct grub_script_cmd *cmd)
87
struct grub_script_cmdline *cmdline = (struct grub_script_cmdline *) cmd;
88
struct grub_script_arglist *arglist;
91
grub_command_t grubcmd;
94
grub_script_function_t func = 0;
98
/* Lookup the command. */
99
cmdname = grub_script_execute_argument_to_string (cmdline->arglist->arg);
100
grubcmd = grub_command_find (cmdname);
104
grub_errno = GRUB_ERR_NONE;
106
/* It's not a GRUB command, try all functions. */
107
func = grub_script_function_find (cmdname);
110
/* As a last resort, try if it is an assignment. */
111
char *assign = grub_strdup (cmdname);
112
char *eq = grub_strchr (assign, '=');
116
/* This was set because the command was not found. */
117
grub_errno = GRUB_ERR_NONE;
119
/* Create two strings and set the variable. */
122
grub_env_set (assign, eq);
126
grub_snprintf (errnobuf, sizeof (errnobuf), "%d", grub_errno);
127
grub_env_set ("?", errnobuf);
134
if (cmdline->arglist->next)
136
argcount = cmdline->arglist->argcount - 1;
138
/* Create argv from the arguments. */
139
args = grub_malloc (sizeof (char *) * argcount);
140
for (arglist = cmdline->arglist->next; arglist; arglist = arglist->next)
143
str = grub_script_execute_argument_to_string (arglist->arg);
148
/* Execute the GRUB command or function. */
150
ret = (grubcmd->func) (grubcmd, argcount, args);
152
ret = grub_script_function_call (func, argcount, args);
154
/* Free arguments. */
155
for (i = 0; i < argcount; i++)
159
grub_snprintf (errnobuf, sizeof (errnobuf), "%d", ret);
160
grub_env_set ("?", errnobuf);
165
/* Execute a block of one or more commands. */
167
grub_script_execute_cmdblock (struct grub_script_cmd *cmd)
169
struct grub_script_cmdblock *cmdblock = (struct grub_script_cmdblock *) cmd;
171
/* Loop over every command and execute it. */
172
for (cmd = cmdblock->cmdlist; cmd; cmd = cmd->next)
173
grub_script_execute_cmd (cmd);
178
/* Execute an if statement. */
180
grub_script_execute_cmdif (struct grub_script_cmd *cmd)
182
struct grub_script_cmdif *cmdif = (struct grub_script_cmdif *) cmd;
185
/* Check if the commands results in a true or a false. The value is
186
read from the env variable `?'. */
187
grub_script_execute_cmd (cmdif->exec_to_evaluate);
188
result = grub_env_get ("?");
190
grub_errno = GRUB_ERR_NONE;
192
/* Execute the `if' or the `else' part depending on the value of
194
if (result && ! grub_strcmp (result, "0"))
195
return grub_script_execute_cmd (cmdif->exec_on_true);
197
return grub_script_execute_cmd (cmdif->exec_on_false);
200
/* Execute the menu entry generate statement. */
202
grub_script_execute_menuentry (struct grub_script_cmd *cmd)
204
struct grub_script_cmd_menuentry *cmd_menuentry;
205
struct grub_script_arglist *arglist;
210
cmd_menuentry = (struct grub_script_cmd_menuentry *) cmd;
212
if (cmd_menuentry->arglist)
214
argcount = cmd_menuentry->arglist->argcount;
216
/* Create argv from the arguments. */
217
args = grub_malloc (sizeof (char *) * argcount);
224
for (arglist = cmd_menuentry->arglist; arglist; arglist = arglist->next)
227
str = grub_script_execute_argument_to_string (arglist->arg);
232
grub_normal_add_menu_entry (argcount, (const char **) args,
233
cmd_menuentry->sourcecode);
235
/* Free arguments. */
236
for (i = 0; i < argcount; i++)
245
/* Execute any GRUB pre-parsed command or script. */
247
grub_script_execute (struct grub_script *script)
252
return grub_script_execute_cmd (script->cmd);