2009-01-17 Felix Zielcke <fzielcke@z-51.de>
[grub2/phcoder.git] / normal / command.c
blob6ca56da211283f9465cccd6ab2c9b299b6d12530
1 /*
2 * GRUB -- GRand Unified Bootloader
3 * Copyright (C) 2003,2005,2006,2007 Free Software Foundation, Inc.
5 * GRUB is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * GRUB is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
19 #include <grub/normal.h>
20 #include <grub/misc.h>
21 #include <grub/mm.h>
22 #include <grub/err.h>
23 #include <grub/term.h>
24 #include <grub/env.h>
25 #include <grub/dl.h>
26 #include <grub/parser.h>
27 #include <grub/script.h>
29 static grub_command_t grub_command_list;
31 grub_command_t
32 grub_register_command (const char *name,
33 grub_err_t (*func) (struct grub_arg_list *state,
34 int argc, char **args),
35 unsigned flags,
36 const char *summary,
37 const char *description,
38 const struct grub_arg_option *options)
40 grub_command_t cmd, *p;
42 cmd = (grub_command_t) grub_malloc (sizeof (*cmd));
43 if (! cmd)
44 return 0;
46 cmd->name = grub_strdup (name);
47 if (! cmd->name)
49 grub_free (cmd);
50 return 0;
53 cmd->func = func;
54 cmd->flags = flags;
55 cmd->summary = summary;
56 cmd->description = description;
57 cmd->options = options;
58 cmd->module_name = 0;
60 /* Keep the list sorted for simplicity. */
61 p = &grub_command_list;
62 while (*p)
64 if (grub_strcmp ((*p)->name, name) >= 0)
65 break;
67 p = &((*p)->next);
70 if (*p && grub_strcmp ((*p)->name, name) == 0)
72 grub_command_t q;
74 q = *p;
75 if (q->flags & GRUB_COMMAND_FLAG_NOT_LOADED)
77 q->func = cmd->func;
78 q->flags = cmd->flags;
79 q->summary = cmd->summary;
80 q->description = cmd->description;
81 q->options = cmd->options;
82 grub_free (cmd->name);
83 grub_free (cmd->module_name);
84 grub_free (cmd);
85 cmd = q;
87 else
89 grub_free (cmd->name);
90 grub_free (cmd);
91 cmd = 0;
94 else
96 cmd->next = *p;
97 *p = cmd;
100 return cmd;
103 void
104 grub_unregister_command (const char *name)
106 grub_command_t *p, q;
108 for (p = &grub_command_list, q = *p; q; p = &(q->next), q = q->next)
109 if (grub_strcmp (name, q->name) == 0)
111 *p = q->next;
112 grub_free (q->name);
113 grub_free (q->module_name);
114 grub_free (q);
115 break;
119 grub_command_t
120 grub_command_find (char *cmdline)
122 char *first_space;
123 grub_command_t cmd;
124 int count = 0;
126 first_space = grub_strchr (cmdline, ' ');
127 if (first_space)
128 *first_space = '\0';
130 again:
132 for (cmd = grub_command_list; cmd; cmd = cmd->next)
133 if (grub_strcmp (cmdline, cmd->name) == 0)
134 break;
136 if (! cmd)
137 grub_error (GRUB_ERR_UNKNOWN_COMMAND, "unknown command `%s'", cmdline);
138 else if (cmd->flags & GRUB_COMMAND_FLAG_NOT_LOADED)
140 /* Automatically load the command. */
141 if (count == 0)
143 grub_dl_t mod;
144 char *module_name;
146 module_name = grub_strdup (cmd->module_name);
147 if (module_name)
149 mod = grub_dl_load (module_name);
150 if (mod)
152 grub_dl_ref (mod);
153 count++;
154 grub_free (module_name);
155 goto again;
158 grub_free (module_name);
162 /* This module seems broken. */
163 grub_unregister_command (cmdline);
164 grub_error (GRUB_ERR_UNKNOWN_COMMAND, "unknown command `%s'", cmdline);
165 cmd = 0;
168 if (first_space)
169 *first_space = ' ';
171 return cmd;
175 grub_iterate_commands (int (*iterate) (grub_command_t))
177 grub_command_t cmd;
179 for (cmd = grub_command_list; cmd; cmd = cmd->next)
180 if (iterate (cmd))
181 return 1;
183 return 0;
187 grub_command_execute (char *cmdline, int interactive)
189 auto grub_err_t cmdline_get (char **s);
190 grub_err_t cmdline_get (char **s)
192 *s = grub_malloc (GRUB_MAX_CMDLINE);
193 *s[0] = '\0';
194 return grub_cmdline_get (">", *s, GRUB_MAX_CMDLINE, 0, 1);
197 grub_err_t ret = 0;
198 char *pager;
199 struct grub_script *parsed_script;
201 /* Enable the pager if the environment pager is set to 1. */
202 if (interactive)
203 pager = grub_env_get ("pager");
204 else
205 pager = NULL;
206 if (pager && (! grub_strcmp (pager, "1")))
207 grub_set_more (1);
209 /* Parse the script. */
210 parsed_script = grub_script_parse (cmdline, cmdline_get);
212 if (parsed_script)
214 /* Execute the command(s). */
215 grub_script_execute (parsed_script);
217 /* The parsed script was executed, throw it away. */
218 grub_script_free (parsed_script);
221 if (pager && (! grub_strcmp (pager, "1")))
222 grub_set_more (0);
224 return ret;
227 static grub_err_t
228 rescue_command (struct grub_arg_list *state __attribute__ ((unused)),
229 int argc __attribute__ ((unused)),
230 char **args __attribute__ ((unused)))
232 grub_longjmp (grub_exit_env, 0);
234 /* Never reach here. */
235 return 0;
239 static grub_err_t
240 set_command (struct grub_arg_list *state __attribute__ ((unused)),
241 int argc, char **args)
243 char *var;
244 char *val;
246 auto int print_env (struct grub_env_var *env);
247 int print_env (struct grub_env_var *env)
249 grub_printf ("%s=%s\n", env->name, env->value);
250 return 0;
253 if (! argc)
255 grub_env_iterate (print_env);
256 return 0;
259 var = args[0];
260 val = grub_strchr (var, '=');
261 if (! val)
263 grub_error (GRUB_ERR_BAD_ARGUMENT, "not an assignment");
264 return grub_errno;
267 val[0] = 0;
268 grub_env_set (var, val + 1);
269 val[0] = '=';
270 return 0;
273 static grub_err_t
274 unset_command (struct grub_arg_list *state __attribute__ ((unused)),
275 int argc, char **args)
277 if (argc < 1)
278 return grub_error (GRUB_ERR_BAD_ARGUMENT,
279 "no environment variable specified");
281 grub_env_unset (args[0]);
282 return 0;
285 static grub_err_t
286 export_command (struct grub_arg_list *state __attribute__ ((unused)),
287 int argc, char **args)
289 if (argc < 1)
290 return grub_error (GRUB_ERR_BAD_ARGUMENT,
291 "no environment variable specified");
293 grub_env_export (args[0]);
294 return 0;
297 static grub_err_t
298 insmod_command (struct grub_arg_list *state __attribute__ ((unused)),
299 int argc, char **args)
301 char *p;
302 grub_dl_t mod;
304 if (argc == 0)
305 return grub_error (GRUB_ERR_BAD_ARGUMENT, "no module specified");
307 p = grub_strchr (args[0], '/');
308 if (! p)
309 mod = grub_dl_load (args[0]);
310 else
311 mod = grub_dl_load_file (args[0]);
313 if (mod)
314 grub_dl_ref (mod);
316 return 0;
319 static grub_err_t
320 rmmod_command (struct grub_arg_list *state __attribute__ ((unused)),
321 int argc, char **args)
323 grub_dl_t mod;
325 if (argc == 0)
326 return grub_error (GRUB_ERR_BAD_ARGUMENT, "no module specified");
328 mod = grub_dl_get (args[0]);
329 if (! mod)
330 return grub_error (GRUB_ERR_BAD_ARGUMENT, "no such module");
332 if (! grub_dl_unref (mod))
333 grub_dl_unload (mod);
335 return 0;
338 static grub_err_t
339 lsmod_command (struct grub_arg_list *state __attribute__ ((unused)),
340 int argc __attribute__ ((unused)),
341 char **args __attribute__ ((unused)))
343 auto int print_module (grub_dl_t mod);
345 int print_module (grub_dl_t mod)
347 grub_dl_dep_t dep;
349 grub_printf ("%s\t%d\t\t", mod->name, mod->ref_count);
350 for (dep = mod->dep; dep; dep = dep->next)
352 if (dep != mod->dep)
353 grub_putchar (',');
355 grub_printf ("%s", dep->mod->name);
357 grub_putchar ('\n');
358 grub_refresh ();
360 return 0;
363 grub_printf ("Name\tRef Count\tDependencies\n");
364 grub_dl_iterate (print_module);
365 return 0;
368 void
369 grub_command_init (void)
371 grub_register_command ("rescue", rescue_command, GRUB_COMMAND_FLAG_BOTH,
372 "rescue", "Go back to the rescue mode.", 0);
374 grub_register_command ("set", set_command, GRUB_COMMAND_FLAG_BOTH,
375 "set [ENVVAR=VALUE]",
376 "Set an environment variable.", 0);
378 grub_register_command ("unset", unset_command, GRUB_COMMAND_FLAG_BOTH,
379 "unset ENVVAR", "Remove an environment variable.", 0);
381 grub_register_command ("export", export_command, GRUB_COMMAND_FLAG_BOTH,
382 "export ENVVAR", "Export a variable.", 0);
384 grub_register_command ("insmod", insmod_command, GRUB_COMMAND_FLAG_BOTH,
385 "insmod MODULE",
386 "Insert a module. The argument can be a file or a module name.",
389 grub_register_command ("rmmod", rmmod_command, GRUB_COMMAND_FLAG_BOTH,
390 "rmmod MODULE", "Remove a module.", 0);
392 grub_register_command ("lsmod", lsmod_command, GRUB_COMMAND_FLAG_BOTH,
393 "lsmod", "Show loaded modules.", 0);