]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
add example usage to hello command
authorBVK Chaitanya <bvk.groups@gmail.com>
Thu, 10 Jun 2010 06:42:03 +0000 (12:12 +0530)
committerBVK Chaitanya <bvk.groups@gmail.com>
Thu, 10 Jun 2010 06:42:03 +0000 (12:12 +0530)
34 files changed:
commands/acpi.c
commands/echo.c
commands/extcmd.c
commands/hashsum.c
commands/hdparm.c
commands/help.c
commands/hexdump.c
commands/i386/cpuid.c
commands/i386/pc/drivemap.c
commands/i386/pc/halt.c
commands/iorw.c
commands/keystatus.c
commands/loadenv.c
commands/ls.c
commands/lspci.c
commands/memrw.c
commands/probe.c
commands/search_wrap.c
commands/setpci.c
commands/sleep.c
disk/loopback.c
hello/hello.c
include/grub/command.h
include/grub/extcmd.h
include/grub/script_sh.h
loader/i386/bsd.c
loader/xnu.c
script/argv.c
script/execute.c
script/parser.y
script/script.c
term/gfxterm.c
term/serial.c
tests/lib/functional_test.c

index 5bbfd008b172b38dc1f3a916537862ac87e15f26..bdfdea073f23db78d4ff06cbbcde8e9beaa2cdb0 100644 (file)
@@ -456,10 +456,9 @@ free_tables (void)
 }
 
 static grub_err_t
-grub_cmd_acpi (struct grub_extcmd *cmd,
-                     int argc, char **args)
+grub_cmd_acpi (struct grub_extcmd_context *ctxt, int argc, char **args)
 {
-  struct grub_arg_list *state = cmd->state;
+  struct grub_arg_list *state = ctxt->state;
   struct grub_acpi_rsdp_v10 *rsdp;
   struct efiemu_acpi_table *cur, *t;
   grub_err_t err;
index 4fea091cb41e2c311baf5c2c8c96aef5703358f7..6bc00eae877e9f73585702f4365ca6ff8113111e 100644 (file)
@@ -30,9 +30,9 @@ static const struct grub_arg_option options[] =
   };
 
 static grub_err_t
-grub_cmd_echo (grub_extcmd_t cmd, int argc, char **args)
+grub_cmd_echo (grub_extcmd_context_t ctxt, int argc, char **args)
 {
-  struct grub_arg_list *state = cmd->state;
+  struct grub_arg_list *state = ctxt->state;
   int newline = 1;
   int i;
 
index 16796febf8fe8269f15e7695ac3593c34eacee91..76cbe4e267360c4d5ee4e61cd88829743b5f02c1 100644 (file)
 #include <grub/list.h>
 #include <grub/misc.h>
 #include <grub/extcmd.h>
+#include <grub/script_sh.h>
 
-static grub_err_t
-grub_extcmd_dispatcher (struct grub_command *cmd,
-                       int argc, char **args)
+grub_err_t
+grub_extcmd_dispatcher (struct grub_command *cmd, int argc, char **args,
+                       struct grub_script **scripts)
 {
   int new_argc;
   char **new_args;
   struct grub_arg_option *parser;
   struct grub_arg_list *state;
+  struct grub_extcmd_context context;
   int maxargs = 0;
   grub_err_t ret;
   grub_extcmd_t ext;
@@ -44,8 +46,11 @@ grub_extcmd_dispatcher (struct grub_command *cmd,
 
   if (grub_arg_parse (ext, argc, args, state, &new_args, &new_argc))
     {
-      ext->state = state;
-      ret = (ext->func) (ext, new_argc, new_args);
+      context.extcmd = ext;
+      context.state = state;
+      context.script_params = scripts;
+
+      ret = (ext->func) (&context, new_argc, new_args);
       grub_free (new_args);
     }
   else
@@ -56,6 +61,12 @@ grub_extcmd_dispatcher (struct grub_command *cmd,
   return ret;
 }
 
+static grub_err_t
+grub_extcmd_dispatch (struct grub_command *cmd, int argc, char **args)
+{
+  return grub_extcmd_dispatcher (cmd, argc, args, 0);
+}
+
 grub_extcmd_t
 grub_register_extcmd (const char *name, grub_extcmd_func_t func,
                      unsigned flags, const char *summary,
@@ -69,7 +80,7 @@ grub_register_extcmd (const char *name, grub_extcmd_func_t func,
   if (! ext)
     return 0;
 
-  cmd = grub_register_command_prio (name, grub_extcmd_dispatcher,
+  cmd = grub_register_command_prio (name, grub_extcmd_dispatch,
                                    summary, description, 1);
   if (! cmd)
     {
index d5f551dbbb00eb2229800ae6b291c2b74ef24aa5..df85015a6178902f7d2fcb5cce1f0a13a67c9834 100644 (file)
@@ -165,10 +165,10 @@ check_list (const gcry_md_spec_t *hash, const char *hashfilename,
 }
 
 static grub_err_t
-grub_cmd_hashsum (struct grub_extcmd *cmd,
+grub_cmd_hashsum (struct grub_extcmd_context *ctxt,
                  int argc, char **args)
 {
-  struct grub_arg_list *state = cmd->state;
+  struct grub_arg_list *state = ctxt->state;
   const char *hashname = NULL;
   const char *prefix = NULL;
   const gcry_md_spec_t *hash;
@@ -177,7 +177,7 @@ grub_cmd_hashsum (struct grub_extcmd *cmd,
   unsigned unread = 0;
 
   for (i = 0; i < ARRAY_SIZE (aliases); i++)
-    if (grub_strcmp (cmd->cmd->name, aliases[i].name) == 0)
+    if (grub_strcmp (ctxt->extcmd->cmd->name, aliases[i].name) == 0)
       hashname = aliases[i].hashname;
   if (state[0].set)
     hashname = state[0].arg;
index a3f8bbff03f652f4968070a9f849b8124d84a0ee..54724077d8a5e1ae768ee52a3632d50c5f8b418f 100644 (file)
@@ -270,9 +270,9 @@ static int get_int_arg (const struct grub_arg_list *state)
 }
 
 static grub_err_t
-grub_cmd_hdparm (grub_extcmd_t cmd, int argc, char **args) // state????
+grub_cmd_hdparm (grub_extcmd_context_t ctxt, int argc, char **args) // state????
 {
-  struct grub_arg_list *state = cmd->state;
+  struct grub_arg_list *state = ctxt->state;
 
   /* Check command line.  */
   if (argc != 1)
index c2aad03b23cd8a4b0f6f587c6126517184fdc7e0..2b2eeaa843b29702d428370028586c83a860282b 100644 (file)
@@ -27,7 +27,7 @@
 #include <grub/charset.h>
 
 static grub_err_t
-grub_cmd_help (grub_extcmd_t ext __attribute__ ((unused)), int argc,
+grub_cmd_help (grub_extcmd_context_t ctxt __attribute__ ((unused)), int argc,
               char **args)
 {
   int cnt = 0;
index c1d4ecba9e84371a9e388aa22f8310d2fc74d031..6c518f649b1db8ec6e8b4274928d8c6fb12ce52c 100644 (file)
@@ -34,9 +34,9 @@ static const struct grub_arg_option options[] = {
 };
 
 static grub_err_t
-grub_cmd_hexdump (grub_extcmd_t cmd, int argc, char **args)
+grub_cmd_hexdump (grub_extcmd_context_t ctxt, int argc, char **args)
 {
-  struct grub_arg_list *state = cmd->state;
+  struct grub_arg_list *state = ctxt->state;
   char buf[GRUB_DISK_SECTOR_SIZE * 4];
   grub_ssize_t size, length;
   grub_disk_addr_t skip;
index 6eebf91a1ce570edf3e9b81fd5d9fb9ab1d2c327..412b284d08d7d947c271cd91e08b86092a41f010 100644 (file)
@@ -43,7 +43,7 @@ static const struct grub_arg_option options[] =
 unsigned char grub_cpuid_has_longmode = 0;
 
 static grub_err_t
-grub_cmd_cpuid (grub_extcmd_t cmd __attribute__ ((unused)),
+grub_cmd_cpuid (grub_extcmd_context_t ctxt __attribute__ ((unused)),
                int argc __attribute__ ((unused)),
                char **args __attribute__ ((unused)))
 {
index 4afc4335856e97f062ce4edac3e525a2ef528596..7ecfe745493a502c00989b621ec959958310f2a0 100644 (file)
@@ -196,13 +196,13 @@ list_mappings (void)
 }
 
 static grub_err_t
-grub_cmd_drivemap (struct grub_extcmd *cmd, int argc, char **args)
+grub_cmd_drivemap (struct grub_extcmd_context *ctxt, int argc, char **args)
 {
-  if (cmd->state[OPTIDX_LIST].set)
+  if (ctxt->state[OPTIDX_LIST].set)
     {
       return list_mappings ();
     }
-  else if (cmd->state[OPTIDX_RESET].set)
+  else if (ctxt->state[OPTIDX_RESET].set)
     {
       /* Reset: just delete all mappings, freeing their memory.  */
       drivemap_node_t *curnode = map_head;
@@ -216,7 +216,7 @@ grub_cmd_drivemap (struct grub_extcmd *cmd, int argc, char **args)
       map_head = 0;
       return GRUB_ERR_NONE;
     }
-  else if (!cmd->state[OPTIDX_SWAP].set && argc == 0)
+  else if (!ctxt->state[OPTIDX_SWAP].set && argc == 0)
     {
       /* No arguments */
       return list_mappings ();
@@ -248,11 +248,11 @@ grub_cmd_drivemap (struct grub_extcmd *cmd, int argc, char **args)
     }
   /* Set the mapping for the disk (overwrites any existing mapping).  */
   grub_dprintf ("drivemap", "%s %s (%02x) = %s (%02x)\n",
-               cmd->state[OPTIDX_SWAP].set ? "Swapping" : "Mapping",
+               ctxt->state[OPTIDX_SWAP].set ? "Swapping" : "Mapping",
                args[1], mapto, args[0], mapfrom);
   err = drivemap_set (mapto, mapfrom);
   /* If -s, perform the reverse mapping too (only if the first was OK).  */
-  if (cmd->state[OPTIDX_SWAP].set && err == GRUB_ERR_NONE)
+  if (ctxt->state[OPTIDX_SWAP].set && err == GRUB_ERR_NONE)
     err = drivemap_set (mapfrom, mapto);
   return err;
 }
index 4c39612ae81f22db67a85904d7ed1d457f917486..10b29864414ff58ff6eccd12c2827b0aa96a63f4 100644 (file)
@@ -29,12 +29,12 @@ static const struct grub_arg_option options[] =
   };
 
 static grub_err_t
-grub_cmd_halt (grub_extcmd_t cmd,
+grub_cmd_halt (grub_extcmd_context_t ctxt,
               int argc __attribute__ ((unused)),
               char **args __attribute__ ((unused)))
 
 {
-  struct grub_arg_list *state = cmd->state;
+  struct grub_arg_list *state = ctxt->state;
   int no_apm = 0;
   if (state[0].set)
     no_apm = 1;
index 474c8712ed74fccee061619aaacf85213bb82f1e..bd0183794aad8bdaffd6264195e6c0c4e4269fe6 100644 (file)
@@ -36,7 +36,7 @@ static const struct grub_arg_option options[] =
 
 
 static grub_err_t
-grub_cmd_read (grub_extcmd_t cmd, int argc, char **argv)
+grub_cmd_read (grub_extcmd_context_t ctxt, int argc, char **argv)
 {
   grub_target_addr_t addr;
   grub_uint32_t value = 0;
@@ -46,7 +46,7 @@ grub_cmd_read (grub_extcmd_t cmd, int argc, char **argv)
     return grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid number of arguments");
 
   addr = grub_strtoul (argv[0], 0, 0);
-  switch (cmd->cmd->name[sizeof ("in") - 1])
+  switch (ctxt->extcmd->cmd->name[sizeof ("in") - 1])
     {
     case 'l':
       value = grub_inl (addr);
@@ -61,10 +61,10 @@ grub_cmd_read (grub_extcmd_t cmd, int argc, char **argv)
       break;
     }
 
-  if (cmd->state[0].set)
+  if (ctxt->state[0].set)
     {
       grub_snprintf (buf, sizeof (buf), "%x", value);
-      grub_env_set (cmd->state[0].arg, buf);
+      grub_env_set (ctxt->state[0].arg, buf);
     }
   else
     grub_printf ("0x%x\n", value);
index 838792889ff3a58322f53965c6e9dd35ae5c6e57..c83c00560e258cf986ca1a8697a1af85ac88c386 100644 (file)
@@ -34,11 +34,11 @@ static const struct grub_arg_option options[] =
 #define grub_cur_term_input    grub_term_get_current_input ()
 
 static grub_err_t
-grub_cmd_keystatus (grub_extcmd_t cmd,
+grub_cmd_keystatus (grub_extcmd_context_t ctxt,
                    int argc __attribute__ ((unused)),
                    char **args __attribute__ ((unused)))
 {
-  struct grub_arg_list *state = cmd->state;
+  struct grub_arg_list *state = ctxt->state;
   int expect_mods = 0;
   int mods;
 
index d763b2d5e5e0c53082ab41104d92fd044c48176a..381810a9234c61defd0cb4b87e63fa3d263965c6 100644 (file)
@@ -111,11 +111,11 @@ read_envblk_file (grub_file_t file)
 }
 
 static grub_err_t
-grub_cmd_load_env (grub_extcmd_t cmd,
+grub_cmd_load_env (grub_extcmd_context_t ctxt,
                   int argc __attribute__ ((unused)),
                   char **args __attribute__ ((unused)))
 {
-  struct grub_arg_list *state = cmd->state;
+  struct grub_arg_list *state = ctxt->state;
   grub_file_t file;
   grub_envblk_t envblk;
 
@@ -143,11 +143,11 @@ grub_cmd_load_env (grub_extcmd_t cmd,
 }
 
 static grub_err_t
-grub_cmd_list_env (grub_extcmd_t cmd,
+grub_cmd_list_env (grub_extcmd_context_t ctxt,
                   int argc __attribute__ ((unused)),
                   char **args __attribute__ ((unused)))
 {
-  struct grub_arg_list *state = cmd->state;
+  struct grub_arg_list *state = ctxt->state;
   grub_file_t file;
   grub_envblk_t envblk;
 
@@ -280,9 +280,9 @@ write_blocklists (grub_envblk_t envblk, struct blocklist *blocklists,
 }
 
 static grub_err_t
-grub_cmd_save_env (grub_extcmd_t cmd, int argc, char **args)
+grub_cmd_save_env (grub_extcmd_context_t ctxt, int argc, char **args)
 {
-  struct grub_arg_list *state = cmd->state;
+  struct grub_arg_list *state = ctxt->state;
   grub_file_t file;
   grub_envblk_t envblk;
   struct blocklist *head = 0;
index eb10496178898a6fb103a760c0f71166f1a88c9b..6b2f63c194bc25fffdc960857317185f5df7118a 100644 (file)
@@ -248,9 +248,9 @@ grub_ls_list_files (char *dirname, int longlist, int all, int human)
 }
 
 static grub_err_t
-grub_cmd_ls (grub_extcmd_t cmd, int argc, char **args)
+grub_cmd_ls (grub_extcmd_context_t ctxt, int argc, char **args)
 {
-  struct grub_arg_list *state = cmd->state;
+  struct grub_arg_list *state = ctxt->state;
 
   if (argc == 0)
     grub_ls_list_devices (state[0].set);
index a69bb35ad14f19b3bc03f7609ddc373c81365e63..bc52e060a6228d9fb2ff44d418981cc105a9cccf 100644 (file)
@@ -211,11 +211,11 @@ grub_lspci_iter (grub_pci_device_t dev, grub_pci_id_t pciid)
 }
 
 static grub_err_t
-grub_cmd_lspci (grub_extcmd_t cmd,
+grub_cmd_lspci (grub_extcmd_context_t ctxt,
                int argc __attribute__ ((unused)),
                char **args __attribute__ ((unused)))
 {
-  iospace = cmd->state[0].set;
+  iospace = ctxt->state[0].set;
   grub_pci_iterate (grub_lspci_iter);
   return GRUB_ERR_NONE;
 }
index 6a4d43be2c80a2ef5e28a8a95e2b08e73fdb2013..d28f45ec1e6ddf0623fea27b2542ad3955a1a841 100644 (file)
@@ -35,7 +35,7 @@ static const struct grub_arg_option options[] =
 
 
 static grub_err_t
-grub_cmd_read (grub_extcmd_t cmd, int argc, char **argv)
+grub_cmd_read (grub_extcmd_context_t ctxt, int argc, char **argv)
 {
   grub_target_addr_t addr;
   grub_uint32_t value = 0;
@@ -45,7 +45,7 @@ grub_cmd_read (grub_extcmd_t cmd, int argc, char **argv)
     return grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid number of arguments");
 
   addr = grub_strtoul (argv[0], 0, 0);
-  switch (cmd->cmd->name[sizeof ("read_") - 1])
+  switch (ctxt->extcmd->cmd->name[sizeof ("read_") - 1])
     {
     case 'd':
       value = *((volatile grub_uint32_t *) addr);
@@ -60,10 +60,10 @@ grub_cmd_read (grub_extcmd_t cmd, int argc, char **argv)
       break;
     }
 
-  if (cmd->state[0].set)
+  if (ctxt->state[0].set)
     {
       grub_snprintf (buf, sizeof (buf), "%x", value);
-      grub_env_set (cmd->state[0].arg, buf);
+      grub_env_set (ctxt->state[0].arg, buf);
     }
   else
     grub_printf ("0x%x\n", value);
index c2cc599e99eefcdaf29eda3c649cd0d4069c6283..f3941e0295daba42d2d0f0cb7d6a2daa740f4a07 100644 (file)
@@ -45,9 +45,9 @@ static const struct grub_arg_option options[] =
   };
 
 static grub_err_t
-grub_cmd_probe (grub_extcmd_t cmd, int argc, char **args)
+grub_cmd_probe (grub_extcmd_context_t ctxt, int argc, char **args)
 {
-  struct grub_arg_list *state = cmd->state;
+  struct grub_arg_list *state = ctxt->state;
   grub_device_t dev;
   grub_fs_t fs;
   char *ptr;
index 2891d85d75363178c9d7055e34d448e967ebea2f..fff3fb47a153b37650c75c2d4e648b8e14a31bb2 100644 (file)
@@ -50,9 +50,9 @@ enum options
  };
 
 static grub_err_t
-grub_cmd_search (grub_extcmd_t cmd, int argc, char **args)
+grub_cmd_search (grub_extcmd_context_t ctxt, int argc, char **args)
 {
-  struct grub_arg_list *state = cmd->state;
+  struct grub_arg_list *state = ctxt->state;
   const char *var = 0;
 
   if (argc == 0)
index fbc7c214ee752da5bd2a91e41c0fb99efb06efc4..89a0085d84ee44c5da53187171d052c259c6a60f 100644 (file)
@@ -155,7 +155,7 @@ grub_setpci_iter (grub_pci_device_t dev, grub_pci_id_t pciid)
 }
 
 static grub_err_t
-grub_cmd_setpci (grub_extcmd_t cmd, int argc, char **argv)
+grub_cmd_setpci (grub_extcmd_context_t ctxt, int argc, char **argv)
 {
   const char *ptr;
   unsigned i;
@@ -163,14 +163,14 @@ grub_cmd_setpci (grub_extcmd_t cmd, int argc, char **argv)
   pciid_check_value = 0;
   pciid_check_mask = 0;
 
-  if (cmd->state[0].set)
+  if (ctxt->state[0].set)
     {
-      ptr = cmd->state[0].arg;
+      ptr = ctxt->state[0].arg;
       pciid_check_value |= (grub_strtoul (ptr, (char **) &ptr, 16) & 0xffff);
       if (grub_errno == GRUB_ERR_BAD_NUMBER)
        {
          grub_errno = GRUB_ERR_NONE;
-         ptr = cmd->state[0].arg;
+         ptr = ctxt->state[0].arg;
        }
       else
        pciid_check_mask |= 0xffff;
@@ -191,11 +191,11 @@ grub_cmd_setpci (grub_extcmd_t cmd, int argc, char **argv)
 
   check_bus = check_device = check_function = 0;
 
-  if (cmd->state[1].set)
+  if (ctxt->state[1].set)
     {
       const char *optr;
       
-      ptr = cmd->state[1].arg;
+      ptr = ctxt->state[1].arg;
       optr = ptr;
       bus = grub_strtoul (ptr, (char **) &ptr, 16);
       if (grub_errno == GRUB_ERR_BAD_NUMBER)
@@ -229,8 +229,8 @@ grub_cmd_setpci (grub_extcmd_t cmd, int argc, char **argv)
        }
     }
 
-  if (cmd->state[2].set)
-    varname = cmd->state[2].arg;
+  if (ctxt->state[2].set)
+    varname = ctxt->state[2].arg;
   else
     varname = NULL;
 
index ead279506ed82b12a54008e8555944525d9a9884..ee0875cf76756be6d7aefd477dff8bf936e88821 100644 (file)
@@ -60,9 +60,9 @@ grub_interruptible_millisleep (grub_uint32_t ms)
 }
 
 static grub_err_t
-grub_cmd_sleep (grub_extcmd_t cmd, int argc, char **args)
+grub_cmd_sleep (grub_extcmd_context_t ctxt, int argc, char **args)
 {
-  struct grub_arg_list *state = cmd->state;
+  struct grub_arg_list *state = ctxt->state;
   int n;
 
   if (argc != 1)
index 1b525e05f55f59e0adc525a22951844bcf44cd3e..52929e7657e58e8fe438c0aaebbdbb0c94e2e823 100644 (file)
@@ -71,9 +71,9 @@ delete_loopback (const char *name)
 
 /* The command to add and remove loopback devices.  */
 static grub_err_t
-grub_cmd_loopback (grub_extcmd_t cmd, int argc, char **args)
+grub_cmd_loopback (grub_extcmd_context_t ctxt, int argc, char **args)
 {
-  struct grub_arg_list *state = state = cmd->state;
+  struct grub_arg_list *state = ctxt->state;
   grub_file_t file;
   struct grub_loopback *newdev;
 
index eff07d9414b130476ac11a0f0d96c2d3960d1438..16c3bb5ceacd825524278ac253acf4a92d47103c 100644 (file)
 #include <grub/extcmd.h>
 #include <grub/i18n.h>
 
+static struct grub_script *script;
+
 static grub_err_t
-grub_cmd_hello (struct grub_extcmd *cmd __attribute__ ((unused)),
-               int argc __attribute__ ((unused)),
-               char **args __attribute__ ((unused)))
+grub_cmd_hello (grub_extcmd_context_t ctxt,
+               int argc, char **args __attribute__ ((unused)))
 {
-  grub_printf ("Hello World\n");
+  if (argc == 0 && script == 0)
+    grub_printf ("Hello World\n");
+
+  else if (argc == 0)
+    grub_script_execute (script);
+
+  else
+    {
+      if (! ctxt->script_params || ! ctxt->script_params[0])
+       return 1;
+
+      if (script)
+       grub_script_free (script);
+
+      script = grub_malloc (sizeof (*script));
+      if (! script)
+       return 1;
+
+      script->cmd = ctxt->script_params[0]->cmd;
+      script->mem = ctxt->script_params[0]->mem;
+      ctxt->script_params[0]->cmd = 0;
+      ctxt->script_params[0]->mem = 0;
+    }
+
   return 0;
 }
 
@@ -39,11 +63,15 @@ static grub_extcmd_t cmd;
 
 GRUB_MOD_INIT(hello)
 {
-  cmd = grub_register_extcmd ("hello", grub_cmd_hello, GRUB_COMMAND_FLAG_BOTH,
+  cmd = grub_register_extcmd ("hello", grub_cmd_hello,
+                             GRUB_COMMAND_FLAG_BOTH | GRUB_COMMAND_FLAG_BLOCKS,
                              0, N_("Say \"Hello World\"."), 0);
 }
 
 GRUB_MOD_FINI(hello)
 {
+  if (script)
+    grub_script_free (script);
+
   grub_unregister_extcmd (cmd);
 }
index 6e9942b60b781051d4396edc2f4fa0f58a2dab9a..c2523f2887a9004560ddedc00af96ea255780f2b 100644 (file)
@@ -37,6 +37,8 @@
 #define GRUB_COMMAND_FLAG_EXTCMD       0x10
 /* This is an dynamic command.  */
 #define GRUB_COMMAND_FLAG_DYNCMD       0x20
+/* This command accepts block arguments.  */
+#define GRUB_COMMAND_FLAG_BLOCKS       0x40
 
 struct grub_command;
 
index 03eaba8f89f1e80726caa4a359531d5bedd94f37..54f0958fee568e03970c2ab14827d255c394d2b3 100644 (file)
 
 #include <grub/lib/arg.h>
 #include <grub/command.h>
+#include <grub/script_sh.h>
 
 struct grub_extcmd;
+struct grub_extcmd_context;
 
-typedef grub_err_t (*grub_extcmd_func_t) (struct grub_extcmd *cmd,
+typedef grub_err_t (*grub_extcmd_func_t) (struct grub_extcmd_context *ctxt,
                                          int argc, char **args);
 
 /* The argcmd description.  */
@@ -38,10 +40,20 @@ struct grub_extcmd
   const struct grub_arg_option *options;
 
   void *data;
+};
+typedef struct grub_extcmd *grub_extcmd_t;
+
+/* Command context for each instance of execution.  */
+struct grub_extcmd_context
+{
+  struct grub_extcmd *extcmd;
 
   struct grub_arg_list *state;
+
+  /* Script parameters, if any.  */
+  struct grub_script **script_params;
 };
-typedef struct grub_extcmd *grub_extcmd_t;
+typedef struct grub_extcmd_context *grub_extcmd_context_t;
 
 grub_extcmd_t grub_register_extcmd (const char *name,
                                    grub_extcmd_func_t func,
@@ -52,4 +64,8 @@ grub_extcmd_t grub_register_extcmd (const char *name,
 
 void grub_unregister_extcmd (grub_extcmd_t cmd);
 
+grub_err_t
+grub_extcmd_dispatcher (struct grub_command *cmd, int argc, char **args,
+                       struct grub_script **scripts);
+
 #endif /* ! GRUB_EXTCMD_HEADER */
index 87fb26f93a8e0393e6860b56bef08f85e10661de..a17dcca7028df5d3a03f70af7f2c6feeac105afd 100644 (file)
@@ -72,6 +72,7 @@ struct grub_script_argv
 {
   unsigned argc;
   char **args;
+  struct grub_script **scripts;
 };
 
 /* A complete argument.  It consists of a list of one or more `struct
@@ -230,6 +231,8 @@ void grub_script_argv_free    (struct grub_script_argv *argv);
 int grub_script_argv_next     (struct grub_script_argv *argv);
 int grub_script_argv_append   (struct grub_script_argv *argv, const char *s);
 int grub_script_argv_split_append (struct grub_script_argv *argv, char *s);
+int grub_script_argv_script_append (struct grub_script_argv *argv,
+                                   struct grub_script *s);
 
 struct grub_script_arglist *
 grub_script_create_arglist (struct grub_parser_param *state);
index 3c7fe2feec4b39437368788122d6c42eeb68ce94..c92712562e92e2060f5c32ecfb07980b2d07d4f0 100644 (file)
@@ -946,10 +946,10 @@ grub_bsd_parse_flags (const struct grub_arg_list *state,
 }
 
 static grub_err_t
-grub_cmd_freebsd (grub_extcmd_t cmd, int argc, char *argv[])
+grub_cmd_freebsd (grub_extcmd_context_t ctxt, int argc, char *argv[])
 {
   kernel_type = KERNEL_TYPE_FREEBSD;
-  bootflags = grub_bsd_parse_flags (cmd->state, freebsd_flags);
+  bootflags = grub_bsd_parse_flags (ctxt->state, freebsd_flags);
 
   if (grub_bsd_load (argc, argv) == GRUB_ERR_NONE)
     {
@@ -1009,16 +1009,16 @@ grub_cmd_freebsd (grub_extcmd_t cmd, int argc, char *argv[])
 }
 
 static grub_err_t
-grub_cmd_openbsd (grub_extcmd_t cmd, int argc, char *argv[])
+grub_cmd_openbsd (grub_extcmd_context_t ctxt, int argc, char *argv[])
 {
   grub_uint32_t bootdev;
 
   kernel_type = KERNEL_TYPE_OPENBSD;
-  bootflags = grub_bsd_parse_flags (cmd->state, openbsd_flags);
+  bootflags = grub_bsd_parse_flags (ctxt->state, openbsd_flags);
 
-  if (cmd->state[OPENBSD_ROOT_ARG].set)
+  if (ctxt->state[OPENBSD_ROOT_ARG].set)
     {
-      const char *arg = cmd->state[OPENBSD_ROOT_ARG].arg;
+      const char *arg = ctxt->state[OPENBSD_ROOT_ARG].arg;
       int unit, part;
       if (*(arg++) != 'w' || *(arg++) != 'd')
        return grub_error (GRUB_ERR_BAD_ARGUMENT,
@@ -1049,16 +1049,16 @@ grub_cmd_openbsd (grub_extcmd_t cmd, int argc, char *argv[])
 }
 
 static grub_err_t
-grub_cmd_netbsd (grub_extcmd_t cmd, int argc, char *argv[])
+grub_cmd_netbsd (grub_extcmd_context_t ctxt, int argc, char *argv[])
 {
   kernel_type = KERNEL_TYPE_NETBSD;
-  bootflags = grub_bsd_parse_flags (cmd->state, netbsd_flags);
+  bootflags = grub_bsd_parse_flags (ctxt->state, netbsd_flags);
 
   if (grub_bsd_load (argc, argv) == GRUB_ERR_NONE)
     {
       grub_loader_set (grub_netbsd_boot, grub_bsd_unload, 1);
-      if (cmd->state[NETBSD_ROOT_ARG].set)
-       netbsd_root = grub_strdup (cmd->state[NETBSD_ROOT_ARG].arg);
+      if (ctxt->state[NETBSD_ROOT_ARG].set)
+       netbsd_root = grub_strdup (ctxt->state[NETBSD_ROOT_ARG].arg);
     }
 
   return grub_errno;
index 8f1d0c6415b5ed2c80e6dd22ad4a6129fead9707..5c7bd50be6a2dfe862e8a5619b752cfcb3e8f7d5 100644 (file)
@@ -1368,15 +1368,15 @@ static const struct grub_arg_option xnu_splash_cmd_options[] =
   };
 
 static grub_err_t
-grub_cmd_xnu_splash (grub_extcmd_t cmd,
+grub_cmd_xnu_splash (grub_extcmd_context_t ctxt,
                     int argc, char *args[])
 {
   grub_err_t err;
   if (argc != 1)
     return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required");
 
-  if (cmd->state[XNU_SPLASH_CMD_ARGINDEX_MODE].set &&
-      grub_strcmp (cmd->state[XNU_SPLASH_CMD_ARGINDEX_MODE].arg,
+  if (ctxt->state[XNU_SPLASH_CMD_ARGINDEX_MODE].set &&
+      grub_strcmp (ctxt->state[XNU_SPLASH_CMD_ARGINDEX_MODE].arg,
                   "stretch") == 0)
     grub_xnu_bitmap_mode = GRUB_XNU_BITMAP_STRETCH;
   else
index 69322779db07e8403ce49d5233d3b50c498e31f9..f962556d8ad10603aaf34b654521ffe518438c8d 100644 (file)
@@ -52,8 +52,17 @@ grub_script_argv_free (struct grub_script_argv *argv)
       grub_free (argv->args);
     }
 
+  if (argv->scripts)
+    {
+      for (i = 0; i < argv->argc; i++)
+       grub_script_free (argv->scripts[i]);
+
+      grub_free (argv->scripts);
+    }
+
   argv->argc = 0;
   argv->args = 0;
+  argv->scripts = 0;
 }
 
 /* Prepare for next argc.  */
@@ -61,20 +70,33 @@ int
 grub_script_argv_next (struct grub_script_argv *argv)
 {
   char **p = argv->args;
+  struct grub_script **q = argv->scripts;
 
-  if (argv->args && argv->args[argv->argc - 1] == 0)
+  if (argv->args && argv->argc && argv->args[argv->argc - 1] == 0)
     return 0;
 
   p = grub_realloc (p, round_up_exp ((argv->argc + 2) * sizeof (char *)));
   if (! p)
     return 1;
 
+  q = grub_realloc (q, round_up_exp ((argv->argc + 2) * sizeof (struct grub_script *)));
+  if (! q)
+    {
+      grub_free (p);
+      return 1;
+    }
+
   argv->argc++;
   argv->args = p;
+  argv->scripts = q;
 
   if (argv->argc == 1)
-    argv->args[0] = 0;
+    {
+      argv->args[0] = 0;
+      argv->scripts[0] = 0;
+    }
   argv->args[argv->argc] = 0;
+  argv->scripts[argv->argc] = 0;
   return 0;
 }
 
@@ -100,6 +122,25 @@ grub_script_argv_append (struct grub_script_argv *argv, const char *s)
   return 0;
 }
 
+/* Append grub_script `s' as the last argument.  */
+int
+grub_script_argv_script_append (struct grub_script_argv *argv,
+                               struct grub_script *script)
+{
+  struct grub_script *s;
+
+  s = grub_malloc (sizeof (*s));
+  if (! s)
+    return 1;
+
+  if (argv->scripts[argv->argc - 1])
+    grub_script_free (argv->scripts[argv->argc - 1]);
+
+  *s = *script;
+  argv->scripts[argv->argc - 1] = s;
+  return 0;
+}
+
 /* Split `s' and append words as multiple arguments.  */
 int
 grub_script_argv_split_append (struct grub_script_argv *argv, char *s)
index 691b3c8934b2f9020b837bdff6dc44ec23ca1a42..0ac42cf4ac6261a788ba803a51850d5285a02b8e 100644 (file)
@@ -25,6 +25,7 @@
 #include <grub/menu.h>
 #include <grub/lib/arg.h>
 #include <grub/normal.h>
+#include <grub/extcmd.h>
 
 /* Max digits for a char is 3 (0xFF is 255), similarly for an int it
    is sizeof (int) * 3, and one extra for a possible -ve sign.  */
@@ -51,7 +52,7 @@ grub_env_special (const char *name)
 static char **
 grub_script_env_get (const char *name, grub_script_arg_type_t type)
 {
-  struct grub_script_argv result = { 0, 0 };
+  struct grub_script_argv result = { 0, 0, 0 };
 
   if (grub_script_argv_next (&result))
     goto fail;
@@ -169,7 +170,7 @@ grub_script_arglist_to_argv (struct grub_script_arglist *arglist,
   int i;
   char **values = 0;
   struct grub_script_arg *arg = 0;
-  struct grub_script_argv result = { 0, 0 };
+  struct grub_script_argv result = { 0, 0, 0 };
 
   for (; arglist && arglist->arg; arglist = arglist->next)
     {
@@ -196,6 +197,11 @@ grub_script_arglist_to_argv (struct grub_script_arglist *arglist,
              break;
 
            case GRUB_SCRIPT_ARG_TYPE_BLOCK:
+             if (grub_script_argv_append (&result, arg->str) ||
+                 grub_script_argv_script_append (&result, &arg->block))
+               goto fail;
+             break;
+
            case GRUB_SCRIPT_ARG_TYPE_TEXT:
              if (grub_strlen (arg->str) &&
                  grub_script_argv_append (&result, arg->str))
@@ -270,7 +276,7 @@ grub_script_execute_cmdline (struct grub_script_cmd *cmd)
   grub_script_function_t func = 0;
   char errnobuf[18];
   char *cmdname;
-  struct grub_script_argv argv = { 0, 0 };
+  struct grub_script_argv argv = { 0, 0, 0 };
 
   /* Lookup the command.  */
   if (grub_script_arglist_to_argv (cmdline->arglist, &argv))
@@ -314,7 +320,14 @@ grub_script_execute_cmdline (struct grub_script_cmd *cmd)
 
   /* Execute the GRUB command or function.  */
   if (grubcmd)
-    ret = (grubcmd->func) (grubcmd, argv.argc - 1, argv.args + 1);
+    {
+      if ((grubcmd->flags & GRUB_COMMAND_FLAG_BLOCKS) &&
+         (grubcmd->flags & GRUB_COMMAND_FLAG_EXTCMD))
+       ret = grub_extcmd_dispatcher (grubcmd, argv.argc - 1, argv.args + 1,
+                                     argv.scripts + 1);
+      else
+       ret = (grubcmd->func) (grubcmd, argv.argc - 1, argv.args + 1);
+    }
   else
     ret = grub_script_function_call (func, argv.argc - 1, argv.args + 1);
 
@@ -374,7 +387,7 @@ grub_script_execute_cmdfor (struct grub_script_cmd *cmd)
 {
   unsigned i;
   grub_err_t result;
-  struct grub_script_argv argv = { 0, 0 };
+  struct grub_script_argv argv = { 0, 0, 0 };
   struct grub_script_cmdfor *cmdfor = (struct grub_script_cmdfor *) cmd;
 
   if (grub_script_arglist_to_argv (cmdfor->words, &argv))
@@ -416,7 +429,7 @@ grub_err_t
 grub_script_execute_menuentry (struct grub_script_cmd *cmd)
 {
   struct grub_script_cmd_menuentry *cmd_menuentry;
-  struct grub_script_argv argv = { 0, 0 };
+  struct grub_script_argv argv = { 0, 0, 0 };
 
   cmd_menuentry = (struct grub_script_cmd_menuentry *) cmd;
 
index 653e2bc84b488eef1409ae020e0df96423f0861e..d774ca9189469a6fce22a0e38338edfec6da0d96 100644 (file)
@@ -164,7 +164,7 @@ block: "{"
          if ((p = grub_script_lexer_record_stop (state, $<offset>2)))
           *grub_strrchr (p, '}') = '\0';
 
-         if (arg = grub_script_arg_add (state, 0, GRUB_SCRIPT_ARG_TYPE_BLOCK, p))
+         if ((arg = grub_script_arg_add (state, 0, GRUB_SCRIPT_ARG_TYPE_BLOCK, p)))
           {
             arg->block.cmd = $3;
             arg->block.mem = memory;
index 9cee40dcb81ef51210539813cfb9e78cfa5a1167..9017a08e8dd0ae552d04529bba78e80c3292c489 100644 (file)
@@ -96,7 +96,10 @@ grub_script_free (struct grub_script *script)
 {
   if (!script)
     return;
-  grub_script_mem_free (script->mem);
+
+  if (script->mem)
+    grub_script_mem_free (script->mem);
+
   grub_free (script);
 }
 \f
@@ -119,6 +122,9 @@ grub_script_arg_add (struct grub_parser_param *state,
     return arg;
 
   argpart->type = type;
+  argpart->block.mem = 0;
+  argpart->block.cmd = 0;
+
   len = grub_strlen (str) + 1;
   argpart->str = grub_script_malloc (state, len);
   if (!argpart->str)
index ecfe4ff3b57ac2895d171268edafb13638f6c6e6..ffded5e6bdb099e558589ef6f69a85234746b524 100644 (file)
@@ -1091,11 +1091,10 @@ static const struct grub_arg_option background_image_cmd_options[] =
   };
 
 static grub_err_t
-grub_gfxterm_background_image_cmd (grub_extcmd_t cmd __attribute__ ((unused)),
-                                   int argc,
-                                   char **args)
+grub_gfxterm_background_image_cmd (grub_extcmd_context_t ctxt,
+                                   int argc, char **args)
 {
-  struct grub_arg_list *state = cmd->state;
+  struct grub_arg_list *state = ctxt->state;
 
   /* Check that we have video adapter active.  */
   if (grub_video_get_info(NULL) != GRUB_ERR_NONE)
index 2347bb3ee676929e0e33bbf320034ed824d13fbe..168e40bad4fc452f0b0876a0a4d6e7a03e1c5d60 100644 (file)
@@ -497,11 +497,11 @@ static struct grub_term_output grub_serial_term_output =
 \f
 
 static grub_err_t
-grub_cmd_serial (grub_extcmd_t cmd,
+grub_cmd_serial (grub_extcmd_context_t ctxt,
                  int argc __attribute__ ((unused)),
                 char **args __attribute__ ((unused)))
 {
-  struct grub_arg_list *state = cmd->state;
+  struct grub_arg_list *state = ctxt->state;
   struct serial_port backup_settings = serial_settings;
   grub_err_t hwiniterr;
 
index 8ff08cf8a846b6e61ba88802ddd93912ee560056..8be6c8e89018aca0491d624f376314810cdf228b 100644 (file)
@@ -22,7 +22,7 @@
 #include <grub/test.h>
 
 static grub_err_t
-grub_functional_test (struct grub_extcmd *cmd __attribute__ ((unused)),
+grub_functional_test (grub_extcmd_context_t ctxt __attribute__ ((unused)),
                      int argc __attribute__ ((unused)),
                      char **args __attribute__ ((unused)))
 {