Fix `help' with unloaded modules.

* include/grub/normal.h (grub_dyncmd_get_cmd): New proto.
	* grub-core/normal/dyncmd.c (grub_dyncmd_get_cmd): New function.
	(grub_dyncmd_dispatcher): Small stylistic fix.
	* grub-core/commands/help.c (grub_cmd_help): Load missing modules when
	explicit help is requested.
This commit is contained in:
Vladimir 'phcoder' Serbinenko 2012-02-09 14:38:34 +01:00
parent e1ea3ade95
commit e4e37e8dfa
4 changed files with 82 additions and 37 deletions

View file

@ -1,3 +1,13 @@
2012-02-09 Vladimir Serbinenko <phcoder@gmail.com>
Fix `help' with unloaded modules.
* include/grub/normal.h (grub_dyncmd_get_cmd): New proto.
* grub-core/normal/dyncmd.c (grub_dyncmd_get_cmd): New function.
(grub_dyncmd_dispatcher): Small stylistic fix.
* grub-core/commands/help.c (grub_cmd_help): Load missing modules when
explicit help is requested.
2012-02-09 Vladimir Serbinenko <phcoder@gmail.com> 2012-02-09 Vladimir Serbinenko <phcoder@gmail.com>
* grub-core/fs/cpio.c (grub_cpio_dir): Fix a bug with multiple listing. * grub-core/fs/cpio.c (grub_cpio_dir): Fix a bug with multiple listing.

View file

@ -47,7 +47,7 @@ grub_cmd_help (grub_extcmd_context_t ctxt __attribute__ ((unused)), int argc,
char *command_help; char *command_help;
grub_uint32_t *unicode_command_help; grub_uint32_t *unicode_command_help;
grub_uint32_t *unicode_last_position; grub_uint32_t *unicode_last_position;
command_help = grub_xasprintf ("%s %s", cmd->name, summary_translated); command_help = grub_xasprintf ("%s %s", cmd->name, summary_translated);
if (!command_help) if (!command_help)
break; break;
@ -99,28 +99,37 @@ grub_cmd_help (grub_extcmd_context_t ctxt __attribute__ ((unused)), int argc,
else else
{ {
int i; int i;
grub_command_t cmd; grub_command_t cmd_iter, cmd;
for (i = 0; i < argc; i++) for (i = 0; i < argc; i++)
{ {
currarg = args[i]; currarg = args[i];
FOR_COMMANDS(cmd) FOR_COMMANDS(cmd_iter)
{ {
if (cmd->prio & GRUB_PRIO_LIST_FLAG_ACTIVE) if (!(cmd_iter->prio & GRUB_PRIO_LIST_FLAG_ACTIVE))
{ continue;
if (! grub_strncmp (cmd->name, currarg, grub_strlen (currarg)))
{
if (cnt++ > 0)
grub_printf ("\n\n");
if ((cmd->flags & GRUB_COMMAND_FLAG_EXTCMD) && if (grub_strncmp (cmd_iter->name, currarg,
! (cmd->flags & GRUB_COMMAND_FLAG_DYNCMD)) grub_strlen (currarg)) != 0)
grub_arg_show_help ((grub_extcmd_t) cmd->data); continue;
else if (cmd_iter->flags & GRUB_COMMAND_FLAG_DYNCMD)
grub_printf ("%s %s %s\n%s\n", _("Usage:"), cmd->name, _(cmd->summary), cmd = grub_dyncmd_get_cmd (cmd_iter);
_(cmd->description)); else
} cmd = cmd_iter;
if (!cmd)
{
grub_print_error ();
continue;
} }
if (cnt++ > 0)
grub_printf ("\n\n");
if ((cmd->flags & GRUB_COMMAND_FLAG_EXTCMD) &&
! (cmd->flags & GRUB_COMMAND_FLAG_DYNCMD))
grub_arg_show_help ((grub_extcmd_t) cmd->data);
else
grub_printf ("%s %s %s\n%s\n", _("Usage:"), cmd->name,
_(cmd->summary), _(cmd->description));
} }
} }
} }

View file

@ -27,6 +27,32 @@
#include <grub/script_sh.h> #include <grub/script_sh.h>
#include <grub/i18n.h> #include <grub/i18n.h>
grub_command_t
grub_dyncmd_get_cmd (grub_command_t cmd)
{
grub_extcmd_t extcmd = cmd->data;
char *modname;
char *name;
grub_dl_t mod;
modname = extcmd->data;
mod = grub_dl_load (modname);
if (!mod)
return NULL;
grub_free (modname);
grub_dl_ref (mod);
name = (char *) cmd->name;
grub_unregister_extcmd (extcmd);
cmd = grub_command_find (name);
grub_free (name);
return cmd;
}
static grub_err_t static grub_err_t
grub_dyncmd_dispatcher (struct grub_extcmd_context *ctxt, grub_dyncmd_dispatcher (struct grub_extcmd_context *ctxt,
int argc, char **args) int argc, char **args)
@ -36,36 +62,33 @@ grub_dyncmd_dispatcher (struct grub_extcmd_context *ctxt,
grub_err_t ret; grub_err_t ret;
grub_extcmd_t extcmd = ctxt->extcmd; grub_extcmd_t extcmd = ctxt->extcmd;
grub_command_t cmd = extcmd->cmd; grub_command_t cmd = extcmd->cmd;
char *name;
modname = extcmd->data; modname = extcmd->data;
mod = grub_dl_load (modname); mod = grub_dl_load (modname);
if (mod) if (!mod)
return grub_errno;
grub_free (modname);
grub_dl_ref (mod);
name = (char *) cmd->name;
grub_unregister_extcmd (extcmd);
cmd = grub_command_find (name);
if (cmd)
{ {
char *name; if (cmd->flags & GRUB_COMMAND_FLAG_BLOCKS &&
cmd->flags & GRUB_COMMAND_FLAG_EXTCMD)
grub_free (modname); ret = grub_extcmd_dispatcher (cmd, argc, args, ctxt->script);
grub_dl_ref (mod);
name = (char *) cmd->name;
grub_unregister_extcmd (extcmd);
cmd = grub_command_find (name);
if (cmd)
{
if (cmd->flags & GRUB_COMMAND_FLAG_BLOCKS &&
cmd->flags & GRUB_COMMAND_FLAG_EXTCMD)
ret = grub_extcmd_dispatcher (cmd, argc, args, ctxt->script);
else
ret = (cmd->func) (cmd, argc, args);
}
else else
ret = grub_errno; ret = (cmd->func) (cmd, argc, args);
grub_free (name);
} }
else else
ret = grub_errno; ret = grub_errno;
grub_free (name);
return ret; return ret;
} }

View file

@ -132,4 +132,7 @@ void grub_normal_free_menu (grub_menu_t menu);
void grub_normal_auth_init (void); void grub_normal_auth_init (void);
void grub_normal_auth_fini (void); void grub_normal_auth_fini (void);
grub_command_t
grub_dyncmd_get_cmd (grub_command_t cmd);
#endif /* ! GRUB_NORMAL_HEADER */ #endif /* ! GRUB_NORMAL_HEADER */